diff --git a/.gitignore b/.gitignore index 5946060d..30934cbb 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,7 @@ _mysites/vendor/* _mysites/console/bin/.files/cache/* /Sites/*/vendor/* /Sites/**/wp-config* -/Sites/**/configuration.php \ No newline at end of file +/Sites/**/configuration.php +!/Sites/pages/configuration.php +/Projects/joomlatools-pages/cache/* +/Sites/pages/administrator/cache/* \ No newline at end of file diff --git a/Projects/.gitkeep b/Projects/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/Projects/joomlatools-pages/cache/pages/page_628915681.php b/Projects/joomlatools-pages/cache/pages/page_628915681.php new file mode 100644 index 00000000..3a2e1ada --- /dev/null +++ b/Projects/joomlatools-pages/cache/pages/page_628915681.php @@ -0,0 +1,43 @@ + + array ( + 'hello' => 'hello.html.php', + ), + 'pages' => + array ( + 'hello.html.php' => + array ( + 'path' => 'hello', + 'slug' => 'hello', + 'format' => 'html', + 'hash' => 'f007625f', + 'process' => + array ( + ), + 'route' => 'hello', + 'date' => 1616843837, + 'language' => 'en-GB', + 'metadata' => + array ( + 'robots' => + array ( + ), + ), + ), + ), + 'routes' => + array ( + 'hello' => + array ( + 0 => 'hello', + ), + ), + 'collections' => + array ( + ), + 'redirects' => + array ( + ), + 'hash' => 'c60f2a34', +); \ No newline at end of file diff --git a/Projects/joomlatools-pages/pages/hello.html.php b/Projects/joomlatools-pages/pages/hello.html.php new file mode 100644 index 00000000..b81fcde2 --- /dev/null +++ b/Projects/joomlatools-pages/pages/hello.html.php @@ -0,0 +1,2 @@ +

Hello World!

+

Welcome to my new page.

\ No newline at end of file diff --git a/README.md b/README.md index 26ac7be5..526a76ef 100644 --- a/README.md +++ b/README.md @@ -1,146 +1,32 @@ -![Screenshot](/screenshot.png?raw=true) - -# my-sites-ide - -`my-sites-ide` is designed to be an easy way to spin up new php development environments on the fly: - -`composer global require yiendos/my-sites-ide` - -Create new play areas, or you can integrate the IDE into existing projects. Simply navigate to the folder of your choice and run: - -`mysites setup` - -Followed by: - -`[project-name] spark` - -To launch your new play area... See `Your project path is important` below for further details. - ---- - ### Prerequisites Here is the list of prerequisites for your host system: * Docker -* php -* composer - -### Initial setup - -Now you are going to need to add the global `~./composer/vendor/bin` to your path if you haven't already done this. - -To do this temporarily for the session of your terminal screen: - -``` -export PATH=$PATH:~/.composer/vendor/bin -```` - -Or a more permanent solution: - -``` -echo 'export PATH="$PATH:$HOME/.composer/vendor/bin"' >> ~/.bashrc - -source ~/.bashrc -``` - -Or if you use zshrc: - -``` -echo 'export PATH="$PATH:$HOME/.composer/vendor/bin"' >> ~/.zshrc - -source ~/.zshrc && -``` -### Your project path is important +* php (not strictly needed, we could organise things to run off docker-compose alone) +* composer (see above) -Where you choose to install the `my-sites-ide` is important. Let's say you wanted to host sites(s) at: `~/Sites/new-site`: +### Getting started -* This would translate to project path of: -`/Users/somebody/Sites/new-site` - -* With the project name of -`new-site` - -So you would therefore install the `my-site-ide` by issuing the following commands: - -* Create the folder if it doesn't already exist: -``` -mkdir -p ~/Sites/new-site && cd ~/Sites/new-site -``` - -* Install the IDE -``` -mysites setup -``` - -* Launch the IDE -``` -new-site spark -``` - -This can take a while for the first time, we are building apache, nginx, php base images for you. The next time you come to use `mysites setup` for a new project the installation time will be super speedy. - -Then you are able to control the docker instances through commands we've created under the project namespace. So if your project is `new-sites` typing this into the terminal will give you access to these commands. See `Controlling your my-sites-ide` section below. - - -### Apple M1/ ARM64 chip support - -Note if you want to use this on Arm64 chips, we need to handle mysql differently. Currently only mysql:8.0 is supported: - -`mysites setup -f docker-compose-arm.yml` - -### Controlling your my-sites-ide - -We've made working with your my-sites-ide as easy as possible, as part of the `mysites setup` process we also created these commands under the project namespace. - -So once again if your site is hosted at `new-site`, then your new terminal commands will be available under the `new-site` namespace: - -``` -new-site - -Console Tool - -Usage: - command [options] [arguments] - -Options: - -h, --help Display help for the given command. When no command is given display help for the list command - -q, --quiet Do not output any message - -V, --version Display this application version - --ansi Force ANSI output - --no-ansi Disable ANSI output - -n, --no-interaction Do not ask any interactive question - -v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug - -Available commands: - douse Temporarily pause your sites - export Export a database(s) - help Displays help for a command - list Lists commands - panic Kindle won't launch? This is our troubleshooting command - restart Made changes locally? Restart the corresponding docker container - setup Create the initial mysites configuration file - spark Fire up your mysites IDE - status See the status of mysites containers - wordpress - wordpress:create Create a WordPress site - wordpress:delete Nuke an existing site - wordpress:vhost Creates a new Apache2 and/or Nginx virtual host -``` +1. `cd ~/Sites` +1. `git clone git@github.com:yiendos/my-sites-ide.git` +1. `cd ~/Sites/my-sites-ide` +1. `git checkout feature/16-pages ` +1. `php _mysites/console/bin/mysites setup` (slow first time, building base images... much quicker next pages installation) +1. `my-sites-ide spark` ### Welcome to your new play area -* http://localhost:8080 - apache2 -* http://localhost:8081 - nginx +* http://localhost:8080/pages/hello - apache2 +* http://localhost:8081/pages/hello - nginx * http://localhost:8083 - Mailhog * http://localhost:8084 - phpmyadmin -* http://localhost:3000 - Theia editor +* http://localhost:3000 - Theia editor - Temporarily switched off for this branch to save memory issues on host Database available at: -H 127.0.0.1 - P 3306 root:root We hope you feel at home! - ### Continuous Deployment as Standard `my-sites-ide` came from 8 years working with deployment processes (Jenkins, Travis, github actions) and from this the IDE came into being. So going full circle we've included a barebones github actions integration for you. diff --git a/Sites/index.php b/Sites/index.php new file mode 100644 index 00000000..0c8c0dca --- /dev/null +++ b/Sites/index.php @@ -0,0 +1,24 @@ +Welcome home"; +echo "
";
+echo $ascii;
+echo "
"; diff --git a/Sites/pages/.htaccess b/Sites/pages/.htaccess new file mode 100644 index 00000000..25b89f65 --- /dev/null +++ b/Sites/pages/.htaccess @@ -0,0 +1,92 @@ +## +# @package Joomla +# @copyright Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +# @license GNU General Public License version 2 or later; see LICENSE.txt +## + +## +# READ THIS COMPLETELY IF YOU CHOOSE TO USE THIS FILE! +# +# The line 'Options +FollowSymLinks' may cause problems with some server configurations. +# It is required for the use of Apache mod_rewrite, but it may have already been set by +# your server administrator in a way that disallows changing it in this .htaccess file. +# If using it causes your site to produce an error, comment it out (add # to the +# beginning of the line), reload your site in your browser and test your sef urls. If +# they work, then it has been set by your server administrator and you do not need to +# set it here. +## + +## No directory listings + + IndexIgnore * + + +## Suppress mime type detection in browsers for unknown types + +Header always set X-Content-Type-Options "nosniff" + + +## Can be commented out if causes errors, see notes above. +Options +FollowSymlinks +Options -Indexes + +## Disable inline JavaScript when directly opening SVG files or embedding them with the object-tag + + + Header always set Content-Security-Policy "script-src 'none'" + + + +## Mod_rewrite in use. + +RewriteEngine On + +## Begin - Rewrite rules to block out some common exploits. +# If you experience problems on your site then comment out the operations listed +# below by adding a # to the beginning of the line. +# This attempts to block the most common type of exploit `attempts` on Joomla! +# +# Block any script trying to base64_encode data within the URL. +RewriteCond %{QUERY_STRING} base64_encode[^(]*\([^)]*\) [OR] +# Block any script that includes a '); + + // Decode HTML entities. + $input = html_entity_decode($input, ENT_QUOTES, 'UTF-8'); + + // Convert entities equivalent to spaces to actual spaces. + $input = str_replace(array(' ', ' '), ' ', $input); + + // Add a space before both the OPEN and CLOSE tags of BLOCK and LINE BREAKING elements, + // e.g. 'all

mobile List

' will become 'all mobile List' + $input = preg_replace('/(<|<\/)(' . + 'address|article|aside|blockquote|br|canvas|dd|div|dl|dt|' . + 'fieldset|figcaption|figure|footer|form|h1|h2|h3|h4|h5|h6|header|hgroup|hr|li|' . + 'main|nav|noscript|ol|output|p|pre|section|table|tfoot|ul|video' . + ')\b/i', ' $1$2', $input + ); + + // Strip HTML tags. + $input = strip_tags($input); + + return parent::parse($input); + } + + /** + * Method to process HTML input and extract the plain text. + * + * @param string $input The input to process. + * + * @return string The plain text input. + * + * @since 2.5 + */ + protected function process($input) + { + // Replace any amount of white space with a single space. + return preg_replace('#\s+#u', ' ', $input); + } + + /** + * Method to remove blocks of text between a start and an end tag. + * Each block removed is effectively replaced by a single space. + * + * Note: The start tag and the end tag must be different. + * Note: Blocks must not be nested. + * Note: This method will function correctly with multi-byte strings. + * + * @param string $input String to be processed. + * @param string $startTag String representing the start tag. + * @param string $endTag String representing the end tag. + * + * @return string with blocks removed. + * + * @since 3.4 + */ + private function removeBlocks($input, $startTag, $endTag) + { + $return = ''; + $offset = 0; + $startTagLength = strlen($startTag); + $endTagLength = strlen($endTag); + + // Find the first start tag. + $start = stripos($input, $startTag); + + // If no start tags were found, return the string unchanged. + if ($start === false) + { + return $input; + } + + // Look for all blocks defined by the start and end tags. + while ($start !== false) + { + // Accumulate the substring up to the start tag. + $return .= substr($input, $offset, $start - $offset) . ' '; + + // Look for an end tag corresponding to the start tag. + $end = stripos($input, $endTag, $start + $startTagLength); + + // If no corresponding end tag, leave the string alone. + if ($end === false) + { + // Fix the offset so part of the string is not duplicated. + $offset = $start; + break; + } + + // Advance the start position. + $offset = $end + $endTagLength; + + // Look for the next start tag and loop. + $start = stripos($input, $startTag, $offset); + } + + // Add in the final substring after the last end tag. + $return .= substr($input, $offset); + + return $return; + } +} diff --git a/Sites/pages/administrator/components/com_finder/helpers/indexer/parser/rtf.php b/Sites/pages/administrator/components/com_finder/helpers/indexer/parser/rtf.php new file mode 100644 index 00000000..b8515733 --- /dev/null +++ b/Sites/pages/administrator/components/com_finder/helpers/indexer/parser/rtf.php @@ -0,0 +1,42 @@ +input = isset($options['input']) ? $options['input'] : null; + + // Get the empty query setting. + $this->empty = isset($options['empty']) ? (bool) $options['empty'] : false; + + // Get the input language. + $this->language = !empty($options['language']) ? $options['language'] : FinderIndexerHelper::getDefaultLanguage(); + $this->language = FinderIndexerHelper::getPrimaryLanguage($this->language); + + // Get the matching mode. + $this->mode = 'AND'; + + // Initialize the temporary date storage. + $this->dates = new Registry; + + // Populate the temporary date storage. + if (!empty($options['date1'])) + { + $this->dates->set('date1', $options['date1']); + } + + if (!empty($options['date2'])) + { + $this->dates->set('date2', $options['date2']); + } + + if (!empty($options['when1'])) + { + $this->dates->set('when1', $options['when1']); + } + + if (!empty($options['when2'])) + { + $this->dates->set('when2', $options['when2']); + } + + // Process the static taxonomy filters. + if (!empty($options['filter'])) + { + $this->processStaticTaxonomy($options['filter']); + } + + // Process the dynamic taxonomy filters. + if (!empty($options['filters'])) + { + $this->processDynamicTaxonomy($options['filters']); + } + + // Get the date filters. + $d1 = $this->dates->get('date1'); + $d2 = $this->dates->get('date2'); + $w1 = $this->dates->get('when1'); + $w2 = $this->dates->get('when2'); + + // Process the date filters. + if (!empty($d1) || !empty($d2)) + { + $this->processDates($d1, $d2, $w1, $w2); + } + + // Process the input string. + $this->processString($this->input, $this->language, $this->mode); + + // Get the number of matching terms. + foreach ($this->included as $token) + { + $this->terms += count($token->matches); + } + + // Remove the temporary date storage. + unset($this->dates); + + // Lastly, determine whether this query can return a result set. + + // Check if we have a query string. + if (!empty($this->input)) + { + $this->search = true; + } + // Check if we can search without a query string. + elseif ($this->empty && (!empty($this->filter) || !empty($this->filters) || !empty($this->date1) || !empty($this->date2))) + { + $this->search = true; + } + // We do not have a valid search query. + else + { + $this->search = false; + } + } + + /** + * Method to convert the query object into a URI string. + * + * @param string $base The base URI. [optional] + * + * @return string The complete query URI. + * + * @since 2.5 + */ + public function toUri($base = '') + { + // Set the base if not specified. + if ($base === '') + { + $base = 'index.php?option=com_finder&view=search'; + } + + // Get the base URI. + $uri = JUri::getInstance($base); + + // Add the static taxonomy filter if present. + if ((bool) $this->filter) + { + $uri->setVar('f', $this->filter); + } + + // Get the filters in the request. + $t = JFactory::getApplication()->input->request->get('t', array(), 'array'); + + // Add the dynamic taxonomy filters if present. + if ((bool) $this->filters) + { + foreach ($this->filters as $nodes) + { + foreach ($nodes as $node) + { + if (!in_array($node, $t)) + { + continue; + } + + $uri->setVar('t[]', $node); + } + } + } + + // Add the input string if present. + if (!empty($this->input)) + { + $uri->setVar('q', $this->input); + } + + // Add the start date if present. + if (!empty($this->date1)) + { + $uri->setVar('d1', $this->date1); + } + + // Add the end date if present. + if (!empty($this->date2)) + { + $uri->setVar('d2', $this->date2); + } + + // Add the start date modifier if present. + if (!empty($this->when1)) + { + $uri->setVar('w1', $this->when1); + } + + // Add the end date modifier if present. + if (!empty($this->when2)) + { + $uri->setVar('w2', $this->when2); + } + + // Add a menu item id if one is not present. + if (!$uri->getVar('Itemid')) + { + // Get the menu item id. + $query = array( + 'view' => $uri->getVar('view'), + 'f' => $uri->getVar('f'), + 'q' => $uri->getVar('q'), + ); + + $item = FinderHelperRoute::getItemid($query); + + // Add the menu item id if present. + if ($item !== null) + { + $uri->setVar('Itemid', $item); + } + } + + return $uri->toString(array('path', 'query')); + } + + /** + * Method to get a list of excluded search term ids. + * + * @return array An array of excluded term ids. + * + * @since 2.5 + */ + public function getExcludedTermIds() + { + $results = array(); + + // Iterate through the excluded tokens and compile the matching terms. + for ($i = 0, $c = count($this->excluded); $i < $c; $i++) + { + $results = array_merge($results, $this->excluded[$i]->matches); + } + + // Sanitize the terms. + $results = array_unique($results); + + return ArrayHelper::toInteger($results); + } + + /** + * Method to get a list of included search term ids. + * + * @return array An array of included term ids. + * + * @since 2.5 + */ + public function getIncludedTermIds() + { + $results = array(); + + // Iterate through the included tokens and compile the matching terms. + for ($i = 0, $c = count($this->included); $i < $c; $i++) + { + // Check if we have any terms. + if (empty($this->included[$i]->matches)) + { + continue; + } + + // Get the term. + $term = $this->included[$i]->term; + + // Prepare the container for the term if necessary. + if (!array_key_exists($term, $results)) + { + $results[$term] = array(); + } + + // Add the matches to the stack. + $results[$term] = array_merge($results[$term], $this->included[$i]->matches); + } + + // Sanitize the terms. + foreach ($results as $key => $value) + { + $results[$key] = array_unique($results[$key]); + $results[$key] = ArrayHelper::toInteger($results[$key]); + } + + return $results; + } + + /** + * Method to get a list of required search term ids. + * + * @return array An array of required term ids. + * + * @since 2.5 + */ + public function getRequiredTermIds() + { + $results = array(); + + // Iterate through the included tokens and compile the matching terms. + for ($i = 0, $c = count($this->included); $i < $c; $i++) + { + // Check if the token is required. + if ($this->included[$i]->required) + { + // Get the term. + $term = $this->included[$i]->term; + + // Prepare the container for the term if necessary. + if (!array_key_exists($term, $results)) + { + $results[$term] = array(); + } + + // Add the matches to the stack. + $results[$term] = array_merge($results[$term], $this->included[$i]->matches); + } + } + + // Sanitize the terms. + foreach ($results as $key => $value) + { + $results[$key] = array_unique($results[$key]); + $results[$key] = ArrayHelper::toInteger($results[$key]); + } + + return $results; + } + + /** + * Method to process the static taxonomy input. The static taxonomy input + * comes in the form of a pre-defined search filter that is assigned to the + * search form. + * + * @param integer $filterId The id of static filter. + * + * @return boolean True on success, false on failure. + * + * @since 2.5 + * @throws Exception on database error. + */ + protected function processStaticTaxonomy($filterId) + { + // Get the database object. + $db = JFactory::getDbo(); + + // Initialize user variables + $groups = implode(',', JFactory::getUser()->getAuthorisedViewLevels()); + + // Load the predefined filter. + $query = $db->getQuery(true) + ->select('f.data, f.params') + ->from($db->quoteName('#__finder_filters') . ' AS f') + ->where('f.filter_id = ' . (int) $filterId); + + $db->setQuery($query); + $return = $db->loadObject(); + + // Check the returned filter. + if (empty($return)) + { + return false; + } + + // Set the filter. + $this->filter = (int) $filterId; + + // Get a parameter object for the filter date options. + $registry = new Registry($return->params); + $params = $registry; + + // Set the dates if not already set. + $this->dates->def('d1', $params->get('d1')); + $this->dates->def('d2', $params->get('d2')); + $this->dates->def('w1', $params->get('w1')); + $this->dates->def('w2', $params->get('w2')); + + // Remove duplicates and sanitize. + $filters = explode(',', $return->data); + $filters = array_unique($filters); + $filters = ArrayHelper::toInteger($filters); + + // Remove any values of zero. + if (in_array(0, $filters, true) !== false) + { + unset($filters[array_search(0, $filters, true)]); + } + + // Check if we have any real input. + if (empty($filters)) + { + return true; + } + + /* + * Create the query to get filters from the database. We do this for + * two reasons: one, it allows us to ensure that the filters being used + * are real; two, we need to sort the filters by taxonomy branch. + */ + $query->clear() + ->select('t1.id, t1.title, t2.title AS branch') + ->from($db->quoteName('#__finder_taxonomy') . ' AS t1') + ->join('INNER', $db->quoteName('#__finder_taxonomy') . ' AS t2 ON t2.id = t1.parent_id') + ->where('t1.state = 1') + ->where('t1.access IN (' . $groups . ')') + ->where('t1.id IN (' . implode(',', $filters) . ')') + ->where('t2.state = 1') + ->where('t2.access IN (' . $groups . ')'); + + // Load the filters. + $db->setQuery($query); + $results = $db->loadObjectList(); + + // Sort the filter ids by branch. + foreach ($results as $result) + { + $this->filters[$result->branch][$result->title] = (int) $result->id; + } + + return true; + } + + /** + * Method to process the dynamic taxonomy input. The dynamic taxonomy input + * comes in the form of select fields that the user chooses from. The + * dynamic taxonomy input is processed AFTER the static taxonomy input + * because the dynamic options can be used to further narrow a static + * taxonomy filter. + * + * @param array $filters An array of taxonomy node ids. + * + * @return boolean True on success. + * + * @since 2.5 + * @throws Exception on database error. + */ + protected function processDynamicTaxonomy($filters) + { + // Initialize user variables + $groups = implode(',', JFactory::getUser()->getAuthorisedViewLevels()); + + // Remove duplicates and sanitize. + $filters = array_unique($filters); + $filters = ArrayHelper::toInteger($filters); + + // Remove any values of zero. + if (in_array(0, $filters, true) !== false) + { + unset($filters[array_search(0, $filters, true)]); + } + + // Check if we have any real input. + if (empty($filters)) + { + return true; + } + + // Get the database object. + $db = JFactory::getDbo(); + + $query = $db->getQuery(true); + + /* + * Create the query to get filters from the database. We do this for + * two reasons: one, it allows us to ensure that the filters being used + * are real; two, we need to sort the filters by taxonomy branch. + */ + $query->select('t1.id, t1.title, t2.title AS branch') + ->from($db->quoteName('#__finder_taxonomy') . ' AS t1') + ->join('INNER', $db->quoteName('#__finder_taxonomy') . ' AS t2 ON t2.id = t1.parent_id') + ->where('t1.state = 1') + ->where('t1.access IN (' . $groups . ')') + ->where('t1.id IN (' . implode(',', $filters) . ')') + ->where('t2.state = 1') + ->where('t2.access IN (' . $groups . ')'); + + // Load the filters. + $db->setQuery($query); + $results = $db->loadObjectList(); + + // Cleared filter branches. + $cleared = array(); + + /* + * Sort the filter ids by branch. Because these filters are designed to + * override and further narrow the items selected in the static filter, + * we will clear the values from the static filter on a branch by + * branch basis before adding the dynamic filters. So, if the static + * filter defines a type filter of "articles" and three "category" + * filters but the user only limits the category further, the category + * filters will be flushed but the type filters will not. + */ + foreach ($results as $result) + { + // Check if the branch has been cleared. + if (!in_array($result->branch, $cleared, true)) + { + // Clear the branch. + $this->filters[$result->branch] = array(); + + // Add the branch to the cleared list. + $cleared[] = $result->branch; + } + + // Add the filter to the list. + $this->filters[$result->branch][$result->title] = (int) $result->id; + } + + return true; + } + + /** + * Method to process the query date filters to determine start and end + * date limitations. + * + * @param string $date1 The first date filter. + * @param string $date2 The second date filter. + * @param string $when1 The first date modifier. + * @param string $when2 The second date modifier. + * + * @return boolean True on success. + * + * @since 2.5 + */ + protected function processDates($date1, $date2, $when1, $when2) + { + // Clean up the inputs. + $date1 = trim(StringHelper::strtolower($date1)); + $date2 = trim(StringHelper::strtolower($date2)); + $when1 = trim(StringHelper::strtolower($when1)); + $when2 = trim(StringHelper::strtolower($when2)); + + // Get the time offset. + $offset = JFactory::getApplication()->get('offset'); + + // Array of allowed when values. + $whens = array('before', 'after', 'exact'); + + // The value of 'today' is a special case that we need to handle. + if ($date1 === StringHelper::strtolower(JText::_('COM_FINDER_QUERY_FILTER_TODAY'))) + { + $date1 = JFactory::getDate('now', $offset)->format('%Y-%m-%d'); + } + + // Try to parse the date string. + $date = JFactory::getDate($date1, $offset); + + // Check if the date was parsed successfully. + if ($date->toUnix() !== null) + { + // Set the date filter. + $this->date1 = $date->toSql(); + $this->when1 = in_array($when1, $whens, true) ? $when1 : 'before'; + } + + // The value of 'today' is a special case that we need to handle. + if ($date2 === StringHelper::strtolower(JText::_('COM_FINDER_QUERY_FILTER_TODAY'))) + { + $date2 = JFactory::getDate('now', $offset)->format('%Y-%m-%d'); + } + + // Try to parse the date string. + $date = JFactory::getDate($date2, $offset); + + // Check if the date was parsed successfully. + if ($date->toUnix() !== null) + { + // Set the date filter. + $this->date2 = $date->toSql(); + $this->when2 = in_array($when2, $whens, true) ? $when2 : 'before'; + } + + return true; + } + + /** + * Method to process the query input string and extract required, optional, + * and excluded tokens; taxonomy filters; and date filters. + * + * @param string $input The query input string. + * @param string $lang The query input language. + * @param string $mode The query matching mode. + * + * @return boolean True on success. + * + * @since 2.5 + * @throws Exception on database error. + */ + protected function processString($input, $lang, $mode) + { + // Clean up the input string. + $input = html_entity_decode($input, ENT_QUOTES, 'UTF-8'); + $input = StringHelper::strtolower($input); + $input = preg_replace('#\s+#mi', ' ', $input); + $input = trim($input); + $debug = JFactory::getConfig()->get('debug_lang'); + + /* + * First, we need to handle string based modifiers. String based + * modifiers could potentially include things like "category:blah" or + * "before:2009-10-21" or "type:article", etc. + */ + $patterns = array( + 'before' => JText::_('COM_FINDER_FILTER_WHEN_BEFORE'), + 'after' => JText::_('COM_FINDER_FILTER_WHEN_AFTER'), + ); + + // Add the taxonomy branch titles to the possible patterns. + foreach (FinderIndexerTaxonomy::getBranchTitles() as $branch) + { + // Add the pattern. + $patterns[$branch] = StringHelper::strtolower(JText::_(FinderHelperLanguage::branchSingular($branch))); + } + + // Container for search terms and phrases. + $terms = array(); + $phrases = array(); + + // Cleared filter branches. + $cleared = array(); + + /* + * Compile the suffix pattern. This is used to match the values of the + * filter input string. Single words can be input directly, multi-word + * values have to be wrapped in double quotes. + */ + $quotes = html_entity_decode('‘’'', ENT_QUOTES, 'UTF-8'); + $suffix = '(([\w\d' . $quotes . '-]+)|\"([\w\d\s' . $quotes . '-]+)\")'; + + /* + * Iterate through the possible filter patterns and search for matches. + * We need to match the key, colon, and a value pattern for the match + * to be valid. + */ + foreach ($patterns as $modifier => $pattern) + { + $matches = array(); + + if ($debug) + { + $pattern = substr($pattern, 2, -2); + } + + // Check if the filter pattern is in the input string. + if (preg_match('#' . $pattern . '\s*:\s*' . $suffix . '#mi', $input, $matches)) + { + // Get the value given to the modifier. + $value = isset($matches[3]) ? $matches[3] : $matches[1]; + + // Now we have to handle the filter string. + switch ($modifier) + { + // Handle a before and after date filters. + case 'before': + case 'after': + { + // Get the time offset. + $offset = JFactory::getApplication()->get('offset'); + + // Array of allowed when values. + $whens = array('before', 'after', 'exact'); + + // The value of 'today' is a special case that we need to handle. + if ($value === StringHelper::strtolower(JText::_('COM_FINDER_QUERY_FILTER_TODAY'))) + { + $value = JFactory::getDate('now', $offset)->format('%Y-%m-%d'); + } + + // Try to parse the date string. + $date = JFactory::getDate($value, $offset); + + // Check if the date was parsed successfully. + if ($date->toUnix() !== null) + { + // Set the date filter. + $this->date1 = $date->toSql(); + $this->when1 = in_array($modifier, $whens, true) ? $modifier : 'before'; + } + + break; + } + + // Handle a taxonomy branch filter. + default: + { + // Try to find the node id. + $return = FinderIndexerTaxonomy::getNodeByTitle($modifier, $value); + + // Check if the node id was found. + if ($return) + { + // Check if the branch has been cleared. + if (!in_array($modifier, $cleared, true)) + { + // Clear the branch. + $this->filters[$modifier] = array(); + + // Add the branch to the cleared list. + $cleared[] = $modifier; + } + + // Add the filter to the list. + $this->filters[$modifier][$return->title] = (int) $return->id; + } + + break; + } + } + + // Clean up the input string again. + $input = str_replace($matches[0], '', $input); + $input = preg_replace('#\s+#mi', ' ', $input); + $input = trim($input); + } + } + + /* + * Extract the tokens enclosed in double quotes so that we can handle + * them as phrases. + */ + if (StringHelper::strpos($input, '"') !== false) + { + $matches = array(); + + // Extract the tokens enclosed in double quotes. + if (preg_match_all('#\"([^"]+)\"#m', $input, $matches)) + { + /* + * One or more phrases were found so we need to iterate through + * them, tokenize them as phrases, and remove them from the raw + * input string before we move on to the next processing step. + */ + foreach ($matches[1] as $key => $match) + { + // Find the complete phrase in the input string. + $pos = StringHelper::strpos($input, $matches[0][$key]); + $len = StringHelper::strlen($matches[0][$key]); + + // Add any terms that are before this phrase to the stack. + if (trim(StringHelper::substr($input, 0, $pos))) + { + $terms = array_merge($terms, explode(' ', trim(StringHelper::substr($input, 0, $pos)))); + } + + // Strip out everything up to and including the phrase. + $input = StringHelper::substr($input, $pos + $len); + + // Clean up the input string again. + $input = preg_replace('#\s+#mi', ' ', $input); + $input = trim($input); + + // Get the number of words in the phrase. + $parts = explode(' ', $match); + + // Check if the phrase is longer than three words. + if (count($parts) > 3) + { + /* + * If the phrase is longer than three words, we need to + * break it down into smaller chunks of phrases that + * are less than or equal to three words. We overlap + * the chunks so that we can ensure that a match is + * found for the complete phrase and not just portions + * of it. + */ + for ($i = 0, $c = count($parts); $i < $c; $i += 2) + { + // Set up the chunk. + $chunk = array(); + + // The chunk has to be assembled based on how many + // pieces are available to use. + switch ($c - $i) + { + /* + * If only one word is left, we can break from + * the switch and loop because the last word + * was already used at the end of the last + * chunk. + */ + case 1: + break 2; + + // If there words are left, we use them both as + // the last chunk of the phrase and we're done. + case 2: + $chunk[] = $parts[$i]; + $chunk[] = $parts[$i + 1]; + break; + + // If there are three or more words left, we + // build a three word chunk and continue on. + default: + $chunk[] = $parts[$i]; + $chunk[] = $parts[$i + 1]; + $chunk[] = $parts[$i + 2]; + break; + } + + // If the chunk is not empty, add it as a phrase. + if (count($chunk)) + { + $phrases[] = implode(' ', $chunk); + $terms[] = implode(' ', $chunk); + } + } + } + else + { + // The phrase is <= 3 words so we can use it as is. + $phrases[] = $match; + $terms[] = $match; + } + } + } + } + + // Add the remaining terms if present. + if ((bool) $input) + { + $terms = array_merge($terms, explode(' ', $input)); + } + + // An array of our boolean operators. $operator => $translation + $operators = array( + 'AND' => StringHelper::strtolower(JText::_('COM_FINDER_QUERY_OPERATOR_AND')), + 'OR' => StringHelper::strtolower(JText::_('COM_FINDER_QUERY_OPERATOR_OR')), + 'NOT' => StringHelper::strtolower(JText::_('COM_FINDER_QUERY_OPERATOR_NOT')), + ); + + // If language debugging is enabled you need to ignore the debug strings in matching. + if (JDEBUG) + { + $debugStrings = array('**', '??'); + $operators = str_replace($debugStrings, '', $operators); + } + + /* + * Iterate through the terms and perform any sorting that needs to be + * done based on boolean search operators. Terms that are before an + * and/or/not modifier have to be handled in relation to their operator. + */ + for ($i = 0, $c = count($terms); $i < $c; $i++) + { + // Check if the term is followed by an operator that we understand. + if (isset($terms[$i + 1]) && in_array($terms[$i + 1], $operators, true)) + { + // Get the operator mode. + $op = array_search($terms[$i + 1], $operators, true); + + // Handle the AND operator. + if ($op === 'AND' && isset($terms[$i + 2])) + { + // Tokenize the current term. + $token = FinderIndexerHelper::tokenize($terms[$i], $lang, true); + + // Todo: The previous function call may return an array, which seems not to be handled by the next one, which expects an object + $token = $this->getTokenData($token); + + // Set the required flag. + $token->required = true; + + // Add the current token to the stack. + $this->included[] = $token; + $this->highlight = array_merge($this->highlight, array_keys($token->matches)); + + // Skip the next token (the mode operator). + $this->operators[] = $terms[$i + 1]; + + // Tokenize the term after the next term (current plus two). + $other = FinderIndexerHelper::tokenize($terms[$i + 2], $lang, true); + $other = $this->getTokenData($other); + + // Set the required flag. + $other->required = true; + + // Add the token after the next token to the stack. + $this->included[] = $other; + $this->highlight = array_merge($this->highlight, array_keys($other->matches)); + + // Remove the processed phrases if possible. + if (($pk = array_search($terms[$i], $phrases, true)) !== false) + { + unset($phrases[$pk]); + } + + if (($pk = array_search($terms[$i + 2], $phrases, true)) !== false) + { + unset($phrases[$pk]); + } + + // Remove the processed terms. + unset($terms[$i], $terms[$i + 1], $terms[$i + 2]); + + // Adjust the loop. + $i += 2; + continue; + } + // Handle the OR operator. + elseif ($op === 'OR' && isset($terms[$i + 2])) + { + // Tokenize the current term. + $token = FinderIndexerHelper::tokenize($terms[$i], $lang, true); + $token = $this->getTokenData($token); + + // Set the required flag. + $token->required = false; + + // Add the current token to the stack. + if ((bool) $token->matches) + { + $this->included[] = $token; + $this->highlight = array_merge($this->highlight, array_keys($token->matches)); + } + else + { + $this->ignored[] = $token; + } + + // Skip the next token (the mode operator). + $this->operators[] = $terms[$i + 1]; + + // Tokenize the term after the next term (current plus two). + $other = FinderIndexerHelper::tokenize($terms[$i + 2], $lang, true); + $other = $this->getTokenData($other); + + // Set the required flag. + $other->required = false; + + // Add the token after the next token to the stack. + if ((bool) $other->matches) + { + $this->included[] = $other; + $this->highlight = array_merge($this->highlight, array_keys($other->matches)); + } + else + { + $this->ignored[] = $other; + } + + // Remove the processed phrases if possible. + if (($pk = array_search($terms[$i], $phrases, true)) !== false) + { + unset($phrases[$pk]); + } + + if (($pk = array_search($terms[$i + 2], $phrases, true)) !== false) + { + unset($phrases[$pk]); + } + + // Remove the processed terms. + unset($terms[$i], $terms[$i + 1], $terms[$i + 2]); + + // Adjust the loop. + $i += 2; + continue; + } + } + // Handle an orphaned OR operator. + elseif (isset($terms[$i + 1]) && array_search($terms[$i], $operators, true) === 'OR') + { + // Skip the next token (the mode operator). + $this->operators[] = $terms[$i]; + + // Tokenize the next term (current plus one). + $other = FinderIndexerHelper::tokenize($terms[$i + 1], $lang, true); + $other = $this->getTokenData($other); + + // Set the required flag. + $other->required = false; + + // Add the token after the next token to the stack. + if ((bool) $other->matches) + { + $this->included[] = $other; + $this->highlight = array_merge($this->highlight, array_keys($other->matches)); + } + else + { + $this->ignored[] = $other; + } + + // Remove the processed phrase if possible. + if (($pk = array_search($terms[$i + 1], $phrases, true)) !== false) + { + unset($phrases[$pk]); + } + + // Remove the processed terms. + unset($terms[$i], $terms[$i + 1]); + + // Adjust the loop. + $i++; + continue; + } + // Handle the NOT operator. + elseif (isset($terms[$i + 1]) && array_search($terms[$i], $operators, true) === 'NOT') + { + // Skip the next token (the mode operator). + $this->operators[] = $terms[$i]; + + // Tokenize the next term (current plus one). + $other = FinderIndexerHelper::tokenize($terms[$i + 1], $lang, true); + $other = $this->getTokenData($other); + + // Set the required flag. + $other->required = false; + + // Add the next token to the stack. + if ((bool) $other->matches) + { + $this->excluded[] = $other; + } + else + { + $this->ignored[] = $other; + } + + // Remove the processed phrase if possible. + if (($pk = array_search($terms[$i + 1], $phrases, true)) !== false) + { + unset($phrases[$pk]); + } + + // Remove the processed terms. + unset($terms[$i], $terms[$i + 1]); + + // Adjust the loop. + $i++; + continue; + } + } + + /* + * Iterate through any search phrases and tokenize them. We handle + * phrases as autonomous units and do not break them down into two and + * three word combinations. + */ + for ($i = 0, $c = count($phrases); $i < $c; $i++) + { + // Tokenize the phrase. + $token = FinderIndexerHelper::tokenize($phrases[$i], $lang, true); + $token = $this->getTokenData($token); + + // Set the required flag. + $token->required = true; + + // Add the current token to the stack. + $this->included[] = $token; + $this->highlight = array_merge($this->highlight, array_keys($token->matches)); + + // Remove the processed term if possible. + if (($pk = array_search($phrases[$i], $terms, true)) !== false) + { + unset($terms[$pk]); + } + + // Remove the processed phrase. + unset($phrases[$i]); + } + + /* + * Handle any remaining tokens using the standard processing mechanism. + */ + if ((bool) $terms) + { + // Tokenize the terms. + $terms = implode(' ', $terms); + $tokens = FinderIndexerHelper::tokenize($terms, $lang, false); + + // Make sure we are working with an array. + $tokens = is_array($tokens) ? $tokens : array($tokens); + + // Get the token data and required state for all the tokens. + foreach ($tokens as $token) + { + // Get the token data. + $token = $this->getTokenData($token); + + // Set the required flag for the token. + $token->required = $mode === 'AND' ? (!$token->phrase) : false; + + // Add the token to the appropriate stack. + if ($token->required || (bool) $token->matches) + { + $this->included[] = $token; + $this->highlight = array_merge($this->highlight, array_keys($token->matches)); + } + else + { + $this->ignored[] = $token; + } + } + } + + return true; + } + + /** + * Method to get the base and similar term ids and, if necessary, suggested + * term data from the database. The terms ids are identified based on a + * 'like' match in MySQL and/or a common stem. If no term ids could be + * found, then we know that we will not be able to return any results for + * that term and we should try to find a similar term to use that we can + * match so that we can suggest the alternative search query to the user. + * + * @param FinderIndexerToken $token A FinderIndexerToken object. + * + * @return FinderIndexerToken A FinderIndexerToken object. + * + * @since 2.5 + * @throws Exception on database error. + */ + protected function getTokenData($token) + { + // Get the database object. + $db = JFactory::getDbo(); + + // Create a database query to build match the token. + $query = $db->getQuery(true) + ->select('t.term, t.term_id') + ->from('#__finder_terms AS t'); + + /* + * If the token is a phrase, the lookup process is fairly simple. If + * the token is a word, it is a little more complicated. We have to + * create two queries to lookup the term and the stem respectively, + * then union the result sets together. This is MUCH faster than using + * an or condition in the database query. + */ + if ($token->phrase) + { + // Add the phrase to the query. + $query->where('t.term = ' . $db->quote($token->term)) + ->where('t.phrase = 1'); + } + else + { + // Add the term to the query. + $query->where('t.term = ' . $db->quote($token->term)) + ->where('t.phrase = 0'); + + // Clone the query, replace the WHERE clause. + $sub = clone $query; + $sub->clear('where'); + $sub->where('t.stem = ' . $db->quote($token->stem)); + $sub->where('t.phrase = 0'); + + // Union the two queries. + $query->union($sub); + } + + // Get the terms. + $db->setQuery($query); + $matches = $db->loadObjectList(); + + // Check the matching terms. + if ((bool) $matches) + { + // Add the matches to the token. + for ($i = 0, $c = count($matches); $i < $c; $i++) + { + $token->matches[$matches[$i]->term] = (int) $matches[$i]->term_id; + } + } + + // If no matches were found, try to find a similar but better token. + if (empty($token->matches)) + { + // Create a database query to get the similar terms. + // TODO: PostgreSQL doesn't support SOUNDEX out of the box + $query->clear() + ->select('DISTINCT t.term_id AS id, t.term AS term') + ->from('#__finder_terms AS t') + // ->where('t.soundex = ' . soundex($db->quote($token->term))) + ->where('t.soundex = SOUNDEX(' . $db->quote($token->term) . ')') + ->where('t.phrase = ' . (int) $token->phrase); + + // Get the terms. + $db->setQuery($query); + $results = $db->loadObjectList(); + + // Check if any similar terms were found. + if (empty($results)) + { + return $token; + } + + // Stack for sorting the similar terms. + $suggestions = array(); + + // Get the levnshtein distance for all suggested terms. + foreach ($results as $sk => $st) + { + // Get the levenshtein distance between terms. + $distance = levenshtein($st->term, $token->term); + + // Make sure the levenshtein distance isn't over 50. + if ($distance < 50) + { + $suggestions[$sk] = $distance; + } + } + + // Sort the suggestions. + asort($suggestions, SORT_NUMERIC); + + // Get the closest match. + $keys = array_keys($suggestions); + $key = $keys[0]; + + // Add the suggested term. + $token->suggestion = $results[$key]->term; + } + + return $token; + } +} diff --git a/Sites/pages/administrator/components/com_finder/helpers/indexer/result.php b/Sites/pages/administrator/components/com_finder/helpers/indexer/result.php new file mode 100644 index 00000000..2551a995 --- /dev/null +++ b/Sites/pages/administrator/components/com_finder/helpers/indexer/result.php @@ -0,0 +1,425 @@ + array('title', 'subtitle', 'id'), + FinderIndexer::TEXT_CONTEXT => array('summary', 'body'), + FinderIndexer::META_CONTEXT => array('meta', 'list_price', 'sale_price'), + FinderIndexer::PATH_CONTEXT => array('path', 'alias'), + FinderIndexer::MISC_CONTEXT => array('comments'), + ); + + /** + * The indexer will use this data to create taxonomy mapping entries for + * the item so that it can be filtered by type, label, category, + * or whatever. + * + * @var array + * @since 2.5 + */ + protected $taxonomy = array(); + + /** + * The content URL. + * + * @var string + * @since 2.5 + */ + public $url; + + /** + * The content route. + * + * @var string + * @since 2.5 + */ + public $route; + + /** + * The content title. + * + * @var string + * @since 2.5 + */ + public $title; + + /** + * The content description. + * + * @var string + * @since 2.5 + */ + public $description; + + /** + * The published state of the result. + * + * @var integer + * @since 2.5 + */ + public $published; + + /** + * The content published state. + * + * @var integer + * @since 2.5 + */ + public $state; + + /** + * The content access level. + * + * @var integer + * @since 2.5 + */ + public $access; + + /** + * The content language. + * + * @var string + * @since 2.5 + */ + public $language = '*'; + + /** + * The publishing start date. + * + * @var string + * @since 2.5 + */ + public $publish_start_date; + + /** + * The publishing end date. + * + * @var string + * @since 2.5 + */ + public $publish_end_date; + + /** + * The generic start date. + * + * @var string + * @since 2.5 + */ + public $start_date; + + /** + * The generic end date. + * + * @var string + * @since 2.5 + */ + public $end_date; + + /** + * The item list price. + * + * @var mixed + * @since 2.5 + */ + public $list_price; + + /** + * The item sale price. + * + * @var mixed + * @since 2.5 + */ + public $sale_price; + + /** + * The content type id. This is set by the adapter. + * + * @var integer + * @since 2.5 + */ + public $type_id; + + /** + * The default language for content. + * + * @var string + * @since 3.0.2 + */ + public $defaultLanguage; + + /** + * Constructor + * + * @since 3.0.3 + */ + public function __construct() + { + $this->defaultLanguage = JComponentHelper::getParams('com_languages')->get('site', 'en-GB'); + } + + /** + * The magic set method is used to push additional values into the elements + * array in order to preserve the cleanliness of the object. + * + * @param string $name The name of the element. + * @param mixed $value The value of the element. + * + * @return void + * + * @since 2.5 + */ + public function __set($name, $value) + { + $this->setElement($name, $value); + } + + /** + * The magic get method is used to retrieve additional element values from the elements array. + * + * @param string $name The name of the element. + * + * @return mixed The value of the element if set, null otherwise. + * + * @since 2.5 + */ + public function __get($name) + { + return $this->getElement($name); + } + + /** + * The magic isset method is used to check the state of additional element values in the elements array. + * + * @param string $name The name of the element. + * + * @return boolean True if set, false otherwise. + * + * @since 2.5 + */ + public function __isset($name) + { + return isset($this->elements[$name]); + } + + /** + * The magic unset method is used to unset additional element values in the elements array. + * + * @param string $name The name of the element. + * + * @return void + * + * @since 2.5 + */ + public function __unset($name) + { + unset($this->elements[$name]); + } + + /** + * Method to retrieve additional element values from the elements array. + * + * @param string $name The name of the element. + * + * @return mixed The value of the element if set, null otherwise. + * + * @since 2.5 + */ + public function getElement($name) + { + // Get the element value if set. + if (array_key_exists($name, $this->elements)) + { + return $this->elements[$name]; + } + + return null; + } + + /** + * Method to retrieve all elements. + * + * @return array The elements + * + * @since 3.8.3 + */ + public function getElements() + { + return $this->elements; + } + + /** + * Method to set additional element values in the elements array. + * + * @param string $name The name of the element. + * @param mixed $value The value of the element. + * + * @return void + * + * @since 2.5 + */ + public function setElement($name, $value) + { + $this->elements[$name] = $value; + } + + /** + * Method to get all processing instructions. + * + * @return array An array of processing instructions. + * + * @since 2.5 + */ + public function getInstructions() + { + return $this->instructions; + } + + /** + * Method to add a processing instruction for an item property. + * + * @param string $group The group to associate the property with. + * @param string $property The property to process. + * + * @return void + * + * @since 2.5 + */ + public function addInstruction($group, $property) + { + // Check if the group exists. We can't add instructions for unknown groups. + // Check if the property exists in the group. + if (array_key_exists($group, $this->instructions) && !in_array($property, $this->instructions[$group], true)) + { + // Add the property to the group. + $this->instructions[$group][] = $property; + } + } + + /** + * Method to remove a processing instruction for an item property. + * + * @param string $group The group to associate the property with. + * @param string $property The property to process. + * + * @return void + * + * @since 2.5 + */ + public function removeInstruction($group, $property) + { + // Check if the group exists. We can't remove instructions for unknown groups. + if (array_key_exists($group, $this->instructions)) + { + // Search for the property in the group. + $key = array_search($property, $this->instructions[$group]); + + // If the property was found, remove it. + if ($key !== false) + { + unset($this->instructions[$group][$key]); + } + } + } + + /** + * Method to get the taxonomy maps for an item. + * + * @param string $branch The taxonomy branch to get. [optional] + * + * @return array An array of taxonomy maps. + * + * @since 2.5 + */ + public function getTaxonomy($branch = null) + { + // Get the taxonomy branch if available. + if ($branch !== null && isset($this->taxonomy[$branch])) + { + // Filter the input. + $branch = preg_replace('#[^\pL\pM\pN\p{Pi}\p{Pf}\'+-.,_]+#mui', ' ', $branch); + + return $this->taxonomy[$branch]; + } + + return $this->taxonomy; + } + + /** + * Method to add a taxonomy map for an item. + * + * @param string $branch The title of the taxonomy branch to add the node to. + * @param string $title The title of the taxonomy node. + * @param integer $state The published state of the taxonomy node. [optional] + * @param integer $access The access level of the taxonomy node. [optional] + * + * @return void + * + * @since 2.5 + */ + public function addTaxonomy($branch, $title, $state = 1, $access = 1) + { + // Filter the input. + $branch = preg_replace('#[^\pL\pM\pN\p{Pi}\p{Pf}\'+-.,_]+#mui', ' ', $branch); + + // Create the taxonomy node. + $node = new JObject; + $node->title = $title; + $node->state = (int) $state; + $node->access = (int) $access; + + // Add the node to the taxonomy branch. + $this->taxonomy[$branch][$node->title] = $node; + } + + /** + * Method to set the item language + * + * @return void + * + * @since 3.0 + */ + public function setLanguage() + { + if ($this->language == '') + { + $this->language = $this->defaultLanguage; + } + } +} diff --git a/Sites/pages/administrator/components/com_finder/helpers/indexer/stemmer.php b/Sites/pages/administrator/components/com_finder/helpers/indexer/stemmer.php new file mode 100644 index 00000000..3366c8f7 --- /dev/null +++ b/Sites/pages/administrator/components/com_finder/helpers/indexer/stemmer.php @@ -0,0 +1,83 @@ +clean($adapter, 'cmd'); + $path = __DIR__ . '/stemmer/' . $adapter . '.php'; + $class = 'FinderIndexerStemmer' . ucfirst($adapter); + + // Check if a stemmer exists for the adapter. + if (!file_exists($path)) + { + // Throw invalid adapter exception. + throw new Exception(JText::sprintf('COM_FINDER_INDEXER_INVALID_STEMMER', $adapter)); + } + + // Instantiate the stemmer. + JLoader::register($class, $path); + $instances[$adapter] = new $class; + + return $instances[$adapter]; + } + + /** + * Method to stem a token and return the root. + * + * @param string $token The token to stem. + * @param string $lang The language of the token. + * + * @return string The root token. + * + * @since 2.5 + */ + abstract public function stem($token, $lang); +} diff --git a/Sites/pages/administrator/components/com_finder/helpers/indexer/stemmer/fr.php b/Sites/pages/administrator/components/com_finder/helpers/indexer/stemmer/fr.php new file mode 100644 index 00000000..006abd9f --- /dev/null +++ b/Sites/pages/administrator/components/com_finder/helpers/indexer/stemmer/fr.php @@ -0,0 +1,256 @@ +cache[$lang][$token])) + { + // Stem the token. + $result = self::getStem($token); + + // Add the token to the cache. + $this->cache[$lang][$token] = $result; + } + + return $this->cache[$lang][$token]; + } + + /** + * French stemmer rules variables. + * + * @return array The rules + * + * @since 3.0 + */ + protected static function getStemRules() + { + if (self::$stemRules) + { + return self::$stemRules; + } + + $vars = array(); + + // French accented letters in ISO-8859-1 encoding + $vars['accents'] = chr(224) . chr(226) . chr(232) . chr(233) . chr(234) . chr(235) . chr(238) . chr(239) + . chr(244) . chr(251) . chr(249) . chr(231); + + // The rule patterns include all accented words for french language + $vars['rule_pattern'] = '/^([a-z' . $vars['accents'] . ']*)(\*){0,1}(\d)([a-z' . $vars['accents'] . ']*)([.|>])/'; + + // French vowels (including y) in ISO-8859-1 encoding + $vars['vowels'] = chr(97) . chr(224) . chr(226) . chr(101) . chr(232) . chr(233) . chr(234) . chr(235) + . chr(105) . chr(238) . chr(239) . chr(111) . chr(244) . chr(117) . chr(251) . chr(249) . chr(121); + + // The French rules in ISO-8859-1 encoding + $vars['rules'] = array( + 'esre1>', 'esio1>', 'siol1.', 'siof0.', 'sioe0.', 'sio3>', 'st1>', 'sf1>', 'sle1>', 'slo1>', 's' . chr(233) . '1>', chr(233) . 'tuae5.', + chr(233) . 'tuae2.', 'tnia0.', 'tniv1.', 'tni3>', 'suor1.', 'suo0.', 'sdrail5.', 'sdrai4.', 'er' . chr(232) . 'i1>', 'sesue3x>', + 'esuey5i.', 'esue2x>', 'se1>', 'er' . chr(232) . 'g3.', 'eca1>', 'esiah0.', 'esi1>', 'siss2.', 'sir2>', 'sit2>', 'egan' . chr(233) . '1.', + 'egalli6>', 'egass1.', 'egas0.', 'egat3.', 'ega3>', 'ette4>', 'ett2>', 'etio1.', 'tio' . chr(231) . '4c.', 'tio0.', 'et1>', 'eb1>', + 'snia1>', 'eniatnau8>', 'eniatn4.', 'enia1>', 'niatnio3.', 'niatg3.', 'e' . chr(233) . '1>', chr(233) . 'hcat1.', chr(233) . 'hca4.', + chr(233) . 'tila5>', chr(233) . 'tici5.', chr(233) . 'tir1.', chr(233) . 'ti3>', chr(233) . 'gan1.', chr(233) . 'ga3>', + chr(233) . 'tehc1.', chr(233) . 'te3>', chr(233) . 'it0.', chr(233) . '1>', 'eire4.', 'eirue5.', 'eio1.', 'eia1.', 'ei1>', 'eng1.', + 'xuaessi7.', 'xuae1>', 'uaes0.', 'uae3.', 'xuave2l.', 'xuav2li>', 'xua3la>', 'ela1>', 'lart2.', 'lani2>', 'la' . chr(233) . '2>', + 'siay4i.', 'siassia7.', 'siarv1*.', 'sia1>', 'tneiayo6i.', 'tneiay6i.', 'tneiassia9.', 'tneiareio7.', 'tneia5>', 'tneia4>', 'tiario4.', + 'tiarim3.', 'tiaria3.', 'tiaris3.', 'tiari5.', 'tiarve6>', 'tiare5>', 'iare4>', 'are3>', 'tiay4i.', 'tia3>', 'tnay4i.', + 'em' . chr(232) . 'iu5>', 'em' . chr(232) . 'i4>', 'tnaun3.', 'tnauqo3.', 'tnau4>', 'tnaf0.', 'tnat' . chr(233) . '2>', 'tna3>', 'tno3>', + 'zeiy4i.', 'zey3i.', 'zeire5>', 'zeird4.', 'zeirio4.', 'ze2>', 'ssiab0.', 'ssia4.', 'ssi3.', 'tnemma6>', 'tnemesuey9i.', 'tnemesue8>', + 'tnemevi7.', 'tnemessia5.', 'tnemessi8.', 'tneme5>', 'tnemia4.', 'tnem' . chr(233) . '5>', 'el2l>', 'lle3le>', 'let' . chr(244) . '0.', + 'lepp0.', 'le2>', 'srei1>', 'reit3.', 'reila2.', 'rei3>', 'ert' . chr(226) . 'e5.', 'ert' . chr(226) . chr(233) . '1.', + 'ert' . chr(226) . '4.', 'drai4.', 'erdro0.', 'erute5.', 'ruta0.', 'eruta1.', 'erutiov1.', 'erub3.', 'eruh3.', 'erul3.', 'er2r>', 'nn1>', + 'r' . chr(232) . 'i3.', 'srev0.', 'sr1>', 'rid2>', 're2>', 'xuei4.', 'esuei5.', 'lbati3.', 'lba3>', 'rueis0.', 'ruehcn4.', 'ecirta6.', + 'ruetai6.', 'rueta5.', 'rueir0.', 'rue3>', 'esseti6.', 'essere6>', 'esserd1.', 'esse4>', 'essiab1.', 'essia5.', 'essio1.', 'essi4.', + 'essal4.', 'essa1>', 'ssab1.', 'essurp1.', 'essu4.', 'essi1.', 'ssor1.', 'essor2.', 'esso1>', 'ess2>', 'tio3.', 'r' . chr(232) . 's2re.', + 'r' . chr(232) . '0e.', 'esn1.', 'eu1>', 'sua0.', 'su1>', 'utt1>', 'tu' . chr(231) . '3c.', 'u' . chr(231) . '2c.', 'ur1.', 'ehcn2>', + 'ehcu1>', 'snorr3.', 'snoru3.', 'snorua3.', 'snorv3.', 'snorio4.', 'snori5.', 'snore5>', 'snortt4>', 'snort' . chr(238) . 'a7.', 'snort3.', + 'snor4.', 'snossi6.', 'snoire6.', 'snoird5.', 'snoitai7.', 'snoita6.', 'snoits1>', 'noits0.', 'snoi4>', 'noitaci7>', 'noitai6.', 'noita5.', + 'noitu4.', 'noi3>', 'snoya0.', 'snoy4i.', 'sno' . chr(231) . 'a1.', 'sno' . chr(231) . 'r1.', 'snoe4.', 'snosiar1>', 'snola1.', 'sno3>', + 'sno1>', 'noll2.', 'tnennei4.', 'ennei2>', 'snei1>', 'sne' . chr(233) . '1>', 'enne' . chr(233) . '5e.', 'ne' . chr(233) . '3e.', 'neic0.', + 'neiv0.', 'nei3.', 'sc1.', 'sd1.', 'sg1.', 'sni1.', 'tiu0.', 'ti2.', 'sp1>', 'sna1>', 'sue1.', 'enn2>', 'nong2.', 'noss2.', 'rioe4.', + 'riot0.', 'riorc1.', 'riovec5.', 'rio3.', 'ric2.', 'ril2.', 'tnerim3.', 'tneris3>', 'tneri5.', 't' . chr(238) . 'a3.', 'riss2.', + 't' . chr(238) . '2.', 't' . chr(226) . '2>', 'ario2.', 'arim1.', 'ara1.', 'aris1.', 'ari3.', 'art1>', 'ardn2.', 'arr1.', 'arua1.', + 'aro1.', 'arv1.', 'aru1.', 'ar2.', 'rd1.', 'ud1.', 'ul1.', 'ini1.', 'rin2.', 'tnessiab3.', 'tnessia7.', 'tnessi6.', 'tnessni4.', 'sini2.', + 'sl1.', 'iard3.', 'iario3.', 'ia2>', 'io0.', 'iule2.', 'i1>', 'sid2.', 'sic2.', 'esoi4.', 'ed1.', 'ai2>', 'a1>', 'adr1.', + 'tner' . chr(232) . '5>', 'evir1.', 'evio4>', 'evi3.', 'fita4.', 'fi2>', 'enie1.', 'sare4>', 'sari4>', 'sard3.', 'sart2>', 'sa2.', + 'tnessa6>', 'tnessu6>', 'tnegna3.', 'tnegi3.', 'tneg0.', 'tneru5>', 'tnemg0.', 'tnerni4.', 'tneiv1.', 'tne3>', 'une1.', 'en1>', 'nitn2.', + 'ecnay5i.', 'ecnal1.', 'ecna4.', 'ec1>', 'nn1.', 'rit2>', 'rut2>', 'rud2.', 'ugn1>', 'eg1>', 'tuo0.', 'tul2>', 't' . chr(251) . '2>', + 'ev1>', 'v' . chr(232) . '2ve>', 'rtt1>', 'emissi6.', 'em1.', 'ehc1.', 'c' . chr(233) . 'i2c' . chr(232) . '.', 'libi2l.', 'llie1.', + 'liei4i.', 'xuev1.', 'xuey4i.', 'xueni5>', 'xuell4.', 'xuere5.', 'xue3>', 'rb' . chr(233) . '3rb' . chr(232) . '.', 'tur2.', + 'rir' . chr(233) . '4re.', 'rir2.', 'c' . chr(226) . '2ca.', 'snu1.', 'rt' . chr(238) . 'a4.', 'long2.', 'vec2.', chr(231) . '1c>', + 'ssilp3.', 'silp2.', 't' . chr(232) . 'hc2te.', 'n' . chr(232) . 'm2ne.', 'llepp1.', 'tan2.', 'rv' . chr(232) . '3rve.', + 'rv' . chr(233) . '3rve.', 'r' . chr(232) . '2re.', 'r' . chr(233) . '2re.', 't' . chr(232) . '2te.', 't' . chr(233) . '2te.', 'epp1.', + 'eya2i.', 'ya1i.', 'yo1i.', 'esu1.', 'ugi1.', 'tt1.', 'end0.' + ); + + self::$stemRules = $vars; + + return self::$stemRules; + } + + /** + * Returns the number of the first rule from the rule number + * that can be applied to the given reversed input. + * returns -1 if no rule can be applied, ie the stem has been found + * + * @param string $reversedInput The input to check in reversed order + * @param integer $ruleNumber The rule number to check + * + * @return integer Number of the first rule + * + * @since 3.0 + */ + private static function getFirstRule($reversedInput, $ruleNumber) + { + $vars = static::getStemRules(); + + $nb_rules = count($vars['rules']); + + for ($i = $ruleNumber; $i < $nb_rules; $i++) + { + // Gets the letters from the current rule + $rule = $vars['rules'][$i]; + $rule = preg_replace($vars['rule_pattern'], "\\1", $rule); + + if (strncasecmp(utf8_decode($rule), $reversedInput, strlen(utf8_decode($rule))) == 0) + { + return $i; + } + } + + return -1; + } + + /** + * Check the acceptability of a stem for French language + * + * @param string $reversedStem The stem to check in reverse form + * + * @return boolean True if stem is acceptable + * + * @since 3.0 + */ + private static function check($reversedStem) + { + $vars = static::getStemRules(); + + if (preg_match('/[' . $vars['vowels'] . ']$/', utf8_encode($reversedStem))) + { + // If the form starts with a vowel then at least two letters must remain after stemming (e.g.: "etaient" --> "et") + return (strlen($reversedStem) > 2); + } + else + { + // If the reversed stem starts with a consonant then at least two letters must remain after stemming + if (strlen($reversedStem) <= 2) + { + return false; + } + + // And at least one of these must be a vowel or "y" + return preg_match('/[' . $vars['vowels'] . ']/', utf8_encode($reversedStem)); + } + } + + /** + * Paice/Husk stemmer which returns a stem for the given $input + * + * @param string $input The word for which we want the stem in UTF-8 + * + * @return string The stem + * + * @since 3.0 + */ + private static function getStem($input) + { + $vars = static::getStemRules(); + + $reversed_input = strrev(utf8_decode($input)); + $rule_number = 0; + + // This loop goes through the rules' array until it finds an ending one (ending by '.') or the last one ('end0.') + while (true) + { + $rule_number = self::getFirstRule($reversed_input, $rule_number); + + if ($rule_number === -1) + { + // No other rule can be applied => the stem has been found + break; + } + + $rule = $vars['rules'][$rule_number]; + preg_match($vars['rule_pattern'], $rule, $matches); + + $reversed_stem = utf8_decode($matches[4]) . substr($reversed_input, $matches[3]); + + if (self::check($reversed_stem)) + { + $reversed_input = $reversed_stem; + + if ($matches[5] === '.') + { + break; + } + } + else + { + // Go to another rule + $rule_number++; + } + } + + return utf8_encode(strrev($reversed_input)); + } +} diff --git a/Sites/pages/administrator/components/com_finder/helpers/indexer/stemmer/porter_en.php b/Sites/pages/administrator/components/com_finder/helpers/indexer/stemmer/porter_en.php new file mode 100644 index 00000000..ca46bd6e --- /dev/null +++ b/Sites/pages/administrator/components/com_finder/helpers/indexer/stemmer/porter_en.php @@ -0,0 +1,450 @@ +cache[$lang][$token])) + { + // Stem the token. + $result = $token; + $result = self::step1ab($result); + $result = self::step1c($result); + $result = self::step2($result); + $result = self::step3($result); + $result = self::step4($result); + $result = self::step5($result); + + // Add the token to the cache. + $this->cache[$lang][$token] = $result; + } + + return $this->cache[$lang][$token]; + } + + /** + * Step 1 + * + * @param string $word The token to stem. + * + * @return string + * + * @since 2.5 + */ + private static function step1ab($word) + { + // Part a + if (substr($word, -1) === 's') + { + self::replace($word, 'sses', 'ss') + || self::replace($word, 'ies', 'i') + || self::replace($word, 'ss', 'ss') + || self::replace($word, 's', ''); + } + + // Part b + if (substr($word, -2, 1) !== 'e' || !self::replace($word, 'eed', 'ee', 0)) + { + // First rule + $v = self::$regex_vowel; + + // Words ending with ing and ed + // Note use of && and OR, for precedence reasons + if (preg_match("#$v+#", substr($word, 0, -3)) && self::replace($word, 'ing', '') + || preg_match("#$v+#", substr($word, 0, -2)) && self::replace($word, 'ed', '')) + { + // If one of above two test successful + if (!self::replace($word, 'at', 'ate') && !self::replace($word, 'bl', 'ble') && !self::replace($word, 'iz', 'ize')) + { + // Double consonant ending + $wordSubStr = substr($word, -2); + + if ($wordSubStr !== 'll' && $wordSubStr !== 'ss' && $wordSubStr !== 'zz' && self::doubleConsonant($word)) + { + $word = substr($word, 0, -1); + } + elseif (self::m($word) === 1 && self::cvc($word)) + { + $word .= 'e'; + } + } + } + } + + return $word; + } + + /** + * Step 1c + * + * @param string $word The token to stem. + * + * @return string + * + * @since 2.5 + */ + private static function step1c($word) + { + $v = self::$regex_vowel; + + if (substr($word, -1) === 'y' && preg_match("#$v+#", substr($word, 0, -1))) + { + self::replace($word, 'y', 'i'); + } + + return $word; + } + + /** + * Step 2 + * + * @param string $word The token to stem. + * + * @return string + * + * @since 2.5 + */ + private static function step2($word) + { + switch (substr($word, -2, 1)) + { + case 'a': + self::replace($word, 'ational', 'ate', 0) + || self::replace($word, 'tional', 'tion', 0); + break; + case 'c': + self::replace($word, 'enci', 'ence', 0) + || self::replace($word, 'anci', 'ance', 0); + break; + case 'e': + self::replace($word, 'izer', 'ize', 0); + break; + case 'g': + self::replace($word, 'logi', 'log', 0); + break; + case 'l': + self::replace($word, 'entli', 'ent', 0) + || self::replace($word, 'ousli', 'ous', 0) + || self::replace($word, 'alli', 'al', 0) + || self::replace($word, 'bli', 'ble', 0) + || self::replace($word, 'eli', 'e', 0); + break; + case 'o': + self::replace($word, 'ization', 'ize', 0) + || self::replace($word, 'ation', 'ate', 0) + || self::replace($word, 'ator', 'ate', 0); + break; + case 's': + self::replace($word, 'iveness', 'ive', 0) + || self::replace($word, 'fulness', 'ful', 0) + || self::replace($word, 'ousness', 'ous', 0) + || self::replace($word, 'alism', 'al', 0); + break; + case 't': + self::replace($word, 'biliti', 'ble', 0) + || self::replace($word, 'aliti', 'al', 0) + || self::replace($word, 'iviti', 'ive', 0); + break; + } + + return $word; + } + + /** + * Step 3 + * + * @param string $word The token to stem. + * + * @return string + * + * @since 2.5 + */ + private static function step3($word) + { + switch (substr($word, -2, 1)) + { + case 'a': + self::replace($word, 'ical', 'ic', 0); + break; + case 's': + self::replace($word, 'ness', '', 0); + break; + case 't': + self::replace($word, 'icate', 'ic', 0) + || self::replace($word, 'iciti', 'ic', 0); + break; + case 'u': + self::replace($word, 'ful', '', 0); + break; + case 'v': + self::replace($word, 'ative', '', 0); + break; + case 'z': + self::replace($word, 'alize', 'al', 0); + break; + } + + return $word; + } + + /** + * Step 4 + * + * @param string $word The token to stem. + * + * @return string + * + * @since 2.5 + */ + private static function step4($word) + { + switch (substr($word, -2, 1)) + { + case 'a': + self::replace($word, 'al', '', 1); + break; + case 'c': + self::replace($word, 'ance', '', 1) + || self::replace($word, 'ence', '', 1); + break; + case 'e': + self::replace($word, 'er', '', 1); + break; + case 'i': + self::replace($word, 'ic', '', 1); + break; + case 'l': + self::replace($word, 'able', '', 1) + || self::replace($word, 'ible', '', 1); + break; + case 'n': + self::replace($word, 'ant', '', 1) + || self::replace($word, 'ement', '', 1) + || self::replace($word, 'ment', '', 1) + || self::replace($word, 'ent', '', 1); + break; + case 'o': + $wordSubStr = substr($word, -4); + + if ($wordSubStr === 'tion' || $wordSubStr === 'sion') + { + self::replace($word, 'ion', '', 1); + } + else + { + self::replace($word, 'ou', '', 1); + } + break; + case 's': + self::replace($word, 'ism', '', 1); + break; + case 't': + self::replace($word, 'ate', '', 1) + || self::replace($word, 'iti', '', 1); + break; + case 'u': + self::replace($word, 'ous', '', 1); + break; + case 'v': + self::replace($word, 'ive', '', 1); + break; + case 'z': + self::replace($word, 'ize', '', 1); + break; + } + + return $word; + } + + /** + * Step 5 + * + * @param string $word The token to stem. + * + * @return string + * + * @since 2.5 + */ + private static function step5($word) + { + // Part a + if (substr($word, -1) === 'e') + { + if (self::m(substr($word, 0, -1)) > 1) + { + self::replace($word, 'e', ''); + } + elseif (self::m(substr($word, 0, -1)) === 1) + { + if (!self::cvc(substr($word, 0, -1))) + { + self::replace($word, 'e', ''); + } + } + } + + // Part b + if (self::m($word) > 1 && self::doubleConsonant($word) && substr($word, -1) === 'l') + { + $word = substr($word, 0, -1); + } + + return $word; + } + + /** + * Replaces the first string with the second, at the end of the string. If third + * arg is given, then the preceding string must match that m count at least. + * + * @param string $str String to check + * @param string $check Ending to check for + * @param string $repl Replacement string + * @param integer $m Optional minimum number of m() to meet + * + * @return boolean Whether the $check string was at the end + * of the $str string. True does not necessarily mean + * that it was replaced. + * + * @since 2.5 + */ + private static function replace(&$str, $check, $repl, $m = null) + { + $len = 0 - strlen($check); + + if (substr($str, $len) === $check) + { + $substr = substr($str, 0, $len); + + if ($m === null || self::m($substr) > $m) + { + $str = $substr . $repl; + } + + return true; + } + + return false; + } + + /** + * m() measures the number of consonant sequences in $str. if c is + * a consonant sequence and v a vowel sequence, and <..> indicates arbitrary + * presence, + * + * gives 0 + * vc gives 1 + * vcvc gives 2 + * vcvcvc gives 3 + * + * @param string $str The string to return the m count for + * + * @return integer The m count + * + * @since 2.5 + */ + private static function m($str) + { + $c = self::$regex_consonant; + $v = self::$regex_vowel; + + $str = preg_replace("#^$c+#", '', $str); + $str = preg_replace("#$v+$#", '', $str); + + preg_match_all("#($v+$c+)#", $str, $matches); + + return count($matches[1]); + } + + /** + * Returns true/false as to whether the given string contains two + * of the same consonant next to each other at the end of the string. + * + * @param string $str String to check + * + * @return boolean Result + * + * @since 2.5 + */ + private static function doubleConsonant($str) + { + $c = self::$regex_consonant; + + return preg_match("#$c{2}$#", $str, $matches) && $matches[0][0] === $matches[0][1]; + } + + /** + * Checks for ending CVC sequence where second C is not W, X or Y + * + * @param string $str String to check + * + * @return boolean Result + * + * @since 2.5 + */ + private static function cvc($str) + { + $c = self::$regex_consonant; + $v = self::$regex_vowel; + + return preg_match("#($c$v$c)$#", $str, $matches) && strlen($matches[1]) === 3 && $matches[1][2] !== 'w' && $matches[1][2] !== 'x' + && $matches[1][2] !== 'y'; + } +} diff --git a/Sites/pages/administrator/components/com_finder/helpers/indexer/stemmer/snowball.php b/Sites/pages/administrator/components/com_finder/helpers/indexer/stemmer/snowball.php new file mode 100644 index 00000000..19be19fc --- /dev/null +++ b/Sites/pages/administrator/components/com_finder/helpers/indexer/stemmer/snowball.php @@ -0,0 +1,133 @@ +sef) ? $languages[0]->sef : '*'; + $lang = $defaultLang; + } + + // Stem the token if it is not in the cache. + if (!isset($this->cache[$lang][$token])) + { + // Get the stem function from the language string. + switch ($lang) + { + // Danish stemmer. + case 'da': + $function = 'stem_danish'; + break; + + // German stemmer. + case 'de': + $function = 'stem_german'; + break; + + // English stemmer. + default: + case 'en': + $function = 'stem_english'; + break; + + // Spanish stemmer. + case 'es': + $function = 'stem_spanish'; + break; + + // Finnish stemmer. + case 'fi': + $function = 'stem_finnish'; + break; + + // French stemmer. + case 'fr': + $function = 'stem_french'; + break; + + // Hungarian stemmer. + case 'hu': + $function = 'stem_hungarian'; + break; + + // Italian stemmer. + case 'it': + $function = 'stem_italian'; + break; + + // Norwegian stemmer. + case 'nb': + $function = 'stem_norwegian'; + break; + + // Dutch stemmer. + case 'nl': + $function = 'stem_dutch'; + break; + + // Portuguese stemmer. + case 'pt': + $function = 'stem_portuguese'; + break; + + // Romanian stemmer. + case 'ro': + $function = 'stem_romanian'; + break; + + // Russian stemmer. + case 'ru': + $function = 'stem_russian_unicode'; + break; + + // Swedish stemmer. + case 'sv': + $function = 'stem_swedish'; + break; + + // Turkish stemmer. + case 'tr': + $function = 'stem_turkish_unicode'; + break; + } + + // Stem the word if the stemmer method exists. + $this->cache[$lang][$token] = function_exists($function) ? $function($token) : $token; + } + + return $this->cache[$lang][$token]; + } +} diff --git a/Sites/pages/administrator/components/com_finder/helpers/indexer/taxonomy.php b/Sites/pages/administrator/components/com_finder/helpers/indexer/taxonomy.php new file mode 100644 index 00000000..e27329f3 --- /dev/null +++ b/Sites/pages/administrator/components/com_finder/helpers/indexer/taxonomy.php @@ -0,0 +1,382 @@ +id; + } + + // Check to see if the branch is in the table. + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->select('*') + ->from($db->quoteName('#__finder_taxonomy')) + ->where($db->quoteName('parent_id') . ' = 1') + ->where($db->quoteName('title') . ' = ' . $db->quote($title)); + $db->setQuery($query); + + // Get the result. + $result = $db->loadObject(); + + // Check if the database matches the input data. + if ((bool) $result && $result->state == $state && $result->access == $access) + { + // The data matches, add the item to the cache. + static::$branches[$title] = $result; + + return static::$branches[$title]->id; + } + + /* + * The database did not match the input. This could be because the + * state has changed or because the branch does not exist. Let's figure + * out which case is true and deal with it. + */ + $branch = new JObject; + + if (empty($result)) + { + // Prepare the branch object. + $branch->parent_id = 1; + $branch->title = $title; + $branch->state = (int) $state; + $branch->access = (int) $access; + } + else + { + // Prepare the branch object. + $branch->id = (int) $result->id; + $branch->parent_id = (int) $result->parent_id; + $branch->title = $result->title; + $branch->state = (int) $result->title; + $branch->access = (int) $result->access; + $branch->ordering = (int) $result->ordering; + } + + // Store the branch. + static::storeNode($branch); + + // Add the branch to the cache. + static::$branches[$title] = $branch; + + return static::$branches[$title]->id; + } + + /** + * Method to add a node to the taxonomy tree. + * + * @param string $branch The title of the branch to store the node in. + * @param string $title The title of the node. + * @param integer $state The published state of the node. [optional] + * @param integer $access The access state of the node. [optional] + * + * @return integer The id of the node. + * + * @since 2.5 + * @throws Exception on database error. + */ + public static function addNode($branch, $title, $state = 1, $access = 1) + { + // Check to see if the node is in the cache. + if (isset(static::$nodes[$branch][$title])) + { + return static::$nodes[$branch][$title]->id; + } + + // Get the branch id, insert it if it does not exist. + $branchId = static::addBranch($branch); + + // Check to see if the node is in the table. + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->select('*') + ->from($db->quoteName('#__finder_taxonomy')) + ->where($db->quoteName('parent_id') . ' = ' . $db->quote($branchId)) + ->where($db->quoteName('title') . ' = ' . $db->quote($title)); + $db->setQuery($query); + + // Get the result. + $result = $db->loadObject(); + + // Check if the database matches the input data. + if ((bool) $result && $result->state == $state && $result->access == $access) + { + // The data matches, add the item to the cache. + static::$nodes[$branch][$title] = $result; + + return static::$nodes[$branch][$title]->id; + } + + /* + * The database did not match the input. This could be because the + * state has changed or because the node does not exist. Let's figure + * out which case is true and deal with it. + */ + $node = new JObject; + + if (empty($result)) + { + // Prepare the node object. + $node->parent_id = (int) $branchId; + $node->title = $title; + $node->state = (int) $state; + $node->access = (int) $access; + } + else + { + // Prepare the node object. + $node->id = (int) $result->id; + $node->parent_id = (int) $result->parent_id; + $node->title = $result->title; + $node->state = (int) $result->title; + $node->access = (int) $result->access; + $node->ordering = (int) $result->ordering; + } + + // Store the node. + static::storeNode($node); + + // Add the node to the cache. + static::$nodes[$branch][$title] = $node; + + return static::$nodes[$branch][$title]->id; + } + + /** + * Method to add a map entry between a link and a taxonomy node. + * + * @param integer $linkId The link to map to. + * @param integer $nodeId The node to map to. + * + * @return boolean True on success. + * + * @since 2.5 + * @throws Exception on database error. + */ + public static function addMap($linkId, $nodeId) + { + // Insert the map. + $db = JFactory::getDbo(); + + $query = $db->getQuery(true) + ->select($db->quoteName('link_id')) + ->from($db->quoteName('#__finder_taxonomy_map')) + ->where($db->quoteName('link_id') . ' = ' . (int) $linkId) + ->where($db->quoteName('node_id') . ' = ' . (int) $nodeId); + $db->setQuery($query); + $db->execute(); + $id = (int) $db->loadResult(); + + $map = new JObject; + $map->link_id = (int) $linkId; + $map->node_id = (int) $nodeId; + + if ($id) + { + $db->updateObject('#__finder_taxonomy_map', $map, array('link_id', 'node_id')); + } + else + { + $db->insertObject('#__finder_taxonomy_map', $map); + } + + return true; + } + + /** + * Method to get the title of all taxonomy branches. + * + * @return array An array of branch titles. + * + * @since 2.5 + * @throws Exception on database error. + */ + public static function getBranchTitles() + { + $db = JFactory::getDbo(); + + // Set user variables + $groups = implode(',', JFactory::getUser()->getAuthorisedViewLevels()); + + // Create a query to get the taxonomy branch titles. + $query = $db->getQuery(true) + ->select($db->quoteName('title')) + ->from($db->quoteName('#__finder_taxonomy')) + ->where($db->quoteName('parent_id') . ' = 1') + ->where($db->quoteName('state') . ' = 1') + ->where($db->quoteName('access') . ' IN (' . $groups . ')'); + + // Get the branch titles. + $db->setQuery($query); + + return $db->loadColumn(); + } + + /** + * Method to find a taxonomy node in a branch. + * + * @param string $branch The branch to search. + * @param string $title The title of the node. + * + * @return mixed Integer id on success, null on no match. + * + * @since 2.5 + * @throws Exception on database error. + */ + public static function getNodeByTitle($branch, $title) + { + $db = JFactory::getDbo(); + + // Set user variables + $groups = implode(',', JFactory::getUser()->getAuthorisedViewLevels()); + + // Create a query to get the node. + $query = $db->getQuery(true) + ->select('t1.*') + ->from($db->quoteName('#__finder_taxonomy') . ' AS t1') + ->join('INNER', $db->quoteName('#__finder_taxonomy') . ' AS t2 ON t2.id = t1.parent_id') + ->where('t1.access IN (' . $groups . ')') + ->where('t1.state = 1') + ->where('t1.title LIKE ' . $db->quote($db->escape($title) . '%')) + ->where('t2.access IN (' . $groups . ')') + ->where('t2.state = 1') + ->where('t2.title = ' . $db->quote($branch)); + + // Get the node. + $db->setQuery($query, 0, 1); + + return $db->loadObject(); + } + + /** + * Method to remove map entries for a link. + * + * @param integer $linkId The link to remove. + * + * @return boolean True on success. + * + * @since 2.5 + * @throws Exception on database error. + */ + public static function removeMaps($linkId) + { + // Delete the maps. + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->delete($db->quoteName('#__finder_taxonomy_map')) + ->where($db->quoteName('link_id') . ' = ' . (int) $linkId); + $db->setQuery($query); + $db->execute(); + + return true; + } + + /** + * Method to remove orphaned taxonomy nodes and branches. + * + * @return integer The number of deleted rows. + * + * @since 2.5 + * @throws Exception on database error. + */ + public static function removeOrphanNodes() + { + // Delete all orphaned nodes. + $db = JFactory::getDbo(); + $query = $db->getQuery(true); + $subquery = $db->getQuery(true); + $subquery1 = $db->getQuery(true); + + $subquery1->select($db->quoteName('t.id')) + ->from($db->quoteName('#__finder_taxonomy', 't')) + ->join('LEFT', $db->quoteName('#__finder_taxonomy_map', 'm') . ' ON ' . $db->quoteName('m.node_id') . '=' . $db->quoteName('t.id')) + ->where($db->quoteName('t.parent_id') . ' > 1 ') + ->where($db->quoteName('m.link_id') . ' IS NULL'); + + $subquery->select($db->quoteName('id')) + ->from('(' . $subquery1 . ') temp'); + + $query->delete($db->quoteName('#__finder_taxonomy')) + ->where($db->quoteName('id') . ' IN (' . $subquery . ')'); + + $db->setQuery($query); + $db->execute(); + + return $db->getAffectedRows(); + } + + /** + * Method to store a node to the database. This method will accept either a branch or a node. + * + * @param object $item The item to store. + * + * @return boolean True on success. + * + * @since 2.5 + * @throws Exception on database error. + */ + protected static function storeNode($item) + { + $db = JFactory::getDbo(); + + // Check if we are updating or inserting the item. + if (empty($item->id)) + { + // Insert the item. + $db->insertObject('#__finder_taxonomy', $item, 'id'); + } + else + { + // Update the item. + $db->updateObject('#__finder_taxonomy', $item, 'id'); + } + + return true; + } +} diff --git a/Sites/pages/administrator/components/com_finder/helpers/indexer/token.php b/Sites/pages/administrator/components/com_finder/helpers/indexer/token.php new file mode 100644 index 00000000..7351605a --- /dev/null +++ b/Sites/pages/administrator/components/com_finder/helpers/indexer/token.php @@ -0,0 +1,171 @@ +language = $lang; + + // Tokens can be a single word or an array of words representing a phrase. + if (is_array($term)) + { + // Populate the token instance. + $this->term = implode($spacer, $term); + $this->stem = implode($spacer, array_map(array('FinderIndexerHelper', 'stem'), $term, array($lang))); + $this->numeric = false; + $this->common = false; + $this->phrase = true; + $this->length = StringHelper::strlen($this->term); + + /* + * Calculate the weight of the token. + * + * 1. Length of the token up to 30 and divide by 30, add 1. + * 2. Round weight to 4 decimal points. + */ + $this->weight = (($this->length >= 30 ? 30 : $this->length) / 30) + 1; + $this->weight = round($this->weight, 4); + } + else + { + // Populate the token instance. + $this->term = $term; + $this->stem = FinderIndexerHelper::stem($this->term, $lang); + $this->numeric = (is_numeric($this->term) || (bool) preg_match('#^[0-9,.\-\+]+$#', $this->term)); + $this->common = $this->numeric ? false : FinderIndexerHelper::isCommon($this->term, $lang); + $this->phrase = false; + $this->length = StringHelper::strlen($this->term); + + /* + * Calculate the weight of the token. + * + * 1. Length of the token up to 15 and divide by 15. + * 2. If common term, divide weight by 8. + * 3. If numeric, multiply weight by 1.5. + * 4. Round weight to 4 decimal points. + */ + $this->weight = ($this->length >= 15 ? 15 : $this->length) / 15; + $this->weight = $this->common === true ? $this->weight / 8 : $this->weight; + $this->weight = $this->numeric === true ? $this->weight * 1.5 : $this->weight; + $this->weight = round($this->weight, 4); + } + } +} diff --git a/Sites/pages/administrator/components/com_finder/helpers/language.php b/Sites/pages/administrator/components/com_finder/helpers/language.php new file mode 100644 index 00000000..3d5f29f7 --- /dev/null +++ b/Sites/pages/administrator/components/com_finder/helpers/language.php @@ -0,0 +1,144 @@ +title; + } + } + + return $title; + } + + /** + * Method to load Smart Search component language file. + * + * @return void + * + * @since 2.5 + */ + public static function loadComponentLanguage() + { + JFactory::getLanguage()->load('com_finder', JPATH_SITE); + } + + /** + * Method to load Smart Search plugin language files. + * + * @return void + * + * @since 2.5 + */ + public static function loadPluginLanguage() + { + static $loaded = false; + + // If already loaded, don't load again. + if ($loaded) + { + return; + } + + $loaded = true; + + // Get array of all the enabled Smart Search plugin names. + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->select(array($db->qn('name'), $db->qn('element'))) + ->from($db->quoteName('#__extensions')) + ->where($db->quoteName('type') . ' = ' . $db->quote('plugin')) + ->where($db->quoteName('folder') . ' = ' . $db->quote('finder')) + ->where($db->quoteName('enabled') . ' = 1'); + $db->setQuery($query); + $plugins = $db->loadObjectList(); + + if (empty($plugins)) + { + return; + } + + // Load generic language strings. + $lang = JFactory::getLanguage(); + $lang->load('plg_content_finder', JPATH_ADMINISTRATOR); + + // Load language file for each plugin. + foreach ($plugins as $plugin) + { + $lang->load($plugin->name, JPATH_ADMINISTRATOR) + || $lang->load($plugin->name, JPATH_PLUGINS . '/finder/' . $plugin->element); + } + } +} diff --git a/Sites/pages/administrator/components/com_finder/models/fields/branches.php b/Sites/pages/administrator/components/com_finder/models/fields/branches.php new file mode 100644 index 00000000..f4880e58 --- /dev/null +++ b/Sites/pages/administrator/components/com_finder/models/fields/branches.php @@ -0,0 +1,40 @@ +getQuery(true); + $levelQuery->select('title AS branch_title, 1 as level') + ->select($db->quoteName('id')) + ->from($db->quoteName('#__finder_taxonomy')) + ->where($db->quoteName('parent_id') . ' = 1'); + $levelQuery2 = $db->getQuery(true); + $levelQuery2->select('b.title AS branch_title, 2 as level') + ->select($db->quoteName('a.id')) + ->from($db->quoteName('#__finder_taxonomy', 'a')) + ->join('LEFT', $db->quoteName('#__finder_taxonomy', 'b') . ' ON ' . $db->qn('a.parent_id') . ' = ' . $db->qn('b.id')) + ->where($db->quoteName('a.parent_id') . ' NOT IN (0, 1)'); + + $levelQuery->union($levelQuery2); + + // Main query. + $query = $db->getQuery(true) + ->select($db->quoteName('a.title', 'text')) + ->select($db->quoteName('a.id', 'value')) + ->select($db->quoteName('d.level')) + ->from($db->quoteName('#__finder_taxonomy', 'a')) + ->join('LEFT', '(' . $levelQuery . ') AS d ON ' . $db->qn('d.id') . ' = ' . $db->qn('a.id')) + ->where($db->quoteName('a.parent_id') . ' <> 0') + ->order('d.branch_title ASC, d.level ASC, a.title ASC'); + + $db->setQuery($query); + + try + { + $contentMap = $db->loadObjectList(); + } + catch (RuntimeException $e) + { + return; + } + + // Build the grouped list array. + if ($contentMap) + { + $lang = JFactory::getLanguage(); + + foreach ($contentMap as $branch) + { + if ((int) $branch->level === 1) + { + $name = $branch->text; + } + else + { + $levelPrefix = str_repeat('- ', max(0, $branch->level - 1)); + + if (trim($name, '**') === 'Language') + { + $text = FinderHelperLanguage::branchLanguageTitle($branch->text); + } + else + { + $key = FinderHelperLanguage::branchSingular($branch->text); + $text = $lang->hasKey($key) ? JText::_($key) : $branch->text; + } + + // Initialize the group if necessary. + if (!isset($groups[$name])) + { + $groups[$name] = array(); + } + + $groups[$name][] = JHtml::_('select.option', $branch->value, $levelPrefix . $text); + } + } + } + + // Merge any additional groups in the XML definition. + $groups = array_merge(parent::getGroups(), $groups); + + return $groups; + } +} diff --git a/Sites/pages/administrator/components/com_finder/models/fields/contenttypes.php b/Sites/pages/administrator/components/com_finder/models/fields/contenttypes.php new file mode 100644 index 00000000..ca31d0f8 --- /dev/null +++ b/Sites/pages/administrator/components/com_finder/models/fields/contenttypes.php @@ -0,0 +1,84 @@ +getQuery(true) + ->select($db->quoteName('id', 'value')) + ->select($db->quoteName('title', 'text')) + ->from($db->quoteName('#__finder_types')); + + // Get the options. + $db->setQuery($query); + + try + { + $contentTypes = $db->loadObjectList(); + } + catch (RuntimeException $e) + { + JError::raiseWarning(500, $db->getMessage()); + } + + // Translate. + foreach ($contentTypes as $contentType) + { + $key = FinderHelperLanguage::branchSingular($contentType->text); + $contentType->translatedText = $lang->hasKey($key) ? JText::_($key) : $contentType->text; + } + + // Order by title. + $contentTypes = ArrayHelper::sortObjects($contentTypes, 'translatedText', 1, true, true); + + // Convert the values to options. + foreach ($contentTypes as $contentType) + { + $options[] = JHtml::_('select.option', $contentType->value, $contentType->translatedText); + } + + // Merge any additional options in the XML definition. + $options = array_merge(parent::getOptions(), $options); + + return $options; + } +} diff --git a/Sites/pages/administrator/components/com_finder/models/fields/directories.php b/Sites/pages/administrator/components/com_finder/models/fields/directories.php new file mode 100644 index 00000000..a2d0b7bb --- /dev/null +++ b/Sites/pages/administrator/components/com_finder/models/fields/directories.php @@ -0,0 +1,94 @@ +get('log_path'), + JFactory::getApplication()->get('tmp_path') + ); + + // Get the base directories. + jimport('joomla.filesystem.folder'); + $dirs = JFolder::folders(JPATH_SITE, '.', false, true); + + // Iterate through the base directories and find the subdirectories. + foreach ($dirs as $dir) + { + // Check if the directory should be excluded. + if (in_array($dir, $exclude)) + { + continue; + } + + // Get the child directories. + $return = JFolder::folders($dir, '.', true, true); + + // Merge the directories. + if (is_array($return)) + { + $values[] = $dir; + $values = array_merge($values, $return); + } + } + + // Convert the values to options. + foreach ($values as $value) + { + $options[] = JHtml::_('select.option', str_replace(JPATH_SITE . '/', '', $value), str_replace(JPATH_SITE . '/', '', $values)); + } + + // Add a null option. + array_unshift($options, JHtml::_('select.option', '', '- ' . JText::_('JNONE') . ' -')); + + return $options; + } +} diff --git a/Sites/pages/administrator/components/com_finder/models/fields/searchfilter.php b/Sites/pages/administrator/components/com_finder/models/fields/searchfilter.php new file mode 100644 index 00000000..90566d2c --- /dev/null +++ b/Sites/pages/administrator/components/com_finder/models/fields/searchfilter.php @@ -0,0 +1,52 @@ +getQuery(true) + ->select('f.title AS text, f.filter_id AS value') + ->from($db->quoteName('#__finder_filters') . ' AS f') + ->where('f.state = 1') + ->order('f.title ASC'); + $db->setQuery($query); + $options = $db->loadObjectList(); + + array_unshift($options, JHtml::_('select.option', '', JText::_('COM_FINDER_SELECT_SEARCH_FILTER'), 'value', 'text')); + + return $options; + } +} diff --git a/Sites/pages/administrator/components/com_finder/models/filter.php b/Sites/pages/administrator/components/com_finder/models/filter.php new file mode 100644 index 00000000..a9e70dfa --- /dev/null +++ b/Sites/pages/administrator/components/com_finder/models/filter.php @@ -0,0 +1,173 @@ +getState('filter.id'); + + // Get a FinderTableFilter instance. + $filter = $this->getTable(); + + // Attempt to load the row. + $return = $filter->load($filter_id); + + // Check for a database error. + if ($return === false && $filter->getError()) + { + $this->setError($filter->getError()); + + return false; + } + + // Process the filter data. + if (!empty($filter->data)) + { + $filter->data = explode(',', $filter->data); + } + elseif (empty($filter->data)) + { + $filter->data = array(); + } + + // Check for a database error. + if ($this->_db->getErrorNum()) + { + $this->setError($this->_db->getErrorMsg()); + + return false; + } + + return $filter; + } + + /** + * Method to get the record form. + * + * @param array $data Data for the form. [optional] + * @param boolean $loadData True if the form is to load its own data (default case), false if not. [optional] + * + * @return JForm|boolean A JForm object on success, false on failure + * + * @since 2.5 + */ + public function getForm($data = array(), $loadData = true) + { + // Get the form. + $form = $this->loadForm('com_finder.filter', 'filter', array('control' => 'jform', 'load_data' => $loadData)); + + if (empty($form)) + { + return false; + } + + return $form; + } + + /** + * Returns a JTable object, always creating it. + * + * @param string $type The table type to instantiate. [optional] + * @param string $prefix A prefix for the table class name. [optional] + * @param array $config Configuration array for model. [optional] + * + * @return JTable A database object + * + * @since 2.5 + */ + public function getTable($type = 'Filter', $prefix = 'FinderTable', $config = array()) + { + return JTable::getInstance($type, $prefix, $config); + } + + /** + * Method to get the data that should be injected in the form. + * + * @return mixed The data for the form. + * + * @since 2.5 + */ + protected function loadFormData() + { + // Check the session for previously entered form data. + $data = JFactory::getApplication()->getUserState('com_finder.edit.filter.data', array()); + + if (empty($data)) + { + $data = $this->getItem(); + } + + $this->preprocessData('com_finder.filter', $data); + + return $data; + } + + /** + * Method to get the total indexed items + * + * @return number the number of indexed items + * + * @since 3.5 + */ + public function getTotal() + { + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->select('MAX(link_id)') + ->from('#__finder_links'); + + return $db->setQuery($query)->loadResult(); + } +} diff --git a/Sites/pages/administrator/components/com_finder/models/filters.php b/Sites/pages/administrator/components/com_finder/models/filters.php new file mode 100644 index 00000000..16c69213 --- /dev/null +++ b/Sites/pages/administrator/components/com_finder/models/filters.php @@ -0,0 +1,134 @@ +getDbo(); + $query = $db->getQuery(true); + + // Select all fields from the table. + $query->select('a.*') + ->from($db->quoteName('#__finder_filters', 'a')); + + // Join over the users for the checked out user. + $query->select($db->quoteName('uc.name', 'editor')) + ->join('LEFT', $db->quoteName('#__users', 'uc') . ' ON ' . $db->quoteName('uc.id') . ' = ' . $db->quoteName('a.checked_out')); + + // Join over the users for the author. + $query->select($db->quoteName('ua.name', 'user_name')) + ->join('LEFT', $db->quoteName('#__users', 'ua') . ' ON ' . $db->quoteName('ua.id') . ' = ' . $db->quoteName('a.created_by')); + + // Check for a search filter. + if ($search = $this->getState('filter.search')) + { + $search = $db->quote('%' . str_replace(' ', '%', $db->escape(trim($search), true) . '%')); + $query->where($db->quoteName('a.title') . ' LIKE ' . $search); + } + + // If the model is set to check item state, add to the query. + $state = $this->getState('filter.state'); + + if (is_numeric($state)) + { + $query->where($db->quoteName('a.state') . ' = ' . (int) $state); + } + + // Add the list ordering clause. + $query->order($db->escape($this->getState('list.ordering', 'a.title') . ' ' . $db->escape($this->getState('list.direction', 'ASC')))); + + return $query; + } + + /** + * Method to get a store id based on model configuration state. + * + * This is necessary because the model is used by the component and + * different modules that might need different sets of data or different + * ordering requirements. + * + * @param string $id A prefix for the store id. [optional] + * + * @return string A store id. + * + * @since 2.5 + */ + protected function getStoreId($id = '') + { + // Compile the store id. + $id .= ':' . $this->getState('filter.search'); + $id .= ':' . $this->getState('filter.state'); + + return parent::getStoreId($id); + } + + /** + * Method to auto-populate the model state. Calling getState in this method will result in recursion. + * + * @param string $ordering An optional ordering field. [optional] + * @param string $direction An optional direction. [optional] + * + * @return void + * + * @since 2.5 + */ + protected function populateState($ordering = 'a.title', $direction = 'asc') + { + // Load the filter state. + $this->setState('filter.search', $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search', '', 'string')); + $this->setState('filter.state', $this->getUserStateFromRequest($this->context . '.filter.state', 'filter_state', '', 'cmd')); + + // Load the parameters. + $params = JComponentHelper::getParams('com_finder'); + $this->setState('params', $params); + + // List state information. + parent::populateState($ordering, $direction); + } +} diff --git a/Sites/pages/administrator/components/com_finder/models/forms/filter.xml b/Sites/pages/administrator/components/com_finder/models/forms/filter.xml new file mode 100644 index 00000000..f281aa88 --- /dev/null +++ b/Sites/pages/administrator/components/com_finder/models/forms/filter.xml @@ -0,0 +1,173 @@ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/Sites/pages/administrator/components/com_finder/models/forms/filter_filters.xml b/Sites/pages/administrator/components/com_finder/models/forms/filter_filters.xml new file mode 100644 index 00000000..d9304026 --- /dev/null +++ b/Sites/pages/administrator/components/com_finder/models/forms/filter_filters.xml @@ -0,0 +1,56 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/Sites/pages/administrator/components/com_finder/models/forms/filter_index.xml b/Sites/pages/administrator/components/com_finder/models/forms/filter_index.xml new file mode 100644 index 00000000..e3288989 --- /dev/null +++ b/Sites/pages/administrator/components/com_finder/models/forms/filter_index.xml @@ -0,0 +1,74 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/Sites/pages/administrator/components/com_finder/models/forms/filter_maps.xml b/Sites/pages/administrator/components/com_finder/models/forms/filter_maps.xml new file mode 100644 index 00000000..b7393316 --- /dev/null +++ b/Sites/pages/administrator/components/com_finder/models/forms/filter_maps.xml @@ -0,0 +1,69 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/Sites/pages/administrator/components/com_finder/models/index.php b/Sites/pages/administrator/components/com_finder/models/index.php new file mode 100644 index 00000000..b5655677 --- /dev/null +++ b/Sites/pages/administrator/components/com_finder/models/index.php @@ -0,0 +1,455 @@ +authorise('core.delete', $this->option); + } + + /** + * Method to test whether a record can have its state changed. + * + * @param object $record A record object. + * + * @return boolean True if allowed to change the state of the record. Defaults to the permission for the component. + * + * @since 2.5 + */ + protected function canEditState($record) + { + return JFactory::getUser()->authorise('core.edit.state', $this->option); + } + + /** + * Method to delete one or more records. + * + * @param array $pks An array of record primary keys. + * + * @return boolean True if successful, false if an error occurs. + * + * @since 2.5 + */ + public function delete(&$pks) + { + $dispatcher = JEventDispatcher::getInstance(); + $pks = (array) $pks; + $table = $this->getTable(); + + // Include the content plugins for the on delete events. + JPluginHelper::importPlugin('content'); + + // Iterate the items to delete each one. + foreach ($pks as $i => $pk) + { + if ($table->load($pk)) + { + if ($this->canDelete($table)) + { + $context = $this->option . '.' . $this->name; + + // Trigger the onContentBeforeDelete event. + $result = $dispatcher->trigger($this->event_before_delete, array($context, $table)); + + if (in_array(false, $result, true)) + { + $this->setError($table->getError()); + + return false; + } + + if (!$table->delete($pk)) + { + $this->setError($table->getError()); + + return false; + } + + // Trigger the onContentAfterDelete event. + $dispatcher->trigger($this->event_after_delete, array($context, $table)); + } + else + { + // Prune items that you can't change. + unset($pks[$i]); + $error = $this->getError(); + + if ($error) + { + $this->setError($error); + } + else + { + $this->setError(JText::_('JLIB_APPLICATION_ERROR_DELETE_NOT_PERMITTED')); + } + } + } + else + { + $this->setError($table->getError()); + + return false; + } + } + + // Clear the component's cache + $this->cleanCache(); + + return true; + } + + /** + * Build an SQL query to load the list data. + * + * @return JDatabaseQuery A JDatabaseQuery object + * + * @since 2.5 + */ + protected function getListQuery() + { + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select('l.*') + ->select($db->quoteName('t.title', 't_title')) + ->from($db->quoteName('#__finder_links', 'l')) + ->join('INNER', $db->quoteName('#__finder_types', 't') . ' ON ' . $db->quoteName('t.id') . ' = ' . $db->quoteName('l.type_id')); + + // Check the type filter. + $type = $this->getState('filter.type'); + + if (is_numeric($type)) + { + $query->where($db->quoteName('l.type_id') . ' = ' . (int) $type); + } + + // Check the map filter. + $contentMapId = $this->getState('filter.content_map'); + + if (is_numeric($contentMapId)) + { + $query->join('INNER', $db->quoteName('#__finder_taxonomy_map', 'm') . ' ON ' . $db->quoteName('m.link_id') . ' = ' . $db->quoteName('l.link_id')) + ->where($db->quoteName('m.node_id') . ' = ' . (int) $contentMapId); + } + + // Check for state filter. + $state = $this->getState('filter.state'); + + if (is_numeric($state)) + { + $query->where($db->quoteName('l.published') . ' = ' . (int) $state); + } + + // Check the search phrase. + $search = $this->getState('filter.search'); + + if (!empty($search)) + { + $search = $db->quote('%' . str_replace(' ', '%', $db->escape(trim($search), true) . '%')); + $orSearchSql = $db->quoteName('l.title') . ' LIKE ' . $search . ' OR ' . $db->quoteName('l.url') . ' LIKE ' . $search; + + // Filter by indexdate only if $search doesn't contains non-ascii characters + if (!preg_match('/[^\x00-\x7F]/', $search)) + { + $orSearchSql .= ' OR ' . $query->castAsChar($db->quoteName('l.indexdate')) . ' LIKE ' . $search; + } + + $query->where('(' . $orSearchSql . ')'); + } + + // Handle the list ordering. + $listOrder = $this->getState('list.ordering', 'l.title'); + $listDir = $this->getState('list.direction', 'ASC'); + + if ($listOrder === 't.title') + { + $ordering = $db->quoteName('t.title') . ' ' . $db->escape($listDir) . ', ' . $db->quoteName('l.title') . ' ' . $db->escape($listDir); + } + else + { + $ordering = $db->escape($listOrder) . ' ' . $db->escape($listDir); + } + + $query->order($ordering); + + return $query; + } + + /** + * Method to get the state of the Smart Search Plugins. + * + * @return array Array of relevant plugins and whether they are enabled or not. + * + * @since 2.5 + */ + public function getPluginState() + { + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select('name, enabled') + ->from($db->quoteName('#__extensions')) + ->where($db->quoteName('type') . ' = ' . $db->quote('plugin')) + ->where($db->quoteName('folder') . ' IN (' . $db->quote('system') . ',' . $db->quote('content') . ')') + ->where($db->quoteName('element') . ' = ' . $db->quote('finder')); + $db->setQuery($query); + + return $db->loadObjectList('name'); + } + + /** + * Method to get a store id based on model configuration state. + * + * This is necessary because the model is used by the component and + * different modules that might need different sets of data or different + * ordering requirements. + * + * @param string $id A prefix for the store id. [optional] + * + * @return string A store id. + * + * @since 2.5 + */ + protected function getStoreId($id = '') + { + // Compile the store id. + $id .= ':' . $this->getState('filter.search'); + $id .= ':' . $this->getState('filter.state'); + $id .= ':' . $this->getState('filter.type'); + $id .= ':' . $this->getState('filter.content_map'); + + return parent::getStoreId($id); + } + + /** + * Gets the total of indexed items. + * + * @return integer The total of indexed items. + * + * @since 3.6.0 + */ + public function getTotalIndexed() + { + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select('COUNT(link_id)') + ->from($db->quoteName('#__finder_links')); + $db->setQuery($query); + + $db->execute(); + + return (int) $db->loadResult(); + } + + /** + * Returns a JTable object, always creating it. + * + * @param string $type The table type to instantiate. [optional] + * @param string $prefix A prefix for the table class name. [optional] + * @param array $config Configuration array for model. [optional] + * + * @return JTable A database object + * + * @since 2.5 + */ + public function getTable($type = 'Link', $prefix = 'FinderTable', $config = array()) + { + return JTable::getInstance($type, $prefix, $config); + } + + /** + * Method to purge the index, deleting all links. + * + * @return boolean True on success, false on failure. + * + * @since 2.5 + * @throws Exception on database error + */ + public function purge() + { + $db = $this->getDbo(); + + // Truncate the links table. + $db->truncateTable('#__finder_links'); + + // Truncate the links terms tables. + for ($i = 0; $i <= 15; $i++) + { + // Get the mapping table suffix. + $suffix = dechex($i); + + $db->truncateTable('#__finder_links_terms' . $suffix); + } + + // Truncate the terms table. + $db->truncateTable('#__finder_terms'); + + // Truncate the taxonomy map table. + $db->truncateTable('#__finder_taxonomy_map'); + + // Delete all the taxonomy nodes except the root. + $query = $db->getQuery(true) + ->delete($db->quoteName('#__finder_taxonomy')) + ->where($db->quoteName('id') . ' > 1'); + $db->setQuery($query); + $db->execute(); + + // Truncate the tokens tables. + $db->truncateTable('#__finder_tokens'); + + // Truncate the tokens aggregate table. + $db->truncateTable('#__finder_tokens_aggregate'); + + return true; + } + + /** + * Method to auto-populate the model state. Calling getState in this method will result in recursion. + * + * @param string $ordering An optional ordering field. [optional] + * @param string $direction An optional direction. [optional] + * + * @return void + * + * @since 2.5 + */ + protected function populateState($ordering = 'l.title', $direction = 'asc') + { + // Load the filter state. + $this->setState('filter.search', $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search', '', 'string')); + $this->setState('filter.state', $this->getUserStateFromRequest($this->context . '.filter.state', 'filter_state', '', 'cmd')); + $this->setState('filter.type', $this->getUserStateFromRequest($this->context . '.filter.type', 'filter_type', '', 'cmd')); + $this->setState('filter.content_map', $this->getUserStateFromRequest($this->context . '.filter.content_map', 'filter_content_map', '', 'cmd')); + + // Load the parameters. + $params = JComponentHelper::getParams('com_finder'); + $this->setState('params', $params); + + // List state information. + parent::populateState($ordering, $direction); + } + + /** + * Method to change the published state of one or more records. + * + * @param array $pks A list of the primary keys to change. + * @param integer $value The value of the published state. [optional] + * + * @return boolean True on success. + * + * @since 2.5 + */ + public function publish(&$pks, $value = 1) + { + $dispatcher = JEventDispatcher::getInstance(); + $user = JFactory::getUser(); + $table = $this->getTable(); + $pks = (array) $pks; + + // Include the content plugins for the change of state event. + JPluginHelper::importPlugin('content'); + + // Access checks. + foreach ($pks as $i => $pk) + { + $table->reset(); + + if ($table->load($pk) && !$this->canEditState($table)) + { + // Prune items that you can't change. + unset($pks[$i]); + $this->setError(JText::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED')); + + return false; + } + } + + // Attempt to change the state of the records. + if (!$table->publish($pks, $value, $user->get('id'))) + { + $this->setError($table->getError()); + + return false; + } + + $context = $this->option . '.' . $this->name; + + // Trigger the onContentChangeState event. + $result = $dispatcher->trigger('onContentChangeState', array($context, $pks, $value)); + + if (in_array(false, $result, true)) + { + $this->setError($table->getError()); + + return false; + } + + // Clear the component's cache + $this->cleanCache(); + + return true; + } +} diff --git a/Sites/pages/administrator/components/com_finder/models/indexer.php b/Sites/pages/administrator/components/com_finder/models/indexer.php new file mode 100644 index 00000000..5e49c511 --- /dev/null +++ b/Sites/pages/administrator/components/com_finder/models/indexer.php @@ -0,0 +1,19 @@ +authorise('core.delete', $this->option); + } + + /** + * Method to test whether a record can have its state changed. + * + * @param object $record A record object. + * + * @return boolean True if allowed to change the state of the record. Defaults to the permission for the component. + * + * @since 2.5 + */ + protected function canEditState($record) + { + return JFactory::getUser()->authorise('core.edit.state', $this->option); + } + + /** + * Method to delete one or more records. + * + * @param array $pks An array of record primary keys. + * + * @return boolean True if successful, false if an error occurs. + * + * @since 2.5 + */ + public function delete(&$pks) + { + $dispatcher = JEventDispatcher::getInstance(); + $pks = (array) $pks; + $table = $this->getTable(); + + // Include the content plugins for the on delete events. + JPluginHelper::importPlugin('content'); + + // Iterate the items to delete each one. + foreach ($pks as $i => $pk) + { + if ($table->load($pk)) + { + if ($this->canDelete($table)) + { + $context = $this->option . '.' . $this->name; + + // Trigger the onContentBeforeDelete event. + $result = $dispatcher->trigger('onContentBeforeDelete', array($context, $table)); + + if (in_array(false, $result, true)) + { + $this->setError($table->getError()); + + return false; + } + + if (!$table->delete($pk)) + { + $this->setError($table->getError()); + + return false; + } + + // Trigger the onContentAfterDelete event. + $dispatcher->trigger('onContentAfterDelete', array($context, $table)); + } + else + { + // Prune items that you can't change. + unset($pks[$i]); + $error = $this->getError(); + + if ($error) + { + $this->setError($error); + } + else + { + $this->setError(JText::_('JLIB_APPLICATION_ERROR_DELETE_NOT_PERMITTED')); + } + } + } + else + { + $this->setError($table->getError()); + + return false; + } + } + + // Clear the component's cache + $this->cleanCache(); + + return true; + } + + /** + * Build an SQL query to load the list data. + * + * @return JDatabaseQuery A JDatabaseQuery object + * + * @since 2.5 + */ + protected function getListQuery() + { + $db = $this->getDbo(); + + // Select all fields from the table. + $query = $db->getQuery(true) + ->select('a.id, a.parent_id, a.title, a.state, a.access, a.ordering') + ->select('CASE WHEN a.parent_id = 1 THEN 1 ELSE 2 END AS level') + ->select('p.title AS parent_title') + ->from($db->quoteName('#__finder_taxonomy', 'a')) + ->leftJoin($db->quoteName('#__finder_taxonomy', 'p') . ' ON p.id = a.parent_id') + ->where('a.parent_id != 0'); + + $childQuery = $db->getQuery(true) + ->select('parent_id') + ->select('COUNT(*) AS num_children') + ->from($db->quoteName('#__finder_taxonomy')) + ->where('parent_id != 0') + ->group('parent_id'); + + // Join to get children. + $query->select('b.num_children'); + $query->select('CASE WHEN a.parent_id = 1 THEN a.title ELSE p.title END AS branch_title'); + $query->leftJoin('(' . $childQuery . ') AS b ON b.parent_id = a.id'); + + // Join to get the map links. + $stateQuery = $db->getQuery(true) + ->select('m.node_id') + ->select('COUNT(NULLIF(l.published, 0)) AS count_published') + ->select('COUNT(NULLIF(l.published, 1)) AS count_unpublished') + ->from($db->quoteName('#__finder_taxonomy_map', 'm')) + ->leftJoin($db->quoteName('#__finder_links', 'l') . ' ON l.link_id = m.link_id') + ->group('m.node_id'); + + $query->select('COALESCE(s.count_published, 0) AS count_published'); + $query->select('COALESCE(s.count_unpublished, 0) AS count_unpublished'); + $query->leftJoin('(' . $stateQuery . ') AS s ON s.node_id = a.id'); + + // If the model is set to check item state, add to the query. + $state = $this->getState('filter.state'); + + if (is_numeric($state)) + { + $query->where('a.state = ' . (int) $state); + } + + // Filter over level. + $level = $this->getState('filter.level'); + + if (is_numeric($level) && (int) $level === 1) + { + $query->where('a.parent_id = 1'); + } + + // Filter the maps over the branch if set. + $branchId = $this->getState('filter.branch'); + + if (is_numeric($branchId)) + { + $query->where('a.parent_id = ' . (int) $branchId); + } + + // Filter the maps over the search string if set. + if ($search = $this->getState('filter.search')) + { + $search = $db->quote('%' . str_replace(' ', '%', $db->escape(trim($search), true) . '%')); + $query->where('a.title LIKE ' . $search); + } + + // Handle the list ordering. + $listOrdering = $this->getState('list.ordering', 'd.branch_title'); + $listDirn = $this->getState('list.direction', 'ASC'); + + if ($listOrdering === 'd.branch_title') + { + $query->order("branch_title $listDirn, level ASC, a.title $listDirn"); + } + elseif ($listOrdering === 'a.state') + { + $query->order("a.state $listDirn, branch_title $listDirn, level ASC"); + } + + return $query; + } + + /** + * Returns a record count for the query. + * + * @param JDatabaseQuery|string $query The query. + * + * @return integer Number of rows for query. + * + * @since 3.0 + */ + protected function _getListCount($query) + { + $query = clone $query; + $query->clear('select')->clear('join')->clear('order')->clear('limit')->clear('offset')->select('COUNT(*)'); + + return (int) $this->getDbo()->setQuery($query)->loadResult(); + } + + /** + * Method to get a store id based on model configuration state. + * + * This is necessary because the model is used by the component and + * different modules that might need different sets of data or different + * ordering requirements. + * + * @param string $id A prefix for the store id. [optional] + * + * @return string A store id. + * + * @since 2.5 + */ + protected function getStoreId($id = '') + { + // Compile the store id. + $id .= ':' . $this->getState('filter.search'); + $id .= ':' . $this->getState('filter.state'); + $id .= ':' . $this->getState('filter.branch'); + $id .= ':' . $this->getState('filter.level'); + + return parent::getStoreId($id); + } + + /** + * Returns a JTable object, always creating it. + * + * @param string $type The table type to instantiate. [optional] + * @param string $prefix A prefix for the table class name. [optional] + * @param array $config Configuration array for model. [optional] + * + * @return JTable A database object + * + * @since 2.5 + */ + public function getTable($type = 'Map', $prefix = 'FinderTable', $config = array()) + { + return JTable::getInstance($type, $prefix, $config); + } + + /** + * Method to auto-populate the model state. Calling getState in this method will result in recursion. + * + * @param string $ordering An optional ordering field. [optional] + * @param string $direction An optional direction. [optional] + * + * @return void + * + * @since 2.5 + */ + protected function populateState($ordering = 'd.branch_title', $direction = 'ASC') + { + // Load the filter state. + $this->setState('filter.search', $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search', '', 'string')); + $this->setState('filter.state', $this->getUserStateFromRequest($this->context . '.filter.state', 'filter_state', '', 'cmd')); + $this->setState('filter.branch', $this->getUserStateFromRequest($this->context . '.filter.branch', 'filter_branch', '', 'cmd')); + $this->setState('filter.level', $this->getUserStateFromRequest($this->context . '.filter.level', 'filter_level', '', 'cmd')); + + // Load the parameters. + $params = JComponentHelper::getParams('com_finder'); + $this->setState('params', $params); + + // List state information. + parent::populateState($ordering, $direction); + } + + /** + * Method to change the published state of one or more records. + * + * @param array $pks A list of the primary keys to change. + * @param integer $value The value of the published state. [optional] + * + * @return boolean True on success. + * + * @since 2.5 + */ + public function publish(&$pks, $value = 1) + { + $dispatcher = JEventDispatcher::getInstance(); + $user = JFactory::getUser(); + $table = $this->getTable(); + $pks = (array) $pks; + + // Include the content plugins for the change of state event. + JPluginHelper::importPlugin('content'); + + // Access checks. + foreach ($pks as $i => $pk) + { + $table->reset(); + + if ($table->load($pk) && !$this->canEditState($table)) + { + // Prune items that you can't change. + unset($pks[$i]); + $this->setError(JText::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED')); + + return false; + } + } + + // Attempt to change the state of the records. + if (!$table->publish($pks, $value, $user->get('id'))) + { + $this->setError($table->getError()); + + return false; + } + + $context = $this->option . '.' . $this->name; + + // Trigger the onContentChangeState event. + $result = $dispatcher->trigger('onContentChangeState', array($context, $pks, $value)); + + if (in_array(false, $result, true)) + { + $this->setError($table->getError()); + + return false; + } + + // Clear the component's cache + $this->cleanCache(); + + return true; + } + + /** + * Method to purge all maps from the taxonomy. + * + * @return boolean Returns true on success, false on failure. + * + * @since 2.5 + */ + public function purge() + { + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->delete($db->quoteName('#__finder_taxonomy')) + ->where($db->quoteName('parent_id') . ' > 1'); + $db->setQuery($query); + $db->execute(); + + $query->clear() + ->delete($db->quoteName('#__finder_taxonomy_map')); + $db->setQuery($query); + $db->execute(); + + return true; + } +} diff --git a/Sites/pages/administrator/components/com_finder/models/statistics.php b/Sites/pages/administrator/components/com_finder/models/statistics.php new file mode 100644 index 00000000..cc56b468 --- /dev/null +++ b/Sites/pages/administrator/components/com_finder/models/statistics.php @@ -0,0 +1,78 @@ +getDbo(); + $query = $db->getQuery(true); + $data = new JObject; + + $query->select('COUNT(term_id)') + ->from($db->quoteName('#__finder_terms')); + $db->setQuery($query); + $data->term_count = $db->loadResult(); + + $query->clear() + ->select('COUNT(link_id)') + ->from($db->quoteName('#__finder_links')); + $db->setQuery($query); + $data->link_count = $db->loadResult(); + + $query->clear() + ->select('COUNT(id)') + ->from($db->quoteName('#__finder_taxonomy')) + ->where($db->quoteName('parent_id') . ' = 1'); + $db->setQuery($query); + $data->taxonomy_branch_count = $db->loadResult(); + + $query->clear() + ->select('COUNT(id)') + ->from($db->quoteName('#__finder_taxonomy')) + ->where($db->quoteName('parent_id') . ' > 1'); + $db->setQuery($query); + $data->taxonomy_node_count = $db->loadResult(); + + $query->clear() + ->select('t.title AS type_title, COUNT(a.link_id) AS link_count') + ->from($db->quoteName('#__finder_links') . ' AS a') + ->join('INNER', $db->quoteName('#__finder_types') . ' AS t ON t.id = a.type_id') + ->group('a.type_id, t.title') + ->order($db->quoteName('type_title') . ' ASC'); + $db->setQuery($query); + $data->type_list = $db->loadObjectList(); + + $lang = JFactory::getLanguage(); + $plugins = JPluginHelper::getPlugin('finder'); + + foreach ($plugins as $plugin) + { + $lang->load('plg_finder_' . $plugin->name . '.sys', JPATH_ADMINISTRATOR, null, false, true) + || $lang->load('plg_finder_' . $plugin->name . '.sys', JPATH_PLUGINS . '/finder/' . $plugin->name, null, false, true); + } + + return $data; + } +} diff --git a/Sites/pages/administrator/components/com_finder/sql/install.mysql.sql b/Sites/pages/administrator/components/com_finder/sql/install.mysql.sql new file mode 100644 index 00000000..4207fa21 --- /dev/null +++ b/Sites/pages/administrator/components/com_finder/sql/install.mysql.sql @@ -0,0 +1,496 @@ +-- +-- Table structure for table `#__finder_filters` +-- + +CREATE TABLE IF NOT EXISTS `#__finder_filters` ( + `filter_id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `title` varchar(255) NOT NULL, + `alias` varchar(255) NOT NULL, + `state` tinyint(1) NOT NULL DEFAULT 1, + `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `created_by` int(10) unsigned NOT NULL, + `created_by_alias` varchar(255) NOT NULL, + `modified` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `modified_by` int(10) unsigned NOT NULL DEFAULT 0, + `checked_out` int(10) unsigned NOT NULL DEFAULT 0, + `checked_out_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `map_count` int(10) unsigned NOT NULL DEFAULT 0, + `data` text NOT NULL, + `params` mediumtext, + PRIMARY KEY (`filter_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_general_ci; + +-- +-- Table structure for table `#__finder_links` +-- + +CREATE TABLE IF NOT EXISTS `#__finder_links` ( + `link_id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `url` varchar(255) NOT NULL, + `route` varchar(255) NOT NULL, + `title` varchar(400) DEFAULT NULL, + `description` varchar(255) DEFAULT NULL, + `indexdate` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `md5sum` varchar(32) DEFAULT NULL, + `published` tinyint(1) NOT NULL DEFAULT 1, + `state` int(5) DEFAULT 1, + `access` int(5) DEFAULT 0, + `language` varchar(8) NOT NULL, + `publish_start_date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `publish_end_date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `start_date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `end_date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `list_price` double unsigned NOT NULL DEFAULT 0, + `sale_price` double unsigned NOT NULL DEFAULT 0, + `type_id` int(11) NOT NULL, + `object` mediumblob NOT NULL, + PRIMARY KEY (`link_id`), + KEY `idx_type` (`type_id`), + KEY `idx_title` (`title`(100)), + KEY `idx_md5` (`md5sum`), + KEY `idx_url` (`url`(75)), + KEY `idx_published_list` (`published`,`state`,`access`,`publish_start_date`,`publish_end_date`,`list_price`), + KEY `idx_published_sale` (`published`,`state`,`access`,`publish_start_date`,`publish_end_date`,`sale_price`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_general_ci; + +-- +-- Table structure for table `#__finder_links_terms0` +-- + +CREATE TABLE IF NOT EXISTS `#__finder_links_terms0` ( + `link_id` int(10) unsigned NOT NULL, + `term_id` int(10) unsigned NOT NULL, + `weight` float unsigned NOT NULL, + PRIMARY KEY (`link_id`,`term_id`), + KEY `idx_term_weight` (`term_id`,`weight`), + KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_general_ci; + +-- +-- Table structure for table `#__finder_links_terms1` +-- + +CREATE TABLE IF NOT EXISTS `#__finder_links_terms1` ( + `link_id` int(10) unsigned NOT NULL, + `term_id` int(10) unsigned NOT NULL, + `weight` float unsigned NOT NULL, + PRIMARY KEY (`link_id`,`term_id`), + KEY `idx_term_weight` (`term_id`,`weight`), + KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_general_ci; + +-- +-- Table structure for table `#__finder_links_terms2` +-- + +CREATE TABLE IF NOT EXISTS `#__finder_links_terms2` ( + `link_id` int(10) unsigned NOT NULL, + `term_id` int(10) unsigned NOT NULL, + `weight` float unsigned NOT NULL, + PRIMARY KEY (`link_id`,`term_id`), + KEY `idx_term_weight` (`term_id`,`weight`), + KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_general_ci; + +-- +-- Table structure for table `#__finder_links_terms3` +-- + +CREATE TABLE IF NOT EXISTS `#__finder_links_terms3` ( + `link_id` int(10) unsigned NOT NULL, + `term_id` int(10) unsigned NOT NULL, + `weight` float unsigned NOT NULL, + PRIMARY KEY (`link_id`,`term_id`), + KEY `idx_term_weight` (`term_id`,`weight`), + KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_general_ci; + +-- +-- Table structure for table `#__finder_links_terms4` +-- + +CREATE TABLE IF NOT EXISTS `#__finder_links_terms4` ( + `link_id` int(10) unsigned NOT NULL, + `term_id` int(10) unsigned NOT NULL, + `weight` float unsigned NOT NULL, + PRIMARY KEY (`link_id`,`term_id`), + KEY `idx_term_weight` (`term_id`,`weight`), + KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_general_ci; + +-- +-- Table structure for table `#__finder_links_terms5` +-- + +CREATE TABLE IF NOT EXISTS `#__finder_links_terms5` ( + `link_id` int(10) unsigned NOT NULL, + `term_id` int(10) unsigned NOT NULL, + `weight` float unsigned NOT NULL, + PRIMARY KEY (`link_id`,`term_id`), + KEY `idx_term_weight` (`term_id`,`weight`), + KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_general_ci; + +-- +-- Table structure for table `#__finder_links_terms6` +-- + +CREATE TABLE IF NOT EXISTS `#__finder_links_terms6` ( + `link_id` int(10) unsigned NOT NULL, + `term_id` int(10) unsigned NOT NULL, + `weight` float unsigned NOT NULL, + PRIMARY KEY (`link_id`,`term_id`), + KEY `idx_term_weight` (`term_id`,`weight`), + KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_general_ci; + +-- +-- Table structure for table `#__finder_links_terms7` +-- + +CREATE TABLE IF NOT EXISTS `#__finder_links_terms7` ( + `link_id` int(10) unsigned NOT NULL, + `term_id` int(10) unsigned NOT NULL, + `weight` float unsigned NOT NULL, + PRIMARY KEY (`link_id`,`term_id`), + KEY `idx_term_weight` (`term_id`,`weight`), + KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_general_ci; + +-- +-- Table structure for table `#__finder_links_terms8` +-- + +CREATE TABLE IF NOT EXISTS `#__finder_links_terms8` ( + `link_id` int(10) unsigned NOT NULL, + `term_id` int(10) unsigned NOT NULL, + `weight` float unsigned NOT NULL, + PRIMARY KEY (`link_id`,`term_id`), + KEY `idx_term_weight` (`term_id`,`weight`), + KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_general_ci; + +-- +-- Table structure for table `#__finder_links_terms9` +-- + +CREATE TABLE IF NOT EXISTS `#__finder_links_terms9` ( + `link_id` int(10) unsigned NOT NULL, + `term_id` int(10) unsigned NOT NULL, + `weight` float unsigned NOT NULL, + PRIMARY KEY (`link_id`,`term_id`), + KEY `idx_term_weight` (`term_id`,`weight`), + KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_general_ci; + +-- +-- Table structure for table `#__finder_links_termsa` +-- + +CREATE TABLE IF NOT EXISTS `#__finder_links_termsa` ( + `link_id` int(10) unsigned NOT NULL, + `term_id` int(10) unsigned NOT NULL, + `weight` float unsigned NOT NULL, + PRIMARY KEY (`link_id`,`term_id`), + KEY `idx_term_weight` (`term_id`,`weight`), + KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_general_ci; + +-- +-- Table structure for table `#__finder_links_termsb` +-- + +CREATE TABLE IF NOT EXISTS `#__finder_links_termsb` ( + `link_id` int(10) unsigned NOT NULL, + `term_id` int(10) unsigned NOT NULL, + `weight` float unsigned NOT NULL, + PRIMARY KEY (`link_id`,`term_id`), + KEY `idx_term_weight` (`term_id`,`weight`), + KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_general_ci; + +-- +-- Table structure for table `#__finder_links_termsc` +-- + +CREATE TABLE IF NOT EXISTS `#__finder_links_termsc` ( + `link_id` int(10) unsigned NOT NULL, + `term_id` int(10) unsigned NOT NULL, + `weight` float unsigned NOT NULL, + PRIMARY KEY (`link_id`,`term_id`), + KEY `idx_term_weight` (`term_id`,`weight`), + KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_general_ci; + +-- +-- Table structure for table `#__finder_links_termsd` +-- + +CREATE TABLE IF NOT EXISTS `#__finder_links_termsd` ( + `link_id` int(10) unsigned NOT NULL, + `term_id` int(10) unsigned NOT NULL, + `weight` float unsigned NOT NULL, + PRIMARY KEY (`link_id`,`term_id`), + KEY `idx_term_weight` (`term_id`,`weight`), + KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_general_ci; + +-- +-- Table structure for table `#__finder_links_termse` +-- + +CREATE TABLE IF NOT EXISTS `#__finder_links_termse` ( + `link_id` int(10) unsigned NOT NULL, + `term_id` int(10) unsigned NOT NULL, + `weight` float unsigned NOT NULL, + PRIMARY KEY (`link_id`,`term_id`), + KEY `idx_term_weight` (`term_id`,`weight`), + KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_general_ci; + +-- +-- Table structure for table `#__finder_links_termsf` +-- + +CREATE TABLE IF NOT EXISTS `#__finder_links_termsf` ( + `link_id` int(10) unsigned NOT NULL, + `term_id` int(10) unsigned NOT NULL, + `weight` float unsigned NOT NULL, + PRIMARY KEY (`link_id`,`term_id`), + KEY `idx_term_weight` (`term_id`,`weight`), + KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_general_ci; + +-- +-- Table structure for table `#__finder_taxonomy` +-- + +CREATE TABLE IF NOT EXISTS `#__finder_taxonomy` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `parent_id` int(10) unsigned NOT NULL DEFAULT 0, + `title` varchar(255) NOT NULL, + `state` tinyint(1) unsigned NOT NULL DEFAULT 1, + `access` tinyint(1) unsigned NOT NULL DEFAULT 0, + `ordering` tinyint(1) unsigned NOT NULL DEFAULT 0, + PRIMARY KEY (`id`), + KEY `parent_id` (`parent_id`), + KEY `state` (`state`), + KEY `ordering` (`ordering`), + KEY `access` (`access`), + KEY `idx_parent_published` (`parent_id`,`state`,`access`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_general_ci; + +-- +-- Dumping data for table `#__finder_taxonomy` +-- + +REPLACE INTO `#__finder_taxonomy` (`id`, `parent_id`, `title`, `state`, `access`, `ordering`) VALUES +(1, 0, 'ROOT', 0, 0, 0); + +-- +-- Table structure for table `#__finder_taxonomy_map` +-- + +CREATE TABLE IF NOT EXISTS `#__finder_taxonomy_map` ( + `link_id` int(10) unsigned NOT NULL, + `node_id` int(10) unsigned NOT NULL, + PRIMARY KEY (`link_id`,`node_id`), + KEY `link_id` (`link_id`), + KEY `node_id` (`node_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_general_ci; + +-- +-- Table structure for table `#__finder_terms` +-- + +CREATE TABLE IF NOT EXISTS `#__finder_terms` ( + `term_id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `term` varchar(75) NOT NULL, + `stem` varchar(75) NOT NULL, + `common` tinyint(1) unsigned NOT NULL DEFAULT 0, + `phrase` tinyint(1) unsigned NOT NULL DEFAULT 0, + `weight` float unsigned NOT NULL DEFAULT 0, + `soundex` varchar(75) NOT NULL, + `links` int(10) NOT NULL DEFAULT 0, + `language` char(3) NOT NULL DEFAULT '', + PRIMARY KEY (`term_id`), + UNIQUE KEY `idx_term` (`term`), + KEY `idx_term_phrase` (`term`,`phrase`), + KEY `idx_stem_phrase` (`stem`,`phrase`), + KEY `idx_soundex_phrase` (`soundex`,`phrase`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_general_ci; + +-- +-- Table structure for table `#__finder_terms_common` +-- + +CREATE TABLE IF NOT EXISTS `#__finder_terms_common` ( + `term` varchar(75) NOT NULL, + `language` varchar(3) NOT NULL, + KEY `idx_word_lang` (`term`,`language`), + KEY `idx_lang` (`language`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_general_ci; + +-- +-- Dumping data for table `#__finder_terms_common` +-- + +REPLACE INTO `#__finder_terms_common` (`term`, `language`) VALUES +('a', 'en'), +('about', 'en'), +('after', 'en'), +('ago', 'en'), +('all', 'en'), +('am', 'en'), +('an', 'en'), +('and', 'en'), +('any', 'en'), +('are', 'en'), +('aren''t', 'en'), +('as', 'en'), +('at', 'en'), +('be', 'en'), +('but', 'en'), +('by', 'en'), +('for', 'en'), +('from', 'en'), +('get', 'en'), +('go', 'en'), +('how', 'en'), +('if', 'en'), +('in', 'en'), +('into', 'en'), +('is', 'en'), +('isn''t', 'en'), +('it', 'en'), +('its', 'en'), +('me', 'en'), +('more', 'en'), +('most', 'en'), +('must', 'en'), +('my', 'en'), +('new', 'en'), +('no', 'en'), +('none', 'en'), +('not', 'en'), +('nothing', 'en'), +('of', 'en'), +('off', 'en'), +('often', 'en'), +('old', 'en'), +('on', 'en'), +('onc', 'en'), +('once', 'en'), +('only', 'en'), +('or', 'en'), +('other', 'en'), +('our', 'en'), +('ours', 'en'), +('out', 'en'), +('over', 'en'), +('page', 'en'), +('she', 'en'), +('should', 'en'), +('small', 'en'), +('so', 'en'), +('some', 'en'), +('than', 'en'), +('thank', 'en'), +('that', 'en'), +('the', 'en'), +('their', 'en'), +('theirs', 'en'), +('them', 'en'), +('then', 'en'), +('there', 'en'), +('these', 'en'), +('they', 'en'), +('this', 'en'), +('those', 'en'), +('thus', 'en'), +('time', 'en'), +('times', 'en'), +('to', 'en'), +('too', 'en'), +('true', 'en'), +('under', 'en'), +('until', 'en'), +('up', 'en'), +('upon', 'en'), +('use', 'en'), +('user', 'en'), +('users', 'en'), +('version', 'en'), +('very', 'en'), +('via', 'en'), +('want', 'en'), +('was', 'en'), +('way', 'en'), +('were', 'en'), +('what', 'en'), +('when', 'en'), +('where', 'en'), +('which', 'en'), +('who', 'en'), +('whom', 'en'), +('whose', 'en'), +('why', 'en'), +('wide', 'en'), +('will', 'en'), +('with', 'en'), +('within', 'en'), +('without', 'en'), +('would', 'en'), +('yes', 'en'), +('yet', 'en'), +('you', 'en'), +('your', 'en'), +('yours', 'en'); + +-- +-- Table structure for table `#__finder_tokens` +-- + +CREATE TABLE IF NOT EXISTS `#__finder_tokens` ( + `term` varchar(75) NOT NULL, + `stem` varchar(75) NOT NULL, + `common` tinyint(1) unsigned NOT NULL DEFAULT 0, + `phrase` tinyint(1) unsigned NOT NULL DEFAULT 0, + `weight` float unsigned NOT NULL DEFAULT 1, + `context` tinyint(1) unsigned NOT NULL DEFAULT 2, + `language` char(3) NOT NULL DEFAULT '', + KEY `idx_word` (`term`), + KEY `idx_context` (`context`) +) ENGINE=MEMORY DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_general_ci; + +-- +-- Table structure for table `#__finder_tokens_aggregate` +-- + +CREATE TABLE IF NOT EXISTS `#__finder_tokens_aggregate` ( + `term_id` int(10) unsigned NOT NULL, + `map_suffix` char(1) NOT NULL, + `term` varchar(75) NOT NULL, + `stem` varchar(75) NOT NULL, + `common` tinyint(1) unsigned NOT NULL DEFAULT 0, + `phrase` tinyint(1) unsigned NOT NULL DEFAULT 0, + `term_weight` float unsigned NOT NULL, + `context` tinyint(1) unsigned NOT NULL DEFAULT 2, + `context_weight` float unsigned NOT NULL, + `total_weight` float unsigned NOT NULL, + `language` char(3) NOT NULL DEFAULT '', + KEY `token` (`term`), + KEY `keyword_id` (`term_id`) +) ENGINE=MEMORY DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_general_ci; + +-- +-- Table structure for table `#__finder_types` +-- + +CREATE TABLE IF NOT EXISTS `#__finder_types` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `title` varchar(100) NOT NULL, + `mime` varchar(100) NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `title` (`title`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_general_ci; diff --git a/Sites/pages/administrator/components/com_finder/sql/install.postgresql.sql b/Sites/pages/administrator/components/com_finder/sql/install.postgresql.sql new file mode 100644 index 00000000..8097507e --- /dev/null +++ b/Sites/pages/administrator/components/com_finder/sql/install.postgresql.sql @@ -0,0 +1,1025 @@ +-- +-- Table: #__finder_filters +-- +CREATE TABLE "#__finder_filters" ( + "filter_id" serial NOT NULL, + "title" character varying(255) NOT NULL, + "alias" character varying(255) NOT NULL, + "state" smallint DEFAULT 1 NOT NULL, + "created" timestamp without time zone DEFAULT '1970-01-01 00:00:00' NOT NULL, + "created_by" integer NOT NULL, + "created_by_alias" character varying(255) NOT NULL, + "modified" timestamp without time zone DEFAULT '1970-01-01 00:00:00' NOT NULL, + "modified_by" integer DEFAULT 0 NOT NULL, + "checked_out" integer DEFAULT 0 NOT NULL, + "checked_out_time" timestamp without time zone DEFAULT '1970-01-01 00:00:00' NOT NULL, + "map_count" integer DEFAULT 0 NOT NULL, + "data" text NOT NULL, + "params" text, + PRIMARY KEY ("filter_id") +); + +-- +-- Table: #__finder_links +-- +CREATE TABLE "#__finder_links" ( + "link_id" serial NOT NULL, + "url" character varying(255) NOT NULL, + "route" character varying(255) NOT NULL, + "title" character varying(255) DEFAULT NULL, + "description" character varying(255) DEFAULT NULL, + "indexdate" timestamp without time zone DEFAULT '1970-01-01 00:00:00' NOT NULL, + "md5sum" character varying(32) DEFAULT NULL, + "published" smallint DEFAULT 1 NOT NULL, + "state" integer DEFAULT 1, + "access" integer DEFAULT 0, + "language" character varying(8) NOT NULL, + "publish_start_date" timestamp without time zone DEFAULT '1970-01-01 00:00:00' NOT NULL, + "publish_end_date" timestamp without time zone DEFAULT '1970-01-01 00:00:00' NOT NULL, + "start_date" timestamp without time zone DEFAULT '1970-01-01 00:00:00' NOT NULL, + "end_date" timestamp without time zone DEFAULT '1970-01-01 00:00:00' NOT NULL, + "list_price" numeric(8,2) DEFAULT 0 NOT NULL, + "sale_price" numeric(8,2) DEFAULT 0 NOT NULL, + "type_id" bigint NOT NULL, + "object" bytea NOT NULL, + PRIMARY KEY ("link_id") +); +CREATE INDEX "#__finder_links_idx_type" on "#__finder_links" ("type_id"); +CREATE INDEX "#__finder_links_idx_title" on "#__finder_links" ("title"); +CREATE INDEX "#__finder_links_idx_md5" on "#__finder_links" ("md5sum"); +CREATE INDEX "#__finder_links_idx_url" on "#__finder_links" (url(75)); +CREATE INDEX "#__finder_links_idx_published_list" on "#__finder_links" ("published", "state", "access", "publish_start_date", "publish_end_date", "list_price"); +CREATE INDEX "#__finder_links_idx_published_sale" on "#__finder_links" ("published", "state", "access", "publish_start_date", "publish_end_date", "sale_price"); + +-- +-- Table: #__finder_links_terms0 +-- +CREATE TABLE "#__finder_links_terms0" ( + "link_id" integer NOT NULL, + "term_id" integer NOT NULL, + "weight" numeric(8,2) NOT NULL, + PRIMARY KEY ("link_id", "term_id") +); +CREATE INDEX "#__finder_links_terms0_idx_term_weight" on "#__finder_links_terms0" ("term_id", "weight"); +CREATE INDEX "#__finder_links_terms0_idx_link_term_weight" on "#__finder_links_terms0" ("link_id", "term_id", "weight"); + +-- +-- Table: #__finder_links_terms1 +-- +CREATE TABLE "#__finder_links_terms1" ( + "link_id" integer NOT NULL, + "term_id" integer NOT NULL, + "weight" numeric(8,2) NOT NULL, + PRIMARY KEY ("link_id", "term_id") +); +CREATE INDEX "#__finder_links_terms1_idx_term_weight" on "#__finder_links_terms1" ("term_id", "weight"); +CREATE INDEX "#__finder_links_terms1_idx_link_term_weight" on "#__finder_links_terms1" ("link_id", "term_id", "weight"); + +-- +-- Table: #__finder_links_terms2 +-- +CREATE TABLE "#__finder_links_terms2" ( + "link_id" integer NOT NULL, + "term_id" integer NOT NULL, + "weight" numeric(8,2) NOT NULL, + PRIMARY KEY ("link_id", "term_id") +); +CREATE INDEX "#__finder_links_terms2_idx_term_weight" on "#__finder_links_terms2" ("term_id", "weight"); +CREATE INDEX "#__finder_links_terms2_idx_link_term_weight" on "#__finder_links_terms2" ("link_id", "term_id", "weight"); + +-- +-- Table: #__finder_links_terms3 +-- +CREATE TABLE "#__finder_links_terms3" ( + "link_id" integer NOT NULL, + "term_id" integer NOT NULL, + "weight" numeric(8,2) NOT NULL, + PRIMARY KEY ("link_id", "term_id") +); +CREATE INDEX "#__finder_links_terms3_idx_term_weight" on "#__finder_links_terms3" ("term_id", "weight"); +CREATE INDEX "#__finder_links_terms3_idx_link_term_weight" on "#__finder_links_terms3" ("link_id", "term_id", "weight"); + +-- +-- Table: #__finder_links_terms4 +-- +CREATE TABLE "#__finder_links_terms4" ( + "link_id" integer NOT NULL, + "term_id" integer NOT NULL, + "weight" numeric(8,2) NOT NULL, + PRIMARY KEY ("link_id", "term_id") +); +CREATE INDEX "#__finder_links_terms4_idx_term_weight" on "#__finder_links_terms4" ("term_id", "weight"); +CREATE INDEX "#__finder_links_terms4_idx_link_term_weight" on "#__finder_links_terms4" ("link_id", "term_id", "weight"); + +-- +-- Table: #__finder_links_terms5 +-- +CREATE TABLE "#__finder_links_terms5" ( + "link_id" integer NOT NULL, + "term_id" integer NOT NULL, + "weight" numeric(8,2) NOT NULL, + PRIMARY KEY ("link_id", "term_id") +); +CREATE INDEX "#__finder_links_terms5_idx_term_weight" on "#__finder_links_terms5" ("term_id", "weight"); +CREATE INDEX "#__finder_links_terms5_idx_link_term_weight" on "#__finder_links_terms5" ("link_id", "term_id", "weight"); + +-- +-- Table: #__finder_links_terms6 +-- +CREATE TABLE "#__finder_links_terms6" ( + "link_id" integer NOT NULL, + "term_id" integer NOT NULL, + "weight" numeric(8,2) NOT NULL, + PRIMARY KEY ("link_id", "term_id") +); +CREATE INDEX "#__finder_links_terms6_idx_term_weight" on "#__finder_links_terms6" ("term_id", "weight"); +CREATE INDEX "#__finder_links_terms6_idx_link_term_weight" on "#__finder_links_terms6" ("link_id", "term_id", "weight"); + +-- +-- Table: #__finder_links_terms7 +-- +CREATE TABLE "#__finder_links_terms7" ( + "link_id" integer NOT NULL, + "term_id" integer NOT NULL, + "weight" numeric(8,2) NOT NULL, + PRIMARY KEY ("link_id", "term_id") +); +CREATE INDEX "#__finder_links_terms7_idx_term_weight" on "#__finder_links_terms7" ("term_id", "weight"); +CREATE INDEX "#__finder_links_terms7_idx_link_term_weight" on "#__finder_links_terms7" ("link_id", "term_id", "weight"); + +-- +-- Table: #__finder_links_terms8 +-- +CREATE TABLE "#__finder_links_terms8" ( + "link_id" integer NOT NULL, + "term_id" integer NOT NULL, + "weight" numeric(8,2) NOT NULL, + PRIMARY KEY ("link_id", "term_id") +); +CREATE INDEX "#__finder_links_terms8_idx_term_weight" on "#__finder_links_terms8" ("term_id", "weight"); +CREATE INDEX "#__finder_links_terms8_idx_link_term_weight" on "#__finder_links_terms8" ("link_id", "term_id", "weight"); + +-- +-- Table: #__finder_links_terms9 +-- +CREATE TABLE "#__finder_links_terms9" ( + "link_id" integer NOT NULL, + "term_id" integer NOT NULL, + "weight" numeric(8,2) NOT NULL, + PRIMARY KEY ("link_id", "term_id") +); +CREATE INDEX "#__finder_links_terms9_idx_term_weight" on "#__finder_links_terms9" ("term_id", "weight"); +CREATE INDEX "#__finder_links_terms9_idx_link_term_weight" on "#__finder_links_terms9" ("link_id", "term_id", "weight"); + +-- +-- Table: #__finder_links_termsa +-- +CREATE TABLE "#__finder_links_termsa" ( + "link_id" integer NOT NULL, + "term_id" integer NOT NULL, + "weight" numeric(8,2) NOT NULL, + PRIMARY KEY ("link_id", "term_id") +); +CREATE INDEX "#__finder_links_termsa_idx_term_weight" on "#__finder_links_termsa" ("term_id", "weight"); +CREATE INDEX "#__finder_links_termsa_idx_link_term_weight" on "#__finder_links_termsa" ("link_id", "term_id", "weight"); + +-- +-- Table: #__finder_links_termsb +-- +CREATE TABLE "#__finder_links_termsb" ( + "link_id" integer NOT NULL, + "term_id" integer NOT NULL, + "weight" numeric(8,2) NOT NULL, + PRIMARY KEY ("link_id", "term_id") +); +CREATE INDEX "#__finder_links_termsb_idx_term_weight" on "#__finder_links_termsb" ("term_id", "weight"); +CREATE INDEX "#__finder_links_termsb_idx_link_term_weight" on "#__finder_links_termsb" ("link_id", "term_id", "weight"); + +-- +-- Table: #__finder_links_termsc +-- +CREATE TABLE "#__finder_links_termsc" ( + "link_id" integer NOT NULL, + "term_id" integer NOT NULL, + "weight" numeric(8,2) NOT NULL, + PRIMARY KEY ("link_id", "term_id") +); +CREATE INDEX "#__finder_links_termsc_idx_term_weight" on "#__finder_links_termsc" ("term_id", "weight"); +CREATE INDEX "#__finder_links_termsc_idx_link_term_weight" on "#__finder_links_termsc" ("link_id", "term_id", "weight"); + +-- +-- Table: #__finder_links_termsd +-- +CREATE TABLE "#__finder_links_termsd" ( + "link_id" integer NOT NULL, + "term_id" integer NOT NULL, + "weight" numeric(8,2) NOT NULL, + PRIMARY KEY ("link_id", "term_id") +); +CREATE INDEX "#__finder_links_termsd_idx_term_weight" on "#__finder_links_termsd" ("term_id", "weight"); +CREATE INDEX "#__finder_links_termsd_idx_link_term_weight" on "#__finder_links_termsd" ("link_id", "term_id", "weight"); + +-- +-- Table: #__finder_links_termse +-- +CREATE TABLE "#__finder_links_termse" ( + "link_id" integer NOT NULL, + "term_id" integer NOT NULL, + "weight" numeric(8,2) NOT NULL, + PRIMARY KEY ("link_id", "term_id") +); +CREATE INDEX "#__finder_links_termse_idx_term_weight" on "#__finder_links_termse" ("term_id", "weight"); +CREATE INDEX "#__finder_links_termse_idx_link_term_weight" on "#__finder_links_termse" ("link_id", "term_id", "weight"); + +-- +-- Table: #__finder_links_termsf +-- +CREATE TABLE "#__finder_links_termsf" ( + "link_id" integer NOT NULL, + "term_id" integer NOT NULL, + "weight" numeric(8,2) NOT NULL, + PRIMARY KEY ("link_id", "term_id") +); +CREATE INDEX "#__finder_links_termsf_idx_term_weight" on "#__finder_links_termsf" ("term_id", "weight"); +CREATE INDEX "#__finder_links_termsf_idx_link_term_weight" on "#__finder_links_termsf" ("link_id", "term_id", "weight"); + +-- +-- Table: #__finder_taxonomy +-- +CREATE TABLE "#__finder_taxonomy" ( + "id" serial NOT NULL, + "parent_id" integer DEFAULT 0 NOT NULL, + "title" character varying(255) NOT NULL, + "state" smallint DEFAULT 1 NOT NULL, + "access" smallint DEFAULT 0 NOT NULL, + "ordering" smallint DEFAULT 0 NOT NULL, + PRIMARY KEY ("id") +); +CREATE INDEX "#__finder_taxonomy_parent_id" on "#__finder_taxonomy" ("parent_id"); +CREATE INDEX "#__finder_taxonomy_state" on "#__finder_taxonomy" ("state"); +CREATE INDEX "#__finder_taxonomy_ordering" on "#__finder_taxonomy" ("ordering"); +CREATE INDEX "#__finder_taxonomy_access" on "#__finder_taxonomy" ("access"); +CREATE INDEX "#__finder_taxonomy_idx_parent_published" on "#__finder_taxonomy" ("parent_id", "state", "access"); + +-- +-- Dumping data for table #__finder_taxonomy +-- +UPDATE "#__finder_taxonomy" SET ("id", "parent_id", "title", "state", "access", "ordering") = (1, 0, 'ROOT', 0, 0, 0) +WHERE "id"=1; + +INSERT INTO "#__finder_taxonomy" ("id", "parent_id", "title", "state", "access", "ordering") +SELECT 1, 0, 'ROOT', 0, 0, 0 WHERE 1 NOT IN +(SELECT 1 FROM "#__finder_taxonomy" WHERE "id"=1); + + + +-- +-- Table: #__finder_taxonomy_map +-- +CREATE TABLE "#__finder_taxonomy_map" ( + "link_id" integer NOT NULL, + "node_id" integer NOT NULL, + PRIMARY KEY ("link_id", "node_id") +); +CREATE INDEX "#__finder_taxonomy_map_link_id" on "#__finder_taxonomy_map" ("link_id"); +CREATE INDEX "#__finder_taxonomy_map_node_id" on "#__finder_taxonomy_map" ("node_id"); + +-- +-- Table: #__finder_terms +-- +CREATE TABLE "#__finder_terms" ( + "term_id" serial NOT NULL, + "term" character varying(75) NOT NULL, + "stem" character varying(75) NOT NULL, + "common" smallint DEFAULT 0 NOT NULL, + "phrase" smallint DEFAULT 0 NOT NULL, + "weight" numeric(8,2) DEFAULT 0 NOT NULL, + "soundex" character varying(75) NOT NULL, + "links" integer DEFAULT 0 NOT NULL, + PRIMARY KEY ("term_id"), + CONSTRAINT "#__finder_terms_idx_term" UNIQUE ("term") +); +CREATE INDEX "#__finder_terms_idx_term_phrase" on "#__finder_terms" ("term", "phrase"); +CREATE INDEX "#__finder_terms_idx_stem_phrase" on "#__finder_terms" ("stem", "phrase"); +CREATE INDEX "#__finder_terms_idx_soundex_phrase" on "#__finder_terms" ("soundex", "phrase"); + +-- +-- Table: #__finder_terms_common +-- +CREATE TABLE "#__finder_terms_common" ( + "term" character varying(75) NOT NULL, + "language" character varying(3) NOT NULL +); +CREATE INDEX "#__finder_terms_common_idx_word_lang" on "#__finder_terms_common" ("term", "language"); +CREATE INDEX "#__finder_terms_common_idx_lang" on "#__finder_terms_common" ("language"); + + +-- +-- Dumping data for table `#__finder_terms_common` +-- + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('a', 'en') WHERE "term"='a'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'a', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='a'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('about', 'en') WHERE "term"='about'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'about', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='about'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('after', 'en') WHERE "term"='after'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'after', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='after'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('ago', 'en') WHERE "term"='ago'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'ago', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='ago'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('all', 'en') WHERE "term"='all'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'all', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='all'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('am', 'en') WHERE "term"='am'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'am', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='am'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('an', 'en') WHERE "term"='an'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'an', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='an'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('and', 'en') WHERE "term"='and'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'and', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='and'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('any', 'en') WHERE "term"='any'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'any', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='any'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('are', 'en') WHERE "term"='are'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'are', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='are'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('aren''t', 'en') WHERE "term"='aren''t'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'aren''t', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='aren''t'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('as', 'en') WHERE "term"='as'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'as', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='as'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('at', 'en') WHERE "term"='at'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'at', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='at'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('be', 'en') WHERE "term"='be'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'be', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='be'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('but', 'en') WHERE "term"='but'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'but', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='but'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('by', 'en') WHERE "term"='by'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'by', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='by'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('for', 'en') WHERE "term"='for'; + +INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'for', 'en' WHERE 1 NOT IN +(SELECT 1 FROM "#__finder_terms_common" WHERE "term"='for'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('from', 'en') WHERE "term"='from'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'from', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='from'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('get', 'en') WHERE "term"='get'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'get', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='get'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('go', 'en') WHERE "term"='go'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'go', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='go'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('how', 'en') WHERE "term"='how'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'how', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='how'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('if', 'en') WHERE "term"='if'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'if', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='if'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('in', 'en') WHERE "term"='in'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'in', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='in'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('into', 'en') WHERE "term"='into'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'into', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='into'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('is', 'en') WHERE "term"='is'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'is', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='is'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('isn''t', 'en') WHERE "term"='isn''t'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'isn''t', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='isn''t'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('it', 'en') WHERE "term"='it'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'it', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='it'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('its', 'en') WHERE "term"='its'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'its', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='its'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('me', 'en') WHERE "term"='me'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'me', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='me'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('more', 'en') WHERE "term"='more'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'more', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='more'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('most', 'en') WHERE "term"='most'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'most', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='most'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('must', 'en') WHERE "term"='must'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'must', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='must'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('my', 'en') WHERE "term"='my'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'my', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='my'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('new', 'en') WHERE "term"='new'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'new', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='new'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('no', 'en') WHERE "term"='no'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'no', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='no'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('none', 'en') WHERE "term"='none'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'none', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='none'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('not', 'en') WHERE "term"='not'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'not', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='not'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('nothing', 'en') WHERE "term"='nothing'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'nothing', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='nothing'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('of', 'en') WHERE "term"='of'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'of', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='of'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('off', 'en') WHERE "term"='off'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'off', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='off'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('often', 'en') WHERE "term"='often'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'often', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='often'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('old', 'en') WHERE "term"='old'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'old', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='old'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('on', 'en') WHERE "term"='on'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'on', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='on'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('onc', 'en') WHERE "term"='onc'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'onc', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='onc'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('once', 'en') WHERE "term"='once'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'once', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='once'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('only', 'en') WHERE "term"='only'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'only', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='only'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('or', 'en') WHERE "term"='or'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'or', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='or'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('other', 'en') WHERE "term"='other'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'other', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='other'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('our', 'en') WHERE "term"='our'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'our', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='our'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('ours', 'en') WHERE "term"='ours'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'ours', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='ours'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('out', 'en') WHERE "term"='out'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'out', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='out'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('over', 'en') WHERE "term"='over'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'over', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='over'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('page', 'en') WHERE "term"='page'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'page', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='page'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('she', 'en') WHERE "term"='she'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'she', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='she'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('should', 'en') WHERE "term"='should'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'should', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='should'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('small', 'en') WHERE "term"='small'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'small', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='small'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('so', 'en') WHERE "term"='so'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'so', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='so'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('some', 'en') WHERE "term"='some'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'some', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='some'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('than', 'en') WHERE "term"='than'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'than', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='than'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('thank', 'en') WHERE "term"='thank'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'thank', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='thank'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('that', 'en') WHERE "term"='that'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'that', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='that'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('the', 'en') WHERE "term"='the'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'the', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='the'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('their', 'en') WHERE "term"='their'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'their', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='their'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('theirs', 'en') WHERE "term"='theirs'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'theirs', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='theirs'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('them', 'en') WHERE "term"='them'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'them', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='them'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('then', 'en') WHERE "term"='then'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'then', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='then'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('there', 'en') WHERE "term"='there'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'there', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='there'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('these', 'en') WHERE "term"='these'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'these', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='these'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('they', 'en') WHERE "term"='they'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'they', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='they'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('this', 'en') WHERE "term"='this'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'this', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='this'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('those', 'en') WHERE "term"='those'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'those', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='those'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('thus', 'en') WHERE "term"='thus'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'thus', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='thus'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('time', 'en') WHERE "term"='time'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'time', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='time'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('times', 'en') WHERE "term"='times'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'times', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='times'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('to', 'en') WHERE "term"='to'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'to', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='to'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('too', 'en') WHERE "term"='too'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'too', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='too'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('true', 'en') WHERE "term"='true'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'true', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='true'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('under', 'en')WHERE "term"='under'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'under', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='under'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('until', 'en') WHERE "term"='until'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'until', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='until'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('up', 'en') WHERE "term"='up'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'up', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='up'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('upon', 'en') WHERE "term"='upon'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'upon', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='upon'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('use', 'en') WHERE "term"='use'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'use', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='use'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('user', 'en') WHERE "term"='user'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'user', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='user'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('users', 'en') WHERE "term"='users'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'users', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='users'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('version', 'en') WHERE "term"='version'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'version', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='version'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('very', 'en') WHERE "term"='very'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'very', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='very'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('via', 'en') WHERE "term"='via'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'via', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='via'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('want', 'en') WHERE "term"='want'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'want', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='want'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('was', 'en') WHERE "term"='was'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'was', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='was'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('way', 'en') WHERE "term"='way'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'way', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='way'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('were', 'en') WHERE "term"='were'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'were', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='were'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('what', 'en') WHERE "term"='what'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'what', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='what'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('when', 'en') WHERE "term"='when'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'when', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='when'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('where', 'en') WHERE "term"='where'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'where', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='where'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('which', 'en') WHERE "term"='which'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'which', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='which'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('who', 'en') WHERE "term"='who'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'who', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='who'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('whom', 'en') WHERE "term"='whom'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'whom', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='whom'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('whose', 'en') WHERE "term"='whose'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'whose', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='whose'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('why', 'en') WHERE "term"='why'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'why', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='why'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('wide', 'en') WHERE "term"='wide'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'wide', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='wide'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('will', 'en') WHERE "term"='will'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'will', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='will'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('with', 'en') WHERE "term"='with'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'with', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='with'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('within', 'en') WHERE "term"='within'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'within', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='within'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('without', 'en') WHERE "term"='without'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'without', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='without'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('would', 'en') WHERE "term"='would'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'would', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='would'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('yes', 'en') WHERE "term"='yes'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'yes', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='yes'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('yet', 'en') WHERE "term"='yet'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'yet', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='yet'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('you', 'en') WHERE "term"='you'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'you', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='you'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('your', 'en') WHERE "term"='your'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'your', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='your'); + +-- +UPDATE "#__finder_terms_common" SET ("term", "language") = ('yours', 'en') WHERE "term"='yours'; + +INSERT INTO "#__finder_terms_common" ("term", "language") +SELECT 'yours', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='yours'); + + + +-- +-- Table: #__finder_tokens +-- +CREATE TABLE "#__finder_tokens" ( + "term" character varying(75) NOT NULL, + "stem" character varying(75) NOT NULL, + "common" smallint DEFAULT 0 NOT NULL, + "phrase" smallint DEFAULT 0 NOT NULL, + "weight" numeric(8,2) DEFAULT 1 NOT NULL, + "context" smallint DEFAULT 2 NOT NULL +); +CREATE INDEX "#__finder_tokens_idx_word" on "#__finder_tokens" ("term"); +CREATE INDEX "#__finder_tokens_idx_context" on "#__finder_tokens" ("context"); + +-- +-- Table: #__finder_tokens_aggregate +-- +CREATE TABLE "#__finder_tokens_aggregate" ( + "term_id" integer NOT NULL, + "map_suffix" character(1) NOT NULL, + "term" character varying(75) NOT NULL, + "stem" character varying(75) NOT NULL, + "common" smallint DEFAULT 0 NOT NULL, + "phrase" smallint DEFAULT 0 NOT NULL, + "term_weight" numeric(8,2) NOT NULL, + "context" smallint DEFAULT 2 NOT NULL, + "context_weight" numeric(8,2) NOT NULL, + "total_weight" numeric(8,2) NOT NULL +); +CREATE INDEX "#__finder_tokens_aggregate_token" on "#__finder_tokens_aggregate" ("term"); +CREATE INDEX "_#__finder_tokens_aggregate_keyword_id" on "#__finder_tokens_aggregate" ("term_id"); + +-- +-- Table: #__finder_types +-- +CREATE TABLE "#__finder_types" ( + "id" serial NOT NULL, + "title" character varying(100) NOT NULL, + "mime" character varying(100) NOT NULL, + PRIMARY KEY ("id"), + CONSTRAINT "#__finder_types_title" UNIQUE ("title") +); + diff --git a/Sites/pages/administrator/components/com_finder/sql/uninstall.mysql.sql b/Sites/pages/administrator/components/com_finder/sql/uninstall.mysql.sql new file mode 100644 index 00000000..89579b98 --- /dev/null +++ b/Sites/pages/administrator/components/com_finder/sql/uninstall.mysql.sql @@ -0,0 +1,25 @@ +DROP TABLE IF EXISTS `#__finder_filters`; +DROP TABLE IF EXISTS `#__finder_links`; +DROP TABLE IF EXISTS `#__finder_links_terms0`; +DROP TABLE IF EXISTS `#__finder_links_terms1`; +DROP TABLE IF EXISTS `#__finder_links_terms2`; +DROP TABLE IF EXISTS `#__finder_links_terms3`; +DROP TABLE IF EXISTS `#__finder_links_terms4`; +DROP TABLE IF EXISTS `#__finder_links_terms5`; +DROP TABLE IF EXISTS `#__finder_links_terms6`; +DROP TABLE IF EXISTS `#__finder_links_terms7`; +DROP TABLE IF EXISTS `#__finder_links_terms8`; +DROP TABLE IF EXISTS `#__finder_links_terms9`; +DROP TABLE IF EXISTS `#__finder_links_termsa`; +DROP TABLE IF EXISTS `#__finder_links_termsb`; +DROP TABLE IF EXISTS `#__finder_links_termsc`; +DROP TABLE IF EXISTS `#__finder_links_termsd`; +DROP TABLE IF EXISTS `#__finder_links_termse`; +DROP TABLE IF EXISTS `#__finder_links_termsf`; +DROP TABLE IF EXISTS `#__finder_taxonomy`; +DROP TABLE IF EXISTS `#__finder_taxonomy_map`; +DROP TABLE IF EXISTS `#__finder_terms`; +DROP TABLE IF EXISTS `#__finder_terms_common`; +DROP TABLE IF EXISTS `#__finder_tokens`; +DROP TABLE IF EXISTS `#__finder_tokens_aggregate`; +DROP TABLE IF EXISTS `#__finder_types`; diff --git a/Sites/pages/administrator/components/com_finder/sql/uninstall.postgresql.sql b/Sites/pages/administrator/components/com_finder/sql/uninstall.postgresql.sql new file mode 100644 index 00000000..76d79815 --- /dev/null +++ b/Sites/pages/administrator/components/com_finder/sql/uninstall.postgresql.sql @@ -0,0 +1,25 @@ +DROP TABLE IF EXISTS "#__finder_filters"; +DROP TABLE IF EXISTS "#__finder_links"; +DROP TABLE IF EXISTS "#__finder_links_terms0"; +DROP TABLE IF EXISTS "#__finder_links_terms1"; +DROP TABLE IF EXISTS "#__finder_links_terms2"; +DROP TABLE IF EXISTS "#__finder_links_terms3"; +DROP TABLE IF EXISTS "#__finder_links_terms4"; +DROP TABLE IF EXISTS "#__finder_links_terms5"; +DROP TABLE IF EXISTS "#__finder_links_terms6"; +DROP TABLE IF EXISTS "#__finder_links_terms7"; +DROP TABLE IF EXISTS "#__finder_links_terms8"; +DROP TABLE IF EXISTS "#__finder_links_terms9"; +DROP TABLE IF EXISTS "#__finder_links_termsa"; +DROP TABLE IF EXISTS "#__finder_links_termsb"; +DROP TABLE IF EXISTS "#__finder_links_termsc"; +DROP TABLE IF EXISTS "#__finder_links_termsd"; +DROP TABLE IF EXISTS "#__finder_links_termse"; +DROP TABLE IF EXISTS "#__finder_links_termsf"; +DROP TABLE IF EXISTS "#__finder_taxonomy"; +DROP TABLE IF EXISTS "#__finder_taxonomy_map"; +DROP TABLE IF EXISTS "#__finder_terms"; +DROP TABLE IF EXISTS "#__finder_terms_common"; +DROP TABLE IF EXISTS "#__finder_tokens"; +DROP TABLE IF EXISTS "#__finder_tokens_aggregate"; +DROP TABLE IF EXISTS "#__finder_types"; diff --git a/Sites/pages/administrator/components/com_finder/tables/filter.php b/Sites/pages/administrator/components/com_finder/tables/filter.php new file mode 100644 index 00000000..6911afd9 --- /dev/null +++ b/Sites/pages/administrator/components/com_finder/tables/filter.php @@ -0,0 +1,256 @@ +setColumnAlias('published', 'state'); + } + + /** + * Method to bind an associative array or object to the JTable instance. This + * method only binds properties that are publicly accessible and optionally + * takes an array of properties to ignore when binding. + * + * @param array $array Named array + * @param mixed $ignore An optional array or space separated list of properties + * to ignore while binding. [optional] + * + * @return mixed Null if operation was satisfactory, otherwise returns an error string + * + * @since 2.5 + */ + public function bind($array, $ignore = '') + { + if (isset($array['params']) && is_array($array['params'])) + { + $registry = new Registry($array['params']); + $array['params'] = (string) $registry; + } + + return parent::bind($array, $ignore); + } + + /** + * Method to perform sanity checks on the JTable instance properties to ensure + * they are safe to store in the database. Child classes should override this + * method to make sure the data they are storing in the database is safe and + * as expected before storage. + * + * @return boolean True if the instance is sane and able to be stored in the database. + * + * @since 2.5 + */ + public function check() + { + if (trim($this->alias) === '') + { + $this->alias = $this->title; + } + + $this->alias = JApplicationHelper::stringURLSafe($this->alias); + + if (trim(str_replace('-', '', $this->alias)) === '') + { + $this->alias = JFactory::getDate()->format('Y-m-d-H-i-s'); + } + + $params = new Registry($this->params); + + $nullDate = $this->_db->getNullDate(); + $d1 = $params->get('d1', $nullDate); + $d2 = $params->get('d2', $nullDate); + + // Check the end date is not earlier than the start date. + if ($d2 > $nullDate && $d2 < $d1) + { + // Swap the dates. + $params->set('d1', $d2); + $params->set('d2', $d1); + $this->params = (string) $params; + } + + return true; + } + + /** + * Method to set the publishing state for a row or list of rows in the database + * table. The method respects checked out rows by other users and will attempt + * to checkin rows that it can after adjustments are made. + * + * @param mixed $pks An array of primary key values to update. If not + * set the instance property value is used. [optional] + * @param integer $state The publishing state. eg. [0 = unpublished, 1 = published] [optional] + * @param integer $userId The user id of the user performing the operation. [optional] + * + * @return boolean True on success. + * + * @since 2.5 + */ + public function publish($pks = null, $state = 1, $userId = 0) + { + $k = $this->_tbl_key; + + // Sanitize input. + $pks = ArrayHelper::toInteger($pks); + $userId = (int) $userId; + $state = (int) $state; + + // If there are no primary keys set check to see if the instance key is set. + if (empty($pks)) + { + if ($this->$k) + { + $pks = array($this->$k); + } + // Nothing to set publishing state on, return false. + else + { + $this->setError(JText::_('JLIB_DATABASE_ERROR_NO_ROWS_SELECTED')); + + return false; + } + } + + // Build the WHERE clause for the primary keys. + $where = $k . '=' . implode(' OR ' . $k . '=', $pks); + + // Determine if there is checkin support for the table. + if (!property_exists($this, 'checked_out') || !property_exists($this, 'checked_out_time')) + { + $checkin = ''; + } + else + { + $checkin = ' AND (checked_out = 0 OR checked_out = ' . (int) $userId . ')'; + } + + // Update the publishing state for rows with the given primary keys. + $query = $this->_db->getQuery(true) + ->update($this->_db->quoteName($this->_tbl)) + ->set($this->_db->quoteName('state') . ' = ' . (int) $state) + ->where($where); + $this->_db->setQuery($query . $checkin); + + try + { + $this->_db->execute(); + } + catch (RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + + // If checkin is supported and all rows were adjusted, check them in. + if ($checkin && count($pks) === $this->_db->getAffectedRows()) + { + // Checkin the rows. + foreach ($pks as $pk) + { + $this->checkIn($pk); + } + } + + // If the JTable instance value is in the list of primary keys that were set, set the instance. + if (in_array($this->$k, $pks)) + { + $this->state = $state; + } + + $this->setError(''); + + return true; + } + + /** + * Method to store a row in the database from the JTable instance properties. + * If a primary key value is set the row with that primary key value will be + * updated with the instance property values. If no primary key value is set + * a new row will be inserted into the database with the properties from the + * JTable instance. + * + * @param boolean $updateNulls True to update fields even if they are null. [optional] + * + * @return boolean True on success. + * + * @since 2.5 + */ + public function store($updateNulls = false) + { + $date = JFactory::getDate()->toSql(); + $userId = JFactory::getUser()->id; + + $this->modified = $date; + + if ($this->filter_id) + { + // Existing item + $this->modified_by = $userId; + } + else + { + // New item. A filter's created field can be set by the user, + // so we don't touch it if it is set. + if (!(int) $this->created) + { + $this->created = $date; + } + + if (empty($this->created_by)) + { + $this->created_by = $userId; + } + } + + if (is_array($this->data)) + { + $this->map_count = count($this->data); + $this->data = implode(',', $this->data); + } + else + { + $this->map_count = 0; + $this->data = implode(',', array()); + } + + // Verify that the alias is unique + $table = JTable::getInstance('Filter', 'FinderTable', array('dbo' => $this->_db)); + + if ($table->load(array('alias' => $this->alias)) && ($table->filter_id != $this->filter_id || $this->filter_id == 0)) + { + $this->setError(JText::_('JLIB_DATABASE_ERROR_ARTICLE_UNIQUE_ALIAS')); + + return false; + } + + return parent::store($updateNulls); + } +} diff --git a/Sites/pages/administrator/components/com_finder/tables/link.php b/Sites/pages/administrator/components/com_finder/tables/link.php new file mode 100644 index 00000000..916c20d8 --- /dev/null +++ b/Sites/pages/administrator/components/com_finder/tables/link.php @@ -0,0 +1,30 @@ +_tbl_key; + + // Sanitize input. + $pks = ArrayHelper::toInteger($pks); + $state = (int) $state; + + // If there are no primary keys set check to see if the instance key is set. + if (empty($pks)) + { + if ($this->$k) + { + $pks = array($this->$k); + } + // Nothing to set publishing state on, return false. + else + { + $this->setError(JText::_('JLIB_DATABASE_ERROR_NO_ROWS_SELECTED')); + + return false; + } + } + + // Build the WHERE clause for the primary keys. + $where = $k . '=' . implode(' OR ' . $k . '=', $pks); + + // Update the publishing state for rows with the given primary keys. + $query = $this->_db->getQuery(true) + ->update($this->_db->quoteName($this->_tbl)) + ->set($this->_db->quoteName('state') . ' = ' . (int) $state) + ->where($where); + $this->_db->setQuery($query); + + try + { + $this->_db->execute(); + } + catch (RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + + // If the JTable instance value is in the list of primary keys that were set, set the instance. + if (in_array($this->$k, $pks)) + { + $this->state = $state; + } + + $this->setError(''); + + return true; + } +} diff --git a/Sites/pages/administrator/components/com_finder/views/filter/tmpl/edit.php b/Sites/pages/administrator/components/com_finder/views/filter/tmpl/edit.php new file mode 100644 index 00000000..021d2220 --- /dev/null +++ b/Sites/pages/administrator/components/com_finder/views/filter/tmpl/edit.php @@ -0,0 +1,103 @@ +addScriptDeclaration(' + Joomla.submitbutton = function(task) + { + if (task == "filter.cancel" || document.formvalidator.isValid(document.getElementById("adminForm"))) + { + Joomla.submitform(task, document.getElementById("adminForm")); + } + }; + + jQuery(document).ready(function($) { + $("#rightbtn").on("click", function() { + if($(this).text() == "' . JText::_('COM_FINDER_FILTER_SHOW_ALL') . '") { + $(".collapse:not(.in)").each(function (index) { + $(this).collapse("toggle"); + }); + $(this).text("' . JText::_('COM_FINDER_FILTER_HIDE_ALL') . '"); + } else { + $(this).text("' . JText::_('COM_FINDER_FILTER_SHOW_ALL') . '"); + $(".collapse.in").each(function (index) { + $(this).collapse("toggle"); + }); + } + return false; + }); + + $(".filter-node").change(function() { + $(\'input[id="jform_map_count"]\').val(document.querySelectorAll(\'input[type="checkbox"]:checked\').length); + }); + + + }); +'); + +JFactory::getDocument()->addStyleDeclaration(' + .accordion-inner .control-group .controls { + margin-left: 10px; + } + .accordion-inner > .control-group { + margin-bottom: 0; + } + '); +?> + +
+ + + +
+ 'details')); ?> + + +
+
+ total > 0) : ?> +
+ form->renderField('map_count'); ?> +
+ + + +
+ + + $this->filter->data)); ?> +
+
+ +
+
+ + + +
+ +
+ + + + + +
+ + + + +
diff --git a/Sites/pages/administrator/components/com_finder/views/filter/view.html.php b/Sites/pages/administrator/components/com_finder/views/filter/view.html.php new file mode 100644 index 00000000..5dec9164 --- /dev/null +++ b/Sites/pages/administrator/components/com_finder/views/filter/view.html.php @@ -0,0 +1,159 @@ +filter = $this->get('Filter'); + $this->item = $this->get('Item'); + $this->form = $this->get('Form'); + $this->state = $this->get('State'); + $this->total = $this->get('Total'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html'); + JHtml::addIncludePath(JPATH_SITE . '/components/com_finder/helpers/html'); + + // Configure the toolbar. + $this->addToolbar(); + + return parent::display($tpl); + } + + /** + * Method to configure the toolbar for this view. + * + * @return void + * + * @since 2.5 + */ + protected function addToolbar() + { + JFactory::getApplication()->input->set('hidemainmenu', true); + + $isNew = ($this->item->filter_id == 0); + $checkedOut = !($this->item->checked_out == 0 || $this->item->checked_out == JFactory::getUser()->id); + $canDo = JHelperContent::getActions('com_finder'); + + // Configure the toolbar. + JToolbarHelper::title( + $isNew ? JText::_('COM_FINDER_FILTER_NEW_TOOLBAR_TITLE') : JText::_('COM_FINDER_FILTER_EDIT_TOOLBAR_TITLE'), + 'zoom-in finder' + ); + + // Set the actions for new and existing records. + if ($isNew) + { + // For new records, check the create permission. + if ($canDo->get('core.create')) + { + JToolbarHelper::apply('filter.apply'); + JToolbarHelper::save('filter.save'); + JToolbarHelper::save2new('filter.save2new'); + } + + JToolbarHelper::cancel('filter.cancel'); + } + else + { + // Can't save the record if it's checked out. + // Since it's an existing record, check the edit permission. + if (!$checkedOut && $canDo->get('core.edit')) + { + JToolbarHelper::apply('filter.apply'); + JToolbarHelper::save('filter.save'); + + // We can save this record, but check the create permission to see if we can return to make a new one. + if ($canDo->get('core.create')) + { + JToolbarHelper::save2new('filter.save2new'); + } + } + + // If an existing item, can save as a copy + if ($canDo->get('core.create')) + { + JToolbarHelper::save2copy('filter.save2copy'); + } + + JToolbarHelper::cancel('filter.cancel', 'JTOOLBAR_CLOSE'); + } + + JToolbarHelper::divider(); + JToolbarHelper::help('JHELP_COMPONENTS_FINDER_MANAGE_SEARCH_FILTERS_EDIT'); + } +} diff --git a/Sites/pages/administrator/components/com_finder/views/filters/tmpl/default.php b/Sites/pages/administrator/components/com_finder/views/filters/tmpl/default.php new file mode 100644 index 00000000..160df1da --- /dev/null +++ b/Sites/pages/administrator/components/com_finder/views/filters/tmpl/default.php @@ -0,0 +1,140 @@ +get('id'); +$listOrder = $this->escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); + +JText::script('COM_FINDER_INDEX_CONFIRM_DELETE_PROMPT'); + +JFactory::getDocument()->addScriptDeclaration(' + Joomla.submitbutton = function(pressbutton) + { + if (pressbutton == "filters.delete") + { + if (confirm(Joomla.JText._("COM_FINDER_INDEX_CONFIRM_DELETE_PROMPT"))) + { + Joomla.submitform(pressbutton); + } + else + { + return false; + } + } + Joomla.submitform(pressbutton); + }; +'); +?> +
+ sidebar)) : ?> +
+ sidebar; ?> +
+
+ +
+ + $this)); ?> +
+ items)) : ?> +
+ +
+ + + + + + + + + + + + + + + + + + + + authorise('core.create', 'com_finder'); + $canEdit = $user->authorise('core.edit', 'com_finder'); + $userAuthoriseCoreManage = $user->authorise('core.manage', 'com_checkin'); + $userAuthoriseCoreEditState = $user->authorise('core.edit.state', 'com_finder'); + $userId = $user->get('id'); + foreach ($this->items as $i => $item) : + $canCheckIn = $userAuthoriseCoreManage || $item->checked_out == $userId || $item->checked_out == 0; + $canChange = $userAuthoriseCoreEditState && $canCheckIn; + $escapedTitle = $this->escape($item->title); + ?> + + + + + + + + + + + +
+ + + + + + + + + + + + + +
+ pagination->getListFooter(); ?> +
+ filter_id); ?> + + state, $i, 'filters.', $canChange); ?> + + checked_out) : ?> + editor, $item->checked_out_time, 'filters.', $canCheckIn); ?> + + + + + + + + + created_by_alias ?: $item->user_name; ?> + + created, JText::_('DATE_FORMAT_LC4')); ?> + + map_count; ?> + + filter_id; ?> +
+ + + + +
+ diff --git a/Sites/pages/administrator/components/com_finder/views/filters/view.html.php b/Sites/pages/administrator/components/com_finder/views/filters/view.html.php new file mode 100644 index 00000000..a9363d6b --- /dev/null +++ b/Sites/pages/administrator/components/com_finder/views/filters/view.html.php @@ -0,0 +1,145 @@ +items = $this->get('Items'); + $this->pagination = $this->get('Pagination'); + $this->total = $this->get('Total'); + $this->state = $this->get('State'); + $this->filterForm = $this->get('FilterForm'); + $this->activeFilters = $this->get('ActiveFilters'); + + FinderHelper::addSubmenu('filters'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html'); + + // Configure the toolbar. + $this->addToolbar(); + $this->sidebar = JHtmlSidebar::render(); + + return parent::display($tpl); + } + + /** + * Method to configure the toolbar for this view. + * + * @return void + * + * @since 2.5 + */ + protected function addToolbar() + { + $canDo = JHelperContent::getActions('com_finder'); + + JToolbarHelper::title(JText::_('COM_FINDER_FILTERS_TOOLBAR_TITLE'), 'zoom-in finder'); + $toolbar = JToolbar::getInstance('toolbar'); + + if ($canDo->get('core.create')) + { + JToolbarHelper::addNew('filter.add'); + JToolbarHelper::editList('filter.edit'); + JToolbarHelper::divider(); + } + + if ($canDo->get('core.edit.state')) + { + JToolbarHelper::publishList('filters.publish'); + JToolbarHelper::unpublishList('filters.unpublish'); + JToolbarHelper::checkin('filters.checkin'); + JToolbarHelper::divider(); + } + + if ($canDo->get('core.admin') || $canDo->get('core.options')) + { + JToolbarHelper::preferences('com_finder'); + } + + JToolbarHelper::divider(); + $toolbar->appendButton('Popup', 'bars', 'COM_FINDER_STATISTICS', 'index.php?option=com_finder&view=statistics&tmpl=component', 550, 350); + JToolbarHelper::divider(); + JToolbarHelper::help('JHELP_COMPONENTS_FINDER_MANAGE_SEARCH_FILTERS'); + + if ($canDo->get('core.delete')) + { + JToolbarHelper::deleteList('', 'filters.delete'); + JToolbarHelper::divider(); + } + } +} diff --git a/Sites/pages/administrator/components/com_finder/views/index/tmpl/default.php b/Sites/pages/administrator/components/com_finder/views/index/tmpl/default.php new file mode 100644 index 00000000..7ef96a67 --- /dev/null +++ b/Sites/pages/administrator/components/com_finder/views/index/tmpl/default.php @@ -0,0 +1,138 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$lang = JFactory::getLanguage(); + +JText::script('COM_FINDER_INDEX_CONFIRM_PURGE_PROMPT'); +JText::script('COM_FINDER_INDEX_CONFIRM_DELETE_PROMPT'); + +JFactory::getDocument()->addScriptDeclaration(' + Joomla.submitbutton = function(pressbutton) + { + if (pressbutton == "index.purge") + { + if (confirm(Joomla.JText._("COM_FINDER_INDEX_CONFIRM_PURGE_PROMPT"))) + { + Joomla.submitform(pressbutton); + } + else + { + return false; + } + } + if (pressbutton == "index.delete") + { + if (confirm(Joomla.JText._("COM_FINDER_INDEX_CONFIRM_DELETE_PROMPT"))) + { + Joomla.submitform(pressbutton); + } + else + { + return false; + } + } + + Joomla.submitform(pressbutton); + }; +'); +?> +
+sidebar)) : ?> +
+ sidebar; ?> +
+
+ +
+ + $this)); ?> + + + + + + + + + + + + + + + + + + + authorise('core.manage', 'com_finder'); ?> + items as $i => $item) : ?> + + + + + + + + + + + + +
+ + + + + + + + + + + + + +
+ pagination->getListFooter(); ?> +
+ link_id); ?> + + published, $i, 'index.', $canChange, 'cb'); ?> + + + + t_title); + echo $lang->hasKey($key) ? JText::_($key) : $item->t_title; + ?> + + indexdate, JText::_('DATE_FORMAT_LC4')); ?> + + publish_start_date || (int) $item->publish_end_date || (int) $item->start_date || (int) $item->end_date) : ?> + + publish_start_date, $item->publish_end_date, $item->start_date, $item->end_date); ?> + + + url) > 80) ? substr($item->url, 0, 70) . '...' : $item->url; ?> +
+ + + +
+ diff --git a/Sites/pages/administrator/components/com_finder/views/index/view.html.php b/Sites/pages/administrator/components/com_finder/views/index/view.html.php new file mode 100644 index 00000000..bb880bee --- /dev/null +++ b/Sites/pages/administrator/components/com_finder/views/index/view.html.php @@ -0,0 +1,170 @@ +items = $this->get('Items'); + $this->total = $this->get('Total'); + $this->pagination = $this->get('Pagination'); + $this->state = $this->get('State'); + $this->pluginState = $this->get('pluginState'); + $this->filterForm = $this->get('FilterForm'); + $this->activeFilters = $this->get('ActiveFilters'); + + FinderHelper::addSubmenu('index'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + JError::raiseError(500, implode("\n", $errors)); + + return false; + } + + if (!$this->pluginState['plg_content_finder']->enabled) + { + $link = JRoute::_('index.php?option=com_plugins&task=plugin.edit&extension_id=' . FinderHelper::getFinderPluginId()); + JFactory::getApplication()->enqueueMessage(JText::sprintf('COM_FINDER_INDEX_PLUGIN_CONTENT_NOT_ENABLED', $link), 'warning'); + } + elseif ($this->get('TotalIndexed') === 0) + { + JFactory::getApplication()->enqueueMessage(JText::_('COM_FINDER_INDEX_NO_DATA') . ' ' . JText::_('COM_FINDER_INDEX_TIP'), 'notice'); + } + + JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html'); + + // Configure the toolbar. + $this->addToolbar(); + $this->sidebar = JHtmlSidebar::render(); + + return parent::display($tpl); + } + + /** + * Method to configure the toolbar for this view. + * + * @return void + * + * @since 2.5 + */ + protected function addToolbar() + { + $canDo = JHelperContent::getActions('com_finder'); + + JToolbarHelper::title(JText::_('COM_FINDER_INDEX_TOOLBAR_TITLE'), 'zoom-in finder'); + + $toolbar = JToolbar::getInstance('toolbar'); + $toolbar->appendButton( + 'Popup', 'archive', 'COM_FINDER_INDEX', 'index.php?option=com_finder&view=indexer&tmpl=component', 500, 210, 0, 0, + 'window.parent.location.reload()', 'COM_FINDER_HEADING_INDEXER' + ); + + if ($canDo->get('core.edit.state')) + { + JToolbarHelper::publishList('index.publish'); + JToolbarHelper::unpublishList('index.unpublish'); + } + + if ($canDo->get('core.admin') || $canDo->get('core.options')) + { + JToolbarHelper::preferences('com_finder'); + } + + $toolbar->appendButton('Popup', 'bars', 'COM_FINDER_STATISTICS', 'index.php?option=com_finder&view=statistics&tmpl=component', 550, 350); + + if ($canDo->get('core.delete')) + { + JToolbarHelper::deleteList('', 'index.delete'); + } + + if ($canDo->get('core.edit.state')) + { + JToolbarHelper::trash('index.purge', 'COM_FINDER_INDEX_TOOLBAR_PURGE', false); + } + + JToolbarHelper::help('JHELP_COMPONENTS_FINDER_MANAGE_INDEXED_CONTENT'); + } +} diff --git a/Sites/pages/administrator/components/com_finder/views/indexer/tmpl/default.php b/Sites/pages/administrator/components/com_finder/views/indexer/tmpl/default.php new file mode 100644 index 00000000..3f5025b4 --- /dev/null +++ b/Sites/pages/administrator/components/com_finder/views/indexer/tmpl/default.php @@ -0,0 +1,30 @@ + 'auto', 'relative' => true)); +JFactory::getDocument()->addScriptDeclaration('var msg = "' . JText::_('COM_FINDER_INDEXER_MESSAGE_COMPLETE') . '";'); +?> + +
+

+

+ +

+ +
+
+
+ + +
diff --git a/Sites/pages/administrator/components/com_finder/views/indexer/view.html.php b/Sites/pages/administrator/components/com_finder/views/indexer/view.html.php new file mode 100644 index 00000000..ead9f584 --- /dev/null +++ b/Sites/pages/administrator/components/com_finder/views/indexer/view.html.php @@ -0,0 +1,20 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$lang = JFactory::getLanguage(); +$branchFilter = $this->escape($this->state->get('filter.branch')); +$colSpan = $branchFilter ? 5 : 6; +JText::script('COM_FINDER_MAPS_CONFIRM_DELETE_PROMPT'); + +JFactory::getDocument()->addScriptDeclaration(' + Joomla.submitbutton = function(pressbutton) + { + if (pressbutton == "map.delete") + { + if (confirm(Joomla.JText._("COM_FINDER_MAPS_CONFIRM_DELETE_PROMPT"))) + { + Joomla.submitform(pressbutton); + } + else + { + return false; + } + } + Joomla.submitform(pressbutton); + }; +'); +?> +
+sidebar)) : ?> +
+ sidebar; ?> +
+
+ +
+ + $this)); ?> +
+ items)) : ?> +
+ +
+ + + + + + + + + + + + + + + + + + + + + authorise('core.manage', 'com_finder'); ?> + items as $i => $item) : ?> + + + + + + + + + + + + +
+ + + + + + + + + + + + + +
+ pagination->getListFooter(); ?> +
+ id); ?> + + state, $i, 'maps.', $canChange, 'cb'); ?> + + parent_title, '**') === 'Language') + { + $title = FinderHelperLanguage::branchLanguageTitle($item->title); + } + else + { + $key = FinderHelperLanguage::branchSingular($item->title); + $title = $lang->hasKey($key) ? JText::_($key) : $item->title; + } + ?> + num_children === 0) : ?> + + + + escape(trim($title, '**')) === 'Language' && JLanguageMultilang::isEnabled()) : ?> + + + + num_children !== 0) : ?> + + num_children; ?> + + - + + + num_children === 0) : ?> + + count_published; ?> + + - + + + num_children === 0) : ?> + + count_unpublished; ?> + + - + +
+ +
+ + + + + diff --git a/Sites/pages/administrator/components/com_finder/views/maps/view.html.php b/Sites/pages/administrator/components/com_finder/views/maps/view.html.php new file mode 100644 index 00000000..bed9b480 --- /dev/null +++ b/Sites/pages/administrator/components/com_finder/views/maps/view.html.php @@ -0,0 +1,148 @@ +items = $this->get('Items'); + $this->total = $this->get('Total'); + $this->pagination = $this->get('Pagination'); + $this->state = $this->get('State'); + $this->filterForm = $this->get('FilterForm'); + $this->activeFilters = $this->get('ActiveFilters'); + + FinderHelper::addSubmenu('maps'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html'); + + // Prepare the view. + $this->addToolbar(); + $this->sidebar = JHtmlSidebar::render(); + + return parent::display($tpl); + } + + /** + * Method to configure the toolbar for this view. + * + * @return void + * + * @since 2.5 + */ + protected function addToolbar() + { + $canDo = JHelperContent::getActions('com_finder'); + + JToolbarHelper::title(JText::_('COM_FINDER_MAPS_TOOLBAR_TITLE'), 'zoom-in finder'); + + if ($canDo->get('core.edit.state')) + { + JToolbarHelper::publishList('maps.publish'); + JToolbarHelper::unpublishList('maps.unpublish'); + JToolbarHelper::divider(); + } + + if ($canDo->get('core.admin') || $canDo->get('core.options')) + { + JToolbarHelper::preferences('com_finder'); + } + + JToolbarHelper::divider(); + JToolbar::getInstance('toolbar')->appendButton( + 'Popup', + 'bars', + 'COM_FINDER_STATISTICS', + 'index.php?option=com_finder&view=statistics&tmpl=component', + 550, + 350 + ); + JToolbarHelper::divider(); + JToolbarHelper::help('JHELP_COMPONENTS_FINDER_MANAGE_CONTENT_MAPS'); + + if ($canDo->get('core.delete')) + { + JToolbarHelper::deleteList('', 'maps.delete'); + JToolbarHelper::divider(); + } + } +} diff --git a/Sites/pages/administrator/components/com_finder/views/statistics/tmpl/default.php b/Sites/pages/administrator/components/com_finder/views/statistics/tmpl/default.php new file mode 100644 index 00000000..79efc48e --- /dev/null +++ b/Sites/pages/administrator/components/com_finder/views/statistics/tmpl/default.php @@ -0,0 +1,56 @@ + +

+ +

+ +
+
+

data->term_count, 0, JText::_('DECIMALS_SEPARATOR'), JText::_('THOUSANDS_SEPARATOR')), number_format($this->data->link_count, 0, JText::_('DECIMALS_SEPARATOR'), JText::_('THOUSANDS_SEPARATOR')), number_format($this->data->taxonomy_node_count, 0, JText::_('DECIMALS_SEPARATOR'), JText::_('THOUSANDS_SEPARATOR')), number_format($this->data->taxonomy_branch_count, 0, JText::_('DECIMALS_SEPARATOR'), JText::_('THOUSANDS_SEPARATOR'))); ?>

+ + + + + + + + + data->type_list as $type) : ?> + + + + + + + + + + +
+ + + +
+ type_title); + $lang_string = JText::_($lang_key); + echo $lang_string === $lang_key ? $type->type_title : $lang_string; + ?> + + link_count, 0, JText::_('DECIMALS_SEPARATOR'), JText::_('THOUSANDS_SEPARATOR')); ?> +
+ + + data->link_count, 0, JText::_('DECIMALS_SEPARATOR'), JText::_('THOUSANDS_SEPARATOR')); ?> +
+
+
diff --git a/Sites/pages/administrator/components/com_finder/views/statistics/view.html.php b/Sites/pages/administrator/components/com_finder/views/statistics/view.html.php new file mode 100644 index 00000000..fa5251b8 --- /dev/null +++ b/Sites/pages/administrator/components/com_finder/views/statistics/view.html.php @@ -0,0 +1,50 @@ +data = $this->get('Data'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + return parent::display($tpl); + } +} diff --git a/Sites/pages/administrator/components/com_installer/access.xml b/Sites/pages/administrator/components/com_installer/access.xml new file mode 100644 index 00000000..1c90bfc4 --- /dev/null +++ b/Sites/pages/administrator/components/com_installer/access.xml @@ -0,0 +1,10 @@ + + +
+ + + + + +
+
diff --git a/Sites/pages/administrator/components/com_installer/config.xml b/Sites/pages/administrator/components/com_installer/config.xml new file mode 100644 index 00000000..cc833115 --- /dev/null +++ b/Sites/pages/administrator/components/com_installer/config.xml @@ -0,0 +1,65 @@ + + +
+ + + + + + + + + + + + + + + + +
+ +
+ + + +
+
diff --git a/Sites/pages/administrator/components/com_installer/controller.php b/Sites/pages/administrator/components/com_installer/controller.php new file mode 100644 index 00000000..c4703e25 --- /dev/null +++ b/Sites/pages/administrator/components/com_installer/controller.php @@ -0,0 +1,64 @@ +input->get('view', 'install'); + $vFormat = $document->getType(); + $lName = $this->input->get('layout', 'default', 'string'); + + // Get and render the view. + if ($view = $this->getView($vName, $vFormat)) + { + $ftp = JClientHelper::setCredentialsFromRequest('ftp'); + $view->ftp = &$ftp; + + // Get the model for the view. + $model = $this->getModel($vName); + + // Push the model into the view (as default). + $view->setModel($model, true); + $view->setLayout($lName); + + // Push document object into the view. + $view->document = $document; + + // Load the submenu. + InstallerHelper::addSubmenu($vName); + $view->display(); + } + + return $this; + } +} diff --git a/Sites/pages/administrator/components/com_installer/controllers/database.php b/Sites/pages/administrator/components/com_installer/controllers/database.php new file mode 100644 index 00000000..475e19bd --- /dev/null +++ b/Sites/pages/administrator/components/com_installer/controllers/database.php @@ -0,0 +1,45 @@ +checkToken(); + + $model = $this->getModel('database'); + $model->fix(); + + // Purge updates + JModelLegacy::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_joomlaupdate/models', 'JoomlaupdateModel'); + $updateModel = JModelLegacy::getInstance('default', 'JoomlaupdateModel'); + $updateModel->purge(); + + // Refresh versionable assets cache + JFactory::getApplication()->flushAssets(); + + $this->setRedirect(JRoute::_('index.php?option=com_installer&view=database', false)); + } +} diff --git a/Sites/pages/administrator/components/com_installer/controllers/discover.php b/Sites/pages/administrator/components/com_installer/controllers/discover.php new file mode 100644 index 00000000..94d30bc8 --- /dev/null +++ b/Sites/pages/administrator/components/com_installer/controllers/discover.php @@ -0,0 +1,65 @@ +checkToken(); + + $model = $this->getModel('discover'); + $model->discover(); + $this->setRedirect(JRoute::_('index.php?option=com_installer&view=discover', false)); + } + + /** + * Install a discovered extension. + * + * @return void + * + * @since 1.6 + */ + public function install() + { + $this->checkToken(); + + $this->getModel('discover')->discover_install(); + $this->setRedirect(JRoute::_('index.php?option=com_installer&view=discover', false)); + } + + /** + * Clean out the discovered extension cache. + * + * @return void + * + * @since 1.6 + */ + public function purge() + { + $this->checkToken(); + + $model = $this->getModel('discover'); + $model->purge(); + $this->setRedirect(JRoute::_('index.php?option=com_installer&view=discover', false), $model->_message); + } +} diff --git a/Sites/pages/administrator/components/com_installer/controllers/install.php b/Sites/pages/administrator/components/com_installer/controllers/install.php new file mode 100644 index 00000000..d7b781a2 --- /dev/null +++ b/Sites/pages/administrator/components/com_installer/controllers/install.php @@ -0,0 +1,99 @@ +checkToken(); + + /** @var InstallerModelInstall $model */ + $model = $this->getModel('install'); + + // TODO: Reset the users acl here as well to kill off any missing bits. + $result = $model->install(); + + $app = JFactory::getApplication(); + $redirect_url = $app->getUserState('com_installer.redirect_url'); + + if (!$redirect_url) + { + $redirect_url = base64_decode($app->input->get('return', null, 'BASE64')); + } + + // Don't redirect to an external URL. + if (!JUri::isInternal($redirect_url)) + { + $redirect_url = ''; + } + + if (empty($redirect_url)) + { + $redirect_url = JRoute::_('index.php?option=com_installer&view=install', false); + } + else + { + // Wipe out the user state when we're going to redirect. + $app->setUserState('com_installer.redirect_url', ''); + $app->setUserState('com_installer.message', ''); + $app->setUserState('com_installer.extension_message', ''); + } + + $this->setRedirect($redirect_url); + + return $result; + } + + /** + * Install an extension from drag & drop ajax upload. + * + * @return void + * + * @since 3.7.0 + */ + public function ajax_upload() + { + // Check for request forgeries. + JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + + $app = JFactory::getApplication(); + $message = $app->getUserState('com_installer.message'); + + // Do install + $result = $this->install(); + + // Get redirect URL + $redirect = $this->redirect; + + // Push message queue to session because we will redirect page by Javascript, not $app->redirect(). + // The "application.queue" is only set in redirect() method, so we must manually store it. + $app->getSession()->set('application.queue', $app->getMessageQueue()); + + header('Content-Type: application/json'); + + echo new JResponseJson(array('redirect' => $redirect), $message, !$result); + + exit(); + } +} diff --git a/Sites/pages/administrator/components/com_installer/controllers/manage.php b/Sites/pages/administrator/components/com_installer/controllers/manage.php new file mode 100644 index 00000000..0bad40b3 --- /dev/null +++ b/Sites/pages/administrator/components/com_installer/controllers/manage.php @@ -0,0 +1,130 @@ +registerTask('unpublish', 'publish'); + $this->registerTask('publish', 'publish'); + } + + /** + * Enable/Disable an extension (if supported). + * + * @return void + * + * @since 1.6 + */ + public function publish() + { + // Check for request forgeries. + $this->checkToken(); + + $ids = $this->input->get('cid', array(), 'array'); + $values = array('publish' => 1, 'unpublish' => 0); + $task = $this->getTask(); + $value = ArrayHelper::getValue($values, $task, 0, 'int'); + + if (empty($ids)) + { + JError::raiseWarning(500, JText::_('COM_INSTALLER_ERROR_NO_EXTENSIONS_SELECTED')); + } + else + { + // Get the model. + /** @var InstallerModelManage $model */ + $model = $this->getModel('manage'); + + // Change the state of the records. + if (!$model->publish($ids, $value)) + { + JError::raiseWarning(500, implode('
', $model->getErrors())); + } + else + { + if ($value == 1) + { + $ntext = 'COM_INSTALLER_N_EXTENSIONS_PUBLISHED'; + } + elseif ($value == 0) + { + $ntext = 'COM_INSTALLER_N_EXTENSIONS_UNPUBLISHED'; + } + + $this->setMessage(JText::plural($ntext, count($ids))); + } + } + + $this->setRedirect(JRoute::_('index.php?option=com_installer&view=manage', false)); + } + + /** + * Remove an extension (Uninstall). + * + * @return void + * + * @since 1.5 + */ + public function remove() + { + // Check for request forgeries. + $this->checkToken(); + + $eid = $this->input->get('cid', array(), 'array'); + + /** @var InstallerModelManage $model */ + $model = $this->getModel('manage'); + + $eid = ArrayHelper::toInteger($eid, array()); + $model->remove($eid); + $this->setRedirect(JRoute::_('index.php?option=com_installer&view=manage', false)); + } + + /** + * Refreshes the cached metadata about an extension. + * + * Useful for debugging and testing purposes when the XML file might change. + * + * @return void + * + * @since 1.6 + */ + public function refresh() + { + // Check for request forgeries. + $this->checkToken(); + + $uid = $this->input->get('cid', array(), 'array'); + $model = $this->getModel('manage'); + + $uid = ArrayHelper::toInteger($uid, array()); + $model->refresh($uid); + $this->setRedirect(JRoute::_('index.php?option=com_installer&view=manage', false)); + } +} diff --git a/Sites/pages/administrator/components/com_installer/controllers/update.php b/Sites/pages/administrator/components/com_installer/controllers/update.php new file mode 100644 index 00000000..08635af9 --- /dev/null +++ b/Sites/pages/administrator/components/com_installer/controllers/update.php @@ -0,0 +1,200 @@ +checkToken(); + + /** @var InstallerModelUpdate $model */ + $model = $this->getModel('update'); + $uid = $this->input->get('cid', array(), 'array'); + + $uid = ArrayHelper::toInteger($uid, array()); + + // Get the minimum stability. + $component = JComponentHelper::getComponent('com_installer'); + $params = $component->params; + $minimum_stability = (int) $params->get('minimum_stability', JUpdater::STABILITY_STABLE); + + $model->update($uid, $minimum_stability); + + $app = JFactory::getApplication(); + $redirect_url = $app->getUserState('com_installer.redirect_url'); + + // Don't redirect to an external URL. + if (!JUri::isInternal($redirect_url)) + { + $redirect_url = ''; + } + + if (empty($redirect_url)) + { + $redirect_url = JRoute::_('index.php?option=com_installer&view=update', false); + } + else + { + // Wipe out the user state when we're going to redirect. + $app->setUserState('com_installer.redirect_url', ''); + $app->setUserState('com_installer.message', ''); + $app->setUserState('com_installer.extension_message', ''); + } + + $this->setRedirect($redirect_url); + } + + /** + * Find new updates. + * + * @return void + * + * @since 1.6 + */ + public function find() + { + $this->checkToken('request'); + + // Get the caching duration. + $component = JComponentHelper::getComponent('com_installer'); + $params = $component->params; + $cache_timeout = (int) $params->get('cachetimeout', 6); + $cache_timeout = 3600 * $cache_timeout; + + // Get the minimum stability. + $minimum_stability = (int) $params->get('minimum_stability', JUpdater::STABILITY_STABLE); + + // Find updates. + /** @var InstallerModelUpdate $model */ + $model = $this->getModel('update'); + + $disabledUpdateSites = $model->getDisabledUpdateSites(); + + if ($disabledUpdateSites) + { + $updateSitesUrl = JRoute::_('index.php?option=com_installer&view=updatesites'); + $this->setMessage(JText::sprintf('COM_INSTALLER_MSG_UPDATE_SITES_COUNT_CHECK', $updateSitesUrl), 'warning'); + } + + $model->findUpdates(0, $cache_timeout, $minimum_stability); + $this->setRedirect(JRoute::_('index.php?option=com_installer&view=update', false)); + } + + /** + * Purges updates. + * + * @return void + * + * @since 1.6 + */ + public function purge() + { + // Check for request forgeries. + $this->checkToken(); + + $model = $this->getModel('update'); + $model->purge(); + + /** + * We no longer need to enable update sites in Joomla! 3.4 as we now allow the users to manage update sites + * themselves. + * $model->enableSites(); + */ + + $this->setRedirect(JRoute::_('index.php?option=com_installer&view=update', false), $model->_message); + } + + /** + * Fetch and report updates in JSON format, for AJAX requests + * + * @return void + * + * @since 2.5 + */ + public function ajax() + { + $app = JFactory::getApplication(); + + if (!JSession::checkToken('get')) + { + $app->setHeader('status', 403, true); + $app->sendHeaders(); + echo JText::_('JINVALID_TOKEN_NOTICE'); + $app->close(); + } + + $eid = $this->input->getInt('eid', 0); + $skip = $this->input->get('skip', array(), 'array'); + $cache_timeout = $this->input->getInt('cache_timeout', 0); + $minimum_stability = $this->input->getInt('minimum_stability', -1); + + $component = JComponentHelper::getComponent('com_installer'); + $params = $component->params; + + if ($cache_timeout == 0) + { + $cache_timeout = (int) $params->get('cachetimeout', 6); + $cache_timeout = 3600 * $cache_timeout; + } + + if ($minimum_stability < 0) + { + $minimum_stability = (int) $params->get('minimum_stability', JUpdater::STABILITY_STABLE); + } + + /** @var InstallerModelUpdate $model */ + $model = $this->getModel('update'); + $model->findUpdates($eid, $cache_timeout, $minimum_stability); + + $model->setState('list.start', 0); + $model->setState('list.limit', 0); + + if ($eid != 0) + { + $model->setState('filter.extension_id', $eid); + } + + $updates = $model->getItems(); + + if (!empty($skip)) + { + $unfiltered_updates = $updates; + $updates = array(); + + foreach ($unfiltered_updates as $update) + { + if (!in_array($update->extension_id, $skip)) + { + $updates[] = $update; + } + } + } + + echo json_encode($updates); + + $app->close(); + } +} diff --git a/Sites/pages/administrator/components/com_installer/controllers/updatesites.php b/Sites/pages/administrator/components/com_installer/controllers/updatesites.php new file mode 100644 index 00000000..d38b96e2 --- /dev/null +++ b/Sites/pages/administrator/components/com_installer/controllers/updatesites.php @@ -0,0 +1,125 @@ +registerTask('unpublish', 'publish'); + $this->registerTask('publish', 'publish'); + $this->registerTask('delete', 'delete'); + $this->registerTask('rebuild', 'rebuild'); + } + + /** + * Enable/Disable an extension (if supported). + * + * @return void + * + * @since 3.4 + * + * @throws Exception on error + */ + public function publish() + { + // Check for request forgeries. + $this->checkToken(); + + $ids = $this->input->get('cid', array(), 'array'); + $values = array('publish' => 1, 'unpublish' => 0); + $task = $this->getTask(); + $value = ArrayHelper::getValue($values, $task, 0, 'int'); + + if (empty($ids)) + { + throw new Exception(JText::_('COM_INSTALLER_ERROR_NO_UPDATESITES_SELECTED'), 500); + } + + // Get the model. + $model = $this->getModel('Updatesites'); + + // Change the state of the records. + if (!$model->publish($ids, $value)) + { + throw new Exception(implode('
', $model->getErrors()), 500); + } + + $ntext = ($value == 0) ? 'COM_INSTALLER_N_UPDATESITES_UNPUBLISHED' : 'COM_INSTALLER_N_UPDATESITES_PUBLISHED'; + + $this->setMessage(JText::plural($ntext, count($ids))); + + $this->setRedirect(JRoute::_('index.php?option=com_installer&view=updatesites', false)); + } + + /** + * Deletes an update site (if supported). + * + * @return void + * + * @since 3.6 + * + * @throws Exception on error + */ + public function delete() + { + // Check for request forgeries. + $this->checkToken(); + + $ids = $this->input->get('cid', array(), 'array'); + + if (empty($ids)) + { + throw new Exception(JText::_('COM_INSTALLER_ERROR_NO_UPDATESITES_SELECTED'), 500); + } + + // Delete the records. + $this->getModel('Updatesites')->delete($ids); + + $this->setRedirect(JRoute::_('index.php?option=com_installer&view=updatesites', false)); + } + + /** + * Rebuild update sites tables. + * + * @return void + * + * @since 3.6 + */ + public function rebuild() + { + // Check for request forgeries. + $this->checkToken(); + + // Rebuild the update sites. + $this->getModel('Updatesites')->rebuild(); + + $this->setRedirect(JRoute::_('index.php?option=com_installer&view=updatesites', false)); + } +} diff --git a/Sites/pages/administrator/components/com_installer/helpers/html/manage.php b/Sites/pages/administrator/components/com_installer/helpers/html/manage.php new file mode 100644 index 00000000..14d5fbf6 --- /dev/null +++ b/Sites/pages/administrator/components/com_installer/helpers/html/manage.php @@ -0,0 +1,67 @@ + array( + '', + 'COM_INSTALLER_EXTENSION_PROTECTED', + '', + 'COM_INSTALLER_EXTENSION_PROTECTED', + true, + 'protected', + 'protected', + ), + 1 => array( + 'unpublish', + 'COM_INSTALLER_EXTENSION_ENABLED', + 'COM_INSTALLER_EXTENSION_DISABLE', + 'COM_INSTALLER_EXTENSION_ENABLED', + true, + 'publish', + 'publish', + ), + 0 => array( + 'publish', + 'COM_INSTALLER_EXTENSION_DISABLED', + 'COM_INSTALLER_EXTENSION_ENABLE', + 'COM_INSTALLER_EXTENSION_DISABLED', + true, + 'unpublish', + 'unpublish', + ), + ); + + return JHtml::_('jgrid.state', $states, $value, $i, 'manage.', $enabled, true, $checkbox); + } +} diff --git a/Sites/pages/administrator/components/com_installer/helpers/html/updatesites.php b/Sites/pages/administrator/components/com_installer/helpers/html/updatesites.php new file mode 100644 index 00000000..2687ee18 --- /dev/null +++ b/Sites/pages/administrator/components/com_installer/helpers/html/updatesites.php @@ -0,0 +1,57 @@ + array( + 'unpublish', + 'COM_INSTALLER_UPDATESITE_ENABLED', + 'COM_INSTALLER_UPDATESITE_DISABLE', + 'COM_INSTALLER_UPDATESITE_ENABLED', + true, + 'publish', + 'publish', + ), + 0 => array( + 'publish', + 'COM_INSTALLER_UPDATESITE_DISABLED', + 'COM_INSTALLER_UPDATESITE_ENABLE', + 'COM_INSTALLER_UPDATESITE_DISABLED', + true, + 'unpublish', + 'unpublish', + ), + ); + + return JHtml::_('jgrid.state', $states, $value, $i, 'updatesites.', $enabled, true, $checkbox); + } +} diff --git a/Sites/pages/administrator/components/com_installer/helpers/installer.php b/Sites/pages/administrator/components/com_installer/helpers/installer.php new file mode 100644 index 00000000..41b92cf1 --- /dev/null +++ b/Sites/pages/administrator/components/com_installer/helpers/installer.php @@ -0,0 +1,187 @@ +getQuery(true) + ->select('DISTINCT type') + ->from('#__extensions'); + $db->setQuery($query); + $types = $db->loadColumn(); + + $options = array(); + + foreach ($types as $type) + { + $options[] = JHtml::_('select.option', $type, JText::_('COM_INSTALLER_TYPE_' . strtoupper($type))); + } + + return $options; + } + + /** + * Get a list of filter options for the extension types. + * + * @return array An array of stdClass objects. + * + * @since 3.0 + */ + public static function getExtensionGroupes() + { + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->select('DISTINCT folder') + ->from('#__extensions') + ->where('folder != ' . $db->quote('')) + ->order('folder'); + $db->setQuery($query); + $folders = $db->loadColumn(); + + $options = array(); + + foreach ($folders as $folder) + { + $options[] = JHtml::_('select.option', $folder, $folder); + } + + return $options; + } + + /** + * Gets a list of the actions that can be performed. + * + * @return JObject + * + * @since 1.6 + * @deprecated 3.2 Use JHelperContent::getActions() instead + */ + public static function getActions() + { + // Log usage of deprecated function + try + { + JLog::add( + sprintf('%s() is deprecated. Use JHelperContent::getActions() with new arguments order instead.', __METHOD__), + JLog::WARNING, + 'deprecated' + ); + } + catch (RuntimeException $exception) + { + // Informational log only + } + + // Get list of actions + return JHelperContent::getActions('com_installer'); + } + + /** + * Get a list of filter options for the application clients. + * + * @return array An array of JHtmlOption elements. + * + * @since 3.5 + */ + public static function getClientOptions() + { + // Build the filter options. + $options = array(); + $options[] = JHtml::_('select.option', '0', JText::_('JSITE')); + $options[] = JHtml::_('select.option', '1', JText::_('JADMINISTRATOR')); + + return $options; + } + + /** + * Get a list of filter options for the application statuses. + * + * @return array An array of JHtmlOption elements. + * + * @since 3.5 + */ + public static function getStateOptions() + { + // Build the filter options. + $options = array(); + $options[] = JHtml::_('select.option', '0', JText::_('JDISABLED')); + $options[] = JHtml::_('select.option', '1', JText::_('JENABLED')); + $options[] = JHtml::_('select.option', '2', JText::_('JPROTECTED')); + $options[] = JHtml::_('select.option', '3', JText::_('JUNPROTECTED')); + + return $options; + } +} diff --git a/Sites/pages/administrator/components/com_installer/installer.php b/Sites/pages/administrator/components/com_installer/installer.php new file mode 100644 index 00000000..a9560fd3 --- /dev/null +++ b/Sites/pages/administrator/components/com_installer/installer.php @@ -0,0 +1,20 @@ +authorise('core.manage', 'com_installer')) +{ + throw new JAccessExceptionNotallowed(JText::_('JERROR_ALERTNOAUTHOR'), 403); +} + +$controller = JControllerLegacy::getInstance('Installer'); +$controller->execute(JFactory::getApplication()->input->get('task')); +$controller->redirect(); diff --git a/Sites/pages/administrator/components/com_installer/installer.xml b/Sites/pages/administrator/components/com_installer/installer.xml new file mode 100644 index 00000000..274110e3 --- /dev/null +++ b/Sites/pages/administrator/components/com_installer/installer.xml @@ -0,0 +1,28 @@ + + + com_installer + Joomla! Project + April 2006 + (C) 2005 - 2020 Open Source Matters. All rights reserved. + GNU General Public License version 2 or later; see LICENSE.txt + admin@joomla.org + www.joomla.org + 3.0.0 + COM_INSTALLER_XML_DESCRIPTION + + + config.xml + controller.php + installer.php + controllers + helpers + models + views + + + language/en-GB.com_installer.ini + language/en-GB.com_installer.sys.ini + + + + diff --git a/Sites/pages/administrator/components/com_installer/models/database.php b/Sites/pages/administrator/components/com_installer/models/database.php new file mode 100644 index 00000000..6412661e --- /dev/null +++ b/Sites/pages/administrator/components/com_installer/models/database.php @@ -0,0 +1,327 @@ +setState('message', $app->getUserState('com_installer.message')); + $this->setState('extension_message', $app->getUserState('com_installer.extension_message')); + $app->setUserState('com_installer.message', ''); + $app->setUserState('com_installer.extension_message', ''); + + // Prepare the utf8mb4 conversion check table + $this->prepareUtf8mb4StatusTable(); + + parent::populateState($ordering, $direction); + } + + /** + * Fixes database problems. + * + * @return void + */ + public function fix() + { + if (!$changeSet = $this->getItems()) + { + return false; + } + + $changeSet->fix(); + $this->fixSchemaVersion($changeSet); + $this->fixUpdateVersion(); + $installer = new JoomlaInstallerScript; + $installer->deleteUnexistingFiles(); + $this->fixDefaultTextFilters(); + + /* + * Finally, if the schema updates succeeded, make sure the database is + * converted to utf8mb4 or, if not supported by the server, compatible to it. + */ + $statusArray = $changeSet->getStatus(); + + if (count($statusArray['error']) == 0) + { + $installer->convertTablesToUtf8mb4(false); + } + } + + /** + * Gets the changeset object. + * + * @return JSchemaChangeset + */ + public function getItems() + { + $folder = JPATH_ADMINISTRATOR . '/components/com_admin/sql/updates/'; + + try + { + $changeSet = JSchemaChangeset::getInstance($this->getDbo(), $folder); + } + catch (RuntimeException $e) + { + JFactory::getApplication()->enqueueMessage($e->getMessage(), 'warning'); + + return false; + } + + return $changeSet; + } + + /** + * Method to get a JPagination object for the data set. + * + * @return boolean + * + * @since 3.0.1 + */ + public function getPagination() + { + return true; + } + + /** + * Get version from #__schemas table. + * + * @return mixed the return value from the query, or null if the query fails. + * + * @throws Exception + */ + public function getSchemaVersion() + { + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select('version_id') + ->from($db->quoteName('#__schemas')) + ->where('extension_id = 700'); + $db->setQuery($query); + $result = $db->loadResult(); + + return $result; + } + + /** + * Fix schema version if wrong. + * + * @param JSchemaChangeSet $changeSet Schema change set. + * + * @return mixed string schema version if success, false if fail. + */ + public function fixSchemaVersion($changeSet) + { + // Get correct schema version -- last file in array. + $schema = $changeSet->getSchema(); + + // Check value. If ok, don't do update. + if ($schema == $this->getSchemaVersion()) + { + return $schema; + } + + // Delete old row. + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->delete($db->quoteName('#__schemas')) + ->where($db->quoteName('extension_id') . ' = 700'); + $db->setQuery($query); + $db->execute(); + + // Add new row. + $query->clear() + ->insert($db->quoteName('#__schemas')) + ->columns($db->quoteName('extension_id') . ',' . $db->quoteName('version_id')) + ->values('700, ' . $db->quote($schema)); + $db->setQuery($query); + + try + { + $db->execute(); + } + catch (JDatabaseExceptionExecuting $e) + { + return false; + } + + return $schema; + } + + /** + * Get current version from #__extensions table. + * + * @return mixed version if successful, false if fail. + */ + public function getUpdateVersion() + { + $table = JTable::getInstance('Extension'); + $table->load('700'); + $cache = new Registry($table->manifest_cache); + + return $cache->get('version'); + } + + /** + * Fix Joomla version in #__extensions table if wrong (doesn't equal JVersion short version). + * + * @return mixed string update version if success, false if fail. + */ + public function fixUpdateVersion() + { + $table = JTable::getInstance('Extension'); + $table->load('700'); + $cache = new Registry($table->manifest_cache); + $updateVersion = $cache->get('version'); + $cmsVersion = new JVersion; + + if ($updateVersion == $cmsVersion->getShortVersion()) + { + return $updateVersion; + } + + $cache->set('version', $cmsVersion->getShortVersion()); + $table->manifest_cache = $cache->toString(); + + if ($table->store()) + { + return $cmsVersion->getShortVersion(); + } + + return false; + } + + /** + * For version 2.5.x only + * Check if com_config parameters are blank. + * + * @return string default text filters (if any). + */ + public function getDefaultTextFilters() + { + $table = JTable::getInstance('Extension'); + $table->load($table->find(array('name' => 'com_config'))); + + return $table->params; + } + + /** + * For version 2.5.x only + * Check if com_config parameters are blank. If so, populate with com_content text filters. + * + * @return mixed boolean true if params are updated, null otherwise. + */ + public function fixDefaultTextFilters() + { + $table = JTable::getInstance('Extension'); + $table->load($table->find(array('name' => 'com_config'))); + + // Check for empty $config and non-empty content filters. + if (!$table->params) + { + // Get filters from com_content and store if you find them. + $contentParams = JComponentHelper::getParams('com_content'); + + if ($contentParams->get('filters')) + { + $newParams = new Registry; + $newParams->set('filters', $contentParams->get('filters')); + $table->params = (string) $newParams; + $table->store(); + + return true; + } + } + } + + /** + * Prepare the table to save the status of utf8mb4 conversion + * Make sure it contains 1 initialized record if there is not + * already exactly 1 record. + * + * @return void + * + * @since 3.5 + */ + private function prepareUtf8mb4StatusTable() + { + $db = JFactory::getDbo(); + + $serverType = $db->getServerType(); + + if ($serverType != 'mysql') + { + return; + } + + $creaTabSql = 'CREATE TABLE IF NOT EXISTS ' . $db->quoteName('#__utf8_conversion') + . ' (' . $db->quoteName('converted') . ' tinyint(4) NOT NULL DEFAULT 0' + . ') ENGINE=InnoDB'; + + if ($db->hasUTF8mb4Support()) + { + $creaTabSql = $creaTabSql + . ' DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_unicode_ci;'; + } + else + { + $creaTabSql = $creaTabSql + . ' DEFAULT CHARSET=utf8 DEFAULT COLLATE=utf8_unicode_ci;'; + } + + $db->setQuery($creaTabSql)->execute(); + + $db->setQuery('SELECT COUNT(*) FROM ' . $db->quoteName('#__utf8_conversion') . ';'); + + $count = $db->loadResult(); + + if ($count > 1) + { + // Table messed up somehow, clear it + $db->setQuery('DELETE FROM ' . $db->quoteName('#__utf8_conversion') . ';') + ->execute(); + $db->setQuery('INSERT INTO ' . $db->quoteName('#__utf8_conversion') + . ' (' . $db->quoteName('converted') . ') VALUES (0);' + )->execute(); + } + elseif ($count == 0) + { + // Record missing somehow, fix this + $db->setQuery('INSERT INTO ' . $db->quoteName('#__utf8_conversion') + . ' (' . $db->quoteName('converted') . ') VALUES (0);' + )->execute(); + } + } +} diff --git a/Sites/pages/administrator/components/com_installer/models/discover.php b/Sites/pages/administrator/components/com_installer/models/discover.php new file mode 100644 index 00000000..8d4f4b26 --- /dev/null +++ b/Sites/pages/administrator/components/com_installer/models/discover.php @@ -0,0 +1,258 @@ +setState('filter.search', $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search', '', 'string')); + $this->setState('filter.client_id', $this->getUserStateFromRequest($this->context . '.filter.client_id', 'filter_client_id', null, 'int')); + $this->setState('filter.type', $this->getUserStateFromRequest($this->context . '.filter.type', 'filter_type', '', 'string')); + $this->setState('filter.folder', $this->getUserStateFromRequest($this->context . '.filter.folder', 'filter_folder', '', 'string')); + + $this->setState('message', $app->getUserState('com_installer.message')); + $this->setState('extension_message', $app->getUserState('com_installer.extension_message')); + + $app->setUserState('com_installer.message', ''); + $app->setUserState('com_installer.extension_message', ''); + + parent::populateState($ordering, $direction); + } + + /** + * Method to get the database query. + * + * @return JDatabaseQuery the database query + * + * @since 3.1 + */ + protected function getListQuery() + { + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select('*') + ->from($db->quoteName('#__extensions')) + ->where($db->quoteName('state') . ' = -1'); + + // Process select filters. + $type = $this->getState('filter.type'); + $clientId = $this->getState('filter.client_id'); + $folder = $this->getState('filter.folder'); + + if ($type) + { + $query->where($db->quoteName('type') . ' = ' . $db->quote($type)); + } + + if ($clientId != '') + { + $query->where($db->quoteName('client_id') . ' = ' . (int) $clientId); + } + + if ($folder != '' && in_array($type, array('plugin', 'library', ''))) + { + $query->where($db->quoteName('folder') . ' = ' . $db->quote($folder == '*' ? '' : $folder)); + } + + // Process search filter. + $search = $this->getState('filter.search'); + + if (!empty($search)) + { + if (stripos($search, 'id:') === 0) + { + $query->where($db->quoteName('extension_id') . ' = ' . (int) substr($search, 3)); + } + } + + // Note: The search for name, ordering and pagination are processed by the parent InstallerModel class (in extension.php). + + return $query; + } + + /** + * Discover extensions. + * + * Finds uninstalled extensions + * + * @return void + * + * @since 1.6 + */ + public function discover() + { + // Purge the list of discovered extensions and fetch them again. + $this->purge(); + $results = JInstaller::getInstance()->discover(); + + // Get all templates, including discovered ones + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select($db->quoteName(array('extension_id', 'element', 'folder', 'client_id', 'type'))) + ->from($db->quoteName('#__extensions')); + $db->setQuery($query); + $installedtmp = $db->loadObjectList(); + + $extensions = array(); + + foreach ($installedtmp as $install) + { + $key = implode(':', array($install->type, $install->element, $install->folder, $install->client_id)); + $extensions[$key] = $install; + } + + foreach ($results as $result) + { + // Check if we have a match on the element + $key = implode(':', array($result->type, $result->element, $result->folder, $result->client_id)); + + if (!array_key_exists($key, $extensions)) + { + // Put it into the table + $result->check(); + $result->store(); + } + } + } + + /** + * Installs a discovered extension. + * + * @return void + * + * @since 1.6 + */ + public function discover_install() + { + $app = JFactory::getApplication(); + $input = $app->input; + $eid = $input->get('cid', 0, 'array'); + + if (is_array($eid) || $eid) + { + if (!is_array($eid)) + { + $eid = array($eid); + } + + $eid = ArrayHelper::toInteger($eid); + $failed = false; + + foreach ($eid as $id) + { + $installer = new JInstaller; + + $result = $installer->discover_install($id); + + if (!$result) + { + $failed = true; + $app->enqueueMessage(JText::_('COM_INSTALLER_MSG_DISCOVER_INSTALLFAILED') . ': ' . $id); + } + } + + // TODO - We are only receiving the message for the last JInstaller instance + $this->setState('action', 'remove'); + $this->setState('name', $installer->get('name')); + $app->setUserState('com_installer.message', $installer->message); + $app->setUserState('com_installer.extension_message', $installer->get('extension_message')); + + if (!$failed) + { + $app->enqueueMessage(JText::_('COM_INSTALLER_MSG_DISCOVER_INSTALLSUCCESSFUL')); + } + } + else + { + $app->enqueueMessage(JText::_('COM_INSTALLER_MSG_DISCOVER_NOEXTENSIONSELECTED')); + } + } + + /** + * Cleans out the list of discovered extensions. + * + * @return boolean True on success + * + * @since 1.6 + */ + public function purge() + { + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->delete($db->quoteName('#__extensions')) + ->where($db->quoteName('state') . ' = -1'); + $db->setQuery($query); + + try + { + $db->execute(); + } + catch (JDatabaseExceptionExecuting $e) + { + $this->_message = JText::_('COM_INSTALLER_MSG_DISCOVER_FAILEDTOPURGEEXTENSIONS'); + + return false; + } + + $this->_message = JText::_('COM_INSTALLER_MSG_DISCOVER_PURGEDDISCOVEREDEXTENSIONS'); + + return true; + } +} diff --git a/Sites/pages/administrator/components/com_installer/models/extension.php b/Sites/pages/administrator/components/com_installer/models/extension.php new file mode 100644 index 00000000..207610b5 --- /dev/null +++ b/Sites/pages/administrator/components/com_installer/models/extension.php @@ -0,0 +1,231 @@ +getState('list.ordering', 'name'); + $listDirn = $this->getState('list.direction', 'asc'); + + // Replace slashes so preg_match will work + $search = $this->getState('filter.search'); + $search = str_replace('/', ' ', $search); + $db = $this->getDbo(); + + // Define which fields have to be processed in a custom way because of translation. + $customOrderFields = array('name', 'client_translated', 'type_translated', 'folder_translated'); + + // Process searching, ordering and pagination for fields that need to be translated. + if (in_array($listOrder, $customOrderFields) || (!empty($search) && stripos($search, 'id:') !== 0)) + { + // Get results from database and translate them. + $db->setQuery($query); + $result = $db->loadObjectList(); + $this->translate($result); + + // Process searching. + if (!empty($search) && stripos($search, 'id:') !== 0) + { + $escapedSearchString = $this->refineSearchStringToRegex($search, '/'); + + // By default search only the extension name field. + $searchFields = array('name'); + + // If in update sites view search also in the update site name field. + if ($this instanceof InstallerModelUpdatesites) + { + $searchFields[] = 'update_site_name'; + } + + foreach ($result as $i => $item) + { + // Check if search string exists in any of the fields to be searched. + $found = 0; + + foreach ($searchFields as $key => $field) + { + if (!$found && preg_match('/' . $escapedSearchString . '/i', $item->{$field})) + { + $found = 1; + } + } + + // If search string was not found in any of the fields searched remove it from results array. + if (!$found) + { + unset($result[$i]); + } + } + } + + // Process ordering. + // Sort array object by selected ordering and selected direction. Sort is case insensitive and using locale sorting. + $result = ArrayHelper::sortObjects($result, $listOrder, strtolower($listDirn) == 'desc' ? -1 : 1, false, true); + + // Process pagination. + $total = count($result); + $this->cache[$this->getStoreId('getTotal')] = $total; + + if ($total <= $limitstart) + { + $limitstart = 0; + $this->setState('list.limitstart', 0); + } + + return array_slice($result, $limitstart, $limit ?: null); + } + + // Process searching, ordering and pagination for regular database fields. + $query->order($db->quoteName($listOrder) . ' ' . $db->escape($listDirn)); + $result = parent::_getList($query, $limitstart, $limit); + $this->translate($result); + + return $result; + } + + /** + * Translate a list of objects + * + * @param array $items The array of objects + * + * @return array The array of translated objects + */ + protected function translate(&$items) + { + $lang = JFactory::getLanguage(); + + foreach ($items as &$item) + { + if (strlen($item->manifest_cache) && $data = json_decode($item->manifest_cache)) + { + foreach ($data as $key => $value) + { + if ($key == 'type') + { + // Ignore the type field + continue; + } + + $item->$key = $value; + } + } + + $item->author_info = @$item->authorEmail . '
' . @$item->authorUrl; + $item->client = $item->client_id ? JText::_('JADMINISTRATOR') : JText::_('JSITE'); + $item->client_translated = $item->client; + $item->type_translated = JText::_('COM_INSTALLER_TYPE_' . strtoupper($item->type)); + $item->folder_translated = @$item->folder ? $item->folder : JText::_('COM_INSTALLER_TYPE_NONAPPLICABLE'); + + $path = $item->client_id ? JPATH_ADMINISTRATOR : JPATH_SITE; + + switch ($item->type) + { + case 'component': + $extension = $item->element; + $source = JPATH_ADMINISTRATOR . '/components/' . $extension; + $lang->load("$extension.sys", JPATH_ADMINISTRATOR, null, false, true) + || $lang->load("$extension.sys", $source, null, false, true); + break; + case 'file': + $extension = 'files_' . $item->element; + $lang->load("$extension.sys", JPATH_SITE, null, false, true); + break; + case 'library': + $parts = explode('/', $item->element); + $vendor = (isset($parts[1]) ? $parts[0] : null); + $extension = 'lib_' . ($vendor ? implode('_', $parts) : $item->element); + + if (!$lang->load("$extension.sys", $path, null, false, true)) + { + $source = $path . '/libraries/' . ($vendor ? $vendor . '/' . $parts[1] : $item->element); + $lang->load("$extension.sys", $source, null, false, true); + } + break; + case 'module': + $extension = $item->element; + $source = $path . '/modules/' . $extension; + $lang->load("$extension.sys", $path, null, false, true) + || $lang->load("$extension.sys", $source, null, false, true); + break; + case 'plugin': + $extension = 'plg_' . $item->folder . '_' . $item->element; + $source = JPATH_PLUGINS . '/' . $item->folder . '/' . $item->element; + $lang->load("$extension.sys", JPATH_ADMINISTRATOR, null, false, true) + || $lang->load("$extension.sys", $source, null, false, true); + break; + case 'template': + $extension = 'tpl_' . $item->element; + $source = $path . '/templates/' . $item->element; + $lang->load("$extension.sys", $path, null, false, true) + || $lang->load("$extension.sys", $source, null, false, true); + break; + case 'package': + default: + $extension = $item->element; + $lang->load("$extension.sys", JPATH_SITE, null, false, true); + break; + } + + // Translate the extension name if possible + $item->name = JText::_($item->name); + + settype($item->description, 'string'); + + if (!in_array($item->type, array('language'))) + { + $item->description = JText::_($item->description); + } + } + } +} diff --git a/Sites/pages/administrator/components/com_installer/models/fields/extensionstatus.php b/Sites/pages/administrator/components/com_installer/models/fields/extensionstatus.php new file mode 100644 index 00000000..9e91a819 --- /dev/null +++ b/Sites/pages/administrator/components/com_installer/models/fields/extensionstatus.php @@ -0,0 +1,44 @@ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Sites/pages/administrator/components/com_installer/models/forms/filter_languages.xml b/Sites/pages/administrator/components/com_installer/models/forms/filter_languages.xml new file mode 100644 index 00000000..28d4ef1c --- /dev/null +++ b/Sites/pages/administrator/components/com_installer/models/forms/filter_languages.xml @@ -0,0 +1,40 @@ + +
+ + + + + + + + + + + + + + +
diff --git a/Sites/pages/administrator/components/com_installer/models/forms/filter_manage.xml b/Sites/pages/administrator/components/com_installer/models/forms/filter_manage.xml new file mode 100644 index 00000000..a0648a45 --- /dev/null +++ b/Sites/pages/administrator/components/com_installer/models/forms/filter_manage.xml @@ -0,0 +1,87 @@ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Sites/pages/administrator/components/com_installer/models/forms/filter_update.xml b/Sites/pages/administrator/components/com_installer/models/forms/filter_update.xml new file mode 100644 index 00000000..75299870 --- /dev/null +++ b/Sites/pages/administrator/components/com_installer/models/forms/filter_update.xml @@ -0,0 +1,66 @@ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Sites/pages/administrator/components/com_installer/models/forms/filter_updatesites.xml b/Sites/pages/administrator/components/com_installer/models/forms/filter_updatesites.xml new file mode 100644 index 00000000..66fa00e6 --- /dev/null +++ b/Sites/pages/administrator/components/com_installer/models/forms/filter_updatesites.xml @@ -0,0 +1,83 @@ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Sites/pages/administrator/components/com_installer/models/install.php b/Sites/pages/administrator/components/com_installer/models/install.php new file mode 100644 index 00000000..d3eaa3a7 --- /dev/null +++ b/Sites/pages/administrator/components/com_installer/models/install.php @@ -0,0 +1,433 @@ +setState('message', $app->getUserState('com_installer.message')); + $this->setState('extension_message', $app->getUserState('com_installer.extension_message')); + $app->setUserState('com_installer.message', ''); + $app->setUserState('com_installer.extension_message', ''); + + parent::populateState(); + } + + /** + * Install an extension from either folder, URL or upload. + * + * @return boolean result of install. + * + * @since 1.5 + */ + public function install() + { + $this->setState('action', 'install'); + + // Set FTP credentials, if given. + JClientHelper::setCredentialsFromRequest('ftp'); + $app = JFactory::getApplication(); + + // Load installer plugins for assistance if required: + JPluginHelper::importPlugin('installer'); + $dispatcher = JEventDispatcher::getInstance(); + + $package = null; + + // This event allows an input pre-treatment, a custom pre-packing or custom installation. + // (e.g. from a JSON description). + $results = $dispatcher->trigger('onInstallerBeforeInstallation', array($this, &$package)); + + if (in_array(true, $results, true)) + { + return true; + } + + if (in_array(false, $results, true)) + { + return false; + } + + $installType = $app->input->getWord('installtype'); + + if ($package === null) + { + switch ($installType) + { + case 'folder': + // Remember the 'Install from Directory' path. + $app->getUserStateFromRequest($this->_context . '.install_directory', 'install_directory'); + $package = $this->_getPackageFromFolder(); + break; + + case 'upload': + $package = $this->_getPackageFromUpload(); + break; + + case 'url': + $package = $this->_getPackageFromUrl(); + break; + + default: + $app->setUserState('com_installer.message', JText::_('COM_INSTALLER_NO_INSTALL_TYPE_FOUND')); + + return false; + break; + } + } + + // This event allows a custom installation of the package or a customization of the package: + $results = $dispatcher->trigger('onInstallerBeforeInstaller', array($this, &$package)); + + if (in_array(true, $results, true)) + { + return true; + } + + if (in_array(false, $results, true)) + { + if (in_array($installType, array('upload', 'url'))) + { + JInstallerHelper::cleanupInstall($package['packagefile'], $package['extractdir']); + } + + return false; + } + + // Check if package was uploaded successfully. + if (!\is_array($package)) + { + $app->enqueueMessage(JText::_('COM_INSTALLER_UNABLE_TO_FIND_INSTALL_PACKAGE'), 'error'); + + return false; + } + + // Get an installer instance. + $installer = JInstaller::getInstance(); + + /* + * Check for a Joomla core package. + * To do this we need to set the source path to find the manifest (the same first step as JInstaller::install()) + * + * This must be done before the unpacked check because JInstallerHelper::detectType() returns a boolean false since the manifest + * can't be found in the expected location. + */ + if (isset($package['dir']) && is_dir($package['dir'])) + { + $installer->setPath('source', $package['dir']); + + if (!$installer->findManifest()) + { + // If a manifest isn't found at the source, this may be a Joomla package; check the package directory for the Joomla manifest + if (file_exists($package['dir'] . '/administrator/manifests/files/joomla.xml')) + { + // We have a Joomla package + if (in_array($installType, array('upload', 'url'))) + { + JInstallerHelper::cleanupInstall($package['packagefile'], $package['extractdir']); + } + + $app->enqueueMessage( + JText::sprintf('COM_INSTALLER_UNABLE_TO_INSTALL_JOOMLA_PACKAGE', JRoute::_('index.php?option=com_joomlaupdate')), + 'warning' + ); + + return false; + } + } + } + + // Was the package unpacked? + if (empty($package['type'])) + { + if (in_array($installType, array('upload', 'url'))) + { + JInstallerHelper::cleanupInstall($package['packagefile'], $package['extractdir']); + } + + $app->enqueueMessage(JText::_('JLIB_INSTALLER_ABORT_DETECTMANIFEST'), 'error'); + + return false; + } + + // Install the package. + if (!$installer->install($package['dir'])) + { + // There was an error installing the package. + $msg = JText::sprintf('COM_INSTALLER_INSTALL_ERROR', JText::_('COM_INSTALLER_TYPE_TYPE_' . strtoupper($package['type']))); + $result = false; + $msgType = 'error'; + } + else + { + // Package installed successfully. + $msg = JText::sprintf('COM_INSTALLER_INSTALL_SUCCESS', JText::_('COM_INSTALLER_TYPE_TYPE_' . strtoupper($package['type']))); + $result = true; + $msgType = 'message'; + } + + // This event allows a custom a post-flight: + $dispatcher->trigger('onInstallerAfterInstaller', array($this, &$package, $installer, &$result, &$msg)); + + // Set some model state values. + $app = JFactory::getApplication(); + $app->enqueueMessage($msg, $msgType); + $this->setState('name', $installer->get('name')); + $this->setState('result', $result); + $app->setUserState('com_installer.message', $installer->message); + $app->setUserState('com_installer.extension_message', $installer->get('extension_message')); + $app->setUserState('com_installer.redirect_url', $installer->get('redirect_url')); + + // Cleanup the install files. + if (!is_file($package['packagefile'])) + { + $config = JFactory::getConfig(); + $package['packagefile'] = $config->get('tmp_path') . '/' . $package['packagefile']; + } + + JInstallerHelper::cleanupInstall($package['packagefile'], $package['extractdir']); + + // Clear the cached extension data and menu cache + $this->cleanCache('_system', 0); + $this->cleanCache('_system', 1); + $this->cleanCache('com_modules', 0); + $this->cleanCache('com_modules', 1); + $this->cleanCache('com_plugins', 0); + $this->cleanCache('com_plugins', 1); + $this->cleanCache('mod_menu', 0); + $this->cleanCache('mod_menu', 1); + + return $result; + } + + /** + * Works out an installation package from a HTTP upload. + * + * @return package definition or false on failure. + */ + protected function _getPackageFromUpload() + { + // Get the uploaded file information. + $input = JFactory::getApplication()->input; + + // Do not change the filter type 'raw'. We need this to let files containing PHP code to upload. See JInputFiles::get. + $userfile = $input->files->get('install_package', null, 'raw'); + + // Make sure that file uploads are enabled in php. + if (!(bool) ini_get('file_uploads')) + { + JError::raiseWarning('', JText::_('COM_INSTALLER_MSG_INSTALL_WARNINSTALLFILE')); + + return false; + } + + // Make sure that zlib is loaded so that the package can be unpacked. + if (!extension_loaded('zlib')) + { + JError::raiseWarning('', JText::_('COM_INSTALLER_MSG_INSTALL_WARNINSTALLZLIB')); + + return false; + } + + // If there is no uploaded file, we have a problem... + if (!is_array($userfile)) + { + JError::raiseWarning('', JText::_('COM_INSTALLER_MSG_INSTALL_NO_FILE_SELECTED')); + + return false; + } + + // Is the PHP tmp directory missing? + if ($userfile['error'] && ($userfile['error'] == UPLOAD_ERR_NO_TMP_DIR)) + { + JError::raiseWarning( + '', + JText::_('COM_INSTALLER_MSG_INSTALL_WARNINSTALLUPLOADERROR') . '
' . JText::_('COM_INSTALLER_MSG_WARNINGS_PHPUPLOADNOTSET') + ); + + return false; + } + + // Is the max upload size too small in php.ini? + if ($userfile['error'] && ($userfile['error'] == UPLOAD_ERR_INI_SIZE)) + { + JError::raiseWarning( + '', + JText::_('COM_INSTALLER_MSG_INSTALL_WARNINSTALLUPLOADERROR') . '
' . JText::_('COM_INSTALLER_MSG_WARNINGS_SMALLUPLOADSIZE') + ); + + return false; + } + + // Check if there was a different problem uploading the file. + if ($userfile['error'] || $userfile['size'] < 1) + { + JError::raiseWarning('', JText::_('COM_INSTALLER_MSG_INSTALL_WARNINSTALLUPLOADERROR')); + + return false; + } + + // Build the appropriate paths. + $config = JFactory::getConfig(); + $tmp_dest = $config->get('tmp_path') . '/' . $userfile['name']; + $tmp_src = $userfile['tmp_name']; + + // Move uploaded file. + jimport('joomla.filesystem.file'); + JFile::upload($tmp_src, $tmp_dest, false, true); + + // Unpack the downloaded package file. + $package = JInstallerHelper::unpack($tmp_dest, true); + + return $package; + } + + /** + * Install an extension from a directory + * + * @return array Package details or false on failure + * + * @since 1.5 + */ + protected function _getPackageFromFolder() + { + $input = JFactory::getApplication()->input; + + // Get the path to the package to install. + $p_dir = $input->getString('install_directory'); + $p_dir = JPath::clean($p_dir); + + // Did you give us a valid directory? + if (!is_dir($p_dir)) + { + JError::raiseWarning('', JText::_('COM_INSTALLER_MSG_INSTALL_PLEASE_ENTER_A_PACKAGE_DIRECTORY')); + + return false; + } + + // Detect the package type + $type = JInstallerHelper::detectType($p_dir); + + // Did you give us a valid package? + if (!$type) + { + JError::raiseWarning('', JText::_('COM_INSTALLER_MSG_INSTALL_PATH_DOES_NOT_HAVE_A_VALID_PACKAGE')); + } + + $package['packagefile'] = null; + $package['extractdir'] = null; + $package['dir'] = $p_dir; + $package['type'] = $type; + + return $package; + } + + /** + * Install an extension from a URL. + * + * @return Package details or false on failure. + * + * @since 1.5 + */ + protected function _getPackageFromUrl() + { + $input = JFactory::getApplication()->input; + + // Get the URL of the package to install. + $url = $input->getString('install_url'); + + // Did you give us a URL? + if (!$url) + { + JError::raiseWarning('', JText::_('COM_INSTALLER_MSG_INSTALL_ENTER_A_URL')); + + return false; + } + + // We only allow http & https here + $uri = new JUri($url); + + if (!in_array($uri->getScheme(), ['http', 'https'])) + { + JError::raiseWarning('', JText::_('COM_INSTALLER_MSG_INSTALL_INVALID_URL_SCHEME')); + + return false; + } + + // Handle updater XML file case: + if (preg_match('/\.xml\s*$/', $url)) + { + jimport('joomla.updater.update'); + $update = new JUpdate; + $update->loadFromXml($url); + $package_url = trim($update->get('downloadurl', false)->_data); + + if ($package_url) + { + $url = $package_url; + } + + unset($update); + } + + // Download the package at the URL given. + $p_file = JInstallerHelper::downloadPackage($url); + + // Was the package downloaded? + if (!$p_file) + { + JError::raiseWarning('', JText::_('COM_INSTALLER_MSG_INSTALL_INVALID_URL')); + + return false; + } + + $config = JFactory::getConfig(); + $tmp_dest = $config->get('tmp_path'); + + // Unpack the downloaded package file. + $package = JInstallerHelper::unpack($tmp_dest . '/' . $p_file, true); + + return $package; + } +} diff --git a/Sites/pages/administrator/components/com_installer/models/languages.php b/Sites/pages/administrator/components/com_installer/models/languages.php new file mode 100644 index 00000000..ab332cc1 --- /dev/null +++ b/Sites/pages/administrator/components/com_installer/models/languages.php @@ -0,0 +1,261 @@ +getDbo(); + $query = $db->getQuery(true) + ->select($db->qn('us.location')) + ->from($db->qn('#__extensions', 'e')) + ->where($db->qn('e.type') . ' = ' . $db->q('package')) + ->where($db->qn('e.element') . ' = ' . $db->q('pkg_en-GB')) + ->where($db->qn('e.client_id') . ' = 0') + ->join('LEFT', $db->qn('#__update_sites_extensions', 'use') . ' ON ' . $db->qn('use.extension_id') . ' = ' . $db->qn('e.extension_id')) + ->join('LEFT', $db->qn('#__update_sites', 'us') . ' ON ' . $db->qn('us.update_site_id') . ' = ' . $db->qn('use.update_site_id')); + + return $db->setQuery($query)->loadResult(); + } + + /** + * Method to get an array of data items. + * + * @return mixed An array of data items on success, false on failure. + * + * @since 3.7.0 + */ + public function getItems() + { + // Get a storage key. + $store = $this->getStoreId(); + + // Try to load the data from internal storage. + if (isset($this->cache[$store])) + { + return $this->cache[$store]; + } + + try + { + // Load the list items and add the items to the internal cache. + $this->cache[$store] = $this->getLanguages(); + } + catch (RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + + return $this->cache[$store]; + } + + /** + * Gets an array of objects from the updatesite. + * + * @return object[] An array of results. + * + * @since 3.0 + * @throws RuntimeException + */ + protected function getLanguages() + { + $updateSite = $this->getUpdateSite(); + + // Check whether the updateserver is found + if (empty($updateSite)) + { + JFactory::getApplication()->enqueueMessage(JText::_('COM_INSTALLER_MSG_WARNING_NO_LANGUAGES_UPDATESERVER'), 'warning'); + + return; + } + + $http = new JHttp; + + try + { + $response = $http->get($updateSite); + } + catch (RuntimeException $e) + { + $response = null; + } + + if ($response === null || $response->code !== 200) + { + JFactory::getApplication()->enqueueMessage(JText::sprintf('COM_INSTALLER_MSG_ERROR_CANT_CONNECT_TO_UPDATESERVER', $updateSite), 'error'); + + return; + } + + $updateSiteXML = simplexml_load_string($response->body); + $languages = array(); + $search = strtolower($this->getState('filter.search')); + + foreach ($updateSiteXML->extension as $extension) + { + $language = new stdClass; + + foreach ($extension->attributes() as $key => $value) + { + $language->$key = (string) $value; + } + + if ($search) + { + if (strpos(strtolower($language->name), $search) === false + && strpos(strtolower($language->element), $search) === false) + { + continue; + } + } + + $languages[$language->name] = $language; + } + + // Workaround for php 5.3 + $that = $this; + + // Sort the array by value of subarray + usort( + $languages, + function($a, $b) use ($that) + { + $ordering = $that->getState('list.ordering'); + + if (strtolower($that->getState('list.direction')) === 'asc') + { + return StringHelper::strcmp($a->$ordering, $b->$ordering); + } + else + { + return StringHelper::strcmp($b->$ordering, $a->$ordering); + } + } + ); + + // Count the non-paginated list + $this->languageCount = count($languages); + $limit = ($this->getState('list.limit') > 0) ? $this->getState('list.limit') : $this->languageCount; + + return array_slice($languages, $this->getStart(), $limit); + } + + /** + * Returns a record count for the updatesite. + * + * @param JDatabaseQuery|string $query The query. + * + * @return integer Number of rows for query. + * + * @since 3.7.0 + */ + protected function _getListCount($query) + { + return $this->languageCount; + } + + /** + * Method to get a store id based on model configuration state. + * + * @param string $id A prefix for the store id. + * + * @return string A store id. + * + * @since 2.5.7 + */ + protected function getStoreId($id = '') + { + // Compile the store id. + $id .= ':' . $this->getState('filter.search'); + + return parent::getStoreId($id); + } + + /** + * Method to auto-populate the model state. + * + * Note. Calling getState in this method will result in recursion. + * + * @param string $ordering list order + * @param string $direction direction in the list + * + * @return void + * + * @since 2.5.7 + */ + protected function populateState($ordering = 'name', $direction = 'asc') + { + $this->setState('filter.search', $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search', '', 'string')); + + $this->setState('extension_message', JFactory::getApplication()->getUserState('com_installer.extension_message')); + + parent::populateState($ordering, $direction); + } + + /** + * Method to compare two languages in order to sort them. + * + * @param object $lang1 The first language. + * @param object $lang2 The second language. + * + * @return integer + * + * @since 3.7.0 + */ + protected function compareLanguages($lang1, $lang2) + { + return strcmp($lang1->name, $lang2->name); + } +} diff --git a/Sites/pages/administrator/components/com_installer/models/manage.php b/Sites/pages/administrator/components/com_installer/models/manage.php new file mode 100644 index 00000000..8bdafeb0 --- /dev/null +++ b/Sites/pages/administrator/components/com_installer/models/manage.php @@ -0,0 +1,354 @@ +setState('filter.search', $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search', '', 'string')); + $this->setState('filter.client_id', $this->getUserStateFromRequest($this->context . '.filter.client_id', 'filter_client_id', null, 'int')); + $this->setState('filter.status', $this->getUserStateFromRequest($this->context . '.filter.status', 'filter_status', '', 'string')); + $this->setState('filter.type', $this->getUserStateFromRequest($this->context . '.filter.type', 'filter_type', '', 'string')); + $this->setState('filter.folder', $this->getUserStateFromRequest($this->context . '.filter.folder', 'filter_folder', '', 'string')); + + $this->setState('message', $app->getUserState('com_installer.message')); + $this->setState('extension_message', $app->getUserState('com_installer.extension_message')); + $app->setUserState('com_installer.message', ''); + $app->setUserState('com_installer.extension_message', ''); + + parent::populateState($ordering, $direction); + } + + /** + * Enable/Disable an extension. + * + * @param array $eid Extension ids to un/publish + * @param int $value Publish value + * + * @return boolean True on success + * + * @since 1.5 + */ + public function publish(&$eid = array(), $value = 1) + { + $user = JFactory::getUser(); + + if (!$user->authorise('core.edit.state', 'com_installer')) + { + JError::raiseWarning(403, JText::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED')); + + return false; + } + + $result = true; + + /* + * Ensure eid is an array of extension ids + * TODO: If it isn't an array do we want to set an error and fail? + */ + if (!is_array($eid)) + { + $eid = array($eid); + } + + // Get a table object for the extension type + $table = JTable::getInstance('Extension'); + JTable::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_templates/tables'); + + // Enable the extension in the table and store it in the database + foreach ($eid as $i => $id) + { + $table->load($id); + + if ($table->type == 'template') + { + $style = JTable::getInstance('Style', 'TemplatesTable'); + + if ($style->load(array('template' => $table->element, 'client_id' => $table->client_id, 'home' => 1))) + { + JError::raiseNotice(403, JText::_('COM_INSTALLER_ERROR_DISABLE_DEFAULT_TEMPLATE_NOT_PERMITTED')); + unset($eid[$i]); + continue; + } + } + + if ($table->protected == 1) + { + $result = false; + JError::raiseWarning(403, JText::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED')); + } + else + { + $table->enabled = $value; + } + + $context = $this->option . '.' . $this->name; + JPluginHelper::importPlugin('extension'); + JEventDispatcher::getInstance()->trigger('onExtensionChangeState', array($context, $eid, $value)); + + if (!$table->store()) + { + $this->setError($table->getError()); + $result = false; + } + } + + // Clear the cached extension data and menu cache + $this->cleanCache('_system', 0); + $this->cleanCache('_system', 1); + $this->cleanCache('com_modules', 0); + $this->cleanCache('com_modules', 1); + $this->cleanCache('mod_menu', 0); + $this->cleanCache('mod_menu', 1); + + return $result; + } + + /** + * Refreshes the cached manifest information for an extension. + * + * @param int $eid extension identifier (key in #__extensions) + * + * @return boolean result of refresh + * + * @since 1.6 + */ + public function refresh($eid) + { + if (!is_array($eid)) + { + $eid = array($eid => 0); + } + + // Get an installer object for the extension type + $installer = JInstaller::getInstance(); + $result = 0; + + // Uninstall the chosen extensions + foreach ($eid as $id) + { + $result |= $installer->refreshManifestCache($id); + } + + return $result; + } + + /** + * Remove (uninstall) an extension + * + * @param array $eid An array of identifiers + * + * @return boolean True on success + * + * @since 1.5 + */ + public function remove($eid = array()) + { + $user = JFactory::getUser(); + + if (!$user->authorise('core.delete', 'com_installer')) + { + JError::raiseWarning(403, JText::_('JERROR_CORE_DELETE_NOT_PERMITTED')); + + return false; + } + + /* + * Ensure eid is an array of extension ids in the form id => client_id + * TODO: If it isn't an array do we want to set an error and fail? + */ + if (!is_array($eid)) + { + $eid = array($eid => 0); + } + + // Get an installer object for the extension type + $installer = JInstaller::getInstance(); + $row = JTable::getInstance('extension'); + + // Uninstall the chosen extensions + $msgs = array(); + $result = false; + + foreach ($eid as $id) + { + $id = trim($id); + $row->load($id); + $result = false; + + $langstring = 'COM_INSTALLER_TYPE_TYPE_' . strtoupper($row->type); + $rowtype = JText::_($langstring); + + if (strpos($rowtype, $langstring) !== false) + { + $rowtype = $row->type; + } + + if ($row->type) + { + $result = $installer->uninstall($row->type, $id); + + // Build an array of extensions that failed to uninstall + if ($result === false) + { + // There was an error in uninstalling the package + $msgs[] = JText::sprintf('COM_INSTALLER_UNINSTALL_ERROR', $rowtype); + + continue; + } + + // Package uninstalled successfully + $msgs[] = JText::sprintf('COM_INSTALLER_UNINSTALL_SUCCESS', $rowtype); + $result = true; + + continue; + } + + // There was an error in uninstalling the package + $msgs[] = JText::sprintf('COM_INSTALLER_UNINSTALL_ERROR', $rowtype); + } + + $msg = implode('
', $msgs); + $app = JFactory::getApplication(); + $app->enqueueMessage($msg); + $this->setState('action', 'remove'); + $this->setState('name', $installer->get('name')); + $app->setUserState('com_installer.message', $installer->message); + $app->setUserState('com_installer.extension_message', $installer->get('extension_message')); + + // Clear the cached extension data and menu cache + $this->cleanCache('_system', 0); + $this->cleanCache('_system', 1); + $this->cleanCache('com_modules', 0); + $this->cleanCache('com_modules', 1); + $this->cleanCache('com_plugins', 0); + $this->cleanCache('com_plugins', 1); + $this->cleanCache('mod_menu', 0); + $this->cleanCache('mod_menu', 1); + + return $result; + } + + /** + * Method to get the database query + * + * @return JDatabaseQuery The database query + * + * @since 1.6 + */ + protected function getListQuery() + { + $query = $this->getDbo()->getQuery(true) + ->select('*') + ->select('2*protected+(1-protected)*enabled AS status') + ->from('#__extensions') + ->where('state = 0'); + + // Process select filters. + $status = $this->getState('filter.status'); + $type = $this->getState('filter.type'); + $clientId = $this->getState('filter.client_id'); + $folder = $this->getState('filter.folder'); + + if ($status != '') + { + if ($status == '2') + { + $query->where('protected = 1'); + } + elseif ($status == '3') + { + $query->where('protected = 0'); + } + else + { + $query->where('protected = 0') + ->where('enabled = ' . (int) $status); + } + } + + if ($type) + { + $query->where('type = ' . $this->_db->quote($type)); + } + + if ($clientId != '') + { + $query->where('client_id = ' . (int) $clientId); + } + + if ($folder != '') + { + $query->where('folder = ' . $this->_db->quote($folder == '*' ? '' : $folder)); + } + + // Process search filter (extension id). + $search = $this->getState('filter.search'); + + if (!empty($search) && stripos($search, 'id:') === 0) + { + $query->where('extension_id = ' . (int) substr($search, 3)); + } + + // Note: The search for name, ordering and pagination are processed by the parent InstallerModel class (in extension.php). + + return $query; + } +} diff --git a/Sites/pages/administrator/components/com_installer/models/update.php b/Sites/pages/administrator/components/com_installer/models/update.php new file mode 100644 index 00000000..9afc684b --- /dev/null +++ b/Sites/pages/administrator/components/com_installer/models/update.php @@ -0,0 +1,626 @@ +setState('filter.search', $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search', '', 'string')); + $this->setState('filter.client_id', $this->getUserStateFromRequest($this->context . '.filter.client_id', 'filter_client_id', null, 'int')); + $this->setState('filter.type', $this->getUserStateFromRequest($this->context . '.filter.type', 'filter_type', '', 'string')); + $this->setState('filter.folder', $this->getUserStateFromRequest($this->context . '.filter.folder', 'filter_folder', '', 'string')); + + $app = JFactory::getApplication(); + $this->setState('message', $app->getUserState('com_installer.message')); + $this->setState('extension_message', $app->getUserState('com_installer.extension_message')); + $app->setUserState('com_installer.message', ''); + $app->setUserState('com_installer.extension_message', ''); + + parent::populateState($ordering, $direction); + } + + /** + * Method to get the database query + * + * @return JDatabaseQuery The database query + * + * @since 1.6 + */ + protected function getListQuery() + { + $db = $this->getDbo(); + + // Grab updates ignoring new installs + $query = $db->getQuery(true) + ->select('u.*') + ->select($db->quoteName('e.manifest_cache')) + ->from($db->quoteName('#__updates', 'u')) + ->join('LEFT', $db->quoteName('#__extensions', 'e') . ' ON ' . $db->quoteName('e.extension_id') . ' = ' . $db->quoteName('u.extension_id')) + ->where($db->quoteName('u.extension_id') . ' != ' . $db->quote(0)); + + // Process select filters. + $clientId = $this->getState('filter.client_id'); + $type = $this->getState('filter.type'); + $folder = $this->getState('filter.folder'); + $extensionId = $this->getState('filter.extension_id'); + + if ($type) + { + $query->where($db->quoteName('u.type') . ' = ' . $db->quote($type)); + } + + if ($clientId != '') + { + $query->where($db->quoteName('u.client_id') . ' = ' . (int) $clientId); + } + + if ($folder != '' && in_array($type, array('plugin', 'library', ''))) + { + $query->where($db->quoteName('u.folder') . ' = ' . $db->quote($folder == '*' ? '' : $folder)); + } + + if ($extensionId) + { + $query->where($db->quoteName('u.extension_id') . ' = ' . $db->quote((int) $extensionId)); + } + else + { + $query->where($db->quoteName('u.extension_id') . ' != ' . $db->quote(0)) + ->where($db->quoteName('u.extension_id') . ' != ' . $db->quote(700)); + } + + // Process search filter. + $search = $this->getState('filter.search'); + + if (!empty($search)) + { + if (stripos($search, 'eid:') !== false) + { + $query->where($db->quoteName('u.extension_id') . ' = ' . (int) substr($search, 4)); + } + else + { + if (stripos($search, 'uid:') !== false) + { + $query->where($db->quoteName('u.update_site_id') . ' = ' . (int) substr($search, 4)); + } + elseif (stripos($search, 'id:') !== false) + { + $query->where($db->quoteName('u.update_id') . ' = ' . (int) substr($search, 3)); + } + else + { + $query->where($db->quoteName('u.name') . ' LIKE ' . $db->quote('%' . str_replace(' ', '%', $db->escape(trim($search), true)) . '%')); + } + } + } + + return $query; + } + + /** + * Translate a list of objects + * + * @param array $items The array of objects + * + * @return array The array of translated objects + * + * @since 3.5 + */ + protected function translate(&$items) + { + foreach ($items as &$item) + { + $item->client_translated = $item->client_id ? JText::_('JADMINISTRATOR') : JText::_('JSITE'); + $manifest = json_decode($item->manifest_cache); + $item->current_version = isset($manifest->version) ? $manifest->version : JText::_('JLIB_UNKNOWN'); + $item->type_translated = JText::_('COM_INSTALLER_TYPE_' . strtoupper($item->type)); + $item->folder_translated = $item->folder ?: JText::_('COM_INSTALLER_TYPE_NONAPPLICABLE'); + $item->install_type = $item->extension_id ? JText::_('COM_INSTALLER_MSG_UPDATE_UPDATE') : JText::_('COM_INSTALLER_NEW_INSTALL'); + } + + return $items; + } + + /** + * Returns an object list + * + * @param string $query The query + * @param int $limitstart Offset + * @param int $limit The number of records + * + * @return array + * + * @since 3.5 + */ + protected function _getList($query, $limitstart = 0, $limit = 0) + { + $db = $this->getDbo(); + $listOrder = $this->getState('list.ordering', 'u.name'); + $listDirn = $this->getState('list.direction', 'asc'); + + // Process ordering. + if (in_array($listOrder, array('client_translated', 'folder_translated', 'type_translated'))) + { + $db->setQuery($query); + $result = $db->loadObjectList(); + $this->translate($result); + $result = ArrayHelper::sortObjects($result, $listOrder, strtolower($listDirn) === 'desc' ? -1 : 1, true, true); + $total = count($result); + + if ($total < $limitstart) + { + $limitstart = 0; + $this->setState('list.start', 0); + } + + return array_slice($result, $limitstart, $limit ?: null); + } + else + { + $query->order($db->quoteName($listOrder) . ' ' . $db->escape($listDirn)); + + $result = parent::_getList($query, $limitstart, $limit); + $this->translate($result); + + return $result; + } + } + + /** + * Get the count of disabled update sites + * + * @return integer + * + * @since 3.4 + */ + public function getDisabledUpdateSites() + { + $db = $this->getDbo(); + + $query = $db->getQuery(true) + ->select('COUNT(*)') + ->from($db->quoteName('#__update_sites')) + ->where($db->quoteName('enabled') . ' = 0'); + + $db->setQuery($query); + + return $db->loadResult(); + } + + /** + * Finds updates for an extension. + * + * @param int $eid Extension identifier to look for + * @param int $cacheTimeout Cache timout + * @param int $minimumStability Minimum stability for updates {@see JUpdater} (0=dev, 1=alpha, 2=beta, 3=rc, 4=stable) + * + * @return boolean Result + * + * @since 1.6 + */ + public function findUpdates($eid = 0, $cacheTimeout = 0, $minimumStability = JUpdater::STABILITY_STABLE) + { + JUpdater::getInstance()->findUpdates($eid, $cacheTimeout, $minimumStability); + + return true; + } + + /** + * Removes all of the updates from the table. + * + * @return boolean result of operation + * + * @since 1.6 + */ + public function purge() + { + $db = $this->getDbo(); + + // Note: TRUNCATE is a DDL operation + // This may or may not mean depending on your database + $db->setQuery('TRUNCATE TABLE #__updates'); + + try + { + $db->execute(); + } + catch (JDatabaseExceptionExecuting $e) + { + $this->_message = JText::_('JLIB_INSTALLER_FAILED_TO_PURGE_UPDATES'); + + return false; + } + + // Reset the last update check timestamp + $query = $db->getQuery(true) + ->update($db->quoteName('#__update_sites')) + ->set($db->quoteName('last_check_timestamp') . ' = ' . $db->quote(0)); + $db->setQuery($query); + $db->execute(); + + // Clear the administrator cache + $this->cleanCache('_system', 1); + + $this->_message = JText::_('JLIB_INSTALLER_PURGED_UPDATES'); + + return true; + } + + /** + * Enables any disabled rows in #__update_sites table + * + * @return boolean result of operation + * + * @since 1.6 + */ + public function enableSites() + { + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->update($db->quoteName('#__update_sites')) + ->set($db->quoteName('enabled') . ' = 1') + ->where($db->quoteName('enabled') . ' = 0'); + $db->setQuery($query); + + try + { + $db->execute(); + } + catch (JDatabaseExceptionExecuting $e) + { + $this->_message .= JText::_('COM_INSTALLER_FAILED_TO_ENABLE_UPDATES'); + + return false; + } + + if ($rows = $db->getAffectedRows()) + { + $this->_message .= JText::plural('COM_INSTALLER_ENABLED_UPDATES', $rows); + } + + return true; + } + + /** + * Update function. + * + * Sets the "result" state with the result of the operation. + * + * @param array $uids Array[int] List of updates to apply + * @param int $minimumStability The minimum allowed stability for installed updates {@see JUpdater} + * + * @return void + * + * @since 1.6 + */ + public function update($uids, $minimumStability = JUpdater::STABILITY_STABLE) + { + $result = true; + + foreach ($uids as $uid) + { + $update = new JUpdate; + $instance = JTable::getInstance('update'); + $instance->load($uid); + $update->loadFromXml($instance->detailsurl, $minimumStability); + $update->set('extra_query', $instance->extra_query); + + $this->preparePreUpdate($update, $instance); + + // Install sets state and enqueues messages + $res = $this->install($update); + + if ($res) + { + $instance->delete($uid); + } + + $result = $res & $result; + } + + // Clear the cached extension data and menu cache + $this->cleanCache('_system', 0); + $this->cleanCache('_system', 1); + $this->cleanCache('com_modules', 0); + $this->cleanCache('com_modules', 1); + $this->cleanCache('com_plugins', 0); + $this->cleanCache('com_plugins', 1); + $this->cleanCache('mod_menu', 0); + $this->cleanCache('mod_menu', 1); + + // Set the final state + $this->setState('result', $result); + } + + /** + * Handles the actual update installation. + * + * @param JUpdate $update An update definition + * + * @return boolean Result of install + * + * @since 1.6 + */ + private function install($update) + { + $app = JFactory::getApplication(); + + if (!isset($update->get('downloadurl')->_data)) + { + JError::raiseWarning('', JText::_('COM_INSTALLER_INVALID_EXTENSION_UPDATE')); + + return false; + } + + $url = trim($update->downloadurl->_data); + $sources = $update->get('downloadSources', array()); + + if ($extra_query = $update->get('extra_query')) + { + $url .= (strpos($url, '?') === false) ? '?' : '&'; + $url .= $extra_query; + } + + $mirror = 0; + + while (!($p_file = InstallerHelper::downloadPackage($url)) && isset($sources[$mirror])) + { + $name = $sources[$mirror]; + $url = trim($name->url); + + if ($extra_query) + { + $url .= (strpos($url, '?') === false) ? '?' : '&'; + $url .= $extra_query; + } + + $mirror++; + } + + // Was the package downloaded? + if (!$p_file) + { + JError::raiseWarning('', JText::sprintf('COM_INSTALLER_PACKAGE_DOWNLOAD_FAILED', $url)); + + return false; + } + + $config = JFactory::getConfig(); + $tmp_dest = $config->get('tmp_path'); + + // Unpack the downloaded package file + $package = InstallerHelper::unpack($tmp_dest . '/' . $p_file); + + if (empty($package)) + { + $app->enqueueMessage(JText::sprintf('COM_INSTALLER_UNPACK_ERROR', $p_file), 'error'); + + return false; + } + + // Get an installer instance + $installer = JInstaller::getInstance(); + $update->set('type', $package['type']); + + // Check the package + $check = InstallerHelper::isChecksumValid($package['packagefile'], $update); + + // The validation was not successful. Just a warning for now. + // TODO: In Joomla 4 this will abort the installation + if ($check === InstallerHelper::HASH_NOT_VALIDATED) + { + $app->enqueueMessage(JText::_('COM_INSTALLER_INSTALL_CHECKSUM_WRONG'), 'error'); + } + + // Install the package + if (!$installer->update($package['dir'])) + { + // There was an error updating the package + $app->enqueueMessage( + JText::sprintf('COM_INSTALLER_MSG_UPDATE_ERROR', + JText::_('COM_INSTALLER_TYPE_TYPE_' . strtoupper($package['type'])) + ), 'error' + ); + $result = false; + } + else + { + // Package updated successfully + $app->enqueueMessage( + JText::sprintf('COM_INSTALLER_MSG_UPDATE_SUCCESS', + JText::_('COM_INSTALLER_TYPE_TYPE_' . strtoupper($package['type'])) + ) + ); + $result = true; + } + + // Quick change + $this->type = $package['type']; + + // TODO: Reconfigure this code when you have more battery life left + $this->setState('name', $installer->get('name')); + $this->setState('result', $result); + $app->setUserState('com_installer.message', $installer->message); + $app->setUserState('com_installer.extension_message', $installer->get('extension_message')); + + // Cleanup the install files + if (!is_file($package['packagefile'])) + { + $config = JFactory::getConfig(); + $package['packagefile'] = $config->get('tmp_path') . '/' . $package['packagefile']; + } + + InstallerHelper::cleanupInstall($package['packagefile'], $package['extractdir']); + + return $result; + } + + /** + * Method to get the row form. + * + * @param array $data Data for the form. + * @param boolean $loadData True if the form is to load its own data (default case), false if not. + * + * @return mixed A JForm object on success, false on failure + * + * @since 2.5.2 + */ + public function getForm($data = array(), $loadData = true) + { + // Get the form. + JForm::addFormPath(JPATH_COMPONENT . '/models/forms'); + JForm::addFieldPath(JPATH_COMPONENT . '/models/fields'); + $form = JForm::getInstance('com_installer.update', 'update', array('load_data' => $loadData)); + + // Check for an error. + if ($form == false) + { + $this->setError($form->getMessage()); + + return false; + } + + // Check the session for previously entered form data. + $data = $this->loadFormData(); + + // Bind the form data if present. + if (!empty($data)) + { + $form->bind($data); + } + + return $form; + } + + /** + * Method to get the data that should be injected in the form. + * + * @return mixed The data for the form. + * + * @since 2.5.2 + */ + protected function loadFormData() + { + // Check the session for previously entered form data. + $data = JFactory::getApplication()->getUserState($this->context, array()); + + return $data; + } + + /** + * Method to add parameters to the update + * + * @param JUpdate $update An update definition + * @param JTableUpdate $table The update instance from the database + * + * @return void + * + * @since 3.7.0 + */ + protected function preparePreUpdate($update, $table) + { + jimport('joomla.filesystem.file'); + + switch ($table->type) + { + // Components could have a helper which adds additional data + case 'component': + $ename = str_replace('com_', '', $table->element); + $fname = $ename . '.php'; + $cname = ucfirst($ename) . 'Helper'; + + $path = JPATH_ADMINISTRATOR . '/components/' . $table->element . '/helpers/' . $fname; + + if (JFile::exists($path)) + { + require_once $path; + + if (class_exists($cname) && is_callable(array($cname, 'prepareUpdate'))) + { + call_user_func_array(array($cname, 'prepareUpdate'), array(&$update, &$table)); + } + } + + break; + + // Modules could have a helper which adds additional data + case 'module': + $cname = str_replace('_', '', $table->element) . 'Helper'; + $path = ($table->client_id ? JPATH_ADMINISTRATOR : JPATH_SITE) . '/modules/' . $table->element . '/helper.php'; + + if (JFile::exists($path)) + { + require_once $path; + + if (class_exists($cname) && is_callable(array($cname, 'prepareUpdate'))) + { + call_user_func_array(array($cname, 'prepareUpdate'), array(&$update, &$table)); + } + } + + break; + + // If we have a plugin, we can use the plugin trigger "onInstallerBeforePackageDownload" + // But we should make sure, that our plugin is loaded, so we don't need a second "installer" plugin + case 'plugin': + $cname = str_replace('plg_', '', $table->element); + JPluginHelper::importPlugin($table->folder, $cname); + break; + } + } +} diff --git a/Sites/pages/administrator/components/com_installer/models/updatesites.php b/Sites/pages/administrator/components/com_installer/models/updatesites.php new file mode 100644 index 00000000..ce8af0cf --- /dev/null +++ b/Sites/pages/administrator/components/com_installer/models/updatesites.php @@ -0,0 +1,472 @@ +setState('filter.search', $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search', '', 'string')); + $this->setState('filter.client_id', $this->getUserStateFromRequest($this->context . '.filter.client_id', 'filter_client_id', null, 'int')); + $this->setState('filter.enabled', $this->getUserStateFromRequest($this->context . '.filter.enabled', 'filter_enabled', '', 'string')); + $this->setState('filter.type', $this->getUserStateFromRequest($this->context . '.filter.type', 'filter_type', '', 'string')); + $this->setState('filter.folder', $this->getUserStateFromRequest($this->context . '.filter.folder', 'filter_folder', '', 'string')); + + parent::populateState($ordering, $direction); + } + + /** + * Enable/Disable an extension. + * + * @param array $eid Extension ids to un/publish + * @param int $value Publish value + * + * @return boolean True on success + * + * @since 3.4 + * + * @throws Exception on ACL error + */ + public function publish(&$eid = array(), $value = 1) + { + if (!JFactory::getUser()->authorise('core.edit.state', 'com_installer')) + { + throw new Exception(JText::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED'), 403); + } + + $result = true; + + // Ensure eid is an array of extension ids + if (!is_array($eid)) + { + $eid = array($eid); + } + + // Get a table object for the extension type + $table = JTable::getInstance('Updatesite'); + + // Enable the update site in the table and store it in the database + foreach ($eid as $i => $id) + { + $table->load($id); + $table->enabled = $value; + + if (!$table->store()) + { + $this->setError($table->getError()); + $result = false; + } + } + + return $result; + } + + /** + * Deletes an update site. + * + * @param array $ids Extension ids to delete. + * + * @return void + * + * @since 3.6 + * + * @throws Exception on ACL error + */ + public function delete($ids = array()) + { + if (!JFactory::getUser()->authorise('core.delete', 'com_installer')) + { + throw new Exception(JText::_('JLIB_APPLICATION_ERROR_DELETE_NOT_PERMITTED'), 403); + } + + // Ensure eid is an array of extension ids + if (!is_array($ids)) + { + $ids = array($ids); + } + + $db = JFactory::getDbo(); + $app = JFactory::getApplication(); + + $count = 0; + + // Gets the update site names. + $query = $db->getQuery(true) + ->select($db->qn(array('update_site_id', 'name'))) + ->from($db->qn('#__update_sites')) + ->where($db->qn('update_site_id') . ' IN (' . implode(', ', $ids) . ')'); + $db->setQuery($query); + $updateSitesNames = $db->loadObjectList('update_site_id'); + + // Gets Joomla core update sites Ids. + $joomlaUpdateSitesIds = $this->getJoomlaUpdateSitesIds(0); + + // Enable the update site in the table and store it in the database + foreach ($ids as $i => $id) + { + // Don't allow to delete Joomla Core update sites. + if (in_array((int) $id, $joomlaUpdateSitesIds)) + { + $app->enqueueMessage(JText::sprintf('COM_INSTALLER_MSG_UPDATESITES_DELETE_CANNOT_DELETE', $updateSitesNames[$id]->name), 'error'); + continue; + } + + // Delete the update site from all tables. + try + { + $query = $db->getQuery(true) + ->delete($db->qn('#__update_sites')) + ->where($db->qn('update_site_id') . ' = ' . (int) $id); + $db->setQuery($query); + $db->execute(); + + $query = $db->getQuery(true) + ->delete($db->qn('#__update_sites_extensions')) + ->where($db->qn('update_site_id') . ' = ' . (int) $id); + $db->setQuery($query); + $db->execute(); + + $query = $db->getQuery(true) + ->delete($db->qn('#__updates')) + ->where($db->qn('update_site_id') . ' = ' . (int) $id); + $db->setQuery($query); + $db->execute(); + + $count++; + } + catch (RuntimeException $e) + { + $app->enqueueMessage(JText::sprintf('COM_INSTALLER_MSG_UPDATESITES_DELETE_ERROR', $updateSitesNames[$id]->name, $e->getMessage()), 'error'); + } + } + + if ($count > 0) + { + $app->enqueueMessage(JText::plural('COM_INSTALLER_MSG_UPDATESITES_N_DELETE_UPDATESITES_DELETED', $count), 'message'); + } + } + + /** + * Rebuild update sites tables. + * + * @return void + * + * @since 3.6 + * + * @throws Exception on ACL error + */ + public function rebuild() + { + if (!JFactory::getUser()->authorise('core.admin', 'com_installer')) + { + throw new Exception(JText::_('COM_INSTALLER_MSG_UPDATESITES_REBUILD_NOT_PERMITTED'), 403); + } + + $db = JFactory::getDbo(); + $app = JFactory::getApplication(); + + // Check if Joomla Extension plugin is enabled. + if (!JPluginHelper::isEnabled('extension', 'joomla')) + { + $query = $db->getQuery(true) + ->select($db->quoteName('extension_id')) + ->from($db->quoteName('#__extensions')) + ->where($db->quoteName('type') . ' = ' . $db->quote('plugin')) + ->where($db->quoteName('element') . ' = ' . $db->quote('joomla')) + ->where($db->quoteName('folder') . ' = ' . $db->quote('extension')); + $db->setQuery($query); + + $pluginId = (int) $db->loadResult(); + + $link = JRoute::_('index.php?option=com_plugins&task=plugin.edit&extension_id=' . $pluginId); + $app->enqueueMessage(JText::sprintf('COM_INSTALLER_MSG_UPDATESITES_REBUILD_EXTENSION_PLUGIN_NOT_ENABLED', $link), 'error'); + + return; + } + + $clients = array(JPATH_SITE, JPATH_ADMINISTRATOR); + $extensionGroupFolders = array('components', 'modules', 'plugins', 'templates', 'language', 'manifests'); + + $pathsToSearch = array(); + + // Identifies which folders to search for manifest files. + foreach ($clients as $clientPath) + { + foreach ($extensionGroupFolders as $extensionGroupFolderName) + { + // Components, modules, plugins, templates, languages and manifest (files, libraries, etc) + if ($extensionGroupFolderName != 'plugins') + { + foreach (glob($clientPath . '/' . $extensionGroupFolderName . '/*', GLOB_NOSORT | GLOB_ONLYDIR) as $extensionFolderPath) + { + $pathsToSearch[] = $extensionFolderPath; + } + } + + // Plugins (another directory level is needed) + else + { + foreach (glob($clientPath . '/' . $extensionGroupFolderName . '/*', GLOB_NOSORT | GLOB_ONLYDIR) as $pluginGroupFolderPath) + { + foreach (glob($pluginGroupFolderPath . '/*', GLOB_NOSORT | GLOB_ONLYDIR) as $extensionFolderPath) + { + $pathsToSearch[] = $extensionFolderPath; + } + } + } + } + } + + // Gets Joomla core update sites Ids. + $joomlaUpdateSitesIds = implode(', ', $this->getJoomlaUpdateSitesIds(0)); + + // Delete from all tables (except joomla core update sites). + $query = $db->getQuery(true) + ->delete($db->quoteName('#__update_sites')) + ->where($db->quoteName('update_site_id') . ' NOT IN (' . $joomlaUpdateSitesIds . ')'); + $db->setQuery($query); + $db->execute(); + + $query = $db->getQuery(true) + ->delete($db->quoteName('#__update_sites_extensions')) + ->where($db->quoteName('update_site_id') . ' NOT IN (' . $joomlaUpdateSitesIds . ')'); + $db->setQuery($query); + $db->execute(); + + $query = $db->getQuery(true) + ->delete($db->quoteName('#__updates')) + ->where($db->quoteName('update_site_id') . ' NOT IN (' . $joomlaUpdateSitesIds . ')'); + $db->setQuery($query); + $db->execute(); + + $count = 0; + + // Gets Joomla core extension Ids. + $joomlaCoreExtensionIds = implode(', ', $this->getJoomlaUpdateSitesIds(1)); + + // Search for updateservers in manifest files inside the folders to search. + foreach ($pathsToSearch as $extensionFolderPath) + { + $tmpInstaller = new JInstaller; + + $tmpInstaller->setPath('source', $extensionFolderPath); + + // Main folder manifests (higher priority) + $parentXmlfiles = JFolder::files($tmpInstaller->getPath('source'), '.xml$', false, true); + + // Search for children manifests (lower priority) + $allXmlFiles = JFolder::files($tmpInstaller->getPath('source'), '.xml$', 1, true); + + // Create an unique array of files ordered by priority + $xmlfiles = array_unique(array_merge($parentXmlfiles, $allXmlFiles)); + + if (!empty($xmlfiles)) + { + foreach ($xmlfiles as $file) + { + // Is it a valid Joomla installation manifest file? + $manifest = $tmpInstaller->isManifest($file); + + if (!is_null($manifest)) + { + // Search if the extension exists in the extensions table. Excluding joomla core extensions (id < 10000) and discovered extensions. + $query = $db->getQuery(true) + ->select($db->quoteName('extension_id')) + ->from($db->quoteName('#__extensions')) + ->where('(' + . $db->quoteName('name') . ' = ' . $db->quote($manifest->name) + . ' OR ' . $db->quoteName('name') . ' = ' . $db->quote($manifest->packagename) + . ')' ) + ->where($db->quoteName('type') . ' = ' . $db->quote($manifest['type'])) + ->where($db->quoteName('extension_id') . ' NOT IN (' . $joomlaCoreExtensionIds . ')') + ->where($db->quoteName('state') . ' != -1'); + $db->setQuery($query); + + $eid = (int) $db->loadResult(); + + if ($eid && $manifest->updateservers) + { + // Set the manifest object and path + $tmpInstaller->manifest = $manifest; + $tmpInstaller->setPath('manifest', $file); + + // Load the extension plugin (if not loaded yet). + JPluginHelper::importPlugin('extension', 'joomla'); + + // Fire the onExtensionAfterUpdate + JEventDispatcher::getInstance()->trigger('onExtensionAfterUpdate', array('installer' => $tmpInstaller, 'eid' => $eid)); + + $count++; + } + } + } + } + } + + if ($count > 0) + { + $app->enqueueMessage(JText::_('COM_INSTALLER_MSG_UPDATESITES_REBUILD_SUCCESS'), 'message'); + } + else + { + $app->enqueueMessage(JText::_('COM_INSTALLER_MSG_UPDATESITES_REBUILD_MESSAGE'), 'message'); + } + } + + /** + * Fetch the Joomla update sites ids. + * + * @param integer $column Column to return. 0 for update site ids, 1 for extension ids. + * + * @return array Array with joomla core update site ids. + * + * @since 3.6.0 + */ + protected function getJoomlaUpdateSitesIds($column = 0) + { + $db = JFactory::getDbo(); + + // Fetch the Joomla core update sites ids and their extension ids. We search for all except the core joomla extension with update sites. + $query = $db->getQuery(true) + ->select($db->quoteName(array('use.update_site_id', 'e.extension_id'))) + ->from($db->quoteName('#__update_sites_extensions', 'use')) + ->join('LEFT', $db->quoteName('#__update_sites', 'us') . ' ON ' . $db->qn('us.update_site_id') . ' = ' . $db->qn('use.update_site_id')) + ->join('LEFT', $db->quoteName('#__extensions', 'e') . ' ON ' . $db->qn('e.extension_id') . ' = ' . $db->qn('use.extension_id')) + ->where('(' + . '(' . $db->qn('e.type') . ' = ' . $db->quote('file') . ' AND ' . $db->qn('e.element') . ' = ' . $db->quote('joomla') . ')' + . ' OR (' . $db->qn('e.type') . ' = ' . $db->quote('package') . ' AND ' . $db->qn('e.element') . ' = ' . $db->quote('pkg_en-GB') . ')' + . ' OR (' . $db->qn('e.type') . ' = ' . $db->quote('component') . ' AND ' . $db->qn('e.element') . ' = ' . $db->quote('com_joomlaupdate') . ')' + . ')' + ); + + $db->setQuery($query); + + return $db->loadColumn($column); + } + + /** + * Method to get the database query + * + * @return JDatabaseQuery The database query + * + * @since 3.4 + */ + protected function getListQuery() + { + $query = JFactory::getDbo()->getQuery(true) + ->select( + array( + 's.update_site_id', + 's.name AS update_site_name', + 's.type AS update_site_type', + 's.location', + 's.enabled', + 'e.extension_id', + 'e.name', + 'e.type', + 'e.element', + 'e.folder', + 'e.client_id', + 'e.state', + 'e.manifest_cache', + ) + ) + ->from('#__update_sites AS s') + ->innerJoin('#__update_sites_extensions AS se ON (se.update_site_id = s.update_site_id)') + ->innerJoin('#__extensions AS e ON (e.extension_id = se.extension_id)') + ->where('state = 0'); + + // Process select filters. + $enabled = $this->getState('filter.enabled'); + $type = $this->getState('filter.type'); + $clientId = $this->getState('filter.client_id'); + $folder = $this->getState('filter.folder'); + + if ($enabled != '') + { + $query->where('s.enabled = ' . (int) $enabled); + } + + if ($type) + { + $query->where('e.type = ' . $this->_db->quote($type)); + } + + if ($clientId != '') + { + $query->where('e.client_id = ' . (int) $clientId); + } + + if ($folder != '' && in_array($type, array('plugin', 'library', ''))) + { + $query->where('e.folder = ' . $this->_db->quote($folder == '*' ? '' : $folder)); + } + + // Process search filter (update site id). + $search = $this->getState('filter.search'); + + if (!empty($search) && stripos($search, 'id:') === 0) + { + $query->where('s.update_site_id = ' . (int) substr($search, 3)); + } + + // Note: The search for name, ordering and pagination are processed by the parent InstallerModel class (in extension.php). + + return $query; + } +} diff --git a/Sites/pages/administrator/components/com_installer/models/warnings.php b/Sites/pages/administrator/components/com_installer/models/warnings.php new file mode 100644 index 00000000..cb05def7 --- /dev/null +++ b/Sites/pages/administrator/components/com_installer/models/warnings.php @@ -0,0 +1,169 @@ + JText::_('COM_INSTALLER_MSG_WARNINGS_FILEUPLOADSDISABLED'), + 'description' => JText::_('COM_INSTALLER_MSG_WARNINGS_FILEUPLOADISDISABLEDDESC')); + } + + $upload_dir = ini_get('upload_tmp_dir'); + + if (!$upload_dir) + { + $messages[] = array('message' => JText::_('COM_INSTALLER_MSG_WARNINGS_PHPUPLOADNOTSET'), + 'description' => JText::_('COM_INSTALLER_MSG_WARNINGS_PHPUPLOADNOTSETDESC')); + } + else + { + if (!is_writeable($upload_dir)) + { + $messages[] = array('message' => JText::_('COM_INSTALLER_MSG_WARNINGS_PHPUPLOADNOTWRITEABLE'), + 'description' => JText::sprintf('COM_INSTALLER_MSG_WARNINGS_PHPUPLOADNOTWRITEABLEDESC', $upload_dir)); + } + } + + $config = JFactory::getConfig(); + $tmp_path = $config->get('tmp_path'); + + if (!$tmp_path) + { + $messages[] = array('message' => JText::_('COM_INSTALLER_MSG_WARNINGS_JOOMLATMPNOTSET'), + 'description' => JText::_('COM_INSTALLER_MSG_WARNINGS_JOOMLATMPNOTSETDESC')); + } + else + { + if (!is_writeable($tmp_path)) + { + $messages[] = array('message' => JText::_('COM_INSTALLER_MSG_WARNINGS_JOOMLATMPNOTWRITEABLE'), + 'description' => JText::sprintf('COM_INSTALLER_MSG_WARNINGS_JOOMLATMPNOTWRITEABLEDESC', $tmp_path)); + } + } + + $memory_limit = $this->return_bytes(ini_get('memory_limit')); + + if ($memory_limit < (8 * 1024 * 1024) && $memory_limit != -1) + { + // 8MB + $messages[] = array('message' => JText::_('COM_INSTALLER_MSG_WARNINGS_LOWMEMORYWARN'), + 'description' => JText::_('COM_INSTALLER_MSG_WARNINGS_LOWMEMORYDESC')); + } + elseif ($memory_limit < (16 * 1024 * 1024) && $memory_limit != -1) + { + // 16MB + $messages[] = array('message' => JText::_('COM_INSTALLER_MSG_WARNINGS_MEDMEMORYWARN'), + 'description' => JText::_('COM_INSTALLER_MSG_WARNINGS_MEDMEMORYDESC')); + } + + $post_max_size = $this->return_bytes(ini_get('post_max_size')); + $upload_max_filesize = $this->return_bytes(ini_get('upload_max_filesize')); + + if ($post_max_size < $upload_max_filesize) + { + $messages[] = array('message' => JText::_('COM_INSTALLER_MSG_WARNINGS_UPLOADBIGGERTHANPOST'), + 'description' => JText::_('COM_INSTALLER_MSG_WARNINGS_UPLOADBIGGERTHANPOSTDESC')); + } + + if ($post_max_size < (8 * 1024 * 1024)) // 8MB + { + $messages[] = array('message' => JText::_('COM_INSTALLER_MSG_WARNINGS_SMALLPOSTSIZE'), + 'description' => JText::_('COM_INSTALLER_MSG_WARNINGS_SMALLPOSTSIZEDESC')); + } + + if ($upload_max_filesize < (8 * 1024 * 1024)) // 8MB + { + $messages[] = array('message' => JText::_('COM_INSTALLER_MSG_WARNINGS_SMALLUPLOADSIZE'), + 'description' => JText::_('COM_INSTALLER_MSG_WARNINGS_SMALLUPLOADSIZEDESC')); + } + + return $messages; + } +} diff --git a/Sites/pages/administrator/components/com_installer/views/database/tmpl/default.php b/Sites/pages/administrator/components/com_installer/views/database/tmpl/default.php new file mode 100644 index 00000000..bdfd8111 --- /dev/null +++ b/Sites/pages/administrator/components/com_installer/views/database/tmpl/default.php @@ -0,0 +1,77 @@ + +
+
+ + sidebar)) : ?> +
+ sidebar; ?> +
+
+ +
+ + errorCount === 0) : ?> + 'other')); ?> + + 'problems')); ?> + errorCount)); ?> +
+
    + filterParams) : ?> +
  • + + + schemaVersion != $this->changeSet->getSchema()) : ?> +
  • schemaVersion, $this->changeSet->getSchema()); ?>
  • + + + updateVersion, JVERSION) != 0) : ?> +
  • updateVersion, JVERSION); ?>
  • + + + errors as $line => $error) : ?> + queryType; + $msgs = $error->msgElements; + $file = basename($error->file); + $msg0 = isset($msgs[0]) ? $msgs[0] : ' '; + $msg1 = isset($msgs[1]) ? $msgs[1] : ' '; + $msg2 = isset($msgs[2]) ? $msgs[2] : ' '; + $message = JText::sprintf($key, $file, $msg0, $msg1, $msg2); ?> +
  • + +
+
+ + + +
+
+
    +
  • schemaVersion); ?>
  • +
  • updateVersion); ?>
  • +
  • name); ?>
  • +
  • results['ok'])); ?>
  • +
  • results['skipped'])); ?>
  • +
+
+
+ + + + + + +
+ +
diff --git a/Sites/pages/administrator/components/com_installer/views/database/tmpl/default.xml b/Sites/pages/administrator/components/com_installer/views/database/tmpl/default.xml new file mode 100755 index 00000000..c0285983 --- /dev/null +++ b/Sites/pages/administrator/components/com_installer/views/database/tmpl/default.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/Sites/pages/administrator/components/com_installer/views/database/view.html.php b/Sites/pages/administrator/components/com_installer/views/database/view.html.php new file mode 100644 index 00000000..657b85bc --- /dev/null +++ b/Sites/pages/administrator/components/com_installer/views/database/view.html.php @@ -0,0 +1,92 @@ +state = $this->get('State'); + $this->changeSet = $this->get('Items'); + $this->errors = $this->changeSet->check(); + $this->results = $this->changeSet->getStatus(); + $this->schemaVersion = $this->get('SchemaVersion'); + $this->updateVersion = $this->get('UpdateVersion'); + $this->filterParams = $this->get('DefaultTextFilters'); + $this->schemaVersion = $this->schemaVersion ?: JText::_('JNONE'); + $this->updateVersion = $this->updateVersion ?: JText::_('JNONE'); + $this->pagination = $this->get('Pagination'); + $this->errorCount = count($this->errors); + + if ($this->schemaVersion != $this->changeSet->getSchema()) + { + $this->errorCount++; + } + + if (!$this->filterParams) + { + $this->errorCount++; + } + + if (version_compare($this->updateVersion, JVERSION) != 0) + { + $this->errorCount++; + } + + if ($this->errorCount === 0) + { + $app->enqueueMessage(JText::_('COM_INSTALLER_MSG_DATABASE_OK'), 'notice'); + } + else + { + $app->enqueueMessage(JText::_('COM_INSTALLER_MSG_DATABASE_ERRORS'), 'warning'); + } + + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + /* + * Set toolbar items for the page. + */ + JToolbarHelper::custom('database.fix', 'refresh', 'refresh', 'COM_INSTALLER_TOOLBAR_DATABASE_FIX', false); + JToolbarHelper::divider(); + parent::addToolbar(); + JToolbarHelper::help('JHELP_EXTENSIONS_EXTENSION_MANAGER_DATABASE'); + } +} diff --git a/Sites/pages/administrator/components/com_installer/views/default/tmpl/default_ftp.php b/Sites/pages/administrator/components/com_installer/views/default/tmpl/default_ftp.php new file mode 100644 index 00000000..d9b18437 --- /dev/null +++ b/Sites/pages/administrator/components/com_installer/views/default/tmpl/default_ftp.php @@ -0,0 +1,42 @@ + +
+ + + + + ftp instanceof Exception) : ?> +

ftp->getMessage()); ?>

+ + + + + + + + + + + + + +
+ + + +
+ + + +
+ +
diff --git a/Sites/pages/administrator/components/com_installer/views/default/tmpl/default_message.php b/Sites/pages/administrator/components/com_installer/views/default/tmpl/default_message.php new file mode 100644 index 00000000..5e6f1a7a --- /dev/null +++ b/Sites/pages/administrator/components/com_installer/views/default/tmpl/default_message.php @@ -0,0 +1,30 @@ +get('State'); +$message1 = $state->get('message'); +$message2 = $state->get('extension_message'); +?> + + +
+
+ +
+
+ + +
+
+ +
+
+ diff --git a/Sites/pages/administrator/components/com_installer/views/default/view.php b/Sites/pages/administrator/components/com_installer/views/default/view.php new file mode 100644 index 00000000..33447153 --- /dev/null +++ b/Sites/pages/administrator/components/com_installer/views/default/view.php @@ -0,0 +1,86 @@ +_addPath('template', $this->_basePath . '/views/default/tmpl'); + $this->_addPath('template', JPATH_THEMES . '/' . $app->getTemplate() . '/html/com_installer/default'); + } + + /** + * Display the view. + * + * @param string $tpl Template + * + * @return void + * + * @since 1.5 + */ + public function display($tpl = null) + { + // Get data from the model. + $state = $this->get('State'); + + // Are there messages to display? + $showMessage = false; + + if (is_object($state)) + { + $message1 = $state->get('message'); + $message2 = $state->get('extension_message'); + $showMessage = ($message1 || $message2); + } + + $this->showMessage = $showMessage; + $this->state = &$state; + + $this->addToolbar(); + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + $canDo = JHelperContent::getActions('com_installer'); + JToolbarHelper::title(JText::_('COM_INSTALLER_HEADER_' . $this->getName()), 'puzzle install'); + + if ($canDo->get('core.admin') || $canDo->get('core.options')) + { + JToolbarHelper::preferences('com_installer'); + JToolbarHelper::divider(); + } + + // Render side bar. + $this->sidebar = JHtmlSidebar::render(); + } +} diff --git a/Sites/pages/administrator/components/com_installer/views/discover/tmpl/default.php b/Sites/pages/administrator/components/com_installer/views/discover/tmpl/default.php new file mode 100644 index 00000000..c72ba023 --- /dev/null +++ b/Sites/pages/administrator/components/com_installer/views/discover/tmpl/default.php @@ -0,0 +1,127 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +?> +
+
+ sidebar)) : ?> +
+ sidebar; ?> +
+
+ +
+ + showMessage) : ?> + loadTemplate('message'); ?> + + ftp) : ?> + loadTemplate('ftp'); ?> + + $this)); ?> +
+
+ +
+ items)) : ?> +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + items as $i => $item) : ?> + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + +
pagination->getListFooter(); ?>
+ extension_id); ?> + + + + client_translated; ?> + + type_translated; ?> + + version != '' ? $item->version : ' '; ?> + + creationDate != '' ? $item->creationDate : ' '; ?> + + + author != '' ? $item->author : ' '; ?> + + + folder_translated; ?> + + extension_id; ?> +
+ + + + +
+ +
diff --git a/Sites/pages/administrator/components/com_installer/views/discover/tmpl/default.xml b/Sites/pages/administrator/components/com_installer/views/discover/tmpl/default.xml new file mode 100755 index 00000000..350dddaf --- /dev/null +++ b/Sites/pages/administrator/components/com_installer/views/discover/tmpl/default.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/Sites/pages/administrator/components/com_installer/views/discover/tmpl/default_item.php b/Sites/pages/administrator/components/com_installer/views/discover/tmpl/default_item.php new file mode 100644 index 00000000..58890b40 --- /dev/null +++ b/Sites/pages/administrator/components/com_installer/views/discover/tmpl/default_item.php @@ -0,0 +1,35 @@ + +item->style; ?>> + + item->cbd; ?> /> + + item->name; ?> + + + item->type ?> + + + item->element) : ?> + X + + item->img, $this->item->alt, array('title' => $this->item->action)); ?> + + + item->folder != '' ? $this->item->folder : 'N/A'; ?> + item->client != '' ? $this->item->client : 'N/A'; ?> + + + item->author != '' ? $this->item->author : ' '; ?> + + + diff --git a/Sites/pages/administrator/components/com_installer/views/discover/view.html.php b/Sites/pages/administrator/components/com_installer/views/discover/view.html.php new file mode 100644 index 00000000..5d937183 --- /dev/null +++ b/Sites/pages/administrator/components/com_installer/views/discover/view.html.php @@ -0,0 +1,97 @@ +checkExtensions()) + { + $this->getModel('discover')->discover(); + } + + // Get data from the model. + $this->state = $this->get('State'); + $this->items = $this->get('Items'); + $this->pagination = $this->get('Pagination'); + $this->filterForm = $this->get('FilterForm'); + $this->activeFilters = $this->get('ActiveFilters'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 3.1 + */ + protected function addToolbar() + { + /* + * Set toolbar items for the page. + */ + JToolbarHelper::custom('discover.install', 'upload', 'upload', 'JTOOLBAR_INSTALL', true); + JToolbarHelper::custom('discover.refresh', 'refresh', 'refresh', 'COM_INSTALLER_TOOLBAR_DISCOVER', false); + JToolbarHelper::divider(); + + JHtmlSidebar::setAction('index.php?option=com_installer&view=discover'); + + parent::addToolbar(); + JToolbarHelper::help('JHELP_EXTENSIONS_EXTENSION_MANAGER_DISCOVER'); + } + + /** + * Check extensions. + * + * Checks uninstalled extensions in extensions table. + * + * @return boolean True if there are discovered extensions on the database. + * + * @since 3.5 + */ + public function checkExtensions() + { + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->select('*') + ->from($db->quoteName('#__extensions')) + ->where($db->quoteName('state') . ' = -1'); + $db->setQuery($query); + $discoveredExtensions = $db->loadObjectList(); + + return (count($discoveredExtensions) === 0) ? false : true; + } +} diff --git a/Sites/pages/administrator/components/com_installer/views/install/tmpl/default.php b/Sites/pages/administrator/components/com_installer/views/install/tmpl/default.php new file mode 100644 index 00000000..19b9d074 --- /dev/null +++ b/Sites/pages/administrator/components/com_installer/views/install/tmpl/default.php @@ -0,0 +1,163 @@ +addScriptDeclaration( + ' + Joomla.submitbutton4 = function() { + var form = document.getElementById("adminForm"); + + // do field validation + if (form.install_url.value == "" || form.install_url.value == "http://" || form.install_url.value == "https://") { + alert("' . JText::_('COM_INSTALLER_MSG_INSTALL_ENTER_A_URL', true) . '"); + } + else + { + JoomlaInstaller.showLoading(); + + form.installtype.value = "url"; + form.submit(); + } + }; + + Joomla.submitbuttonInstallWebInstaller = function() { + var form = document.getElementById("adminForm"); + + form.install_url.value = "https://appscdn.joomla.org/webapps/jedapps/webinstaller.xml"; + + Joomla.submitbutton4(); + }; + + // Add spindle-wheel for installations: + jQuery(document).ready(function($) { + var outerDiv = $("#installer-install"); + + JoomlaInstaller.getLoadingOverlay() + .css("top", outerDiv.position().top - $(window).scrollTop()) + .css("left", "0") + .css("width", "100%") + .css("height", "100%") + .css("display", "none") + .css("margin-top", "-10px"); + }); + + var JoomlaInstaller = { + getLoadingOverlay: function () { + return jQuery("#loading"); + }, + showLoading: function () { + this.getLoadingOverlay().css("display", "block"); + }, + hideLoading: function () { + this.getLoadingOverlay().css("display", "none"); + } + }; + ' +); + +JFactory::getDocument()->addStyleDeclaration( + ' + #loading { + background: rgba(255, 255, 255, .8) url(\'' . JHtml::_('image', 'jui/ajax-loader.gif', '', null, true, true) . '\') 50% 15% no-repeat; + position: fixed; + opacity: 0.8; + -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity = 80); + filter: alpha(opacity = 80); + overflow: hidden; + } + ' +); + +?> + + + +
+
+ sidebar)) : ?> +
+ sidebar; ?> +
+
+ +
+ + + showMessage) : ?> + loadTemplate('message'); ?> + showJedAndWebInstaller) : ?> +
+ ' . str_replace('"', '"', JText::_('COM_INSTALLER_SHOW_JED_INFORMATION_TOOLTIP')) . '', + 'class="alert-options hasTooltip icon-options" data-dismiss="alert" title="' . str_replace('"', '"', JText::_('COM_INSTALLER_SHOW_JED_INFORMATION_TOOLTIP')) . '"' + ); + ?> +

+

+ +
+ + + + trigger('onInstallerViewBeforeFirstTab', array()); ?> + + trigger('onInstallerAddInstallationTab', array()); ?> + + +
+ +
+ + + + trigger('onInstallerViewAfterLastTab', array()); ?> + + + enqueueMessage(JText::_('COM_INSTALLER_NO_INSTALLATION_PLUGINS_FOUND'), 'warning'); ?> + + + ftp) : ?> + + loadTemplate('ftp'); ?> + + + + + + + + +
+ +
+
diff --git a/Sites/pages/administrator/components/com_installer/views/install/tmpl/default.xml b/Sites/pages/administrator/components/com_installer/views/install/tmpl/default.xml new file mode 100755 index 00000000..e6fd86b3 --- /dev/null +++ b/Sites/pages/administrator/components/com_installer/views/install/tmpl/default.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/Sites/pages/administrator/components/com_installer/views/install/view.html.php b/Sites/pages/administrator/components/com_installer/views/install/view.html.php new file mode 100644 index 00000000..f916f4fd --- /dev/null +++ b/Sites/pages/administrator/components/com_installer/views/install/view.html.php @@ -0,0 +1,61 @@ +first = ''; + $state = $this->get('state'); + + $this->paths = &$paths; + $this->state = &$state; + + $this->showJedAndWebInstaller = JComponentHelper::getParams('com_installer')->get('show_jed_info', 1); + + JPluginHelper::importPlugin('installer'); + + $dispatcher = JEventDispatcher::getInstance(); + $dispatcher->trigger('onInstallerBeforeDisplay', array(&$this->showJedAndWebInstaller, $this)); + + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + parent::addToolbar(); + JToolbarHelper::help('JHELP_EXTENSIONS_EXTENSION_MANAGER_INSTALL'); + } +} diff --git a/Sites/pages/administrator/components/com_installer/views/languages/tmpl/default.php b/Sites/pages/administrator/components/com_installer/views/languages/tmpl/default.php new file mode 100644 index 00000000..cd4b6e73 --- /dev/null +++ b/Sites/pages/administrator/components/com_installer/views/languages/tmpl/default.php @@ -0,0 +1,108 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +?> +
+
+ sidebar)) : ?> +
+ sidebar; ?> +
+
+ +
+ + $this, 'options' => array('filterButton' => false))); ?> +
+ items)) : ?> +
+ +
+ + + + + + + + + + + + + + + + + + getShortVersion()); + $i = 0; + foreach ($this->items as $language) : + preg_match('#^pkg_([a-z]{2,3}-[A-Z]{2})$#', $language->element, $element); + $language->code = $element[1]; + ?> + + + + + + + + + + +
+ + + + + + + +
+ pagination->getListFooter(); ?> +
+ installedLang[0][$language->code]) || isset($this->installedLang[1][$language->code])) ? 'REINSTALL' : 'INSTALL'; ?> + detailsurl . '\'; Joomla.submitbutton(\'install.install\');'; ?> + + + name; ?> + + code; ?> + + + + version, $minorVersion) !== 0 || strpos($language->version, $currentShortVersion) !== 0) : ?> + version; ?> + + version; ?> + + + detailsurl; ?> +
+ + + + + + + +
+ +
diff --git a/Sites/pages/administrator/components/com_installer/views/languages/tmpl/default.xml b/Sites/pages/administrator/components/com_installer/views/languages/tmpl/default.xml new file mode 100755 index 00000000..4f52293e --- /dev/null +++ b/Sites/pages/administrator/components/com_installer/views/languages/tmpl/default.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/Sites/pages/administrator/components/com_installer/views/languages/view.html.php b/Sites/pages/administrator/components/com_installer/views/languages/view.html.php new file mode 100644 index 00000000..43c62884 --- /dev/null +++ b/Sites/pages/administrator/components/com_installer/views/languages/view.html.php @@ -0,0 +1,80 @@ +state = $this->get('State'); + $this->items = $this->get('Items'); + $this->pagination = $this->get('Pagination'); + $this->filterForm = $this->get('FilterForm'); + $this->activeFilters = $this->get('ActiveFilters'); + $this->installedLang = JLanguageHelper::getInstalledLanguages(); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + */ + protected function addToolbar() + { + $canDo = JHelperContent::getActions('com_installer'); + JToolBarHelper::title(JText::_('COM_INSTALLER_HEADER_' . $this->getName()), 'puzzle install'); + + if ($canDo->get('core.admin')) + { + parent::addToolbar(); + + // TODO: this help screen will need to be created. + JToolBarHelper::help('JHELP_EXTENSIONS_EXTENSION_MANAGER_LANGUAGES'); + } + } +} diff --git a/Sites/pages/administrator/components/com_installer/views/manage/tmpl/default.php b/Sites/pages/administrator/components/com_installer/views/manage/tmpl/default.php new file mode 100644 index 00000000..0492c67d --- /dev/null +++ b/Sites/pages/administrator/components/com_installer/views/manage/tmpl/default.php @@ -0,0 +1,144 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +?> +
+
+ sidebar)) : ?> +
+ sidebar; ?> +
+
+ +
+ + showMessage) : ?> + loadTemplate('message'); ?> + + ftp) : ?> + loadTemplate('ftp'); ?> + + $this)); ?> +
+ items)) : ?> +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + items as $i => $item) : ?> + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + +
+ pagination->getListFooter(); ?> +
+ extension_id); ?> + + element) : ?> + X + + status, $i, $item->status < 2, 'cb'); ?> + + + + + client_translated; ?> + + type_translated; ?> + + version != '' ? $item->version : ' '; ?> + + creationDate != '' ? $item->creationDate : ' '; ?> + + + author != '' ? $item->author : ' '; ?> + + + folder_translated; ?> + + package_id ?: ' '; ?> + + extension_id; ?> +
+ + + + + +
+ +
diff --git a/Sites/pages/administrator/components/com_installer/views/manage/tmpl/default.xml b/Sites/pages/administrator/components/com_installer/views/manage/tmpl/default.xml new file mode 100755 index 00000000..13dc66fc --- /dev/null +++ b/Sites/pages/administrator/components/com_installer/views/manage/tmpl/default.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/Sites/pages/administrator/components/com_installer/views/manage/view.html.php b/Sites/pages/administrator/components/com_installer/views/manage/view.html.php new file mode 100644 index 00000000..03564d92 --- /dev/null +++ b/Sites/pages/administrator/components/com_installer/views/manage/view.html.php @@ -0,0 +1,92 @@ +state = $this->get('State'); + $this->items = $this->get('Items'); + $this->pagination = $this->get('Pagination'); + $this->filterForm = $this->get('FilterForm'); + $this->activeFilters = $this->get('ActiveFilters'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + // Include the component HTML helpers. + JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html'); + + // Display the view. + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + $canDo = JHelperContent::getActions('com_installer'); + + if ($canDo->get('core.edit.state')) + { + JToolbarHelper::publish('manage.publish', 'JTOOLBAR_ENABLE', true); + JToolbarHelper::unpublish('manage.unpublish', 'JTOOLBAR_DISABLE', true); + JToolbarHelper::divider(); + } + + JToolbarHelper::custom('manage.refresh', 'refresh', 'refresh', 'JTOOLBAR_REFRESH_CACHE', true); + JToolbarHelper::divider(); + + if ($canDo->get('core.delete')) + { + JToolbarHelper::deleteList('COM_INSTALLER_CONFIRM_UNINSTALL', 'manage.remove', 'JTOOLBAR_UNINSTALL'); + JToolbarHelper::divider(); + } + + JHtmlSidebar::setAction('index.php?option=com_installer&view=manage'); + + parent::addToolbar(); + JToolbarHelper::help('JHELP_EXTENSIONS_EXTENSION_MANAGER_MANAGE'); + } +} diff --git a/Sites/pages/administrator/components/com_installer/views/update/tmpl/default.php b/Sites/pages/administrator/components/com_installer/views/update/tmpl/default.php new file mode 100644 index 00000000..74c18728 --- /dev/null +++ b/Sites/pages/administrator/components/com_installer/views/update/tmpl/default.php @@ -0,0 +1,138 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +?> +
+
+ sidebar)) : ?> +
+ sidebar; ?> +
+
+ +
+ + showMessage) : ?> + loadTemplate('message'); ?> + + + ftp) : ?> + loadTemplate('ftp'); ?> + + + $this)); ?> +
+ items)) : ?> +
+ +
+ + + + + + + + + + + + + + + + + + + + + + items as $i => $item) : ?> + client_id ? JText::_('JADMINISTRATOR') : JText::_('JSITE'); + $manifest = json_decode($item->manifest_cache); + $current_version = isset($manifest->version) ? $manifest->version : JText::_('JLIB_UNKNOWN'); + ?> + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + +
+ pagination->getListFooter(); ?> +
+ update_id); ?> + + + + client_translated; ?> + + type_translated; ?> + + current_version; ?> + + version; ?> + + folder_translated; ?> + + install_type; ?> + + + detailsurl; ?> + infourl)) : ?> +
+ escape($item->infourl); ?> + +
+
+ + + + +
+ +
diff --git a/Sites/pages/administrator/components/com_installer/views/update/tmpl/default.xml b/Sites/pages/administrator/components/com_installer/views/update/tmpl/default.xml new file mode 100755 index 00000000..d262a8a9 --- /dev/null +++ b/Sites/pages/administrator/components/com_installer/views/update/tmpl/default.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/Sites/pages/administrator/components/com_installer/views/update/view.html.php b/Sites/pages/administrator/components/com_installer/views/update/view.html.php new file mode 100644 index 00000000..ba89edc4 --- /dev/null +++ b/Sites/pages/administrator/components/com_installer/views/update/view.html.php @@ -0,0 +1,92 @@ +state = $this->get('State'); + $this->items = $this->get('Items'); + $this->pagination = $this->get('Pagination'); + $this->filterForm = $this->get('FilterForm'); + $this->activeFilters = $this->get('ActiveFilters'); + + $paths = new stdClass; + $paths->first = ''; + + $this->paths = &$paths; + + if (count($this->items) > 0) + { + JFactory::getApplication()->enqueueMessage(JText::_('COM_INSTALLER_MSG_WARNINGS_UPDATE_NOTICE'), 'warning'); + } + + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + JToolbarHelper::custom('update.update', 'upload', 'upload', 'COM_INSTALLER_TOOLBAR_UPDATE', true); + JToolbarHelper::custom('update.find', 'refresh', 'refresh', 'COM_INSTALLER_TOOLBAR_FIND_UPDATES', false); + JToolbarHelper::custom('update.purge', 'purge', 'purge', 'COM_INSTALLER_TOOLBAR_PURGE', false); + JToolbarHelper::divider(); + + JHtmlSidebar::setAction('index.php?option=com_installer&view=manage'); + + parent::addToolbar(); + JToolbarHelper::help('JHELP_EXTENSIONS_EXTENSION_MANAGER_UPDATE'); + } +} diff --git a/Sites/pages/administrator/components/com_installer/views/updatesites/tmpl/default.php b/Sites/pages/administrator/components/com_installer/views/updatesites/tmpl/default.php new file mode 100644 index 00000000..58a63c80 --- /dev/null +++ b/Sites/pages/administrator/components/com_installer/views/updatesites/tmpl/default.php @@ -0,0 +1,121 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +?> +
+
+ sidebar)) : ?> +
+ sidebar; ?> +
+
+ +
+ + $this)); ?> +
+ items)) : ?> +
+ +
+ + + + + + + + + + + + + + + + + + + + + items as $i => $item) : ?> + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ pagination->getListFooter(); ?> +
+ update_site_id); ?> + + element) : ?> + X + + enabled, $i, $item->enabled < 2, 'cb'); ?> + + + + + + name; ?> + + + client_translated; ?> + + type_translated; ?> + + folder_translated; ?> + + update_site_id; ?> +
+ + + + +
+ +
diff --git a/Sites/pages/administrator/components/com_installer/views/updatesites/tmpl/default.xml b/Sites/pages/administrator/components/com_installer/views/updatesites/tmpl/default.xml new file mode 100755 index 00000000..f9cf92a6 --- /dev/null +++ b/Sites/pages/administrator/components/com_installer/views/updatesites/tmpl/default.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/Sites/pages/administrator/components/com_installer/views/updatesites/view.html.php b/Sites/pages/administrator/components/com_installer/views/updatesites/view.html.php new file mode 100644 index 00000000..7d1333ae --- /dev/null +++ b/Sites/pages/administrator/components/com_installer/views/updatesites/view.html.php @@ -0,0 +1,98 @@ +state = $this->get('State'); + $this->items = $this->get('Items'); + $this->pagination = $this->get('Pagination'); + $this->filterForm = $this->get('FilterForm'); + $this->activeFilters = $this->get('ActiveFilters'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + // Include the component HTML helpers. + JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html'); + + // Display the view + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 3.4 + */ + protected function addToolbar() + { + $canDo = JHelperContent::getActions('com_installer'); + + if ($canDo->get('core.edit.state')) + { + JToolbarHelper::publish('updatesites.publish', 'JTOOLBAR_ENABLE', true); + JToolbarHelper::unpublish('updatesites.unpublish', 'JTOOLBAR_DISABLE', true); + JToolbarHelper::divider(); + } + + if ($canDo->get('core.delete')) + { + JToolbarHelper::deleteList('JGLOBAL_CONFIRM_DELETE', 'updatesites.delete', 'JTOOLBAR_DELETE'); + JToolbarHelper::divider(); + } + + if ($canDo->get('core.admin') || $canDo->get('core.options')) + { + JToolbarHelper::custom('updatesites.rebuild', 'refresh.png', 'refresh_f2.png', 'JTOOLBAR_REBUILD', false); + } + + JHtmlSidebar::setAction('index.php?option=com_installer&view=updatesites'); + + parent::addToolbar(); + JToolbarHelper::help('JHELP_EXTENSIONS_EXTENSION_MANAGER_UPDATESITES'); + } +} diff --git a/Sites/pages/administrator/components/com_installer/views/warnings/tmpl/default.php b/Sites/pages/administrator/components/com_installer/views/warnings/tmpl/default.php new file mode 100644 index 00000000..5489ee45 --- /dev/null +++ b/Sites/pages/administrator/components/com_installer/views/warnings/tmpl/default.php @@ -0,0 +1,41 @@ + +
+
+ sidebar)) : ?> +
+ sidebar; ?> +
+
+ +
+ + messages)) : ?> + 'warning0')); ?> + + messages as $message) : ?> + + + + + + + + + +
+ + +
+
+ +
diff --git a/Sites/pages/administrator/components/com_installer/views/warnings/tmpl/default.xml b/Sites/pages/administrator/components/com_installer/views/warnings/tmpl/default.xml new file mode 100755 index 00000000..8e6472cd --- /dev/null +++ b/Sites/pages/administrator/components/com_installer/views/warnings/tmpl/default.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/Sites/pages/administrator/components/com_installer/views/warnings/view.html.php b/Sites/pages/administrator/components/com_installer/views/warnings/view.html.php new file mode 100644 index 00000000..316360dc --- /dev/null +++ b/Sites/pages/administrator/components/com_installer/views/warnings/view.html.php @@ -0,0 +1,58 @@ +get('Items'); + $this->messages = &$items; + parent::display($tpl); + + if (count($items) > 0) + { + JFactory::getApplication()->enqueueMessage(JText::_('COM_INSTALLER_MSG_WARNINGS_NOTICE'), 'warning'); + } + else + { + JFactory::getApplication()->enqueueMessage(JText::_('COM_INSTALLER_MSG_WARNINGS_NONE'), 'notice'); + } + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + parent::addToolbar(); + JToolbarHelper::help('JHELP_EXTENSIONS_EXTENSION_MANAGER_WARNINGS'); + } +} diff --git a/Sites/pages/administrator/components/com_joomlaupdate/config.xml b/Sites/pages/administrator/components/com_joomlaupdate/config.xml new file mode 100644 index 00000000..d4b814bc --- /dev/null +++ b/Sites/pages/administrator/components/com_joomlaupdate/config.xml @@ -0,0 +1,51 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + +
+
diff --git a/Sites/pages/administrator/components/com_joomlaupdate/controller.php b/Sites/pages/administrator/components/com_joomlaupdate/controller.php new file mode 100644 index 00000000..e808a049 --- /dev/null +++ b/Sites/pages/administrator/components/com_joomlaupdate/controller.php @@ -0,0 +1,74 @@ +input->get('view', 'default'); + $vFormat = $document->getType(); + $lName = $this->input->get('layout', 'default', 'string'); + + // Get and render the view. + if ($view = $this->getView($vName, $vFormat)) + { + $ftp = JClientHelper::setCredentialsFromRequest('ftp'); + $view->ftp = &$ftp; + + // Get the model for the view. + /** @var JoomlaupdateModelDefault $model */ + $model = $this->getModel('default'); + + // Push the Installer Warnings model into the view, if we can load it + static::addModelPath(JPATH_ADMINISTRATOR . '/components/com_installer/models', 'InstallerModel'); + + $warningsModel = $this->getModel('warnings', 'InstallerModel'); + + if (is_object($warningsModel)) + { + $view->setModel($warningsModel, false); + } + + // Perform update source preference check and refresh update information. + $model->applyUpdateSite(); + $model->refreshUpdates(); + + // Push the model into the view (as default). + $view->setModel($model, true); + $view->setLayout($lName); + + // Push document object into the view. + $view->document = $document; + $view->display(); + } + + return $this; + } +} diff --git a/Sites/pages/administrator/components/com_joomlaupdate/controllers/update.php b/Sites/pages/administrator/components/com_joomlaupdate/controllers/update.php new file mode 100644 index 00000000..3b04f6c5 --- /dev/null +++ b/Sites/pages/administrator/components/com_joomlaupdate/controllers/update.php @@ -0,0 +1,493 @@ +checkToken(); + + $options['format'] = '{DATE}\t{TIME}\t{LEVEL}\t{CODE}\t{MESSAGE}'; + $options['text_file'] = 'joomla_update.php'; + JLog::addLogger($options, JLog::INFO, array('Update', 'databasequery', 'jerror')); + $user = JFactory::getUser(); + + try + { + JLog::add(JText::sprintf('COM_JOOMLAUPDATE_UPDATE_LOG_START', $user->id, $user->name, JVERSION), JLog::INFO, 'Update'); + } + catch (RuntimeException $exception) + { + // Informational log only + } + + $this->_applyCredentials(); + + /** @var JoomlaupdateModelDefault $model */ + $model = $this->getModel('Default'); + $result = $model->download(); + $file = $result['basename']; + $message = null; + $messageType = null; + + // The validation was not successful for now just a warning. + // TODO: In Joomla 4 this will abort the installation + if ($result['check'] === false) + { + $message = JText::_('COM_JOOMLAUPDATE_VIEW_UPDATE_CHECKSUM_WRONG'); + $messageType = 'warning'; + + try + { + JLog::add($message, JLog::INFO, 'Update'); + } + catch (RuntimeException $exception) + { + // Informational log only + } + } + + if ($file) + { + JFactory::getApplication()->setUserState('com_joomlaupdate.file', $file); + $url = 'index.php?option=com_joomlaupdate&task=update.install&' . JFactory::getSession()->getFormToken() . '=1'; + + try + { + JLog::add(JText::sprintf('COM_JOOMLAUPDATE_UPDATE_LOG_FILE', $file), JLog::INFO, 'Update'); + } + catch (RuntimeException $exception) + { + // Informational log only + } + } + else + { + JFactory::getApplication()->setUserState('com_joomlaupdate.file', null); + $url = 'index.php?option=com_joomlaupdate'; + $message = JText::_('COM_JOOMLAUPDATE_VIEW_UPDATE_DOWNLOADFAILED'); + $messageType = 'error'; + } + + $this->setRedirect($url, $message, $messageType); + } + + /** + * Start the installation of the new Joomla! version + * + * @return void + * + * @since 2.5.4 + */ + public function install() + { + $this->checkToken('get'); + JFactory::getApplication()->setUserState('com_joomlaupdate.oldversion', JVERSION); + + $options['format'] = '{DATE}\t{TIME}\t{LEVEL}\t{CODE}\t{MESSAGE}'; + $options['text_file'] = 'joomla_update.php'; + JLog::addLogger($options, JLog::INFO, array('Update', 'databasequery', 'jerror')); + + try + { + JLog::add(JText::_('COM_JOOMLAUPDATE_UPDATE_LOG_INSTALL'), JLog::INFO, 'Update'); + } + catch (RuntimeException $exception) + { + // Informational log only + } + + $this->_applyCredentials(); + + /** @var JoomlaupdateModelDefault $model */ + $model = $this->getModel('Default'); + + $file = JFactory::getApplication()->getUserState('com_joomlaupdate.file', null); + $model->createRestorationFile($file); + + $this->display(); + } + + /** + * Finalise the upgrade by running the necessary scripts + * + * @return void + * + * @since 2.5.4 + */ + public function finalise() + { + /* + * Finalize with login page. Used for pre-token check versions + * to allow updates without problems but with a maximum of security. + */ + if (!JSession::checkToken('get')) + { + $this->setRedirect('index.php?option=com_joomlaupdate&view=update&layout=finaliseconfirm'); + + return false; + } + + $options['format'] = '{DATE}\t{TIME}\t{LEVEL}\t{CODE}\t{MESSAGE}'; + $options['text_file'] = 'joomla_update.php'; + JLog::addLogger($options, JLog::INFO, array('Update', 'databasequery', 'jerror')); + + try + { + JLog::add(JText::_('COM_JOOMLAUPDATE_UPDATE_LOG_FINALISE'), JLog::INFO, 'Update'); + } + catch (RuntimeException $exception) + { + // Informational log only + } + + $this->_applyCredentials(); + + /** @var JoomlaupdateModelDefault $model */ + $model = $this->getModel('Default'); + + $model->finaliseUpgrade(); + + $url = 'index.php?option=com_joomlaupdate&task=update.cleanup&' . JFactory::getSession()->getFormToken() . '=1'; + $this->setRedirect($url); + } + + /** + * Clean up after ourselves + * + * @return void + * + * @since 2.5.4 + */ + public function cleanup() + { + /* + * Cleanup with login page. Used for pre-token check versions to be able to update + * from =< 3.2.7 to allow updates without problems but with a maximum of security. + */ + if (!JSession::checkToken('get')) + { + $this->setRedirect('index.php?option=com_joomlaupdate&view=update&layout=finaliseconfirm'); + + return false; + } + + $options['format'] = '{DATE}\t{TIME}\t{LEVEL}\t{CODE}\t{MESSAGE}'; + $options['text_file'] = 'joomla_update.php'; + JLog::addLogger($options, JLog::INFO, array('Update', 'databasequery', 'jerror')); + + try + { + JLog::add(JText::_('COM_JOOMLAUPDATE_UPDATE_LOG_CLEANUP'), JLog::INFO, 'Update'); + } + catch (RuntimeException $exception) + { + // Informational log only + } + + $this->_applyCredentials(); + + /** @var JoomlaupdateModelDefault $model */ + $model = $this->getModel('Default'); + + $model->cleanUp(); + + $url = 'index.php?option=com_joomlaupdate&view=default&layout=complete'; + $this->setRedirect($url); + + try + { + JLog::add(JText::sprintf('COM_JOOMLAUPDATE_UPDATE_LOG_COMPLETE', JVERSION), JLog::INFO, 'Update'); + } + catch (RuntimeException $exception) + { + // Informational log only + } + } + + /** + * Purges updates. + * + * @return void + * + * @since 3.0 + */ + public function purge() + { + // Check for request forgeries + $this->checkToken(); + + // Purge updates + /** @var JoomlaupdateModelDefault $model */ + $model = $this->getModel('Default'); + $model->purge(); + + $url = 'index.php?option=com_joomlaupdate'; + $this->setRedirect($url, $model->_message); + } + + /** + * Uploads an update package to the temporary directory, under a random name + * + * @return void + * + * @since 3.6.0 + */ + public function upload() + { + // Check for request forgeries + $this->checkToken(); + + // Did a non Super User tried to upload something (a.k.a. pathetic hacking attempt)? + JFactory::getUser()->authorise('core.admin') or jexit(JText::_('JLIB_APPLICATION_ERROR_ACCESS_FORBIDDEN')); + + $this->_applyCredentials(); + + /** @var JoomlaupdateModelDefault $model */ + $model = $this->getModel('Default'); + + try + { + $model->upload(); + } + catch (RuntimeException $e) + { + $url = 'index.php?option=com_joomlaupdate'; + $this->setRedirect($url, $e->getMessage(), 'error'); + + return; + } + + $token = JSession::getFormToken(); + $url = 'index.php?option=com_joomlaupdate&task=update.captive&' . $token . '=1'; + $this->setRedirect($url); + } + + /** + * Checks there is a valid update package and redirects to the captive view for super admin authentication. + * + * @return array + * + * @since 3.6.0 + */ + public function captive() + { + // Check for request forgeries + $this->checkToken('get'); + + // Did a non Super User tried to upload something (a.k.a. pathetic hacking attempt)? + if (!JFactory::getUser()->authorise('core.admin')) + { + throw new RuntimeException(JText::_('JLIB_APPLICATION_ERROR_ACCESS_FORBIDDEN'), 403); + } + + // Do I really have an update package? + $tempFile = JFactory::getApplication()->getUserState('com_joomlaupdate.temp_file', null); + + JLoader::import('joomla.filesystem.file'); + + if (empty($tempFile) || !JFile::exists($tempFile)) + { + throw new RuntimeException(JText::_('JLIB_APPLICATION_ERROR_ACCESS_FORBIDDEN'), 403); + } + + $this->input->set('view', 'upload'); + $this->input->set('layout', 'captive'); + + $this->display(); + } + + /** + * Checks the admin has super administrator privileges and then proceeds with the update. + * + * @return array + * + * @since 3.6.0 + */ + public function confirm() + { + // Check for request forgeries + $this->checkToken(); + + // Did a non Super User tried to upload something (a.k.a. pathetic hacking attempt)? + if (!JFactory::getUser()->authorise('core.admin')) + { + throw new RuntimeException(JText::_('JLIB_APPLICATION_ERROR_ACCESS_FORBIDDEN'), 403); + } + + // Get the model + /** @var JoomlaupdateModelDefault $model */ + $model = $this->getModel('default'); + + // Get the captive file before the session resets + $tempFile = JFactory::getApplication()->getUserState('com_joomlaupdate.temp_file', null); + + // Do I really have an update package? + if (!$model->captiveFileExists()) + { + throw new RuntimeException(JText::_('JLIB_APPLICATION_ERROR_ACCESS_FORBIDDEN'), 403); + } + + // Try to log in + $credentials = array( + 'username' => $this->input->post->get('username', '', 'username'), + 'password' => $this->input->post->get('passwd', '', 'raw'), + 'secretkey' => $this->input->post->get('secretkey', '', 'raw'), + ); + + $result = $model->captiveLogin($credentials); + + if (!$result) + { + $model->removePackageFiles(); + + throw new RuntimeException(JText::_('JLIB_APPLICATION_ERROR_ACCESS_FORBIDDEN'), 403); + } + + // Set the update source in the session + JFactory::getApplication()->setUserState('com_joomlaupdate.file', basename($tempFile)); + + try + { + JLog::add(JText::sprintf('COM_JOOMLAUPDATE_UPDATE_LOG_FILE', $tempFile), JLog::INFO, 'Update'); + } + catch (RuntimeException $exception) + { + // Informational log only + } + + // Redirect to the actual update page + $url = 'index.php?option=com_joomlaupdate&task=update.install&' . JFactory::getSession()->getFormToken() . '=1'; + $this->setRedirect($url); + } + + /** + * Method to display a view. + * + * @param boolean $cachable If true, the view output will be cached + * @param array $urlparams An array of safe URL parameters and their variable types, for valid values see {@link JFilterInput::clean()}. + * + * @return JoomlaupdateControllerUpdate This object to support chaining. + * + * @since 2.5.4 + */ + public function display($cachable = false, $urlparams = array()) + { + // Get the document object. + $document = JFactory::getDocument(); + + // Set the default view name and format from the Request. + $vName = $this->input->get('view', 'update'); + $vFormat = $document->getType(); + $lName = $this->input->get('layout', 'default', 'string'); + + // Get and render the view. + if ($view = $this->getView($vName, $vFormat)) + { + // Get the model for the view. + /** @var JoomlaupdateModelDefault $model */ + $model = $this->getModel('Default'); + + // Push the model into the view (as default). + $view->setModel($model, true); + $view->setLayout($lName); + + // Push document object into the view. + $view->document = $document; + $view->display(); + } + + return $this; + } + + /** + * Applies FTP credentials to Joomla! itself, when required + * + * @return void + * + * @since 2.5.4 + */ + protected function _applyCredentials() + { + JFactory::getApplication()->getUserStateFromRequest('com_joomlaupdate.method', 'method', 'direct', 'cmd'); + + if (!JClientHelper::hasCredentials('ftp')) + { + $user = JFactory::getApplication()->getUserStateFromRequest('com_joomlaupdate.ftp_user', 'ftp_user', null, 'raw'); + $pass = JFactory::getApplication()->getUserStateFromRequest('com_joomlaupdate.ftp_pass', 'ftp_pass', null, 'raw'); + + if ($user != '' && $pass != '') + { + // Add credentials to the session + if (!JClientHelper::setCredentials('ftp', $user, $pass)) + { + JError::raiseWarning(500, JText::_('JLIB_CLIENT_ERROR_HELPER_SETCREDENTIALSFROMREQUEST_FAILED')); + } + } + } + } + + /** + * Checks the admin has super administrator privileges and then proceeds with the final & cleanup steps. + * + * @return array + * + * @since 3.6.3 + */ + public function finaliseconfirm() + { + // Check for request forgeries + $this->checkToken(); + + // Did a non Super User try do this? + if (!JFactory::getUser()->authorise('core.admin')) + { + throw new RuntimeException(JText::_('JLIB_APPLICATION_ERROR_ACCESS_FORBIDDEN'), 403); + } + + // Get the model + /** @var JoomlaupdateModelDefault $model */ + $model = $this->getModel('default'); + + // Try to log in + $credentials = array( + 'username' => $this->input->post->get('username', '', 'username'), + 'password' => $this->input->post->get('passwd', '', 'raw'), + 'secretkey' => $this->input->post->get('secretkey', '', 'raw'), + ); + + $result = $model->captiveLogin($credentials); + + // The login fails? + if (!$result) + { + JFactory::getApplication()->enqueueMessage(JText::_('JGLOBAL_AUTH_INVALID_PASS'), 'warning'); + $this->setRedirect('index.php?option=com_joomlaupdate&view=update&layout=finaliseconfirm'); + + return false; + } + + // Redirect back to the actual finalise page + $this->setRedirect('index.php?option=com_joomlaupdate&task=update.finalise&' . JFactory::getSession()->getFormToken() . '=1'); + } +} diff --git a/Sites/pages/administrator/components/com_joomlaupdate/helpers/joomlaupdate.php b/Sites/pages/administrator/components/com_joomlaupdate/helpers/joomlaupdate.php new file mode 100644 index 00000000..0da77911 --- /dev/null +++ b/Sites/pages/administrator/components/com_joomlaupdate/helpers/joomlaupdate.php @@ -0,0 +1,46 @@ +authorise('core.admin')) +{ + throw new JAccessExceptionNotallowed(JText::_('JERROR_ALERTNOAUTHOR'), 403); +} + +$controller = JControllerLegacy::getInstance('Joomlaupdate'); +$controller->execute(JFactory::getApplication()->input->get('task')); +$controller->redirect(); diff --git a/Sites/pages/administrator/components/com_joomlaupdate/joomlaupdate.xml b/Sites/pages/administrator/components/com_joomlaupdate/joomlaupdate.xml new file mode 100644 index 00000000..0475b8b7 --- /dev/null +++ b/Sites/pages/administrator/components/com_joomlaupdate/joomlaupdate.xml @@ -0,0 +1,36 @@ + + + com_joomlaupdate + Joomla! Project + February 2012 + (C) 2005 - 2020 Open Source Matters. All rights reserved. + GNU General Public License version 2 or later; see LICENSE.txt + admin@joomla.org + www.joomla.org + 3.6.2 + COM_JOOMLAUPDATE_XML_DESCRIPTION + + js + + + com_joomlaupdate + + access.xml + config.xml + controller.php + joomlaupdate.php + restore.php + controllers + helpers + models + views + + + language/en-GB.com_joomlaupdate.ini + language/en-GB.com_joomlaupdate.sys.ini + + + + https://update.joomla.org/core/extensions/com_joomlaupdate.xml + + diff --git a/Sites/pages/administrator/components/com_joomlaupdate/models/default.php b/Sites/pages/administrator/components/com_joomlaupdate/models/default.php new file mode 100644 index 00000000..7e3035db --- /dev/null +++ b/Sites/pages/administrator/components/com_joomlaupdate/models/default.php @@ -0,0 +1,1104 @@ +get('updatesource', 'nochange')) + { + // "Minor & Patch Release for Current version AND Next Major Release". + case 'sts': + case 'next': + $updateURL = 'https://update.joomla.org/core/sts/list_sts.xml'; + break; + + // "Testing" + case 'testing': + $updateURL = 'https://update.joomla.org/core/test/list_test.xml'; + break; + + // "Custom" + // TODO: check if the customurl is valid and not just "not empty". + case 'custom': + if (trim($params->get('customurl', '')) != '') + { + $updateURL = trim($params->get('customurl', '')); + } + else + { + return JError::raiseWarning(403, JText::_('COM_JOOMLAUPDATE_CONFIG_UPDATESOURCE_CUSTOM_ERROR')); + } + break; + + /** + * "Minor & Patch Release for Current version (recommended and default)". + * The commented "case" below are for documenting where 'default' and legacy options falls + * case 'default': + * case 'lts': + * case 'nochange': + */ + default: + $updateURL = 'https://update.joomla.org/core/list.xml'; + } + + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select($db->quoteName('us') . '.*') + ->from($db->quoteName('#__update_sites_extensions') . ' AS ' . $db->quoteName('map')) + ->join( + 'INNER', $db->quoteName('#__update_sites') . ' AS ' . $db->quoteName('us') + . ' ON (' . 'us.update_site_id = map.update_site_id)' + ) + ->where('map.extension_id = ' . $db->quote(700)); + $db->setQuery($query); + $update_site = $db->loadObject(); + + if ($update_site->location != $updateURL) + { + // Modify the database record. + $update_site->last_check_timestamp = 0; + $update_site->location = $updateURL; + $db->updateObject('#__update_sites', $update_site, 'update_site_id'); + + // Remove cached updates. + $query->clear() + ->delete($db->quoteName('#__updates')) + ->where($db->quoteName('extension_id') . ' = ' . $db->quote('700')); + $db->setQuery($query); + $db->execute(); + } + } + + /** + * Makes sure that the Joomla! update cache is up-to-date. + * + * @param boolean $force Force reload, ignoring the cache timeout. + * + * @return void + * + * @since 2.5.4 + */ + public function refreshUpdates($force = false) + { + if ($force) + { + $cache_timeout = 0; + } + else + { + $cache_timeout = 3600 * JComponentHelper::getParams('com_installer')->get('cachetimeout', 6, 'int'); + } + + $updater = JUpdater::getInstance(); + $minimumStability = JUpdater::STABILITY_STABLE; + $comJoomlaupdateParams = JComponentHelper::getParams('com_joomlaupdate'); + + if (in_array($comJoomlaupdateParams->get('updatesource', 'nochange'), array('testing', 'custom'))) + { + $minimumStability = $comJoomlaupdateParams->get('minimum_stability', JUpdater::STABILITY_STABLE); + } + + $reflection = new ReflectionObject($updater); + $reflectionMethod = $reflection->getMethod('findUpdates'); + $methodParameters = $reflectionMethod->getParameters(); + + if (count($methodParameters) >= 4) + { + // Reinstall support is available in JUpdater + $updater->findUpdates(700, $cache_timeout, $minimumStability, true); + } + else + { + $updater->findUpdates(700, $cache_timeout, $minimumStability); + } + } + + /** + * Returns an array with the Joomla! update information. + * + * @return array + * + * @since 2.5.4 + */ + public function getUpdateInformation() + { + // Initialise the return array. + $ret = array( + 'installed' => JVERSION, + 'latest' => null, + 'object' => null, + 'hasUpdate' => false, + ); + + // Fetch the update information from the database. + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select('*') + ->from($db->quoteName('#__updates')) + ->where($db->quoteName('extension_id') . ' = ' . $db->quote(700)); + $db->setQuery($query); + $updateObject = $db->loadObject(); + + if (is_null($updateObject)) + { + // We have not found any update in the database we seem to run the latest version + $ret['latest'] = JVERSION; + + return $ret; + } + + // Check whether this is a valid update or not + if (version_compare($updateObject->version, JVERSION, '<')) + { + // This update points to an outdated version we should not offer to update to this + $ret['latest'] = JVERSION; + + return $ret; + } + + $ret['latest'] = $updateObject->version; + + // Check whether this is an update or not. + if (version_compare($updateObject->version, JVERSION, '>')) + { + $ret['hasUpdate'] = true; + } + + $minimumStability = JUpdater::STABILITY_STABLE; + $comJoomlaupdateParams = JComponentHelper::getParams('com_joomlaupdate'); + + if (in_array($comJoomlaupdateParams->get('updatesource', 'nochange'), array('testing', 'custom'))) + { + $minimumStability = $comJoomlaupdateParams->get('minimum_stability', JUpdater::STABILITY_STABLE); + } + + // Fetch the full update details from the update details URL. + jimport('joomla.updater.update'); + $update = new JUpdate; + $update->loadFromXML($updateObject->detailsurl, $minimumStability); + + $ret['object'] = $update; + + return $ret; + } + + /** + * Returns an array with the configured FTP options. + * + * @return array + * + * @since 2.5.4 + */ + public function getFTPOptions() + { + $config = JFactory::getConfig(); + + return array( + 'host' => $config->get('ftp_host'), + 'port' => $config->get('ftp_port'), + 'username' => $config->get('ftp_user'), + 'password' => $config->get('ftp_pass'), + 'directory' => $config->get('ftp_root'), + 'enabled' => $config->get('ftp_enable'), + ); + } + + /** + * Removes all of the updates from the table and enable all update streams. + * + * @return boolean Result of operation. + * + * @since 3.0 + */ + public function purge() + { + $db = $this->getDbo(); + + // Reset the last update check timestamp + $query = $db->getQuery(true) + ->update($db->quoteName('#__update_sites')) + ->set($db->quoteName('last_check_timestamp') . ' = 0'); + $db->setQuery($query); + $db->execute(); + + // We should delete all core updates here + $query = $db->getQuery(true) + ->delete($db->quoteName('#__updates')) + ->where($db->quoteName('element') . ' = ' . $db->quote('joomla')) + ->where($db->quoteName('type') . ' = ' . $db->quote('file')); + $db->setQuery($query); + + if ($db->execute()) + { + $this->_message = JText::_('COM_JOOMLAUPDATE_CHECKED_UPDATES'); + + return true; + } + else + { + $this->_message = JText::_('COM_JOOMLAUPDATE_FAILED_TO_CHECK_UPDATES'); + + return false; + } + } + + /** + * Downloads the update package to the site. + * + * @return boolean|string False on failure, basename of the file in any other case. + * + * @since 2.5.4 + */ + public function download() + { + $updateInfo = $this->getUpdateInformation(); + $packageURL = trim($updateInfo['object']->downloadurl->_data); + $sources = $updateInfo['object']->get('downloadSources', array()); + $headers = get_headers($packageURL, 1); + + // Follow the Location headers until the actual download URL is known + while (isset($headers['Location'])) + { + $packageURL = $headers['Location']; + $headers = get_headers($packageURL, 1); + } + + // Remove protocol, path and query string from URL + $basename = basename($packageURL); + + if (strpos($basename, '?') !== false) + { + $basename = substr($basename, 0, strpos($basename, '?')); + } + + // Find the path to the temp directory and the local package. + $config = JFactory::getConfig(); + $tempdir = (string) InputFilter::getInstance(array(), array(), 1, 1)->clean($config->get('tmp_path'), 'path'); + $target = $tempdir . '/' . $basename; + $response = array(); + + // Do we have a cached file? + $exists = JFile::exists($target); + + if (!$exists) + { + // Not there, let's fetch it. + $mirror = 0; + + while (!($download = $this->downloadPackage($packageURL, $target)) && isset($sources[$mirror])) + { + $name = $sources[$mirror]; + $packageURL = trim($name->url); + $mirror++; + } + + $response['basename'] = $download; + } + else + { + // Is it a 0-byte file? If so, re-download please. + $filesize = @filesize($target); + + if (empty($filesize)) + { + $mirror = 0; + + while (!($download = $this->downloadPackage($packageURL, $target)) && isset($sources[$mirror])) + { + $name = $sources[$mirror]; + $packageURL = trim($name->url); + $mirror++; + } + + $response['basename'] = $download; + } + + // Yes, it's there, skip downloading. + $response['basename'] = $basename; + } + + $response['check'] = $this->isChecksumValid($target, $updateInfo['object']); + + return $response; + } + + /** + * Return the result of the checksum of a package with the SHA256/SHA384/SHA512 tags in the update server manifest + * + * @param string $packagefile Location of the package to be installed + * @param JUpdate $updateObject The Update Object + * + * @return boolean False in case the validation did not work; true in any other case. + * + * @note This method has been forked from (JInstallerHelper::isChecksumValid) so it + * does not depend on an up-to-date InstallerHelper at the update time + * + * @since 3.9.0 + */ + private function isChecksumValid($packagefile, $updateObject) + { + $hashes = array('sha256', 'sha384', 'sha512'); + + foreach ($hashes as $hash) + { + if ($updateObject->get($hash, false)) + { + $hashPackage = hash_file($hash, $packagefile); + $hashRemote = $updateObject->$hash->_data; + + if ($hashPackage !== $hashRemote) + { + // Return false in case the hash did not match + return false; + } + } + } + + // Well nothing was provided or all worked + return true; + } + + /** + * Downloads a package file to a specific directory + * + * @param string $url The URL to download from + * @param string $target The directory to store the file + * + * @return boolean True on success + * + * @since 2.5.4 + */ + protected function downloadPackage($url, $target) + { + JLoader::import('helpers.download', JPATH_COMPONENT_ADMINISTRATOR); + + try + { + JLog::add(JText::sprintf('COM_JOOMLAUPDATE_UPDATE_LOG_URL', $url), JLog::INFO, 'Update'); + } + catch (RuntimeException $exception) + { + // Informational log only + } + + // Get the handler to download the package + try + { + $http = JHttpFactory::getHttp(null, array('curl', 'stream')); + } + catch (RuntimeException $e) + { + return false; + } + + jimport('joomla.filesystem.file'); + + // Make sure the target does not exist. + JFile::delete($target); + + // Download the package + try + { + $result = $http->get($url); + } + catch (RuntimeException $e) + { + return false; + } + + if (!$result || ($result->code != 200 && $result->code != 310)) + { + return false; + } + + // Write the file to disk + JFile::write($target, $result->body); + + return basename($target); + } + + /** + * Create restoration file. + * + * @param string $basename Optional base path to the file. + * + * @return boolean True if successful; false otherwise. + * + * @since 2.5.4 + */ + public function createRestorationFile($basename = null) + { + // Get a password + $password = JUserHelper::genRandomPassword(32); + $app = JFactory::getApplication(); + $app->setUserState('com_joomlaupdate.password', $password); + + // Do we have to use FTP? + $method = JFactory::getApplication()->getUserStateFromRequest('com_joomlaupdate.method', 'method', 'direct', 'cmd'); + + // Get the absolute path to site's root. + $siteroot = JPATH_SITE; + + // If the package name is not specified, get it from the update info. + if (empty($basename)) + { + $updateInfo = $this->getUpdateInformation(); + $packageURL = $updateInfo['object']->downloadurl->_data; + $basename = basename($packageURL); + } + + // Get the package name. + $config = JFactory::getConfig(); + $tempdir = $config->get('tmp_path'); + $file = $tempdir . '/' . $basename; + + $filesize = @filesize($file); + $app->setUserState('com_joomlaupdate.password', $password); + $app->setUserState('com_joomlaupdate.filesize', $filesize); + + $data = " '$password', + 'kickstart.tuning.max_exec_time' => '5', + 'kickstart.tuning.run_time_bias' => '75', + 'kickstart.tuning.min_exec_time' => '0', + 'kickstart.procengine' => '$method', + 'kickstart.setup.sourcefile' => '$file', + 'kickstart.setup.destdir' => '$siteroot', + 'kickstart.setup.restoreperms' => '0', + 'kickstart.setup.filetype' => 'zip', + 'kickstart.setup.dryrun' => '0', + 'kickstart.setup.renamefiles' => array(), + 'kickstart.setup.postrenamefiles' => false +ENDDATA; + + if ($method != 'direct') + { + /* + * Fetch the FTP parameters from the request. Note: The password should be + * allowed as raw mode, otherwise something like !@43H% would be + * sanitised to !@43H% which is just plain wrong. + */ + $ftp_host = $app->input->get('ftp_host', ''); + $ftp_port = $app->input->get('ftp_port', '21'); + $ftp_user = $app->input->get('ftp_user', ''); + $ftp_pass = addcslashes($app->input->get('ftp_pass', '', 'raw'), "'\\"); + $ftp_root = $app->input->get('ftp_root', ''); + + // Is the tempdir really writable? + $writable = @is_writeable($tempdir); + + if ($writable) + { + // Let's be REALLY sure. + $fp = @fopen($tempdir . '/test.txt', 'w'); + + if ($fp === false) + { + $writable = false; + } + else + { + fclose($fp); + unlink($tempdir . '/test.txt'); + } + } + + // If the tempdir is not writable, create a new writable subdirectory. + if (!$writable) + { + $FTPOptions = JClientHelper::getCredentials('ftp'); + $ftp = JClientFtp::getInstance($FTPOptions['host'], $FTPOptions['port'], array(), $FTPOptions['user'], $FTPOptions['pass']); + $dest = JPath::clean(str_replace(JPATH_ROOT, $FTPOptions['root'], $tempdir . '/admintools'), '/'); + + if (!@mkdir($tempdir . '/admintools')) + { + $ftp->mkdir($dest); + } + + if (!@chmod($tempdir . '/admintools', 511)) + { + $ftp->chmod($dest, 511); + } + + $tempdir .= '/admintools'; + } + + // Just in case the temp-directory was off-root, try using the default tmp directory. + $writable = @is_writeable($tempdir); + + if (!$writable) + { + $tempdir = JPATH_ROOT . '/tmp'; + + // Does the JPATH_ROOT/tmp directory exist? + if (!is_dir($tempdir)) + { + JFolder::create($tempdir, 511); + $htaccessContents = "order deny,allow\ndeny from all\nallow from none\n"; + JFile::write($tempdir . '/.htaccess', $htaccessContents); + } + + // If it exists and it is unwritable, try creating a writable admintools subdirectory. + if (!is_writable($tempdir)) + { + $FTPOptions = JClientHelper::getCredentials('ftp'); + $ftp = JClientFtp::getInstance($FTPOptions['host'], $FTPOptions['port'], array(), $FTPOptions['user'], $FTPOptions['pass']); + $dest = JPath::clean(str_replace(JPATH_ROOT, $FTPOptions['root'], $tempdir . '/admintools'), '/'); + + if (!@mkdir($tempdir . '/admintools')) + { + $ftp->mkdir($dest); + } + + if (!@chmod($tempdir . '/admintools', 511)) + { + $ftp->chmod($dest, 511); + } + + $tempdir .= '/admintools'; + } + } + + // If we still have no writable directory, we'll try /tmp and the system's temp-directory. + $writable = @is_writeable($tempdir); + + if (!$writable) + { + if (@is_dir('/tmp') && @is_writable('/tmp')) + { + $tempdir = '/tmp'; + } + else + { + // Try to find the system temp path. + $tmpfile = @tempnam('dummy', ''); + $systemp = @dirname($tmpfile); + @unlink($tmpfile); + + if (!empty($systemp)) + { + if (@is_dir($systemp) && @is_writable($systemp)) + { + $tempdir = $systemp; + } + } + } + } + + $data .= << '0', + 'kickstart.ftp.passive' => '1', + 'kickstart.ftp.host' => '$ftp_host', + 'kickstart.ftp.port' => '$ftp_port', + 'kickstart.ftp.user' => '$ftp_user', + 'kickstart.ftp.pass' => '$ftp_pass', + 'kickstart.ftp.dir' => '$ftp_root', + 'kickstart.ftp.tempdir' => '$tempdir' +ENDDATA; + } + + $data .= ');'; + + // Remove the old file, if it's there... + $configpath = JPATH_COMPONENT_ADMINISTRATOR . '/restoration.php'; + + if (JFile::exists($configpath)) + { + JFile::delete($configpath); + } + + // Write new file. First try with JFile. + $result = JFile::write($configpath, $data); + + // In case JFile used FTP but direct access could help. + if (!$result) + { + if (function_exists('file_put_contents')) + { + $result = @file_put_contents($configpath, $data); + + if ($result !== false) + { + $result = true; + } + } + else + { + $fp = @fopen($configpath, 'wt'); + + if ($fp !== false) + { + $result = @fwrite($fp, $data); + + if ($result !== false) + { + $result = true; + } + + @fclose($fp); + } + } + } + + return $result; + } + + /** + * Runs the schema update SQL files, the PHP update script and updates the + * manifest cache and #__extensions entry. Essentially, it is identical to + * JInstallerFile::install() without the file copy. + * + * @return boolean True on success. + * + * @since 2.5.4 + */ + public function finaliseUpgrade() + { + $installer = JInstaller::getInstance(); + + $manifest = $installer->isManifest(JPATH_MANIFESTS . '/files/joomla.xml'); + + if ($manifest === false) + { + $installer->abort(JText::_('JLIB_INSTALLER_ABORT_DETECTMANIFEST')); + + return false; + } + + $installer->manifest = $manifest; + + $installer->setUpgrade(true); + $installer->setOverwrite(true); + + $installer->extension = JTable::getInstance('extension'); + $installer->extension->load(700); + + $installer->setAdapter($installer->extension->type); + + $installer->setPath('manifest', JPATH_MANIFESTS . '/files/joomla.xml'); + $installer->setPath('source', JPATH_MANIFESTS . '/files'); + $installer->setPath('extension_root', JPATH_ROOT); + + // Run the script file. + JLoader::register('JoomlaInstallerScript', JPATH_ADMINISTRATOR . '/components/com_admin/script.php'); + + $manifestClass = new JoomlaInstallerScript; + + ob_start(); + ob_implicit_flush(false); + + if ($manifestClass && method_exists($manifestClass, 'preflight')) + { + if ($manifestClass->preflight('update', $installer) === false) + { + $installer->abort(JText::_('JLIB_INSTALLER_ABORT_FILE_INSTALL_CUSTOM_INSTALL_FAILURE')); + + return false; + } + } + + // Create msg object; first use here. + $msg = ob_get_contents(); + ob_end_clean(); + + // Get a database connector object. + $db = $this->getDbo(); + + /* + * Check to see if a file extension by the same name is already installed. + * If it is, then update the table because if the files aren't there + * we can assume that it was (badly) uninstalled. + * If it isn't, add an entry to extensions. + */ + $query = $db->getQuery(true) + ->select($db->quoteName('extension_id')) + ->from($db->quoteName('#__extensions')) + ->where($db->quoteName('type') . ' = ' . $db->quote('file')) + ->where($db->quoteName('element') . ' = ' . $db->quote('joomla')); + $db->setQuery($query); + + try + { + $db->execute(); + } + catch (RuntimeException $e) + { + // Install failed, roll back changes. + $installer->abort( + JText::sprintf('JLIB_INSTALLER_ABORT_FILE_ROLLBACK', JText::_('JLIB_INSTALLER_UPDATE'), $e->getMessage()) + ); + + return false; + } + + $id = $db->loadResult(); + $row = JTable::getInstance('extension'); + + if ($id) + { + // Load the entry and update the manifest_cache. + $row->load($id); + + // Update name. + $row->set('name', 'files_joomla'); + + // Update manifest. + $row->manifest_cache = $installer->generateManifestCache(); + + if (!$row->store()) + { + // Install failed, roll back changes. + $installer->abort( + JText::sprintf('JLIB_INSTALLER_ABORT_FILE_ROLLBACK', JText::_('JLIB_INSTALLER_UPDATE'), $row->getError()) + ); + + return false; + } + } + else + { + // Add an entry to the extension table with a whole heap of defaults. + $row->set('name', 'files_joomla'); + $row->set('type', 'file'); + $row->set('element', 'joomla'); + + // There is no folder for files so leave it blank. + $row->set('folder', ''); + $row->set('enabled', 1); + $row->set('protected', 0); + $row->set('access', 0); + $row->set('client_id', 0); + $row->set('params', ''); + $row->set('system_data', ''); + $row->set('manifest_cache', $installer->generateManifestCache()); + + if (!$row->store()) + { + // Install failed, roll back changes. + $installer->abort(JText::sprintf('JLIB_INSTALLER_ABORT_FILE_INSTALL_ROLLBACK', $row->getError())); + + return false; + } + + // Set the insert id. + $row->set('extension_id', $db->insertid()); + + // Since we have created a module item, we add it to the installation step stack + // so that if we have to rollback the changes we can undo it. + $installer->pushStep(array('type' => 'extension', 'extension_id' => $row->extension_id)); + } + + $result = $installer->parseSchemaUpdates($manifest->update->schemas, $row->extension_id); + + if ($result === false) + { + // Install failed, rollback changes. + $installer->abort(JText::sprintf('JLIB_INSTALLER_ABORT_FILE_UPDATE_SQL_ERROR', $db->stderr(true))); + + return false; + } + + // Start Joomla! 1.6. + ob_start(); + ob_implicit_flush(false); + + if ($manifestClass && method_exists($manifestClass, 'update')) + { + if ($manifestClass->update($installer) === false) + { + // Install failed, rollback changes. + $installer->abort(JText::_('JLIB_INSTALLER_ABORT_FILE_INSTALL_CUSTOM_INSTALL_FAILURE')); + + return false; + } + } + + // Append messages. + $msg .= ob_get_contents(); + ob_end_clean(); + + // Clobber any possible pending updates. + $update = JTable::getInstance('update'); + $uid = $update->find( + array('element' => 'joomla', 'type' => 'file', 'client_id' => '0', 'folder' => '') + ); + + if ($uid) + { + $update->delete($uid); + } + + // And now we run the postflight. + ob_start(); + ob_implicit_flush(false); + + if ($manifestClass && method_exists($manifestClass, 'postflight')) + { + $manifestClass->postflight('update', $installer); + } + + // Append messages. + $msg .= ob_get_contents(); + ob_end_clean(); + + if ($msg != '') + { + $installer->set('extension_message', $msg); + } + + // Refresh versionable assets cache. + JFactory::getApplication()->flushAssets(); + + return true; + } + + /** + * Removes the extracted package file. + * + * @return void + * + * @since 2.5.4 + */ + public function cleanUp() + { + // Remove the update package. + $config = JFactory::getConfig(); + $tempdir = $config->get('tmp_path'); + + $file = JFactory::getApplication()->getUserState('com_joomlaupdate.file', null); + $target = $tempdir . '/' . $file; + + if (!@unlink($target)) + { + JFile::delete($target); + } + + // Remove the restoration.php file. + $target = JPATH_COMPONENT_ADMINISTRATOR . '/restoration.php'; + + if (!@unlink($target)) + { + JFile::delete($target); + } + + // Remove joomla.xml from the site's root. + $target = JPATH_ROOT . '/joomla.xml'; + + if (!@unlink($target)) + { + JFile::delete($target); + } + + // Unset the update filename from the session. + JFactory::getApplication()->setUserState('com_joomlaupdate.file', null); + $oldVersion = JFactory::getApplication()->getUserState('com_joomlaupdate.oldversion'); + + // Trigger event after joomla update. + JFactory::getApplication()->triggerEvent('onJoomlaAfterUpdate', array($oldVersion)); + JFactory::getApplication()->setUserState('com_joomlaupdate.oldversion', null); + } + + /** + * Uploads what is presumably an update ZIP file under a mangled name in the temporary directory. + * + * @return void + * + * @since 3.6.0 + */ + public function upload() + { + // Get the uploaded file information. + $input = JFactory::getApplication()->input; + + // Do not change the filter type 'raw'. We need this to let files containing PHP code to upload. See JInputFiles::get. + $userfile = $input->files->get('install_package', null, 'raw'); + + // Make sure that file uploads are enabled in php. + if (!(bool) ini_get('file_uploads')) + { + throw new RuntimeException(JText::_('COM_INSTALLER_MSG_INSTALL_WARNINSTALLFILE'), 500); + } + + // Make sure that zlib is loaded so that the package can be unpacked. + if (!extension_loaded('zlib')) + { + throw new RuntimeException('COM_INSTALLER_MSG_INSTALL_WARNINSTALLZLIB', 500); + } + + // If there is no uploaded file, we have a problem... + if (!is_array($userfile)) + { + throw new RuntimeException(JText::_('COM_INSTALLER_MSG_INSTALL_NO_FILE_SELECTED'), 500); + } + + // Is the PHP tmp directory missing? + if ($userfile['error'] && ($userfile['error'] == UPLOAD_ERR_NO_TMP_DIR)) + { + throw new RuntimeException( + JText::_('COM_INSTALLER_MSG_INSTALL_WARNINSTALLUPLOADERROR') . '
' . + JText::_('COM_INSTALLER_MSG_WARNINGS_PHPUPLOADNOTSET'), + 500 + ); + } + + // Is the max upload size too small in php.ini? + if ($userfile['error'] && ($userfile['error'] == UPLOAD_ERR_INI_SIZE)) + { + throw new RuntimeException( + JText::_('COM_INSTALLER_MSG_INSTALL_WARNINSTALLUPLOADERROR') . '
' . JText::_('COM_INSTALLER_MSG_WARNINGS_SMALLUPLOADSIZE'), + 500 + ); + } + + // Check if there was a different problem uploading the file. + if ($userfile['error'] || $userfile['size'] < 1) + { + throw new RuntimeException(JText::_('COM_INSTALLER_MSG_INSTALL_WARNINSTALLUPLOADERROR'), 500); + } + + // Build the appropriate paths. + $config = JFactory::getConfig(); + $tmp_dest = tempnam($config->get('tmp_path'), 'ju'); + $tmp_src = $userfile['tmp_name']; + + // Move uploaded file. + jimport('joomla.filesystem.file'); + + if (version_compare(JVERSION, '3.4.0', 'ge')) + { + $result = JFile::upload($tmp_src, $tmp_dest, false, true); + } + else + { + // Old Joomla! versions didn't have UploadShield and don't need the fourth parameter to accept uploads + $result = JFile::upload($tmp_src, $tmp_dest); + } + + if (!$result) + { + throw new RuntimeException(JText::_('COM_INSTALLER_MSG_INSTALL_WARNINSTALLUPLOADERROR'), 500); + } + + JFactory::getApplication()->setUserState('com_joomlaupdate.temp_file', $tmp_dest); + } + + /** + * Checks the super admin credentials are valid for the currently logged in users + * + * @param array $credentials The credentials to authenticate the user with + * + * @return boolean + * + * @since 3.6.0 + */ + public function captiveLogin($credentials) + { + // Make sure the username matches + $username = isset($credentials['username']) ? $credentials['username'] : null; + $user = JFactory::getUser(); + + if (strtolower($user->username) != strtolower($username)) + { + return false; + } + + // Make sure the user is authorised + if (!$user->authorise('core.admin')) + { + return false; + } + + // Get the global JAuthentication object. + $authenticate = JAuthentication::getInstance(); + $response = $authenticate->authenticate($credentials); + + if ($response->status !== JAuthentication::STATUS_SUCCESS) + { + return false; + } + + return true; + } + + /** + * Does the captive (temporary) file we uploaded before still exist? + * + * @return boolean + * + * @since 3.6.0 + */ + public function captiveFileExists() + { + $file = JFactory::getApplication()->getUserState('com_joomlaupdate.temp_file', null); + + JLoader::import('joomla.filesystem.file'); + + if (empty($file) || !JFile::exists($file)) + { + return false; + } + + return true; + } + + /** + * Remove the captive (temporary) file we uploaded before and the . + * + * @return void + * + * @since 3.6.0 + */ + public function removePackageFiles() + { + $files = array( + JFactory::getApplication()->getUserState('com_joomlaupdate.temp_file', null), + JFactory::getApplication()->getUserState('com_joomlaupdate.file', null), + ); + + JLoader::import('joomla.filesystem.file'); + + foreach ($files as $file) + { + if (JFile::exists($file)) + { + if (!@unlink($file)) + { + JFile::delete($file); + } + } + } + } +} diff --git a/Sites/pages/administrator/components/com_joomlaupdate/restore.php b/Sites/pages/administrator/components/com_joomlaupdate/restore.php new file mode 100644 index 00000000..00a8bde3 --- /dev/null +++ b/Sites/pages/administrator/components/com_joomlaupdate/restore.php @@ -0,0 +1,8440 @@ +|'), + array('*' => '.*', '?' => '.?')) . '$/i', $string + ); + } +} + +// Unicode-safe binary data length function +if (!function_exists('akstringlen')) +{ + if (function_exists('mb_strlen')) + { + function akstringlen($string) + { + return mb_strlen($string, '8bit'); + } + } + else + { + function akstringlen($string) + { + return strlen($string); + } + } +} + +if (!function_exists('aksubstr')) +{ + if (function_exists('mb_strlen')) + { + function aksubstr($string, $start, $length = null) + { + return mb_substr($string, $start, $length, '8bit'); + } + } + else + { + function aksubstr($string, $start, $length = null) + { + return substr($string, $start, $length); + } + } +} + +/** + * Gets a query parameter from GET or POST data + * + * @param $key + * @param $default + */ +function getQueryParam($key, $default = null) +{ + $value = $default; + + if (array_key_exists($key, $_REQUEST)) + { + $value = $_REQUEST[$key]; + } + + if (PHP_VERSION_ID < 50400 && get_magic_quotes_gpc() && !is_null($value)) + { + $value = stripslashes($value); + } + + return $value; +} + +// Debugging function +function debugMsg($msg) +{ + if (!defined('KSDEBUG')) + { + return; + } + + $fp = fopen('debug.txt', 'at'); + + fwrite($fp, $msg . "\n"); + fclose($fp); + + // Echo to stdout if KSDEBUGCLI is defined + if (defined('KSDEBUGCLI')) + { + echo $msg . "\n"; + } +} + +/** + * Akeeba Restore + * A JSON-powered JPA, JPS and ZIP archive extraction library + * + * @copyright 2008-2017 Nicholas K. Dionysopoulos / Akeeba Ltd. + * @license GNU GPL v2 or - at your option - any later version + * @package akeebabackup + * @subpackage kickstart + */ + +/** + * The base class of Akeeba Engine objects. Allows for error and warnings logging + * and propagation. Largely based on the Joomla! 1.5 JObject class. + */ +abstract class AKAbstractObject +{ + /** @var array The queue size of the $_errors array. Set to 0 for infinite size. */ + protected $_errors_queue_size = 0; + /** @var array The queue size of the $_warnings array. Set to 0 for infinite size. */ + protected $_warnings_queue_size = 0; + /** @var array An array of errors */ + private $_errors = array(); + /** @var array An array of warnings */ + private $_warnings = array(); + + /** + * Public constructor, makes sure we are instantiated only by the factory class + */ + public function __construct() + { + /* + // Assisted Singleton pattern + if(function_exists('debug_backtrace')) + { + $caller=debug_backtrace(); + if( + ($caller[1]['class'] != 'AKFactory') && + ($caller[2]['class'] != 'AKFactory') && + ($caller[3]['class'] != 'AKFactory') && + ($caller[4]['class'] != 'AKFactory') + ) { + var_dump(debug_backtrace()); + trigger_error("You can't create direct descendants of ".__CLASS__, E_USER_ERROR); + } + } + */ + } + + /** + * Get the most recent error message + * + * @param integer $i Optional error index + * + * @return string Error message + */ + public function getError($i = null) + { + return $this->getItemFromArray($this->_errors, $i); + } + + /** + * Returns the last item of a LIFO string message queue, or a specific item + * if so specified. + * + * @param array $array An array of strings, holding messages + * @param int $i Optional message index + * + * @return mixed The message string, or false if the key doesn't exist + */ + private function getItemFromArray($array, $i = null) + { + // Find the item + if ($i === null) + { + // Default, return the last item + $item = end($array); + } + else if (!array_key_exists($i, $array)) + { + // If $i has been specified but does not exist, return false + return false; + } + else + { + $item = $array[$i]; + } + + return $item; + } + + /** + * Return all errors, if any + * + * @return array Array of error messages + */ + public function getErrors() + { + return $this->_errors; + } + + /** + * Resets all error messages + */ + public function resetErrors() + { + $this->_errors = array(); + } + + /** + * Get the most recent warning message + * + * @param integer $i Optional warning index + * + * @return string Error message + */ + public function getWarning($i = null) + { + return $this->getItemFromArray($this->_warnings, $i); + } + + /** + * Return all warnings, if any + * + * @return array Array of error messages + */ + public function getWarnings() + { + return $this->_warnings; + } + + /** + * Resets all warning messages + */ + public function resetWarnings() + { + $this->_warnings = array(); + } + + /** + * Propagates errors and warnings to a foreign object. The foreign object SHOULD + * implement the setError() and/or setWarning() methods but DOESN'T HAVE TO be of + * AKAbstractObject type. For example, this can even be used to propagate to a + * JObject instance in Joomla!. Propagated items will be removed from ourselves. + * + * @param object $object The object to propagate errors and warnings to. + */ + public function propagateToObject(&$object) + { + // Skip non-objects + if (!is_object($object)) + { + return; + } + + if (method_exists($object, 'setError')) + { + if (!empty($this->_errors)) + { + foreach ($this->_errors as $error) + { + $object->setError($error); + } + $this->_errors = array(); + } + } + + if (method_exists($object, 'setWarning')) + { + if (!empty($this->_warnings)) + { + foreach ($this->_warnings as $warning) + { + $object->setWarning($warning); + } + $this->_warnings = array(); + } + } + } + + /** + * Propagates errors and warnings from a foreign object. Each propagated list is + * then cleared on the foreign object, as long as it implements resetErrors() and/or + * resetWarnings() methods. + * + * @param object $object The object to propagate errors and warnings from + */ + public function propagateFromObject(&$object) + { + if (method_exists($object, 'getErrors')) + { + $errors = $object->getErrors(); + if (!empty($errors)) + { + foreach ($errors as $error) + { + $this->setError($error); + } + } + if (method_exists($object, 'resetErrors')) + { + $object->resetErrors(); + } + } + + if (method_exists($object, 'getWarnings')) + { + $warnings = $object->getWarnings(); + if (!empty($warnings)) + { + foreach ($warnings as $warning) + { + $this->setWarning($warning); + } + } + if (method_exists($object, 'resetWarnings')) + { + $object->resetWarnings(); + } + } + } + + /** + * Add an error message + * + * @param string $error Error message + */ + public function setError($error) + { + if ($this->_errors_queue_size > 0) + { + if (count($this->_errors) >= $this->_errors_queue_size) + { + array_shift($this->_errors); + } + } + + $this->_errors[] = $error; + } + + /** + * Add an error message + * + * @param string $error Error message + */ + public function setWarning($warning) + { + if ($this->_warnings_queue_size > 0) + { + if (count($this->_warnings) >= $this->_warnings_queue_size) + { + array_shift($this->_warnings); + } + } + + $this->_warnings[] = $warning; + } + + /** + * Sets the size of the error queue (acts like a LIFO buffer) + * + * @param int $newSize The new queue size. Set to 0 for infinite length. + */ + protected function setErrorsQueueSize($newSize = 0) + { + $this->_errors_queue_size = (int) $newSize; + } + + /** + * Sets the size of the warnings queue (acts like a LIFO buffer) + * + * @param int $newSize The new queue size. Set to 0 for infinite length. + */ + protected function setWarningsQueueSize($newSize = 0) + { + $this->_warnings_queue_size = (int) $newSize; + } + +} + +/** + * Akeeba Restore + * A JSON-powered JPA, JPS and ZIP archive extraction library + * + * @copyright 2008-2017 Nicholas K. Dionysopoulos / Akeeba Ltd. + * @license GNU GPL v2 or - at your option - any later version + * @package akeebabackup + * @subpackage kickstart + */ + +/** + * The superclass of all Akeeba Kickstart parts. The "parts" are intelligent stateful + * classes which perform a single procedure and have preparation, running and + * finalization phases. The transition between phases is handled automatically by + * this superclass' tick() final public method, which should be the ONLY public API + * exposed to the rest of the Akeeba Engine. + */ +abstract class AKAbstractPart extends AKAbstractObject +{ + /** + * Indicates whether this part has finished its initialisation cycle + * + * @var boolean + */ + protected $isPrepared = false; + + /** + * Indicates whether this part has more work to do (it's in running state) + * + * @var boolean + */ + protected $isRunning = false; + + /** + * Indicates whether this part has finished its finalization cycle + * + * @var boolean + */ + protected $isFinished = false; + + /** + * Indicates whether this part has finished its run cycle + * + * @var boolean + */ + protected $hasRan = false; + + /** + * The name of the engine part (a.k.a. Domain), used in return table + * generation. + * + * @var string + */ + protected $active_domain = ""; + + /** + * The step this engine part is in. Used verbatim in return table and + * should be set by the code in the _run() method. + * + * @var string + */ + protected $active_step = ""; + + /** + * A more detailed description of the step this engine part is in. Used + * verbatim in return table and should be set by the code in the _run() + * method. + * + * @var string + */ + protected $active_substep = ""; + + /** + * Any configuration variables, in the form of an array. + * + * @var array + */ + protected $_parametersArray = array(); + + /** @var string The database root key */ + protected $databaseRoot = array(); + /** @var array An array of observers */ + protected $observers = array(); + /** @var int Last reported warnings's position in array */ + private $warnings_pointer = -1; + + /** + * The public interface to an engine part. This method takes care for + * calling the correct method in order to perform the initialisation - + * run - finalisation cycle of operation and return a proper response array. + * + * @return array A Response Array + */ + final public function tick() + { + // Call the right action method, depending on engine part state + switch ($this->getState()) + { + case "init": + $this->_prepare(); + break; + case "prepared": + $this->_run(); + break; + case "running": + $this->_run(); + break; + case "postrun": + $this->_finalize(); + break; + } + + // Send a Return Table back to the caller + $out = $this->_makeReturnTable(); + + return $out; + } + + /** + * Returns the state of this engine part. + * + * @return string The state of this engine part. It can be one of + * error, init, prepared, running, postrun, finished. + */ + final public function getState() + { + if ($this->getError()) + { + return "error"; + } + + if (!($this->isPrepared)) + { + return "init"; + } + + if (!($this->isFinished) && !($this->isRunning) && !($this->hasRun) && ($this->isPrepared)) + { + return "prepared"; + } + + if (!($this->isFinished) && $this->isRunning && !($this->hasRun)) + { + return "running"; + } + + if (!($this->isFinished) && !($this->isRunning) && $this->hasRun) + { + return "postrun"; + } + + if ($this->isFinished) + { + return "finished"; + } + } + + /** + * Runs the preparation for this part. Should set _isPrepared + * to true + */ + abstract protected function _prepare(); + + /** + * Runs the main functionality loop for this part. Upon calling, + * should set the _isRunning to true. When it finished, should set + * the _hasRan to true. If an error is encountered, setError should + * be used. + */ + abstract protected function _run(); + + /** + * Runs the finalisation process for this part. Should set + * _isFinished to true. + */ + abstract protected function _finalize(); + + /** + * Constructs a Response Array based on the engine part's state. + * + * @return array The Response Array for the current state + */ + final protected function _makeReturnTable() + { + // Get a list of warnings + $warnings = $this->getWarnings(); + // Report only new warnings if there is no warnings queue size + if ($this->_warnings_queue_size == 0) + { + if (($this->warnings_pointer > 0) && ($this->warnings_pointer < (count($warnings)))) + { + $warnings = array_slice($warnings, $this->warnings_pointer + 1); + $this->warnings_pointer += count($warnings); + } + else + { + $this->warnings_pointer = count($warnings); + } + } + + $out = array( + 'HasRun' => (!($this->isFinished)), + 'Domain' => $this->active_domain, + 'Step' => $this->active_step, + 'Substep' => $this->active_substep, + 'Error' => $this->getError(), + 'Warnings' => $warnings + ); + + return $out; + } + + /** + * Returns a copy of the class's status array + * + * @return array + */ + public function getStatusArray() + { + return $this->_makeReturnTable(); + } + + /** + * Sends any kind of setup information to the engine part. Using this, + * we avoid passing parameters to the constructor of the class. These + * parameters should be passed as an indexed array and should be taken + * into account during the preparation process only. This function will + * set the error flag if it's called after the engine part is prepared. + * + * @param array $parametersArray The parameters to be passed to the + * engine part. + */ + final public function setup($parametersArray) + { + if ($this->isPrepared) + { + $this->setState('error', "Can't modify configuration after the preparation of " . $this->active_domain); + } + else + { + $this->_parametersArray = $parametersArray; + if (array_key_exists('root', $parametersArray)) + { + $this->databaseRoot = $parametersArray['root']; + } + } + } + + /** + * Sets the engine part's internal state, in an easy to use manner + * + * @param string $state One of init, prepared, running, postrun, finished, error + * @param string $errorMessage The reported error message, should the state be set to error + */ + protected function setState($state = 'init', $errorMessage = 'Invalid setState argument') + { + switch ($state) + { + case 'init': + $this->isPrepared = false; + $this->isRunning = false; + $this->isFinished = false; + $this->hasRun = false; + break; + + case 'prepared': + $this->isPrepared = true; + $this->isRunning = false; + $this->isFinished = false; + $this->hasRun = false; + break; + + case 'running': + $this->isPrepared = true; + $this->isRunning = true; + $this->isFinished = false; + $this->hasRun = false; + break; + + case 'postrun': + $this->isPrepared = true; + $this->isRunning = false; + $this->isFinished = false; + $this->hasRun = true; + break; + + case 'finished': + $this->isPrepared = true; + $this->isRunning = false; + $this->isFinished = true; + $this->hasRun = false; + break; + + case 'error': + default: + $this->setError($errorMessage); + break; + } + } + + final public function getDomain() + { + return $this->active_domain; + } + + final public function getStep() + { + return $this->active_step; + } + + final public function getSubstep() + { + return $this->active_substep; + } + + /** + * Attaches an observer object + * + * @param AKAbstractPartObserver $obs + */ + function attach(AKAbstractPartObserver $obs) + { + $this->observers["$obs"] = $obs; + } + + /** + * Detaches an observer object + * + * @param AKAbstractPartObserver $obs + */ + function detach(AKAbstractPartObserver $obs) + { + delete($this->observers["$obs"]); + } + + /** + * Sets the BREAKFLAG, which instructs this engine part that the current step must break immediately, + * in fear of timing out. + */ + protected function setBreakFlag() + { + AKFactory::set('volatile.breakflag', true); + } + + final protected function setDomain($new_domain) + { + $this->active_domain = $new_domain; + } + + final protected function setStep($new_step) + { + $this->active_step = $new_step; + } + + final protected function setSubstep($new_substep) + { + $this->active_substep = $new_substep; + } + + /** + * Notifies observers each time something interesting happened to the part + * + * @param mixed $message The event object + */ + protected function notify($message) + { + foreach ($this->observers as $obs) + { + $obs->update($this, $message); + } + } +} + +/** + * Akeeba Restore + * A JSON-powered JPA, JPS and ZIP archive extraction library + * + * @copyright 2008-2017 Nicholas K. Dionysopoulos / Akeeba Ltd. + * @license GNU GPL v2 or - at your option - any later version + * @package akeebabackup + * @subpackage kickstart + */ + +/** + * The base class of unarchiver classes + */ +abstract class AKAbstractUnarchiver extends AKAbstractPart +{ + /** @var array List of the names of all archive parts */ + public $archiveList = array(); + /** @var int The total size of all archive parts */ + public $totalSize = array(); + /** @var array Which files to rename */ + public $renameFiles = array(); + /** @var array Which directories to rename */ + public $renameDirs = array(); + /** @var array Which files to skip */ + public $skipFiles = array(); + /** @var string Archive filename */ + protected $filename = null; + /** @var integer Current archive part number */ + protected $currentPartNumber = -1; + /** @var integer The offset inside the current part */ + protected $currentPartOffset = 0; + /** @var bool Should I restore permissions? */ + protected $flagRestorePermissions = false; + /** @var AKAbstractPostproc Post processing class */ + protected $postProcEngine = null; + /** @var string Absolute path to prepend to extracted files */ + protected $addPath = ''; + /** @var string Absolute path to remove from extracted files */ + protected $removePath = ''; + /** @var integer Chunk size for processing */ + protected $chunkSize = 524288; + + /** @var resource File pointer to the current archive part file */ + protected $fp = null; + + /** @var int Run state when processing the current archive file */ + protected $runState = null; + + /** @var stdClass File header data, as read by the readFileHeader() method */ + protected $fileHeader = null; + + /** @var int How much of the uncompressed data we've read so far */ + protected $dataReadLength = 0; + + /** @var array Unwriteable files in these directories are always ignored and do not cause errors when not extracted */ + protected $ignoreDirectories = array(); + + /** + * Public constructor + */ + public function __construct() + { + parent::__construct(); + } + + /** + * Wakeup function, called whenever the class is unserialized + */ + public function __wakeup() + { + if ($this->currentPartNumber >= 0 && !empty($this->archiveList[$this->currentPartNumber])) + { + $this->fp = @fopen($this->archiveList[$this->currentPartNumber], 'rb'); + if ((is_resource($this->fp)) && ($this->currentPartOffset > 0)) + { + @fseek($this->fp, $this->currentPartOffset); + } + } + } + + /** + * Sleep function, called whenever the class is serialized + */ + public function shutdown() + { + if (is_resource($this->fp)) + { + $this->currentPartOffset = @ftell($this->fp); + @fclose($this->fp); + } + } + + /** + * Is this file or directory contained in a directory we've decided to ignore + * write errors for? This is useful to let the extraction work despite write + * errors in the log, logs and tmp directories which MIGHT be used by the system + * on some low quality hosts and Plesk-powered hosts. + * + * @param string $shortFilename The relative path of the file/directory in the package + * + * @return boolean True if it belongs in an ignored directory + */ + public function isIgnoredDirectory($shortFilename) + { + // return false; + + if (substr($shortFilename, -1) == '/') + { + $check = rtrim($shortFilename, '/'); + } + else + { + $check = dirname($shortFilename); + } + + return in_array($check, $this->ignoreDirectories); + } + + /** + * Implements the abstract _prepare() method + */ + final protected function _prepare() + { + parent::__construct(); + + if (count($this->_parametersArray) > 0) + { + foreach ($this->_parametersArray as $key => $value) + { + switch ($key) + { + // Archive's absolute filename + case 'filename': + $this->filename = $value; + + // Sanity check + if (!empty($value)) + { + $value = strtolower($value); + + if (strlen($value) > 6) + { + if ( + (substr($value, 0, 7) == 'http://') + || (substr($value, 0, 8) == 'https://') + || (substr($value, 0, 6) == 'ftp://') + || (substr($value, 0, 7) == 'ssh2://') + || (substr($value, 0, 6) == 'ssl://') + ) + { + $this->setState('error', 'Invalid archive location'); + } + } + } + + + break; + + // Should I restore permissions? + case 'restore_permissions': + $this->flagRestorePermissions = $value; + break; + + // Should I use FTP? + case 'post_proc': + $this->postProcEngine = AKFactory::getpostProc($value); + break; + + // Path to add in the beginning + case 'add_path': + $this->addPath = $value; + $this->addPath = str_replace('\\', '/', $this->addPath); + $this->addPath = rtrim($this->addPath, '/'); + if (!empty($this->addPath)) + { + $this->addPath .= '/'; + } + break; + + // Path to remove from the beginning + case 'remove_path': + $this->removePath = $value; + $this->removePath = str_replace('\\', '/', $this->removePath); + $this->removePath = rtrim($this->removePath, '/'); + if (!empty($this->removePath)) + { + $this->removePath .= '/'; + } + break; + + // Which files to rename (hash array) + case 'rename_files': + $this->renameFiles = $value; + break; + + // Which files to rename (hash array) + case 'rename_dirs': + $this->renameDirs = $value; + break; + + // Which files to skip (indexed array) + case 'skip_files': + $this->skipFiles = $value; + break; + + // Which directories to ignore when we can't write files in them (indexed array) + case 'ignoredirectories': + $this->ignoreDirectories = $value; + break; + } + } + } + + $this->scanArchives(); + + $this->readArchiveHeader(); + $errMessage = $this->getError(); + if (!empty($errMessage)) + { + $this->setState('error', $errMessage); + } + else + { + $this->runState = AK_STATE_NOFILE; + $this->setState('prepared'); + } + } + + /** + * Scans for archive parts + */ + private function scanArchives() + { + if (defined('KSDEBUG')) + { + @unlink('debug.txt'); + } + debugMsg('Preparing to scan archives'); + + $privateArchiveList = array(); + + // Get the components of the archive filename + $dirname = dirname($this->filename); + $base_extension = $this->getBaseExtension(); + $basename = basename($this->filename, $base_extension); + $this->totalSize = 0; + + // Scan for multiple parts until we don't find any more of them + $count = 0; + $found = true; + $this->archiveList = array(); + while ($found) + { + ++$count; + $extension = substr($base_extension, 0, 2) . sprintf('%02d', $count); + $filename = $dirname . DIRECTORY_SEPARATOR . $basename . $extension; + $found = file_exists($filename); + if ($found) + { + debugMsg('- Found archive ' . $filename); + // Add yet another part, with a numeric-appended filename + $this->archiveList[] = $filename; + + $filesize = @filesize($filename); + $this->totalSize += $filesize; + + $privateArchiveList[] = array($filename, $filesize); + } + else + { + debugMsg('- Found archive ' . $this->filename); + // Add the last part, with the regular extension + $this->archiveList[] = $this->filename; + + $filename = $this->filename; + $filesize = @filesize($filename); + $this->totalSize += $filesize; + + $privateArchiveList[] = array($filename, $filesize); + } + } + debugMsg('Total archive parts: ' . $count); + + $this->currentPartNumber = -1; + $this->currentPartOffset = 0; + $this->runState = AK_STATE_NOFILE; + + // Send start of file notification + $message = new stdClass; + $message->type = 'totalsize'; + $message->content = new stdClass; + $message->content->totalsize = $this->totalSize; + $message->content->filelist = $privateArchiveList; + $this->notify($message); + } + + /** + * Returns the base extension of the file, e.g. '.jpa' + * + * @return string + */ + private function getBaseExtension() + { + static $baseextension; + + if (empty($baseextension)) + { + $basename = basename($this->filename); + $lastdot = strrpos($basename, '.'); + $baseextension = substr($basename, $lastdot); + } + + return $baseextension; + } + + /** + * Concrete classes are supposed to use this method in order to read the archive's header and + * prepare themselves to the point of being ready to extract the first file. + */ + protected abstract function readArchiveHeader(); + + protected function _run() + { + if ($this->getState() == 'postrun') + { + return; + } + + $this->setState('running'); + + $timer = AKFactory::getTimer(); + + $status = true; + while ($status && ($timer->getTimeLeft() > 0)) + { + switch ($this->runState) + { + case AK_STATE_NOFILE: + debugMsg(__CLASS__ . '::_run() - Reading file header'); + $status = $this->readFileHeader(); + if ($status) + { + // Send start of file notification + $message = new stdClass; + $message->type = 'startfile'; + $message->content = new stdClass; + $message->content->realfile = $this->fileHeader->file; + $message->content->file = $this->fileHeader->file; + $message->content->uncompressed = $this->fileHeader->uncompressed; + + if (array_key_exists('realfile', get_object_vars($this->fileHeader))) + { + $message->content->realfile = $this->fileHeader->realFile; + } + + if (array_key_exists('compressed', get_object_vars($this->fileHeader))) + { + $message->content->compressed = $this->fileHeader->compressed; + } + else + { + $message->content->compressed = 0; + } + + debugMsg(__CLASS__ . '::_run() - Preparing to extract ' . $message->content->realfile); + + $this->notify($message); + } + else + { + debugMsg(__CLASS__ . '::_run() - Could not read file header'); + } + break; + + case AK_STATE_HEADER: + case AK_STATE_DATA: + debugMsg(__CLASS__ . '::_run() - Processing file data'); + $status = $this->processFileData(); + break; + + case AK_STATE_DATAREAD: + case AK_STATE_POSTPROC: + debugMsg(__CLASS__ . '::_run() - Calling post-processing class'); + $this->postProcEngine->timestamp = $this->fileHeader->timestamp; + $status = $this->postProcEngine->process(); + $this->propagateFromObject($this->postProcEngine); + $this->runState = AK_STATE_DONE; + break; + + case AK_STATE_DONE: + default: + if ($status) + { + debugMsg(__CLASS__ . '::_run() - Finished extracting file'); + // Send end of file notification + $message = new stdClass; + $message->type = 'endfile'; + $message->content = new stdClass; + if (array_key_exists('realfile', get_object_vars($this->fileHeader))) + { + $message->content->realfile = $this->fileHeader->realFile; + } + else + { + $message->content->realfile = $this->fileHeader->file; + } + $message->content->file = $this->fileHeader->file; + if (array_key_exists('compressed', get_object_vars($this->fileHeader))) + { + $message->content->compressed = $this->fileHeader->compressed; + } + else + { + $message->content->compressed = 0; + } + $message->content->uncompressed = $this->fileHeader->uncompressed; + $this->notify($message); + } + $this->runState = AK_STATE_NOFILE; + break; + } + } + + $error = $this->getError(); + if (!$status && ($this->runState == AK_STATE_NOFILE) && empty($error)) + { + debugMsg(__CLASS__ . '::_run() - Just finished'); + // We just finished + $this->setState('postrun'); + } + elseif (!empty($error)) + { + debugMsg(__CLASS__ . '::_run() - Halted with an error:'); + debugMsg($error); + $this->setState('error', $error); + } + } + + /** + * Concrete classes must use this method to read the file header + * + * @return bool True if reading the file was successful, false if an error occurred or we reached end of archive + */ + protected abstract function readFileHeader(); + + /** + * Concrete classes must use this method to process file data. It must set $runState to AK_STATE_DATAREAD when + * it's finished processing the file data. + * + * @return bool True if processing the file data was successful, false if an error occurred + */ + protected abstract function processFileData(); + + protected function _finalize() + { + // Nothing to do + $this->setState('finished'); + } + + /** + * Opens the next part file for reading + */ + protected function nextFile() + { + debugMsg('Current part is ' . $this->currentPartNumber . '; opening the next part'); + ++$this->currentPartNumber; + + if ($this->currentPartNumber > (count($this->archiveList) - 1)) + { + $this->setState('postrun'); + + return false; + } + else + { + if (is_resource($this->fp)) + { + @fclose($this->fp); + } + debugMsg('Opening file ' . $this->archiveList[$this->currentPartNumber]); + $this->fp = @fopen($this->archiveList[$this->currentPartNumber], 'rb'); + if ($this->fp === false) + { + debugMsg('Could not open file - crash imminent'); + $this->setError(AKText::sprintf('ERR_COULD_NOT_OPEN_ARCHIVE_PART', $this->archiveList[$this->currentPartNumber])); + } + fseek($this->fp, 0); + $this->currentPartOffset = 0; + + return true; + } + } + + /** + * Returns true if we have reached the end of file + * + * @param $local bool True to return EOF of the local file, false (default) to return if we have reached the end of + * the archive set + * + * @return bool True if we have reached End Of File + */ + protected function isEOF($local = false) + { + $eof = @feof($this->fp); + + if (!$eof) + { + // Border case: right at the part's end (eeeek!!!). For the life of me, I don't understand why + // feof() doesn't report true. It expects the fp to be positioned *beyond* the EOF to report + // true. Incredible! :( + $position = @ftell($this->fp); + $filesize = @filesize($this->archiveList[$this->currentPartNumber]); + if ($filesize <= 0) + { + // 2Gb or more files on a 32 bit version of PHP tend to get screwed up. Meh. + $eof = false; + } + elseif ($position >= $filesize) + { + $eof = true; + } + } + + if ($local) + { + return $eof; + } + else + { + return $eof && ($this->currentPartNumber >= (count($this->archiveList) - 1)); + } + } + + /** + * Tries to make a directory user-writable so that we can write a file to it + * + * @param $path string A path to a file + */ + protected function setCorrectPermissions($path) + { + static $rootDir = null; + + if (is_null($rootDir)) + { + $rootDir = rtrim(AKFactory::get('kickstart.setup.destdir', ''), '/\\'); + } + + $directory = rtrim(dirname($path), '/\\'); + if ($directory != $rootDir) + { + // Is this an unwritable directory? + if (!is_writeable($directory)) + { + $this->postProcEngine->chmod($directory, 0755); + } + } + $this->postProcEngine->chmod($path, 0644); + } + + /** + * Reads data from the archive and notifies the observer with the 'reading' message + * + * @param $fp + * @param $length + */ + protected function fread($fp, $length = null) + { + if (is_numeric($length)) + { + if ($length > 0) + { + $data = fread($fp, $length); + } + else + { + $data = fread($fp, PHP_INT_MAX); + } + } + else + { + $data = fread($fp, PHP_INT_MAX); + } + if ($data === false) + { + $data = ''; + } + + // Send start of file notification + $message = new stdClass; + $message->type = 'reading'; + $message->content = new stdClass; + $message->content->length = strlen($data); + $this->notify($message); + + return $data; + } + + /** + * Removes the configured $removePath from the path $path + * + * @param string $path The path to reduce + * + * @return string The reduced path + */ + protected function removePath($path) + { + if (empty($this->removePath)) + { + return $path; + } + + if (strpos($path, $this->removePath) === 0) + { + $path = substr($path, strlen($this->removePath)); + $path = ltrim($path, '/\\'); + } + + return $path; + } +} + +/** + * Akeeba Restore + * A JSON-powered JPA, JPS and ZIP archive extraction library + * + * @copyright 2008-2017 Nicholas K. Dionysopoulos / Akeeba Ltd. + * @license GNU GPL v2 or - at your option - any later version + * @package akeebabackup + * @subpackage kickstart + */ + +/** + * File post processor engines base class + */ +abstract class AKAbstractPostproc extends AKAbstractObject +{ + /** @var int The UNIX timestamp of the file's desired modification date */ + public $timestamp = 0; + /** @var string The current (real) file path we'll have to process */ + protected $filename = null; + /** @var int The requested permissions */ + protected $perms = 0755; + /** @var string The temporary file path we gave to the unarchiver engine */ + protected $tempFilename = null; + + /** + * Processes the current file, e.g. moves it from temp to final location by FTP + */ + abstract public function process(); + + /** + * The unarchiver tells us the path to the filename it wants to extract and we give it + * a different path instead. + * + * @param string $filename The path to the real file + * @param int $perms The permissions we need the file to have + * + * @return string The path to the temporary file + */ + abstract public function processFilename($filename, $perms = 0755); + + /** + * Recursively creates a directory if it doesn't exist + * + * @param string $dirName The directory to create + * @param int $perms The permissions to give to that directory + */ + abstract public function createDirRecursive($dirName, $perms); + + abstract public function chmod($file, $perms); + + abstract public function unlink($file); + + abstract public function rmdir($directory); + + abstract public function rename($from, $to); +} + + +/** + * Akeeba Restore + * A JSON-powered JPA, JPS and ZIP archive extraction library + * + * @copyright 2008-2017 Nicholas K. Dionysopoulos / Akeeba Ltd. + * @license GNU GPL v2 or - at your option - any later version + * @package akeebabackup + * @subpackage kickstart + */ + +/** + * Descendants of this class can be used in the unarchiver's observer methods (attach, detach and notify) + * + * @author Nicholas + * + */ +abstract class AKAbstractPartObserver +{ + abstract public function update($object, $message); +} + + +/** + * Akeeba Restore + * A JSON-powered JPA, JPS and ZIP archive extraction library + * + * @copyright 2008-2017 Nicholas K. Dionysopoulos / Akeeba Ltd. + * @license GNU GPL v2 or - at your option - any later version + * @package akeebabackup + * @subpackage kickstart + */ + +/** + * Direct file writer + */ +class AKPostprocDirect extends AKAbstractPostproc +{ + public function process() + { + $restorePerms = AKFactory::get('kickstart.setup.restoreperms', false); + if ($restorePerms) + { + @chmod($this->filename, $this->perms); + } + else + { + if (@is_file($this->filename)) + { + @chmod($this->filename, 0644); + } + else + { + @chmod($this->filename, 0755); + } + } + if ($this->timestamp > 0) + { + @touch($this->filename, $this->timestamp); + } + + return true; + } + + public function processFilename($filename, $perms = 0755) + { + $this->perms = $perms; + $this->filename = $filename; + + return $filename; + } + + public function createDirRecursive($dirName, $perms) + { + if (AKFactory::get('kickstart.setup.dryrun', '0')) + { + return true; + } + if (@mkdir($dirName, 0755, true)) + { + @chmod($dirName, 0755); + + return true; + } + + $root = AKFactory::get('kickstart.setup.destdir'); + $root = rtrim(str_replace('\\', '/', $root), '/'); + $dir = rtrim(str_replace('\\', '/', $dirName), '/'); + if (strpos($dir, $root) === 0) + { + $dir = ltrim(substr($dir, strlen($root)), '/'); + $root .= '/'; + } + else + { + $root = ''; + } + + if (empty($dir)) + { + return true; + } + + $dirArray = explode('/', $dir); + $path = ''; + foreach ($dirArray as $dir) + { + $path .= $dir . '/'; + $ret = is_dir($root . $path) ? true : @mkdir($root . $path); + if (!$ret) + { + // Is this a file instead of a directory? + if (is_file($root . $path)) + { + @unlink($root . $path); + $ret = @mkdir($root . $path); + } + if (!$ret) + { + $this->setError(AKText::sprintf('COULDNT_CREATE_DIR', $path)); + + return false; + } + } + // Try to set new directory permissions to 0755 + @chmod($root . $path, $perms); + } + + return true; + } + + public function chmod($file, $perms) + { + if (AKFactory::get('kickstart.setup.dryrun', '0')) + { + return true; + } + + return @chmod($file, $perms); + } + + public function unlink($file) + { + return @unlink($file); + } + + public function rmdir($directory) + { + return @rmdir($directory); + } + + public function rename($from, $to) + { + return @rename($from, $to); + } + +} + +/** + * Akeeba Restore + * A JSON-powered JPA, JPS and ZIP archive extraction library + * + * @copyright 2008-2017 Nicholas K. Dionysopoulos / Akeeba Ltd. + * @license GNU GPL v2 or - at your option - any later version + * @package akeebabackup + * @subpackage kickstart + */ + +/** + * FTP file writer + */ +class AKPostprocFTP extends AKAbstractPostproc +{ + /** @var bool Should I use FTP over implicit SSL? */ + public $useSSL = false; + /** @var bool use Passive mode? */ + public $passive = true; + /** @var string FTP host name */ + public $host = ''; + /** @var int FTP port */ + public $port = 21; + /** @var string FTP user name */ + public $user = ''; + /** @var string FTP password */ + public $pass = ''; + /** @var string FTP initial directory */ + public $dir = ''; + /** @var resource The FTP handle */ + private $handle = null; + /** @var string The temporary directory where the data will be stored */ + private $tempDir = ''; + + public function __construct() + { + parent::__construct(); + + $this->useSSL = AKFactory::get('kickstart.ftp.ssl', false); + $this->passive = AKFactory::get('kickstart.ftp.passive', true); + $this->host = AKFactory::get('kickstart.ftp.host', ''); + $this->port = AKFactory::get('kickstart.ftp.port', 21); + if (trim($this->port) == '') + { + $this->port = 21; + } + $this->user = AKFactory::get('kickstart.ftp.user', ''); + $this->pass = AKFactory::get('kickstart.ftp.pass', ''); + $this->dir = AKFactory::get('kickstart.ftp.dir', ''); + $this->tempDir = AKFactory::get('kickstart.ftp.tempdir', ''); + + $connected = $this->connect(); + + if ($connected) + { + if (!empty($this->tempDir)) + { + $tempDir = rtrim($this->tempDir, '/\\') . '/'; + $writable = $this->isDirWritable($tempDir); + } + else + { + $tempDir = ''; + $writable = false; + } + + if (!$writable) + { + // Default temporary directory is the current root + $tempDir = KSROOTDIR; + if (empty($tempDir)) + { + // Oh, we have no directory reported! + $tempDir = '.'; + } + $absoluteDirToHere = $tempDir; + $tempDir = rtrim(str_replace('\\', '/', $tempDir), '/'); + if (!empty($tempDir)) + { + $tempDir .= '/'; + } + $this->tempDir = $tempDir; + // Is this directory writable? + $writable = $this->isDirWritable($tempDir); + } + + if (!$writable) + { + // Nope. Let's try creating a temporary directory in the site's root. + $tempDir = $absoluteDirToHere . '/kicktemp'; + $trustMeIKnowWhatImDoing = 500 + 10 + 1; // working around overzealous scanners written by bozos + $this->createDirRecursive($tempDir, $trustMeIKnowWhatImDoing); + // Try making it writable... + $this->fixPermissions($tempDir); + $writable = $this->isDirWritable($tempDir); + } + + // Was the new directory writable? + if (!$writable) + { + // Let's see if the user has specified one + $userdir = AKFactory::get('kickstart.ftp.tempdir', ''); + if (!empty($userdir)) + { + // Is it an absolute or a relative directory? + $absolute = false; + $absolute = $absolute || (substr($userdir, 0, 1) == '/'); + $absolute = $absolute || (substr($userdir, 1, 1) == ':'); + $absolute = $absolute || (substr($userdir, 2, 1) == ':'); + if (!$absolute) + { + // Make absolute + $tempDir = $absoluteDirToHere . $userdir; + } + else + { + // it's already absolute + $tempDir = $userdir; + } + // Does the directory exist? + if (is_dir($tempDir)) + { + // Yeah. Is it writable? + $writable = $this->isDirWritable($tempDir); + } + } + } + $this->tempDir = $tempDir; + + if (!$writable) + { + // No writable directory found!!! + $this->setError(AKText::_('FTP_TEMPDIR_NOT_WRITABLE')); + } + else + { + AKFactory::set('kickstart.ftp.tempdir', $tempDir); + $this->tempDir = $tempDir; + } + } + } + + public function connect() + { + // Connect to server, using SSL if so required + if ($this->useSSL) + { + $this->handle = @ftp_ssl_connect($this->host, $this->port); + } + else + { + $this->handle = @ftp_connect($this->host, $this->port); + } + if ($this->handle === false) + { + $this->setError(AKText::_('WRONG_FTP_HOST')); + + return false; + } + + // Login + if (!@ftp_login($this->handle, $this->user, $this->pass)) + { + $this->setError(AKText::_('WRONG_FTP_USER')); + @ftp_close($this->handle); + + return false; + } + + // Change to initial directory + if (!@ftp_chdir($this->handle, $this->dir)) + { + $this->setError(AKText::_('WRONG_FTP_PATH1')); + @ftp_close($this->handle); + + return false; + } + + // Enable passive mode if the user requested it + if ($this->passive) + { + @ftp_pasv($this->handle, true); + } + else + { + @ftp_pasv($this->handle, false); + } + + // Try to download ourselves + $testFilename = defined('KSSELFNAME') ? KSSELFNAME : basename(__FILE__); + $tempHandle = fopen('php://temp', 'r+'); + if (@ftp_fget($this->handle, $tempHandle, $testFilename, FTP_ASCII, 0) === false) + { + $this->setError(AKText::_('WRONG_FTP_PATH2')); + @ftp_close($this->handle); + fclose($tempHandle); + + return false; + } + fclose($tempHandle); + + return true; + } + + private function isDirWritable($dir) + { + $fp = @fopen($dir . '/kickstart.dat', 'wb'); + if ($fp === false) + { + return false; + } + else + { + @fclose($fp); + unlink($dir . '/kickstart.dat'); + + return true; + } + } + + public function createDirRecursive($dirName, $perms) + { + // Strip absolute filesystem path to website's root + $removePath = AKFactory::get('kickstart.setup.destdir', ''); + if (!empty($removePath)) + { + // UNIXize the paths + $removePath = str_replace('\\', '/', $removePath); + $dirName = str_replace('\\', '/', $dirName); + // Make sure they both end in a slash + $removePath = rtrim($removePath, '/\\') . '/'; + $dirName = rtrim($dirName, '/\\') . '/'; + // Process the path removal + $left = substr($dirName, 0, strlen($removePath)); + if ($left == $removePath) + { + $dirName = substr($dirName, strlen($removePath)); + } + } + if (empty($dirName)) + { + $dirName = ''; + } // 'cause the substr() above may return FALSE. + + $check = '/' . trim($this->dir, '/') . '/' . trim($dirName, '/'); + if ($this->is_dir($check)) + { + return true; + } + + $alldirs = explode('/', $dirName); + $previousDir = '/' . trim($this->dir); + foreach ($alldirs as $curdir) + { + $check = $previousDir . '/' . $curdir; + if (!$this->is_dir($check)) + { + // Proactively try to delete a file by the same name + @ftp_delete($this->handle, $check); + + if (@ftp_mkdir($this->handle, $check) === false) + { + // If we couldn't create the directory, attempt to fix the permissions in the PHP level and retry! + $this->fixPermissions($removePath . $check); + if (@ftp_mkdir($this->handle, $check) === false) + { + // Can we fall back to pure PHP mode, sire? + if (!@mkdir($check)) + { + $this->setError(AKText::sprintf('FTP_CANT_CREATE_DIR', $check)); + + return false; + } + else + { + // Since the directory was built by PHP, change its permissions + $trustMeIKnowWhatImDoing = + 500 + 10 + 1; // working around overzealous scanners written by bozos + @chmod($check, $trustMeIKnowWhatImDoing); + + return true; + } + } + } + @ftp_chmod($this->handle, $perms, $check); + } + $previousDir = $check; + } + + return true; + } + + private function is_dir($dir) + { + return @ftp_chdir($this->handle, $dir); + } + + private function fixPermissions($path) + { + // Turn off error reporting + if (!defined('KSDEBUG')) + { + $oldErrorReporting = @error_reporting(E_NONE); + } + + // Get UNIX style paths + $relPath = str_replace('\\', '/', $path); + $basePath = rtrim(str_replace('\\', '/', KSROOTDIR), '/'); + $basePath = rtrim($basePath, '/'); + if (!empty($basePath)) + { + $basePath .= '/'; + } + // Remove the leading relative root + if (substr($relPath, 0, strlen($basePath)) == $basePath) + { + $relPath = substr($relPath, strlen($basePath)); + } + $dirArray = explode('/', $relPath); + $pathBuilt = rtrim($basePath, '/'); + foreach ($dirArray as $dir) + { + if (empty($dir)) + { + continue; + } + $oldPath = $pathBuilt; + $pathBuilt .= '/' . $dir; + if (is_dir($oldPath . $dir)) + { + $trustMeIKnowWhatImDoing = 500 + 10 + 1; // working around overzealous scanners written by bozos + @chmod($oldPath . $dir, $trustMeIKnowWhatImDoing); + } + else + { + $trustMeIKnowWhatImDoing = 500 + 10 + 1; // working around overzealous scanners written by bozos + if (@chmod($oldPath . $dir, $trustMeIKnowWhatImDoing) === false) + { + @unlink($oldPath . $dir); + } + } + } + + // Restore error reporting + if (!defined('KSDEBUG')) + { + @error_reporting($oldErrorReporting); + } + } + + function __wakeup() + { + $this->connect(); + } + + public function process() + { + if (is_null($this->tempFilename)) + { + // If an empty filename is passed, it means that we shouldn't do any post processing, i.e. + // the entity was a directory or symlink + return true; + } + + $remotePath = dirname($this->filename); + $removePath = AKFactory::get('kickstart.setup.destdir', ''); + if (!empty($removePath)) + { + $removePath = ltrim($removePath, "/"); + $remotePath = ltrim($remotePath, "/"); + $left = substr($remotePath, 0, strlen($removePath)); + if ($left == $removePath) + { + $remotePath = substr($remotePath, strlen($removePath)); + } + } + + $absoluteFSPath = dirname($this->filename); + $relativeFTPPath = trim($remotePath, '/'); + $absoluteFTPPath = '/' . trim($this->dir, '/') . '/' . trim($remotePath, '/'); + $onlyFilename = basename($this->filename); + + $remoteName = $absoluteFTPPath . '/' . $onlyFilename; + + $ret = @ftp_chdir($this->handle, $absoluteFTPPath); + if ($ret === false) + { + $ret = $this->createDirRecursive($absoluteFSPath, 0755); + if ($ret === false) + { + $this->setError(AKText::sprintf('FTP_COULDNT_UPLOAD', $this->filename)); + + return false; + } + $ret = @ftp_chdir($this->handle, $absoluteFTPPath); + if ($ret === false) + { + $this->setError(AKText::sprintf('FTP_COULDNT_UPLOAD', $this->filename)); + + return false; + } + } + + $ret = @ftp_put($this->handle, $remoteName, $this->tempFilename, FTP_BINARY); + if ($ret === false) + { + // If we couldn't create the file, attempt to fix the permissions in the PHP level and retry! + $this->fixPermissions($this->filename); + $this->unlink($this->filename); + + $fp = @fopen($this->tempFilename, 'rb'); + if ($fp !== false) + { + $ret = @ftp_fput($this->handle, $remoteName, $fp, FTP_BINARY); + @fclose($fp); + } + else + { + $ret = false; + } + } + @unlink($this->tempFilename); + + if ($ret === false) + { + $this->setError(AKText::sprintf('FTP_COULDNT_UPLOAD', $this->filename)); + + return false; + } + $restorePerms = AKFactory::get('kickstart.setup.restoreperms', false); + if ($restorePerms) + { + @ftp_chmod($this->_handle, $this->perms, $remoteName); + } + else + { + @ftp_chmod($this->_handle, 0644, $remoteName); + } + + return true; + } + + /* + * Tries to fix directory/file permissions in the PHP level, so that + * the FTP operation doesn't fail. + * @param $path string The full path to a directory or file + */ + + public function unlink($file) + { + $removePath = AKFactory::get('kickstart.setup.destdir', ''); + if (!empty($removePath)) + { + $left = substr($file, 0, strlen($removePath)); + if ($left == $removePath) + { + $file = substr($file, strlen($removePath)); + } + } + + $check = '/' . trim($this->dir, '/') . '/' . trim($file, '/'); + + return @ftp_delete($this->handle, $check); + } + + public function processFilename($filename, $perms = 0755) + { + // Catch some error conditions... + if ($this->getError()) + { + return false; + } + + // If a null filename is passed, it means that we shouldn't do any post processing, i.e. + // the entity was a directory or symlink + if (is_null($filename)) + { + $this->filename = null; + $this->tempFilename = null; + + return null; + } + + // Strip absolute filesystem path to website's root + $removePath = AKFactory::get('kickstart.setup.destdir', ''); + if (!empty($removePath)) + { + $left = substr($filename, 0, strlen($removePath)); + if ($left == $removePath) + { + $filename = substr($filename, strlen($removePath)); + } + } + + // Trim slash on the left + $filename = ltrim($filename, '/'); + + $this->filename = $filename; + $this->tempFilename = tempnam($this->tempDir, 'kickstart-'); + $this->perms = $perms; + + if (empty($this->tempFilename)) + { + // Oops! Let's try something different + $this->tempFilename = $this->tempDir . '/kickstart-' . time() . '.dat'; + } + + return $this->tempFilename; + } + + public function close() + { + @ftp_close($this->handle); + } + + public function chmod($file, $perms) + { + return @ftp_chmod($this->handle, $perms, $file); + } + + public function rmdir($directory) + { + $removePath = AKFactory::get('kickstart.setup.destdir', ''); + if (!empty($removePath)) + { + $left = substr($directory, 0, strlen($removePath)); + if ($left == $removePath) + { + $directory = substr($directory, strlen($removePath)); + } + } + + $check = '/' . trim($this->dir, '/') . '/' . trim($directory, '/'); + + return @ftp_rmdir($this->handle, $check); + } + + public function rename($from, $to) + { + $originalFrom = $from; + $originalTo = $to; + + $removePath = AKFactory::get('kickstart.setup.destdir', ''); + if (!empty($removePath)) + { + $left = substr($from, 0, strlen($removePath)); + if ($left == $removePath) + { + $from = substr($from, strlen($removePath)); + } + } + $from = '/' . trim($this->dir, '/') . '/' . trim($from, '/'); + + if (!empty($removePath)) + { + $left = substr($to, 0, strlen($removePath)); + if ($left == $removePath) + { + $to = substr($to, strlen($removePath)); + } + } + $to = '/' . trim($this->dir, '/') . '/' . trim($to, '/'); + + $result = @ftp_rename($this->handle, $from, $to); + if ($result !== true) + { + return @rename($from, $to); + } + else + { + return true; + } + } + +} + + +/** + * Akeeba Restore + * A JSON-powered JPA, JPS and ZIP archive extraction library + * + * @copyright 2008-2017 Nicholas K. Dionysopoulos / Akeeba Ltd. + * @license GNU GPL v2 or - at your option - any later version + * @package akeebabackup + * @subpackage kickstart + */ + +/** + * FTP file writer + */ +class AKPostprocSFTP extends AKAbstractPostproc +{ + /** @var bool Should I use FTP over implicit SSL? */ + public $useSSL = false; + /** @var bool use Passive mode? */ + public $passive = true; + /** @var string FTP host name */ + public $host = ''; + /** @var int FTP port */ + public $port = 21; + /** @var string FTP user name */ + public $user = ''; + /** @var string FTP password */ + public $pass = ''; + /** @var string FTP initial directory */ + public $dir = ''; + + /** @var resource SFTP resource handle */ + private $handle = null; + + /** @var resource SSH2 connection resource handle */ + private $_connection = null; + + /** @var string Current remote directory, including the remote directory string */ + private $_currentdir; + + /** @var string The temporary directory where the data will be stored */ + private $tempDir = ''; + + public function __construct() + { + parent::__construct(); + + $this->host = AKFactory::get('kickstart.ftp.host', ''); + $this->port = AKFactory::get('kickstart.ftp.port', 22); + + if (trim($this->port) == '') + { + $this->port = 22; + } + + $this->user = AKFactory::get('kickstart.ftp.user', ''); + $this->pass = AKFactory::get('kickstart.ftp.pass', ''); + $this->dir = AKFactory::get('kickstart.ftp.dir', ''); + $this->tempDir = AKFactory::get('kickstart.ftp.tempdir', ''); + + $connected = $this->connect(); + + if ($connected) + { + if (!empty($this->tempDir)) + { + $tempDir = rtrim($this->tempDir, '/\\') . '/'; + $writable = $this->isDirWritable($tempDir); + } + else + { + $tempDir = ''; + $writable = false; + } + + if (!$writable) + { + // Default temporary directory is the current root + $tempDir = KSROOTDIR; + if (empty($tempDir)) + { + // Oh, we have no directory reported! + $tempDir = '.'; + } + $absoluteDirToHere = $tempDir; + $tempDir = rtrim(str_replace('\\', '/', $tempDir), '/'); + if (!empty($tempDir)) + { + $tempDir .= '/'; + } + $this->tempDir = $tempDir; + // Is this directory writable? + $writable = $this->isDirWritable($tempDir); + } + + if (!$writable) + { + // Nope. Let's try creating a temporary directory in the site's root. + $tempDir = $absoluteDirToHere . '/kicktemp'; + $trustMeIKnowWhatImDoing = 500 + 10 + 1; // working around overzealous scanners written by bozos + $this->createDirRecursive($tempDir, $trustMeIKnowWhatImDoing); + // Try making it writable... + $this->fixPermissions($tempDir); + $writable = $this->isDirWritable($tempDir); + } + + // Was the new directory writable? + if (!$writable) + { + // Let's see if the user has specified one + $userdir = AKFactory::get('kickstart.ftp.tempdir', ''); + if (!empty($userdir)) + { + // Is it an absolute or a relative directory? + $absolute = false; + $absolute = $absolute || (substr($userdir, 0, 1) == '/'); + $absolute = $absolute || (substr($userdir, 1, 1) == ':'); + $absolute = $absolute || (substr($userdir, 2, 1) == ':'); + if (!$absolute) + { + // Make absolute + $tempDir = $absoluteDirToHere . $userdir; + } + else + { + // it's already absolute + $tempDir = $userdir; + } + // Does the directory exist? + if (is_dir($tempDir)) + { + // Yeah. Is it writable? + $writable = $this->isDirWritable($tempDir); + } + } + } + $this->tempDir = $tempDir; + + if (!$writable) + { + // No writable directory found!!! + $this->setError(AKText::_('SFTP_TEMPDIR_NOT_WRITABLE')); + } + else + { + AKFactory::set('kickstart.ftp.tempdir', $tempDir); + $this->tempDir = $tempDir; + } + } + } + + public function connect() + { + $this->_connection = false; + + if (!function_exists('ssh2_connect')) + { + $this->setError(AKText::_('SFTP_NO_SSH2')); + + return false; + } + + $this->_connection = @ssh2_connect($this->host, $this->port); + + if (!@ssh2_auth_password($this->_connection, $this->user, $this->pass)) + { + $this->setError(AKText::_('SFTP_WRONG_USER')); + + $this->_connection = false; + + return false; + } + + $this->handle = @ssh2_sftp($this->_connection); + + // I must have an absolute directory + if (!$this->dir) + { + $this->setError(AKText::_('SFTP_WRONG_STARTING_DIR')); + + return false; + } + + // Change to initial directory + if (!$this->sftp_chdir('/')) + { + $this->setError(AKText::_('SFTP_WRONG_STARTING_DIR')); + + unset($this->_connection); + unset($this->handle); + + return false; + } + + // Try to download ourselves + $testFilename = defined('KSSELFNAME') ? KSSELFNAME : basename(__FILE__); + $basePath = '/' . trim($this->dir, '/'); + + if (@fopen("ssh2.sftp://{$this->handle}$basePath/$testFilename", 'r+') === false) + { + $this->setError(AKText::_('SFTP_WRONG_STARTING_DIR')); + + unset($this->_connection); + unset($this->handle); + + return false; + } + + return true; + } + + /** + * Changes to the requested directory in the remote server. You give only the + * path relative to the initial directory and it does all the rest by itself, + * including doing nothing if the remote directory is the one we want. + * + * @param string $dir The (realtive) remote directory + * + * @return bool True if successful, false otherwise. + */ + private function sftp_chdir($dir) + { + // Strip absolute filesystem path to website's root + $removePath = AKFactory::get('kickstart.setup.destdir', ''); + if (!empty($removePath)) + { + // UNIXize the paths + $removePath = str_replace('\\', '/', $removePath); + $dir = str_replace('\\', '/', $dir); + + // Make sure they both end in a slash + $removePath = rtrim($removePath, '/\\') . '/'; + $dir = rtrim($dir, '/\\') . '/'; + + // Process the path removal + $left = substr($dir, 0, strlen($removePath)); + + if ($left == $removePath) + { + $dir = substr($dir, strlen($removePath)); + } + } + + if (empty($dir)) + { + // Because the substr() above may return FALSE. + $dir = ''; + } + + // Calculate "real" (absolute) SFTP path + $realdir = substr($this->dir, -1) == '/' ? substr($this->dir, 0, strlen($this->dir) - 1) : $this->dir; + $realdir .= '/' . $dir; + $realdir = substr($realdir, 0, 1) == '/' ? $realdir : '/' . $realdir; + + if ($this->_currentdir == $realdir) + { + // Already there, do nothing + return true; + } + + $result = @ssh2_sftp_stat($this->handle, $realdir); + + if ($result === false) + { + return false; + } + else + { + // Update the private "current remote directory" variable + $this->_currentdir = $realdir; + + return true; + } + } + + private function isDirWritable($dir) + { + if (@fopen("ssh2.sftp://{$this->handle}$dir/kickstart.dat", 'wb') === false) + { + return false; + } + else + { + @ssh2_sftp_unlink($this->handle, $dir . '/kickstart.dat'); + + return true; + } + } + + public function createDirRecursive($dirName, $perms) + { + // Strip absolute filesystem path to website's root + $removePath = AKFactory::get('kickstart.setup.destdir', ''); + if (!empty($removePath)) + { + // UNIXize the paths + $removePath = str_replace('\\', '/', $removePath); + $dirName = str_replace('\\', '/', $dirName); + // Make sure they both end in a slash + $removePath = rtrim($removePath, '/\\') . '/'; + $dirName = rtrim($dirName, '/\\') . '/'; + // Process the path removal + $left = substr($dirName, 0, strlen($removePath)); + if ($left == $removePath) + { + $dirName = substr($dirName, strlen($removePath)); + } + } + if (empty($dirName)) + { + $dirName = ''; + } // 'cause the substr() above may return FALSE. + + $check = '/' . trim($this->dir, '/ ') . '/' . trim($dirName, '/'); + + if ($this->is_dir($check)) + { + return true; + } + + $alldirs = explode('/', $dirName); + $previousDir = '/' . trim($this->dir, '/ '); + + foreach ($alldirs as $curdir) + { + if (!$curdir) + { + continue; + } + + $check = $previousDir . '/' . $curdir; + + if (!$this->is_dir($check)) + { + // Proactively try to delete a file by the same name + @ssh2_sftp_unlink($this->handle, $check); + + if (@ssh2_sftp_mkdir($this->handle, $check) === false) + { + // If we couldn't create the directory, attempt to fix the permissions in the PHP level and retry! + $this->fixPermissions($check); + + if (@ssh2_sftp_mkdir($this->handle, $check) === false) + { + // Can we fall back to pure PHP mode, sire? + if (!@mkdir($check)) + { + $this->setError(AKText::sprintf('FTP_CANT_CREATE_DIR', $check)); + + return false; + } + else + { + // Since the directory was built by PHP, change its permissions + $trustMeIKnowWhatImDoing = + 500 + 10 + 1; // working around overzealous scanners written by bozos + @chmod($check, $trustMeIKnowWhatImDoing); + + return true; + } + } + } + + @ssh2_sftp_chmod($this->handle, $check, $perms); + } + + $previousDir = $check; + } + + return true; + } + + private function is_dir($dir) + { + return $this->sftp_chdir($dir); + } + + private function fixPermissions($path) + { + // Turn off error reporting + if (!defined('KSDEBUG')) + { + $oldErrorReporting = @error_reporting(E_NONE); + } + + // Get UNIX style paths + $relPath = str_replace('\\', '/', $path); + $basePath = rtrim(str_replace('\\', '/', KSROOTDIR), '/'); + $basePath = rtrim($basePath, '/'); + + if (!empty($basePath)) + { + $basePath .= '/'; + } + + // Remove the leading relative root + if (substr($relPath, 0, strlen($basePath)) == $basePath) + { + $relPath = substr($relPath, strlen($basePath)); + } + + $dirArray = explode('/', $relPath); + $pathBuilt = rtrim($basePath, '/'); + + foreach ($dirArray as $dir) + { + if (empty($dir)) + { + continue; + } + + $oldPath = $pathBuilt; + $pathBuilt .= '/' . $dir; + + if (is_dir($oldPath . '/' . $dir)) + { + $trustMeIKnowWhatImDoing = 500 + 10 + 1; // working around overzealous scanners written by bozos + @chmod($oldPath . '/' . $dir, $trustMeIKnowWhatImDoing); + } + else + { + $trustMeIKnowWhatImDoing = 500 + 10 + 1; // working around overzealous scanners written by bozos + if (@chmod($oldPath . '/' . $dir, $trustMeIKnowWhatImDoing) === false) + { + @unlink($oldPath . $dir); + } + } + } + + // Restore error reporting + if (!defined('KSDEBUG')) + { + @error_reporting($oldErrorReporting); + } + } + + function __wakeup() + { + $this->connect(); + } + + /* + * Tries to fix directory/file permissions in the PHP level, so that + * the FTP operation doesn't fail. + * @param $path string The full path to a directory or file + */ + + public function process() + { + if (is_null($this->tempFilename)) + { + // If an empty filename is passed, it means that we shouldn't do any post processing, i.e. + // the entity was a directory or symlink + return true; + } + + $remotePath = dirname($this->filename); + $absoluteFSPath = dirname($this->filename); + $absoluteFTPPath = '/' . trim($this->dir, '/') . '/' . trim($remotePath, '/'); + $onlyFilename = basename($this->filename); + + $remoteName = $absoluteFTPPath . '/' . $onlyFilename; + + $ret = $this->sftp_chdir($absoluteFTPPath); + + if ($ret === false) + { + $ret = $this->createDirRecursive($absoluteFSPath, 0755); + + if ($ret === false) + { + $this->setError(AKText::sprintf('SFTP_COULDNT_UPLOAD', $this->filename)); + + return false; + } + + $ret = $this->sftp_chdir($absoluteFTPPath); + + if ($ret === false) + { + $this->setError(AKText::sprintf('SFTP_COULDNT_UPLOAD', $this->filename)); + + return false; + } + } + + // Create the file + $ret = $this->write($this->tempFilename, $remoteName); + + // If I got a -1 it means that I wasn't able to open the file, so I have to stop here + if ($ret === -1) + { + $this->setError(AKText::sprintf('SFTP_COULDNT_UPLOAD', $this->filename)); + + return false; + } + + if ($ret === false) + { + // If we couldn't create the file, attempt to fix the permissions in the PHP level and retry! + $this->fixPermissions($this->filename); + $this->unlink($this->filename); + + $ret = $this->write($this->tempFilename, $remoteName); + } + + @unlink($this->tempFilename); + + if ($ret === false) + { + $this->setError(AKText::sprintf('SFTP_COULDNT_UPLOAD', $this->filename)); + + return false; + } + $restorePerms = AKFactory::get('kickstart.setup.restoreperms', false); + + if ($restorePerms) + { + $this->chmod($remoteName, $this->perms); + } + else + { + $this->chmod($remoteName, 0644); + } + + return true; + } + + private function write($local, $remote) + { + $fp = @fopen("ssh2.sftp://{$this->handle}$remote", 'w'); + $localfp = @fopen($local, 'rb'); + + if ($fp === false) + { + return -1; + } + + if ($localfp === false) + { + @fclose($fp); + + return -1; + } + + $res = true; + + while (!feof($localfp) && ($res !== false)) + { + $buffer = @fread($localfp, 65567); + $res = @fwrite($fp, $buffer); + } + + @fclose($fp); + @fclose($localfp); + + return $res; + } + + public function unlink($file) + { + $check = '/' . trim($this->dir, '/') . '/' . trim($file, '/'); + + return @ssh2_sftp_unlink($this->handle, $check); + } + + public function chmod($file, $perms) + { + return @ssh2_sftp_chmod($this->handle, $file, $perms); + } + + public function processFilename($filename, $perms = 0755) + { + // Catch some error conditions... + if ($this->getError()) + { + return false; + } + + // If a null filename is passed, it means that we shouldn't do any post processing, i.e. + // the entity was a directory or symlink + if (is_null($filename)) + { + $this->filename = null; + $this->tempFilename = null; + + return null; + } + + // Strip absolute filesystem path to website's root + $removePath = AKFactory::get('kickstart.setup.destdir', ''); + if (!empty($removePath)) + { + $left = substr($filename, 0, strlen($removePath)); + if ($left == $removePath) + { + $filename = substr($filename, strlen($removePath)); + } + } + + // Trim slash on the left + $filename = ltrim($filename, '/'); + + $this->filename = $filename; + $this->tempFilename = tempnam($this->tempDir, 'kickstart-'); + $this->perms = $perms; + + if (empty($this->tempFilename)) + { + // Oops! Let's try something different + $this->tempFilename = $this->tempDir . '/kickstart-' . time() . '.dat'; + } + + return $this->tempFilename; + } + + public function close() + { + unset($this->_connection); + unset($this->handle); + } + + public function rmdir($directory) + { + $check = '/' . trim($this->dir, '/') . '/' . trim($directory, '/'); + + return @ssh2_sftp_rmdir($this->handle, $check); + } + + public function rename($from, $to) + { + $from = '/' . trim($this->dir, '/') . '/' . trim($from, '/'); + $to = '/' . trim($this->dir, '/') . '/' . trim($to, '/'); + + $result = @ssh2_sftp_rename($this->handle, $from, $to); + + if ($result !== true) + { + return @rename($from, $to); + } + else + { + return true; + } + } + +} + + +/** + * Akeeba Restore + * A JSON-powered JPA, JPS and ZIP archive extraction library + * + * @copyright 2008-2017 Nicholas K. Dionysopoulos / Akeeba Ltd. + * @license GNU GPL v2 or - at your option - any later version + * @package akeebabackup + * @subpackage kickstart + */ + +/** + * Hybrid direct / FTP mode file writer + */ +class AKPostprocHybrid extends AKAbstractPostproc +{ + + /** @var bool Should I use the FTP layer? */ + public $useFTP = false; + + /** @var bool Should I use FTP over implicit SSL? */ + public $useSSL = false; + + /** @var bool use Passive mode? */ + public $passive = true; + + /** @var string FTP host name */ + public $host = ''; + + /** @var int FTP port */ + public $port = 21; + + /** @var string FTP user name */ + public $user = ''; + + /** @var string FTP password */ + public $pass = ''; + + /** @var string FTP initial directory */ + public $dir = ''; + + /** @var resource The FTP handle */ + private $handle = null; + + /** @var string The temporary directory where the data will be stored */ + private $tempDir = ''; + + /** @var null The FTP connection handle */ + private $_handle = null; + + /** + * Public constructor. Tries to connect to the FTP server. + */ + public function __construct() + { + parent::__construct(); + + $this->useFTP = true; + $this->useSSL = AKFactory::get('kickstart.ftp.ssl', false); + $this->passive = AKFactory::get('kickstart.ftp.passive', true); + $this->host = AKFactory::get('kickstart.ftp.host', ''); + $this->port = AKFactory::get('kickstart.ftp.port', 21); + $this->user = AKFactory::get('kickstart.ftp.user', ''); + $this->pass = AKFactory::get('kickstart.ftp.pass', ''); + $this->dir = AKFactory::get('kickstart.ftp.dir', ''); + $this->tempDir = AKFactory::get('kickstart.ftp.tempdir', ''); + + if (trim($this->port) == '') + { + $this->port = 21; + } + + // If FTP is not configured, skip it altogether + if (empty($this->host) || empty($this->user) || empty($this->pass)) + { + $this->useFTP = false; + } + + // Try to connect to the FTP server + $connected = $this->connect(); + + // If the connection fails, skip FTP altogether + if (!$connected) + { + $this->useFTP = false; + } + + if ($connected) + { + if (!empty($this->tempDir)) + { + $tempDir = rtrim($this->tempDir, '/\\') . '/'; + $writable = $this->isDirWritable($tempDir); + } + else + { + $tempDir = ''; + $writable = false; + } + + if (!$writable) + { + // Default temporary directory is the current root + $tempDir = KSROOTDIR; + if (empty($tempDir)) + { + // Oh, we have no directory reported! + $tempDir = '.'; + } + $absoluteDirToHere = $tempDir; + $tempDir = rtrim(str_replace('\\', '/', $tempDir), '/'); + if (!empty($tempDir)) + { + $tempDir .= '/'; + } + $this->tempDir = $tempDir; + // Is this directory writable? + $writable = $this->isDirWritable($tempDir); + } + + if (!$writable) + { + // Nope. Let's try creating a temporary directory in the site's root. + $tempDir = $absoluteDirToHere . '/kicktemp'; + $trustMeIKnowWhatImDoing = 500 + 10 + 1; // working around overzealous scanners written by bozos + $this->createDirRecursive($tempDir, $trustMeIKnowWhatImDoing); + // Try making it writable... + $this->fixPermissions($tempDir); + $writable = $this->isDirWritable($tempDir); + } + + // Was the new directory writable? + if (!$writable) + { + // Let's see if the user has specified one + $userdir = AKFactory::get('kickstart.ftp.tempdir', ''); + if (!empty($userdir)) + { + // Is it an absolute or a relative directory? + $absolute = false; + $absolute = $absolute || (substr($userdir, 0, 1) == '/'); + $absolute = $absolute || (substr($userdir, 1, 1) == ':'); + $absolute = $absolute || (substr($userdir, 2, 1) == ':'); + if (!$absolute) + { + // Make absolute + $tempDir = $absoluteDirToHere . $userdir; + } + else + { + // it's already absolute + $tempDir = $userdir; + } + // Does the directory exist? + if (is_dir($tempDir)) + { + // Yeah. Is it writable? + $writable = $this->isDirWritable($tempDir); + } + } + } + $this->tempDir = $tempDir; + + if (!$writable) + { + // No writable directory found!!! + $this->setError(AKText::_('FTP_TEMPDIR_NOT_WRITABLE')); + } + else + { + AKFactory::set('kickstart.ftp.tempdir', $tempDir); + $this->tempDir = $tempDir; + } + } + } + + /** + * Tries to connect to the FTP server + * + * @return bool + */ + public function connect() + { + if (!$this->useFTP) + { + return false; + } + + // Connect to server, using SSL if so required + if ($this->useSSL) + { + $this->handle = @ftp_ssl_connect($this->host, $this->port); + } + else + { + $this->handle = @ftp_connect($this->host, $this->port); + } + if ($this->handle === false) + { + $this->setError(AKText::_('WRONG_FTP_HOST')); + + return false; + } + + // Login + if (!@ftp_login($this->handle, $this->user, $this->pass)) + { + $this->setError(AKText::_('WRONG_FTP_USER')); + @ftp_close($this->handle); + + return false; + } + + // Change to initial directory + if (!@ftp_chdir($this->handle, $this->dir)) + { + $this->setError(AKText::_('WRONG_FTP_PATH1')); + @ftp_close($this->handle); + + return false; + } + + // Enable passive mode if the user requested it + if ($this->passive) + { + @ftp_pasv($this->handle, true); + } + else + { + @ftp_pasv($this->handle, false); + } + + // Try to download ourselves + $testFilename = defined('KSSELFNAME') ? KSSELFNAME : basename(__FILE__); + $tempHandle = fopen('php://temp', 'r+'); + + if (@ftp_fget($this->handle, $tempHandle, $testFilename, FTP_ASCII, 0) === false) + { + $this->setError(AKText::_('WRONG_FTP_PATH2')); + @ftp_close($this->handle); + fclose($tempHandle); + + return false; + } + + fclose($tempHandle); + + return true; + } + + /** + * Is the directory writeable? + * + * @param string $dir The directory ti check + * + * @return bool + */ + private function isDirWritable($dir) + { + $fp = @fopen($dir . '/kickstart.dat', 'wb'); + + if ($fp === false) + { + return false; + } + + @fclose($fp); + unlink($dir . '/kickstart.dat'); + + return true; + } + + /** + * Create a directory, recursively + * + * @param string $dirName The directory to create + * @param int $perms The permissions to give to the directory + * + * @return bool + */ + public function createDirRecursive($dirName, $perms) + { + // Strip absolute filesystem path to website's root + $removePath = AKFactory::get('kickstart.setup.destdir', ''); + + if (!empty($removePath)) + { + // UNIXize the paths + $removePath = str_replace('\\', '/', $removePath); + $dirName = str_replace('\\', '/', $dirName); + // Make sure they both end in a slash + $removePath = rtrim($removePath, '/\\') . '/'; + $dirName = rtrim($dirName, '/\\') . '/'; + // Process the path removal + $left = substr($dirName, 0, strlen($removePath)); + + if ($left == $removePath) + { + $dirName = substr($dirName, strlen($removePath)); + } + } + + // 'cause the substr() above may return FALSE. + if (empty($dirName)) + { + $dirName = ''; + } + + $check = '/' . trim($this->dir, '/') . '/' . trim($dirName, '/'); + $checkFS = $removePath . trim($dirName, '/'); + + if ($this->is_dir($check)) + { + return true; + } + + $alldirs = explode('/', $dirName); + $previousDir = '/' . trim($this->dir); + $previousDirFS = rtrim($removePath, '/\\'); + + foreach ($alldirs as $curdir) + { + $check = $previousDir . '/' . $curdir; + $checkFS = $previousDirFS . '/' . $curdir; + + if (!is_dir($checkFS) && !$this->is_dir($check)) + { + // Proactively try to delete a file by the same name + if (!@unlink($checkFS) && $this->useFTP) + { + @ftp_delete($this->handle, $check); + } + + $createdDir = @mkdir($checkFS, 0755); + + if (!$createdDir && $this->useFTP) + { + $createdDir = @ftp_mkdir($this->handle, $check); + } + + if ($createdDir === false) + { + // If we couldn't create the directory, attempt to fix the permissions in the PHP level and retry! + $this->fixPermissions($checkFS); + + $createdDir = @mkdir($checkFS, 0755); + if (!$createdDir && $this->useFTP) + { + $createdDir = @ftp_mkdir($this->handle, $check); + } + + if ($createdDir === false) + { + $this->setError(AKText::sprintf('FTP_CANT_CREATE_DIR', $check)); + + return false; + } + } + + if (!@chmod($checkFS, $perms) && $this->useFTP) + { + @ftp_chmod($this->handle, $perms, $check); + } + } + + $previousDir = $check; + $previousDirFS = $checkFS; + } + + return true; + } + + private function is_dir($dir) + { + if ($this->useFTP) + { + return @ftp_chdir($this->handle, $dir); + } + + return false; + } + + /** + * Tries to fix directory/file permissions in the PHP level, so that + * the FTP operation doesn't fail. + * + * @param $path string The full path to a directory or file + */ + private function fixPermissions($path) + { + // Turn off error reporting + if (!defined('KSDEBUG')) + { + $oldErrorReporting = error_reporting(0); + } + + // Get UNIX style paths + $relPath = str_replace('\\', '/', $path); + $basePath = rtrim(str_replace('\\', '/', KSROOTDIR), '/'); + $basePath = rtrim($basePath, '/'); + + if (!empty($basePath)) + { + $basePath .= '/'; + } + + // Remove the leading relative root + if (substr($relPath, 0, strlen($basePath)) == $basePath) + { + $relPath = substr($relPath, strlen($basePath)); + } + + $dirArray = explode('/', $relPath); + $pathBuilt = rtrim($basePath, '/'); + + foreach ($dirArray as $dir) + { + if (empty($dir)) + { + continue; + } + + $oldPath = $pathBuilt; + $pathBuilt .= '/' . $dir; + + if (is_dir($oldPath . $dir)) + { + $trustMeIKnowWhatImDoing = 500 + 10 + 1; // working around overzealous scanners written by bozos + @chmod($oldPath . $dir, $trustMeIKnowWhatImDoing); + } + else + { + $trustMeIKnowWhatImDoing = 500 + 10 + 1; // working around overzealous scanners written by bozos + if (@chmod($oldPath . $dir, $trustMeIKnowWhatImDoing) === false) + { + @unlink($oldPath . $dir); + } + } + } + + // Restore error reporting + if (!defined('KSDEBUG')) + { + @error_reporting($oldErrorReporting); + } + } + + /** + * Called after unserialisation, tries to reconnect to FTP + */ + function __wakeup() + { + if ($this->useFTP) + { + $this->connect(); + } + } + + function __destruct() + { + if (!$this->useFTP) + { + @ftp_close($this->handle); + } + } + + /** + * Post-process an extracted file, using FTP or direct file writes to move it + * + * @return bool + */ + public function process() + { + if (is_null($this->tempFilename)) + { + // If an empty filename is passed, it means that we shouldn't do any post processing, i.e. + // the entity was a directory or symlink + return true; + } + + $remotePath = dirname($this->filename); + $removePath = AKFactory::get('kickstart.setup.destdir', ''); + $root = rtrim($removePath, '/\\'); + + if (!empty($removePath)) + { + $removePath = ltrim($removePath, "/"); + $remotePath = ltrim($remotePath, "/"); + $left = substr($remotePath, 0, strlen($removePath)); + + if ($left == $removePath) + { + $remotePath = substr($remotePath, strlen($removePath)); + } + } + + $absoluteFSPath = dirname($this->filename); + $relativeFTPPath = trim($remotePath, '/'); + $absoluteFTPPath = '/' . trim($this->dir, '/') . '/' . trim($remotePath, '/'); + $onlyFilename = basename($this->filename); + + $remoteName = $absoluteFTPPath . '/' . $onlyFilename; + + // Does the directory exist? + if (!is_dir($root . '/' . $absoluteFSPath)) + { + $ret = $this->createDirRecursive($absoluteFSPath, 0755); + + if (($ret === false) && ($this->useFTP)) + { + $ret = @ftp_chdir($this->handle, $absoluteFTPPath); + } + + if ($ret === false) + { + $this->setError(AKText::sprintf('FTP_COULDNT_UPLOAD', $this->filename)); + + return false; + } + } + + if ($this->useFTP) + { + $ret = @ftp_chdir($this->handle, $absoluteFTPPath); + } + + // Try copying directly + $ret = @copy($this->tempFilename, $root . '/' . $this->filename); + + if ($ret === false) + { + $this->fixPermissions($this->filename); + $this->unlink($this->filename); + + $ret = @copy($this->tempFilename, $root . '/' . $this->filename); + } + + if ($this->useFTP && ($ret === false)) + { + $ret = @ftp_put($this->handle, $remoteName, $this->tempFilename, FTP_BINARY); + + if ($ret === false) + { + // If we couldn't create the file, attempt to fix the permissions in the PHP level and retry! + $this->fixPermissions($this->filename); + $this->unlink($this->filename); + + $fp = @fopen($this->tempFilename, 'rb'); + if ($fp !== false) + { + $ret = @ftp_fput($this->handle, $remoteName, $fp, FTP_BINARY); + @fclose($fp); + } + else + { + $ret = false; + } + } + } + + @unlink($this->tempFilename); + + if ($ret === false) + { + $this->setError(AKText::sprintf('FTP_COULDNT_UPLOAD', $this->filename)); + + return false; + } + + $restorePerms = AKFactory::get('kickstart.setup.restoreperms', false); + $perms = $restorePerms ? $this->perms : 0644; + + $ret = @chmod($root . '/' . $this->filename, $perms); + + if ($this->useFTP && ($ret === false)) + { + @ftp_chmod($this->_handle, $perms, $remoteName); + } + + return true; + } + + public function unlink($file) + { + $ret = @unlink($file); + + if (!$ret && $this->useFTP) + { + $removePath = AKFactory::get('kickstart.setup.destdir', ''); + if (!empty($removePath)) + { + $left = substr($file, 0, strlen($removePath)); + if ($left == $removePath) + { + $file = substr($file, strlen($removePath)); + } + } + + $check = '/' . trim($this->dir, '/') . '/' . trim($file, '/'); + + $ret = @ftp_delete($this->handle, $check); + } + + return $ret; + } + + /** + * Create a temporary filename + * + * @param string $filename The original filename + * @param int $perms The file permissions + * + * @return string + */ + public function processFilename($filename, $perms = 0755) + { + // Catch some error conditions... + if ($this->getError()) + { + return false; + } + + // If a null filename is passed, it means that we shouldn't do any post processing, i.e. + // the entity was a directory or symlink + if (is_null($filename)) + { + $this->filename = null; + $this->tempFilename = null; + + return null; + } + + // Strip absolute filesystem path to website's root + $removePath = AKFactory::get('kickstart.setup.destdir', ''); + + if (!empty($removePath)) + { + $left = substr($filename, 0, strlen($removePath)); + + if ($left == $removePath) + { + $filename = substr($filename, strlen($removePath)); + } + } + + // Trim slash on the left + $filename = ltrim($filename, '/'); + + $this->filename = $filename; + $this->tempFilename = tempnam($this->tempDir, 'kickstart-'); + $this->perms = $perms; + + if (empty($this->tempFilename)) + { + // Oops! Let's try something different + $this->tempFilename = $this->tempDir . '/kickstart-' . time() . '.dat'; + } + + return $this->tempFilename; + } + + /** + * Closes the FTP connection + */ + public function close() + { + if (!$this->useFTP) + { + @ftp_close($this->handle); + } + } + + public function chmod($file, $perms) + { + if (AKFactory::get('kickstart.setup.dryrun', '0')) + { + return true; + } + + $ret = @chmod($file, $perms); + + if (!$ret && $this->useFTP) + { + // Strip absolute filesystem path to website's root + $removePath = AKFactory::get('kickstart.setup.destdir', ''); + + if (!empty($removePath)) + { + $left = substr($file, 0, strlen($removePath)); + + if ($left == $removePath) + { + $file = substr($file, strlen($removePath)); + } + } + + // Trim slash on the left + $file = ltrim($file, '/'); + + $ret = @ftp_chmod($this->handle, $perms, $file); + } + + return $ret; + } + + public function rmdir($directory) + { + $ret = @rmdir($directory); + + if (!$ret && $this->useFTP) + { + $removePath = AKFactory::get('kickstart.setup.destdir', ''); + if (!empty($removePath)) + { + $left = substr($directory, 0, strlen($removePath)); + if ($left == $removePath) + { + $directory = substr($directory, strlen($removePath)); + } + } + + $check = '/' . trim($this->dir, '/') . '/' . trim($directory, '/'); + + $ret = @ftp_rmdir($this->handle, $check); + } + + return $ret; + } + + public function rename($from, $to) + { + $ret = @rename($from, $to); + + if (!$ret && $this->useFTP) + { + $originalFrom = $from; + $originalTo = $to; + + $removePath = AKFactory::get('kickstart.setup.destdir', ''); + if (!empty($removePath)) + { + $left = substr($from, 0, strlen($removePath)); + if ($left == $removePath) + { + $from = substr($from, strlen($removePath)); + } + } + $from = '/' . trim($this->dir, '/') . '/' . trim($from, '/'); + + if (!empty($removePath)) + { + $left = substr($to, 0, strlen($removePath)); + if ($left == $removePath) + { + $to = substr($to, strlen($removePath)); + } + } + $to = '/' . trim($this->dir, '/') . '/' . trim($to, '/'); + + $ret = @ftp_rename($this->handle, $from, $to); + } + + return $ret; + } +} + +/** + * Akeeba Restore + * A JSON-powered JPA, JPS and ZIP archive extraction library + * + * @copyright 2008-2017 Nicholas K. Dionysopoulos / Akeeba Ltd. + * @license GNU GPL v2 or - at your option - any later version + * @package akeebabackup + * @subpackage kickstart + */ + +/** + * JPA archive extraction class + */ +class AKUnarchiverJPA extends AKAbstractUnarchiver +{ + protected $archiveHeaderData = array(); + + protected function readArchiveHeader() + { + debugMsg('Preparing to read archive header'); + // Initialize header data array + $this->archiveHeaderData = new stdClass(); + + // Open the first part + debugMsg('Opening the first part'); + $this->nextFile(); + + // Fail for unreadable files + if ($this->fp === false) + { + debugMsg('Could not open the first part'); + + return false; + } + + // Read the signature + $sig = fread($this->fp, 3); + + if ($sig != 'JPA') + { + // Not a JPA file + debugMsg('Invalid archive signature'); + $this->setError(AKText::_('ERR_NOT_A_JPA_FILE')); + + return false; + } + + // Read and parse header length + $header_length_array = unpack('v', fread($this->fp, 2)); + $header_length = $header_length_array[1]; + + // Read and parse the known portion of header data (14 bytes) + $bin_data = fread($this->fp, 14); + $header_data = unpack('Cmajor/Cminor/Vcount/Vuncsize/Vcsize', $bin_data); + + // Load any remaining header data (forward compatibility) + $rest_length = $header_length - 19; + + if ($rest_length > 0) + { + $junk = fread($this->fp, $rest_length); + } + else + { + $junk = ''; + } + + // Temporary array with all the data we read + $temp = array( + 'signature' => $sig, + 'length' => $header_length, + 'major' => $header_data['major'], + 'minor' => $header_data['minor'], + 'filecount' => $header_data['count'], + 'uncompressedsize' => $header_data['uncsize'], + 'compressedsize' => $header_data['csize'], + 'unknowndata' => $junk + ); + + // Array-to-object conversion + foreach ($temp as $key => $value) + { + $this->archiveHeaderData->{$key} = $value; + } + + debugMsg('Header data:'); + debugMsg('Length : ' . $header_length); + debugMsg('Major : ' . $header_data['major']); + debugMsg('Minor : ' . $header_data['minor']); + debugMsg('File count : ' . $header_data['count']); + debugMsg('Uncompressed size : ' . $header_data['uncsize']); + debugMsg('Compressed size : ' . $header_data['csize']); + + $this->currentPartOffset = @ftell($this->fp); + + $this->dataReadLength = 0; + + return true; + } + + /** + * Concrete classes must use this method to read the file header + * + * @return bool True if reading the file was successful, false if an error occurred or we reached end of archive + */ + protected function readFileHeader() + { + // If the current part is over, proceed to the next part please + if ($this->isEOF(true)) + { + debugMsg('Archive part EOF; moving to next file'); + $this->nextFile(); + } + + $this->currentPartOffset = ftell($this->fp); + + debugMsg("Reading file signature; part {$this->currentPartNumber}, offset {$this->currentPartOffset}"); + // Get and decode Entity Description Block + $signature = fread($this->fp, 3); + + $this->fileHeader = new stdClass(); + $this->fileHeader->timestamp = 0; + + // Check signature + if ($signature != 'JPF') + { + if ($this->isEOF(true)) + { + // This file is finished; make sure it's the last one + $this->nextFile(); + + if (!$this->isEOF(false)) + { + debugMsg('Invalid file signature before end of archive encountered'); + $this->setError(AKText::sprintf('INVALID_FILE_HEADER', $this->currentPartNumber, $this->currentPartOffset)); + + return false; + } + + // We're just finished + return false; + } + else + { + $screwed = true; + + if (AKFactory::get('kickstart.setup.ignoreerrors', false)) + { + debugMsg('Invalid file block signature; launching heuristic file block signature scanner'); + $screwed = !$this->heuristicFileHeaderLocator(); + + if (!$screwed) + { + $signature = 'JPF'; + } + else + { + debugMsg('Heuristics failed. Brace yourself for the imminent crash.'); + } + } + + if ($screwed) + { + debugMsg('Invalid file block signature'); + // This is not a file block! The archive is corrupt. + $this->setError(AKText::sprintf('INVALID_FILE_HEADER', $this->currentPartNumber, $this->currentPartOffset)); + + return false; + } + } + } + // This a JPA Entity Block. Process the header. + + $isBannedFile = false; + + // Read length of EDB and of the Entity Path Data + $length_array = unpack('vblocksize/vpathsize', fread($this->fp, 4)); + // Read the path data + if ($length_array['pathsize'] > 0) + { + $file = fread($this->fp, $length_array['pathsize']); + } + else + { + $file = ''; + } + + // Handle file renaming + $isRenamed = false; + if (is_array($this->renameFiles) && (count($this->renameFiles) > 0)) + { + if (array_key_exists($file, $this->renameFiles)) + { + $file = $this->renameFiles[$file]; + $isRenamed = true; + } + } + + // Handle directory renaming + $isDirRenamed = false; + if (is_array($this->renameDirs) && (count($this->renameDirs) > 0)) + { + if (array_key_exists(dirname($file), $this->renameDirs)) + { + $file = rtrim($this->renameDirs[dirname($file)], '/') . '/' . basename($file); + $isRenamed = true; + $isDirRenamed = true; + } + } + + // Read and parse the known data portion + $bin_data = fread($this->fp, 14); + $header_data = unpack('Ctype/Ccompression/Vcompsize/Vuncompsize/Vperms', $bin_data); + // Read any unknown data + $restBytes = $length_array['blocksize'] - (21 + $length_array['pathsize']); + + if ($restBytes > 0) + { + // Start reading the extra fields + while ($restBytes >= 4) + { + $extra_header_data = fread($this->fp, 4); + $extra_header = unpack('vsignature/vlength', $extra_header_data); + $restBytes -= 4; + $extra_header['length'] -= 4; + + switch ($extra_header['signature']) + { + case 256: + // File modified timestamp + if ($extra_header['length'] > 0) + { + $bindata = fread($this->fp, $extra_header['length']); + $restBytes -= $extra_header['length']; + $timestamps = unpack('Vmodified', substr($bindata, 0, 4)); + $filectime = $timestamps['modified']; + $this->fileHeader->timestamp = $filectime; + } + break; + + default: + // Unknown field + if ($extra_header['length'] > 0) + { + $junk = fread($this->fp, $extra_header['length']); + $restBytes -= $extra_header['length']; + } + break; + } + } + + if ($restBytes > 0) + { + $junk = fread($this->fp, $restBytes); + } + } + + $compressionType = $header_data['compression']; + + // Populate the return array + $this->fileHeader->file = $file; + $this->fileHeader->compressed = $header_data['compsize']; + $this->fileHeader->uncompressed = $header_data['uncompsize']; + + switch ($header_data['type']) + { + case 0: + $this->fileHeader->type = 'dir'; + break; + + case 1: + $this->fileHeader->type = 'file'; + break; + + case 2: + $this->fileHeader->type = 'link'; + break; + } + + switch ($compressionType) + { + case 0: + $this->fileHeader->compression = 'none'; + break; + case 1: + $this->fileHeader->compression = 'gzip'; + break; + case 2: + $this->fileHeader->compression = 'bzip2'; + break; + } + + $this->fileHeader->permissions = $header_data['perms']; + + // Find hard-coded banned files + if ((basename($this->fileHeader->file) == ".") || (basename($this->fileHeader->file) == "..")) + { + $isBannedFile = true; + } + + // Also try to find banned files passed in class configuration + if ((count($this->skipFiles) > 0) && (!$isRenamed)) + { + if (in_array($this->fileHeader->file, $this->skipFiles)) + { + $isBannedFile = true; + } + } + + // If we have a banned file, let's skip it + if ($isBannedFile) + { + debugMsg('Skipping file ' . $this->fileHeader->file); + // Advance the file pointer, skipping exactly the size of the compressed data + $seekleft = $this->fileHeader->compressed; + while ($seekleft > 0) + { + // Ensure that we can seek past archive part boundaries + $curSize = @filesize($this->archiveList[$this->currentPartNumber]); + $curPos = @ftell($this->fp); + $canSeek = $curSize - $curPos; + if ($canSeek > $seekleft) + { + $canSeek = $seekleft; + } + @fseek($this->fp, $canSeek, SEEK_CUR); + $seekleft -= $canSeek; + if ($seekleft) + { + $this->nextFile(); + } + } + + $this->currentPartOffset = @ftell($this->fp); + $this->runState = AK_STATE_DONE; + + return true; + } + + // Remove the removePath, if any + $this->fileHeader->file = $this->removePath($this->fileHeader->file); + + // Last chance to prepend a path to the filename + if (!empty($this->addPath) && !$isDirRenamed) + { + $this->fileHeader->file = $this->addPath . $this->fileHeader->file; + } + + // Get the translated path name + $restorePerms = AKFactory::get('kickstart.setup.restoreperms', false); + if ($this->fileHeader->type == 'file') + { + // Regular file; ask the postproc engine to process its filename + if ($restorePerms) + { + $this->fileHeader->realFile = + $this->postProcEngine->processFilename($this->fileHeader->file, $this->fileHeader->permissions); + } + else + { + $this->fileHeader->realFile = $this->postProcEngine->processFilename($this->fileHeader->file); + } + } + elseif ($this->fileHeader->type == 'dir') + { + $dir = $this->fileHeader->file; + + // Directory; just create it + if ($restorePerms) + { + $this->postProcEngine->createDirRecursive($this->fileHeader->file, $this->fileHeader->permissions); + } + else + { + $this->postProcEngine->createDirRecursive($this->fileHeader->file, 0755); + } + $this->postProcEngine->processFilename(null); + } + else + { + // Symlink; do not post-process + $this->postProcEngine->processFilename(null); + } + + $this->createDirectory(); + + // Header is read + $this->runState = AK_STATE_HEADER; + + $this->dataReadLength = 0; + + return true; + } + + protected function heuristicFileHeaderLocator() + { + $ret = false; + $fullEOF = false; + + while (!$ret && !$fullEOF) + { + $this->currentPartOffset = @ftell($this->fp); + + if ($this->isEOF(true)) + { + $this->nextFile(); + } + + if ($this->isEOF(false)) + { + $fullEOF = true; + continue; + } + + // Read 512Kb + $chunk = fread($this->fp, 524288); + $size_read = mb_strlen($chunk, '8bit'); + //$pos = strpos($chunk, 'JPF'); + $pos = mb_strpos($chunk, 'JPF', 0, '8bit'); + + if ($pos !== false) + { + // We found it! + $this->currentPartOffset += $pos + 3; + @fseek($this->fp, $this->currentPartOffset, SEEK_SET); + $ret = true; + } + else + { + // Not yet found :( + $this->currentPartOffset = @ftell($this->fp); + } + } + + return $ret; + } + + /** + * Creates the directory this file points to + */ + protected function createDirectory() + { + if (AKFactory::get('kickstart.setup.dryrun', '0')) + { + return true; + } + + // Do we need to create a directory? + if (empty($this->fileHeader->realFile)) + { + $this->fileHeader->realFile = $this->fileHeader->file; + } + + $lastSlash = strrpos($this->fileHeader->realFile, '/'); + $dirName = substr($this->fileHeader->realFile, 0, $lastSlash); + $perms = $this->flagRestorePermissions ? $this->fileHeader->permissions : 0755; + $ignore = AKFactory::get('kickstart.setup.ignoreerrors', false) || $this->isIgnoredDirectory($dirName); + + if (($this->postProcEngine->createDirRecursive($dirName, $perms) == false) && (!$ignore)) + { + $this->setError(AKText::sprintf('COULDNT_CREATE_DIR', $dirName)); + + return false; + } + else + { + return true; + } + } + + /** + * Concrete classes must use this method to process file data. It must set $runState to AK_STATE_DATAREAD when + * it's finished processing the file data. + * + * @return bool True if processing the file data was successful, false if an error occurred + */ + protected function processFileData() + { + switch ($this->fileHeader->type) + { + case 'dir': + return $this->processTypeDir(); + break; + + case 'link': + return $this->processTypeLink(); + break; + + case 'file': + switch ($this->fileHeader->compression) + { + case 'none': + return $this->processTypeFileUncompressed(); + break; + + case 'gzip': + case 'bzip2': + return $this->processTypeFileCompressedSimple(); + break; + + } + break; + + default: + debugMsg('Unknown file type ' . $this->fileHeader->type); + break; + } + } + + /** + * Process the file data of a directory entry + * + * @return bool + */ + private function processTypeDir() + { + // Directory entries in the JPA do not have file data, therefore we're done processing the entry + $this->runState = AK_STATE_DATAREAD; + + return true; + } + + /** + * Process the file data of a link entry + * + * @return bool + */ + private function processTypeLink() + { + $readBytes = 0; + $toReadBytes = 0; + $leftBytes = $this->fileHeader->compressed; + $data = ''; + + while ($leftBytes > 0) + { + $toReadBytes = ($leftBytes > $this->chunkSize) ? $this->chunkSize : $leftBytes; + $mydata = $this->fread($this->fp, $toReadBytes); + $reallyReadBytes = akstringlen($mydata); + $data .= $mydata; + $leftBytes -= $reallyReadBytes; + + if ($reallyReadBytes < $toReadBytes) + { + // We read less than requested! Why? Did we hit local EOF? + if ($this->isEOF(true) && !$this->isEOF(false)) + { + // Yeap. Let's go to the next file + $this->nextFile(); + } + else + { + debugMsg('End of local file before reading all data with no more parts left. The archive is corrupt or truncated.'); + // Nope. The archive is corrupt + $this->setError(AKText::_('ERR_CORRUPT_ARCHIVE')); + + return false; + } + } + } + + $filename = isset($this->fileHeader->realFile) ? $this->fileHeader->realFile : $this->fileHeader->file; + + if (!AKFactory::get('kickstart.setup.dryrun', '0')) + { + // Try to remove an existing file or directory by the same name + if (file_exists($filename)) + { + @unlink($filename); + @rmdir($filename); + } + + // Remove any trailing slash + if (substr($filename, -1) == '/') + { + $filename = substr($filename, 0, -1); + } + // Create the symlink - only possible within PHP context. There's no support built in the FTP protocol, so no postproc use is possible here :( + @symlink($data, $filename); + } + + $this->runState = AK_STATE_DATAREAD; + + return true; // No matter if the link was created! + } + + private function processTypeFileUncompressed() + { + // Uncompressed files are being processed in small chunks, to avoid timeouts + if (($this->dataReadLength == 0) && !AKFactory::get('kickstart.setup.dryrun', '0')) + { + // Before processing file data, ensure permissions are adequate + $this->setCorrectPermissions($this->fileHeader->file); + } + + // Open the output file + if (!AKFactory::get('kickstart.setup.dryrun', '0')) + { + $ignore = + AKFactory::get('kickstart.setup.ignoreerrors', false) || $this->isIgnoredDirectory($this->fileHeader->file); + + if ($this->dataReadLength == 0) + { + $outfp = @fopen($this->fileHeader->realFile, 'wb'); + } + else + { + $outfp = @fopen($this->fileHeader->realFile, 'ab'); + } + + // Can we write to the file? + if (($outfp === false) && (!$ignore)) + { + // An error occurred + debugMsg('Could not write to output file'); + $this->setError(AKText::sprintf('COULDNT_WRITE_FILE', $this->fileHeader->realFile)); + + return false; + } + } + + // Does the file have any data, at all? + if ($this->fileHeader->compressed == 0) + { + // No file data! + if (!AKFactory::get('kickstart.setup.dryrun', '0') && is_resource($outfp)) + { + @fclose($outfp); + } + + $this->runState = AK_STATE_DATAREAD; + + return true; + } + + // Reference to the global timer + $timer = AKFactory::getTimer(); + + $toReadBytes = 0; + $leftBytes = $this->fileHeader->compressed - $this->dataReadLength; + + // Loop while there's data to read and enough time to do it + while (($leftBytes > 0) && ($timer->getTimeLeft() > 0)) + { + $toReadBytes = ($leftBytes > $this->chunkSize) ? $this->chunkSize : $leftBytes; + $data = $this->fread($this->fp, $toReadBytes); + $reallyReadBytes = akstringlen($data); + $leftBytes -= $reallyReadBytes; + $this->dataReadLength += $reallyReadBytes; + + if ($reallyReadBytes < $toReadBytes) + { + // We read less than requested! Why? Did we hit local EOF? + if ($this->isEOF(true) && !$this->isEOF(false)) + { + // Yeap. Let's go to the next file + $this->nextFile(); + } + else + { + // Nope. The archive is corrupt + debugMsg('Not enough data in file. The archive is truncated or corrupt.'); + $this->setError(AKText::_('ERR_CORRUPT_ARCHIVE')); + + return false; + } + } + + if (!AKFactory::get('kickstart.setup.dryrun', '0')) + { + if (is_resource($outfp)) + { + @fwrite($outfp, $data); + } + } + } + + // Close the file pointer + if (!AKFactory::get('kickstart.setup.dryrun', '0')) + { + if (is_resource($outfp)) + { + @fclose($outfp); + } + } + + // Was this a pre-timeout bail out? + if ($leftBytes > 0) + { + $this->runState = AK_STATE_DATA; + } + else + { + // Oh! We just finished! + $this->runState = AK_STATE_DATAREAD; + $this->dataReadLength = 0; + } + + return true; + } + + private function processTypeFileCompressedSimple() + { + if (!AKFactory::get('kickstart.setup.dryrun', '0')) + { + // Before processing file data, ensure permissions are adequate + $this->setCorrectPermissions($this->fileHeader->file); + + // Open the output file + $outfp = @fopen($this->fileHeader->realFile, 'wb'); + + // Can we write to the file? + $ignore = + AKFactory::get('kickstart.setup.ignoreerrors', false) || $this->isIgnoredDirectory($this->fileHeader->file); + + if (($outfp === false) && (!$ignore)) + { + // An error occurred + debugMsg('Could not write to output file'); + $this->setError(AKText::sprintf('COULDNT_WRITE_FILE', $this->fileHeader->realFile)); + + return false; + } + } + + // Does the file have any data, at all? + if ($this->fileHeader->compressed == 0) + { + // No file data! + if (!AKFactory::get('kickstart.setup.dryrun', '0')) + { + if (is_resource($outfp)) + { + @fclose($outfp); + } + } + $this->runState = AK_STATE_DATAREAD; + + return true; + } + + // Simple compressed files are processed as a whole; we can't do chunk processing + $zipData = $this->fread($this->fp, $this->fileHeader->compressed); + while (akstringlen($zipData) < $this->fileHeader->compressed) + { + // End of local file before reading all data, but have more archive parts? + if ($this->isEOF(true) && !$this->isEOF(false)) + { + // Yeap. Read from the next file + $this->nextFile(); + $bytes_left = $this->fileHeader->compressed - akstringlen($zipData); + $zipData .= $this->fread($this->fp, $bytes_left); + } + else + { + debugMsg('End of local file before reading all data with no more parts left. The archive is corrupt or truncated.'); + $this->setError(AKText::_('ERR_CORRUPT_ARCHIVE')); + + return false; + } + } + + if ($this->fileHeader->compression == 'gzip') + { + $unzipData = gzinflate($zipData); + } + elseif ($this->fileHeader->compression == 'bzip2') + { + $unzipData = bzdecompress($zipData); + } + unset($zipData); + + // Write to the file. + if (!AKFactory::get('kickstart.setup.dryrun', '0') && is_resource($outfp)) + { + @fwrite($outfp, $unzipData, $this->fileHeader->uncompressed); + @fclose($outfp); + } + unset($unzipData); + + $this->runState = AK_STATE_DATAREAD; + + return true; + } +} + +/** + * Akeeba Restore + * A JSON-powered JPA, JPS and ZIP archive extraction library + * + * @copyright 2008-2017 Nicholas K. Dionysopoulos / Akeeba Ltd. + * @license GNU GPL v2 or - at your option - any later version + * @package akeebabackup + * @subpackage kickstart + */ + +/** + * ZIP archive extraction class + * + * Since the file data portion of ZIP and JPA are similarly structured (it's empty for dirs, + * linked node name for symlinks, dumped binary data for no compressions and dumped gzipped + * binary data for gzip compression) we just have to subclass AKUnarchiverJPA and change the + * header reading bits. Reusable code ;) + */ +class AKUnarchiverZIP extends AKUnarchiverJPA +{ + var $expectDataDescriptor = false; + + protected function readArchiveHeader() + { + debugMsg('Preparing to read archive header'); + // Initialize header data array + $this->archiveHeaderData = new stdClass(); + + // Open the first part + debugMsg('Opening the first part'); + $this->nextFile(); + + // Fail for unreadable files + if ($this->fp === false) + { + debugMsg('The first part is not readable'); + + return false; + } + + // Read a possible multipart signature + $sigBinary = fread($this->fp, 4); + $headerData = unpack('Vsig', $sigBinary); + + // Roll back if it's not a multipart archive + if ($headerData['sig'] == 0x04034b50) + { + debugMsg('The archive is not multipart'); + fseek($this->fp, -4, SEEK_CUR); + } + else + { + debugMsg('The archive is multipart'); + } + + $multiPartSigs = array( + 0x08074b50, // Multi-part ZIP + 0x30304b50, // Multi-part ZIP (alternate) + 0x04034b50 // Single file + ); + if (!in_array($headerData['sig'], $multiPartSigs)) + { + debugMsg('Invalid header signature ' . dechex($headerData['sig'])); + $this->setError(AKText::_('ERR_CORRUPT_ARCHIVE')); + + return false; + } + + $this->currentPartOffset = @ftell($this->fp); + debugMsg('Current part offset after reading header: ' . $this->currentPartOffset); + + $this->dataReadLength = 0; + + return true; + } + + /** + * Concrete classes must use this method to read the file header + * + * @return bool True if reading the file was successful, false if an error occurred or we reached end of archive + */ + protected function readFileHeader() + { + // If the current part is over, proceed to the next part please + if ($this->isEOF(true)) + { + debugMsg('Opening next archive part'); + $this->nextFile(); + } + + $this->currentPartOffset = ftell($this->fp); + + if ($this->expectDataDescriptor) + { + // The last file had bit 3 of the general purpose bit flag set. This means that we have a + // 12 byte data descriptor we need to skip. To make things worse, there might also be a 4 + // byte optional data descriptor header (0x08074b50). + $junk = @fread($this->fp, 4); + $junk = unpack('Vsig', $junk); + if ($junk['sig'] == 0x08074b50) + { + // Yes, there was a signature + $junk = @fread($this->fp, 12); + debugMsg('Data descriptor (w/ header) skipped at ' . (ftell($this->fp) - 12)); + } + else + { + // No, there was no signature, just read another 8 bytes + $junk = @fread($this->fp, 8); + debugMsg('Data descriptor (w/out header) skipped at ' . (ftell($this->fp) - 8)); + } + + // And check for EOF, too + if ($this->isEOF(true)) + { + debugMsg('EOF before reading header'); + + $this->nextFile(); + } + } + + // Get and decode Local File Header + $headerBinary = fread($this->fp, 30); + $headerData = + unpack('Vsig/C2ver/vbitflag/vcompmethod/vlastmodtime/vlastmoddate/Vcrc/Vcompsize/Vuncomp/vfnamelen/veflen', $headerBinary); + + // Check signature + if (!($headerData['sig'] == 0x04034b50)) + { + debugMsg('Not a file signature at ' . (ftell($this->fp) - 4)); + + // The signature is not the one used for files. Is this a central directory record (i.e. we're done)? + if ($headerData['sig'] == 0x02014b50) + { + debugMsg('EOCD signature at ' . (ftell($this->fp) - 4)); + // End of ZIP file detected. We'll just skip to the end of file... + while ($this->nextFile()) + { + }; + @fseek($this->fp, 0, SEEK_END); // Go to EOF + return false; + } + else + { + debugMsg('Invalid signature ' . dechex($headerData['sig']) . ' at ' . ftell($this->fp)); + $this->setError(AKText::_('ERR_CORRUPT_ARCHIVE')); + + return false; + } + } + + // If bit 3 of the bitflag is set, expectDataDescriptor is true + $this->expectDataDescriptor = ($headerData['bitflag'] & 4) == 4; + + $this->fileHeader = new stdClass(); + $this->fileHeader->timestamp = 0; + + // Read the last modified data and time + $lastmodtime = $headerData['lastmodtime']; + $lastmoddate = $headerData['lastmoddate']; + + if ($lastmoddate && $lastmodtime) + { + // ----- Extract time + $v_hour = ($lastmodtime & 0xF800) >> 11; + $v_minute = ($lastmodtime & 0x07E0) >> 5; + $v_seconde = ($lastmodtime & 0x001F) * 2; + + // ----- Extract date + $v_year = (($lastmoddate & 0xFE00) >> 9) + 1980; + $v_month = ($lastmoddate & 0x01E0) >> 5; + $v_day = $lastmoddate & 0x001F; + + // ----- Get UNIX date format + $this->fileHeader->timestamp = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year); + } + + $isBannedFile = false; + + $this->fileHeader->compressed = $headerData['compsize']; + $this->fileHeader->uncompressed = $headerData['uncomp']; + $nameFieldLength = $headerData['fnamelen']; + $extraFieldLength = $headerData['eflen']; + + // Read filename field + $this->fileHeader->file = fread($this->fp, $nameFieldLength); + + // Handle file renaming + $isRenamed = false; + if (is_array($this->renameFiles) && (count($this->renameFiles) > 0)) + { + if (array_key_exists($this->fileHeader->file, $this->renameFiles)) + { + $this->fileHeader->file = $this->renameFiles[$this->fileHeader->file]; + $isRenamed = true; + } + } + + // Handle directory renaming + $isDirRenamed = false; + if (is_array($this->renameDirs) && (count($this->renameDirs) > 0)) + { + if (array_key_exists(dirname($this->fileHeader->file), $this->renameDirs)) + { + $file = + rtrim($this->renameDirs[dirname($this->fileHeader->file)], '/') . '/' . basename($this->fileHeader->file); + $isRenamed = true; + $isDirRenamed = true; + } + } + + // Read extra field if present + if ($extraFieldLength > 0) + { + $extrafield = fread($this->fp, $extraFieldLength); + } + + debugMsg('*' . ftell($this->fp) . ' IS START OF ' . $this->fileHeader->file . ' (' . $this->fileHeader->compressed . ' bytes)'); + + + // Decide filetype -- Check for directories + $this->fileHeader->type = 'file'; + if (strrpos($this->fileHeader->file, '/') == strlen($this->fileHeader->file) - 1) + { + $this->fileHeader->type = 'dir'; + } + // Decide filetype -- Check for symbolic links + if (($headerData['ver1'] == 10) && ($headerData['ver2'] == 3)) + { + $this->fileHeader->type = 'link'; + } + + switch ($headerData['compmethod']) + { + case 0: + $this->fileHeader->compression = 'none'; + break; + case 8: + $this->fileHeader->compression = 'gzip'; + break; + } + + // Find hard-coded banned files + if ((basename($this->fileHeader->file) == ".") || (basename($this->fileHeader->file) == "..")) + { + $isBannedFile = true; + } + + // Also try to find banned files passed in class configuration + if ((count($this->skipFiles) > 0) && (!$isRenamed)) + { + if (in_array($this->fileHeader->file, $this->skipFiles)) + { + $isBannedFile = true; + } + } + + // If we have a banned file, let's skip it + if ($isBannedFile) + { + // Advance the file pointer, skipping exactly the size of the compressed data + $seekleft = $this->fileHeader->compressed; + while ($seekleft > 0) + { + // Ensure that we can seek past archive part boundaries + $curSize = @filesize($this->archiveList[$this->currentPartNumber]); + $curPos = @ftell($this->fp); + $canSeek = $curSize - $curPos; + if ($canSeek > $seekleft) + { + $canSeek = $seekleft; + } + @fseek($this->fp, $canSeek, SEEK_CUR); + $seekleft -= $canSeek; + if ($seekleft) + { + $this->nextFile(); + } + } + + $this->currentPartOffset = @ftell($this->fp); + $this->runState = AK_STATE_DONE; + + return true; + } + + // Remove the removePath, if any + $this->fileHeader->file = $this->removePath($this->fileHeader->file); + + // Last chance to prepend a path to the filename + if (!empty($this->addPath) && !$isDirRenamed) + { + $this->fileHeader->file = $this->addPath . $this->fileHeader->file; + } + + // Get the translated path name + if ($this->fileHeader->type == 'file') + { + $this->fileHeader->realFile = $this->postProcEngine->processFilename($this->fileHeader->file); + } + elseif ($this->fileHeader->type == 'dir') + { + $this->fileHeader->timestamp = 0; + + $dir = $this->fileHeader->file; + + $this->postProcEngine->createDirRecursive($this->fileHeader->file, 0755); + $this->postProcEngine->processFilename(null); + } + else + { + // Symlink; do not post-process + $this->fileHeader->timestamp = 0; + $this->postProcEngine->processFilename(null); + } + + $this->createDirectory(); + + // Header is read + $this->runState = AK_STATE_HEADER; + + return true; + } + +} + +/** + * Akeeba Restore + * A JSON-powered JPA, JPS and ZIP archive extraction library + * + * @copyright 2008-2017 Nicholas K. Dionysopoulos / Akeeba Ltd. + * @license GNU GPL v2 or - at your option - any later version + * @package akeebabackup + * @subpackage kickstart + */ + +/** + * JPS archive extraction class + */ +class AKUnarchiverJPS extends AKUnarchiverJPA +{ + /** + * Header data for the archive + * + * @var array + */ + protected $archiveHeaderData = array(); + + /** + * Plaintext password from which the encryption key will be derived with PBKDF2 + * + * @var string + */ + protected $password = ''; + + /** + * Which hash algorithm should I use for key derivation with PBKDF2. + * + * @var string + */ + private $pbkdf2Algorithm = 'sha1'; + + /** + * How many iterations should I use for key derivation with PBKDF2 + * + * @var int + */ + private $pbkdf2Iterations = 1000; + + /** + * Should I use a static salt for key derivation with PBKDF2? + * + * @var bool + */ + private $pbkdf2UseStaticSalt = 0; + + /** + * Static salt for key derivation with PBKDF2 + * + * @var string + */ + private $pbkdf2StaticSalt = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; + + /** + * How much compressed data I have read since the last file header read + * + * @var int + */ + private $compressedSizeReadSinceLastFileHeader = 0; + + public function __construct() + { + parent::__construct(); + + $this->password = AKFactory::get('kickstart.jps.password', ''); + } + + public function __wakeup() + { + parent::__wakeup(); + + // Make sure the decryption is all set up (required!) + AKEncryptionAES::setPbkdf2Algorithm($this->pbkdf2Algorithm); + AKEncryptionAES::setPbkdf2Iterations($this->pbkdf2Iterations); + AKEncryptionAES::setPbkdf2UseStaticSalt($this->pbkdf2UseStaticSalt); + AKEncryptionAES::setPbkdf2StaticSalt($this->pbkdf2StaticSalt); + } + + + protected function readArchiveHeader() + { + // Initialize header data array + $this->archiveHeaderData = new stdClass(); + + // Open the first part + $this->nextFile(); + + // Fail for unreadable files + if ($this->fp === false) + { + return false; + } + + // Read the signature + $sig = fread($this->fp, 3); + + if ($sig != 'JPS') + { + // Not a JPA file + $this->setError(AKText::_('ERR_NOT_A_JPS_FILE')); + + return false; + } + + // Read and parse the known portion of header data (5 bytes) + $bin_data = fread($this->fp, 5); + $header_data = unpack('Cmajor/Cminor/cspanned/vextra', $bin_data); + + // Is this a v2 archive? + $versionHumanReadable = $header_data['major'] . '.' . $header_data['minor']; + $isV2Archive = version_compare($versionHumanReadable, '2.0', 'ge'); + + // Load any remaining header data + $rest_length = $header_data['extra']; + + if ($isV2Archive && $rest_length) + { + // V2 archives only have one kind of extra header + if (!$this->readKeyExpansionExtraHeader()) + { + return false; + } + } + elseif ($rest_length > 0) + { + $junk = fread($this->fp, $rest_length); + } + + // Temporary array with all the data we read + $temp = array( + 'signature' => $sig, + 'major' => $header_data['major'], + 'minor' => $header_data['minor'], + 'spanned' => $header_data['spanned'] + ); + // Array-to-object conversion + foreach ($temp as $key => $value) + { + $this->archiveHeaderData->{$key} = $value; + } + + $this->currentPartOffset = @ftell($this->fp); + + $this->dataReadLength = 0; + + return true; + } + + /** + * Concrete classes must use this method to read the file header + * + * @return bool True if reading the file was successful, false if an error occurred or we reached end of archive + */ + protected function readFileHeader() + { + // If the current part is over, proceed to the next part please + if ($this->isEOF(true)) + { + $this->nextFile(); + } + + $this->currentPartOffset = ftell($this->fp); + + // Get and decode Entity Description Block + $signature = fread($this->fp, 3); + + // Check for end-of-archive siganture + if ($signature == 'JPE') + { + $this->setState('postrun'); + + return true; + } + + $this->fileHeader = new stdClass(); + $this->fileHeader->timestamp = 0; + + // Check signature + if ($signature != 'JPF') + { + if ($this->isEOF(true)) + { + // This file is finished; make sure it's the last one + $this->nextFile(); + if (!$this->isEOF(false)) + { + $this->setError(AKText::sprintf('INVALID_FILE_HEADER', $this->currentPartNumber, $this->currentPartOffset)); + + return false; + } + + // We're just finished + return false; + } + else + { + fseek($this->fp, -6, SEEK_CUR); + $signature = fread($this->fp, 3); + if ($signature == 'JPE') + { + return false; + } + + $this->setError(AKText::sprintf('INVALID_FILE_HEADER', $this->currentPartNumber, $this->currentPartOffset)); + + return false; + } + } + + // This a JPS Entity Block. Process the header. + + $isBannedFile = false; + + // Make sure the decryption is all set up + AKEncryptionAES::setPbkdf2Algorithm($this->pbkdf2Algorithm); + AKEncryptionAES::setPbkdf2Iterations($this->pbkdf2Iterations); + AKEncryptionAES::setPbkdf2UseStaticSalt($this->pbkdf2UseStaticSalt); + AKEncryptionAES::setPbkdf2StaticSalt($this->pbkdf2StaticSalt); + + // Read and decrypt the header + $edbhData = fread($this->fp, 4); + $edbh = unpack('vencsize/vdecsize', $edbhData); + $bin_data = fread($this->fp, $edbh['encsize']); + + // Add the header length to the data read + $this->compressedSizeReadSinceLastFileHeader += $edbh['encsize'] + 4; + + // Decrypt and truncate + $bin_data = AKEncryptionAES::AESDecryptCBC($bin_data, $this->password); + $bin_data = substr($bin_data, 0, $edbh['decsize']); + + // Read length of EDB and of the Entity Path Data + $length_array = unpack('vpathsize', substr($bin_data, 0, 2)); + // Read the path data + $file = substr($bin_data, 2, $length_array['pathsize']); + + // Handle file renaming + $isRenamed = false; + if (is_array($this->renameFiles) && (count($this->renameFiles) > 0)) + { + if (array_key_exists($file, $this->renameFiles)) + { + $file = $this->renameFiles[$file]; + $isRenamed = true; + } + } + + // Handle directory renaming + $isDirRenamed = false; + if (is_array($this->renameDirs) && (count($this->renameDirs) > 0)) + { + if (array_key_exists(dirname($file), $this->renameDirs)) + { + $file = rtrim($this->renameDirs[dirname($file)], '/') . '/' . basename($file); + $isRenamed = true; + $isDirRenamed = true; + } + } + + // Read and parse the known data portion + $bin_data = substr($bin_data, 2 + $length_array['pathsize']); + $header_data = unpack('Ctype/Ccompression/Vuncompsize/Vperms/Vfilectime', $bin_data); + + $this->fileHeader->timestamp = $header_data['filectime']; + $compressionType = $header_data['compression']; + + // Populate the return array + $this->fileHeader->file = $file; + $this->fileHeader->uncompressed = $header_data['uncompsize']; + switch ($header_data['type']) + { + case 0: + $this->fileHeader->type = 'dir'; + break; + + case 1: + $this->fileHeader->type = 'file'; + break; + + case 2: + $this->fileHeader->type = 'link'; + break; + } + switch ($compressionType) + { + case 0: + $this->fileHeader->compression = 'none'; + break; + case 1: + $this->fileHeader->compression = 'gzip'; + break; + case 2: + $this->fileHeader->compression = 'bzip2'; + break; + } + $this->fileHeader->permissions = $header_data['perms']; + + // Find hard-coded banned files + if ((basename($this->fileHeader->file) == ".") || (basename($this->fileHeader->file) == "..")) + { + $isBannedFile = true; + } + + // Also try to find banned files passed in class configuration + if ((count($this->skipFiles) > 0) && (!$isRenamed)) + { + if (in_array($this->fileHeader->file, $this->skipFiles)) + { + $isBannedFile = true; + } + } + + // If we have a banned file, let's skip it + if ($isBannedFile) + { + $done = false; + while (!$done) + { + // Read the Data Chunk Block header + $binMiniHead = fread($this->fp, 8); + if (in_array(substr($binMiniHead, 0, 3), array('JPF', 'JPE'))) + { + // Not a Data Chunk Block header, I am done skipping the file + @fseek($this->fp, -8, SEEK_CUR); // Roll back the file pointer + $done = true; // Mark as done + continue; // Exit loop + } + else + { + // Skip forward by the amount of compressed data + $miniHead = unpack('Vencsize/Vdecsize', $binMiniHead); + @fseek($this->fp, $miniHead['encsize'], SEEK_CUR); + $this->compressedSizeReadSinceLastFileHeader += 8 + $miniHead['encsize']; + } + } + + $this->currentPartOffset = @ftell($this->fp); + $this->runState = AK_STATE_DONE; + $this->fileHeader->compressed = $this->compressedSizeReadSinceLastFileHeader; + $this->compressedSizeReadSinceLastFileHeader = 0; + + return true; + } + + // Remove the removePath, if any + $this->fileHeader->file = $this->removePath($this->fileHeader->file); + + // Last chance to prepend a path to the filename + if (!empty($this->addPath) && !$isDirRenamed) + { + $this->fileHeader->file = $this->addPath . $this->fileHeader->file; + } + + // Get the translated path name + $restorePerms = AKFactory::get('kickstart.setup.restoreperms', false); + if ($this->fileHeader->type == 'file') + { + // Regular file; ask the postproc engine to process its filename + if ($restorePerms) + { + $this->fileHeader->realFile = + $this->postProcEngine->processFilename($this->fileHeader->file, $this->fileHeader->permissions); + } + else + { + $this->fileHeader->realFile = $this->postProcEngine->processFilename($this->fileHeader->file); + } + } + elseif ($this->fileHeader->type == 'dir') + { + $dir = $this->fileHeader->file; + $this->fileHeader->realFile = $dir; + + // Directory; just create it + if ($restorePerms) + { + $this->postProcEngine->createDirRecursive($this->fileHeader->file, $this->fileHeader->permissions); + } + else + { + $this->postProcEngine->createDirRecursive($this->fileHeader->file, 0755); + } + $this->postProcEngine->processFilename(null); + } + else + { + // Symlink; do not post-process + $this->postProcEngine->processFilename(null); + } + + $this->fileHeader->compressed = $this->compressedSizeReadSinceLastFileHeader; + $this->compressedSizeReadSinceLastFileHeader = 0; + + $this->createDirectory(); + + // Header is read + $this->runState = AK_STATE_HEADER; + + $this->dataReadLength = 0; + + return true; + } + + /** + * Creates the directory this file points to + */ + protected function createDirectory() + { + if (AKFactory::get('kickstart.setup.dryrun', '0')) + { + return true; + } + + // Do we need to create a directory? + $lastSlash = strrpos($this->fileHeader->realFile, '/'); + $dirName = substr($this->fileHeader->realFile, 0, $lastSlash); + $perms = 0755; + $ignore = AKFactory::get('kickstart.setup.ignoreerrors', false) || $this->isIgnoredDirectory($dirName); + + if (($this->postProcEngine->createDirRecursive($dirName, $perms) == false) && (!$ignore)) + { + $this->setError(AKText::sprintf('COULDNT_CREATE_DIR', $dirName)); + + return false; + } + + return true; + } + + /** + * Concrete classes must use this method to process file data. It must set $runState to AK_STATE_DATAREAD when + * it's finished processing the file data. + * + * @return bool True if processing the file data was successful, false if an error occurred + */ + protected function processFileData() + { + switch ($this->fileHeader->type) + { + case 'dir': + return $this->processTypeDir(); + break; + + case 'link': + return $this->processTypeLink(); + break; + + case 'file': + switch ($this->fileHeader->compression) + { + case 'none': + return $this->processTypeFileUncompressed(); + break; + + case 'gzip': + case 'bzip2': + return $this->processTypeFileCompressedSimple(); + break; + + } + break; + } + } + + /** + * Process the file data of a directory entry + * + * @return bool + */ + private function processTypeDir() + { + // Directory entries in the JPA do not have file data, therefore we're done processing the entry + $this->runState = AK_STATE_DATAREAD; + + return true; + } + + /** + * Process the file data of a link entry + * + * @return bool + */ + private function processTypeLink() + { + + // Does the file have any data, at all? + if ($this->fileHeader->uncompressed == 0) + { + // No file data! + $this->runState = AK_STATE_DATAREAD; + + return true; + } + + // Read the mini header + $binMiniHeader = fread($this->fp, 8); + $reallyReadBytes = akstringlen($binMiniHeader); + + if ($reallyReadBytes < 8) + { + // We read less than requested! Why? Did we hit local EOF? + if ($this->isEOF(true) && !$this->isEOF(false)) + { + // Yeap. Let's go to the next file + $this->nextFile(); + // Retry reading the header + $binMiniHeader = fread($this->fp, 8); + $reallyReadBytes = akstringlen($binMiniHeader); + // Still not enough data? If so, the archive is corrupt or missing parts. + if ($reallyReadBytes < 8) + { + $this->setError(AKText::_('ERR_CORRUPT_ARCHIVE')); + + return false; + } + } + else + { + // Nope. The archive is corrupt + $this->setError(AKText::_('ERR_CORRUPT_ARCHIVE')); + + return false; + } + } + + // Read the encrypted data + $miniHeader = unpack('Vencsize/Vdecsize', $binMiniHeader); + $toReadBytes = $miniHeader['encsize']; + $data = $this->fread($this->fp, $toReadBytes); + $reallyReadBytes = akstringlen($data); + $this->compressedSizeReadSinceLastFileHeader += 8 + $miniHeader['encsize']; + + if ($reallyReadBytes < $toReadBytes) + { + // We read less than requested! Why? Did we hit local EOF? + if ($this->isEOF(true) && !$this->isEOF(false)) + { + // Yeap. Let's go to the next file + $this->nextFile(); + // Read the rest of the data + $toReadBytes -= $reallyReadBytes; + $restData = $this->fread($this->fp, $toReadBytes); + $reallyReadBytes = akstringlen($data); + if ($reallyReadBytes < $toReadBytes) + { + $this->setError(AKText::_('ERR_CORRUPT_ARCHIVE')); + + return false; + } + $data .= $restData; + } + else + { + // Nope. The archive is corrupt + $this->setError(AKText::_('ERR_CORRUPT_ARCHIVE')); + + return false; + } + } + + // Decrypt the data + $data = AKEncryptionAES::AESDecryptCBC($data, $this->password); + + // Is the length of the decrypted data less than expected? + $data_length = akstringlen($data); + if ($data_length < $miniHeader['decsize']) + { + $this->setError(AKText::_('ERR_INVALID_JPS_PASSWORD')); + + return false; + } + + // Trim the data + $data = substr($data, 0, $miniHeader['decsize']); + + if (!AKFactory::get('kickstart.setup.dryrun', '0')) + { + // Try to remove an existing file or directory by the same name + if (file_exists($this->fileHeader->file)) + { + @unlink($this->fileHeader->file); + @rmdir($this->fileHeader->file); + } + // Remove any trailing slash + if (substr($this->fileHeader->file, -1) == '/') + { + $this->fileHeader->file = substr($this->fileHeader->file, 0, -1); + } + // Create the symlink - only possible within PHP context. There's no support built in the FTP protocol, so no postproc use is possible here :( + @symlink($data, $this->fileHeader->file); + } + + $this->runState = AK_STATE_DATAREAD; + + return true; // No matter if the link was created! + } + + private function processTypeFileUncompressed() + { + // Uncompressed files are being processed in small chunks, to avoid timeouts + if (($this->dataReadLength == 0) && !AKFactory::get('kickstart.setup.dryrun', '0')) + { + // Before processing file data, ensure permissions are adequate + $this->setCorrectPermissions($this->fileHeader->file); + } + + // Open the output file + if (!AKFactory::get('kickstart.setup.dryrun', '0')) + { + $ignore = + AKFactory::get('kickstart.setup.ignoreerrors', false) || $this->isIgnoredDirectory($this->fileHeader->file); + if ($this->dataReadLength == 0) + { + $outfp = @fopen($this->fileHeader->realFile, 'wb'); + } + else + { + $outfp = @fopen($this->fileHeader->realFile, 'ab'); + } + + // Can we write to the file? + if (($outfp === false) && (!$ignore)) + { + // An error occurred + $this->setError(AKText::sprintf('COULDNT_WRITE_FILE', $this->fileHeader->realFile)); + + return false; + } + } + + // Does the file have any data, at all? + if ($this->fileHeader->uncompressed == 0) + { + // No file data! + if (!AKFactory::get('kickstart.setup.dryrun', '0') && is_resource($outfp)) + { + @fclose($outfp); + } + $this->runState = AK_STATE_DATAREAD; + + return true; + } + + $this->setError('An uncompressed file was detected; this is not supported by this archive extraction utility'); + + return false; + } + + private function processTypeFileCompressedSimple() + { + $timer = AKFactory::getTimer(); + + // Files are being processed in small chunks, to avoid timeouts + if (($this->dataReadLength == 0) && !AKFactory::get('kickstart.setup.dryrun', '0')) + { + // Before processing file data, ensure permissions are adequate + $this->setCorrectPermissions($this->fileHeader->file); + } + + // Open the output file + if (!AKFactory::get('kickstart.setup.dryrun', '0')) + { + // Open the output file + $outfp = @fopen($this->fileHeader->realFile, 'wb'); + + // Can we write to the file? + $ignore = + AKFactory::get('kickstart.setup.ignoreerrors', false) || $this->isIgnoredDirectory($this->fileHeader->file); + if (($outfp === false) && (!$ignore)) + { + // An error occurred + $this->setError(AKText::sprintf('COULDNT_WRITE_FILE', $this->fileHeader->realFile)); + + return false; + } + } + + // Does the file have any data, at all? + if ($this->fileHeader->uncompressed == 0) + { + // No file data! + if (!AKFactory::get('kickstart.setup.dryrun', '0')) + { + if (is_resource($outfp)) + { + @fclose($outfp); + } + } + $this->runState = AK_STATE_DATAREAD; + + return true; + } + + $leftBytes = $this->fileHeader->uncompressed - $this->dataReadLength; + + // Loop while there's data to write and enough time to do it + while (($leftBytes > 0) && ($timer->getTimeLeft() > 0)) + { + // Read the mini header + $binMiniHeader = fread($this->fp, 8); + $reallyReadBytes = akstringlen($binMiniHeader); + if ($reallyReadBytes < 8) + { + // We read less than requested! Why? Did we hit local EOF? + if ($this->isEOF(true) && !$this->isEOF(false)) + { + // Yeap. Let's go to the next file + $this->nextFile(); + // Retry reading the header + $binMiniHeader = fread($this->fp, 8); + $reallyReadBytes = akstringlen($binMiniHeader); + // Still not enough data? If so, the archive is corrupt or missing parts. + if ($reallyReadBytes < 8) + { + $this->setError(AKText::_('ERR_CORRUPT_ARCHIVE')); + + return false; + } + } + else + { + // Nope. The archive is corrupt + $this->setError(AKText::_('ERR_CORRUPT_ARCHIVE')); + + return false; + } + } + + // Read the encrypted data + $miniHeader = unpack('Vencsize/Vdecsize', $binMiniHeader); + $toReadBytes = $miniHeader['encsize']; + $data = $this->fread($this->fp, $toReadBytes); + $reallyReadBytes = akstringlen($data); + + $this->compressedSizeReadSinceLastFileHeader += $miniHeader['encsize'] + 8; + + if ($reallyReadBytes < $toReadBytes) + { + // We read less than requested! Why? Did we hit local EOF? + if ($this->isEOF(true) && !$this->isEOF(false)) + { + // Yeap. Let's go to the next file + $this->nextFile(); + // Read the rest of the data + $toReadBytes -= $reallyReadBytes; + $restData = $this->fread($this->fp, $toReadBytes); + $reallyReadBytes = akstringlen($restData); + if ($reallyReadBytes < $toReadBytes) + { + $this->setError(AKText::_('ERR_CORRUPT_ARCHIVE')); + + return false; + } + if (akstringlen($data) == 0) + { + $data = $restData; + } + else + { + $data .= $restData; + } + } + else + { + // Nope. The archive is corrupt + $this->setError(AKText::_('ERR_CORRUPT_ARCHIVE')); + + return false; + } + } + + // Decrypt the data + $data = AKEncryptionAES::AESDecryptCBC($data, $this->password); + + // Is the length of the decrypted data less than expected? + $data_length = akstringlen($data); + if ($data_length < $miniHeader['decsize']) + { + $this->setError(AKText::_('ERR_INVALID_JPS_PASSWORD')); + + return false; + } + + // Trim the data + $data = substr($data, 0, $miniHeader['decsize']); + + // Decompress + $data = gzinflate($data); + $unc_len = akstringlen($data); + + // Write the decrypted data + if (!AKFactory::get('kickstart.setup.dryrun', '0')) + { + if (is_resource($outfp)) + { + @fwrite($outfp, $data, akstringlen($data)); + } + } + + // Update the read length + $this->dataReadLength += $unc_len; + $leftBytes = $this->fileHeader->uncompressed - $this->dataReadLength; + } + + // Close the file pointer + if (!AKFactory::get('kickstart.setup.dryrun', '0')) + { + if (is_resource($outfp)) + { + @fclose($outfp); + } + } + + // Was this a pre-timeout bail out? + if ($leftBytes > 0) + { + $this->runState = AK_STATE_DATA; + } + else + { + // Oh! We just finished! + $this->runState = AK_STATE_DATAREAD; + $this->dataReadLength = 0; + } + + return true; + } + + private function readKeyExpansionExtraHeader() + { + $signature = fread($this->fp, 4); + + if ($signature != "JH\x00\x01") + { + // Not a valid JPS file + $this->setError(AKText::_('ERR_NOT_A_JPS_FILE')); + + return false; + } + + $bin_data = fread($this->fp, 8); + $header_data = unpack('vlength/Calgo/Viterations/CuseStaticSalt', $bin_data); + + if ($header_data['length'] != 76) + { + // Not a valid JPS file + $this->setError(AKText::_('ERR_NOT_A_JPS_FILE')); + + return false; + } + + switch ($header_data['algo']) + { + case 0: + $algorithm = 'sha1'; + break; + + case 1: + $algorithm = 'sha256'; + break; + + case 2: + $algorithm = 'sha512'; + break; + + default: + // Not a valid JPS file + $this->setError(AKText::_('ERR_NOT_A_JPS_FILE')); + + return false; + break; + } + + $this->pbkdf2Algorithm = $algorithm; + $this->pbkdf2Iterations = $header_data['iterations']; + $this->pbkdf2UseStaticSalt = $header_data['useStaticSalt']; + $this->pbkdf2StaticSalt = fread($this->fp, 64); + + return true; + } +} + +/** + * Akeeba Restore + * A JSON-powered JPA, JPS and ZIP archive extraction library + * + * @copyright 2008-2017 Nicholas K. Dionysopoulos / Akeeba Ltd. + * @license GNU GPL v2 or - at your option - any later version + * @package akeebabackup + * @subpackage kickstart + */ + +/** + * Timer class + */ +class AKCoreTimer extends AKAbstractObject +{ + /** @var int Maximum execution time allowance per step */ + private $max_exec_time = null; + + /** @var int Timestamp of execution start */ + private $start_time = null; + + /** + * Public constructor, creates the timer object and calculates the execution time limits + * + * @return AECoreTimer + */ + public function __construct() + { + parent::__construct(); + + // Initialize start time + $this->start_time = $this->microtime_float(); + + // Get configured max time per step and bias + $config_max_exec_time = AKFactory::get('kickstart.tuning.max_exec_time', 14); + $bias = AKFactory::get('kickstart.tuning.run_time_bias', 75) / 100; + + // Get PHP's maximum execution time (our upper limit) + if (@function_exists('ini_get')) + { + $php_max_exec_time = @ini_get("maximum_execution_time"); + if ((!is_numeric($php_max_exec_time)) || ($php_max_exec_time == 0)) + { + // If we have no time limit, set a hard limit of about 10 seconds + // (safe for Apache and IIS timeouts, verbose enough for users) + $php_max_exec_time = 14; + } + } + else + { + // If ini_get is not available, use a rough default + $php_max_exec_time = 14; + } + + // Apply an arbitrary correction to counter CMS load time + $php_max_exec_time--; + + // Apply bias + $php_max_exec_time = $php_max_exec_time * $bias; + $config_max_exec_time = $config_max_exec_time * $bias; + + // Use the most appropriate time limit value + if ($config_max_exec_time > $php_max_exec_time) + { + $this->max_exec_time = $php_max_exec_time; + } + else + { + $this->max_exec_time = $config_max_exec_time; + } + } + + /** + * Returns the current timestampt in decimal seconds + */ + private function microtime_float() + { + list($usec, $sec) = explode(" ", microtime()); + + return ((float) $usec + (float) $sec); + } + + /** + * Wake-up function to reset internal timer when we get unserialized + */ + public function __wakeup() + { + // Re-initialize start time on wake-up + $this->start_time = $this->microtime_float(); + } + + /** + * Gets the number of seconds left, before we hit the "must break" threshold + * + * @return float + */ + public function getTimeLeft() + { + return $this->max_exec_time - $this->getRunningTime(); + } + + /** + * Gets the time elapsed since object creation/unserialization, effectively how + * long Akeeba Engine has been processing data + * + * @return float + */ + public function getRunningTime() + { + return $this->microtime_float() - $this->start_time; + } + + /** + * Enforce the minimum execution time + */ + public function enforce_min_exec_time() + { + // Try to get a sane value for PHP's maximum_execution_time INI parameter + if (@function_exists('ini_get')) + { + $php_max_exec = @ini_get("maximum_execution_time"); + } + else + { + $php_max_exec = 10; + } + if (($php_max_exec == "") || ($php_max_exec == 0)) + { + $php_max_exec = 10; + } + // Decrease $php_max_exec time by 500 msec we need (approx.) to tear down + // the application, as well as another 500msec added for rounding + // error purposes. Also make sure this is never gonna be less than 0. + $php_max_exec = max($php_max_exec * 1000 - 1000, 0); + + // Get the "minimum execution time per step" Akeeba Backup configuration variable + $minexectime = AKFactory::get('kickstart.tuning.min_exec_time', 0); + if (!is_numeric($minexectime)) + { + $minexectime = 0; + } + + // Make sure we are not over PHP's time limit! + if ($minexectime > $php_max_exec) + { + $minexectime = $php_max_exec; + } + + // Get current running time + $elapsed_time = $this->getRunningTime() * 1000; + + // Only run a sleep delay if we haven't reached the minexectime execution time + if (($minexectime > $elapsed_time) && ($elapsed_time > 0)) + { + $sleep_msec = $minexectime - $elapsed_time; + if (function_exists('usleep')) + { + usleep(1000 * $sleep_msec); + } + elseif (function_exists('time_nanosleep')) + { + $sleep_sec = floor($sleep_msec / 1000); + $sleep_nsec = 1000000 * ($sleep_msec - ($sleep_sec * 1000)); + time_nanosleep($sleep_sec, $sleep_nsec); + } + elseif (function_exists('time_sleep_until')) + { + $until_timestamp = time() + $sleep_msec / 1000; + time_sleep_until($until_timestamp); + } + elseif (function_exists('sleep')) + { + $sleep_sec = ceil($sleep_msec / 1000); + sleep($sleep_sec); + } + } + elseif ($elapsed_time > 0) + { + // No sleep required, even if user configured us to be able to do so. + } + } + + /** + * Reset the timer. It should only be used in CLI mode! + */ + public function resetTime() + { + $this->start_time = $this->microtime_float(); + } + + /** + * @param int $max_exec_time + */ + public function setMaxExecTime($max_exec_time) + { + $this->max_exec_time = $max_exec_time; + } +} + +/** + * Akeeba Restore + * A JSON-powered JPA, JPS and ZIP archive extraction library + * + * @copyright 2008-2017 Nicholas K. Dionysopoulos / Akeeba Ltd. + * @license GNU GPL v2 or - at your option - any later version + * @package akeebabackup + * @subpackage kickstart + */ + +/** + * A filesystem scanner which uses opendir() + */ +class AKUtilsLister extends AKAbstractObject +{ + public function &getFiles($folder, $pattern = '*') + { + // Initialize variables + $arr = array(); + $false = false; + + if (!is_dir($folder)) + { + return $false; + } + + $handle = @opendir($folder); + // If directory is not accessible, just return FALSE + if ($handle === false) + { + $this->setWarning('Unreadable directory ' . $folder); + + return $false; + } + + while (($file = @readdir($handle)) !== false) + { + if (!fnmatch($pattern, $file)) + { + continue; + } + + if (($file != '.') && ($file != '..')) + { + $ds = + ($folder == '') || ($folder == '/') || (@substr($folder, -1) == '/') || (@substr($folder, -1) == DIRECTORY_SEPARATOR) ? + '' : DIRECTORY_SEPARATOR; + $dir = $folder . $ds . $file; + $isDir = is_dir($dir); + if (!$isDir) + { + $arr[] = $dir; + } + } + } + @closedir($handle); + + return $arr; + } + + public function &getFolders($folder, $pattern = '*') + { + // Initialize variables + $arr = array(); + $false = false; + + if (!is_dir($folder)) + { + return $false; + } + + $handle = @opendir($folder); + // If directory is not accessible, just return FALSE + if ($handle === false) + { + $this->setWarning('Unreadable directory ' . $folder); + + return $false; + } + + while (($file = @readdir($handle)) !== false) + { + if (!fnmatch($pattern, $file)) + { + continue; + } + + if (($file != '.') && ($file != '..')) + { + $ds = + ($folder == '') || ($folder == '/') || (@substr($folder, -1) == '/') || (@substr($folder, -1) == DIRECTORY_SEPARATOR) ? + '' : DIRECTORY_SEPARATOR; + $dir = $folder . $ds . $file; + $isDir = is_dir($dir); + if ($isDir) + { + $arr[] = $dir; + } + } + } + @closedir($handle); + + return $arr; + } +} + +/** + * Akeeba Restore + * A JSON-powered JPA, JPS and ZIP archive extraction library + * + * @copyright 2008-2017 Nicholas K. Dionysopoulos / Akeeba Ltd. + * @license GNU GPL v2 or - at your option - any later version + * @package akeebabackup + * @subpackage kickstart + */ + +/** + * A simple INI-based i18n engine + */ +class AKText extends AKAbstractObject +{ + /** + * The default (en_GB) translation used when no other translation is available + * + * @var array + */ + private $default_translation = array( + 'AUTOMODEON' => 'Auto-mode enabled', + 'ERR_NOT_A_JPA_FILE' => 'The file is not a JPA archive', + 'ERR_CORRUPT_ARCHIVE' => 'The archive file is corrupt, truncated or archive parts are missing', + 'ERR_INVALID_LOGIN' => 'Invalid login', + 'COULDNT_CREATE_DIR' => 'Could not create %s folder', + 'COULDNT_WRITE_FILE' => 'Could not open %s for writing.', + 'WRONG_FTP_HOST' => 'Wrong FTP host or port', + 'WRONG_FTP_USER' => 'Wrong FTP username or password', + 'WRONG_FTP_PATH1' => 'Wrong FTP initial directory - the directory doesn\'t exist', + 'FTP_CANT_CREATE_DIR' => 'Could not create directory %s', + 'FTP_TEMPDIR_NOT_WRITABLE' => 'Could not find or create a writable temporary directory', + 'SFTP_TEMPDIR_NOT_WRITABLE' => 'Could not find or create a writable temporary directory', + 'FTP_COULDNT_UPLOAD' => 'Could not upload %s', + 'THINGS_HEADER' => 'Things you should know about Akeeba Kickstart', + 'THINGS_01' => 'Kickstart is not an installer. It is an archive extraction tool. The actual installer was put inside the archive file at backup time.', + 'THINGS_02' => 'Kickstart is not the only way to extract the backup archive. You can use Akeeba eXtract Wizard and upload the extracted files using FTP instead.', + 'THINGS_03' => 'Kickstart is bound by your server\'s configuration. As such, it may not work at all.', + 'THINGS_04' => 'You should download and upload your archive files using FTP in Binary transfer mode. Any other method could lead to a corrupt backup archive and restoration failure.', + 'THINGS_05' => 'Post-restoration site load errors are usually caused by .htaccess or php.ini directives. You should understand that blank pages, 404 and 500 errors can usually be worked around by editing the aforementioned files. It is not our job to mess with your configuration files, because this could be dangerous for your site.', + 'THINGS_06' => 'Kickstart overwrites files without a warning. If you are not sure that you are OK with that do not continue.', + 'THINGS_07' => 'Trying to restore to the temporary URL of a cPanel host (e.g. http://1.2.3.4/~username) will lead to restoration failure and your site will appear to be not working. This is normal and it\'s just how your server and CMS software work.', + 'THINGS_08' => 'You are supposed to read the documentation before using this software. Most issues can be avoided, or easily worked around, by understanding how this software works.', + 'THINGS_09' => 'This text does not imply that there is a problem detected. It is standard text displayed every time you launch Kickstart.', + 'CLOSE_LIGHTBOX' => 'Click here or press ESC to close this message', + 'SELECT_ARCHIVE' => 'Select a backup archive', + 'ARCHIVE_FILE' => 'Archive file:', + 'SELECT_EXTRACTION' => 'Select an extraction method', + 'WRITE_TO_FILES' => 'Write to files:', + 'WRITE_HYBRID' => 'Hybrid (use FTP only if needed)', + 'WRITE_DIRECTLY' => 'Directly', + 'WRITE_FTP' => 'Use FTP for all files', + 'WRITE_SFTP' => 'Use SFTP for all files', + 'FTP_HOST' => '(S)FTP host name:', + 'FTP_PORT' => '(S)FTP port:', + 'FTP_FTPS' => 'Use FTP over SSL (FTPS)', + 'FTP_PASSIVE' => 'Use FTP Passive Mode', + 'FTP_USER' => '(S)FTP user name:', + 'FTP_PASS' => '(S)FTP password:', + 'FTP_DIR' => '(S)FTP directory:', + 'FTP_TEMPDIR' => 'Temporary directory:', + 'FTP_CONNECTION_OK' => 'FTP Connection Established', + 'SFTP_CONNECTION_OK' => 'SFTP Connection Established', + 'FTP_CONNECTION_FAILURE' => 'The FTP Connection Failed', + 'SFTP_CONNECTION_FAILURE' => 'The SFTP Connection Failed', + 'FTP_TEMPDIR_WRITABLE' => 'The temporary directory is writable.', + 'FTP_TEMPDIR_UNWRITABLE' => 'The temporary directory is not writable. Please check the permissions.', + 'FTPBROWSER_ERROR_HOSTNAME' => "Invalid FTP host or port", + 'FTPBROWSER_ERROR_USERPASS' => "Invalid FTP username or password", + 'FTPBROWSER_ERROR_NOACCESS' => "Directory doesn't exist or you don't have enough permissions to access it", + 'FTPBROWSER_ERROR_UNSUPPORTED' => "Sorry, your FTP server doesn't support our FTP directory browser.", + 'FTPBROWSER_LBL_GOPARENT' => "<up one level>", + 'FTPBROWSER_LBL_INSTRUCTIONS' => 'Click on a directory to navigate into it. Click on OK to select that directory, Cancel to abort the procedure.', + 'FTPBROWSER_LBL_ERROR' => 'An error occurred', + 'SFTP_NO_SSH2' => 'Your web server does not have the SSH2 PHP module, therefore can not connect to SFTP servers.', + 'SFTP_NO_FTP_SUPPORT' => 'Your SSH server does not allow SFTP connections', + 'SFTP_WRONG_USER' => 'Wrong SFTP username or password', + 'SFTP_WRONG_STARTING_DIR' => 'You must supply a valid absolute path', + 'SFTPBROWSER_ERROR_NOACCESS' => "Directory doesn't exist or you don't have enough permissions to access it", + 'SFTP_COULDNT_UPLOAD' => 'Could not upload %s', + 'SFTP_CANT_CREATE_DIR' => 'Could not create directory %s', + 'UI-ROOT' => '<root>', + 'CONFIG_UI_FTPBROWSER_TITLE' => 'FTP Directory Browser', + 'FTP_BROWSE' => 'Browse', + 'BTN_CHECK' => 'Check', + 'BTN_RESET' => 'Reset', + 'BTN_TESTFTPCON' => 'Test FTP connection', + 'BTN_TESTSFTPCON' => 'Test SFTP connection', + 'BTN_GOTOSTART' => 'Start over', + 'FINE_TUNE' => 'Fine tune', + 'BTN_SHOW_FINE_TUNE' => 'Show advanced options (for experts)', + 'MIN_EXEC_TIME' => 'Minimum execution time:', + 'MAX_EXEC_TIME' => 'Maximum execution time:', + 'SECONDS_PER_STEP' => 'seconds per step', + 'EXTRACT_FILES' => 'Extract files', + 'BTN_START' => 'Start', + 'EXTRACTING' => 'Extracting', + 'DO_NOT_CLOSE_EXTRACT' => 'Do not close this window while the extraction is in progress', + 'RESTACLEANUP' => 'Restoration and Clean Up', + 'BTN_RUNINSTALLER' => 'Run the Installer', + 'BTN_CLEANUP' => 'Clean Up', + 'BTN_SITEFE' => 'Visit your site\'s frontend', + 'BTN_SITEBE' => 'Visit your site\'s backend', + 'WARNINGS' => 'Extraction Warnings', + 'ERROR_OCCURED' => 'An error occurred', + 'STEALTH_MODE' => 'Stealth mode', + 'STEALTH_URL' => 'HTML file to show to web visitors', + 'ERR_NOT_A_JPS_FILE' => 'The file is not a JPA archive', + 'ERR_INVALID_JPS_PASSWORD' => 'The password you gave is wrong or the archive is corrupt', + 'JPS_PASSWORD' => 'Archive Password (for JPS files)', + 'INVALID_FILE_HEADER' => 'Invalid header in archive file, part %s, offset %s', + 'NEEDSOMEHELPKS' => 'Want some help to use this tool? Read this first:', + 'QUICKSTART' => 'Quick Start Guide', + 'CANTGETITTOWORK' => 'Can\'t get it to work? Click me!', + 'NOARCHIVESCLICKHERE' => 'No archives detected. Click here for troubleshooting instructions.', + 'POSTRESTORATIONTROUBLESHOOTING' => 'Something not working after the restoration? Click here for troubleshooting instructions.', + 'UPDATE_HEADER' => 'An updated version of Akeeba Kickstart (unknown) is available!', + 'UPDATE_NOTICE' => 'You are advised to always use the latest version of Akeeba Kickstart available. Older versions may be subject to bugs and will not be supported.', + 'UPDATE_DLNOW' => 'Download now', + 'UPDATE_MOREINFO' => 'More information', + 'IGNORE_MOST_ERRORS' => 'Ignore most errors', + 'WRONG_FTP_PATH2' => 'Wrong FTP initial directory - the directory doesn\'t correspond to your site\'s web root', + 'ARCHIVE_DIRECTORY' => 'Archive directory:', + 'RELOAD_ARCHIVES' => 'Reload', + 'CONFIG_UI_SFTPBROWSER_TITLE' => 'SFTP Directory Browser', + 'ERR_COULD_NOT_OPEN_ARCHIVE_PART' => 'Could not open archive part file %s for reading. Check that the file exists, is readable by the web server and is not in a directory made out of reach by chroot, open_basedir restrictions or any other restriction put in place by your host.', + 'RENAME_FILES' => 'Rename server configuration files', + 'RESTORE_PERMISSIONS' => 'Restore file permissions', + ); + + /** + * The array holding the translation keys + * + * @var array + */ + private $strings; + + /** + * The currently detected language (ISO code) + * + * @var string + */ + private $language; + + /* + * Initializes the translation engine + * @return AKText + */ + public function __construct() + { + // Start with the default translation + $this->strings = $this->default_translation; + // Try loading the translation file in English, if it exists + $this->loadTranslation('en-GB'); + // Try loading the translation file in the browser's preferred language, if it exists + $this->getBrowserLanguage(); + if (!is_null($this->language)) + { + $this->loadTranslation(); + } + } + + private function loadTranslation($lang = null) + { + if (defined('KSLANGDIR')) + { + $dirname = KSLANGDIR; + } + else + { + $dirname = KSROOTDIR; + } + $basename = basename(__FILE__, '.php') . '.ini'; + if (empty($lang)) + { + $lang = $this->language; + } + + $translationFilename = $dirname . DIRECTORY_SEPARATOR . $lang . '.' . $basename; + if (!@file_exists($translationFilename) && ($basename != 'kickstart.ini')) + { + $basename = 'kickstart.ini'; + $translationFilename = $dirname . DIRECTORY_SEPARATOR . $lang . '.' . $basename; + } + if (!@file_exists($translationFilename)) + { + return; + } + $temp = self::parse_ini_file($translationFilename, false); + + if (!is_array($this->strings)) + { + $this->strings = array(); + } + if (empty($temp)) + { + $this->strings = array_merge($this->default_translation, $this->strings); + } + else + { + $this->strings = array_merge($this->strings, $temp); + } + } + + /** + * A PHP based INI file parser. + * + * Thanks to asohn ~at~ aircanopy ~dot~ net for posting this handy function on + * the parse_ini_file page on http://gr.php.net/parse_ini_file + * + * @param string $file Filename to process + * @param bool $process_sections True to also process INI sections + * + * @return array An associative array of sections, keys and values + * @access private + */ + public static function parse_ini_file($file, $process_sections = false, $raw_data = false) + { + $process_sections = ($process_sections !== true) ? false : true; + + if (!$raw_data) + { + $ini = @file($file); + } + else + { + $ini = $file; + } + if (count($ini) == 0) + { + return array(); + } + + $sections = array(); + $values = array(); + $result = array(); + $globals = array(); + $i = 0; + if (!empty($ini)) + { + foreach ($ini as $line) + { + $line = trim($line); + $line = str_replace("\t", " ", $line); + + // Comments + if (!preg_match('/^[a-zA-Z0-9[]/', $line)) + { + continue; + } + + // Sections + if ($line[0] == '[') + { + $tmp = explode(']', $line); + $sections[] = trim(substr($tmp[0], 1)); + $i++; + continue; + } + + // Key-value pair + list($key, $value) = explode('=', $line, 2); + $key = trim($key); + $value = trim($value); + if (strstr($value, ";")) + { + $tmp = explode(';', $value); + if (count($tmp) == 2) + { + if ((($value[0] != '"') && ($value[0] != "'")) || + preg_match('/^".*"\s*;/', $value) || preg_match('/^".*;[^"]*$/', $value) || + preg_match("/^'.*'\s*;/", $value) || preg_match("/^'.*;[^']*$/", $value) + ) + { + $value = $tmp[0]; + } + } + else + { + if ($value[0] == '"') + { + $value = preg_replace('/^"(.*)".*/', '$1', $value); + } + elseif ($value[0] == "'") + { + $value = preg_replace("/^'(.*)'.*/", '$1', $value); + } + else + { + $value = $tmp[0]; + } + } + } + $value = trim($value); + $value = trim($value, "'\""); + + if ($i == 0) + { + if (substr($line, -1, 2) == '[]') + { + $globals[$key][] = $value; + } + else + { + $globals[$key] = $value; + } + } + else + { + if (substr($line, -1, 2) == '[]') + { + $values[$i - 1][$key][] = $value; + } + else + { + $values[$i - 1][$key] = $value; + } + } + } + } + + for ($j = 0; $j < $i; $j++) + { + if ($process_sections === true) + { + $result[$sections[$j]] = $values[$j]; + } + else + { + $result[] = $values[$j]; + } + } + + return $result + $globals; + } + + public function getBrowserLanguage() + { + // Detection code from Full Operating system language detection, by Harald Hope + // Retrieved from http://techpatterns.com/downloads/php_language_detection.php + $user_languages = array(); + //check to see if language is set + if (isset($_SERVER["HTTP_ACCEPT_LANGUAGE"])) + { + $languages = strtolower($_SERVER["HTTP_ACCEPT_LANGUAGE"]); + // $languages = ' fr-ch;q=0.3, da, en-us;q=0.8, en;q=0.5, fr;q=0.3'; + // need to remove spaces from strings to avoid error + $languages = str_replace(' ', '', $languages); + $languages = explode(",", $languages); + + foreach ($languages as $language_list) + { + // pull out the language, place languages into array of full and primary + // string structure: + $temp_array = array(); + // slice out the part before ; on first step, the part before - on second, place into array + $temp_array[0] = substr($language_list, 0, strcspn($language_list, ';'));//full language + $temp_array[1] = substr($language_list, 0, 2);// cut out primary language + if ((strlen($temp_array[0]) == 5) && ((substr($temp_array[0], 2, 1) == '-') || (substr($temp_array[0], 2, 1) == '_'))) + { + $langLocation = strtoupper(substr($temp_array[0], 3, 2)); + $temp_array[0] = $temp_array[1] . '-' . $langLocation; + } + //place this array into main $user_languages language array + $user_languages[] = $temp_array; + } + } + else// if no languages found + { + $user_languages[0] = array('', ''); //return blank array. + } + + $this->language = null; + $basename = basename(__FILE__, '.php') . '.ini'; + + // Try to match main language part of the filename, irrespective of the location, e.g. de_DE will do if de_CH doesn't exist. + if (class_exists('AKUtilsLister')) + { + $fs = new AKUtilsLister(); + $iniFiles = $fs->getFiles(KSROOTDIR, '*.' . $basename); + if (empty($iniFiles) && ($basename != 'kickstart.ini')) + { + $basename = 'kickstart.ini'; + $iniFiles = $fs->getFiles(KSROOTDIR, '*.' . $basename); + } + } + else + { + $iniFiles = null; + } + + if (is_array($iniFiles)) + { + foreach ($user_languages as $languageStruct) + { + if (is_null($this->language)) + { + // Get files matching the main lang part + $iniFiles = $fs->getFiles(KSROOTDIR, $languageStruct[1] . '-??.' . $basename); + if (count($iniFiles) > 0) + { + $filename = $iniFiles[0]; + $filename = substr($filename, strlen(KSROOTDIR) + 1); + $this->language = substr($filename, 0, 5); + } + else + { + $this->language = null; + } + } + } + } + + if (is_null($this->language)) + { + // Try to find a full language match + foreach ($user_languages as $languageStruct) + { + if (@file_exists($languageStruct[0] . '.' . $basename) && is_null($this->language)) + { + $this->language = $languageStruct[0]; + } + else + { + + } + } + } + else + { + // Do we have an exact match? + foreach ($user_languages as $languageStruct) + { + if (substr($this->language, 0, strlen($languageStruct[1])) == $languageStruct[1]) + { + if (file_exists($languageStruct[0] . '.' . $basename)) + { + $this->language = $languageStruct[0]; + } + } + } + } + + // Now, scan for full language based on the partial match + + } + + public static function sprintf($key) + { + $text = self::getInstance(); + $args = func_get_args(); + if (count($args) > 0) + { + $args[0] = $text->_($args[0]); + + return @call_user_func_array('sprintf', $args); + } + + return ''; + } + + /** + * Singleton pattern for Language + * + * @return AKText The global AKText instance + */ + public static function &getInstance() + { + static $instance; + + if (!is_object($instance)) + { + $instance = new AKText(); + } + + return $instance; + } + + public static function _($string) + { + $text = self::getInstance(); + + $key = strtoupper($string); + $key = substr($key, 0, 1) == '_' ? substr($key, 1) : $key; + + if (isset ($text->strings[$key])) + { + $string = $text->strings[$key]; + } + else + { + if (defined($string)) + { + $string = constant($string); + } + } + + return $string; + } + + public function dumpLanguage() + { + $out = ''; + foreach ($this->strings as $key => $value) + { + $out .= "$key=$value\n"; + } + + return $out; + } + + public function asJavascript() + { + $out = ''; + foreach ($this->strings as $key => $value) + { + $key = addcslashes($key, '\\\'"'); + $value = addcslashes($value, '\\\'"'); + if (!empty($out)) + { + $out .= ",\n"; + } + $out .= "'$key':\t'$value'"; + } + + return $out; + } + + public function resetTranslation() + { + $this->strings = $this->default_translation; + } + + public function addDefaultLanguageStrings($stringList = array()) + { + if (!is_array($stringList)) + { + return; + } + if (empty($stringList)) + { + return; + } + + $this->strings = array_merge($stringList, $this->strings); + } +} + +/** + * Akeeba Restore + * A JSON-powered JPA, JPS and ZIP archive extraction library + * + * @copyright 2008-2017 Nicholas K. Dionysopoulos / Akeeba Ltd. + * @license GNU GPL v2 or - at your option - any later version + * @package akeebabackup + * @subpackage kickstart + */ + +/** + * The Akeeba Kickstart Factory class + * This class is reponssible for instanciating all Akeeba Kicsktart classes + */ +class AKFactory +{ + /** @var array A list of instantiated objects */ + private $objectlist = array(); + + /** @var array Simple hash data storage */ + private $varlist = array(); + + /** @var self Static instance */ + private static $instance = null; + + /** Private constructor makes sure we can't directly instantiate the class */ + private function __construct() + { + } + + /** + * Gets a serialized snapshot of the Factory for safekeeping (hibernate) + * + * @return string The serialized snapshot of the Factory + */ + public static function serialize() + { + $engine = self::getUnarchiver(); + $engine->shutdown(); + $serialized = serialize(self::getInstance()); + + if (function_exists('base64_encode') && function_exists('base64_decode')) + { + $serialized = base64_encode($serialized); + } + + return $serialized; + } + + /** + * Gets the unarchiver engine + */ + public static function &getUnarchiver($configOverride = null) + { + static $class_name; + + if (!empty($configOverride)) + { + if ($configOverride['reset']) + { + $class_name = null; + } + } + + if (empty($class_name)) + { + $filetype = self::get('kickstart.setup.filetype', null); + + if (empty($filetype)) + { + $filename = self::get('kickstart.setup.sourcefile', null); + $basename = basename($filename); + $baseextension = strtoupper(substr($basename, -3)); + switch ($baseextension) + { + case 'JPA': + $filetype = 'JPA'; + break; + + case 'JPS': + $filetype = 'JPS'; + break; + + case 'ZIP': + $filetype = 'ZIP'; + break; + + default: + die('Invalid archive type or extension in file ' . $filename); + break; + } + } + + $class_name = 'AKUnarchiver' . ucfirst($filetype); + } + + $destdir = self::get('kickstart.setup.destdir', null); + if (empty($destdir)) + { + $destdir = KSROOTDIR; + } + + $object = self::getClassInstance($class_name); + if ($object->getState() == 'init') + { + $sourcePath = self::get('kickstart.setup.sourcepath', ''); + $sourceFile = self::get('kickstart.setup.sourcefile', ''); + + if (!empty($sourcePath)) + { + $sourceFile = rtrim($sourcePath, '/\\') . '/' . $sourceFile; + } + + // Initialize the object –– Any change here MUST be reflected to echoHeadJavascript (default values) + $config = array( + 'filename' => $sourceFile, + 'restore_permissions' => self::get('kickstart.setup.restoreperms', 0), + 'post_proc' => self::get('kickstart.procengine', 'direct'), + 'add_path' => self::get('kickstart.setup.targetpath', $destdir), + 'remove_path' => self::get('kickstart.setup.removepath', ''), + 'rename_files' => self::get('kickstart.setup.renamefiles', array( + '.htaccess' => 'htaccess.bak', 'php.ini' => 'php.ini.bak', 'web.config' => 'web.config.bak', + '.user.ini' => '.user.ini.bak' + )), + 'skip_files' => self::get('kickstart.setup.skipfiles', array( + basename(__FILE__), 'kickstart.php', 'abiautomation.ini', 'htaccess.bak', 'php.ini.bak', + 'cacert.pem' + )), + 'ignoredirectories' => self::get('kickstart.setup.ignoredirectories', array( + 'tmp', 'log', 'logs' + )), + ); + + if (!defined('KICKSTART')) + { + // In restore.php mode we have to exclude the restoration.php files + $moreSkippedFiles = array( + // Akeeba Backup for Joomla! + 'administrator/components/com_akeeba/restoration.php', + // Joomla! Update + 'administrator/components/com_joomlaupdate/restoration.php', + // Akeeba Backup for WordPress + 'wp-content/plugins/akeebabackupwp/app/restoration.php', + 'wp-content/plugins/akeebabackupcorewp/app/restoration.php', + 'wp-content/plugins/akeebabackup/app/restoration.php', + 'wp-content/plugins/akeebabackupwpcore/app/restoration.php', + // Akeeba Solo + 'app/restoration.php', + ); + $config['skip_files'] = array_merge($config['skip_files'], $moreSkippedFiles); + } + + if (!empty($configOverride)) + { + $config = array_merge($config, $configOverride); + } + + $object->setup($config); + } + + return $object; + } + + // ======================================================================== + // Public factory interface + // ======================================================================== + + public static function get($key, $default = null) + { + $self = self::getInstance(); + + if (array_key_exists($key, $self->varlist)) + { + return $self->varlist[$key]; + } + else + { + return $default; + } + } + + /** + * Gets a single, internally used instance of the Factory + * + * @param string $serialized_data [optional] Serialized data to spawn the instance from + * + * @return AKFactory A reference to the unique Factory object instance + */ + protected static function &getInstance($serialized_data = null) + { + if (!is_object(self::$instance) || !is_null($serialized_data)) + { + if (!is_null($serialized_data)) + { + self::$instance = unserialize($serialized_data); + } + else + { + self::$instance = new self(); + } + } + + return self::$instance; + } + + /** + * Internal function which instanciates a class named $class_name. + * The autoloader + * + * @param string $class_name + * + * @return object + */ + protected static function &getClassInstance($class_name) + { + $self = self::getInstance(); + + if (!isset($self->objectlist[$class_name])) + { + $self->objectlist[$class_name] = new $class_name; + } + + return $self->objectlist[$class_name]; + } + + // ======================================================================== + // Public hash data storage interface + // ======================================================================== + + /** + * Regenerates the full Factory state from a serialized snapshot (resume) + * + * @param string $serialized_data The serialized snapshot to resume from + */ + public static function unserialize($serialized_data) + { + if (function_exists('base64_encode') && function_exists('base64_decode')) + { + $serialized_data = base64_decode($serialized_data); + } + self::getInstance($serialized_data); + } + + /** + * Reset the internal factory state, freeing all previously created objects + */ + public static function nuke() + { + self::$instance = null; + } + + // ======================================================================== + // Akeeba Kickstart classes + // ======================================================================== + + public static function set($key, $value) + { + $self = self::getInstance(); + $self->varlist[$key] = $value; + } + + /** + * Gets the post processing engine + * + * @param string $proc_engine + */ + public static function &getPostProc($proc_engine = null) + { + static $class_name; + if (empty($class_name)) + { + if (empty($proc_engine)) + { + $proc_engine = self::get('kickstart.procengine', 'direct'); + } + $class_name = 'AKPostproc' . ucfirst($proc_engine); + } + + return self::getClassInstance($class_name); + } + + /** + * Get the a reference to the Akeeba Engine's timer + * + * @return AKCoreTimer + */ + public static function &getTimer() + { + return self::getClassInstance('AKCoreTimer'); + } + +} + +/** + * Akeeba Restore + * A JSON-powered JPA, JPS and ZIP archive extraction library + * + * @copyright 2008-2017 Nicholas K. Dionysopoulos / Akeeba Ltd. + * @license GNU GPL v2 or - at your option - any later version + * @package akeebabackup + * @subpackage kickstart + */ + +/** + * Interface for AES encryption adapters + */ +interface AKEncryptionAESAdapterInterface +{ + /** + * Decrypts a string. Returns the raw binary ciphertext, zero-padded. + * + * @param string $plainText The plaintext to encrypt + * @param string $key The raw binary key (will be zero-padded or chopped if its size is different than the block size) + * + * @return string The raw encrypted binary string. + */ + public function decrypt($plainText, $key); + + /** + * Returns the encryption block size in bytes + * + * @return int + */ + public function getBlockSize(); + + /** + * Is this adapter supported? + * + * @return bool + */ + public function isSupported(); +} + +/** + * Akeeba Restore + * A JSON-powered JPA, JPS and ZIP archive extraction library + * + * @copyright 2008-2017 Nicholas K. Dionysopoulos / Akeeba Ltd. + * @license GNU GPL v2 or - at your option - any later version + * @package akeebabackup + * @subpackage kickstart + */ + +/** + * Abstract AES encryption class + */ +abstract class AKEncryptionAESAdapterAbstract +{ + /** + * Trims or zero-pads a key / IV + * + * @param string $key The key or IV to treat + * @param int $size The block size of the currently used algorithm + * + * @return null|string Null if $key is null, treated string of $size byte length otherwise + */ + public function resizeKey($key, $size) + { + if (empty($key)) + { + return null; + } + + $keyLength = strlen($key); + + if (function_exists('mb_strlen')) + { + $keyLength = mb_strlen($key, 'ASCII'); + } + + if ($keyLength == $size) + { + return $key; + } + + if ($keyLength > $size) + { + if (function_exists('mb_substr')) + { + return mb_substr($key, 0, $size, 'ASCII'); + } + + return substr($key, 0, $size); + } + + return $key . str_repeat("\0", ($size - $keyLength)); + } + + /** + * Returns null bytes to append to the string so that it's zero padded to the specified block size + * + * @param string $string The binary string which will be zero padded + * @param int $blockSize The block size + * + * @return string The zero bytes to append to the string to zero pad it to $blockSize + */ + protected function getZeroPadding($string, $blockSize) + { + $stringSize = strlen($string); + + if (function_exists('mb_strlen')) + { + $stringSize = mb_strlen($string, 'ASCII'); + } + + if ($stringSize == $blockSize) + { + return ''; + } + + if ($stringSize < $blockSize) + { + return str_repeat("\0", $blockSize - $stringSize); + } + + $paddingBytes = $stringSize % $blockSize; + + return str_repeat("\0", $blockSize - $paddingBytes); + } +} + +/** + * Akeeba Restore + * A JSON-powered JPA, JPS and ZIP archive extraction library + * + * @copyright 2008-2017 Nicholas K. Dionysopoulos / Akeeba Ltd. + * @license GNU GPL v2 or - at your option - any later version + * @package akeebabackup + * @subpackage kickstart + */ + +class Mcrypt extends AKEncryptionAESAdapterAbstract implements AKEncryptionAESAdapterInterface +{ + protected $cipherType = MCRYPT_RIJNDAEL_128; + + protected $cipherMode = MCRYPT_MODE_CBC; + + public function decrypt($cipherText, $key) + { + $iv_size = $this->getBlockSize(); + $key = $this->resizeKey($key, $iv_size); + $iv = substr($cipherText, 0, $iv_size); + $cipherText = substr($cipherText, $iv_size); + $plainText = mcrypt_decrypt($this->cipherType, $key, $cipherText, $this->cipherMode, $iv); + + return $plainText; + } + + public function isSupported() + { + if (!function_exists('mcrypt_get_key_size')) + { + return false; + } + + if (!function_exists('mcrypt_get_iv_size')) + { + return false; + } + + if (!function_exists('mcrypt_create_iv')) + { + return false; + } + + if (!function_exists('mcrypt_encrypt')) + { + return false; + } + + if (!function_exists('mcrypt_decrypt')) + { + return false; + } + + if (!function_exists('mcrypt_list_algorithms')) + { + return false; + } + + if (!function_exists('hash')) + { + return false; + } + + if (!function_exists('hash_algos')) + { + return false; + } + + $algorightms = mcrypt_list_algorithms(); + + if (!in_array('rijndael-128', $algorightms)) + { + return false; + } + + if (!in_array('rijndael-192', $algorightms)) + { + return false; + } + + if (!in_array('rijndael-256', $algorightms)) + { + return false; + } + + $algorightms = hash_algos(); + + if (!in_array('sha256', $algorightms)) + { + return false; + } + + return true; + } + + public function getBlockSize() + { + return mcrypt_get_iv_size($this->cipherType, $this->cipherMode); + } +} + +/** + * Akeeba Restore + * A JSON-powered JPA, JPS and ZIP archive extraction library + * + * @copyright 2008-2017 Nicholas K. Dionysopoulos / Akeeba Ltd. + * @license GNU GPL v2 or - at your option - any later version + * @package akeebabackup + * @subpackage kickstart + */ + +class OpenSSL extends AKEncryptionAESAdapterAbstract implements AKEncryptionAESAdapterInterface +{ + /** + * The OpenSSL options for encryption / decryption + * + * @var int + */ + protected $openSSLOptions = 0; + + /** + * The encryption method to use + * + * @var string + */ + protected $method = 'aes-128-cbc'; + + public function __construct() + { + $this->openSSLOptions = OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING; + } + + public function decrypt($cipherText, $key) + { + $iv_size = $this->getBlockSize(); + $key = $this->resizeKey($key, $iv_size); + $iv = substr($cipherText, 0, $iv_size); + $cipherText = substr($cipherText, $iv_size); + $plainText = openssl_decrypt($cipherText, $this->method, $key, $this->openSSLOptions, $iv); + + return $plainText; + } + + public function isSupported() + { + if (!function_exists('openssl_get_cipher_methods')) + { + return false; + } + + if (!function_exists('openssl_random_pseudo_bytes')) + { + return false; + } + + if (!function_exists('openssl_cipher_iv_length')) + { + return false; + } + + if (!function_exists('openssl_encrypt')) + { + return false; + } + + if (!function_exists('openssl_decrypt')) + { + return false; + } + + if (!function_exists('hash')) + { + return false; + } + + if (!function_exists('hash_algos')) + { + return false; + } + + $algorightms = openssl_get_cipher_methods(); + + if (!in_array('aes-128-cbc', $algorightms)) + { + return false; + } + + $algorightms = hash_algos(); + + if (!in_array('sha256', $algorightms)) + { + return false; + } + + return true; + } + + /** + * @return int + */ + public function getBlockSize() + { + return openssl_cipher_iv_length($this->method); + } +} + +/** + * Akeeba Restore + * A JSON-powered JPA, JPS and ZIP archive extraction library + * + * @copyright 2008-2017 Nicholas K. Dionysopoulos / Akeeba Ltd. + * @license GNU GPL v2 or - at your option - any later version + * @package akeebabackup + * @subpackage kickstart + */ + +/** + * AES implementation in PHP (c) Chris Veness 2005-2016. + * Right to use and adapt is granted for under a simple creative commons attribution + * licence. No warranty of any form is offered. + * + * Heavily modified for Akeeba Backup by Nicholas K. Dionysopoulos + * Also added AES-128 CBC mode (with mcrypt and OpenSSL) on top of AES CTR + */ +class AKEncryptionAES +{ + // Sbox is pre-computed multiplicative inverse in GF(2^8) used in SubBytes and KeyExpansion [�5.1.1] + protected static $Sbox = + array(0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, + 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, + 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, + 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, + 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, + 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, + 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, + 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, + 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, + 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, + 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, + 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, + 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, + 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, + 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, + 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16); + + // Rcon is Round Constant used for the Key Expansion [1st col is 2^(r-1) in GF(2^8)] [�5.2] + protected static $Rcon = array( + array(0x00, 0x00, 0x00, 0x00), + array(0x01, 0x00, 0x00, 0x00), + array(0x02, 0x00, 0x00, 0x00), + array(0x04, 0x00, 0x00, 0x00), + array(0x08, 0x00, 0x00, 0x00), + array(0x10, 0x00, 0x00, 0x00), + array(0x20, 0x00, 0x00, 0x00), + array(0x40, 0x00, 0x00, 0x00), + array(0x80, 0x00, 0x00, 0x00), + array(0x1b, 0x00, 0x00, 0x00), + array(0x36, 0x00, 0x00, 0x00)); + + protected static $passwords = array(); + + /** + * The algorithm to use for PBKDF2. Must be a supported hash_hmac algorithm. Default: sha1 + * + * @var string + */ + private static $pbkdf2Algorithm = 'sha1'; + + /** + * Number of iterations to use for PBKDF2 + * + * @var int + */ + private static $pbkdf2Iterations = 1000; + + /** + * Should we use a static salt for PBKDF2? + * + * @var int + */ + private static $pbkdf2UseStaticSalt = 0; + + /** + * The static salt to use for PBKDF2 + * + * @var string + */ + private static $pbkdf2StaticSalt = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; + + /** + * Encrypt a text using AES encryption in Counter mode of operation + * - see http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf + * + * Unicode multi-byte character safe + * + * @param string $plaintext Source text to be encrypted + * @param string $password The password to use to generate a key + * @param int $nBits Number of bits to be used in the key (128, 192, or 256) + * + * @return string Encrypted text + */ + public static function AESEncryptCtr($plaintext, $password, $nBits) + { + $blockSize = 16; // block size fixed at 16 bytes / 128 bits (Nb=4) for AES + if (!($nBits == 128 || $nBits == 192 || $nBits == 256)) + { + return ''; + } // standard allows 128/192/256 bit keys + // note PHP (5) gives us plaintext and password in UTF8 encoding! + + // use AES itself to encrypt password to get cipher key (using plain password as source for + // key expansion) - gives us well encrypted key + $nBytes = $nBits / 8; // no bytes in key + $pwBytes = array(); + for ($i = 0; $i < $nBytes; $i++) + { + $pwBytes[$i] = ord(substr($password, $i, 1)) & 0xff; + } + $key = self::Cipher($pwBytes, self::KeyExpansion($pwBytes)); + $key = array_merge($key, array_slice($key, 0, $nBytes - 16)); // expand key to 16/24/32 bytes long + + // initialise counter block (NIST SP800-38A �B.2): millisecond time-stamp for nonce in + // 1st 8 bytes, block counter in 2nd 8 bytes + $counterBlock = array(); + $nonce = floor(microtime(true) * 1000); // timestamp: milliseconds since 1-Jan-1970 + $nonceSec = floor($nonce / 1000); + $nonceMs = $nonce % 1000; + // encode nonce with seconds in 1st 4 bytes, and (repeated) ms part filling 2nd 4 bytes + for ($i = 0; $i < 4; $i++) + { + $counterBlock[$i] = self::urs($nonceSec, $i * 8) & 0xff; + } + for ($i = 0; $i < 4; $i++) + { + $counterBlock[$i + 4] = $nonceMs & 0xff; + } + // and convert it to a string to go on the front of the ciphertext + $ctrTxt = ''; + for ($i = 0; $i < 8; $i++) + { + $ctrTxt .= chr($counterBlock[$i]); + } + + // generate key schedule - an expansion of the key into distinct Key Rounds for each round + $keySchedule = self::KeyExpansion($key); + + $blockCount = ceil(strlen($plaintext) / $blockSize); + $ciphertxt = array(); // ciphertext as array of strings + + for ($b = 0; $b < $blockCount; $b++) + { + // set counter (block #) in last 8 bytes of counter block (leaving nonce in 1st 8 bytes) + // done in two stages for 32-bit ops: using two words allows us to go past 2^32 blocks (68GB) + for ($c = 0; $c < 4; $c++) + { + $counterBlock[15 - $c] = self::urs($b, $c * 8) & 0xff; + } + for ($c = 0; $c < 4; $c++) + { + $counterBlock[15 - $c - 4] = self::urs($b / 0x100000000, $c * 8); + } + + $cipherCntr = self::Cipher($counterBlock, $keySchedule); // -- encrypt counter block -- + + // block size is reduced on final block + $blockLength = $b < $blockCount - 1 ? $blockSize : (strlen($plaintext) - 1) % $blockSize + 1; + $cipherByte = array(); + + for ($i = 0; $i < $blockLength; $i++) + { // -- xor plaintext with ciphered counter byte-by-byte -- + $cipherByte[$i] = $cipherCntr[$i] ^ ord(substr($plaintext, $b * $blockSize + $i, 1)); + $cipherByte[$i] = chr($cipherByte[$i]); + } + $ciphertxt[$b] = implode('', $cipherByte); // escape troublesome characters in ciphertext + } + + // implode is more efficient than repeated string concatenation + $ciphertext = $ctrTxt . implode('', $ciphertxt); + $ciphertext = base64_encode($ciphertext); + + return $ciphertext; + } + + /** + * AES Cipher function: encrypt 'input' with Rijndael algorithm + * + * @param array $input Message as byte-array (16 bytes) + * @param array $w key schedule as 2D byte-array (Nr+1 x Nb bytes) - + * generated from the cipher key by KeyExpansion() + * + * @return string Ciphertext as byte-array (16 bytes) + */ + protected static function Cipher($input, $w) + { // main Cipher function [�5.1] + $Nb = 4; // block size (in words): no of columns in state (fixed at 4 for AES) + $Nr = count($w) / $Nb - 1; // no of rounds: 10/12/14 for 128/192/256-bit keys + + $state = array(); // initialise 4xNb byte-array 'state' with input [�3.4] + for ($i = 0; $i < 4 * $Nb; $i++) + { + $state[$i % 4][floor($i / 4)] = $input[$i]; + } + + $state = self::AddRoundKey($state, $w, 0, $Nb); + + for ($round = 1; $round < $Nr; $round++) + { // apply Nr rounds + $state = self::SubBytes($state, $Nb); + $state = self::ShiftRows($state, $Nb); + $state = self::MixColumns($state); + $state = self::AddRoundKey($state, $w, $round, $Nb); + } + + $state = self::SubBytes($state, $Nb); + $state = self::ShiftRows($state, $Nb); + $state = self::AddRoundKey($state, $w, $Nr, $Nb); + + $output = array(4 * $Nb); // convert state to 1-d array before returning [�3.4] + for ($i = 0; $i < 4 * $Nb; $i++) + { + $output[$i] = $state[$i % 4][floor($i / 4)]; + } + + return $output; + } + + protected static function AddRoundKey($state, $w, $rnd, $Nb) + { // xor Round Key into state S [�5.1.4] + for ($r = 0; $r < 4; $r++) + { + for ($c = 0; $c < $Nb; $c++) + { + $state[$r][$c] ^= $w[$rnd * 4 + $c][$r]; + } + } + + return $state; + } + + protected static function SubBytes($s, $Nb) + { // apply SBox to state S [�5.1.1] + for ($r = 0; $r < 4; $r++) + { + for ($c = 0; $c < $Nb; $c++) + { + $s[$r][$c] = self::$Sbox[$s[$r][$c]]; + } + } + + return $s; + } + + protected static function ShiftRows($s, $Nb) + { // shift row r of state S left by r bytes [�5.1.2] + $t = array(4); + for ($r = 1; $r < 4; $r++) + { + for ($c = 0; $c < 4; $c++) + { + $t[$c] = $s[$r][($c + $r) % $Nb]; + } // shift into temp copy + for ($c = 0; $c < 4; $c++) + { + $s[$r][$c] = $t[$c]; + } // and copy back + } // note that this will work for Nb=4,5,6, but not 7,8 (always 4 for AES): + return $s; // see fp.gladman.plus.com/cryptography_technology/rijndael/aes.spec.311.pdf + } + + protected static function MixColumns($s) + { + // combine bytes of each col of state S [�5.1.3] + for ($c = 0; $c < 4; $c++) + { + $a = array(4); // 'a' is a copy of the current column from 's' + $b = array(4); // 'b' is a�{02} in GF(2^8) + + for ($i = 0; $i < 4; $i++) + { + $a[$i] = $s[$i][$c]; + $b[$i] = $s[$i][$c] & 0x80 ? $s[$i][$c] << 1 ^ 0x011b : $s[$i][$c] << 1; + } + + // a[n] ^ b[n] is a�{03} in GF(2^8) + $s[0][$c] = $b[0] ^ $a[1] ^ $b[1] ^ $a[2] ^ $a[3]; // 2*a0 + 3*a1 + a2 + a3 + $s[1][$c] = $a[0] ^ $b[1] ^ $a[2] ^ $b[2] ^ $a[3]; // a0 * 2*a1 + 3*a2 + a3 + $s[2][$c] = $a[0] ^ $a[1] ^ $b[2] ^ $a[3] ^ $b[3]; // a0 + a1 + 2*a2 + 3*a3 + $s[3][$c] = $a[0] ^ $b[0] ^ $a[1] ^ $a[2] ^ $b[3]; // 3*a0 + a1 + a2 + 2*a3 + } + + return $s; + } + + /** + * Key expansion for Rijndael Cipher(): performs key expansion on cipher key + * to generate a key schedule + * + * @param array $key Cipher key byte-array (16 bytes) + * + * @return array Key schedule as 2D byte-array (Nr+1 x Nb bytes) + */ + protected static function KeyExpansion($key) + { + // generate Key Schedule from Cipher Key [�5.2] + + // block size (in words): no of columns in state (fixed at 4 for AES) + $Nb = 4; + // key length (in words): 4/6/8 for 128/192/256-bit keys + $Nk = (int) (count($key) / 4); + // no of rounds: 10/12/14 for 128/192/256-bit keys + $Nr = $Nk + 6; + + $w = array(); + $temp = array(); + + for ($i = 0; $i < $Nk; $i++) + { + $r = array($key[4 * $i], $key[4 * $i + 1], $key[4 * $i + 2], $key[4 * $i + 3]); + $w[$i] = $r; + } + + for ($i = $Nk; $i < ($Nb * ($Nr + 1)); $i++) + { + $w[$i] = array(); + for ($t = 0; $t < 4; $t++) + { + $temp[$t] = $w[$i - 1][$t]; + } + if ($i % $Nk == 0) + { + $temp = self::SubWord(self::RotWord($temp)); + for ($t = 0; $t < 4; $t++) + { + $rConIndex = (int) ($i / $Nk); + $temp[$t] ^= self::$Rcon[$rConIndex][$t]; + } + } + else if ($Nk > 6 && $i % $Nk == 4) + { + $temp = self::SubWord($temp); + } + for ($t = 0; $t < 4; $t++) + { + $w[$i][$t] = $w[$i - $Nk][$t] ^ $temp[$t]; + } + } + + return $w; + } + + protected static function SubWord($w) + { // apply SBox to 4-byte word w + for ($i = 0; $i < 4; $i++) + { + $w[$i] = self::$Sbox[$w[$i]]; + } + + return $w; + } + + /* + * Unsigned right shift function, since PHP has neither >>> operator nor unsigned ints + * + * @param a number to be shifted (32-bit integer) + * @param b number of bits to shift a to the right (0..31) + * @return a right-shifted and zero-filled by b bits + */ + + protected static function RotWord($w) + { // rotate 4-byte word w left by one byte + $tmp = $w[0]; + for ($i = 0; $i < 3; $i++) + { + $w[$i] = $w[$i + 1]; + } + $w[3] = $tmp; + + return $w; + } + + protected static function urs($a, $b) + { + $a &= 0xffffffff; + $b &= 0x1f; // (bounds check) + if ($a & 0x80000000 && $b > 0) + { // if left-most bit set + $a = ($a >> 1) & 0x7fffffff; // right-shift one bit & clear left-most bit + $a = $a >> ($b - 1); // remaining right-shifts + } + else + { // otherwise + $a = ($a >> $b); // use normal right-shift + } + + return $a; + } + + /** + * Decrypt a text encrypted by AES in counter mode of operation + * + * @param string $ciphertext Source text to be decrypted + * @param string $password The password to use to generate a key + * @param int $nBits Number of bits to be used in the key (128, 192, or 256) + * + * @return string Decrypted text + */ + public static function AESDecryptCtr($ciphertext, $password, $nBits) + { + $blockSize = 16; // block size fixed at 16 bytes / 128 bits (Nb=4) for AES + + if (!($nBits == 128 || $nBits == 192 || $nBits == 256)) + { + return ''; + } + + // standard allows 128/192/256 bit keys + $ciphertext = base64_decode($ciphertext); + + // use AES to encrypt password (mirroring encrypt routine) + $nBytes = $nBits / 8; // no bytes in key + $pwBytes = array(); + + for ($i = 0; $i < $nBytes; $i++) + { + $pwBytes[$i] = ord(substr($password, $i, 1)) & 0xff; + } + + $key = self::Cipher($pwBytes, self::KeyExpansion($pwBytes)); + $key = array_merge($key, array_slice($key, 0, $nBytes - 16)); // expand key to 16/24/32 bytes long + + // recover nonce from 1st element of ciphertext + $counterBlock = array(); + $ctrTxt = substr($ciphertext, 0, 8); + + for ($i = 0; $i < 8; $i++) + { + $counterBlock[$i] = ord(substr($ctrTxt, $i, 1)); + } + + // generate key schedule + $keySchedule = self::KeyExpansion($key); + + // separate ciphertext into blocks (skipping past initial 8 bytes) + $nBlocks = ceil((strlen($ciphertext) - 8) / $blockSize); + $ct = array(); + + for ($b = 0; $b < $nBlocks; $b++) + { + $ct[$b] = substr($ciphertext, 8 + $b * $blockSize, 16); + } + + $ciphertext = $ct; // ciphertext is now array of block-length strings + + // plaintext will get generated block-by-block into array of block-length strings + $plaintxt = array(); + + for ($b = 0; $b < $nBlocks; $b++) + { + // set counter (block #) in last 8 bytes of counter block (leaving nonce in 1st 8 bytes) + for ($c = 0; $c < 4; $c++) + { + $counterBlock[15 - $c] = self::urs($b, $c * 8) & 0xff; + } + + for ($c = 0; $c < 4; $c++) + { + $counterBlock[15 - $c - 4] = self::urs(($b + 1) / 0x100000000 - 1, $c * 8) & 0xff; + } + + $cipherCntr = self::Cipher($counterBlock, $keySchedule); // encrypt counter block + + $plaintxtByte = array(); + + for ($i = 0; $i < strlen($ciphertext[$b]); $i++) + { + // -- xor plaintext with ciphered counter byte-by-byte -- + $plaintxtByte[$i] = $cipherCntr[$i] ^ ord(substr($ciphertext[$b], $i, 1)); + $plaintxtByte[$i] = chr($plaintxtByte[$i]); + + } + + $plaintxt[$b] = implode('', $plaintxtByte); + } + + // join array of blocks into single plaintext string + $plaintext = implode('', $plaintxt); + + return $plaintext; + } + + /** + * AES decryption in CBC mode. This is the standard mode (the CTR methods + * actually use Rijndael-128 in CTR mode, which - technically - isn't AES). + * + * It supports AES-128 only. It assumes that the last 4 bytes + * contain a little-endian unsigned long integer representing the unpadded + * data length. + * + * @since 3.0.1 + * @author Nicholas K. Dionysopoulos + * + * @param string $ciphertext The data to encrypt + * @param string $password Encryption password + * + * @return string The plaintext + */ + public static function AESDecryptCBC($ciphertext, $password) + { + $adapter = self::getAdapter(); + + if (!$adapter->isSupported()) + { + return false; + } + + // Read the data size + $data_size = unpack('V', substr($ciphertext, -4)); + + // Do I have a PBKDF2 salt? + $salt = substr($ciphertext, -92, 68); + $rightStringLimit = -4; + + $params = self::getKeyDerivationParameters(); + $keySizeBytes = $params['keySize']; + $algorithm = $params['algorithm']; + $iterations = $params['iterations']; + $useStaticSalt = $params['useStaticSalt']; + + if (substr($salt, 0, 4) == 'JPST') + { + // We have a stored salt. Retrieve it and tell decrypt to process the string minus the last 44 bytes + // (4 bytes for JPST, 16 bytes for the salt, 4 bytes for JPIV, 16 bytes for the IV, 4 bytes for the + // uncompressed string length - note that using PBKDF2 means we're also using a randomized IV per the + // format specification). + $salt = substr($salt, 4); + $rightStringLimit -= 68; + + $key = self::pbkdf2($password, $salt, $algorithm, $iterations, $keySizeBytes); + } + elseif ($useStaticSalt) + { + // We have a static salt. Use it for PBKDF2. + $key = self::getStaticSaltExpandedKey($password); + } + else + { + // Get the expanded key from the password. THIS USES THE OLD, INSECURE METHOD. + $key = self::expandKey($password); + } + + // Try to get the IV from the data + $iv = substr($ciphertext, -24, 20); + + if (substr($iv, 0, 4) == 'JPIV') + { + // We have a stored IV. Retrieve it and tell mdecrypt to process the string minus the last 24 bytes + // (4 bytes for JPIV, 16 bytes for the IV, 4 bytes for the uncompressed string length) + $iv = substr($iv, 4); + $rightStringLimit -= 20; + } + else + { + // No stored IV. Do it the dumb way. + $iv = self::createTheWrongIV($password); + } + + // Decrypt + $plaintext = $adapter->decrypt($iv . substr($ciphertext, 0, $rightStringLimit), $key); + + // Trim padding, if necessary + if (strlen($plaintext) > $data_size) + { + $plaintext = substr($plaintext, 0, $data_size); + } + + return $plaintext; + } + + /** + * That's the old way of creating an IV that's definitely not cryptographically sound. + * + * DO NOT USE, EVER, UNLESS YOU WANT TO DECRYPT LEGACY DATA + * + * @param string $password The raw password from which we create an IV in a super bozo way + * + * @return string A 16-byte IV string + */ + public static function createTheWrongIV($password) + { + static $ivs = array(); + + $key = md5($password); + + if (!isset($ivs[$key])) + { + $nBytes = 16; // AES uses a 128 -bit (16 byte) block size, hence the IV size is always 16 bytes + $pwBytes = array(); + for ($i = 0; $i < $nBytes; $i++) + { + $pwBytes[$i] = ord(substr($password, $i, 1)) & 0xff; + } + $iv = self::Cipher($pwBytes, self::KeyExpansion($pwBytes)); + $newIV = ''; + foreach ($iv as $int) + { + $newIV .= chr($int); + } + + $ivs[$key] = $newIV; + } + + return $ivs[$key]; + } + + /** + * Expand the password to an appropriate 128-bit encryption key + * + * @param string $password + * + * @return string + * + * @since 5.2.0 + * @author Nicholas K. Dionysopoulos + */ + public static function expandKey($password) + { + // Try to fetch cached key or create it if it doesn't exist + $nBits = 128; + $lookupKey = md5($password . '-' . $nBits); + + if (array_key_exists($lookupKey, self::$passwords)) + { + $key = self::$passwords[$lookupKey]; + + return $key; + } + + // use AES itself to encrypt password to get cipher key (using plain password as source for + // key expansion) - gives us well encrypted key. + $nBytes = $nBits / 8; // Number of bytes in key + $pwBytes = array(); + + for ($i = 0; $i < $nBytes; $i++) + { + $pwBytes[$i] = ord(substr($password, $i, 1)) & 0xff; + } + + $key = self::Cipher($pwBytes, self::KeyExpansion($pwBytes)); + $key = array_merge($key, array_slice($key, 0, $nBytes - 16)); // expand key to 16/24/32 bytes long + $newKey = ''; + + foreach ($key as $int) + { + $newKey .= chr($int); + } + + $key = $newKey; + + self::$passwords[$lookupKey] = $key; + + return $key; + } + + /** + * Returns the correct AES-128 CBC encryption adapter + * + * @return AKEncryptionAESAdapterInterface + * + * @since 5.2.0 + * @author Nicholas K. Dionysopoulos + */ + public static function getAdapter() + { + static $adapter = null; + + if (is_object($adapter) && ($adapter instanceof AKEncryptionAESAdapterInterface)) + { + return $adapter; + } + + $adapter = new OpenSSL(); + + if (!$adapter->isSupported()) + { + $adapter = new Mcrypt(); + } + + return $adapter; + } + + /** + * @return string + */ + public static function getPbkdf2Algorithm() + { + return self::$pbkdf2Algorithm; + } + + /** + * @param string $pbkdf2Algorithm + * @return void + */ + public static function setPbkdf2Algorithm($pbkdf2Algorithm) + { + self::$pbkdf2Algorithm = $pbkdf2Algorithm; + } + + /** + * @return int + */ + public static function getPbkdf2Iterations() + { + return self::$pbkdf2Iterations; + } + + /** + * @param int $pbkdf2Iterations + * @return void + */ + public static function setPbkdf2Iterations($pbkdf2Iterations) + { + self::$pbkdf2Iterations = $pbkdf2Iterations; + } + + /** + * @return int + */ + public static function getPbkdf2UseStaticSalt() + { + return self::$pbkdf2UseStaticSalt; + } + + /** + * @param int $pbkdf2UseStaticSalt + * @return void + */ + public static function setPbkdf2UseStaticSalt($pbkdf2UseStaticSalt) + { + self::$pbkdf2UseStaticSalt = $pbkdf2UseStaticSalt; + } + + /** + * @return string + */ + public static function getPbkdf2StaticSalt() + { + return self::$pbkdf2StaticSalt; + } + + /** + * @param string $pbkdf2StaticSalt + * @return void + */ + public static function setPbkdf2StaticSalt($pbkdf2StaticSalt) + { + self::$pbkdf2StaticSalt = $pbkdf2StaticSalt; + } + + /** + * Get the parameters fed into PBKDF2 to expand the user password into an encryption key. These are the static + * parameters (key size, hashing algorithm and number of iterations). A new salt is used for each encryption block + * to minimize the risk of attacks against the password. + * + * @return array + */ + public static function getKeyDerivationParameters() + { + return array( + 'keySize' => 16, + 'algorithm' => self::$pbkdf2Algorithm, + 'iterations' => self::$pbkdf2Iterations, + 'useStaticSalt' => self::$pbkdf2UseStaticSalt, + 'staticSalt' => self::$pbkdf2StaticSalt, + ); + } + + /** + * PBKDF2 key derivation function as defined by RSA's PKCS #5: https://www.ietf.org/rfc/rfc2898.txt + * + * Test vectors can be found here: https://www.ietf.org/rfc/rfc6070.txt + * + * This implementation of PBKDF2 was originally created by https://defuse.ca + * With improvements by http://www.variations-of-shadow.com + * Modified for Akeeba Engine by Akeeba Ltd (removed unnecessary checks to make it faster) + * + * @param string $password The password. + * @param string $salt A salt that is unique to the password. + * @param string $algorithm The hash algorithm to use. Default is sha1. + * @param int $count Iteration count. Higher is better, but slower. Default: 1000. + * @param int $key_length The length of the derived key in bytes. + * + * @return string A string of $key_length bytes + */ + public static function pbkdf2($password, $salt, $algorithm = 'sha1', $count = 1000, $key_length = 16) + { + if (function_exists("hash_pbkdf2")) + { + return hash_pbkdf2($algorithm, $password, $salt, $count, $key_length, true); + } + + $hash_length = akstringlen(hash($algorithm, "", true)); + $block_count = ceil($key_length / $hash_length); + + $output = ""; + + for ($i = 1; $i <= $block_count; $i++) + { + // $i encoded as 4 bytes, big endian. + $last = $salt . pack("N", $i); + + // First iteration + $xorResult = hash_hmac($algorithm, $last, $password, true); + $last = $xorResult; + + // Perform the other $count - 1 iterations + for ($j = 1; $j < $count; $j++) + { + $last = hash_hmac($algorithm, $last, $password, true); + $xorResult ^= $last; + } + + $output .= $xorResult; + } + + return aksubstr($output, 0, $key_length); + } + + /** + * Get the expanded key from the user supplied password using a static salt. The results are cached for performance + * reasons. + * + * @param string $password The user-supplied password, UTF-8 encoded. + * + * @return string The expanded key + */ + private static function getStaticSaltExpandedKey($password) + { + $params = self::getKeyDerivationParameters(); + $keySizeBytes = $params['keySize']; + $algorithm = $params['algorithm']; + $iterations = $params['iterations']; + $staticSalt = $params['staticSalt']; + + $lookupKey = "PBKDF2-$algorithm-$iterations-" . md5($password . $staticSalt); + + if (!array_key_exists($lookupKey, self::$passwords)) + { + self::$passwords[$lookupKey] = self::pbkdf2($password, $staticSalt, $algorithm, $iterations, $keySizeBytes); + } + + return self::$passwords[$lookupKey]; + } + +} + +/** + * Akeeba Restore + * A JSON-powered JPA, JPS and ZIP archive extraction library + * + * @copyright 2008-2017 Nicholas K. Dionysopoulos / Akeeba Ltd. + * @license GNU GPL v2 or - at your option - any later version + * @package akeebabackup + * @subpackage kickstart + */ + +/** + * The Master Setup will read the configuration parameters from restoration.php or + * the JSON-encoded "configuration" input variable and return the status. + * + * @return bool True if the master configuration was applied to the Factory object + */ +function masterSetup() +{ + // ------------------------------------------------------------ + // 1. Import basic setup parameters + // ------------------------------------------------------------ + + $ini_data = null; + + // In restore.php mode, require restoration.php or fail + if (!defined('KICKSTART')) + { + // This is the standalone mode, used by Akeeba Backup Professional. It looks for a restoration.php + // file to perform its magic. If the file is not there, we will abort. + $setupFile = 'restoration.php'; + + if (!file_exists($setupFile)) + { + AKFactory::set('kickstart.enabled', false); + + return false; + } + + // Load restoration.php. It creates a global variable named $restoration_setup + require_once $setupFile; + + $ini_data = $restoration_setup; + + if (empty($ini_data)) + { + // No parameters fetched. Darn, how am I supposed to work like that?! + AKFactory::set('kickstart.enabled', false); + + return false; + } + + AKFactory::set('kickstart.enabled', true); + } + else + { + // Maybe we have $restoration_setup defined in the head of kickstart.php + global $restoration_setup; + + if (!empty($restoration_setup) && !is_array($restoration_setup)) + { + $ini_data = AKText::parse_ini_file($restoration_setup, false, true); + } + elseif (is_array($restoration_setup)) + { + $ini_data = $restoration_setup; + } + } + + // Import any data from $restoration_setup + if (!empty($ini_data)) + { + foreach ($ini_data as $key => $value) + { + AKFactory::set($key, $value); + } + AKFactory::set('kickstart.enabled', true); + } + + // Reinitialize $ini_data + $ini_data = null; + + // ------------------------------------------------------------ + // 2. Explode JSON parameters into $_REQUEST scope + // ------------------------------------------------------------ + + // Detect a JSON string in the request variable and store it. + $json = getQueryParam('json', null); + + // Remove everything from the request, post and get arrays + if (!empty($_REQUEST)) + { + foreach ($_REQUEST as $key => $value) + { + unset($_REQUEST[$key]); + } + } + + if (!empty($_POST)) + { + foreach ($_POST as $key => $value) + { + unset($_POST[$key]); + } + } + + if (!empty($_GET)) + { + foreach ($_GET as $key => $value) + { + unset($_GET[$key]); + } + } + + // Decrypt a possibly encrypted JSON string + $password = AKFactory::get('kickstart.security.password', null); + + if (!empty($json)) + { + if (!empty($password)) + { + $json = AKEncryptionAES::AESDecryptCtr($json, $password, 128); + + if (empty($json)) + { + die('###{"status":false,"message":"Invalid login"}###'); + } + } + + // Get the raw data + $raw = json_decode($json, true); + + if (!empty($password) && (empty($raw))) + { + die('###{"status":false,"message":"Invalid login"}###'); + } + + // Pass all JSON data to the request array + if (!empty($raw)) + { + foreach ($raw as $key => $value) + { + $_REQUEST[$key] = $value; + } + } + } + elseif (!empty($password)) + { + die('###{"status":false,"message":"Invalid login"}###'); + } + + // ------------------------------------------------------------ + // 3. Try the "factory" variable + // ------------------------------------------------------------ + // A "factory" variable will override all other settings. + $serialized = getQueryParam('factory', null); + + if (!is_null($serialized)) + { + // Get the serialized factory + AKFactory::unserialize($serialized); + AKFactory::set('kickstart.enabled', true); + + return true; + } + + // ------------------------------------------------------------ + // 4. Try the configuration variable for Kickstart + // ------------------------------------------------------------ + if (defined('KICKSTART')) + { + $configuration = getQueryParam('configuration'); + + if (!is_null($configuration)) + { + // Let's decode the configuration from JSON to array + $ini_data = json_decode($configuration, true); + } + else + { + // Neither exists. Enable Kickstart's interface anyway. + $ini_data = array('kickstart.enabled' => true); + } + + // Import any INI data we might have from other sources + if (!empty($ini_data)) + { + foreach ($ini_data as $key => $value) + { + AKFactory::set($key, $value); + } + + AKFactory::set('kickstart.enabled', true); + + return true; + } + } +} + +/** + * Akeeba Restore + * A JSON-powered JPA, JPS and ZIP archive extraction library + * + * @copyright 2008-2017 Nicholas K. Dionysopoulos / Akeeba Ltd. + * @license GNU GPL v2 or - at your option - any later version + * @package akeebabackup + * @subpackage kickstart + */ + +// Mini-controller for restore.php +if (!defined('KICKSTART')) +{ + // The observer class, used to report number of files and bytes processed + class RestorationObserver extends AKAbstractPartObserver + { + public $compressedTotal = 0; + public $uncompressedTotal = 0; + public $filesProcessed = 0; + + public function update($object, $message) + { + if (!is_object($message)) + { + return; + } + + if (!array_key_exists('type', get_object_vars($message))) + { + return; + } + + if ($message->type == 'startfile') + { + $this->filesProcessed++; + $this->compressedTotal += $message->content->compressed; + $this->uncompressedTotal += $message->content->uncompressed; + } + } + + public function __toString() + { + return __CLASS__; + } + + } + + // Import configuration + masterSetup(); + + $retArray = array( + 'status' => true, + 'message' => null + ); + + $enabled = AKFactory::get('kickstart.enabled', false); + + if ($enabled) + { + $task = getQueryParam('task'); + + switch ($task) + { + case 'ping': + // ping task - realy does nothing! + $timer = AKFactory::getTimer(); + $timer->enforce_min_exec_time(); + break; + + /** + * There are two separate steps here since we were using an inefficient restoration intialization method in + * the past. Now both startRestore and stepRestore are identical. The difference in behavior depends + * exclusively on the calling Javascript. If no serialized factory was passed in the request then we start a + * new restoration. If a serialized factory was passed in the request then the restoration is resumed. For + * this reason we should NEVER call AKFactory::nuke() in startRestore anymore: that would simply reset the + * extraction engine configuration which was done in masterSetup() leading to an error about the file being + * invalid (since no file is found). + */ + case 'startRestore': + case 'stepRestore': + $engine = AKFactory::getUnarchiver(); // Get the engine + $observer = new RestorationObserver(); // Create a new observer + $engine->attach($observer); // Attach the observer + $engine->tick(); + $ret = $engine->getStatusArray(); + + if ($ret['Error'] != '') + { + $retArray['status'] = false; + $retArray['done'] = true; + $retArray['message'] = $ret['Error']; + } + elseif (!$ret['HasRun']) + { + $retArray['files'] = $observer->filesProcessed; + $retArray['bytesIn'] = $observer->compressedTotal; + $retArray['bytesOut'] = $observer->uncompressedTotal; + $retArray['status'] = true; + $retArray['done'] = true; + } + else + { + $retArray['files'] = $observer->filesProcessed; + $retArray['bytesIn'] = $observer->compressedTotal; + $retArray['bytesOut'] = $observer->uncompressedTotal; + $retArray['status'] = true; + $retArray['done'] = false; + $retArray['factory'] = AKFactory::serialize(); + } + break; + + case 'finalizeRestore': + $root = AKFactory::get('kickstart.setup.destdir'); + // Remove the installation directory + recursive_remove_directory($root . '/installation'); + + $postproc = AKFactory::getPostProc(); + + /** + * Should I rename the htaccess.bak and web.config.bak files back to their live filenames...? + */ + $renameFiles = AKFactory::get('kickstart.setup.postrenamefiles', true); + + if ($renameFiles) + { + // Rename htaccess.bak to .htaccess + if (file_exists($root . '/htaccess.bak')) + { + if (file_exists($root . '/.htaccess')) + { + $postproc->unlink($root . '/.htaccess'); + } + $postproc->rename($root . '/htaccess.bak', $root . '/.htaccess'); + } + + // Rename htaccess.bak to .htaccess + if (file_exists($root . '/web.config.bak')) + { + if (file_exists($root . '/web.config')) + { + $postproc->unlink($root . '/web.config'); + } + $postproc->rename($root . '/web.config.bak', $root . '/web.config'); + } + } + + // Remove restoration.php + $basepath = KSROOTDIR; + $basepath = rtrim(str_replace('\\', '/', $basepath), '/'); + if (!empty($basepath)) + { + $basepath .= '/'; + } + $postproc->unlink($basepath . 'restoration.php'); + + // Import a custom finalisation file + $filename = dirname(__FILE__) . '/restore_finalisation.php'; + if (file_exists($filename)) + { + // opcode cache busting before including the filename + if (function_exists('opcache_invalidate')) + { + opcache_invalidate($filename); + } + if (function_exists('apc_compile_file')) + { + apc_compile_file($filename); + } + if (function_exists('wincache_refresh_if_changed')) + { + wincache_refresh_if_changed(array($filename)); + } + if (function_exists('xcache_asm')) + { + xcache_asm($filename); + } + include_once $filename; + } + + // Run a custom finalisation script + if (function_exists('finalizeRestore')) + { + finalizeRestore($root, $basepath); + } + break; + + default: + // Invalid task! + $enabled = false; + break; + } + } + + // Maybe we weren't authorized or the task was invalid? + if (!$enabled) + { + // Maybe the user failed to enter any information + $retArray['status'] = false; + $retArray['message'] = AKText::_('ERR_INVALID_LOGIN'); + } + + // JSON encode the message + $json = json_encode($retArray); + // Do I have to encrypt? + $password = AKFactory::get('kickstart.security.password', null); + if (!empty($password)) + { + $json = AKEncryptionAES::AESEncryptCtr($json, $password, 128); + } + + // Return the message + echo "###$json###"; + +} + +// ------------ lixlpixel recursive PHP functions ------------- +// recursive_remove_directory( directory to delete, empty ) +// expects path to directory and optional TRUE / FALSE to empty +// of course PHP has to have the rights to delete the directory +// you specify and all files and folders inside the directory +// ------------------------------------------------------------ +function recursive_remove_directory($directory) +{ + // if the path has a slash at the end we remove it here + if (substr($directory, -1) == '/') + { + $directory = substr($directory, 0, -1); + } + // if the path is not valid or is not a directory ... + if (!file_exists($directory) || !is_dir($directory)) + { + // ... we return false and exit the function + return false; + // ... if the path is not readable + } + elseif (!is_readable($directory)) + { + // ... we return false and exit the function + return false; + // ... else if the path is readable + } + else + { + // we open the directory + $handle = opendir($directory); + $postproc = AKFactory::getPostProc(); + // and scan through the items inside + while (false !== ($item = readdir($handle))) + { + // if the filepointer is not the current directory + // or the parent directory + if ($item != '.' && $item != '..') + { + // we build the new path to delete + $path = $directory . '/' . $item; + // if the new path is a directory + if (is_dir($path)) + { + // we call this function with the new path + recursive_remove_directory($path); + // if the new path is a file + } + else + { + // we remove the file + $postproc->unlink($path); + } + } + } + // close the directory + closedir($handle); + // try to delete the now empty directory + if (!$postproc->rmdir($directory)) + { + // return false if not possible + return false; + } + + // return success + return true; + } +} diff --git a/Sites/pages/administrator/components/com_joomlaupdate/restore_finalisation.php b/Sites/pages/administrator/components/com_joomlaupdate/restore_finalisation.php new file mode 100644 index 00000000..ee55ee5f --- /dev/null +++ b/Sites/pages/administrator/components/com_joomlaupdate/restore_finalisation.php @@ -0,0 +1,190 @@ +unlink($fileName); + } + } +} + +// Fake the JFolder class, mapping it to Restore's post-processing class +if (!class_exists('JFolder')) +{ + /** + * JFolder mock class proxing behaviour in the post-upgrade script to that of either native PHP or restore.php + * + * @since 3.5.1 + */ + abstract class JFolder + { + /** + * Proxies checking a folder exists to the native php version + * + * @param string $folderName The path to the folder to be checked + * + * @return boolean + * + * @since 3.5.1 + */ + public static function exists($folderName) + { + return @is_dir($folderName); + } + + /** + * Proxies deleting a folder to the restore.php version + * + * @param string $folderName The path to the folder to be deleted + * + * @return void + * + * @since 3.5.1 + */ + public static function delete($folderName) + { + recursive_remove_directory($folderName); + } + } +} + +// Fake the JText class - we aren't going to show errors to people anyhow +if (!class_exists('JText')) +{ + /** + * JText mock class proxing behaviour in the post-upgrade script to that of either native PHP or restore.php + * + * @since 3.5.1 + */ + abstract class JText + { + /** + * No need for translations in a non-interactive script, so always return an empty string here + * + * @param string $text A language constant + * + * @return string + * + * @since 3.5.1 + */ + public static function sprintf($text) + { + return ''; + } + } +} + +if (!function_exists('finalizeRestore')) +{ + /** + * Run part of the Joomla! finalisation script, namely the part that cleans up unused files/folders + * + * @param string $siteRoot The root to the Joomla! site + * @param string $restorePath The base path to restore.php + * + * @return void + * + * @since 3.5.1 + */ + function finalizeRestore($siteRoot, $restorePath) + { + if (!defined('JPATH_ROOT')) + { + define('JPATH_ROOT', $siteRoot); + } + + $filePath = JPATH_ROOT . '/administrator/components/com_admin/script.php'; + + if (file_exists($filePath)) + { + require_once $filePath; + } + + // Make sure Joomla!'s code can figure out which files exist and need be removed + clearstatcache(); + + // Remove obsolete files - prevents errors occurring in some system plugins + if (class_exists('JoomlaInstallerScript')) + { + $script = new JoomlaInstallerScript; + $script->deleteUnexistingFiles(); + } + + // Clear OPcache + if (function_exists('opcache_reset')) + { + opcache_reset(); + } + elseif (function_exists('apc_clear_cache')) + { + @apc_clear_cache(); + } + } +} diff --git a/Sites/pages/administrator/components/com_joomlaupdate/views/default/tmpl/complete.php b/Sites/pages/administrator/components/com_joomlaupdate/views/default/tmpl/complete.php new file mode 100644 index 00000000..e2b5a21d --- /dev/null +++ b/Sites/pages/administrator/components/com_joomlaupdate/views/default/tmpl/complete.php @@ -0,0 +1,24 @@ + + +
+ + + +

+ +

+
+
+ + +
diff --git a/Sites/pages/administrator/components/com_joomlaupdate/views/default/tmpl/default.php b/Sites/pages/administrator/components/com_joomlaupdate/views/default/tmpl/default.php new file mode 100644 index 00000000..f153d480 --- /dev/null +++ b/Sites/pages/administrator/components/com_joomlaupdate/views/default/tmpl/default.php @@ -0,0 +1,86 @@ + 'auto', 'relative' => true)); + +JFactory::getDocument()->addScriptDeclaration(" +jQuery(document).ready(function($) { + $('#extraction_method').change(function(e){ + extractionMethodHandler('#extraction_method', 'row_ftp'); + }); + $('#upload_method').change(function(e){ + extractionMethodHandler('#upload_method', 'upload_ftp'); + }); + + $('button.submit').on('click', function() { + $('div.download_message').show(); + }); +});"); +?> + +
+ + showUploadAndUpdate) : ?> + 'online-update')); ?> + + + +
+ + selfUpdate) : ?> + + enqueueMessage(JText::_('COM_JOOMLAUPDATE_VIEW_DEFAULT_INSTALL_SELF_UPDATE_FIRST'), 'error'); ?> + loadTemplate('updatemefirst'); ?> + + updateInfo['object']->downloadurl->_data) && !$this->updateInfo['hasUpdate']) : ?> + + loadTemplate('noupdate'); ?> + updateInfo['object']->downloadurl->_data)) : ?> + + loadTemplate('nodownload'); ?> + updateInfo['hasUpdate']) : ?> + + loadTemplate('reinstall'); ?> + + + loadTemplate('update'); ?> + + + + + + + +
+ + + showUploadAndUpdate) : ?> + + + loadTemplate('upload'); ?> + + + + + +
+
diff --git a/Sites/pages/administrator/components/com_joomlaupdate/views/default/tmpl/default.xml b/Sites/pages/administrator/components/com_joomlaupdate/views/default/tmpl/default.xml new file mode 100755 index 00000000..61f8dafe --- /dev/null +++ b/Sites/pages/administrator/components/com_joomlaupdate/views/default/tmpl/default.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/Sites/pages/administrator/components/com_joomlaupdate/views/default/tmpl/default_nodownload.php b/Sites/pages/administrator/components/com_joomlaupdate/views/default/tmpl/default_nodownload.php new file mode 100644 index 00000000..ba707be4 --- /dev/null +++ b/Sites/pages/administrator/components/com_joomlaupdate/views/default/tmpl/default_nodownload.php @@ -0,0 +1,21 @@ + + +
+ + + +

+ updateInfo['latest']); ?> +

+
diff --git a/Sites/pages/administrator/components/com_joomlaupdate/views/default/tmpl/default_noupdate.php b/Sites/pages/administrator/components/com_joomlaupdate/views/default/tmpl/default_noupdate.php new file mode 100644 index 00000000..c088ab3a --- /dev/null +++ b/Sites/pages/administrator/components/com_joomlaupdate/views/default/tmpl/default_noupdate.php @@ -0,0 +1,24 @@ + +
+ + + +

+ langKey, $this->updateSourceKey); ?> +

+
+ +
+
diff --git a/Sites/pages/administrator/components/com_joomlaupdate/views/default/tmpl/default_reinstall.php b/Sites/pages/administrator/components/com_joomlaupdate/views/default/tmpl/default_reinstall.php new file mode 100644 index 00000000..e92f9a3d --- /dev/null +++ b/Sites/pages/administrator/components/com_joomlaupdate/views/default/tmpl/default_reinstall.php @@ -0,0 +1,120 @@ + +
+ + + +

+ langKey, $this->updateSourceKey); ?> +

+ +
+ +
+ + updateInfo['object']) && ($this->updateInfo['object'] instanceof JUpdate)) : ?> + + + + + + + updateInfo['object']->get('infourl')->_data) + && isset($this->updateInfo['object']->get('infourl')->title)) : ?> + + + + + + + + + + ftpFieldsDisplay; ?>> + + + + ftpFieldsDisplay; ?>> + + + + ftpFieldsDisplay; ?>> + + + + ftpFieldsDisplay; ?>> + + + + ftpFieldsDisplay; ?>> + + + + + + + + + + +
+ + + + updateInfo['object']->downloadurl->_data; ?> + + + +
+ + + + updateInfo['object']->get('infourl')->title; ?> + + + +
+ + + methodSelect; ?> +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+   + + +
+ + +
diff --git a/Sites/pages/administrator/components/com_joomlaupdate/views/default/tmpl/default_update.php b/Sites/pages/administrator/components/com_joomlaupdate/views/default/tmpl/default_update.php new file mode 100644 index 00000000..b22220d3 --- /dev/null +++ b/Sites/pages/administrator/components/com_joomlaupdate/views/default/tmpl/default_update.php @@ -0,0 +1,129 @@ + +
+ + + +

+ langKey, $this->updateSourceKey); ?> +

+ + + + + + + + + + + + + + + + updateInfo['object']->get('infourl')->_data) + && isset($this->updateInfo['object']->get('infourl')->title)) : ?> + + + + + + + + + + ftpFieldsDisplay; ?>> + + + + ftpFieldsDisplay; ?>> + + + + ftpFieldsDisplay; ?>> + + + + ftpFieldsDisplay; ?>> + + + + ftpFieldsDisplay; ?>> + + + + + + + + + + +
+ + + updateInfo['installed']; ?> +
+ + + updateInfo['latest']; ?> +
+ + + + updateInfo['object']->downloadurl->_data; ?> + + + +
+ + + + updateInfo['object']->get('infourl')->title; ?> + + + +
+ + + methodSelect; ?> +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+   + + +
+
diff --git a/Sites/pages/administrator/components/com_joomlaupdate/views/default/tmpl/default_updatemefirst.php b/Sites/pages/administrator/components/com_joomlaupdate/views/default/tmpl/default_updatemefirst.php new file mode 100644 index 00000000..79d5b28a --- /dev/null +++ b/Sites/pages/administrator/components/com_joomlaupdate/views/default/tmpl/default_updatemefirst.php @@ -0,0 +1,21 @@ + + +
+ + + +

+ +

+
diff --git a/Sites/pages/administrator/components/com_joomlaupdate/views/default/tmpl/default_upload.php b/Sites/pages/administrator/components/com_joomlaupdate/views/default/tmpl/default_upload.php new file mode 100644 index 00000000..0771278f --- /dev/null +++ b/Sites/pages/administrator/components/com_joomlaupdate/views/default/tmpl/default_upload.php @@ -0,0 +1,205 @@ + form.max_upload_size.value) { + alert("$errPackageTooBig"); + } + else + { + jQuery("#loading").css("display", "block"); + + form.submit(); + } + }; + + Joomla.installpackageChange = function() { + var form = document.getElementById('uploadForm'); + var fileSize = form.install_package.files[0].size; + var fileSizeMB = fileSize * 1.0 / 1024.0 / 1024.0; + var fileSizeText = "$txtPackageSize"; + var fileSizeElement = document.getElementById('file_size'); + var warningElement = document.getElementById('max_upload_size_warn'); + + if (form.install_package.value == '') { + fileSizeElement.classList.add('hidden'); + warningElement .classList.add('hidden'); + } + else if (fileSize) { + fileSizeElement.classList.remove('hidden'); + fileSizeElement.innerHTML = fileSizeText.replace('%s', fileSizeMB.toFixed(2) + ' MB'); + + if (fileSize > form.max_upload_size.value) { + warningElement .classList.remove('hidden'); + } else { + warningElement .classList.add('hidden'); + } + } + }; + + // Add spindle-wheel for installations: + jQuery(document).ready(function($) { + var outerDiv = $("#joomlaupdate-wrapper"); + + $("#loading") + .css("top", outerDiv.position().top - $(window).scrollTop()) + .css("left", "0") + .css("width", "100%") + .css("height", "100%") + .css("display", "none") + .css("margin-top", "-10px"); + }); + +JS; + +JFactory::getDocument()->addScriptDeclaration($js); + +$ajaxLoaderImage = JHtml::_('image', 'jui/ajax-loader.gif', '', null, true, true); +$css = <<< CSS + #loading { + background: rgba(255, 255, 255, .8) url('$ajaxLoaderImage') 50% 15% no-repeat; + position: fixed; + opacity: 1; + -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity = 80); + filter: alpha(opacity = 80); + overflow: hidden; + } +CSS; +JFactory::getDocument()->addStyleDeclaration($css); +?> + +
+

+ + +

+
+ +warnings)) : ?> +
+ + + + + + 'warning' . $i)); ?> + warnings as $message) : ?> + + + + + + + + +
+ + +
+
+ + + + + + + + + + + + ftpFieldsDisplay; ?>> + + + + ftpFieldsDisplay; ?>> + + + + ftpFieldsDisplay; ?>> + + + + ftpFieldsDisplay; ?>> + + + + ftpFieldsDisplay; ?>> + + + + + + + + + + +
+ + +
+ + + +
+ + +
+ + + methodSelectUpload; ?> +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+   + + +
+
+ + + + + +
diff --git a/Sites/pages/administrator/components/com_joomlaupdate/views/default/view.html.php b/Sites/pages/administrator/components/com_joomlaupdate/views/default/view.html.php new file mode 100644 index 00000000..263df188 --- /dev/null +++ b/Sites/pages/administrator/components/com_joomlaupdate/views/default/view.html.php @@ -0,0 +1,218 @@ +state = $this->get('State'); + + // Load useful classes. + /** @var JoomlaupdateModelDefault $model */ + $model = $this->getModel(); + $this->loadHelper('select'); + + // Assign view variables. + $this->ftp = $model->getFTPOptions(); + $defaultMethod = $this->ftp['enabled'] ? 'hybrid' : 'direct'; + + $this->updateInfo = $model->getUpdateInformation(); + $this->methodSelect = JoomlaupdateHelperSelect::getMethods($defaultMethod); + $this->methodSelectUpload = JoomlaupdateHelperSelect::getMethods($defaultMethod, 'method', 'upload_method'); + + // Set the toolbar information. + JToolbarHelper::title(JText::_('COM_JOOMLAUPDATE_OVERVIEW'), 'loop install'); + JToolbarHelper::custom('update.purge', 'loop', 'loop', 'COM_JOOMLAUPDATE_TOOLBAR_CHECK', false); + + // Add toolbar buttons. + if (JFactory::getUser()->authorise('core.admin')) + { + JToolbarHelper::preferences('com_joomlaupdate'); + } + + JToolbarHelper::divider(); + JToolbarHelper::help('JHELP_COMPONENTS_JOOMLA_UPDATE'); + + if (!is_null($this->updateInfo['object'])) + { + // Show the message if an update is found. + JFactory::getApplication()->enqueueMessage(JText::_('COM_JOOMLAUPDATE_VIEW_DEFAULT_UPDATE_NOTICE'), 'warning'); + } + + $this->ftpFieldsDisplay = $this->ftp['enabled'] ? '' : 'style = "display: none"'; + $params = JComponentHelper::getParams('com_joomlaupdate'); + + switch ($params->get('updatesource', 'default')) + { + // "Minor & Patch Release for Current version AND Next Major Release". + case 'sts': + case 'next': + $this->langKey = 'COM_JOOMLAUPDATE_VIEW_DEFAULT_UPDATES_INFO_NEXT'; + $this->updateSourceKey = JText::_('COM_JOOMLAUPDATE_CONFIG_UPDATESOURCE_NEXT'); + break; + + // "Testing" + case 'testing': + $this->langKey = 'COM_JOOMLAUPDATE_VIEW_DEFAULT_UPDATES_INFO_TESTING'; + $this->updateSourceKey = JText::_('COM_JOOMLAUPDATE_CONFIG_UPDATESOURCE_TESTING'); + break; + + // "Custom" + case 'custom': + $this->langKey = 'COM_JOOMLAUPDATE_VIEW_DEFAULT_UPDATES_INFO_CUSTOM'; + $this->updateSourceKey = JText::_('COM_JOOMLAUPDATE_CONFIG_UPDATESOURCE_CUSTOM'); + break; + + /** + * "Minor & Patch Release for Current version (recommended and default)". + * The commented "case" below are for documenting where 'default' and legacy options falls + * case 'default': + * case 'lts': + * case 'nochange': + */ + default: + $this->langKey = 'COM_JOOMLAUPDATE_VIEW_DEFAULT_UPDATES_INFO_DEFAULT'; + $this->updateSourceKey = JText::_('COM_JOOMLAUPDATE_CONFIG_UPDATESOURCE_DEFAULT'); + } + + $this->warnings = array(); + /** @var InstallerModelWarnings $warningsModel */ + $warningsModel = $this->getModel('warnings'); + + if (is_object($warningsModel) && $warningsModel instanceof JModelLegacy) + { + $language = JFactory::getLanguage(); + $language->load('com_installer', JPATH_ADMINISTRATOR, 'en-GB', false, true); + $language->load('com_installer', JPATH_ADMINISTRATOR, null, true); + + $this->warnings = $warningsModel->getItems(); + } + + $this->selfUpdate = $this->checkForSelfUpdate(); + + // Only Super Users have access to the Update & Install for obvious security reasons + $this->showUploadAndUpdate = JFactory::getUser()->authorise('core.admin'); + + // Remove temporary files + $model->removePackageFiles(); + + // Render the view. + parent::display($tpl); + } + + /** + * Makes sure that the Joomla! Update Component Update is in the database and check if there is a new version. + * + * @return boolean True if there is an update else false + * + * @since 3.6.3 + */ + private function checkForSelfUpdate() + { + $db = JFactory::getDbo(); + + $query = $db->getQuery(true) + ->select($db->quoteName('extension_id')) + ->from($db->quoteName('#__extensions')) + ->where($db->quoteName('element') . ' = ' . $db->quote('com_joomlaupdate')); + $db->setQuery($query); + + try + { + // Get the component extension ID + $joomlaUpdateComponentId = $db->loadResult(); + } + catch (RuntimeException $e) + { + // Something is wrong here! + $joomlaUpdateComponentId = 0; + JFactory::getApplication()->enqueueMessage($e->getMessage(), 'error'); + } + + // Try the update only if we have an extension id + if ($joomlaUpdateComponentId != 0) + { + // Always force to check for an update! + $cache_timeout = 0; + + $updater = JUpdater::getInstance(); + $updater->findUpdates($joomlaUpdateComponentId, $cache_timeout, JUpdater::STABILITY_STABLE); + + // Fetch the update information from the database. + $query = $db->getQuery(true) + ->select('*') + ->from($db->quoteName('#__updates')) + ->where($db->quoteName('extension_id') . ' = ' . $db->quote($joomlaUpdateComponentId)); + $db->setQuery($query); + + try + { + $joomlaUpdateComponentObject = $db->loadObject(); + } + catch (RuntimeException $e) + { + // Something is wrong here! + $joomlaUpdateComponentObject = null; + JFactory::getApplication()->enqueueMessage($e->getMessage(), 'error'); + } + + if (is_null($joomlaUpdateComponentObject)) + { + // No Update great! + return false; + } + + return true; + } + } +} diff --git a/Sites/pages/administrator/components/com_joomlaupdate/views/update/tmpl/default.php b/Sites/pages/administrator/components/com_joomlaupdate/views/update/tmpl/default.php new file mode 100644 index 00000000..b897e244 --- /dev/null +++ b/Sites/pages/administrator/components/com_joomlaupdate/views/update/tmpl/default.php @@ -0,0 +1,63 @@ + 'auto', 'relative' => true)); +JHtml::_('script', 'com_joomlaupdate/encryption.js', array('version' => 'auto', 'relative' => true)); +JHtml::_('script', 'com_joomlaupdate/update.js', array('version' => 'auto', 'relative' => true)); + +$password = JFactory::getApplication()->getUserState('com_joomlaupdate.password', null); +$filesize = JFactory::getApplication()->getUserState('com_joomlaupdate.filesize', null); +$ajaxUrl = JUri::base() . 'components/com_joomlaupdate/restore.php'; +$returnUrl = 'index.php?option=com_joomlaupdate&task=update.finalise&' . JFactory::getSession()->getFormToken() . '=1'; + +JFactory::getDocument()->addScriptDeclaration( + " + var joomlaupdate_password = '$password'; + var joomlaupdate_totalsize = '$filesize'; + var joomlaupdate_ajax_url = '$ajaxUrl'; + var joomlaupdate_return_url = '$returnUrl'; + + jQuery(document).ready(function(){ + window.pingExtract(); + }); + " +); +?> + +

+ +
+
+
+
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
diff --git a/Sites/pages/administrator/components/com_joomlaupdate/views/update/tmpl/finaliseconfirm.php b/Sites/pages/administrator/components/com_joomlaupdate/views/update/tmpl/finaliseconfirm.php new file mode 100644 index 00000000..e0794aeb --- /dev/null +++ b/Sites/pages/administrator/components/com_joomlaupdate/views/update/tmpl/finaliseconfirm.php @@ -0,0 +1,95 @@ + + +
+

+ +

+

+ get('sitename')); ?> +

+
+ +
+ +
+
+
+
+
+ + + + + +
+
+
+
+
+
+ + + + + +
+
+
+ 1) : ?> +
+
+
+ + + + + + + + +
+
+
+ +
+
+
+ + + +
+
+ +
+
+
+ + + + +
+
diff --git a/Sites/pages/administrator/components/com_joomlaupdate/views/update/view.html.php b/Sites/pages/administrator/components/com_joomlaupdate/views/update/view.html.php new file mode 100644 index 00000000..c7e66ffc --- /dev/null +++ b/Sites/pages/administrator/components/com_joomlaupdate/views/update/view.html.php @@ -0,0 +1,39 @@ +input->set('hidemainmenu', true); + + // Set the toolbar information. + JToolbarHelper::title(JText::_('COM_JOOMLAUPDATE_OVERVIEW'), 'loop install'); + + // Import com_login's model + JModelLegacy::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_login/models', 'LoginModel'); + + // Render the view. + parent::display($tpl); + } +} diff --git a/Sites/pages/administrator/components/com_joomlaupdate/views/upload/tmpl/captive.php b/Sites/pages/administrator/components/com_joomlaupdate/views/upload/tmpl/captive.php new file mode 100644 index 00000000..8f3ed558 --- /dev/null +++ b/Sites/pages/administrator/components/com_joomlaupdate/views/upload/tmpl/captive.php @@ -0,0 +1,94 @@ + +
+

+ +

+

+ get('sitename')); ?> +

+
+ +
+ +
+
+
+
+
+ + + + + +
+
+
+
+
+
+ + + + + +
+
+
+ 1) : ?> +
+
+
+ + + + + + + + +
+
+
+ +
+
+
+ + + +
+
+ +
+
+
+ + + + +
+
diff --git a/Sites/pages/administrator/components/com_joomlaupdate/views/upload/view.html.php b/Sites/pages/administrator/components/com_joomlaupdate/views/upload/view.html.php new file mode 100644 index 00000000..3b07afcf --- /dev/null +++ b/Sites/pages/administrator/components/com_joomlaupdate/views/upload/view.html.php @@ -0,0 +1,46 @@ +load('com_installer', JPATH_ADMINISTRATOR, 'en-GB', false, true); + $language->load('com_installer', JPATH_ADMINISTRATOR, null, true); + + // Import com_login's model + JModelLegacy::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_login/models', 'LoginModel'); + + // Render the view. + parent::display($tpl); + } +} diff --git a/Sites/pages/administrator/components/com_languages/access.xml b/Sites/pages/administrator/components/com_languages/access.xml new file mode 100644 index 00000000..bad626c9 --- /dev/null +++ b/Sites/pages/administrator/components/com_languages/access.xml @@ -0,0 +1,11 @@ + + +
+ + + + + + +
+
diff --git a/Sites/pages/administrator/components/com_languages/config.xml b/Sites/pages/administrator/components/com_languages/config.xml new file mode 100644 index 00000000..1662ae7c --- /dev/null +++ b/Sites/pages/administrator/components/com_languages/config.xml @@ -0,0 +1,29 @@ + + +
+ + + + + + +
+
diff --git a/Sites/pages/administrator/components/com_languages/controller.php b/Sites/pages/administrator/components/com_languages/controller.php new file mode 100644 index 00000000..a622a0db --- /dev/null +++ b/Sites/pages/administrator/components/com_languages/controller.php @@ -0,0 +1,56 @@ +input->get('view', 'languages'); + $layout = $this->input->get('layout', 'default'); + $id = $this->input->getInt('id'); + + // Check for edit form. + if ($view == 'language' && $layout == 'edit' && !$this->checkEditId('com_languages.edit.language', $id)) + { + // Somehow the person just went to the form - we don't allow that. + $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id)); + $this->setMessage($this->getError(), 'error'); + $this->setRedirect(JRoute::_('index.php?option=com_languages&view=languages', false)); + + return false; + } + + return parent::display(); + } +} diff --git a/Sites/pages/administrator/components/com_languages/controllers/installed.php b/Sites/pages/administrator/components/com_languages/controllers/installed.php new file mode 100644 index 00000000..322df2a6 --- /dev/null +++ b/Sites/pages/administrator/components/com_languages/controllers/installed.php @@ -0,0 +1,95 @@ +checkToken(); + + $cid = $this->input->get('cid', ''); + $model = $this->getModel('installed'); + + if ($model->publish($cid)) + { + // Switching to the new administrator language for the message + if ($model->getState('client_id') == 1) + { + $language = JFactory::getLanguage(); + $newLang = JLanguage::getInstance($cid); + JFactory::$language = $newLang; + JFactory::getApplication()->loadLanguage($language = $newLang); + $newLang->load('com_languages', JPATH_ADMINISTRATOR); + } + + $msg = JText::_('COM_LANGUAGES_MSG_DEFAULT_LANGUAGE_SAVED'); + $type = 'message'; + } + else + { + $msg = $this->getError(); + $type = 'error'; + } + + $clientId = $model->getState('client_id'); + $this->setredirect('index.php?option=com_languages&view=installed&client=' . $clientId, $msg, $type); + } + + /** + * Task to switch the administrator language. + * + * @return void + */ + public function switchAdminLanguage() + { + // Check for request forgeries. + $this->checkToken(); + + $cid = $this->input->get('cid', ''); + $model = $this->getModel('installed'); + + // Fetching the language name from the xx-XX.xml + $file = JPATH_ADMINISTRATOR . '/language/' . $cid . '/' . $cid . '.xml'; + $info = JInstaller::parseXMLInstallFile($file); + $languageName = $info['name']; + + if ($model->switchAdminLanguage($cid)) + { + // Switching to the new language for the message + $language = JFactory::getLanguage(); + $newLang = JLanguage::getInstance($cid); + JFactory::$language = $newLang; + JFactory::getApplication()->loadLanguage($language = $newLang); + $newLang->load('com_languages', JPATH_ADMINISTRATOR); + + $msg = JText::sprintf('COM_LANGUAGES_MSG_SWITCH_ADMIN_LANGUAGE_SUCCESS', $languageName); + $type = 'message'; + } + else + { + $msg = $this->getError(); + $type = 'error'; + } + + $this->setredirect('index.php?option=com_languages&view=installed', $msg, $type); + } +} diff --git a/Sites/pages/administrator/components/com_languages/controllers/language.php b/Sites/pages/administrator/components/com_languages/controllers/language.php new file mode 100644 index 00000000..d383bd29 --- /dev/null +++ b/Sites/pages/administrator/components/com_languages/controllers/language.php @@ -0,0 +1,33 @@ + true)) + { + return parent::getModel($name, $prefix, $config); + } + + /** + * Method to save the submitted ordering values for records via AJAX. + * + * @return void + * + * @since 3.1 + */ + public function saveOrderAjax() + { + $pks = $this->input->post->get('cid', array(), 'array'); + $order = $this->input->post->get('order', array(), 'array'); + + // Sanitize the input. + $pks = ArrayHelper::toInteger($pks); + $order = ArrayHelper::toInteger($order); + + // Get the model. + $model = $this->getModel(); + + // Save the ordering. + $return = $model->saveorder($pks, $order); + + if ($return) + { + echo '1'; + } + + // Close the application. + JFactory::getApplication()->close(); + } +} diff --git a/Sites/pages/administrator/components/com_languages/controllers/override.php b/Sites/pages/administrator/components/com_languages/controllers/override.php new file mode 100644 index 00000000..ea9b8f4f --- /dev/null +++ b/Sites/pages/administrator/components/com_languages/controllers/override.php @@ -0,0 +1,206 @@ +allowCache(false); + + $app = JFactory::getApplication(); + $cid = $this->input->post->get('cid', array(), 'array'); + $context = "$this->option.edit.$this->context"; + + // Get the constant name. + $recordId = (count($cid) ? $cid[0] : $this->input->get('id')); + + // Access check. + if (!$this->allowEdit()) + { + $this->setError(JText::_('JLIB_APPLICATION_ERROR_EDIT_NOT_PERMITTED')); + $this->setMessage($this->getError(), 'error'); + $this->setRedirect(JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_list . $this->getRedirectToListAppend(), false)); + + return; + } + + $app->setUserState($context . '.data', null); + $this->setRedirect('index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend($recordId, 'id')); + } + + /** + * Method to save an override. + * + * @param string $key The name of the primary key of the URL variable (not used here). + * @param string $urlVar The name of the URL variable if different from the primary key (not used here). + * + * @return void + * + * @since 2.5 + */ + public function save($key = null, $urlVar = null) + { + // Check for request forgeries. + $this->checkToken(); + + $app = JFactory::getApplication(); + $model = $this->getModel(); + $data = $this->input->post->get('jform', array(), 'array'); + $context = "$this->option.edit.$this->context"; + $task = $this->getTask(); + + $recordId = $this->input->get('id'); + $data['id'] = $recordId; + + // Access check. + if (!$this->allowSave($data, 'id')) + { + $this->setError(JText::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED')); + $this->setMessage($this->getError(), 'error'); + $this->setRedirect(JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_list . $this->getRedirectToListAppend(), false)); + + return; + } + + // Validate the posted data. + $form = $model->getForm($data, false); + + if (!$form) + { + $app->enqueueMessage($model->getError(), 'error'); + + return; + } + + // Require helper for filter functions called by JForm. + JLoader::register('LanguagesHelper', JPATH_ADMINISTRATOR . '/components/com_languages/helpers/languages.php'); + + // Test whether the data is valid. + $validData = $model->validate($form, $data); + + // Check for validation errors. + if ($validData === false) + { + // Get the validation messages. + $errors = $model->getErrors(); + + // Push up to three validation messages out to the user. + for ($i = 0, $n = count($errors); $i < $n && $i < 3; $i++) + { + if ($errors[$i] instanceof Exception) + { + $app->enqueueMessage($errors[$i]->getMessage(), 'warning'); + } + else + { + $app->enqueueMessage($errors[$i], 'warning'); + } + } + + // Save the data in the session. + $app->setUserState($context . '.data', $data); + + // Redirect back to the edit screen. + $this->setRedirect( + JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend($recordId, 'id'), false) + ); + + return; + } + + // Attempt to save the data. + if (!$model->save($validData)) + { + // Save the data in the session. + $app->setUserState($context . '.data', $validData); + + // Redirect back to the edit screen. + $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_SAVE_FAILED', $model->getError())); + $this->setMessage($this->getError(), 'error'); + $this->setRedirect( + JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend($recordId, 'id'), false) + ); + + return; + } + + // Add message of success. + $this->setMessage(JText::_('COM_LANGUAGES_VIEW_OVERRIDE_SAVE_SUCCESS')); + + // Redirect the user and adjust session state based on the chosen task. + switch ($task) + { + case 'apply': + // Set the record data in the session. + $app->setUserState($context . '.data', null); + + // Redirect back to the edit screen + $this->setRedirect( + JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend($validData['key'], 'id'), false) + ); + break; + + case 'save2new': + // Clear the record id and data from the session. + $app->setUserState($context . '.data', null); + + // Redirect back to the edit screen + $this->setRedirect( + JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend(null, 'id'), false) + ); + break; + + default: + // Clear the record id and data from the session. + $app->setUserState($context . '.data', null); + + // Redirect to the list screen. + $this->setRedirect(JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_list . $this->getRedirectToListAppend(), false)); + break; + } + } + + /** + * Method to cancel an edit. + * + * @param string $key The name of the primary key of the URL variable (not used here). + * + * @return void + * + * @since 2.5 + */ + public function cancel($key = null) + { + $this->checkToken(); + + $app = JFactory::getApplication(); + $context = "$this->option.edit.$this->context"; + + $app->setUserState($context . '.data', null); + $this->setRedirect(JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_list . $this->getRedirectToListAppend(), false)); + } +} diff --git a/Sites/pages/administrator/components/com_languages/controllers/overrides.php b/Sites/pages/administrator/components/com_languages/controllers/overrides.php new file mode 100644 index 00000000..c0577689 --- /dev/null +++ b/Sites/pages/administrator/components/com_languages/controllers/overrides.php @@ -0,0 +1,81 @@ +checkToken(); + + // Get items to delete from the request. + $cid = $this->input->get('cid', array(), 'array'); + + if (!is_array($cid) || count($cid) < 1) + { + $this->setMessage(JText::_($this->text_prefix . '_NO_ITEM_SELECTED'), 'warning'); + } + else + { + // Get the model. + $model = $this->getModel('overrides'); + + // Remove the items. + if ($model->delete($cid)) + { + $this->setMessage(JText::plural($this->text_prefix . '_N_ITEMS_DELETED', count($cid))); + } + else + { + $this->setMessage($model->getError()); + } + } + + $this->setRedirect(JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_list, false)); + } + + /** + * Method to purge the overrider table. + * + * @return void + * + * @since 3.4.2 + */ + public function purge() + { + // Check for request forgeries. + $this->checkToken(); + + $model = $this->getModel('overrides'); + $model->purge(); + $this->setRedirect(JRoute::_('index.php?option=com_languages&view=overrides', false)); + } +} diff --git a/Sites/pages/administrator/components/com_languages/controllers/strings.json.php b/Sites/pages/administrator/components/com_languages/controllers/strings.json.php new file mode 100644 index 00000000..ea6a329c --- /dev/null +++ b/Sites/pages/administrator/components/com_languages/controllers/strings.json.php @@ -0,0 +1,42 @@ +getModel('strings')->refresh()); + } + + /** + * Method for searching language strings + * + * @return void + * + * @since 2.5 + */ + public function search() + { + echo new JResponseJson($this->getModel('strings')->search()); + } +} diff --git a/Sites/pages/administrator/components/com_languages/helpers/html/languages.php b/Sites/pages/administrator/components/com_languages/helpers/html/languages.php new file mode 100644 index 00000000..e521ab66 --- /dev/null +++ b/Sites/pages/administrator/components/com_languages/helpers/html/languages.php @@ -0,0 +1,87 @@ +'; + } + + /** + * Method to generate an array of clients. + * + * @return array of client objects. + */ + public static function clients() + { + return array( + JHtml::_('select.option', 0, JText::_('JSITE')), + JHtml::_('select.option', 1, JText::_('JADMINISTRATOR')) + ); + } + + /** + * Returns an array of published state filter options. + * + * @return string The HTML code for the select tag. + * + * @since 1.6 + */ + public static function publishedOptions() + { + // Build the active state filter options. + $options = array(); + $options[] = JHtml::_('select.option', '1', 'JPUBLISHED'); + $options[] = JHtml::_('select.option', '0', 'JUNPUBLISHED'); + $options[] = JHtml::_('select.option', '-2', 'JTRASHED'); + $options[] = JHtml::_('select.option', '*', 'JALL'); + + return $options; + } +} diff --git a/Sites/pages/administrator/components/com_languages/helpers/jsonresponse.php b/Sites/pages/administrator/components/com_languages/helpers/jsonresponse.php new file mode 100644 index 00000000..0273290d --- /dev/null +++ b/Sites/pages/administrator/components/com_languages/helpers/jsonresponse.php @@ -0,0 +1,134 @@ +success, + * so you can use both flags equivalently. + * + * @var boolean + * @since 2.5 + */ + public $error = false; + + /** + * The main response message. + * + * @var string + * @since 2.5 + */ + public $message = null; + + /** + * Array of messages gathered in the JApplication object. + * + * @var array + * @since 2.5 + */ + public $messages = null; + + /** + * The response data. + * + * @var mixed + * @since 2.5 + */ + public $data = null; + + /** + * Constructor + * + * @param mixed $response The Response data. + * @param string $message The main response message. + * @param boolean $error True, if the success flag shall be set to false, defaults to false. + * + * @since 2.5 + * @deprecated 4.0 Use JResponseJson instead. + */ + public function __construct($response = null, $message = null, $error = false) + { + try + { + JLog::add(sprintf('%s is deprecated, use JResponseJson instead.', __CLASS__), JLog::WARNING, 'deprecated'); + } + catch (RuntimeException $exception) + { + // Informational log only + } + + $this->message = $message; + + // Get the message queue. + $messages = JFactory::getApplication()->getMessageQueue(); + + // Build the sorted messages list. + if (is_array($messages) && count($messages)) + { + foreach ($messages as $message) + { + if (isset($message['type']) && isset($message['message'])) + { + $lists[$message['type']][] = $message['message']; + } + } + } + + // If messages exist add them to the output. + if (isset($lists) && is_array($lists)) + { + $this->messages = $lists; + } + + // Check if we are dealing with an error. + if ($response instanceof Exception) + { + // Prepare the error response. + $this->success = false; + $this->error = true; + $this->message = $response->getMessage(); + } + else + { + // Prepare the response data. + $this->success = !$error; + $this->error = $error; + $this->data = $response; + } + } + + /** + * Magic toString method for sending the response in JSON format. + * + * @return string The response in JSON format. + * + * @since 2.5 + */ + public function __toString() + { + return json_encode($this); + } +} diff --git a/Sites/pages/administrator/components/com_languages/helpers/languages.php b/Sites/pages/administrator/components/com_languages/helpers/languages.php new file mode 100644 index 00000000..17f3e20a --- /dev/null +++ b/Sites/pages/administrator/components/com_languages/helpers/languages.php @@ -0,0 +1,123 @@ +clean($value, 'cmd')); + } + + /** + * Filter method for language strings. + * This method will be called by JForm while filtering the form data. + * + * @param string $value The language string to filter. + * + * @return string The filtered language string. + * + * @since 2.5 + */ + public static function filterText($value) + { + $filter = JFilterInput::getInstance(null, null, 1, 1); + + return $filter->clean($value); + } +} diff --git a/Sites/pages/administrator/components/com_languages/helpers/multilangstatus.php b/Sites/pages/administrator/components/com_languages/helpers/multilangstatus.php new file mode 100644 index 00000000..acdeb5fe --- /dev/null +++ b/Sites/pages/administrator/components/com_languages/helpers/multilangstatus.php @@ -0,0 +1,321 @@ +getQuery(true) + ->select('COUNT(*)') + ->from($db->quoteName('#__menu')) + ->where('home = 1') + ->where('published = 1') + ->where('client_id = 0'); + $db->setQuery($query); + + return $db->loadResult(); + } + + /** + * Method to get the number of published language switcher modules. + * + * @return integer + */ + public static function getLangswitchers() + { + // Check if switcher is published. + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->select('COUNT(*)') + ->from($db->quoteName('#__modules')) + ->where('module = ' . $db->quote('mod_languages')) + ->where('published = 1') + ->where('client_id = 0'); + $db->setQuery($query); + + return $db->loadResult(); + } + + /** + * Method to return a list of published content languages. + * + * @return array of language objects. + */ + public static function getContentlangs() + { + // Check for published Content Languages. + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->select('a.lang_code AS lang_code') + ->select('a.published AS published') + ->from('#__languages AS a'); + $db->setQuery($query); + + return $db->loadObjectList(); + } + + /** + * Method to return a list of published site languages. + * + * @return array of language extension objects. + * + * @deprecated 4.0 Use JLanguageHelper::getInstalledLanguages(0) instead. + */ + public static function getSitelangs() + { + try + { + JLog::add( + sprintf('%s() is deprecated, use JLanguageHelper::getInstalledLanguages(0) instead.', __METHOD__), + JLog::WARNING, + 'deprecated' + ); + } + catch (RuntimeException $exception) + { + // Informational log only + } + + return JLanguageHelper::getInstalledLanguages(0); + } + + /** + * Method to return a list of language home page menu items. + * + * @return array of menu objects. + * + * @deprecated 4.0 Use JLanguageMultilang::getSiteHomePages() instead. + */ + public static function getHomepages() + { + try + { + JLog::add( + sprintf('%s() is deprecated, use JLanguageHelper::getSiteHomePages() instead.', __METHOD__), + JLog::WARNING, + 'deprecated' + ); + } + catch (RuntimeException $exception) + { + // Informational log only + } + + return JLanguageMultilang::getSiteHomePages(); + } + + /** + * Method to return combined language status. + * + * @return array of language objects. + */ + public static function getStatus() + { + // Check for combined status. + $db = JFactory::getDbo(); + $query = $db->getQuery(true); + + // Select all fields from the languages table. + $query->select('a.*', 'l.home') + ->select('a.published AS published') + ->select('a.lang_code AS lang_code') + ->from('#__languages AS a'); + + // Select the language home pages. + $query->select('l.home AS home') + ->select('l.language AS home_language') + ->join('LEFT', '#__menu AS l ON l.language = a.lang_code AND l.home=1 AND l.published=1 AND l.language <> \'*\'') + ->select('e.enabled AS enabled') + ->select('e.element AS element') + ->join('LEFT', '#__extensions AS e ON e.element = a.lang_code') + ->where('e.client_id = 0') + ->where('e.enabled = 1') + ->where('e.state = 0'); + + $db->setQuery($query); + + return $db->loadObjectList(); + } + + /** + * Method to return a list of contact objects. + * + * @return array of contact objects. + */ + public static function getContacts() + { + $db = JFactory::getDbo(); + $languages = count(JLanguageHelper::getLanguages()); + + // Get the number of contact with all as language + $alang = $db->getQuery(true) + ->select('count(*)') + ->from('#__contact_details AS cd') + ->where('cd.user_id=u.id') + ->where('cd.published=1') + ->where('cd.language=' . $db->quote('*')); + + // Get the number of languages for the contact + $slang = $db->getQuery(true) + ->select('count(distinct(l.lang_code))') + ->from('#__languages as l') + ->join('LEFT', '#__contact_details AS cd ON cd.language=l.lang_code') + ->where('cd.user_id=u.id') + ->where('cd.published=1') + ->where('l.published=1'); + + // Get the number of multiple contact/language + $mlang = $db->getQuery(true) + ->select('count(*)') + ->from('#__languages as l') + ->join('LEFT', '#__contact_details AS cd ON cd.language=l.lang_code') + ->where('cd.user_id=u.id') + ->where('cd.published=1') + ->where('l.published=1') + ->group('l.lang_code') + ->having('count(*) > 1'); + + // Get the contacts + $query = $db->getQuery(true) + ->select('u.name, (' . $alang . ') as alang, (' . $slang . ') as slang, (' . $mlang . ') as mlang') + ->from('#__users AS u') + ->join('LEFT', '#__contact_details AS cd ON cd.user_id=u.id') + ->where('EXISTS (SELECT 1 from #__content as c where c.created_by=u.id)') + ->group('u.id'); + + $db->setQuery($query); + $warnings = $db->loadObjectList(); + + foreach ($warnings as $index => $warn) + { + if ($warn->alang == 1 && $warn->slang == 0) + { + unset($warnings[$index]); + } + + if ($warn->alang == 0 && $warn->slang == 0 && empty($warn->mlang)) + { + unset($warnings[$index]); + } + + if ($warn->alang == 0 && $warn->slang == $languages && empty($warn->mlang)) + { + unset($warnings[$index]); + } + } + + return $warnings; + } + + /** + * Method to get the status of the module displaying the menutype of the default Home page set to All languages. + * + * @return boolean True if the module is published, false otherwise. + * + * @since 3.7.0 + */ + public static function getDefaultHomeModule() + { + // Find Default Home menutype. + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->select($db->qn('menutype')) + ->from($db->qn('#__menu')) + ->where($db->qn('home') . ' = ' . $db->q('1')) + ->where($db->qn('published') . ' = ' . $db->q('1')) + ->where($db->qn('client_id') . ' = ' . $db->q('0')) + ->where($db->qn('language') . ' = ' . $db->q('*')); + + $db->setQuery($query); + + $menutype = $db->loadResult(); + + // Get published site menu modules titles. + $query->clear() + ->select($db->qn('title')) + ->from($db->qn('#__modules')) + ->where($db->qn('module') . ' = ' . $db->q('mod_menu')) + ->where($db->qn('published') . ' = ' . $db->q('1')) + ->where($db->qn('client_id') . ' = ' . $db->q('0')); + + $db->setQuery($query); + + $menutitles = $db->loadColumn(); + + // Do we have a published menu module displaying the default Home menu item set to all languages? + foreach ($menutitles as $menutitle) + { + $module = self::getModule('mod_menu', $menutitle); + $moduleParams = new JRegistry($module->params); + $param = $moduleParams->get('menutype', ''); + + if ($param && $param != $menutype) + { + continue; + } + + return true; + } + } + + /** + * Get module by name + * + * @param string $moduleName The name of the module + * @param string $instanceTitle The title of the module, optional + * + * @return stdClass The Module object + * + * @since 3.7.0 + */ + public static function getModule($moduleName, $instanceTitle = null) + { + $db = JFactory::getDbo(); + + $query = $db->getQuery(true) + ->select('id, title, module, position, content, showtitle, params') + ->from($db->qn('#__modules')) + ->where($db->qn('module') . ' = ' . $db->q($moduleName)) + ->where($db->qn('published') . ' = ' . $db->q('1')) + ->where($db->qn('client_id') . ' = ' . $db->q('0')); + + if ($instanceTitle) + { + $query->where($db->qn('title') . ' = ' . $db->q($instanceTitle)); + } + + $db->setQuery($query); + + try + { + $modules = $db->loadObject(); + } + catch (RuntimeException $e) + { + JLog::add(JText::sprintf('JLIB_APPLICATION_ERROR_MODULE_LOAD', $e->getMessage()), JLog::WARNING, 'jerror'); + } + + return $modules; + } +} diff --git a/Sites/pages/administrator/components/com_languages/languages.php b/Sites/pages/administrator/components/com_languages/languages.php new file mode 100644 index 00000000..46517c49 --- /dev/null +++ b/Sites/pages/administrator/components/com_languages/languages.php @@ -0,0 +1,20 @@ +authorise('core.manage', 'com_languages')) +{ + throw new JAccessExceptionNotallowed(JText::_('JERROR_ALERTNOAUTHOR'), 403); +} + +$controller = JControllerLegacy::getInstance('Languages'); +$controller->execute(JFactory::getApplication()->input->get('task')); +$controller->redirect(); diff --git a/Sites/pages/administrator/components/com_languages/languages.xml b/Sites/pages/administrator/components/com_languages/languages.xml new file mode 100644 index 00000000..174d4bda --- /dev/null +++ b/Sites/pages/administrator/components/com_languages/languages.xml @@ -0,0 +1,29 @@ + + + com_languages + Joomla! Project + April 2006 + (C) 2005 - 2020 Open Source Matters. All rights reserved. + GNU General Public License version 2 or later; see LICENSE.txt + admin@joomla.org + www.joomla.org + 3.0.0 + COM_LANGUAGES_XML_DESCRIPTION + + + config.xml + controller.php + languages.php + controllers + helpers + models + tables + views + + + language/en-GB.com_languages.ini + language/en-GB.com_languages.sys.ini + + + + diff --git a/Sites/pages/administrator/components/com_languages/layouts/joomla/searchtools/default/bar.php b/Sites/pages/administrator/components/com_languages/layouts/joomla/searchtools/default/bar.php new file mode 100644 index 00000000..88f449ca --- /dev/null +++ b/Sites/pages/administrator/components/com_languages/layouts/joomla/searchtools/default/bar.php @@ -0,0 +1,24 @@ +filterForm->getField('language_client'); ?> +
+ input; ?> +
+ 'none')); ?> diff --git a/Sites/pages/administrator/components/com_languages/models/fields/languageclient.php b/Sites/pages/administrator/components/com_languages/models/fields/languageclient.php new file mode 100644 index 00000000..21feda56 --- /dev/null +++ b/Sites/pages/administrator/components/com_languages/models/fields/languageclient.php @@ -0,0 +1,76 @@ +cache)) + { + return $this->cache; + } + + // Get all languages of frontend and backend. + $languages = array(); + $site_languages = JLanguageHelper::getKnownLanguages(JPATH_SITE); + $admin_languages = JLanguageHelper::getKnownLanguages(JPATH_ADMINISTRATOR); + + // Create a single array of them. + foreach ($site_languages as $tag => $language) + { + $languages[$tag . '0'] = JText::sprintf('COM_LANGUAGES_VIEW_OVERRIDES_LANGUAGES_BOX_ITEM', $language['name'], JText::_('JSITE')); + } + + foreach ($admin_languages as $tag => $language) + { + $languages[$tag . '1'] = JText::sprintf('COM_LANGUAGES_VIEW_OVERRIDES_LANGUAGES_BOX_ITEM', $language['name'], JText::_('JADMINISTRATOR')); + } + + // Sort it by language tag and by client after that. + ksort($languages); + + // Add the languages to the internal cache. + $this->cache = array_merge(parent::getOptions(), $languages); + + return $this->cache; + } +} diff --git a/Sites/pages/administrator/components/com_languages/models/forms/filter_installed.xml b/Sites/pages/administrator/components/com_languages/models/forms/filter_installed.xml new file mode 100644 index 00000000..e25de546 --- /dev/null +++ b/Sites/pages/administrator/components/com_languages/models/forms/filter_installed.xml @@ -0,0 +1,63 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/Sites/pages/administrator/components/com_languages/models/forms/filter_languages.xml b/Sites/pages/administrator/components/com_languages/models/forms/filter_languages.xml new file mode 100644 index 00000000..6a92abe7 --- /dev/null +++ b/Sites/pages/administrator/components/com_languages/models/forms/filter_languages.xml @@ -0,0 +1,70 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/Sites/pages/administrator/components/com_languages/models/forms/filter_overrides.xml b/Sites/pages/administrator/components/com_languages/models/forms/filter_overrides.xml new file mode 100644 index 00000000..347a1677 --- /dev/null +++ b/Sites/pages/administrator/components/com_languages/models/forms/filter_overrides.xml @@ -0,0 +1,33 @@ + +
+ + + + + + + + + + + +
diff --git a/Sites/pages/administrator/components/com_languages/models/forms/language.xml b/Sites/pages/administrator/components/com_languages/models/forms/language.xml new file mode 100644 index 00000000..61e900bc --- /dev/null +++ b/Sites/pages/administrator/components/com_languages/models/forms/language.xml @@ -0,0 +1,128 @@ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+
+ +
+
diff --git a/Sites/pages/administrator/components/com_languages/models/forms/override.xml b/Sites/pages/administrator/components/com_languages/models/forms/override.xml new file mode 100644 index 00000000..8d1a2ddb --- /dev/null +++ b/Sites/pages/administrator/components/com_languages/models/forms/override.xml @@ -0,0 +1,90 @@ + +
+
+ + + + + + + + + + + + + + + + + + + + +
+
diff --git a/Sites/pages/administrator/components/com_languages/models/installed.php b/Sites/pages/administrator/components/com_languages/models/installed.php new file mode 100644 index 00000000..9dca49d6 --- /dev/null +++ b/Sites/pages/administrator/components/com_languages/models/installed.php @@ -0,0 +1,487 @@ +setState('filter.search', $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search', '', 'string')); + + // Special case for client id. + $clientId = (int) $this->getUserStateFromRequest($this->context . '.client_id', 'client_id', 0, 'int'); + $clientId = (!in_array($clientId, array (0, 1))) ? 0 : $clientId; + $this->setState('client_id', $clientId); + + // Load the parameters. + $params = JComponentHelper::getParams('com_languages'); + $this->setState('params', $params); + + // List state information. + parent::populateState($ordering, $direction); + } + + /** + * Method to get a store id based on model configuration state. + * + * This is necessary because the model is used by the component and + * different modules that might need different sets of data or different + * ordering requirements. + * + * @param string $id A prefix for the store id. + * + * @return string A store id. + * + * @since 1.6 + */ + protected function getStoreId($id = '') + { + // Compile the store id. + $id .= ':' . $this->getState('client_id'); + $id .= ':' . $this->getState('filter.search'); + + return parent::getStoreId($id); + } + + /** + * Method to get the client object. + * + * @return object + * + * @since 1.6 + */ + public function getClient() + { + return JApplicationHelper::getClientInfo($this->getState('client_id', 0)); + } + + /** + * Method to get the ftp credentials. + * + * @return object + * + * @since 1.6 + */ + public function getFtp() + { + if (is_null($this->ftp)) + { + $this->ftp = JClientHelper::setCredentialsFromRequest('ftp'); + } + + return $this->ftp; + } + + /** + * Method to get the option. + * + * @return object + * + * @since 1.6 + */ + public function getOption() + { + $option = $this->getState('option'); + + return $option; + } + + /** + * Method to get Languages item data. + * + * @return array + * + * @since 1.6 + */ + public function getData() + { + // Fetch language data if not fetched yet. + if (is_null($this->data)) + { + $this->data = array(); + + $isCurrentLanguageRtl = JFactory::getLanguage()->isRtl(); + $params = JComponentHelper::getParams('com_languages'); + $installedLanguages = JLanguageHelper::getInstalledLanguages(null, true, true, null, null, null); + + // Compute all the languages. + foreach ($installedLanguages as $clientId => $languages) + { + $defaultLanguage = $params->get(JApplicationHelper::getClientInfo($clientId)->name, 'en-GB'); + + foreach ($languages as $lang) + { + $row = new stdClass; + $row->language = $lang->element; + $row->name = $lang->metadata['name']; + $row->nativeName = isset($lang->metadata['nativeName']) ? $lang->metadata['nativeName'] : '-'; + $row->client_id = (int) $lang->client_id; + $row->extension_id = (int) $lang->extension_id; + $row->author = $lang->manifest['author']; + $row->creationDate = $lang->manifest['creationDate']; + $row->authorEmail = $lang->manifest['authorEmail']; + $row->version = $lang->manifest['version']; + $row->published = $defaultLanguage === $row->language ? 1 : 0; + $row->checked_out = 0; + + // Fix wrongly set parentheses in RTL languages + if ($isCurrentLanguageRtl) + { + $row->name = html_entity_decode($row->name . '‎', ENT_QUOTES, 'UTF-8'); + $row->nativeName = html_entity_decode($row->nativeName . '‎', ENT_QUOTES, 'UTF-8'); + } + + $this->data[] = $row; + } + } + } + + $installedLanguages = array_merge($this->data); + + // Process filters. + $clientId = (int) $this->getState('client_id'); + $search = $this->getState('filter.search'); + + foreach ($installedLanguages as $key => $installedLanguage) + { + // Filter by client id. + if (in_array($clientId, array(0, 1))) + { + if ($installedLanguage->client_id !== $clientId) + { + unset($installedLanguages[$key]); + continue; + } + } + + // Filter by search term. + if (!empty($search)) + { + if (stripos($installedLanguage->name, $search) === false + && stripos($installedLanguage->nativeName, $search) === false + && stripos($installedLanguage->language, $search) === false) + { + unset($installedLanguages[$key]); + continue; + } + } + } + + // Process ordering. + $listOrder = $this->getState('list.ordering', 'name'); + $listDirn = $this->getState('list.direction', 'ASC'); + $installedLanguages = ArrayHelper::sortObjects($installedLanguages, $listOrder, strtolower($listDirn) === 'desc' ? -1 : 1, true, true); + + // Process pagination. + $limit = (int) $this->getState('list.limit', 25); + + // Sets the total for pagination. + $this->total = count($installedLanguages); + + if ($limit !== 0) + { + $start = (int) $this->getState('list.start', 0); + + return array_slice($installedLanguages, $start, $limit); + } + + return $installedLanguages; + } + + /** + * Method to get installed languages data. + * + * @return string An SQL query. + * + * @since 1.6 + * + * @deprecated 4.0 + */ + protected function getLanguageList() + { + // Create a new db object. + $db = $this->getDbo(); + $query = $db->getQuery(true); + $client = $this->getState('client_id'); + $type = 'language'; + + // Select field element from the extensions table. + $query->select($this->getState('list.select', 'a.element')) + ->from('#__extensions AS a'); + + $type = $db->quote($type); + $query->where('(a.type = ' . $type . ')') + ->where('state = 0') + ->where('enabled = 1') + ->where('client_id=' . (int) $client); + + // For client_id = 1 do we need to check language table also? + $db->setQuery($query); + + $this->langlist = $db->loadColumn(); + + return $this->langlist; + } + + /** + * Method to get the total number of Languages items. + * + * @return integer + * + * @since 1.6 + */ + public function getTotal() + { + if (is_null($this->total)) + { + $this->getData(); + } + + return $this->total; + } + + /** + * Method to set the default language. + * + * @param integer $cid Id of the language to publish. + * + * @return boolean + * + * @since 1.6 + */ + public function publish($cid) + { + if ($cid) + { + $client = $this->getClient(); + + $params = JComponentHelper::getParams('com_languages'); + $params->set($client->name, $cid); + + $table = JTable::getInstance('extension'); + $id = $table->find(array('element' => 'com_languages')); + + // Load. + if (!$table->load($id)) + { + $this->setError($table->getError()); + + return false; + } + + $table->params = (string) $params; + + // Pre-save checks. + if (!$table->check()) + { + $this->setError($table->getError()); + + return false; + } + + // Save the changes. + if (!$table->store()) + { + $this->setError($table->getError()); + + return false; + } + } + else + { + $this->setError(JText::_('COM_LANGUAGES_ERR_NO_LANGUAGE_SELECTED')); + + return false; + } + + // Clean the cache of com_languages and component cache. + $this->cleanCache(); + $this->cleanCache('_system', 0); + $this->cleanCache('_system', 1); + + return true; + } + + /** + * Method to get the folders. + * + * @return array Languages folders. + * + * @since 1.6 + */ + protected function getFolders() + { + if (is_null($this->folders)) + { + $path = $this->getPath(); + jimport('joomla.filesystem.folder'); + $this->folders = JFolder::folders($path, '.', false, false, array('.svn', 'CVS', '.DS_Store', '__MACOSX', 'pdf_fonts', 'overrides')); + } + + return $this->folders; + } + + /** + * Method to get the path. + * + * @return string The path to the languages folders. + * + * @since 1.6 + */ + protected function getPath() + { + if (is_null($this->path)) + { + $client = $this->getClient(); + $this->path = JLanguageHelper::getLanguagePath($client->path); + } + + return $this->path; + } + + /** + * Method to compare two languages in order to sort them. + * + * @param object $lang1 The first language. + * @param object $lang2 The second language. + * + * @return integer + * + * @since 1.6 + * + * @deprecated 4.0 + */ + protected function compareLanguages($lang1, $lang2) + { + return strcmp($lang1->name, $lang2->name); + } + + /** + * Method to switch the administrator language. + * + * @param string $cid The language tag. + * + * @return boolean + * + * @since 3.5 + */ + public function switchAdminLanguage($cid) + { + if ($cid) + { + $client = $this->getClient(); + + if ($client->name == 'administrator') + { + JFactory::getApplication()->setUserState('application.lang', $cid); + } + } + else + { + JError::raiseWarning(500, JText::_('COM_LANGUAGES_ERR_NO_LANGUAGE_SELECTED')); + + return false; + } + + return true; + } +} diff --git a/Sites/pages/administrator/components/com_languages/models/language.php b/Sites/pages/administrator/components/com_languages/models/language.php new file mode 100644 index 00000000..570e172c --- /dev/null +++ b/Sites/pages/administrator/components/com_languages/models/language.php @@ -0,0 +1,275 @@ + 'onExtensionAfterSave', + 'event_before_save' => 'onExtensionBeforeSave', + 'events_map' => array( + 'save' => 'extension' + ) + ), $config + ); + + parent::__construct($config); + } + + /** + * Override to get the table. + * + * @param string $name Name of the table. + * @param string $prefix Table name prefix. + * @param array $options Array of options. + * + * @return JTable + * + * @since 1.6 + */ + public function getTable($name = '', $prefix = '', $options = array()) + { + return JTable::getInstance('Language'); + } + + /** + * Method to auto-populate the model state. + * + * Note. Calling getState in this method will result in recursion. + * + * @return void + * + * @since 1.6 + */ + protected function populateState() + { + $app = JFactory::getApplication('administrator'); + $params = JComponentHelper::getParams('com_languages'); + + // Load the User state. + $langId = $app->input->getInt('lang_id'); + $this->setState('language.id', $langId); + + // Load the parameters. + $this->setState('params', $params); + } + + /** + * Method to get a member item. + * + * @param integer $langId The id of the member to get. + * + * @return mixed User data object on success, false on failure. + * + * @since 1.0 + */ + public function getItem($langId = null) + { + $langId = (!empty($langId)) ? $langId : (int) $this->getState('language.id'); + + // Get a member row instance. + $table = $this->getTable(); + + // Attempt to load the row. + $return = $table->load($langId); + + // Check for a table object error. + if ($return === false && $table->getError()) + { + $this->setError($table->getError()); + + return false; + } + + // Set a valid accesslevel in case '0' is stored due to a bug in the installation SQL (was fixed with PR 2714). + if ($table->access == '0') + { + $table->access = (int) JFactory::getConfig()->get('access'); + } + + $properties = $table->getProperties(1); + $value = ArrayHelper::toObject($properties, 'JObject'); + + return $value; + } + + /** + * Method to get the group form. + * + * @param array $data Data for the form. + * @param boolean $loadData True if the form is to load its own data (default case), false if not. + * + * @return mixed A JForm object on success, false on failure. + * + * @since 1.6 + */ + public function getForm($data = array(), $loadData = true) + { + // Get the form. + $form = $this->loadForm('com_languages.language', 'language', array('control' => 'jform', 'load_data' => $loadData)); + + if (empty($form)) + { + return false; + } + + return $form; + } + + /** + * Method to get the data that should be injected in the form. + * + * @return mixed The data for the form. + * + * @since 1.6 + */ + protected function loadFormData() + { + // Check the session for previously entered form data. + $data = JFactory::getApplication()->getUserState('com_languages.edit.language.data', array()); + + if (empty($data)) + { + $data = $this->getItem(); + } + + $this->preprocessData('com_languages.language', $data); + + return $data; + } + + /** + * Method to save the form data. + * + * @param array $data The form data. + * + * @return boolean True on success. + * + * @since 1.6 + */ + public function save($data) + { + $langId = (!empty($data['lang_id'])) ? $data['lang_id'] : (int) $this->getState('language.id'); + $isNew = true; + + $dispatcher = JEventDispatcher::getInstance(); + JPluginHelper::importPlugin($this->events_map['save']); + + $table = $this->getTable(); + $context = $this->option . '.' . $this->name; + + // Load the row if saving an existing item. + if ($langId > 0) + { + $table->load($langId); + $isNew = false; + } + + // Prevent white spaces, including East Asian double bytes. + $spaces = array('/\xE3\x80\x80/', ' '); + + $data['lang_code'] = str_replace($spaces, '', $data['lang_code']); + + // Prevent saving an incorrect language tag + if (!preg_match('#\b([a-z]{2,3})[-]([A-Z]{2})\b#', $data['lang_code'])) + { + $this->setError(JText::_('COM_LANGUAGES_ERROR_LANG_TAG')); + + return false; + } + + $data['sef'] = str_replace($spaces, '', $data['sef']); + $data['sef'] = JApplicationHelper::stringURLSafe($data['sef']); + + // Prevent saving an empty url language code + if ($data['sef'] === '') + { + $this->setError(JText::_('COM_LANGUAGES_ERROR_SEF')); + + return false; + } + + // Bind the data. + if (!$table->bind($data)) + { + $this->setError($table->getError()); + + return false; + } + + // Check the data. + if (!$table->check()) + { + $this->setError($table->getError()); + + return false; + } + + // Trigger the before save event. + $result = $dispatcher->trigger($this->event_before_save, array($context, &$table, $isNew)); + + // Check the event responses. + if (in_array(false, $result, true)) + { + $this->setError($table->getError()); + + return false; + } + + // Store the data. + if (!$table->store()) + { + $this->setError($table->getError()); + + return false; + } + + // Trigger the after save event. + $dispatcher->trigger($this->event_after_save, array($context, &$table, $isNew)); + + $this->setState('language.id', $table->lang_id); + + // Clean the cache. + $this->cleanCache(); + + return true; + } + + /** + * Custom clean cache method. + * + * @param string $group Optional cache group name. + * @param integer $clientId Application client id. + * + * @return void + * + * @since 1.6 + */ + protected function cleanCache($group = null, $clientId = 0) + { + parent::cleanCache('_system'); + parent::cleanCache('com_languages'); + } +} diff --git a/Sites/pages/administrator/components/com_languages/models/languages.php b/Sites/pages/administrator/components/com_languages/models/languages.php new file mode 100644 index 00000000..27cf8387 --- /dev/null +++ b/Sites/pages/administrator/components/com_languages/models/languages.php @@ -0,0 +1,220 @@ +setState('filter.search', $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search', '', 'string')); + $this->setState('filter.access', $this->getUserStateFromRequest($this->context . '.filter.access', 'filter_access', '', 'cmd')); + $this->setState('filter.published', $this->getUserStateFromRequest($this->context . '.filter.published', 'filter_published', '', 'string')); + + // Load the parameters. + $params = JComponentHelper::getParams('com_languages'); + $this->setState('params', $params); + + // List state information. + parent::populateState($ordering, $direction); + } + + /** + * Method to get a store id based on model configuration state. + * + * This is necessary because the model is used by the component and + * different modules that might need different sets of data or different + * ordering requirements. + * + * @param string $id A prefix for the store id. + * + * @return string A store id. + * + * @since 1.6 + */ + protected function getStoreId($id = '') + { + // Compile the store id. + $id .= ':' . $this->getState('filter.search'); + $id .= ':' . $this->getState('filter.access'); + $id .= ':' . $this->getState('filter.published'); + + return parent::getStoreId($id); + } + + /** + * Method to build an SQL query to load the list data. + * + * @return string An SQL query + * + * @since 1.6 + */ + protected function getListQuery() + { + // Create a new query object. + $db = $this->getDbo(); + $query = $db->getQuery(true); + + // Select all fields from the languages table. + $query->select($this->getState('list.select', 'a.*', 'l.home')) + ->from($db->quoteName('#__languages') . ' AS a'); + + // Join over the asset groups. + $query->select('ag.title AS access_level') + ->join('LEFT', '#__viewlevels AS ag ON ag.id = a.access'); + + // Select the language home pages. + $query->select('l.home AS home') + ->join('LEFT', $db->quoteName('#__menu') . ' AS l ON l.language = a.lang_code AND l.home=1 AND l.language <> ' . $db->quote('*')); + + // Filter on the published state. + $published = $this->getState('filter.published'); + + if (is_numeric($published)) + { + $query->where('a.published = ' . (int) $published); + } + elseif ($published === '') + { + $query->where('(a.published IN (0, 1))'); + } + + // Filter by search in title. + $search = $this->getState('filter.search'); + + if (!empty($search)) + { + $search = $db->quote('%' . str_replace(' ', '%', $db->escape(trim($search), true) . '%')); + $query->where('(a.title LIKE ' . $search . ')'); + } + + // Filter by access level. + if ($access = $this->getState('filter.access')) + { + $query->where('a.access = ' . (int) $access); + } + + // Add the list ordering clause. + $query->order($db->escape($this->getState('list.ordering', 'a.ordering')) . ' ' . $db->escape($this->getState('list.direction', 'ASC'))); + + return $query; + } + + /** + * Set the published language(s). + * + * @param array $cid An array of language IDs. + * @param integer $value The value of the published state. + * + * @return boolean True on success, false otherwise. + * + * @since 1.6 + */ + public function setPublished($cid, $value = 0) + { + return JTable::getInstance('Language')->publish($cid, $value); + } + + /** + * Method to delete records. + * + * @param array $pks An array of item primary keys. + * + * @return boolean Returns true on success, false on failure. + * + * @since 1.6 + */ + public function delete($pks) + { + // Sanitize the array. + $pks = (array) $pks; + + // Get a row instance. + $table = JTable::getInstance('Language'); + + // Iterate the items to delete each one. + foreach ($pks as $itemId) + { + if (!$table->delete((int) $itemId)) + { + $this->setError($table->getError()); + + return false; + } + } + + // Clean the cache. + $this->cleanCache(); + + return true; + } + + /** + * Custom clean cache method, 2 places for 2 clients. + * + * @param string $group Optional cache group name. + * @param integer $clientId Application client id. + * + * @return void + * + * @since 1.6 + */ + protected function cleanCache($group = null, $clientId = 0) + { + parent::cleanCache('_system'); + parent::cleanCache('com_languages'); + } +} diff --git a/Sites/pages/administrator/components/com_languages/models/override.php b/Sites/pages/administrator/components/com_languages/models/override.php new file mode 100644 index 00000000..09259403 --- /dev/null +++ b/Sites/pages/administrator/components/com_languages/models/override.php @@ -0,0 +1,212 @@ +loadForm('com_languages.override', 'override', array('control' => 'jform', 'load_data' => $loadData)); + + if (empty($form)) + { + return false; + } + + $client = $this->getState('filter.client', 'site'); + $language = $this->getState('filter.language', 'en-GB'); + $langName = JLanguage::getInstance($language)->getName(); + + if (!$langName) + { + // If a language only exists in frontend, its metadata cannot be + // loaded in backend at the moment, so fall back to the language tag. + $langName = $language; + } + + $form->setValue('client', null, JText::_('COM_LANGUAGES_VIEW_OVERRIDE_CLIENT_' . strtoupper($client))); + $form->setValue('language', null, JText::sprintf('COM_LANGUAGES_VIEW_OVERRIDE_LANGUAGE', $langName, $language)); + $form->setValue('file', null, JPath::clean(constant('JPATH_' . strtoupper($client)) . '/language/overrides/' . $language . '.override.ini')); + + return $form; + } + + /** + * Method to get the data that should be injected in the form. + * + * @return mixed The data for the form. + * + * @since 2.5 + */ + protected function loadFormData() + { + // Check the session for previously entered form data. + $data = JFactory::getApplication()->getUserState('com_languages.edit.override.data', array()); + + if (empty($data)) + { + $data = $this->getItem(); + } + + $this->preprocessData('com_languages.override', $data); + + return $data; + } + + /** + * Method to get a single record. + * + * @param string $pk The key name. + * + * @return mixed Object on success, false otherwise. + * + * @since 2.5 + */ + public function getItem($pk = null) + { + $input = JFactory::getApplication()->input; + $pk = !empty($pk) ? $pk : $input->get('id'); + $fileName = constant('JPATH_' . strtoupper($this->getState('filter.client'))) + . '/language/overrides/' . $this->getState('filter.language', 'en-GB') . '.override.ini'; + $strings = JLanguageHelper::parseIniFile($fileName); + + $result = new stdClass; + $result->key = ''; + $result->override = ''; + + if (isset($strings[$pk])) + { + $result->key = $pk; + $result->override = $strings[$pk]; + } + + $oppositeFileName = constant('JPATH_' . strtoupper($this->getState('filter.client') == 'site' ? 'administrator' : 'site')) + . '/language/overrides/' . $this->getState('filter.language', 'en-GB') . '.override.ini'; + $oppositeStrings = JLanguageHelper::parseIniFile($oppositeFileName); + $result->both = isset($oppositeStrings[$pk]) && ($oppositeStrings[$pk] == $strings[$pk]); + + return $result; + } + + /** + * Method to save the form data. + * + * @param array $data The form data. + * @param boolean $oppositeClient Indicates whether the override should not be created for the current client. + * + * @return boolean True on success, false otherwise. + * + * @since 2.5 + */ + public function save($data, $oppositeClient = false) + { + jimport('joomla.filesystem.file'); + + $app = JFactory::getApplication(); + + $client = $app->getUserState('com_languages.overrides.filter.client', 0); + $language = $app->getUserState('com_languages.overrides.filter.language', 'en-GB'); + + // If the override should be created for both. + if ($oppositeClient) + { + $client = 1 - $client; + } + + // Return false if the constant is a reserved word, i.e. YES, NO, NULL, FALSE, ON, OFF, NONE, TRUE + $blacklist = array('YES', 'NO', 'NULL', 'FALSE', 'ON', 'OFF', 'NONE', 'TRUE'); + + if (in_array($data['key'], $blacklist)) + { + $this->setError(JText::_('COM_LANGUAGES_OVERRIDE_ERROR_RESERVED_WORDS')); + + return false; + } + + $client = $client ? 'administrator' : 'site'; + + // Parse the override.ini file in oder to get the keys and strings. + $fileName = constant('JPATH_' . strtoupper($client)) . '/language/overrides/' . $language . '.override.ini'; + $strings = JLanguageHelper::parseIniFile($fileName); + + if (isset($strings[$data['id']])) + { + // If an existent string was edited check whether + // the name of the constant is still the same. + if ($data['key'] == $data['id']) + { + // If yes, simply override it. + $strings[$data['key']] = $data['override']; + } + else + { + // If no, delete the old string and prepend the new one. + unset($strings[$data['id']]); + $strings = array($data['key'] => $data['override']) + $strings; + } + } + else + { + // If it is a new override simply prepend it. + $strings = array($data['key'] => $data['override']) + $strings; + } + + // Write override.ini file with the strings. + if (JLanguageHelper::saveToIniFile($fileName, $strings) === false) + { + return false; + } + + // If the override should be stored for both clients save + // it also for the other one and prevent endless recursion. + if (isset($data['both']) && $data['both'] && !$oppositeClient) + { + return $this->save($data, true); + } + + return true; + } + + /** + * Method to auto-populate the model state. + * + * Note. Calling getState in this method will result in recursion. + * + * @return void + * + * @since 2.5 + */ + protected function populateState() + { + $app = JFactory::getApplication(); + + $client = $app->getUserStateFromRequest('com_languages.overrides.filter.client', 'filter_client', 0, 'int') ? 'administrator' : 'site'; + $this->setState('filter.client', $client); + + $language = $app->getUserStateFromRequest('com_languages.overrides.filter.language', 'filter_language', 'en-GB', 'cmd'); + $this->setState('filter.language', $language); + } +} diff --git a/Sites/pages/administrator/components/com_languages/models/overrides.php b/Sites/pages/administrator/components/com_languages/models/overrides.php new file mode 100644 index 00000000..9b1cf294 --- /dev/null +++ b/Sites/pages/administrator/components/com_languages/models/overrides.php @@ -0,0 +1,247 @@ +filter_fields = array('key', 'text'); + } + + /** + * Retrieves the overrides data + * + * @param boolean $all True if all overrides shall be returned without considering pagination, defaults to false + * + * @return array Array of objects containing the overrides of the override.ini file + * + * @since 2.5 + */ + public function getOverrides($all = false) + { + // Get a storage key. + $store = $this->getStoreId(); + + // Try to load the data from internal storage. + if (!empty($this->cache[$store])) + { + return $this->cache[$store]; + } + + $client = strtoupper($this->getState('filter.client')); + + // Parse the override.ini file in order to get the keys and strings. + $fileName = constant('JPATH_' . $client) . '/language/overrides/' . $this->getState('filter.language') . '.override.ini'; + $strings = JLanguageHelper::parseIniFile($fileName); + + // Delete the override.ini file if empty. + if (file_exists($fileName) && $strings === array()) + { + JFile::delete($fileName); + } + + // Filter the loaded strings according to the search box. + $search = $this->getState('filter.search'); + + if ($search != '') + { + $search = preg_quote($search, '~'); + $matchvals = preg_grep('~' . $search . '~i', $strings); + $matchkeys = array_intersect_key($strings, array_flip(preg_grep('~' . $search . '~i', array_keys($strings)))); + $strings = array_merge($matchvals, $matchkeys); + } + + // Consider the ordering + if ($this->getState('list.ordering') == 'text') + { + if (strtoupper($this->getState('list.direction')) == 'DESC') + { + arsort($strings); + } + else + { + asort($strings); + } + } + else + { + if (strtoupper($this->getState('list.direction')) == 'DESC') + { + krsort($strings); + } + else + { + ksort($strings); + } + } + + // Consider the pagination. + if (!$all && $this->getState('list.limit') && $this->getTotal() > $this->getState('list.limit')) + { + $strings = array_slice($strings, $this->getStart(), $this->getState('list.limit'), true); + } + + // Add the items to the internal cache. + $this->cache[$store] = $strings; + + return $this->cache[$store]; + } + + /** + * Method to get the total number of overrides. + * + * @return integer The total number of overrides. + * + * @since 2.5 + */ + public function getTotal() + { + // Get a storage key. + $store = $this->getStoreId('getTotal'); + + // Try to load the data from internal storage + if (!empty($this->cache[$store])) + { + return $this->cache[$store]; + } + + // Add the total to the internal cache. + $this->cache[$store] = count($this->getOverrides(true)); + + return $this->cache[$store]; + } + + /** + * Method to auto-populate the model state. + * + * Note. Calling getState in this method will result in recursion. + * + * @param string $ordering An optional ordering field. + * @param string $direction An optional direction (asc|desc). + * + * @return void + * + * @since 2.5 + */ + protected function populateState($ordering = 'key', $direction = 'asc') + { + // We call populate state first so that we can then set the filter.client and filter.language properties in afterwards + parent::populateState($ordering, $direction); + + $app = JFactory::getApplication(); + + $language_client = $this->getUserStateFromRequest('com_languages.overrides.language_client', 'language_client', '', 'cmd'); + $client = substr($language_client, -1); + $language = substr($language_client, 0, -1); + + // Sets the search filter. + $search = $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search'); + $this->setState('filter.search', $search); + + $this->setState('language_client', $language . $client); + $this->setState('filter.client', $client ? 'administrator' : 'site'); + $this->setState('filter.language', $language); + + // Add the 'language_client' value to the session to display a message if none selected + $app->setUserState('com_languages.overrides.language_client', $language . $client); + + // Add filters to the session because they won't be stored there by 'getUserStateFromRequest' if they aren't in the current request. + $app->setUserState('com_languages.overrides.filter.client', $client); + $app->setUserState('com_languages.overrides.filter.language', $language); + } + + /** + * Method to delete one or more overrides. + * + * @param array $cids Array of keys to delete. + * + * @return integer Number of successfully deleted overrides, boolean false if an error occurred. + * + * @since 2.5 + */ + public function delete($cids) + { + // Check permissions first. + if (!JFactory::getUser()->authorise('core.delete', 'com_languages')) + { + $this->setError(JText::_('JLIB_APPLICATION_ERROR_DELETE_NOT_PERMITTED')); + + return false; + } + + jimport('joomla.filesystem.file'); + + $filterclient = JFactory::getApplication()->getUserState('com_languages.overrides.filter.client'); + $client = $filterclient == 0 ? 'SITE' : 'ADMINISTRATOR'; + + // Parse the override.ini file in oder to get the keys and strings. + $fileName = constant('JPATH_' . $client) . '/language/overrides/' . $this->getState('filter.language') . '.override.ini'; + $strings = JLanguageHelper::parseIniFile($fileName); + + // Unset strings that shall be deleted + foreach ($cids as $key) + { + if (isset($strings[$key])) + { + unset($strings[$key]); + } + } + + // Write override.ini file with the strings. + if (JLanguageHelper::saveToIniFile($fileName, $strings) === false) + { + return false; + } + + $this->cleanCache(); + + return count($cids); + } + + /** + * Removes all of the cached strings from the table. + * + * @return boolean result of operation + * + * @since 3.4.2 + */ + public function purge() + { + $db = JFactory::getDbo(); + + // Note: TRUNCATE is a DDL operation + // This may or may not mean depending on your database + try + { + $db->truncateTable('#__overrider'); + } + catch (RuntimeException $e) + { + return $e; + } + + JFactory::getApplication()->enqueueMessage(JText::_('COM_LANGUAGES_VIEW_OVERRIDES_PURGE_SUCCESS')); + } +} diff --git a/Sites/pages/administrator/components/com_languages/models/strings.php b/Sites/pages/administrator/components/com_languages/models/strings.php new file mode 100644 index 00000000..bcf989f3 --- /dev/null +++ b/Sites/pages/administrator/components/com_languages/models/strings.php @@ -0,0 +1,167 @@ +setUserState('com_languages.overrides.cachedtime', null); + + // Empty the database cache first. + try + { + $this->_db->setQuery('TRUNCATE TABLE ' . $this->_db->quoteName('#__overrider')); + $this->_db->execute(); + } + catch (RuntimeException $e) + { + return $e; + } + + // Create the insert query. + $query = $this->_db->getQuery(true) + ->insert($this->_db->quoteName('#__overrider')) + ->columns('constant, string, file'); + + // Initialize some variables. + $client = $app->getUserState('com_languages.overrides.filter.client', 'site') ? 'administrator' : 'site'; + $language = $app->getUserState('com_languages.overrides.filter.language', 'en-GB'); + + $base = constant('JPATH_' . strtoupper($client)); + $path = $base . '/language/' . $language; + + $files = array(); + + // Parse common language directory. + jimport('joomla.filesystem.folder'); + + if (is_dir($path)) + { + $files = JFolder::files($path, $language . '.*ini$', false, true); + } + + // Parse language directories of components. + $files = array_merge($files, JFolder::files($base . '/components', $language . '.*ini$', 3, true)); + + // Parse language directories of modules. + $files = array_merge($files, JFolder::files($base . '/modules', $language . '.*ini$', 3, true)); + + // Parse language directories of templates. + $files = array_merge($files, JFolder::files($base . '/templates', $language . '.*ini$', 3, true)); + + // Parse language directories of plugins. + $files = array_merge($files, JFolder::files(JPATH_PLUGINS, $language . '.*ini$', 4, true)); + + // Parse all found ini files and add the strings to the database cache. + foreach ($files as $file) + { + $strings = LanguagesHelper::parseFile($file); + + if ($strings && count($strings)) + { + $query->clear('values'); + + foreach ($strings as $key => $string) + { + $query->values($this->_db->quote($key) . ',' . $this->_db->quote($string) . ',' . $this->_db->quote(JPath::clean($file))); + } + + try + { + $this->_db->setQuery($query); + $this->_db->execute(); + } + catch (RuntimeException $e) + { + return $e; + } + } + } + + // Update the cached time. + $app->setUserState('com_languages.overrides.cachedtime.' . $client . '.' . $language, time()); + + return true; + } + + /** + * Method for searching language strings. + * + * @return array Array of results on success, Exception object otherwise. + * + * @since 2.5 + */ + public function search() + { + $results = array(); + $input = JFactory::getApplication()->input; + $filter = JFilterInput::getInstance(); + $searchTerm = $input->getString('searchstring'); + + $limitstart = $input->getInt('more'); + + try + { + $searchstring = $this->_db->quote('%' . $filter->clean($searchTerm, 'TRIM') . '%'); + + // Create the search query. + $query = $this->_db->getQuery(true) + ->select('constant, string, file') + ->from($this->_db->quoteName('#__overrider')); + + if ($input->get('searchtype') == 'constant') + { + $query->where('constant LIKE ' . $searchstring); + } + else + { + $query->where('string LIKE ' . $searchstring); + } + + // Consider the limitstart according to the 'more' parameter and load the results. + $this->_db->setQuery($query, $limitstart, 10); + $results['results'] = $this->_db->loadObjectList(); + + // Check whether there are more results than already loaded. + $query->clear('select')->clear('limit') + ->select('COUNT(id)'); + $this->_db->setQuery($query); + + if ($this->_db->loadResult() > $limitstart + 10) + { + // If this is set a 'More Results' link will be displayed in the view. + $results['more'] = $limitstart + 10; + } + } + catch (RuntimeException $e) + { + return $e; + } + + return $results; + } +} diff --git a/Sites/pages/administrator/components/com_languages/views/installed/tmpl/default.php b/Sites/pages/administrator/components/com_languages/views/installed/tmpl/default.php new file mode 100644 index 00000000..7e12dc5f --- /dev/null +++ b/Sites/pages/administrator/components/com_languages/views/installed/tmpl/default.php @@ -0,0 +1,132 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +?> +
+sidebar)) : ?> +
+ sidebar; ?> +
+
+ +
+ + $this)); ?> + total > 0) : ?> + + + + + + + + + + + + + + + + + + + + + + getShortVersion()); + foreach ($this->rows as $i => $row) : + $canCreate = $user->authorise('core.create', 'com_languages'); + $canEdit = $user->authorise('core.edit', 'com_languages'); + $canChange = $user->authorise('core.edit.state', 'com_languages'); + ?> + + + + + + + + + + + + + + +
+   + + + + + + + + + + + + + + + + + + +
+ pagination->getListFooter(); ?> +
+ language); ?> + + + + escape($row->nativeName); ?> + + escape($row->language); ?> + + published, $i, 'installed.', !$row->published && $canChange); ?> + + + + version, $minorVersion) !== 0 || strpos($row->version, $currentShortVersion) !== 0) : ?> + version; ?> + + version; ?> + + + escape($row->creationDate); ?> + + escape($row->author); ?> + + escape($row->authorEmail)); ?> + + escape($row->extension_id); ?> +
+ + + + +
+ diff --git a/Sites/pages/administrator/components/com_languages/views/installed/tmpl/default.xml b/Sites/pages/administrator/components/com_languages/views/installed/tmpl/default.xml new file mode 100755 index 00000000..3c92e7d9 --- /dev/null +++ b/Sites/pages/administrator/components/com_languages/views/installed/tmpl/default.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/Sites/pages/administrator/components/com_languages/views/installed/view.html.php b/Sites/pages/administrator/components/com_languages/views/installed/view.html.php new file mode 100644 index 00000000..19d7edd2 --- /dev/null +++ b/Sites/pages/administrator/components/com_languages/views/installed/view.html.php @@ -0,0 +1,130 @@ +ftp = $this->get('Ftp'); + $this->option = $this->get('Option'); + $this->pagination = $this->get('Pagination'); + $this->rows = $this->get('Data'); + $this->total = $this->get('Total'); + $this->state = $this->get('State'); + $this->filterForm = $this->get('FilterForm'); + $this->activeFilters = $this->get('ActiveFilters'); + + LanguagesHelper::addSubmenu('installed'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + $this->addToolbar(); + + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + $canDo = JHelperContent::getActions('com_languages'); + + if ((int) $this->state->get('client_id') === 1) + { + JToolbarHelper::title(JText::_('COM_LANGUAGES_VIEW_INSTALLED_ADMIN_TITLE'), 'comments-2 langmanager'); + } + else + { + JToolbarHelper::title(JText::_('COM_LANGUAGES_VIEW_INSTALLED_SITE_TITLE'), 'comments-2 langmanager'); + } + + if ($canDo->get('core.edit.state')) + { + JToolbarHelper::makeDefault('installed.setDefault'); + JToolbarHelper::divider(); + } + + if ($canDo->get('core.admin')) + { + // Add install languages link to the lang installer component. + $bar = JToolbar::getInstance('toolbar'); + + // Switch administrator language + if ($this->state->get('client_id', 0) == 1) + { + JToolbarHelper::custom('installed.switchadminlanguage', 'refresh', 'refresh', 'COM_LANGUAGES_SWITCH_ADMIN', false); + JToolbarHelper::divider(); + } + + $bar->appendButton('Link', 'upload', 'COM_LANGUAGES_INSTALL', 'index.php?option=com_installer&view=languages'); + JToolbarHelper::divider(); + + JToolbarHelper::preferences('com_languages'); + JToolbarHelper::divider(); + } + + JToolbarHelper::help('JHELP_EXTENSIONS_LANGUAGE_MANAGER_INSTALLED'); + + $this->sidebar = JHtmlSidebar::render(); + } +} diff --git a/Sites/pages/administrator/components/com_languages/views/language/tmpl/edit.php b/Sites/pages/administrator/components/com_languages/views/language/tmpl/edit.php new file mode 100644 index 00000000..6786c656 --- /dev/null +++ b/Sites/pages/administrator/components/com_languages/views/language/tmpl/edit.php @@ -0,0 +1,86 @@ +addScriptDeclaration( + ' + Joomla.submitbutton = function(task) + { + if (task == "language.cancel" || document.formvalidator.isValid(document.getElementById("language-form"))) + { + Joomla.submitform(task, document.getElementById("language-form")); + } + }; + + jQuery(document).ready(function() { + jQuery("#jform_image").on("change", function() { + var flag = this.value; + if (flag) { + jQuery("#flag img").attr("src", "' . JUri::root(true) . '" + "/media/mod_languages/images/" + flag + ".gif").attr("alt", flag); + } + else + { + jQuery("#flag img").removeAttr("src").removeAttr("alt"); + } + }); +});' +); +?> + +
+ + + +
+ 'details')); ?> + + + form->renderField('title'); ?> + form->renderField('title_native'); ?> + form->renderField('lang_code'); ?> + form->renderField('sef'); ?> +
+
+ form->getLabel('image'); ?> +
+
+ form->getInput('image'); ?> + + form->getValue('image') . '.gif', $this->form->getValue('image'), null, true); ?> + +
+
+ canDo->get('core.edit.state')) : ?> + form->renderField('published'); ?> + + + form->renderField('access'); ?> + form->renderField('description'); ?> + form->renderField('lang_id'); ?> + + + + form->renderFieldset('metadata'); ?> + + + + form->renderFieldset('site_name'); ?> + + + +
+ + +
diff --git a/Sites/pages/administrator/components/com_languages/views/language/view.html.php b/Sites/pages/administrator/components/com_languages/views/language/view.html.php new file mode 100644 index 00000000..1ce2b71c --- /dev/null +++ b/Sites/pages/administrator/components/com_languages/views/language/view.html.php @@ -0,0 +1,92 @@ +item = $this->get('Item'); + $this->form = $this->get('Form'); + $this->state = $this->get('State'); + $this->canDo = JHelperContent::getActions('com_languages'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + $this->addToolbar(); + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + JLoader::register('LanguagesHelper', JPATH_ADMINISTRATOR . '/components/com_languages/helpers/languages.php'); + + JFactory::getApplication()->input->set('hidemainmenu', 1); + $isNew = empty($this->item->lang_id); + $canDo = $this->canDo; + + JToolbarHelper::title( + JText::_($isNew ? 'COM_LANGUAGES_VIEW_LANGUAGE_EDIT_NEW_TITLE' : 'COM_LANGUAGES_VIEW_LANGUAGE_EDIT_EDIT_TITLE'), 'comments-2 langmanager' + ); + + if (($isNew && $canDo->get('core.create')) || (!$isNew && $canDo->get('core.edit'))) + { + JToolbarHelper::apply('language.apply'); + JToolbarHelper::save('language.save'); + } + + // If an existing item, can save to a copy only if we have create rights. + if ($canDo->get('core.create')) + { + JToolbarHelper::save2new('language.save2new'); + } + + if ($isNew) + { + JToolbarHelper::cancel('language.cancel'); + } + else + { + JToolbarHelper::cancel('language.cancel', 'JTOOLBAR_CLOSE'); + } + + JToolbarHelper::divider(); + JToolbarHelper::help('JHELP_EXTENSIONS_LANGUAGE_MANAGER_EDIT'); + } +} diff --git a/Sites/pages/administrator/components/com_languages/views/languages/tmpl/default.php b/Sites/pages/administrator/components/com_languages/views/languages/tmpl/default.php new file mode 100644 index 00000000..e3c395b5 --- /dev/null +++ b/Sites/pages/administrator/components/com_languages/views/languages/tmpl/default.php @@ -0,0 +1,166 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$saveOrder = $listOrder == 'a.ordering'; + +if ($saveOrder) +{ + $saveOrderingUrl = 'index.php?option=com_languages&task=languages.saveOrderAjax&tmpl=component'; + JHtml::_('sortablelist.sortable', 'contentList', 'adminForm', strtolower($listDirn), $saveOrderingUrl); +} +?> +
+sidebar)) : ?> +
+ sidebar; ?> +
+
+ +
+ + $this)); ?> +
+ items)) : ?> +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + items as $i => $item) : + $canCreate = $user->authorise('core.create', 'com_languages'); + $canEdit = $user->authorise('core.edit', 'com_languages'); + $canChange = $user->authorise('core.edit.state', 'com_languages'); + ?> + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + +
+ pagination->getListFooter(); ?> +
+ + + + + + + + + + + + lang_id); ?> + + published, $i, 'languages.', $canChange); ?> + + + + escape($item->title); ?> + + escape($item->title); ?> + + + + escape($item->title_native); ?> + + escape($item->lang_code); ?> + + escape($item->sef); ?> + + image) : ?> + image . '.gif', $item->image, null, true); ?> escape($item->image); ?> + + + + + escape($item->access_level); ?> + + home == '1') ? JText::_('JYES') : JText::_('JNO'); ?> + + escape($item->lang_id); ?> +
+ + + + +
+ diff --git a/Sites/pages/administrator/components/com_languages/views/languages/tmpl/default.xml b/Sites/pages/administrator/components/com_languages/views/languages/tmpl/default.xml new file mode 100755 index 00000000..4c7a003f --- /dev/null +++ b/Sites/pages/administrator/components/com_languages/views/languages/tmpl/default.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/Sites/pages/administrator/components/com_languages/views/languages/view.html.php b/Sites/pages/administrator/components/com_languages/views/languages/view.html.php new file mode 100644 index 00000000..8504a6fe --- /dev/null +++ b/Sites/pages/administrator/components/com_languages/views/languages/view.html.php @@ -0,0 +1,136 @@ +items = $this->get('Items'); + $this->pagination = $this->get('Pagination'); + $this->state = $this->get('State'); + $this->filterForm = $this->get('FilterForm'); + $this->activeFilters = $this->get('ActiveFilters'); + + LanguagesHelper::addSubmenu('languages'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + $this->addToolbar(); + $this->sidebar = JHtmlSidebar::render(); + + return parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + $canDo = JHelperContent::getActions('com_languages'); + + JToolbarHelper::title(JText::_('COM_LANGUAGES_VIEW_LANGUAGES_TITLE'), 'comments-2 langmanager'); + + if ($canDo->get('core.create')) + { + JToolbarHelper::addNew('language.add'); + } + + if ($canDo->get('core.edit')) + { + JToolbarHelper::editList('language.edit'); + JToolbarHelper::divider(); + } + + if ($canDo->get('core.edit.state')) + { + if ($this->state->get('filter.published') != 2) + { + JToolbarHelper::publishList('languages.publish'); + JToolbarHelper::unpublishList('languages.unpublish'); + } + } + + if ($this->state->get('filter.published') == -2 && $canDo->get('core.delete')) + { + JToolbarHelper::deleteList('JGLOBAL_CONFIRM_DELETE', 'languages.delete', 'JTOOLBAR_EMPTY_TRASH'); + JToolbarHelper::divider(); + } + elseif ($canDo->get('core.edit.state')) + { + JToolbarHelper::trash('languages.trash'); + JToolbarHelper::divider(); + } + + if ($canDo->get('core.admin')) + { + // Add install languages link to the lang installer component. + $bar = JToolbar::getInstance('toolbar'); + $bar->appendButton('Link', 'upload', 'COM_LANGUAGES_INSTALL', 'index.php?option=com_installer&view=languages'); + JToolbarHelper::divider(); + + JToolbarHelper::preferences('com_languages'); + JToolbarHelper::divider(); + } + + JToolbarHelper::help('JHELP_EXTENSIONS_LANGUAGE_MANAGER_CONTENT'); + + JHtmlSidebar::setAction('index.php?option=com_languages&view=languages'); + + } + + /** + * Returns an array of fields the table can be sorted by. + * + * @return array Array containing the field name to sort by as the key and display text as value. + * + * @since 3.0 + */ + protected function getSortFields() + { + return array( + 'a.ordering' => JText::_('JGRID_HEADING_ORDERING'), + 'a.published' => JText::_('JSTATUS'), + 'a.title' => JText::_('JGLOBAL_TITLE'), + 'a.title_native' => JText::_('COM_LANGUAGES_HEADING_TITLE_NATIVE'), + 'a.lang_code' => JText::_('COM_LANGUAGES_FIELD_LANG_TAG_LABEL'), + 'a.sef' => JText::_('COM_LANGUAGES_FIELD_LANG_CODE_LABEL'), + 'a.image' => JText::_('COM_LANGUAGES_HEADING_LANG_IMAGE'), + 'a.access' => JText::_('JGRID_HEADING_ACCESS'), + 'a.lang_id' => JText::_('JGRID_HEADING_ID'), + ); + } +} diff --git a/Sites/pages/administrator/components/com_languages/views/multilangstatus/tmpl/default.php b/Sites/pages/administrator/components/com_languages/views/multilangstatus/tmpl/default.php new file mode 100644 index 00000000..6c98ce45 --- /dev/null +++ b/Sites/pages/administrator/components/com_languages/views/multilangstatus/tmpl/default.php @@ -0,0 +1,268 @@ +homes == 2 || $this->homes == 1 || $this->homes - 1 != count($this->contentlangs) && ($this->language_filter || $this->switchers != 0); +$notice_disabled = !$this->language_filter && ($this->homes > 1 || $this->switchers != 0); +$notice_switchers = !$this->switchers && ($this->homes > 1 || $this->language_filter); +?> +
+ language_filter && $this->switchers == 0) : ?> + homes == 1) : ?> +
+ +
+ + + + + defaultHome == true) : ?> + + + + + + + + + + + + + + + + + + + + + + + + contentlangs as $contentlang) : ?> + lang_code, $this->homepages) && (!array_key_exists($contentlang->lang_code, $this->site_langs) || !$contentlang->published)) : ?> + + + + + + lang_code, $this->site_langs)) : ?> + + + + + + published == -2) : ?> + + + + + + + listUsersError) : ?> + + + + + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + lang_code); ?> +
+ + + lang_code); ?> +
+ + + lang_code); ?> +
+ + + +
    + listUsersError as $user) : ?> +
  • + name); ?> +
  • + +
+
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + language_filter) : ?> + + + + +
+ + + switchers != 0) : ?> + switchers; ?> + + + +
+ homes > 1) : ?> + + + + + + homes > 1) : ?> + homes; ?> + + + +
+ + + + + + + + + + + statuses as $status) : ?> + element) : ?> + + + + + element) : ?> + + + + + + lang_code && $status->published == 1) : ?> + + lang_code && $status->published == 0) : ?> + + lang_code && $status->published == -2) : ?> + + + + + + home_language) : ?> + + + + + + + contentlangs as $contentlang) : ?> + lang_code, $this->site_langs)) : ?> + + + + + + + + + +
+ + + + + + + +
+ element; ?> + + + + + + + + + + + + + + + + +
+ lang_code; ?> + + + + published) : ?> + + published && array_key_exists($contentlang->lang_code, $this->homepages)) : ?> + + published) : ?> + + + + lang_code, $this->homepages)) : ?> + + + + +
+ +
diff --git a/Sites/pages/administrator/components/com_languages/views/multilangstatus/view.html.php b/Sites/pages/administrator/components/com_languages/views/multilangstatus/view.html.php new file mode 100644 index 00000000..fbc7afa9 --- /dev/null +++ b/Sites/pages/administrator/components/com_languages/views/multilangstatus/view.html.php @@ -0,0 +1,42 @@ +homes = MultilangstatusHelper::getHomes(); + $this->language_filter = JLanguageMultilang::isEnabled(); + $this->switchers = MultilangstatusHelper::getLangswitchers(); + $this->listUsersError = MultilangstatusHelper::getContacts(); + $this->contentlangs = MultilangstatusHelper::getContentlangs(); + $this->site_langs = JLanguageHelper::getInstalledLanguages(0); + $this->statuses = MultilangstatusHelper::getStatus(); + $this->homepages = JLanguageMultilang::getSiteHomePages(); + $this->defaultHome = MultilangstatusHelper::getDefaultHomeModule(); + + parent::display($tpl); + } +} diff --git a/Sites/pages/administrator/components/com_languages/views/override/tmpl/edit.php b/Sites/pages/administrator/components/com_languages/views/override/tmpl/edit.php new file mode 100644 index 00000000..297baef4 --- /dev/null +++ b/Sites/pages/administrator/components/com_languages/views/override/tmpl/edit.php @@ -0,0 +1,155 @@ +state->get('cache_expired') == 1 ) ? '1' : ''; + +JHtml::_('stylesheet', 'overrider/overrider.css', array('version' => 'auto', 'relative' => true)); + +JHtml::_('behavior.core'); +JHtml::_('jquery.framework'); +JHtml::_('script', 'overrider/overrider.min.js', array('version' => 'auto', 'relative' => true)); + +JFactory::getDocument()->addScriptDeclaration(' + jQuery(document).ready(function($) { + $("#jform_searchstring").on("focus", function() { + if (!Joomla.overrider.states.refreshed) + { + var expired = "' . $expired . '"; + if (expired) + { + Joomla.overrider.refreshCache(); + Joomla.overrider.states.refreshed = true; + } + } + $(this).removeClass("invalid"); + }); + }); + + Joomla.submitbutton = function(task) { + if (task == "override.cancel" || document.formvalidator.isValid(document.getElementById("override-form"))) + { + Joomla.submitform(task, document.getElementById("override-form")); + } + }; +'); +?> + +
+
+
+
+ item->key) ? JText::_('COM_LANGUAGES_VIEW_OVERRIDE_EDIT_NEW_OVERRIDE_LEGEND') : JText::_('COM_LANGUAGES_VIEW_OVERRIDE_EDIT_EDIT_OVERRIDE_LEGEND'); ?> +
+
+ form->getLabel('language'); ?> +
+
+ form->getInput('language'); ?> +
+
+ +
+
+ form->getLabel('client'); ?> +
+
+ form->getInput('client'); ?> +
+
+ +
+
+ form->getLabel('key'); ?> +
+
+ form->getInput('key'); ?> +
+
+ +
+
+ form->getLabel('override'); ?> +
+
+ form->getInput('override'); ?> +
+
+ + state->get('filter.client') == 'administrator') : ?> +
+
+ form->getLabel('both'); ?> +
+
+ form->getInput('both'); ?> +
+
+ + +
+
+ form->getLabel('file'); ?> +
+
+ form->getInput('file'); ?> +
+
+
+ +
+ +
+
+ + +

+ +
+ form->getInput('searchstring'); ?> + + + + +
+
+
+ form->getLabel('searchtype'); ?> +
+
+ form->getInput('searchtype'); ?> +
+
+ +
+ +
+ + + + + +
+ + + + + +
+
+
diff --git a/Sites/pages/administrator/components/com_languages/views/override/view.html.php b/Sites/pages/administrator/components/com_languages/views/override/view.html.php new file mode 100644 index 00000000..a263372a --- /dev/null +++ b/Sites/pages/administrator/components/com_languages/views/override/view.html.php @@ -0,0 +1,133 @@ +form = $this->get('Form'); + $this->item = $this->get('Item'); + $this->state = $this->get('State'); + + $app = JFactory::getApplication(); + + $languageClient = $app->getUserStateFromRequest('com_languages.overrides.language_client', 'language_client'); + + if ($languageClient == null) + { + $app->enqueueMessage(JText::_('COM_LANGUAGES_OVERRIDE_FIRST_SELECT_MESSAGE'), 'warning'); + + $app->redirect('index.php?option=com_languages&view=overrides'); + } + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors)); + } + + // Check whether the cache has to be refreshed. + $cached_time = JFactory::getApplication()->getUserState( + 'com_languages.overrides.cachedtime.' . $this->state->get('filter.client') . '.' . $this->state->get('filter.language'), + 0 + ); + + if (time() - $cached_time > 60 * 5) + { + $this->state->set('cache_expired', true); + } + + // Add strings for translations in Javascript. + JText::script('COM_LANGUAGES_VIEW_OVERRIDE_NO_RESULTS'); + JText::script('COM_LANGUAGES_VIEW_OVERRIDE_REQUEST_ERROR'); + + $this->addToolbar(); + parent::display($tpl); + } + + /** + * Adds the page title and toolbar. + * + * @return void + * + * @since 2.5 + */ + protected function addToolbar() + { + JFactory::getApplication()->input->set('hidemainmenu', true); + + $canDo = JHelperContent::getActions('com_languages'); + + JToolbarHelper::title(JText::_('COM_LANGUAGES_VIEW_OVERRIDE_EDIT_TITLE'), 'comments-2 langmanager'); + + if ($canDo->get('core.edit')) + { + JToolbarHelper::apply('override.apply'); + JToolbarHelper::save('override.save'); + } + + // This component does not support Save as Copy. + if ($canDo->get('core.edit') && $canDo->get('core.create')) + { + JToolbarHelper::save2new('override.save2new'); + } + + if (empty($this->item->key)) + { + JToolbarHelper::cancel('override.cancel'); + } + else + { + JToolbarHelper::cancel('override.cancel', 'JTOOLBAR_CLOSE'); + } + + JToolbarHelper::divider(); + JToolbarHelper::help('JHELP_EXTENSIONS_LANGUAGE_MANAGER_OVERRIDES_EDIT'); + } +} diff --git a/Sites/pages/administrator/components/com_languages/views/overrides/tmpl/default.php b/Sites/pages/administrator/components/com_languages/views/overrides/tmpl/default.php new file mode 100644 index 00000000..2788b91a --- /dev/null +++ b/Sites/pages/administrator/components/com_languages/views/overrides/tmpl/default.php @@ -0,0 +1,110 @@ +state->get('filter.client') == 'site' ? JText::_('JSITE') : JText::_('JADMINISTRATOR'); +$language = $this->state->get('filter.language'); +$listOrder = $this->escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); + +$oppositeClient = $this->state->get('filter.client') == 'administrator' ? JText::_('JSITE') : JText::_('JADMINISTRATOR'); +$oppositeFileName = constant('JPATH_' . strtoupper($this->state->get('filter.client') === 'site' ? 'administrator' : 'site')) + . '/language/overrides/' . $this->state->get('filter.language', 'en-GB') . '.override.ini'; +$oppositeStrings = JLanguageHelper::parseIniFile($oppositeFileName); +?> + +
+sidebar)) : ?> +
+ sidebar; ?> +
+
+ +
+ + $this)); ?> +
+ items)) : ?> +
+ +
+ + + + + + + + + + + + + + + + + + authorise('core.edit', 'com_languages'); ?> + + items as $key => $text) : ?> + + + + + + + + + + +
+ + + + + + + + + +
+ pagination->getListFooter(); ?> +
+ + + + escape($key); ?> + + escape($key); ?> + + + escape($text); ?> + + + + +
+ + + + + +
+ diff --git a/Sites/pages/administrator/components/com_languages/views/overrides/tmpl/default.xml b/Sites/pages/administrator/components/com_languages/views/overrides/tmpl/default.xml new file mode 100755 index 00000000..54b63dcf --- /dev/null +++ b/Sites/pages/administrator/components/com_languages/views/overrides/tmpl/default.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/Sites/pages/administrator/components/com_languages/views/overrides/view.html.php b/Sites/pages/administrator/components/com_languages/views/overrides/view.html.php new file mode 100644 index 00000000..7cb98d72 --- /dev/null +++ b/Sites/pages/administrator/components/com_languages/views/overrides/view.html.php @@ -0,0 +1,119 @@ +state = $this->get('State'); + $this->items = $this->get('Overrides'); + $this->languages = $this->get('Languages'); + $this->pagination = $this->get('Pagination'); + $this->filterForm = $this->get('FilterForm'); + $this->activeFilters = $this->get('ActiveFilters'); + + LanguagesHelper::addSubmenu('overrides'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors)); + } + + $this->addToolbar(); + parent::display($tpl); + } + + /** + * Adds the page title and toolbar. + * + * @return void + * + * @since 2.5 + */ + protected function addToolbar() + { + // Get the results for each action + $canDo = JHelperContent::getActions('com_languages'); + + JToolbarHelper::title(JText::_('COM_LANGUAGES_VIEW_OVERRIDES_TITLE'), 'comments-2 langmanager'); + + if ($canDo->get('core.create')) + { + JToolbarHelper::addNew('override.add'); + } + + if ($canDo->get('core.edit') && $this->pagination->total) + { + JToolbarHelper::editList('override.edit'); + } + + if ($canDo->get('core.delete') && $this->pagination->total) + { + JToolbarHelper::deleteList('JGLOBAL_CONFIRM_DELETE', 'overrides.delete', 'JTOOLBAR_DELETE'); + } + + if (JFactory::getUser()->authorise('core.admin')) + { + JToolbarHelper::custom('overrides.purge', 'refresh.png', 'refresh_f2.png', 'COM_LANGUAGES_VIEW_OVERRIDES_PURGE', false); + } + + if ($canDo->get('core.admin')) + { + JToolbarHelper::preferences('com_languages'); + } + + JToolbarHelper::divider(); + JToolbarHelper::help('JHELP_EXTENSIONS_LANGUAGE_MANAGER_OVERRIDES'); + + JHtmlSidebar::setAction('index.php?option=com_languages&view=overrides'); + + $this->sidebar = JHtmlSidebar::render(); + } +} diff --git a/Sites/pages/administrator/components/com_login/controller.php b/Sites/pages/administrator/components/com_login/controller.php new file mode 100644 index 00000000..e773d083 --- /dev/null +++ b/Sites/pages/administrator/components/com_login/controller.php @@ -0,0 +1,128 @@ +input->set('view', 'login'); + $this->input->set('layout', 'default'); + + // For non-html formats we do not have login view, so just display 403 instead + if ($this->input->get('format', 'html') !== 'html') + { + throw new RuntimeException(JText::_('JERROR_ALERTNOAUTHOR'), 403); + } + + parent::display(); + } + + /** + * Method to log in a user. + * + * @return void + */ + public function login() + { + // Check for request forgeries. + $this->checkToken('request'); + + $app = JFactory::getApplication(); + + $model = $this->getModel('login'); + $credentials = $model->getState('credentials'); + $return = $model->getState('return'); + + $result = $app->login($credentials, array('action' => 'core.login.admin')); + + if ($result && !($result instanceof Exception)) + { + // Only redirect to an internal URL. + if (JUri::isInternal($return)) + { + // If &tmpl=component - redirect to index.php + if (strpos($return, 'tmpl=component') === false) + { + $app->redirect($return); + } + else + { + $app->redirect('index.php'); + } + } + } + + $this->display(); + } + + /** + * Method to log out a user. + * + * @return void + */ + public function logout() + { + $this->checkToken('request'); + + $app = JFactory::getApplication(); + + $userid = $this->input->getInt('uid', null); + + if ($app->get('shared_session', '0')) + { + $clientid = null; + } + else + { + $clientid = $userid ? 0 : 1; + } + + $options = array( + 'clientid' => $clientid, + ); + + $result = $app->logout($userid, $options); + + if (!($result instanceof Exception)) + { + $model = $this->getModel('login'); + $return = $model->getState('return'); + + // Only redirect to an internal URL. + if (JUri::isInternal($return)) + { + $app->redirect($return); + } + } + + parent::display(); + } +} diff --git a/Sites/pages/administrator/components/com_login/login.php b/Sites/pages/administrator/components/com_login/login.php new file mode 100644 index 00000000..41dea32f --- /dev/null +++ b/Sites/pages/administrator/components/com_login/login.php @@ -0,0 +1,23 @@ +input; +$task = $input->get('task'); + +if ($task != 'login' && $task != 'logout') +{ + $input->set('task', ''); + $task = ''; +} + +$controller = JControllerLegacy::getInstance('Login'); +$controller->execute($task); +$controller->redirect(); diff --git a/Sites/pages/administrator/components/com_login/login.xml b/Sites/pages/administrator/components/com_login/login.xml new file mode 100644 index 00000000..3d5ff760 --- /dev/null +++ b/Sites/pages/administrator/components/com_login/login.xml @@ -0,0 +1,25 @@ + + + com_login + Joomla! Project + April 2006 + (C) 2005 - 2020 Open Source Matters. All rights reserved. + GNU General Public License version 2 or later; see LICENSE.txt + admin@joomla.org + www.joomla.org + 3.0.0 + COM_LOGIN_XML_DESCRIPTION + + + controller.php + login.php + views + models + + + language/en-GB.com_login.ini + language/en-GB.com_login.sys.ini + + + + diff --git a/Sites/pages/administrator/components/com_login/models/login.php b/Sites/pages/administrator/components/com_login/models/login.php new file mode 100644 index 00000000..62dd7cb9 --- /dev/null +++ b/Sites/pages/administrator/components/com_login/models/login.php @@ -0,0 +1,183 @@ +input->getInputForRequestMethod(); + + $credentials = array( + 'username' => $input->get('username', '', 'USERNAME'), + 'password' => $input->get('passwd', '', 'RAW'), + 'secretkey' => $input->get('secretkey', '', 'RAW'), + ); + + $this->setState('credentials', $credentials); + + // Check for return URL from the request first. + if ($return = $input->get('return', '', 'BASE64')) + { + $return = base64_decode($return); + + if (!JUri::isInternal($return)) + { + $return = ''; + } + } + + // Set the return URL if empty. + if (empty($return)) + { + $return = 'index.php'; + } + + $this->setState('return', $return); + } + + /** + * Get the administrator login module by name (real, eg 'login' or folder, eg 'mod_login'). + * + * @param string $name The name of the module. + * @param string $title The title of the module, optional. + * + * @return object The Module object. + * + * @since 1.7.0 + */ + public static function getLoginModule($name = 'mod_login', $title = null) + { + $result = null; + $modules = self::_load($name); + $total = count($modules); + + for ($i = 0; $i < $total; $i++) + { + // Match the title if we're looking for a specific instance of the module. + if (!$title || $modules[$i]->title == $title) + { + $result = $modules[$i]; + break; + } + } + + // 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; + } + + /** + * Load login modules. + * + * Note that we load regardless of state or access level since access + * for public is the only thing that makes sense since users are not logged in + * and the module lets them log in. + * This is put in as a failsafe to avoid super user lock out caused by an unpublished + * login module or by a module set to have a viewing access level that is not Public. + * + * @param string $module The name of the module. + * + * @return array + * + * @since 1.7.0 + */ + protected static function _load($module) + { + static $clean; + + if (isset($clean)) + { + return $clean; + } + + $app = JFactory::getApplication(); + $lang = JFactory::getLanguage()->getTag(); + $clientId = (int) $app->getClientId(); + + /** @var JCacheControllerCallback $cache */ + $cache = JFactory::getCache('com_modules', 'callback'); + + $loader = function () use ($app, $lang, $module) { + $db = JFactory::getDbo(); + + $query = $db->getQuery(true) + ->select('m.id, m.title, m.module, m.position, m.showtitle, m.params') + ->from('#__modules AS m') + ->where('m.module =' . $db->quote($module) . ' AND m.client_id = 1') + ->join('LEFT', '#__extensions AS e ON e.element = m.module AND e.client_id = m.client_id') + ->where('e.enabled = 1'); + + // Filter by language. + if ($app->isClient('site') && $app->getLanguageFilter()) + { + $query->where('m.language IN (' . $db->quote($lang) . ',' . $db->quote('*') . ')'); + } + + $query->order('m.position, m.ordering'); + + // Set the query. + $db->setQuery($query); + + return $db->loadObjectList(); + }; + + try + { + return $clean = $cache->get($loader, array(), md5(serialize(array($clientId, $lang)))); + } + catch (JCacheException $cacheException) + { + try + { + return $loader(); + } + catch (JDatabaseExceptionExecuting $databaseException) + { + JError::raiseWarning(500, JText::sprintf('JLIB_APPLICATION_ERROR_MODULE_LOAD', $databaseException->getMessage())); + + return array(); + } + } + catch (JDatabaseExceptionExecuting $databaseException) + { + JError::raiseWarning(500, JText::sprintf('JLIB_APPLICATION_ERROR_MODULE_LOAD', $databaseException->getMessage())); + + return array(); + } + } +} diff --git a/Sites/pages/administrator/components/com_login/views/login/tmpl/default.php b/Sites/pages/administrator/components/com_login/views/login/tmpl/default.php new file mode 100644 index 00000000..7463b96f --- /dev/null +++ b/Sites/pages/administrator/components/com_login/views/login/tmpl/default.php @@ -0,0 +1,32 @@ + 'rounded', 'id' => 'section-box')); + + +/** + * Get any other modules in the login position. + * If you want to use a different position for the modules, change the name here in your override. + */ +$modules = JModuleHelper::getModules('login'); + +foreach ($modules as $module) +// Render the login modules + +if ($module->module != 'mod_login'){ + echo JModuleHelper::renderModule($module, array('style' => 'rounded', 'id' => 'section-box')); +} diff --git a/Sites/pages/administrator/components/com_login/views/login/view.html.php b/Sites/pages/administrator/components/com_login/views/login/view.html.php new file mode 100644 index 00000000..5832926a --- /dev/null +++ b/Sites/pages/administrator/components/com_login/views/login/view.html.php @@ -0,0 +1,41 @@ +setHeader('X-Frame-Options', 'SAMEORIGIN'); + + return parent::display($tpl); + } +} diff --git a/Sites/pages/administrator/components/com_media/access.xml b/Sites/pages/administrator/components/com_media/access.xml new file mode 100644 index 00000000..d4b0fee8 --- /dev/null +++ b/Sites/pages/administrator/components/com_media/access.xml @@ -0,0 +1,10 @@ + + +
+ + + + + +
+
diff --git a/Sites/pages/administrator/components/com_media/config.xml b/Sites/pages/administrator/components/com_media/config.xml new file mode 100644 index 00000000..fcbc171b --- /dev/null +++ b/Sites/pages/administrator/components/com_media/config.xml @@ -0,0 +1,135 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + +
+
diff --git a/Sites/pages/administrator/components/com_media/controller.php b/Sites/pages/administrator/components/com_media/controller.php new file mode 100644 index 00000000..a8dfc64a --- /dev/null +++ b/Sites/pages/administrator/components/com_media/controller.php @@ -0,0 +1,97 @@ +getType(); + $vName = $this->input->get('view', 'media'); + + switch ($vName) + { + case 'images': + $vLayout = $this->input->get('layout', 'default', 'string'); + $mName = 'manager'; + + break; + + case 'imagesList': + $mName = 'list'; + $vLayout = $this->input->get('layout', 'default', 'string'); + + break; + + case 'mediaList': + $app = JFactory::getApplication(); + $mName = 'list'; + $vLayout = $app->getUserStateFromRequest('media.list.layout', 'layout', 'thumbs', 'word'); + + break; + + case 'media': + default: + $vName = 'media'; + $vLayout = $this->input->get('layout', 'default', 'string'); + $mName = 'manager'; + + break; + } + + // Get/Create the view + $view = $this->getView($vName, $vType, '', array('base_path' => JPATH_COMPONENT_ADMINISTRATOR)); + + // Get/Create the model + if ($model = $this->getModel($mName)) + { + // Push the model into the view (as default) + $view->setModel($model, true); + } + + // Set the layout + $view->setLayout($vLayout); + + // Display the view + $view->display(); + + return $this; + } + + /** + * Validate FTP credentials + * + * @return void + * + * @since 1.5 + */ + public function ftpValidate() + { + // Set FTP credentials, if given + JClientHelper::setCredentialsFromRequest('ftp'); + } +} diff --git a/Sites/pages/administrator/components/com_media/controllers/file.json.php b/Sites/pages/administrator/components/com_media/controllers/file.json.php new file mode 100644 index 00000000..8fdaec40 --- /dev/null +++ b/Sites/pages/administrator/components/com_media/controllers/file.json.php @@ -0,0 +1,262 @@ + '0', + 'message' => JText::_('JINVALID_TOKEN'), + 'error' => JText::_('JINVALID_TOKEN') + ); + echo json_encode($response); + + return; + } + + // Get the user + $user = JFactory::getUser(); + JLog::addLogger(array('text_file' => 'upload.error.php'), JLog::ALL, array('upload')); + + // Get some data from the request + $file = $this->input->files->get('Filedata', '', 'array'); + $folder = $this->input->get('folder', '', 'path'); + + // Instantiate the media helper + $mediaHelper = new JHelperMedia; + + if ($_SERVER['CONTENT_LENGTH'] > ($params->get('upload_maxsize', 0) * 1024 * 1024) + || $_SERVER['CONTENT_LENGTH'] > $mediaHelper->toBytes(ini_get('upload_max_filesize')) + || $_SERVER['CONTENT_LENGTH'] > $mediaHelper->toBytes(ini_get('post_max_size')) + || $_SERVER['CONTENT_LENGTH'] > $mediaHelper->toBytes(ini_get('memory_limit'))) + { + $response = array( + 'status' => '0', + 'message' => JText::_('COM_MEDIA_ERROR_WARNFILETOOLARGE'), + 'error' => JText::_('COM_MEDIA_ERROR_WARNFILETOOLARGE') + ); + echo json_encode($response); + + return; + } + + // Set FTP credentials, if given + JClientHelper::setCredentialsFromRequest('ftp'); + + if (isset($file['name'])) + { + // Make the filename safe + $file['name'] = JFile::makeSafe($file['name']); + + // We need a URL safe name + $fileparts = pathinfo(COM_MEDIA_BASE . '/' . $folder . '/' . $file['name']); + + // Transform filename to punycode + $fileparts['filename'] = JStringPunycode::toPunycode($fileparts['filename']); + $tempExt = !empty($fileparts['extension']) ? strtolower($fileparts['extension']) : ''; + + // Transform filename to punycode, then neglect other than non-alphanumeric characters & underscores. Also transform extension to lowercase + $safeFileName = preg_replace(array("/[\\s]/", '/[^a-zA-Z0-9_\-]/'), array('_', ''), $fileparts['filename']) . '.' . $tempExt; + + // Create filepath with safe-filename + $files['final'] = $fileparts['dirname'] . DIRECTORY_SEPARATOR . $safeFileName; + $file['name'] = $safeFileName; + + $filepath = JPath::clean($files['final']); + + if (!$mediaHelper->canUpload($file, 'com_media') + || strpos(realpath($fileparts['dirname']), JPath::clean(realpath(COM_MEDIA_BASE))) !== 0) + { + try + { + JLog::add('Invalid: ' . $filepath, JLog::INFO, 'upload'); + } + catch (RuntimeException $exception) + { + // Informational log only + } + + $response = array( + 'status' => '0', + 'message' => JText::_('COM_MEDIA_ERROR_UNABLE_TO_UPLOAD_FILE'), + 'error' => JText::_('COM_MEDIA_ERROR_UNABLE_TO_UPLOAD_FILE') + ); + + echo json_encode($response); + + return; + } + + // Trigger the onContentBeforeSave event. + JPluginHelper::importPlugin('content'); + $dispatcher = JEventDispatcher::getInstance(); + $object_file = new JObject($file); + $object_file->filepath = $filepath; + $result = $dispatcher->trigger('onContentBeforeSave', array('com_media.file', &$object_file, true)); + + if (in_array(false, $result, true)) + { + // There are some errors in the plugins + try + { + JLog::add( + 'Errors before save: ' . $object_file->filepath . ' : ' . implode(', ', $object_file->getErrors()), + JLog::INFO, + 'upload' + ); + } + catch (RuntimeException $exception) + { + // Informational log only + } + + $response = array( + 'status' => '0', + 'message' => JText::plural('COM_MEDIA_ERROR_BEFORE_SAVE', count($errors = $object_file->getErrors()), implode('
', $errors)), + 'error' => JText::plural('COM_MEDIA_ERROR_BEFORE_SAVE', count($errors = $object_file->getErrors()), implode('
', $errors)) + ); + + echo json_encode($response); + + return; + } + + if (JFile::exists($object_file->filepath)) + { + // File exists + try + { + JLog::add('File exists: ' . $object_file->filepath . ' by user_id ' . $user->id, JLog::INFO, 'upload'); + } + catch (RuntimeException $exception) + { + // Informational log only + } + + $response = array( + 'status' => '0', + 'message' => JText::_('COM_MEDIA_ERROR_FILE_EXISTS'), + 'error' => JText::_('COM_MEDIA_ERROR_FILE_EXISTS'), + 'location' => str_replace(JPATH_ROOT, '', $filepath) + ); + + echo json_encode($response); + + return; + } + elseif (!$user->authorise('core.create', 'com_media')) + { + // File does not exist and user is not authorised to create + try + { + JLog::add('Create not permitted: ' . $object_file->filepath . ' by user_id ' . $user->id, JLog::INFO, 'upload'); + } + catch (RuntimeException $exception) + { + // Informational log only + } + + $response = array( + 'status' => '0', + 'error' => JText::_('COM_MEDIA_ERROR_CREATE_NOT_PERMITTED'), + 'message' => JText::_('COM_MEDIA_ERROR_CREATE_NOT_PERMITTED') + ); + + echo json_encode($response); + + return; + } + + if (!JFile::upload($object_file->tmp_name, $object_file->filepath)) + { + // Error in upload + try + { + JLog::add('Error on upload: ' . $object_file->filepath, JLog::INFO, 'upload'); + } + catch (RuntimeException $exception) + { + // Informational log only + } + + $response = array( + 'status' => '0', + 'message' => JText::_('COM_MEDIA_ERROR_UNABLE_TO_UPLOAD_FILE'), + 'error' => JText::_('COM_MEDIA_ERROR_UNABLE_TO_UPLOAD_FILE') + ); + + echo json_encode($response); + + return; + } + else + { + // Trigger the onContentAfterSave event. + $dispatcher->trigger('onContentAfterSave', array('com_media.file', &$object_file, true)); + + try + { + JLog::add($folder, JLog::INFO, 'upload'); + } + catch (RuntimeException $exception) + { + // Informational log only + } + + $returnUrl = str_replace(JPATH_ROOT, '', $object_file->filepath); + + $response = array( + 'status' => '1', + 'message' => JText::sprintf('COM_MEDIA_UPLOAD_COMPLETE', $returnUrl), + 'error' => JText::sprintf('COM_MEDIA_UPLOAD_COMPLETE', $returnUrl), + 'location' => str_replace('\\', '/', $returnUrl) + ); + + echo json_encode($response); + + return; + } + } + else + { + $response = array( + 'status' => '0', + 'error' => JText::_('COM_MEDIA_ERROR_BAD_REQUEST'), + 'message' => JText::_('COM_MEDIA_ERROR_BAD_REQUEST') + ); + + echo json_encode($response); + + return; + } + } +} diff --git a/Sites/pages/administrator/components/com_media/controllers/file.php b/Sites/pages/administrator/components/com_media/controllers/file.php new file mode 100644 index 00000000..0e58f81d --- /dev/null +++ b/Sites/pages/administrator/components/com_media/controllers/file.php @@ -0,0 +1,368 @@ +checkToken('request'); + + $params = JComponentHelper::getParams('com_media'); + + // Get some data from the request + $files = $this->input->files->get('Filedata', array(), 'array'); + $return = JFactory::getSession()->get('com_media.return_url'); + $this->folder = $this->input->get('folder', '', 'path'); + + // Instantiate the media helper + $mediaHelper = new JHelperMedia; + + // Don't redirect to an external URL. + if (!JUri::isInternal($return)) + { + $return = ''; + } + + // Set the redirect + if ($return) + { + $this->setRedirect($return . '&folder=' . $this->folder); + } + else + { + $this->setRedirect('index.php?option=com_media&folder=' . $this->folder); + } + + // First check against unfiltered input. + if (!$this->input->files->get('Filedata', null, 'RAW')) + { + // Total length of post back data in bytes. + $contentLength = $this->input->server->get('CONTENT_LENGTH', 0, 'INT'); + + // Maximum allowed size of post back data in MB. + $postMaxSize = $mediaHelper->toBytes(ini_get('post_max_size')); + + // Maximum allowed size of script execution in MB. + $memoryLimit = $mediaHelper->toBytes(ini_get('memory_limit')); + + // Check for the total size of post back data. + if (($postMaxSize > 0 && $contentLength > $postMaxSize) + || ($memoryLimit != -1 && $contentLength > $memoryLimit)) + { + // Files are too large. + JError::raiseWarning(100, JText::_('COM_MEDIA_ERROR_WARNUPLOADTOOLARGE')); + + return false; + } + + // No files were provided. + $this->setMessage(JText::_('COM_MEDIA_ERROR_UPLOAD_INPUT'), 'warning'); + + return false; + } + + if (!$files) + { + // Files were provided but are unsafe to upload. + $this->setMessage(JText::_('COM_MEDIA_ERROR_WARNFILENOTSAFE'), 'error'); + + return false; + } + + // Authorize the user + if (!$this->authoriseUser('create')) + { + return false; + } + + $uploadMaxSize = $params->get('upload_maxsize', 0) * 1024 * 1024; + $uploadMaxFileSize = $mediaHelper->toBytes(ini_get('upload_max_filesize')); + + // Perform basic checks on file info before attempting anything + foreach ($files as &$file) + { + // Make the filename safe + $file['name'] = JFile::makeSafe($file['name']); + + // We need a url safe name + $fileparts = pathinfo(COM_MEDIA_BASE . '/' . $this->folder . '/' . $file['name']); + + if (strpos(realpath($fileparts['dirname']), JPath::clean(realpath(COM_MEDIA_BASE))) !== 0) + { + JError::raiseWarning(100, JText::_('COM_MEDIA_ERROR_WARNINVALID_FOLDER')); + + return false; + } + + // Transform filename to punycode, check extension and transform it to lowercase + $fileparts['filename'] = JStringPunycode::toPunycode($fileparts['filename']); + $tempExt = !empty($fileparts['extension']) ? strtolower($fileparts['extension']) : ''; + + // Neglect other than non-alphanumeric characters, hyphens & underscores. + $safeFileName = preg_replace(array("/[\\s]/", '/[^a-zA-Z0-9_\-]/'), array('_', ''), $fileparts['filename']) . '.' . $tempExt; + + $file['name'] = $safeFileName; + + $file['filepath'] = JPath::clean(implode(DIRECTORY_SEPARATOR, array(COM_MEDIA_BASE, $this->folder, $file['name']))); + + if (($file['error'] == 1) + || ($uploadMaxSize > 0 && $file['size'] > $uploadMaxSize) + || ($uploadMaxFileSize > 0 && $file['size'] > $uploadMaxFileSize)) + { + // File size exceed either 'upload_max_filesize' or 'upload_maxsize'. + JError::raiseWarning(100, JText::_('COM_MEDIA_ERROR_WARNFILETOOLARGE')); + + return false; + } + + if (JFile::exists($file['filepath'])) + { + // A file with this name already exists + JError::raiseWarning(100, JText::_('COM_MEDIA_ERROR_FILE_EXISTS')); + + return false; + } + + if (!isset($file['name'])) + { + // No filename (after the name was cleaned by JFile::makeSafe) + $this->setRedirect('index.php', JText::_('COM_MEDIA_INVALID_REQUEST'), 'error'); + + return false; + } + } + + // Set FTP credentials, if given + JClientHelper::setCredentialsFromRequest('ftp'); + JPluginHelper::importPlugin('content'); + $dispatcher = JEventDispatcher::getInstance(); + + foreach ($files as &$file) + { + // The request is valid + $err = null; + + if (!MediaHelper::canUpload($file, $err)) + { + // The file can't be uploaded + return false; + } + + // Trigger the onContentBeforeSave event. + $object_file = new JObject($file); + $result = $dispatcher->trigger('onContentBeforeSave', array('com_media.file', &$object_file, true)); + + if (in_array(false, $result, true)) + { + // There are some errors in the plugins + JError::raiseWarning(100, JText::plural('COM_MEDIA_ERROR_BEFORE_SAVE', count($errors = $object_file->getErrors()), implode('
', $errors))); + + return false; + } + + if (!JFile::upload($object_file->tmp_name, $object_file->filepath)) + { + // Error in upload + JError::raiseWarning(100, JText::_('COM_MEDIA_ERROR_UNABLE_TO_UPLOAD_FILE')); + + return false; + } + + // Trigger the onContentAfterSave event. + $dispatcher->trigger('onContentAfterSave', array('com_media.file', &$object_file, true)); + $this->setMessage(JText::sprintf('COM_MEDIA_UPLOAD_COMPLETE', substr($object_file->filepath, strlen(COM_MEDIA_BASE)))); + } + + return true; + } + + /** + * Check that the user is authorized to perform this action + * + * @param string $action - the action to be performed (create or delete) + * + * @return boolean + * + * @since 1.6 + */ + protected function authoriseUser($action) + { + if (!JFactory::getUser()->authorise('core.' . strtolower($action), 'com_media')) + { + // User is not authorised + JError::raiseWarning(403, JText::_('JLIB_APPLICATION_ERROR_' . strtoupper($action) . '_NOT_PERMITTED')); + + return false; + } + + return true; + } + + /** + * Deletes paths from the current path + * + * @return boolean + * + * @since 1.5 + */ + public function delete() + { + $this->checkToken('request'); + + $user = JFactory::getUser(); + + // Get some data from the request + $tmpl = $this->input->get('tmpl'); + $paths = $this->input->get('rm', array(), 'array'); + $folder = $this->input->get('folder', '', 'path'); + + $redirect = 'index.php?option=com_media&folder=' . $folder; + + if ($tmpl == 'component') + { + // We are inside the iframe + $redirect .= '&view=mediaList&tmpl=component'; + } + + $this->setRedirect($redirect); + + // Just return if there's nothing to do + if (empty($paths)) + { + $this->setMessage(JText::_('JERROR_NO_ITEMS_SELECTED'), 'error'); + + return true; + } + + if (!$user->authorise('core.delete', 'com_media')) + { + // User is not authorised to delete + JError::raiseWarning(403, JText::_('JLIB_APPLICATION_ERROR_DELETE_NOT_PERMITTED')); + + return false; + } + + // Need this to enqueue messages. + $app = JFactory::getApplication(); + + // Set FTP credentials, if given + JClientHelper::setCredentialsFromRequest('ftp'); + + JPluginHelper::importPlugin('content'); + $dispatcher = JEventDispatcher::getInstance(); + + $ret = true; + + $safePaths = array_intersect($paths, array_map(array('JFile', 'makeSafe'), $paths)); + + foreach ($safePaths as $key => $path) + { + $fullPath = implode(DIRECTORY_SEPARATOR, array(COM_MEDIA_BASE, $folder, $path)); + + if (strpos(realpath($fullPath), JPath::clean(realpath(COM_MEDIA_BASE))) !== 0) + { + unset($safePaths[$key]); + } + } + + $unsafePaths = array_diff($paths, $safePaths); + + foreach ($unsafePaths as $path) + { + $path = JPath::clean(implode(DIRECTORY_SEPARATOR, array($folder, $path))); + $path = htmlspecialchars($path, ENT_COMPAT, 'UTF-8'); + $app->enqueueMessage(JText::sprintf('COM_MEDIA_ERROR_UNABLE_TO_DELETE_FILE_WARNFILENAME', $path), 'error'); + } + + foreach ($safePaths as $path) + { + $fullPath = JPath::clean(implode(DIRECTORY_SEPARATOR, array(COM_MEDIA_BASE, $folder, $path))); + $object_file = new JObject(array('filepath' => $fullPath)); + + if (is_file($object_file->filepath)) + { + // Trigger the onContentBeforeDelete event. + $result = $dispatcher->trigger('onContentBeforeDelete', array('com_media.file', &$object_file)); + + if (in_array(false, $result, true)) + { + // There are some errors in the plugins + $errors = $object_file->getErrors(); + JError::raiseWarning(100, JText::plural('COM_MEDIA_ERROR_BEFORE_DELETE', count($errors), implode('
', $errors))); + + continue; + } + + $ret &= JFile::delete($object_file->filepath); + + // Trigger the onContentAfterDelete event. + $dispatcher->trigger('onContentAfterDelete', array('com_media.file', &$object_file)); + $app->enqueueMessage(JText::sprintf('COM_MEDIA_DELETE_COMPLETE', substr($object_file->filepath, strlen(COM_MEDIA_BASE)))); + } + elseif (is_dir($object_file->filepath)) + { + $contents = JFolder::files($object_file->filepath, '.', true, false, array('.svn', 'CVS', '.DS_Store', '__MACOSX', 'index.html')); + + if (!empty($contents)) + { + // This makes no sense... + $folderPath = substr($object_file->filepath, strlen(COM_MEDIA_BASE)); + JError::raiseWarning(100, JText::sprintf('COM_MEDIA_ERROR_UNABLE_TO_DELETE_FOLDER_NOT_EMPTY', $folderPath)); + + continue; + } + + // Trigger the onContentBeforeDelete event. + $result = $dispatcher->trigger('onContentBeforeDelete', array('com_media.folder', &$object_file)); + + if (in_array(false, $result, true)) + { + // There are some errors in the plugins + $errors = $object_file->getErrors(); + JError::raiseWarning(100, JText::plural('COM_MEDIA_ERROR_BEFORE_DELETE', count($errors), implode('
', $errors))); + + continue; + } + + $ret &= !JFolder::delete($object_file->filepath); + + // Trigger the onContentAfterDelete event. + $dispatcher->trigger('onContentAfterDelete', array('com_media.folder', &$object_file)); + $app->enqueueMessage(JText::sprintf('COM_MEDIA_DELETE_COMPLETE', substr($object_file->filepath, strlen(COM_MEDIA_BASE)))); + } + } + + return $ret; + } +} diff --git a/Sites/pages/administrator/components/com_media/controllers/folder.php b/Sites/pages/administrator/components/com_media/controllers/folder.php new file mode 100644 index 00000000..cd8d672f --- /dev/null +++ b/Sites/pages/administrator/components/com_media/controllers/folder.php @@ -0,0 +1,248 @@ +checkToken('request'); + + $user = JFactory::getUser(); + + // Get some data from the request + $tmpl = $this->input->get('tmpl'); + $paths = $this->input->get('rm', array(), 'array'); + $folder = $this->input->get('folder', '', 'path'); + + $redirect = 'index.php?option=com_media&folder=' . $folder; + + if ($tmpl == 'component') + { + // We are inside the iframe + $redirect .= '&view=mediaList&tmpl=component'; + } + + $this->setRedirect($redirect); + + // Just return if there's nothing to do + if (empty($paths)) + { + $this->setMessage(JText::_('JERROR_NO_ITEMS_SELECTED'), 'error'); + + return true; + } + + if (!$user->authorise('core.delete', 'com_media')) + { + // User is not authorised to delete + JError::raiseWarning(403, JText::_('JLIB_APPLICATION_ERROR_DELETE_NOT_PERMITTED')); + + return false; + } + + // Need this to enqueue messages. + $app = JFactory::getApplication(); + + // Set FTP credentials, if given + JClientHelper::setCredentialsFromRequest('ftp'); + + JPluginHelper::importPlugin('content'); + $dispatcher = JEventDispatcher::getInstance(); + + $ret = true; + + $safePaths = array_intersect($paths, array_map(array('JFile', 'makeSafe'), $paths)); + $unsafePaths = array_diff($paths, $safePaths); + + foreach ($unsafePaths as $path) + { + $path = JPath::clean(implode(DIRECTORY_SEPARATOR, array($folder, $path))); + $path = htmlspecialchars($path, ENT_COMPAT, 'UTF-8'); + $app->enqueueMessage(JText::sprintf('COM_MEDIA_ERROR_UNABLE_TO_DELETE_FILE_WARNFILENAME', $path), 'error'); + } + + foreach ($safePaths as $path) + { + $fullPath = JPath::clean(implode(DIRECTORY_SEPARATOR, array(COM_MEDIA_BASE, $folder, $path))); + + if (strpos(realpath($fullPath), JPath::clean(realpath(COM_MEDIA_BASE))) !== 0) + { + JError::raiseWarning(100, JText::_('COM_MEDIA_ERROR_WARNINVALID_FOLDER')); + + continue; + } + + $object_file = new JObject(array('filepath' => $fullPath)); + + if (is_file($object_file->filepath)) + { + // Trigger the onContentBeforeDelete event. + $result = $dispatcher->trigger('onContentBeforeDelete', array('com_media.file', &$object_file)); + + if (in_array(false, $result, true)) + { + // There are some errors in the plugins + $errors = $object_file->getErrors(); + JError::raiseWarning(100, JText::plural('COM_MEDIA_ERROR_BEFORE_DELETE', count($errors), implode('
', $errors))); + + continue; + } + + $ret &= JFile::delete($object_file->filepath); + + // Trigger the onContentAfterDelete event. + $dispatcher->trigger('onContentAfterDelete', array('com_media.file', &$object_file)); + $app->enqueueMessage(JText::sprintf('COM_MEDIA_DELETE_COMPLETE', substr($object_file->filepath, strlen(COM_MEDIA_BASE)))); + } + elseif (is_dir($object_file->filepath)) + { + $contents = JFolder::files($object_file->filepath, '.', true, false, array('.svn', 'CVS', '.DS_Store', '__MACOSX', 'index.html')); + + if (!empty($contents)) + { + // This makes no sense... + $folderPath = substr($object_file->filepath, strlen(COM_MEDIA_BASE)); + JError::raiseWarning(100, JText::sprintf('COM_MEDIA_ERROR_UNABLE_TO_DELETE_FOLDER_NOT_EMPTY', $folderPath)); + + continue; + } + + // Trigger the onContentBeforeDelete event. + $result = $dispatcher->trigger('onContentBeforeDelete', array('com_media.folder', &$object_file)); + + if (in_array(false, $result, true)) + { + // There are some errors in the plugins + $errors = $object_file->getErrors(); + JError::raiseWarning(100, JText::plural('COM_MEDIA_ERROR_BEFORE_DELETE', count($errors), implode('
', $errors))); + + continue; + } + + $ret &= !JFolder::delete($object_file->filepath); + + // Trigger the onContentAfterDelete event. + $dispatcher->trigger('onContentAfterDelete', array('com_media.folder', &$object_file)); + $app->enqueueMessage(JText::sprintf('COM_MEDIA_DELETE_COMPLETE', substr($object_file->filepath, strlen(COM_MEDIA_BASE)))); + } + } + + return $ret; + } + + /** + * Create a folder + * + * @return boolean + * + * @since 1.5 + */ + public function create() + { + // Check for request forgeries + $this->checkToken(); + + $user = JFactory::getUser(); + + $folder = $this->input->get('foldername', ''); + $folderCheck = (string) $this->input->get('foldername', null, 'raw'); + $parent = $this->input->get('folderbase', '', 'path'); + + $this->setRedirect('index.php?option=com_media&folder=' . $parent . '&tmpl=' . $this->input->get('tmpl', 'index')); + + if (strlen($folder) > 0) + { + if (!$user->authorise('core.create', 'com_media')) + { + // User is not authorised to create + JError::raiseWarning(403, JText::_('COM_MEDIA_ERROR_CREATE_NOT_PERMITTED')); + + return false; + } + + // Set FTP credentials, if given + JClientHelper::setCredentialsFromRequest('ftp'); + + $this->input->set('folder', $parent); + + if (($folderCheck !== null) && ($folder !== $folderCheck)) + { + $app = JFactory::getApplication(); + $app->enqueueMessage(JText::_('COM_MEDIA_ERROR_UNABLE_TO_CREATE_FOLDER_WARNDIRNAME'), 'warning'); + + return false; + } + + $path = JPath::clean(COM_MEDIA_BASE . '/' . $parent . '/' . $folder); + + if (strpos(realpath(COM_MEDIA_BASE . '/' . $parent), JPath::clean(realpath(COM_MEDIA_BASE))) !== 0) + { + $app = JFactory::getApplication(); + $app->enqueueMessage(JText::_('COM_MEDIA_ERROR_WARNINVALID_FOLDER'), 'error'); + + return false; + } + + if (!is_dir($path) && !is_file($path)) + { + // Trigger the onContentBeforeSave event. + $object_file = new JObject(array('filepath' => $path)); + JPluginHelper::importPlugin('content'); + $dispatcher = JEventDispatcher::getInstance(); + $result = $dispatcher->trigger('onContentBeforeSave', array('com_media.folder', &$object_file, true)); + + if (in_array(false, $result, true)) + { + // There are some errors in the plugins + JError::raiseWarning(100, JText::plural('COM_MEDIA_ERROR_BEFORE_SAVE', count($errors = $object_file->getErrors()), implode('
', $errors))); + + return false; + } + + if (JFolder::create($object_file->filepath)) + { + $data = "\n\n\n"; + JFile::write($object_file->filepath . '/index.html', $data); + + // Trigger the onContentAfterSave event. + $dispatcher->trigger('onContentAfterSave', array('com_media.folder', &$object_file, true)); + $this->setMessage(JText::sprintf('COM_MEDIA_CREATE_COMPLETE', substr($object_file->filepath, strlen(COM_MEDIA_BASE)))); + } + } + + $this->input->set('folder', ($parent) ? $parent . '/' . $folder : $folder); + } + else + { + // File name is of zero length (null). + JError::raiseWarning(100, JText::_('COM_MEDIA_ERROR_UNABLE_TO_CREATE_FOLDER_WARNDIRNAME')); + + return false; + } + + return true; + } +} diff --git a/Sites/pages/administrator/components/com_media/helpers/media.php b/Sites/pages/administrator/components/com_media/helpers/media.php new file mode 100644 index 00000000..5c48278a --- /dev/null +++ b/Sites/pages/administrator/components/com_media/helpers/media.php @@ -0,0 +1,200 @@ +isImage($fileName); + } + + /** + * Gets the file extension for the purpose of using an icon. + * + * @param string $fileName The filename + * + * @return string File extension + * + * @since 1.5 + * @deprecated 4.0 Use JHelperMedia::getTypeIcon instead + */ + public static function getTypeIcon($fileName) + { + try + { + JLog::add( + sprintf('%s() is deprecated. Use JHelperMedia::getTypeIcon() instead.', __METHOD__), + JLog::WARNING, + 'deprecated' + ); + } + catch (RuntimeException $exception) + { + // Informational log only + } + + $mediaHelper = new JHelperMedia; + + return $mediaHelper->getTypeIcon($fileName); + } + + /** + * Checks if the file can be uploaded + * + * @param array $file File information + * @param string $error An error message to be returned + * + * @return boolean + * + * @since 1.5 + * @deprecated 4.0 Use JHelperMedia::canUpload instead + */ + public static function canUpload($file, $error = '') + { + try + { + JLog::add( + sprintf('%s() is deprecated. Use JHelperMedia::canUpload() instead.', __METHOD__), + JLog::WARNING, + 'deprecated' + ); + } + catch (RuntimeException $exception) + { + // Informational log only + } + + $mediaHelper = new JHelperMedia; + + return $mediaHelper->canUpload($file, 'com_media'); + } + + /** + * Method to parse a file size + * + * @param integer $size The file size in bytes + * + * @return string The converted file size + * + * @since 1.6 + * @deprecated 4.0 Use JHtml::_('number.bytes') instead + */ + public static function parseSize($size) + { + try + { + JLog::add( + sprintf("%s() is deprecated. Use JHtml::_('number.bytes') instead.", __METHOD__), + JLog::WARNING, + 'deprecated' + ); + } + catch (RuntimeException $exception) + { + // Informational log only + } + + return JHtml::_('number.bytes', $size); + } + + /** + * Calculate the size of a resized image + * + * @param integer $width Image width + * @param integer $height Image height + * @param integer $target Target size + * + * @return array The new width and height + * + * @since 3.2 + * @deprecated 4.0 Use JHelperMedia::imageResize instead + */ + public static function imageResize($width, $height, $target) + { + try + { + JLog::add( + sprintf('%s() is deprecated. Use JHelperMedia::imageResize() instead.', __METHOD__), + JLog::WARNING, + 'deprecated' + ); + } + catch (RuntimeException $exception) + { + // Informational log only + } + + $mediaHelper = new JHelperMedia; + + return $mediaHelper->imageResize($width, $height, $target); + } + + /** + * Counts the files and directories in a directory that are not php or html files. + * + * @param string $dir Directory name + * + * @return array The number of files and directories in the given directory + * + * @since 1.5 + * @deprecated 4.0 Use JHelperMedia::countFiles instead + */ + public static function countFiles($dir) + { + try + { + JLog::add( + sprintf('%s() is deprecated. Use JHelperMedia::countFiles() instead.', __METHOD__), + JLog::WARNING, + 'deprecated' + ); + } + catch (RuntimeException $exception) + { + // Informational log only + } + + $mediaHelper = new JHelperMedia; + + return $mediaHelper->countFiles($dir); + } +} diff --git a/Sites/pages/administrator/components/com_media/layouts/toolbar/deletemedia.php b/Sites/pages/administrator/components/com_media/layouts/toolbar/deletemedia.php new file mode 100644 index 00000000..6dca4d01 --- /dev/null +++ b/Sites/pages/administrator/components/com_media/layouts/toolbar/deletemedia.php @@ -0,0 +1,32 @@ + + + + diff --git a/Sites/pages/administrator/components/com_media/layouts/toolbar/newfolder.php b/Sites/pages/administrator/components/com_media/layouts/toolbar/newfolder.php new file mode 100644 index 00000000..21b0c4c4 --- /dev/null +++ b/Sites/pages/administrator/components/com_media/layouts/toolbar/newfolder.php @@ -0,0 +1,16 @@ + + diff --git a/Sites/pages/administrator/components/com_media/layouts/toolbar/uploadmedia.php b/Sites/pages/administrator/components/com_media/layouts/toolbar/uploadmedia.php new file mode 100644 index 00000000..26635aec --- /dev/null +++ b/Sites/pages/administrator/components/com_media/layouts/toolbar/uploadmedia.php @@ -0,0 +1,16 @@ + + diff --git a/Sites/pages/administrator/components/com_media/media.php b/Sites/pages/administrator/components/com_media/media.php new file mode 100644 index 00000000..8ef14081 --- /dev/null +++ b/Sites/pages/administrator/components/com_media/media.php @@ -0,0 +1,53 @@ +input; +$user = JFactory::getUser(); +$asset = $input->get('asset'); +$author = $input->get('author'); + +// Access check. +if (!$user->authorise('core.manage', 'com_media') && (!$asset || (!$user->authorise('core.edit', $asset) + && !$user->authorise('core.create', $asset) + && count($user->getAuthorisedCategories($asset, 'core.create')) == 0) + && !($user->id == $author && $user->authorise('core.edit.own', $asset)))) +{ + throw new JAccessExceptionNotallowed(JText::_('JERROR_ALERTNOAUTHOR'), 403); +} + +$params = JComponentHelper::getParams('com_media'); + +// Load the helper class +JLoader::register('MediaHelper', JPATH_ADMINISTRATOR . '/components/com_media/helpers/media.php'); + +// Set the path definitions +$popup_upload = $input->get('pop_up', null); +$path = 'file_path'; +$view = $input->get('view'); + +if (substr(strtolower($view), 0, 6) == 'images' || $popup_upload == 1) +{ + $path = 'image_path'; +} + +$mediaBaseDir = JPATH_ROOT . '/' . $params->get($path, 'images'); + +if (!is_dir($mediaBaseDir)) +{ + throw new \InvalidArgumentException(JText::_('JERROR_AN_ERROR_HAS_OCCURRED'), 404); +} + +define('COM_MEDIA_BASE', $mediaBaseDir); +define('COM_MEDIA_BASEURL', JUri::root() . $params->get($path, 'images')); + +$controller = JControllerLegacy::getInstance('Media', array('base_path' => JPATH_COMPONENT_ADMINISTRATOR)); +$controller->execute($input->get('task')); +$controller->redirect(); diff --git a/Sites/pages/administrator/components/com_media/media.xml b/Sites/pages/administrator/components/com_media/media.xml new file mode 100644 index 00000000..c88d62b9 --- /dev/null +++ b/Sites/pages/administrator/components/com_media/media.xml @@ -0,0 +1,37 @@ + + + com_media + Joomla! Project + April 2006 + (C) 2005 - 2020 Open Source Matters. All rights reserved. + GNU General Public License version 2 or later; see LICENSE.txt + admin@joomla.org + www.joomla.org + 3.0.0 + COM_MEDIA_XML_DESCRIPTION + + controller.php + media.php + helpers + + + language/en-GB.com_media.ini + + + + config.xml + controller.php + media.php + controllers + helpers + layouts + models + views + + + language/en-GB.com_media.ini + language/en-GB.com_media.sys.ini + + + + diff --git a/Sites/pages/administrator/components/com_media/models/list.php b/Sites/pages/administrator/components/com_media/models/list.php new file mode 100644 index 00000000..b4b86bf7 --- /dev/null +++ b/Sites/pages/administrator/components/com_media/models/list.php @@ -0,0 +1,254 @@ +input; + $folder = $input->get('folder', '', 'path'); + $this->setState('folder', $folder); + + $parent = str_replace("\\", '/', dirname($folder)); + $parent = ($parent == '.') ? null : $parent; + $this->setState('parent', $parent); + $set = true; + } + + return parent::getState($property, $default); + } + + /** + * Get the images on the current folder + * + * @return array + * + * @since 1.5 + */ + public function getImages() + { + $list = $this->getList(); + + return $list['images']; + } + + /** + * Get the folders on the current folder + * + * @return array + * + * @since 1.5 + */ + public function getFolders() + { + $list = $this->getList(); + + return $list['folders']; + } + + /** + * Get the documents on the current folder + * + * @return array + * + * @since 1.5 + */ + public function getDocuments() + { + $list = $this->getList(); + + return $list['docs']; + } + + /** + * Build imagelist + * + * @return array + * + * @since 1.5 + */ + public function getList() + { + static $list; + + // Only process the list once per request + if (is_array($list)) + { + return $list; + } + + // Get current path from request + $current = (string) $this->getState('folder'); + + $basePath = COM_MEDIA_BASE . ((strlen($current) > 0) ? '/' . $current : ''); + $mediaBase = str_replace(DIRECTORY_SEPARATOR, '/', COM_MEDIA_BASE . '/'); + + // Reset base path + if (strpos(realpath($basePath), JPath::clean(realpath(COM_MEDIA_BASE))) !== 0) + { + $basePath = COM_MEDIA_BASE; + } + + $images = array (); + $folders = array (); + $docs = array (); + $videos = array (); + + $fileList = false; + $folderList = false; + + if (file_exists($basePath)) + { + // Get the list of files and folders from the given folder + $fileList = JFolder::files($basePath); + $folderList = JFolder::folders($basePath); + } + + // Iterate over the files if they exist + if ($fileList !== false) + { + $tmpBaseObject = new JObject; + + foreach ($fileList as $file) + { + if (is_file($basePath . '/' . $file) && substr($file, 0, 1) != '.' && strtolower($file) !== 'index.html') + { + $tmp = clone $tmpBaseObject; + $tmp->name = $file; + $tmp->title = $file; + $tmp->path = str_replace(DIRECTORY_SEPARATOR, '/', JPath::clean($basePath . '/' . $file)); + $tmp->path_relative = str_replace($mediaBase, '', $tmp->path); + $tmp->size = filesize($tmp->path); + + $ext = strtolower(JFile::getExt($file)); + + switch ($ext) + { + // Image + case 'jpg': + case 'png': + case 'gif': + case 'xcf': + case 'odg': + case 'bmp': + case 'jpeg': + case 'ico': + $info = @getimagesize($tmp->path); + $tmp->width = @$info[0]; + $tmp->height = @$info[1]; + $tmp->type = @$info[2]; + $tmp->mime = @$info['mime']; + + if (($info[0] > 60) || ($info[1] > 60)) + { + $dimensions = MediaHelper::imageResize($info[0], $info[1], 60); + $tmp->width_60 = $dimensions[0]; + $tmp->height_60 = $dimensions[1]; + } + else + { + $tmp->width_60 = $tmp->width; + $tmp->height_60 = $tmp->height; + } + + if (($info[0] > 16) || ($info[1] > 16)) + { + $dimensions = MediaHelper::imageResize($info[0], $info[1], 16); + $tmp->width_16 = $dimensions[0]; + $tmp->height_16 = $dimensions[1]; + } + else + { + $tmp->width_16 = $tmp->width; + $tmp->height_16 = $tmp->height; + } + + $images[] = $tmp; + break; + + // Video + case 'mp4': + $tmp->icon_32 = 'media/mime-icon-32/' . $ext . '.png'; + $tmp->icon_16 = 'media/mime-icon-16/' . $ext . '.png'; + $videos[] = $tmp; + break; + + // Non-image document + default: + $tmp->icon_32 = 'media/mime-icon-32/' . $ext . '.png'; + $tmp->icon_16 = 'media/mime-icon-16/' . $ext . '.png'; + $docs[] = $tmp; + break; + } + } + } + } + + // Iterate over the folders if they exist + if ($folderList !== false) + { + $tmpBaseObject = new JObject; + + foreach ($folderList as $folder) + { + $tmp = clone $tmpBaseObject; + $tmp->name = basename($folder); + $tmp->path = str_replace(DIRECTORY_SEPARATOR, '/', JPath::clean($basePath . '/' . $folder)); + $tmp->path_relative = str_replace($mediaBase, '', $tmp->path); + $count = MediaHelper::countFiles($tmp->path); + $tmp->files = $count[0]; + $tmp->folders = $count[1]; + + $folders[] = $tmp; + } + } + + $list = array('folders' => $folders, 'docs' => $docs, 'images' => $images, 'videos' => $videos); + + return $list; + } + + /** + * Get the videos on the current folder + * + * @return array + * + * @since 3.5 + */ + public function getVideos() + { + $list = $this->getList(); + + return $list['videos']; + } +} diff --git a/Sites/pages/administrator/components/com_media/models/manager.php b/Sites/pages/administrator/components/com_media/models/manager.php new file mode 100644 index 00000000..2d4523fe --- /dev/null +++ b/Sites/pages/administrator/components/com_media/models/manager.php @@ -0,0 +1,178 @@ +input; + + $folder = $input->get('folder', '', 'path'); + $this->setState('folder', $folder); + + $fieldid = $input->get('fieldid', ''); + $this->setState('field.id', $fieldid); + + $parent = str_replace("\\", '/', dirname($folder)); + $parent = ($parent == '.') ? null : $parent; + $this->setState('parent', $parent); + $set = true; + } + + return parent::getState($property, $default); + } + + /** + * Get a select field with a list of available folders + * + * @param string $base The image directory to display + * + * @return html + * + * @since 1.5 + */ + public function getFolderList($base = null) + { + // Get some paths from the request + if (empty($base)) + { + $base = COM_MEDIA_BASE; + } + + // Corrections for windows paths + $base = str_replace(DIRECTORY_SEPARATOR, '/', $base); + $com_media_base_uni = str_replace(DIRECTORY_SEPARATOR, '/', COM_MEDIA_BASE); + + // Get the list of folders + jimport('joomla.filesystem.folder'); + $folders = JFolder::folders($base, '.', true, true); + + $document = JFactory::getDocument(); + $document->setTitle(JText::_('COM_MEDIA_INSERT_IMAGE')); + + // Build the array of select options for the folder list + $options[] = JHtml::_('select.option', '', '/'); + + foreach ($folders as $folder) + { + $folder = str_replace($com_media_base_uni, '', str_replace(DIRECTORY_SEPARATOR, '/', $folder)); + $value = substr($folder, 1); + $text = str_replace(DIRECTORY_SEPARATOR, '/', $folder); + $options[] = JHtml::_('select.option', $value, $text); + } + + // Sort the folder list array + if (is_array($options)) + { + sort($options); + } + + // Get asset and author id (use integer filter) + $input = JFactory::getApplication()->input; + $asset = $input->get('asset', 0, 'integer'); + + // For new items the asset is a string. JAccess always checks type first + // so both string and integer are supported. + if ($asset == 0) + { + $asset = htmlspecialchars(json_encode(trim($input->get('asset', 0, 'cmd'))), ENT_COMPAT, 'UTF-8'); + } + + $author = $input->get('author', 0, 'integer'); + + // Create the dropdown folder select list + $attribs = 'size="1" onchange="ImageManager.setFolder(this.options[this.selectedIndex].value, ' . $asset . ', ' . $author . ')" '; + $list = JHtml::_('select.genericlist', $options, 'folderlist', $attribs, 'value', 'text', $base); + + return $list; + } + + /** + * Get the folder tree + * + * @param mixed $base Base folder | null for using base media folder + * + * @return array + * + * @since 1.5 + */ + public function getFolderTree($base = null) + { + // Get some paths from the request + if (empty($base)) + { + $base = COM_MEDIA_BASE; + } + + $mediaBase = str_replace(DIRECTORY_SEPARATOR, '/', COM_MEDIA_BASE . '/'); + + // Get the list of folders + jimport('joomla.filesystem.folder'); + $folders = JFolder::folders($base, '.', true, true); + + $tree = array(); + + foreach ($folders as $folder) + { + $folder = str_replace(DIRECTORY_SEPARATOR, '/', $folder); + $name = substr($folder, strrpos($folder, '/') + 1); + $relative = str_replace($mediaBase, '', $folder); + $absolute = $folder; + $path = explode('/', $relative); + $node = (object) array('name' => $name, 'relative' => $relative, 'absolute' => $absolute); + $tmp = &$tree; + + for ($i = 0, $n = count($path); $i < $n; $i++) + { + if (!isset($tmp['children'])) + { + $tmp['children'] = array(); + } + + if ($i == $n - 1) + { + // We need to place the node + $tmp['children'][$relative] = array('data' => $node, 'children' => array()); + + break; + } + + if (array_key_exists($key = implode('/', array_slice($path, 0, $i + 1)), $tmp['children'])) + { + $tmp = &$tmp['children'][$key]; + } + } + } + + $tree['data'] = (object) array('name' => JText::_('COM_MEDIA_MEDIA'), 'relative' => '', 'absolute' => $base); + + return $tree; + } +} diff --git a/Sites/pages/administrator/components/com_media/views/images/tmpl/default.php b/Sites/pages/administrator/components/com_media/views/images/tmpl/default.php new file mode 100644 index 00000000..580eacb4 --- /dev/null +++ b/Sites/pages/administrator/components/com_media/views/images/tmpl/default.php @@ -0,0 +1,198 @@ +input; +$params = JComponentHelper::getParams('com_media'); +$lang = JFactory::getLanguage(); +$onClick = ''; +$fieldInput = $this->state->get('field.id'); +$isMoo = $input->getInt('ismoo', 1); +$author = $input->getCmd('author'); +$asset = $input->getCmd('asset'); + +JHtml::_('formbehavior.chosen', 'select'); + +// Load tooltip instance without HTML support because we have a HTML tag in the tip +JHtml::_('bootstrap.tooltip', '.noHtmlTip', array('html' => false)); + +// Include jQuery +JHtml::_('behavior.core'); +JHtml::_('jquery.framework'); +JHtml::_('script', 'media/popup-imagemanager.min.js', array('version' => 'auto', 'relative' => true)); +JHtml::_('stylesheet', 'media/popup-imagemanager.css', array('version' => 'auto', 'relative' => true)); + +if ($lang->isRtl()) +{ + JHtml::_('stylesheet', 'media/popup-imagemanager_rtl.css', array('version' => 'auto', 'relative' => true)); +} + +JFactory::getDocument()->addScriptOptions( + 'mediamanager', array( + 'base' => $params->get('image_path', 'images') . '/', + 'asset' => $asset, + 'author' => $author + ) +); + +/** + * Mootools compatibility + * + * There is an extra option passed in the URL for the iframe &ismoo=0 for the bootstrap fields. + * By default the value will be 1 or defaults to mootools behaviour + * + * This should be removed when mootools won't be shipped by Joomla. + */ +if (!empty($fieldInput)) // Media Form Field +{ + if ($isMoo) + { + $onClick = "window.parent.jInsertFieldValue(document.getElementById('f_url').value, '" . $fieldInput . "');window.parent.jModalClose();window.parent.jQuery('.modal.in').modal('hide');"; + } +} +else // XTD Image plugin +{ + $onClick = 'ImageManager.onok();window.parent.jModalClose();'; +} +?> +
+ +
+ + + +
+
+
+
+ +
+
+ folderList; ?> + +
+
+
+
+ + +
+
+
+
+ + + +
+
+
+
+ +
+
+ +
+
+
+
+ + state->get('field.id')) : ?> +
+
+
+
+ +
+
+ +
+
+
+
+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+
+
+
+
+ +
+
+ +
+
+
+
+ +
+
+ + + +
+
+
+ + + +
+ +
+ + authorise('core.create', 'com_media')) : ?> +
+
+
+
+
+ +
+
+ +

+ config->get('upload_maxsize'); ?> + + +

+
+
+
+ set('com_media.return_url', 'index.php?option=com_media&view=images&tmpl=component&fieldid=' . $input->getCmd('fieldid', '') . '&e_name=' . $input->getCmd('e_name') . '&asset=' . $asset . '&author=' . $author); ?> +
+
+ +
diff --git a/Sites/pages/administrator/components/com_media/views/images/view.html.php b/Sites/pages/administrator/components/com_media/views/images/view.html.php new file mode 100644 index 00000000..229f4f23 --- /dev/null +++ b/Sites/pages/administrator/components/com_media/views/images/view.html.php @@ -0,0 +1,46 @@ +session = JFactory::getSession(); + $this->config = $config; + $this->state = $this->get('state'); + $this->folderList = $this->get('folderList'); + $this->require_ftp = $ftp; + + parent::display($tpl); + } +} diff --git a/Sites/pages/administrator/components/com_media/views/imageslist/tmpl/default.php b/Sites/pages/administrator/components/com_media/views/imageslist/tmpl/default.php new file mode 100644 index 00000000..e4813e78 --- /dev/null +++ b/Sites/pages/administrator/components/com_media/views/imageslist/tmpl/default.php @@ -0,0 +1,64 @@ + 'auto', 'relative' => true)); + +if ($lang->isRtl()) +{ + JHtml::_('stylesheet', 'media/popup-imagelist_rtl.css', array('version' => 'auto', 'relative' => true)); +} + +JFactory::getDocument()->addScriptDeclaration('var ImageManager = window.parent.ImageManager;'); + +if ($lang->isRtl()) +{ + JFactory::getDocument()->addStyleDeclaration( + ' + @media (max-width: 767px) { + li.imgOutline.thumbnail.height-80.width-80.center { + float: right; + } + } + ' + ); +} +else +{ + JFactory::getDocument()->addStyleDeclaration( + ' + @media (max-width: 767px) { + li.imgOutline.thumbnail.height-80.width-80.center { + float: left; + } + } + ' + ); +} +?> +images) > 0 || count($this->folders) > 0) : ?> +
    + folders); $i < $n; $i++) : + $this->setFolder($i); + echo $this->loadTemplate('folder'); + endfor; ?> + + images); $i < $n; $i++) : + $this->setImage($i); + echo $this->loadTemplate('image'); + endfor; ?> +
+ +
+
+
+ diff --git a/Sites/pages/administrator/components/com_media/views/imageslist/tmpl/default_folder.php b/Sites/pages/administrator/components/com_media/views/imageslist/tmpl/default_folder.php new file mode 100644 index 00000000..869da6ca --- /dev/null +++ b/Sites/pages/administrator/components/com_media/views/imageslist/tmpl/default_folder.php @@ -0,0 +1,23 @@ +input; +?> +
  • + +
    + +
    +
    + escape($this->_tmp_folder->name), 10, false); ?> +
    +
    +
  • diff --git a/Sites/pages/administrator/components/com_media/views/imageslist/tmpl/default_image.php b/Sites/pages/administrator/components/com_media/views/imageslist/tmpl/default_image.php new file mode 100644 index 00000000..e1d4f073 --- /dev/null +++ b/Sites/pages/administrator/components/com_media/views/imageslist/tmpl/default_image.php @@ -0,0 +1,30 @@ +trigger('onContentBeforeDisplay', array('com_media.file', &$this->_tmp_img, &$params, 0)); +?> + +
  • + +
    + baseURL . '/' . $this->escape($this->_tmp_img->path_relative), JText::sprintf('COM_MEDIA_IMAGE_TITLE', $this->escape($this->_tmp_img->title), JHtml::_('number.bytes', $this->_tmp_img->size)), array('width' => $this->_tmp_img->width_60, 'height' => $this->_tmp_img->height_60)); ?> +
    +
    + escape($this->_tmp_img->name), 10, false); ?> +
    +
    +
  • +trigger('onContentAfterDisplay', array('com_media.file', &$this->_tmp_img, &$params, 0)); diff --git a/Sites/pages/administrator/components/com_media/views/imageslist/view.html.php b/Sites/pages/administrator/components/com_media/views/imageslist/view.html.php new file mode 100644 index 00000000..f9c202f0 --- /dev/null +++ b/Sites/pages/administrator/components/com_media/views/imageslist/view.html.php @@ -0,0 +1,86 @@ +allowCache(false); + + $images = $this->get('images'); + $folders = $this->get('folders'); + $state = $this->get('state'); + + $this->baseURL = COM_MEDIA_BASEURL; + $this->images = &$images; + $this->folders = &$folders; + $this->state = &$state; + + parent::display($tpl); + } + + /** + * Set the active folder + * + * @param integer $index Folder position + * + * @return void + * + * @since 1.0 + */ + public function setFolder($index = 0) + { + if (isset($this->folders[$index])) + { + $this->_tmp_folder = &$this->folders[$index]; + } + else + { + $this->_tmp_folder = new JObject; + } + } + + /** + * Set the active image + * + * @param integer $index Image position + * + * @return void + * + * @since 1.0 + */ + public function setImage($index = 0) + { + if (isset($this->images[$index])) + { + $this->_tmp_img = &$this->images[$index]; + } + else + { + $this->_tmp_img = new JObject; + } + } +} diff --git a/Sites/pages/administrator/components/com_media/views/media/tmpl/default.php b/Sites/pages/administrator/components/com_media/views/media/tmpl/default.php new file mode 100644 index 00000000..4581d963 --- /dev/null +++ b/Sites/pages/administrator/components/com_media/views/media/tmpl/default.php @@ -0,0 +1,149 @@ +input; +$lang = JFactory::getLanguage(); +$style = JFactory::getApplication()->getUserStateFromRequest('media.list.layout', 'layout', 'thumbs', 'word'); + +if (DIRECTORY_SEPARATOR == '\\') +{ + $base = str_replace(DIRECTORY_SEPARATOR, "\\\\", COM_MEDIA_BASE); +} +else +{ + $base = COM_MEDIA_BASE; +} + +JFactory::getDocument()->addScriptDeclaration( + " + var basepath = '" . $base . "'; + var viewstyle = '" . $style . "'; + " +); + +JHtml::_('behavior.keepalive'); +JHtml::_('bootstrap.framework'); +JHtml::_('script', 'media/mediamanager.min.js', array('version' => 'auto', 'relative' => true)); +JHtml::_('script', 'media/mediaelement-and-player.js', array('version' => 'auto', 'relative' => true)); +JHtml::_('stylesheet', 'media/mediaelementplayer.css', array('version' => 'auto', 'relative' => true)); +JHtml::_('stylesheet', 'system/mootree.css', array('version' => 'auto', 'relative' => true)); + +if ($lang->isRtl()) +{ + JHtml::_('stylesheet', 'system/mootree_rtl.css', array('version' => 'auto', 'relative' => true)); +} +?> +
    + +
    + sidebar; ?> +
    +

    +
    + +
    + + + +
    + loadTemplate('navigation'); ?> + authorise('core.create', 'com_media')) and $this->require_ftp) : ?> +
    +
    + + + + + + + +
    +
    + + +
    + + + +
    + + authorise('core.create', 'com_media')) : ?> + +
    +
    +
    +
    + + +

    + config->get('upload_maxsize'); ?> + + +

    +
    + + set('com_media.return_url', 'index.php?option=com_media'); ?> +
    +
    +
    +
    +
    +
    + + + + +
    + +
    +
    + + +
    +
    +
    + +
    + +
    +
    +
    + JText::_('COM_MEDIA_PREVIEW'), + 'footer' => '', + ), + '
    preview
    ' +); + +echo JHtml::_( + 'bootstrap.renderModal', + 'videoPreview', + array( + 'title' => JText::_('COM_MEDIA_PREVIEW'), + 'footer' => '', + ), + '
    ' +); +?> + +
    diff --git a/Sites/pages/administrator/components/com_media/views/media/tmpl/default.xml b/Sites/pages/administrator/components/com_media/views/media/tmpl/default.xml new file mode 100755 index 00000000..6aa1cbb2 --- /dev/null +++ b/Sites/pages/administrator/components/com_media/views/media/tmpl/default.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/Sites/pages/administrator/components/com_media/views/media/tmpl/default_folders.php b/Sites/pages/administrator/components/com_media/views/media/tmpl/default_folders.php new file mode 100644 index 00000000..5c360e58 --- /dev/null +++ b/Sites/pages/administrator/components/com_media/views/media/tmpl/default_folders.php @@ -0,0 +1,30 @@ +folders['data']->relative); + +?> + diff --git a/Sites/pages/administrator/components/com_media/views/media/tmpl/default_navigation.php b/Sites/pages/administrator/components/com_media/views/media/tmpl/default_navigation.php new file mode 100644 index 00000000..219959a5 --- /dev/null +++ b/Sites/pages/administrator/components/com_media/views/media/tmpl/default_navigation.php @@ -0,0 +1,20 @@ +getUserStateFromRequest('media.list.layout', 'layout', 'thumbs', 'word'); +?> + +
    + + + + +
    diff --git a/Sites/pages/administrator/components/com_media/views/media/view.html.php b/Sites/pages/administrator/components/com_media/views/media/view.html.php new file mode 100644 index 00000000..e8482fa2 --- /dev/null +++ b/Sites/pages/administrator/components/com_media/views/media/view.html.php @@ -0,0 +1,141 @@ +isClient('administrator')) + { + return $app->enqueueMessage(JText::_('JERROR_ALERTNOAUTHOR'), 'warning'); + } + + /* + * Display form for FTP credentials? + * Don't set them here, as there are other functions called before this one if there is any file write operation + */ + $ftp = !JClientHelper::hasCredentials('ftp'); + + $session = JFactory::getSession(); + $state = $this->get('state'); + $this->session = $session; + $this->config = &$config; + $this->state = &$state; + $this->require_ftp = $ftp; + $this->folders_id = ' id="media-tree"'; + $this->folders = $this->get('folderTree'); + + $this->sidebar = JHtmlSidebar::render(); + + // Set the toolbar + $this->addToolbar(); + + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + // Get the toolbar object instance + $bar = JToolbar::getInstance('toolbar'); + $user = JFactory::getUser(); + + // Set the titlebar text + JToolbarHelper::title(JText::_('COM_MEDIA'), 'images mediamanager'); + + // Add an upload button + if ($user->authorise('core.create', 'com_media')) + { + // Instantiate a new JLayoutFile instance and render the layout + $layout = new JLayoutFile('toolbar.uploadmedia'); + + $bar->appendButton('Custom', $layout->render(array()), 'upload'); + JToolbarHelper::divider(); + } + + // Add a create folder button + if ($user->authorise('core.create', 'com_media')) + { + // Instantiate a new JLayoutFile instance and render the layout + $layout = new JLayoutFile('toolbar.newfolder'); + + $bar->appendButton('Custom', $layout->render(array()), 'create'); + JToolbarHelper::divider(); + } + + // Add a delete button + if ($user->authorise('core.delete', 'com_media')) + { + // Instantiate a new JLayoutFile instance and render the layout + $layout = new JLayoutFile('toolbar.deletemedia'); + + $bar->appendButton('Custom', $layout->render(array()), 'delete'); + JToolbarHelper::divider(); + } + + // Add a preferences button + if ($user->authorise('core.admin', 'com_media') || $user->authorise('core.options', 'com_media')) + { + JToolbarHelper::preferences('com_media'); + JToolbarHelper::divider(); + } + + JToolbarHelper::help('JHELP_CONTENT_MEDIA_MANAGER'); + } + + /** + * Display a folder level + * + * @param array $folder Array with folder data + * + * @return string + * + * @since 1.0 + */ + protected function getFolderLevel($folder) + { + $this->folders_id = null; + $txt = null; + + if (isset($folder['children']) && count($folder['children'])) + { + $tmp = $this->folders; + $this->folders = $folder; + $txt = $this->loadTemplate('folders'); + $this->folders = $tmp; + } + + return $txt; + } +} diff --git a/Sites/pages/administrator/components/com_media/views/medialist/tmpl/default.php b/Sites/pages/administrator/components/com_media/views/medialist/tmpl/default.php new file mode 100644 index 00000000..1bfbbb8e --- /dev/null +++ b/Sites/pages/administrator/components/com_media/views/medialist/tmpl/default.php @@ -0,0 +1,10 @@ +addScriptDeclaration( + " + Joomla.isChecked = function( isitchecked, form ) { + if ( typeof form === 'undefined' ) { + form = document.getElementById( 'mediamanager-form' ); + } + + form.boxchecked.value += isitchecked ? 1 : -1; + + // If we don't have a checkall-toggle, done. + if ( !form.elements[ 'checkall-toggle' ] ) return; + + // Toggle main toggle checkbox depending on checkbox selection + var c = true, + i, e, n; + + for ( i = 0, n = form.elements.length; i < n; i++ ) { + e = form.elements[ i ]; + + if ( e.type == 'checkbox' && e.name != 'checkall-toggle' && !e.checked ) { + c = false; + break; + } + } + + form.elements[ 'checkall-toggle' ].checked = c; + }; + " +); + +$doc->addScriptDeclaration( + " + jQuery(document).ready(function($){ + window.parent.document.updateUploader(); + $('.img-preview, .preview').each(function(index, value) { + $(this).on('click', function(e) { + window.parent.jQuery('#imagePreviewSrc').attr('src', $(this).attr('href')); + window.parent.jQuery('#imagePreview').modal('show'); + return false; + }); + }); + $('.video-preview').each(function(index, value) { + $(this).unbind('click'); + $(this).on('click', function(e) { + e.preventDefault(); + window.parent.jQuery('#videoPreview').modal('show'); + + var elementInitialised = window.parent.jQuery('#mejsPlayer').attr('src'); + + if (!elementInitialised) + { + window.parent.jQuery('#mejsPlayer').attr('src', $(this).attr('href')); + window.parent.jQuery('#mejsPlayer').mediaelementplayer(); + } + + window.parent.jQuery('#mejsPlayer')[0].player.media.setSrc($(this).attr('href')); + + return false; + }); + }); + }); + " +); +?> +
    +
    +

    + + get($path, 'images'), + ($this->escape($this->state->folder) != '') ? '/' . $this->escape($this->state->folder) : ''; + ?> +

    +
    + +
    + + + + canDelete) : ?> + + + + + + + + canDelete) : ?> + + + + + + loadTemplate('up'), + $this->loadTemplate('folders'), + $this->loadTemplate('docs'), + $this->loadTemplate('videos'), + $this->loadTemplate('imgs'); + ?> + +
    + + + +
    +
    + + + + + + +
    diff --git a/Sites/pages/administrator/components/com_media/views/medialist/tmpl/details_doc.php b/Sites/pages/administrator/components/com_media/views/medialist/tmpl/details_doc.php new file mode 100644 index 00000000..a9548709 --- /dev/null +++ b/Sites/pages/administrator/components/com_media/views/medialist/tmpl/details_doc.php @@ -0,0 +1,42 @@ +trigger('onContentBeforeDisplay', array('com_media.file', &$this->_tmp_doc, &$params, 0)); +?> + + + + + _tmp_doc->icon_16, $this->escape($this->_tmp_doc->title), null, true, true) ? JHtml::_('image', $this->_tmp_doc->icon_16, $this->_tmp_doc->title, array('width' => 16, 'height' => 16), true) : JHtml::_('image', 'media/con_info.png', $this->escape($this->_tmp_doc->title), array('width' => 16, 'height' => 16), true);?> + + + escape($this->_tmp_doc->title); ?> + +   + + + + _tmp_doc->size); ?> + +authorise('core.delete', 'com_media')):?> + + + + + + +trigger('onContentAfterDisplay', array('com_media.file', &$this->_tmp_doc, &$params, 0)); diff --git a/Sites/pages/administrator/components/com_media/views/medialist/tmpl/details_docs.php b/Sites/pages/administrator/components/com_media/views/medialist/tmpl/details_docs.php new file mode 100644 index 00000000..5898724f --- /dev/null +++ b/Sites/pages/administrator/components/com_media/views/medialist/tmpl/details_docs.php @@ -0,0 +1,54 @@ + + +documents as $i => $doc) : ?> + trigger('onContentBeforeDisplay', array('com_media.file', &$doc, &$params, 0)); ?> + + canDelete) : ?> + + escape($doc->name), false, 'rm', 'cb-document'); ?> + + + + + + icon_16, $this->escape($doc->title), null, true, true) ? JHtml::_('image', $doc->icon_16, $this->escape($doc->title), array('width' => 16, 'height' => 16), true) : JHtml::_('image', 'media/con_info.png', $this->escape($doc->title), array('width' => 16, 'height' => 16), true); ?> + + + + + escape($doc->title); ?> + + +   + + + size); ?> + + + canDelete) : ?> + + + + + + + + + trigger('onContentAfterDisplay', array('com_media.file', &$doc, &$params, 0)); ?> + diff --git a/Sites/pages/administrator/components/com_media/views/medialist/tmpl/details_folder.php b/Sites/pages/administrator/components/com_media/views/medialist/tmpl/details_folder.php new file mode 100644 index 00000000..b203a00c --- /dev/null +++ b/Sites/pages/administrator/components/com_media/views/medialist/tmpl/details_folder.php @@ -0,0 +1,35 @@ + + + + + + + + escape($this->_tmp_folder->name); ?> + +   + + +   + + + authorise('core.delete', 'com_media')):?> + + + + + + diff --git a/Sites/pages/administrator/components/com_media/views/medialist/tmpl/details_folders.php b/Sites/pages/administrator/components/com_media/views/medialist/tmpl/details_folders.php new file mode 100644 index 00000000..fd09fea4 --- /dev/null +++ b/Sites/pages/administrator/components/com_media/views/medialist/tmpl/details_folders.php @@ -0,0 +1,42 @@ + + +folders as $i => $folder) : ?> + path_relative); ?> + + canDelete) : ?> + + escape($folder->name), false, 'rm', 'cb-folder'); ?> + + + + + + + + escape($folder->name); ?> + + +   + +   + + canDelete) : ?> + + + + + + + + diff --git a/Sites/pages/administrator/components/com_media/views/medialist/tmpl/details_img.php b/Sites/pages/administrator/components/com_media/views/medialist/tmpl/details_img.php new file mode 100644 index 00000000..fd82cbce --- /dev/null +++ b/Sites/pages/administrator/components/com_media/views/medialist/tmpl/details_img.php @@ -0,0 +1,42 @@ +trigger('onContentBeforeDisplay', array('com_media.file', &$this->_tmp_img, &$params, 0)); +?> + + + + escape($this->_tmp_img->path_relative), JText::sprintf('COM_MEDIA_IMAGE_TITLE', $this->_tmp_img->title, JHtml::_('number.bytes', $this->_tmp_img->size)), array('width' => $this->_tmp_img->width_16, 'height' => $this->_tmp_img->height_16)); ?> + + + escape($this->_tmp_img->title); ?> + + + _tmp_img->width, $this->_tmp_img->height); ?> + + + _tmp_img->size); ?> + + authorise('core.delete', 'com_media')):?> + + + + + + +trigger('onContentAfterDisplay', array('com_media.file', &$this->_tmp_img, &$params, 0)); diff --git a/Sites/pages/administrator/components/com_media/views/medialist/tmpl/details_imgs.php b/Sites/pages/administrator/components/com_media/views/medialist/tmpl/details_imgs.php new file mode 100644 index 00000000..c1701888 --- /dev/null +++ b/Sites/pages/administrator/components/com_media/views/medialist/tmpl/details_imgs.php @@ -0,0 +1,59 @@ + + +images as $i => $image) : ?> + trigger('onContentBeforeDisplay', array('com_media.file', &$image, &$params, 0)); ?> + + canDelete) : ?> + + escape($image->name), false, 'rm', 'cb-image'); ?> + + + + + + escape($image->path_relative), JText::sprintf('COM_MEDIA_IMAGE_TITLE', $this->escape($image->title), JHtml::_('number.bytes', $image->size)), array('width' => $image->width_16, 'height' => $image->height_16)); ?> + + + + + + escape($image->title); ?> + + + + + width, $image->height); ?> + + + + size); ?> + + + canDelete) : ?> + + + + + + + + trigger('onContentAfterDisplay', array('com_media.file', &$image, &$params, 0)); ?> + diff --git a/Sites/pages/administrator/components/com_media/views/medialist/tmpl/details_up.php b/Sites/pages/administrator/components/com_media/views/medialist/tmpl/details_up.php new file mode 100644 index 00000000..49055b52 --- /dev/null +++ b/Sites/pages/administrator/components/com_media/views/medialist/tmpl/details_up.php @@ -0,0 +1,32 @@ + +state->folder != '') : ?> + + canDelete) : ?> +   + + + + + + + .. + +   +   + authorise('core.delete', 'com_media')) : ?> +   + + + diff --git a/Sites/pages/administrator/components/com_media/views/medialist/tmpl/details_video.php b/Sites/pages/administrator/components/com_media/views/medialist/tmpl/details_video.php new file mode 100644 index 00000000..2ee2be8c --- /dev/null +++ b/Sites/pages/administrator/components/com_media/views/medialist/tmpl/details_video.php @@ -0,0 +1,54 @@ +trigger('onContentBeforeDisplay', array('com_media.file', &$this->_tmp_video, &$params, 0)); + +JFactory::getDocument()->addScriptDeclaration(" +jQuery(document).ready(function($){ + window.parent.jQuery('#videoPreview').on('hidden', function () { + window.parent.jQuery('#mejsPlayer')[0].player.pause(); + }); +}); +"); +?> + + + + _tmp_video->icon_16, $this->escape($this->_tmp_video->title), null, true); ?> + + + + escape($this->_tmp_video->name), 10, false); ?> + + + + + + + _tmp_video->size); ?> + + authorise('core.delete', 'com_media')):?> + + + + + + + +trigger('onContentAfterDisplay', array('com_media.file', &$this->_tmp_video, &$params, 0)); diff --git a/Sites/pages/administrator/components/com_media/views/medialist/tmpl/details_videos.php b/Sites/pages/administrator/components/com_media/views/medialist/tmpl/details_videos.php new file mode 100644 index 00000000..fa1758a8 --- /dev/null +++ b/Sites/pages/administrator/components/com_media/views/medialist/tmpl/details_videos.php @@ -0,0 +1,67 @@ +addScriptDeclaration(" +jQuery(document).ready(function($){ + window.parent.jQuery('#videoPreview').on('hidden', function () { + window.parent.jQuery('#mejsPlayer')[0].player.pause(); + }); +}); +"); +?> + +videos as $i => $video) : ?> + trigger('onContentBeforeDisplay', array('com_media.file', &$video, &$params, 0)); ?> + + canDelete) : ?> + + escape($video->name), false, 'rm', 'cb-video'); ?> + + + + + + icon_16, $this->escape($video->title), null, true); ?> + + + + + + escape($video->name); ?> + + + + + + + + + size); ?> + + + canDelete) : ?> + + + + + + + + + trigger('onContentAfterDisplay', array('com_media.file', &$video, &$params, 0)); ?> + diff --git a/Sites/pages/administrator/components/com_media/views/medialist/tmpl/thumbs.php b/Sites/pages/administrator/components/com_media/views/medialist/tmpl/thumbs.php new file mode 100644 index 00000000..02a26fcf --- /dev/null +++ b/Sites/pages/administrator/components/com_media/views/medialist/tmpl/thumbs.php @@ -0,0 +1,117 @@ +addScriptDeclaration( + " + Joomla.isChecked = function( isitchecked, form ) { + if ( typeof form === 'undefined' ) { + form = document.getElementById( 'mediamanager-form' ); + } + + form.boxchecked.value += isitchecked ? 1 : -1; + + // If we don't have a checkall-toggle, done. + if ( !form.elements[ 'checkall-toggle' ] ) return; + + // Toggle main toggle checkbox depending on checkbox selection + var c = true, + i, e, n; + + for ( i = 0, n = form.elements.length; i < n; i++ ) { + e = form.elements[ i ]; + + if ( e.type == 'checkbox' && e.name != 'checkall-toggle' && !e.checked ) { + c = false; + break; + } + } + + form.elements[ 'checkall-toggle' ].checked = c; + }; + " +); + +$doc->addScriptDeclaration( + " + jQuery(document).ready(function($){ + window.parent.document.updateUploader(); + $('.img-preview, .preview').each(function(index, value) { + $(this).on('click', function(e) { + window.parent.jQuery('#imagePreviewSrc').attr('src', $(this).attr('href')); + window.parent.jQuery('#imagePreview').modal('show'); + return false; + }); + }); + $('.video-preview').each(function(index, value) { + $(this).unbind('click'); + $(this).on('click', function(e) { + e.preventDefault(); + window.parent.jQuery('#videoPreview').modal('show'); + + var elementInitialised = window.parent.jQuery('#mejsPlayer').attr('src'); + + if (!elementInitialised) + { + window.parent.jQuery('#mejsPlayer').attr('src', $(this).attr('href')); + window.parent.jQuery('#mejsPlayer').mediaelementplayer(); + } + + window.parent.jQuery('#mejsPlayer')[0].player.media.setSrc($(this).attr('href')); + + return false; + }); + }); + }); + " +); +?> +
    + + +
    + +
    + +
      + loadTemplate('up'), + $this->loadTemplate('folders'), + $this->loadTemplate('docs'), + $this->loadTemplate('videos'), + $this->loadTemplate('imgs'); + ?> + + + + + + +
    +
    diff --git a/Sites/pages/administrator/components/com_media/views/medialist/tmpl/thumbs_docs.php b/Sites/pages/administrator/components/com_media/views/medialist/tmpl/thumbs_docs.php new file mode 100644 index 00000000..30c9c61a --- /dev/null +++ b/Sites/pages/administrator/components/com_media/views/medialist/tmpl/thumbs_docs.php @@ -0,0 +1,40 @@ + + +documents as $i => $doc) : ?> + trigger('onContentBeforeDisplay', array('com_media.file', &$doc, &$params, 0)); ?> +
  • + canDelete) : ?> + × +
    + escape($doc->name), false, 'rm', 'cb-document'); ?> +
    +
    + + + + +
    + escape($doc->name), 10, false); ?> +
    +
  • + trigger('onContentAfterDisplay', array('com_media.file', &$doc, &$params, 0)); ?> + diff --git a/Sites/pages/administrator/components/com_media/views/medialist/tmpl/thumbs_folders.php b/Sites/pages/administrator/components/com_media/views/medialist/tmpl/thumbs_folders.php new file mode 100644 index 00000000..5da73b79 --- /dev/null +++ b/Sites/pages/administrator/components/com_media/views/medialist/tmpl/thumbs_folders.php @@ -0,0 +1,35 @@ + +folders as $i => $folder) : ?> +
  • + canDelete) : ?> + × +
    + escape($folder->name), false, 'rm', 'cb-folder'); ?> +
    +
    + + +
    + + + +
    + + +
  • + diff --git a/Sites/pages/administrator/components/com_media/views/medialist/tmpl/thumbs_imgs.php b/Sites/pages/administrator/components/com_media/views/medialist/tmpl/thumbs_imgs.php new file mode 100644 index 00000000..51404833 --- /dev/null +++ b/Sites/pages/administrator/components/com_media/views/medialist/tmpl/thumbs_imgs.php @@ -0,0 +1,44 @@ + + +images as $i => $img) : ?> + trigger('onContentBeforeDisplay', array('com_media.file', &$img, &$params, 0)); ?> +
  • + canDelete) : ?> + × +
    + escape($img->name), false, 'rm', 'cb-image'); ?> +
    +
    + + + + + +
  • + trigger('onContentAfterDisplay', array('com_media.file', &$img, &$params, 0)); ?> + diff --git a/Sites/pages/administrator/components/com_media/views/medialist/tmpl/thumbs_up.php b/Sites/pages/administrator/components/com_media/views/medialist/tmpl/thumbs_up.php new file mode 100644 index 00000000..60d1cc34 --- /dev/null +++ b/Sites/pages/administrator/components/com_media/views/medialist/tmpl/thumbs_up.php @@ -0,0 +1,27 @@ + +state->folder != '') : ?> +
  • +
    +
    + + +
    +
    +
    +   +
    +
    + .. +
    +
  • + diff --git a/Sites/pages/administrator/components/com_media/views/medialist/tmpl/thumbs_videos.php b/Sites/pages/administrator/components/com_media/views/medialist/tmpl/thumbs_videos.php new file mode 100644 index 00000000..7b6f2b68 --- /dev/null +++ b/Sites/pages/administrator/components/com_media/views/medialist/tmpl/thumbs_videos.php @@ -0,0 +1,47 @@ +addScriptDeclaration(" +jQuery(document).ready(function($){ + window.parent.jQuery('#videoPreview').on('hidden', function () { + window.parent.jQuery('#mejsPlayer')[0].player.pause(); + }); +}); +"); +?> +videos as $i => $video) : ?> + trigger('onContentBeforeDisplay', array('com_media.file', &$video, &$params, 0)); ?> +
  • + canDelete) : ?> + × +
    + escape($video->name), false, 'rm', 'cb-video'); ?> +
    +
    + + +
    + icon_32, $this->escape($video->title), null, true); ?> +
    + + +
  • + trigger('onContentAfterDisplay', array('com_media.file', &$video, &$params, 0)); ?> + diff --git a/Sites/pages/administrator/components/com_media/views/medialist/view.html.php b/Sites/pages/administrator/components/com_media/views/medialist/view.html.php new file mode 100644 index 00000000..fccdffb2 --- /dev/null +++ b/Sites/pages/administrator/components/com_media/views/medialist/view.html.php @@ -0,0 +1,63 @@ +isClient('administrator')) + { + return $app->enqueueMessage(JText::_('JERROR_ALERTNOAUTHOR'), 'warning'); + } + + // Do not allow cache + $app->allowCache(false); + + $this->images = $this->get('images'); + $this->documents = $this->get('documents'); + $this->folders = $this->get('folders'); + $this->videos = $this->get('videos'); + $this->state = $this->get('state'); + + // Check for invalid folder name + if (empty($this->state->folder)) + { + $dirname = JFactory::getApplication()->input->getPath('folder', ''); + + if (!empty($dirname)) + { + $dirname = htmlspecialchars($dirname, ENT_COMPAT, 'UTF-8'); + JError::raiseWarning(100, JText::sprintf('COM_MEDIA_ERROR_UNABLE_TO_BROWSE_FOLDER_WARNDIRNAME', $dirname)); + } + } + + $user = JFactory::getUser(); + $this->canDelete = $user->authorise('core.delete', 'com_media'); + + parent::display($tpl); + } +} diff --git a/Sites/pages/administrator/components/com_menus/access.xml b/Sites/pages/administrator/components/com_menus/access.xml new file mode 100644 index 00000000..c709842e --- /dev/null +++ b/Sites/pages/administrator/components/com_menus/access.xml @@ -0,0 +1,19 @@ + + +
    + + + + + + + +
    +
    + + + + + +
    +
    diff --git a/Sites/pages/administrator/components/com_menus/config.xml b/Sites/pages/administrator/components/com_menus/config.xml new file mode 100644 index 00000000..3b1b94a2 --- /dev/null +++ b/Sites/pages/administrator/components/com_menus/config.xml @@ -0,0 +1,65 @@ + + +
    + + + + + + + + + + + + +
    + +
    + + + +
    +
    diff --git a/Sites/pages/administrator/components/com_menus/controller.php b/Sites/pages/administrator/components/com_menus/controller.php new file mode 100644 index 00000000..c9ca28b0 --- /dev/null +++ b/Sites/pages/administrator/components/com_menus/controller.php @@ -0,0 +1,77 @@ +metadata['nativeName'])) + { + $languageName = $language->metadata['nativeName']; + } + else + { + $languageName = $language->metadata['name']; + } + + $langCodes[$language->metadata['tag']] = $languageName; + } + + $db = JFactory::getDbo(); + $query = $db->getQuery(true); + + $query->select($db->qn('m.language')) + ->from($db->qn('#__modules', 'm')) + ->where($db->qn('m.module') . ' = ' . $db->quote('mod_menu')) + ->where($db->qn('m.published') . ' = 1') + ->where($db->qn('m.client_id') . ' = 1') + ->group($db->qn('m.language')); + + $mLanguages = $db->setQuery($query)->loadColumn(); + + // Check if we have a mod_menu module set to All languages or a mod_menu module for each admin language. + if (!in_array('*', $mLanguages) && count($langMissing = array_diff(array_keys($langCodes), $mLanguages))) + { + $app = JFactory::getApplication(); + $langMissing = array_intersect_key($langCodes, array_flip($langMissing)); + + $app->enqueueMessage(JText::sprintf('JMENU_MULTILANG_WARNING_MISSING_MODULES', implode(', ', $langMissing)), 'warning'); + } + } + + return parent::display(); + } +} diff --git a/Sites/pages/administrator/components/com_menus/controllers/ajax.json.php b/Sites/pages/administrator/components/com_menus/controllers/ajax.json.php new file mode 100644 index 00000000..0cdb24a6 --- /dev/null +++ b/Sites/pages/administrator/components/com_menus/controllers/ajax.json.php @@ -0,0 +1,88 @@ +input; + $extension = $input->get('extension'); + + $assocId = $input->getInt('assocId', 0); + + if ($assocId == 0) + { + echo new JResponseJson(null, JText::sprintf('JLIB_FORM_VALIDATE_FIELD_INVALID', 'assocId'), true); + + return; + } + + $excludeLang = $input->get('excludeLang', '', 'STRING'); + + $associations = JLanguageAssociations::getAssociations('com_menus', '#__menu', 'com_menus.item', (int) $assocId, 'id', '', ''); + + unset($associations[$excludeLang]); + + // Add the title to each of the associated records + JTable::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_menus/tables'); + $menuTable = JTable::getInstance('Menu', 'JTable', array()); + + foreach ($associations as $lang => $association) + { + $menuTable->load($association->id); + $associations[$lang]->title = $menuTable->title; + } + + $countContentLanguages = count(LanguageHelper::getContentLanguages(array(0, 1))); + + if (count($associations) == 0) + { + $message = JText::_('JGLOBAL_ASSOCIATIONS_PROPAGATE_MESSAGE_NONE'); + } + elseif ($countContentLanguages > count($associations) + 2) + { + $tags = implode(', ', array_keys($associations)); + $message = JText::sprintf('JGLOBAL_ASSOCIATIONS_PROPAGATE_MESSAGE_SOME', $tags); + } + else + { + $message = JText::_('JGLOBAL_ASSOCIATIONS_PROPAGATE_MESSAGE_ALL'); + } + + echo new JResponseJson($associations, $message); + } + } +} diff --git a/Sites/pages/administrator/components/com_menus/controllers/item.php b/Sites/pages/administrator/components/com_menus/controllers/item.php new file mode 100644 index 00000000..3fa2c03a --- /dev/null +++ b/Sites/pages/administrator/components/com_menus/controllers/item.php @@ -0,0 +1,613 @@ +input->getCmd('menutype', isset($data['menutype']) ? $data['menutype'] : ''); + + $menutypeID = 0; + + // Load menutype ID + if ($menuType) + { + $menutypeID = (int) $this->getMenuTypeId($menuType); + } + + return $user->authorise('core.create', 'com_menus.menu.' . $menutypeID); + } + + /** + * Method to check if you edit a record. + * + * Extended classes can override this if necessary. + * + * @param array $data An array of input data. + * @param string $key The name of the key for the primary key; default is id. + * + * @return boolean + * + * @since 3.6 + */ + protected function allowEdit($data = array(), $key = 'id') + { + $user = JFactory::getUser(); + + $menutypeID = 0; + + if (isset($data[$key])) + { + $model = $this->getModel(); + $item = $model->getItem($data[$key]); + + if (!empty($item->menutype)) + { + // Protected menutype, do not allow edit + if ($item->menutype == 'main') + { + return false; + } + + $menutypeID = (int) $this->getMenuTypeId($item->menutype); + } + } + + return $user->authorise('core.edit', 'com_menus.menu.' . (int) $menutypeID); + } + + /** + * Loads the menutype ID by a given menutype string + * + * @param string $menutype The given menutype + * + * @return integer + * + * @since 3.6 + */ + protected function getMenuTypeId($menutype) + { + $model = $this->getModel(); + $table = $model->getTable('MenuType', 'JTable'); + + $table->load(array('menutype' => $menutype)); + + return (int) $table->id; + } + + /** + * Method to add a new menu item. + * + * @return mixed True if the record can be added, a JError object if not. + * + * @since 1.6 + */ + public function add() + { + $app = JFactory::getApplication(); + $context = 'com_menus.edit.item'; + + $result = parent::add(); + + if ($result) + { + $app->setUserState($context . '.type', null); + $app->setUserState($context . '.link', null); + } + + return $result; + } + + /** + * Method to run batch operations. + * + * @param object $model The model. + * + * @return boolean True if successful, false otherwise and internal error is set. + * + * @since 1.6 + */ + public function batch($model = null) + { + $this->checkToken(); + + $model = $this->getModel('Item', '', array()); + + // Preset the redirect + $this->setRedirect(JRoute::_('index.php?option=com_menus&view=items' . $this->getRedirectToListAppend(), false)); + + return parent::batch($model); + } + + /** + * Method to cancel an edit. + * + * @param string $key The name of the primary key of the URL variable. + * + * @return boolean True if access level checks pass, false otherwise. + * + * @since 1.6 + */ + public function cancel($key = null) + { + $this->checkToken(); + + $app = JFactory::getApplication(); + $context = 'com_menus.edit.item'; + $result = parent::cancel(); + + if ($result) + { + // Clear the ancillary data from the session. + $app->setUserState($context . '.type', null); + $app->setUserState($context . '.link', null); + + // Redirect to the list screen. + $this->setRedirect( + JRoute::_( + 'index.php?option=' . $this->option . '&view=' . $this->view_list . $this->getRedirectToListAppend() + . '&menutype=' . $app->getUserState('com_menus.items.menutype'), false + ) + ); + } + + return $result; + } + + /** + * Method to edit an existing record. + * + * @param string $key The name of the primary key of the URL variable. + * @param string $urlVar The name of the URL variable if different from the primary key + * (sometimes required to avoid router collisions). + * + * @return boolean True if access level check and checkout passes, false otherwise. + * + * @since 1.6 + */ + public function edit($key = null, $urlVar = null) + { + $app = JFactory::getApplication(); + $result = parent::edit(); + + if ($result) + { + // Push the new ancillary data into the session. + $app->setUserState('com_menus.edit.item.type', null); + $app->setUserState('com_menus.edit.item.link', null); + } + + return $result; + } + + /** + * Gets the URL arguments to append to an item redirect. + * + * @param integer $recordId The primary key id for the item. + * @param string $urlVar The name of the URL variable for the id. + * + * @return string The arguments to append to the redirect URL. + * + * @since 3.0.1 + */ + protected function getRedirectToItemAppend($recordId = null, $urlVar = 'id') + { + $append = parent::getRedirectToItemAppend($recordId, $urlVar); + + if ($recordId) + { + $model = $this->getModel(); + $item = $model->getItem($recordId); + $clientId = $item->client_id; + $append = '&client_id=' . $clientId . $append; + } + else + { + $app = JFactory::getApplication(); + $clientId = $app->input->get('client_id', '0', 'int'); + $menuType = $app->input->get('menutype', 'mainmenu', 'cmd'); + $append = '&client_id=' . $clientId . ($menuType ? '&menutype=' . $menuType : '') . $append; + } + + return $append; + } + + /** + * Method to save a record. + * + * @param string $key The name of the primary key of the URL variable. + * @param string $urlVar The name of the URL variable if different from the primary key (sometimes required to avoid router collisions). + * + * @return boolean True if successful, false otherwise. + * + * @since 1.6 + */ + public function save($key = null, $urlVar = null) + { + // Check for request forgeries. + $this->checkToken(); + + $app = JFactory::getApplication(); + $model = $this->getModel('Item', '', array()); + $table = $model->getTable(); + $data = $this->input->post->get('jform', array(), 'array'); + $task = $this->getTask(); + $context = 'com_menus.edit.item'; + + // Set the menutype should we need it. + if ($data['menutype'] !== '') + { + $app->input->set('menutype', $data['menutype']); + } + + // Determine the name of the primary key for the data. + if (empty($key)) + { + $key = $table->getKeyName(); + } + + // To avoid data collisions the urlVar may be different from the primary key. + if (empty($urlVar)) + { + $urlVar = $key; + } + + $recordId = $this->input->getInt($urlVar); + + // Populate the row id from the session. + $data[$key] = $recordId; + + // The save2copy task needs to be handled slightly differently. + if ($task == 'save2copy') + { + // Check-in the original row. + if ($model->checkin($data['id']) === false) + { + // Check-in failed, go back to the item and display a notice. + $this->setMessage(JText::sprintf('JLIB_APPLICATION_ERROR_CHECKIN_FAILED', $model->getError()), 'warning'); + + return false; + } + + // Reset the ID and then treat the request as for Apply. + $data['id'] = 0; + $data['associations'] = array(); + $task = 'apply'; + } + + // Access check. + if (!$this->allowSave($data, $key)) + { + $this->setError(JText::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED')); + $this->setMessage($this->getError(), 'error'); + + $this->setRedirect( + JRoute::_( + 'index.php?option=' . $this->option . '&view=' . $this->view_list + . $this->getRedirectToListAppend(), false + ) + ); + + return false; + } + + // Validate the posted data. + // This post is made up of two forms, one for the item and one for params. + $form = $model->getForm($data); + + if (!$form) + { + JError::raiseError(500, $model->getError()); + + return false; + } + + if ($data['type'] == 'url') + { + $data['link'] = str_replace(array('"', '>', '<'), '', $data['link']); + + if (strstr($data['link'], ':')) + { + $segments = explode(':', $data['link']); + $protocol = strtolower($segments[0]); + $scheme = array( + 'http', 'https', 'ftp', 'ftps', 'gopher', 'mailto', + 'news', 'prospero', 'telnet', 'rlogin', 'tn3270', 'wais', + 'mid', 'cid', 'nntp', 'tel', 'urn', 'ldap', 'file', 'fax', + 'modem', 'git', 'sms', + ); + + if (!in_array($protocol, $scheme)) + { + $app->enqueueMessage(JText::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'warning'); + $this->setRedirect( + JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend($recordId), false) + ); + + return false; + } + } + } + + $data = $model->validate($form, $data); + + // Preprocess request fields to ensure that we remove not set or empty request params + $request = $form->getGroup('request', true); + + // Check for the special 'request' entry. + if ($data['type'] == 'component' && !empty($request)) + { + $removeArgs = array(); + + if (!isset($data['request']) || !is_array($data['request'])) + { + $data['request'] = array(); + } + + foreach ($request as $field) + { + $fieldName = $field->getAttribute('name'); + + if (!isset($data['request'][$fieldName]) || $data['request'][$fieldName] == '') + { + $removeArgs[$fieldName] = ''; + } + } + + // Parse the submitted link arguments. + $args = array(); + parse_str(parse_url($data['link'], PHP_URL_QUERY), $args); + + // Merge in the user supplied request arguments. + $args = array_merge($args, $data['request']); + + // Remove the unused request params + if (!empty($args) && !empty($removeArgs)) + { + $args = array_diff_key($args, $removeArgs); + } + + $data['link'] = 'index.php?' . urldecode(http_build_query($args, '', '&')); + unset($data['request']); + } + + // Check for validation errors. + if ($data === false) + { + // Get the validation messages. + $errors = $model->getErrors(); + + // Push up to three validation messages out to the user. + for ($i = 0, $n = count($errors); $i < $n && $i < 3; $i++) + { + if ($errors[$i] instanceof Exception) + { + $app->enqueueMessage($errors[$i]->getMessage(), 'warning'); + } + else + { + $app->enqueueMessage($errors[$i], 'warning'); + } + } + + // Save the data in the session. + $app->setUserState('com_menus.edit.item.data', $data); + + // Redirect back to the edit screen. + $editUrl = 'index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend($recordId); + $this->setRedirect(JRoute::_($editUrl, false)); + + return false; + } + + // Attempt to save the data. + if (!$model->save($data)) + { + // Save the data in the session. + $app->setUserState('com_menus.edit.item.data', $data); + + // Redirect back to the edit screen. + $editUrl = 'index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend($recordId); + $this->setMessage(JText::sprintf('JLIB_APPLICATION_ERROR_SAVE_FAILED', $model->getError()), 'error'); + $this->setRedirect(JRoute::_($editUrl, false)); + + return false; + } + + // Save succeeded, check-in the row. + if ($model->checkin($data['id']) === false) + { + // Check-in failed, go back to the row and display a notice. + $this->setMessage(JText::sprintf('JLIB_APPLICATION_ERROR_CHECKIN_FAILED', $model->getError()), 'warning'); + $redirectUrl = 'index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend($recordId); + $this->setRedirect(JRoute::_($redirectUrl, false)); + + return false; + } + + $this->setMessage(JText::_('COM_MENUS_SAVE_SUCCESS')); + + // Redirect the user and adjust session state based on the chosen task. + switch ($task) + { + case 'apply': + // Set the row data in the session. + $recordId = $model->getState($this->context . '.id'); + $this->holdEditId($context, $recordId); + $app->setUserState('com_menus.edit.item.data', null); + $app->setUserState('com_menus.edit.item.type', null); + $app->setUserState('com_menus.edit.item.link', null); + + // Redirect back to the edit screen. + $editUrl = 'index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend($recordId); + $this->setRedirect(JRoute::_($editUrl, false)); + break; + + case 'save2new': + // Clear the row id and data in the session. + $this->releaseEditId($context, $recordId); + $app->setUserState('com_menus.edit.item.data', null); + $app->setUserState('com_menus.edit.item.type', null); + $app->setUserState('com_menus.edit.item.link', null); + + // Redirect back to the edit screen. + $this->setRedirect(JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend(), false)); + break; + + default: + // Clear the row id and data in the session. + $this->releaseEditId($context, $recordId); + $app->setUserState('com_menus.edit.item.data', null); + $app->setUserState('com_menus.edit.item.type', null); + $app->setUserState('com_menus.edit.item.link', null); + + // Redirect to the list screen. + $this->setRedirect( + JRoute::_( + 'index.php?option=' . $this->option . '&view=' . $this->view_list . $this->getRedirectToListAppend() + . '&menutype=' . $app->getUserState('com_menus.items.menutype'), false + ) + ); + break; + } + + return true; + } + + /** + * Sets the type of the menu item currently being edited. + * + * @return void + * + * @since 1.6 + */ + public function setType() + { + $this->checkToken(); + + $app = JFactory::getApplication(); + + // Get the posted values from the request. + $data = $this->input->post->get('jform', array(), 'array'); + + // Get the type. + $type = $data['type']; + + $type = json_decode(base64_decode($type)); + $title = isset($type->title) ? $type->title : null; + $recordId = isset($type->id) ? $type->id : 0; + + $specialTypes = array('alias', 'separator', 'url', 'heading', 'container'); + + if (!in_array($title, $specialTypes)) + { + $title = 'component'; + } + else + { + // Set correct component id to ensure proper 404 messages with system links + $data['component_id'] = 0; + } + + $app->setUserState('com_menus.edit.item.type', $title); + + if ($title == 'component') + { + if (isset($type->request)) + { + // Clean component name + $type->request->option = JFilterInput::getInstance()->clean($type->request->option, 'CMD'); + + $component = JComponentHelper::getComponent($type->request->option); + $data['component_id'] = $component->id; + + $app->setUserState('com_menus.edit.item.link', 'index.php?' . JUri::buildQuery((array) $type->request)); + } + } + // If the type is alias you just need the item id from the menu item referenced. + elseif ($title == 'alias') + { + $app->setUserState('com_menus.edit.item.link', 'index.php?Itemid='); + } + + unset($data['request']); + + $data['type'] = $title; + + if ($this->input->get('fieldtype') == 'type') + { + $data['link'] = $app->getUserState('com_menus.edit.item.link'); + } + + // Save the data in the session. + $app->setUserState('com_menus.edit.item.data', $data); + + $this->type = $type; + $this->setRedirect(JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend($recordId), false)); + } + + /** + * Gets the parent items of the menu location currently. + * + * @return void + * + * @since 3.2 + */ + public function getParentItem() + { + $app = JFactory::getApplication(); + + $results = array(); + $menutype = $this->input->get->get('menutype'); + + if ($menutype) + { + $model = $this->getModel('Items', '', array()); + $model->getState(); + $model->setState('filter.menutype', $menutype); + $model->setState('list.select', 'a.id, a.title, a.level'); + $model->setState('list.start', '0'); + $model->setState('list.limit', '0'); + + /** @var MenusModelItems $model */ + $results = $model->getItems(); + + // Pad the option text with spaces using depth level as a multiplier. + for ($i = 0, $n = count($results); $i < $n; $i++) + { + $results[$i]->title = str_repeat(' - ', $results[$i]->level) . $results[$i]->title; + } + } + + // Output a JSON object + echo json_encode($results); + + $app->close(); + } +} diff --git a/Sites/pages/administrator/components/com_menus/controllers/items.php b/Sites/pages/administrator/components/com_menus/controllers/items.php new file mode 100644 index 00000000..3c80f595 --- /dev/null +++ b/Sites/pages/administrator/components/com_menus/controllers/items.php @@ -0,0 +1,320 @@ +registerTask('unsetDefault', 'setDefault'); + } + + /** + * Proxy for getModel. + * + * @param string $name The model name. Optional. + * @param string $prefix The class prefix. Optional. + * @param array $config Configuration array for model. Optional. + * + * @return object The model. + * + * @since 1.6 + */ + public function getModel($name = 'Item', $prefix = 'MenusModel', $config = array()) + { + return parent::getModel($name, $prefix, array('ignore_request' => true)); + } + + /** + * Rebuild the nested set tree. + * + * @return boolean False on failure or error, true on success. + * + * @since 1.6 + */ + public function rebuild() + { + $this->checkToken(); + + $this->setRedirect('index.php?option=com_menus&view=items'); + + $model = $this->getModel(); + + if ($model->rebuild()) + { + // Reorder succeeded. + $this->setMessage(JText::_('COM_MENUS_ITEMS_REBUILD_SUCCESS')); + + return true; + } + else + { + // Rebuild failed. + $this->setMessage(JText::sprintf('COM_MENUS_ITEMS_REBUILD_FAILED'), 'error'); + + return false; + } + } + + /** + * Save the manual order inputs from the menu items list view + * + * @return void + * + * @see JControllerAdmin::saveorder() + * @deprecated 4.0 + */ + public function saveorder() + { + $this->checkToken(); + + try + { + JLog::add( + sprintf('%s() is deprecated. Function will be removed in 4.0.', __METHOD__), + JLog::WARNING, + 'deprecated' + ); + } + catch (RuntimeException $exception) + { + // Informational log only + } + + // Get the arrays from the Request + $order = $this->input->post->get('order', null, 'array'); + $originalOrder = explode(',', $this->input->getString('original_order_values')); + + // Make sure something has changed + if (!($order === $originalOrder)) + { + parent::saveorder(); + } + else + { + // Nothing to reorder + $this->setRedirect(JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_list, false)); + + return true; + } + } + + /** + * Method to set the home property for a list of items + * + * @return void + * + * @since 1.6 + */ + public function setDefault() + { + // Check for request forgeries + $this->checkToken('request'); + + $app = JFactory::getApplication(); + + // Get items to publish from the request. + $cid = $this->input->get('cid', array(), 'array'); + $data = array('setDefault' => 1, 'unsetDefault' => 0); + $task = $this->getTask(); + $value = ArrayHelper::getValue($data, $task, 0, 'int'); + + if (empty($cid)) + { + JError::raiseWarning(500, JText::_($this->text_prefix . '_NO_ITEM_SELECTED')); + } + else + { + // Get the model. + $model = $this->getModel(); + + // Make sure the item ids are integers + $cid = ArrayHelper::toInteger($cid); + + // Publish the items. + if (!$model->setHome($cid, $value)) + { + JError::raiseWarning(500, $model->getError()); + } + else + { + if ($value == 1) + { + $ntext = 'COM_MENUS_ITEMS_SET_HOME'; + } + else + { + $ntext = 'COM_MENUS_ITEMS_UNSET_HOME'; + } + + $this->setMessage(JText::plural($ntext, count($cid))); + } + } + + $this->setRedirect( + JRoute::_( + 'index.php?option=' . $this->option . '&view=' . $this->view_list + . '&menutype=' . $app->getUserState('com_menus.items.menutype'), false + ) + ); + } + + /** + * Method to publish a list of items + * + * @return void + * + * @since 3.6.0 + */ + public function publish() + { + // Check for request forgeries + $this->checkToken(); + + // Get items to publish from the request. + $cid = JFactory::getApplication()->input->get('cid', array(), 'array'); + $data = array('publish' => 1, 'unpublish' => 0, 'trash' => -2, 'report' => -3); + $task = $this->getTask(); + $value = ArrayHelper::getValue($data, $task, 0, 'int'); + + if (empty($cid)) + { + try + { + JLog::add(JText::_($this->text_prefix . '_NO_ITEM_SELECTED'), JLog::WARNING, 'jerror'); + } + catch (RuntimeException $exception) + { + JFactory::getApplication()->enqueueMessage(JText::_($this->text_prefix . '_NO_ITEM_SELECTED'), 'warning'); + } + } + else + { + // Get the model. + $model = $this->getModel(); + + // Make sure the item ids are integers + $cid = ArrayHelper::toInteger($cid); + + // Publish the items. + try + { + $model->publish($cid, $value); + $errors = $model->getErrors(); + $messageType = 'message'; + + if ($value == 1) + { + if ($errors) + { + $messageType = 'error'; + $ntext = $this->text_prefix . '_N_ITEMS_FAILED_PUBLISHING'; + } + else + { + $ntext = $this->text_prefix . '_N_ITEMS_PUBLISHED'; + } + } + elseif ($value == 0) + { + $ntext = $this->text_prefix . '_N_ITEMS_UNPUBLISHED'; + } + else + { + $ntext = $this->text_prefix . '_N_ITEMS_TRASHED'; + } + + $this->setMessage(JText::plural($ntext, count($cid)), $messageType); + } + catch (Exception $e) + { + $this->setMessage($e->getMessage(), 'error'); + } + } + + $this->setRedirect( + JRoute::_( + 'index.php?option=' . $this->option . '&view=' . $this->view_list . '&menutype=' . + JFactory::getApplication()->getUserState('com_menus.items.menutype'), + false + ) + ); + } + + /** + * Check in of one or more records. + * + * @return boolean True on success + * + * @since 3.6.0 + */ + public function checkin() + { + // Check for request forgeries. + $this->checkToken(); + + // Read the Ids from the post data + $cid = JFactory::getApplication()->input->post->get('cid', array(), 'array'); + + // Make sure the item ids are integers + $cid = ArrayHelper::toInteger($cid); + + // Run the model + $model = $this->getModel(); + $return = $model->checkin($cid); + + if ($return === false) + { + // Checkin failed. + $message = JText::sprintf('JLIB_APPLICATION_ERROR_CHECKIN_FAILED', $model->getError()); + $this->setRedirect( + JRoute::_( + 'index.php?option=' . $this->option . '&view=' . $this->view_list + . '&menutype=' . JFactory::getApplication()->getUserState('com_menus.items.menutype'), + false + ), + $message, + 'error' + ); + + return false; + } + else + { + // Checkin succeeded. + $message = JText::plural($this->text_prefix . '_N_ITEMS_CHECKED_IN', count($cid)); + $this->setRedirect( + JRoute::_( + 'index.php?option=' . $this->option . '&view=' . $this->view_list + . '&menutype=' . JFactory::getApplication()->getUserState('com_menus.items.menutype'), + false + ), + $message + ); + + return true; + } + } +} diff --git a/Sites/pages/administrator/components/com_menus/controllers/menu.php b/Sites/pages/administrator/components/com_menus/controllers/menu.php new file mode 100644 index 00000000..522e5575 --- /dev/null +++ b/Sites/pages/administrator/components/com_menus/controllers/menu.php @@ -0,0 +1,213 @@ +setRedirect(JRoute::_('index.php?option=com_menus&view=menus', false)); + } + + /** + * Method to save a menu item. + * + * @param string $key The name of the primary key of the URL variable. + * @param string $urlVar The name of the URL variable if different from the primary key (sometimes required to avoid router collisions). + * + * @return boolean True if successful, false otherwise. + * + * @since 1.6 + */ + public function save($key = null, $urlVar = null) + { + // Check for request forgeries. + $this->checkToken(); + + $app = JFactory::getApplication(); + $data = $this->input->post->get('jform', array(), 'array'); + $context = 'com_menus.edit.menu'; + $task = $this->getTask(); + $recordId = $this->input->getInt('id'); + + // Prevent using 'main' as menutype as this is reserved for backend menus + if (strtolower($data['menutype']) == 'main') + { + $msg = JText::_('COM_MENUS_ERROR_MENUTYPE'); + JFactory::getApplication()->enqueueMessage($msg, 'error'); + + // Redirect back to the edit screen. + $this->setRedirect(JRoute::_('index.php?option=com_menus&view=menu&layout=edit' . $this->getRedirectToItemAppend($recordId), false)); + + return false; + } + + // Populate the row id from the session. + $data['id'] = $recordId; + + // Get the model and attempt to validate the posted data. + $model = $this->getModel('Menu'); + $form = $model->getForm(); + + if (!$form) + { + JError::raiseError(500, $model->getError()); + + return false; + } + + $validData = $model->validate($form, $data); + + // Check for validation errors. + if ($validData === false) + { + // Get the validation messages. + $errors = $model->getErrors(); + + // Push up to three validation messages out to the user. + for ($i = 0, $n = count($errors); $i < $n && $i < 3; $i++) + { + if ($errors[$i] instanceof Exception) + { + $app->enqueueMessage($errors[$i]->getMessage(), 'warning'); + } + else + { + $app->enqueueMessage($errors[$i], 'warning'); + } + } + + // Save the data in the session. + $app->setUserState($context . '.data', $data); + + // Redirect back to the edit screen. + $this->setRedirect(JRoute::_('index.php?option=com_menus&view=menu&layout=edit' . $this->getRedirectToItemAppend($recordId), false)); + + return false; + } + + if (isset($validData['preset'])) + { + $preset = trim($validData['preset']) ?: null; + + unset($validData['preset']); + } + + // Attempt to save the data. + if (!$model->save($validData)) + { + // Save the data in the session. + $app->setUserState($context . '.data', $validData); + + // Redirect back to the edit screen. + $this->setMessage(JText::sprintf('JLIB_APPLICATION_ERROR_SAVE_FAILED', $model->getError()), 'error'); + $this->setRedirect(JRoute::_('index.php?option=com_menus&view=menu&layout=edit' . $this->getRedirectToItemAppend($recordId), false)); + + return false; + } + + // Import the preset selected + if (isset($preset) && $data['client_id'] == 1) + { + try + { + MenusHelper::installPreset($preset, $data['menutype']); + + $this->setMessage(JText::_('COM_MENUS_PRESET_IMPORT_SUCCESS')); + } + catch (Exception $e) + { + // Save was successful but the preset could not be loaded. Let it through with just a warning + $this->setMessage(JText::sprintf('COM_MENUS_PRESET_IMPORT_FAILED', $e->getMessage())); + } + } + else + { + $this->setMessage(JText::_('COM_MENUS_MENU_SAVE_SUCCESS')); + } + + // Redirect the user and adjust session state based on the chosen task. + switch ($task) + { + case 'apply': + // Set the record data in the session. + $recordId = $model->getState($this->context . '.id'); + $this->holdEditId($context, $recordId); + $app->setUserState($context . '.data', null); + + // Redirect back to the edit screen. + $this->setRedirect(JRoute::_('index.php?option=com_menus&view=menu&layout=edit' . $this->getRedirectToItemAppend($recordId), false)); + break; + + case 'save2new': + // Clear the record id and data from the session. + $this->releaseEditId($context, $recordId); + $app->setUserState($context . '.data', null); + + // Redirect back to the edit screen. + $this->setRedirect(JRoute::_('index.php?option=com_menus&view=menu&layout=edit', false)); + break; + + default: + // Clear the record id and data from the session. + $this->releaseEditId($context, $recordId); + $app->setUserState($context . '.data', null); + + // Redirect to the list screen. + $this->setRedirect(JRoute::_('index.php?option=com_menus&view=menus', false)); + break; + } + } + + /** + * Method to display a menu as preset xml. + * + * @return boolean True if successful, false otherwise. + * + * @since 3.8.0 + */ + public function exportXml() + { + // Check for request forgeries. + $this->checkToken(); + + $cid = $this->input->get('cid', array(), 'array'); + $model = $this->getModel('Menu'); + $item = $model->getItem(reset($cid)); + + if (!$item->menutype) + { + $this->setMessage(JText::_('COM_MENUS_SELECT_MENU_FIRST_EXPORT'), 'warning'); + + $this->setRedirect(JRoute::_('index.php?option=com_menus&view=menus', false)); + + return false; + } + + $this->setRedirect(JRoute::_('index.php?option=com_menus&view=menu&menutype=' . $item->menutype . '&format=xml', false)); + + return true; + } +} diff --git a/Sites/pages/administrator/components/com_menus/controllers/menus.php b/Sites/pages/administrator/components/com_menus/controllers/menus.php new file mode 100644 index 00000000..9f38634d --- /dev/null +++ b/Sites/pages/administrator/components/com_menus/controllers/menus.php @@ -0,0 +1,227 @@ + true)) + { + return parent::getModel($name, $prefix, $config); + } + + /** + * Remove an item. + * + * @return void + * + * @since 1.6 + */ + public function delete() + { + // Check for request forgeries + $this->checkToken(); + + $user = JFactory::getUser(); + $app = JFactory::getApplication(); + $cids = (array) $this->input->get('cid', array(), 'array'); + + if (count($cids) < 1) + { + $app->enqueueMessage(JText::_('COM_MENUS_NO_MENUS_SELECTED'), 'notice'); + } + else + { + // Access checks. + foreach ($cids as $i => $id) + { + if (!$user->authorise('core.delete', 'com_menus.menu.' . (int) $id)) + { + // Prune items that you can't change. + unset($cids[$i]); + $app->enqueueMessage(JText::_('JLIB_APPLICATION_ERROR_DELETE_NOT_PERMITTED'), 'error'); + } + } + + if (count($cids) > 0) + { + // Get the model. + $model = $this->getModel(); + + // Make sure the item ids are integers + $cids = ArrayHelper::toInteger($cids); + + // Remove the items. + if (!$model->delete($cids)) + { + $this->setMessage($model->getError(), 'error'); + } + else + { + $this->setMessage(JText::plural('COM_MENUS_N_MENUS_DELETED', count($cids))); + } + } + } + + $this->setRedirect('index.php?option=com_menus&view=menus'); + } + + /** + * Rebuild the menu tree. + * + * @return boolean False on failure or error, true on success. + * + * @since 1.6 + */ + public function rebuild() + { + $this->checkToken(); + + $this->setRedirect('index.php?option=com_menus&view=menus'); + + $model = $this->getModel('Item'); + + if ($model->rebuild()) + { + // Reorder succeeded. + $this->setMessage(JText::_('JTOOLBAR_REBUILD_SUCCESS')); + + return true; + } + else + { + // Rebuild failed. + $this->setMessage(JText::sprintf('JTOOLBAR_REBUILD_FAILED', $model->getError()), 'error'); + + return false; + } + } + + /** + * Temporary method. This should go into the 1.5 to 1.6 upgrade routines. + * + * @return JException|void JException instance on error + * + * @since 1.6 + */ + public function resync() + { + $db = JFactory::getDbo(); + $query = $db->getQuery(true); + $parts = null; + + try + { + $query->select('element, extension_id') + ->from('#__extensions') + ->where('type = ' . $db->quote('component')); + $db->setQuery($query); + + $components = $db->loadAssocList('element', 'extension_id'); + } + catch (RuntimeException $e) + { + return JError::raiseWarning(500, $e->getMessage()); + } + + // Load all the component menu links + $query->select($db->quoteName('id')) + ->select($db->quoteName('link')) + ->select($db->quoteName('component_id')) + ->from('#__menu') + ->where($db->quoteName('type') . ' = ' . $db->quote('component.item')); + $db->setQuery($query); + + try + { + $items = $db->loadObjectList(); + } + catch (RuntimeException $e) + { + return JError::raiseWarning(500, $e->getMessage()); + } + + foreach ($items as $item) + { + // Parse the link. + parse_str(parse_url($item->link, PHP_URL_QUERY), $parts); + + // Tease out the option. + if (isset($parts['option'])) + { + $option = $parts['option']; + + // Lookup the component ID + if (isset($components[$option])) + { + $componentId = $components[$option]; + } + else + { + // Mismatch. Needs human intervention. + $componentId = -1; + } + + // Check for mis-matched component id's in the menu link. + if ($item->component_id != $componentId) + { + // Update the menu table. + $log = "Link $item->id refers to $item->component_id, converting to $componentId ($item->link)"; + echo "
    $log"; + + $query->clear(); + $query->update('#__menu') + ->set('component_id = ' . $componentId) + ->where('id = ' . $item->id); + + try + { + $db->setQuery($query)->execute(); + } + catch (RuntimeException $e) + { + return JError::raiseWarning(500, $e->getMessage()); + } + } + } + } + } +} diff --git a/Sites/pages/administrator/components/com_menus/helpers/associations.php b/Sites/pages/administrator/components/com_menus/helpers/associations.php new file mode 100644 index 00000000..34ee9a65 --- /dev/null +++ b/Sites/pages/administrator/components/com_menus/helpers/associations.php @@ -0,0 +1,165 @@ +getType($typeName); + + $context = $this->extension . '.item'; + + // Get the associations. + $associations = JLanguageAssociations::getAssociations( + $this->extension, + $type['tables']['a'], + $context, + $id, + 'id', + 'alias', + '' + ); + + return $associations; + } + + /** + * Get item information + * + * @param string $typeName The item type + * @param int $id The id of item for which we need the associated items + * + * @return JTable|null + * + * @since 3.7.0 + */ + public function getItem($typeName, $id) + { + if (empty($id)) + { + return null; + } + + $table = null; + + switch ($typeName) + { + case 'item': + $table = JTable::getInstance('menu'); + break; + } + + if (is_null($table)) + { + return null; + } + + $table->load($id); + + return $table; + } + + /** + * Get information about the type + * + * @param string $typeName The item type + * + * @return array Array of item types + * + * @since 3.7.0 + */ + public function getType($typeName = '') + { + $fields = $this->getFieldsTemplate(); + $tables = array(); + $joins = array(); + $support = $this->getSupportTemplate(); + $title = ''; + + if (in_array($typeName, $this->itemTypes)) + { + switch ($typeName) + { + case 'item': + $fields['ordering'] = 'a.lft'; + $fields['level'] = 'a.level'; + $fields['catid'] = ''; + $fields['state'] = 'a.published'; + $fields['created_user_id'] = ''; + $fields['menutype'] = 'a.menutype'; + + $support['state'] = true; + $support['acl'] = true; + $support['checkout'] = true; + $support['level'] = true; + + $tables = array( + 'a' => '#__menu' + ); + + $title = 'menu'; + break; + } + } + + return array( + 'fields' => $fields, + 'support' => $support, + 'tables' => $tables, + 'joins' => $joins, + 'title' => $title + ); + } +} diff --git a/Sites/pages/administrator/components/com_menus/helpers/html/menus.php b/Sites/pages/administrator/components/com_menus/helpers/html/menus.php new file mode 100644 index 00000000..1d849043 --- /dev/null +++ b/Sites/pages/administrator/components/com_menus/helpers/html/menus.php @@ -0,0 +1,258 @@ +getQuery(true) + ->select('m.id, m.title') + ->select('l.sef as lang_sef, l.lang_code') + ->select('mt.title as menu_title') + ->from('#__menu as m') + ->join('LEFT', '#__menu_types as mt ON mt.menutype=m.menutype') + ->where('m.id IN (' . implode(',', array_values($associations)) . ')') + ->where('m.id != ' . $itemid) + ->join('LEFT', '#__languages as l ON m.language=l.lang_code') + ->select('l.image') + ->select('l.title as language_title'); + $db->setQuery($query); + + try + { + $items = $db->loadObjectList('id'); + } + catch (runtimeException $e) + { + throw new Exception($e->getMessage(), 500); + } + + // Construct html + if ($items) + { + foreach ($items as &$item) + { + $text = strtoupper($item->lang_sef); + $url = JRoute::_('index.php?option=com_menus&task=item.edit&id=' . (int) $item->id); + + $tooltip = htmlspecialchars($item->title, ENT_QUOTES, 'UTF-8') . '
    ' . JText::sprintf('COM_MENUS_MENU_SPRINTF', $item->menu_title); + $classes = 'hasPopover label label-association label-' . $item->lang_sef; + + $item->link = '' + . $text . ''; + } + } + + JHtml::_('bootstrap.popover'); + + $html = JLayoutHelper::render('joomla.content.associations', $items); + } + + return $html; + } + + /** + * Returns a published state on a grid + * + * @param integer $value The state value. + * @param integer $i The row index + * @param boolean $enabled An optional setting for access control on the action. + * @param string $checkbox An optional prefix for checkboxes. + * + * @return string The Html code + * + * @see JHtmlJGrid::state + * + * @since 1.7.1 + */ + public static function state($value, $i, $enabled = true, $checkbox = 'cb') + { + $states = array( + 9 => array( + 'unpublish', + '', + 'COM_MENUS_HTML_UNPUBLISH_HEADING', + '', + true, + 'publish', + 'publish', + ), + 8 => array( + 'publish', + '', + 'COM_MENUS_HTML_PUBLISH_HEADING', + '', + true, + 'unpublish', + 'unpublish', + ), + 7 => array( + 'unpublish', + '', + 'COM_MENUS_HTML_UNPUBLISH_SEPARATOR', + '', + true, + 'publish', + 'publish', + ), + 6 => array( + 'publish', + '', + 'COM_MENUS_HTML_PUBLISH_SEPARATOR', + '', + true, + 'unpublish', + 'unpublish', + ), + 5 => array( + 'unpublish', + '', + 'COM_MENUS_HTML_UNPUBLISH_ALIAS', + '', + true, + 'publish', + 'publish', + ), + 4 => array( + 'publish', + '', + 'COM_MENUS_HTML_PUBLISH_ALIAS', + '', + true, + 'unpublish', + 'unpublish', + ), + 3 => array( + 'unpublish', + '', + 'COM_MENUS_HTML_UNPUBLISH_URL', + '', + true, + 'publish', + 'publish', + ), + 2 => array( + 'publish', + '', + 'COM_MENUS_HTML_PUBLISH_URL', + '', + true, + 'unpublish', + 'unpublish', + ), + 1 => array( + 'unpublish', + 'COM_MENUS_EXTENSION_PUBLISHED_ENABLED', + 'COM_MENUS_HTML_UNPUBLISH_ENABLED', + 'COM_MENUS_EXTENSION_PUBLISHED_ENABLED', + true, + 'publish', + 'publish', + ), + 0 => array( + 'publish', + 'COM_MENUS_EXTENSION_UNPUBLISHED_ENABLED', + 'COM_MENUS_HTML_PUBLISH_ENABLED', + 'COM_MENUS_EXTENSION_UNPUBLISHED_ENABLED', + true, + 'unpublish', + 'unpublish', + ), + -1 => array( + 'unpublish', + 'COM_MENUS_EXTENSION_PUBLISHED_DISABLED', + 'COM_MENUS_HTML_UNPUBLISH_DISABLED', + 'COM_MENUS_EXTENSION_PUBLISHED_DISABLED', + true, + 'warning', + 'warning', + ), + -2 => array( + 'publish', + 'COM_MENUS_EXTENSION_UNPUBLISHED_DISABLED', + 'COM_MENUS_HTML_PUBLISH_DISABLED', + 'COM_MENUS_EXTENSION_UNPUBLISHED_DISABLED', + true, + 'trash', + 'trash', + ), + -3 => array( + 'publish', + '', + 'COM_MENUS_HTML_PUBLISH', + '', + true, + 'trash', + 'trash', + ), + ); + + return JHtml::_('jgrid.state', $states, $value, $i, 'items.', $enabled, true, $checkbox); + } + + /** + * Returns a visibility state on a grid + * + * @param integer $params Params of item. + * + * @return string The Html code + * + * @since 3.7.0 + */ + public static function visibility($params) + { + $registry = new Registry; + + try + { + $registry->loadString($params); + } + catch (Exception $e) + { + // Invalid JSON + } + + $show_menu = $registry->get('menu_show'); + + return ($show_menu === 0) ? '' . JText::_('COM_MENUS_LABEL_HIDDEN') . '' : ''; + } +} diff --git a/Sites/pages/administrator/components/com_menus/helpers/menus.php b/Sites/pages/administrator/components/com_menus/helpers/menus.php new file mode 100644 index 00000000..27701bf6 --- /dev/null +++ b/Sites/pages/administrator/components/com_menus/helpers/menus.php @@ -0,0 +1,572 @@ + $value) + { + if ((!in_array($name, self::$_filter)) && (!($name == 'task' && !array_key_exists('view', $request)))) + { + // Remove the variables we want to ignore. + unset($request[$name]); + } + } + + ksort($request); + + return 'index.php?' . http_build_query($request, '', '&'); + } + + /** + * Get the menu list for create a menu module + * + * @param int $clientId Optional client id - viz 0 = site, 1 = administrator, can be NULL for all + * + * @return array The menu array list + * + * @since 1.6 + */ + public static function getMenuTypes($clientId = 0) + { + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->select('a.menutype') + ->from('#__menu_types AS a'); + + if (isset($clientId)) + { + $query->where('a.client_id = ' . (int) $clientId); + } + + $db->setQuery($query); + + return $db->loadColumn(); + } + + /** + * Get a list of menu links for one or all menus. + * + * @param string $menuType An option menu to filter the list on, otherwise all menu with given client id links + * are returned as a grouped array. + * @param integer $parentId An optional parent ID to pivot results around. + * @param integer $mode An optional mode. If parent ID is set and mode=2, the parent and children are excluded from the list. + * @param array $published An optional array of states + * @param array $languages Optional array of specify which languages we want to filter + * @param int $clientId Optional client id - viz 0 = site, 1 = administrator, can be NULL for all (used only if menutype not givein) + * + * @return array + * + * @since 1.6 + */ + public static function getMenuLinks($menuType = null, $parentId = 0, $mode = 0, $published = array(), $languages = array(), $clientId = 0) + { + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->select('DISTINCT(a.id) AS value, + a.title AS text, + a.alias, + a.level, + a.menutype, + a.client_id, + a.type, + a.published, + a.template_style_id, + a.checked_out, + a.language, + a.lft' + ) + ->from('#__menu AS a'); + + $query->select('e.name as componentname, e.element') + ->join('left', '#__extensions e ON e.extension_id = a.component_id'); + + if (JLanguageMultilang::isEnabled()) + { + $query->select('l.title AS language_title, l.image AS language_image, l.sef AS language_sef') + ->join('LEFT', $db->quoteName('#__languages') . ' AS l ON l.lang_code = a.language'); + } + + // Filter by the type if given, this is more specific than client id + if ($menuType) + { + $query->where('(a.menutype = ' . $db->quote($menuType) . ' OR a.parent_id = 0)'); + } + elseif (isset($clientId)) + { + $query->where('a.client_id = ' . (int) $clientId); + } + + // Prevent the parent and children from showing if requested. + if ($parentId && $mode == 2) + { + $query->join('LEFT', '#__menu AS p ON p.id = ' . (int) $parentId) + ->where('(a.lft <= p.lft OR a.rgt >= p.rgt)'); + } + + if (!empty($languages)) + { + if (is_array($languages)) + { + $languages = '(' . implode(',', array_map(array($db, 'quote'), $languages)) . ')'; + } + + $query->where('a.language IN ' . $languages); + } + + if (!empty($published)) + { + if (is_array($published)) + { + $published = '(' . implode(',', $published) . ')'; + } + + $query->where('a.published IN ' . $published); + } + + $query->where('a.published != -2'); + $query->order('a.lft ASC'); + + // Get the options. + $db->setQuery($query); + + try + { + $links = $db->loadObjectList(); + } + catch (RuntimeException $e) + { + JError::raiseWarning(500, $e->getMessage()); + + return false; + } + + if (empty($menuType)) + { + // If the menutype is empty, group the items by menutype. + $query->clear() + ->select('*') + ->from('#__menu_types') + ->where('menutype <> ' . $db->quote('')) + ->order('title, menutype'); + + if (isset($clientId)) + { + $query->where('client_id = ' . (int) $clientId); + } + + $db->setQuery($query); + + try + { + $menuTypes = $db->loadObjectList(); + } + catch (RuntimeException $e) + { + JError::raiseWarning(500, $e->getMessage()); + + return false; + } + + // Create a reverse lookup and aggregate the links. + $rlu = array(); + + foreach ($menuTypes as &$type) + { + $rlu[$type->menutype] = & $type; + $type->links = array(); + } + + // Loop through the list of menu links. + foreach ($links as &$link) + { + if (isset($rlu[$link->menutype])) + { + $rlu[$link->menutype]->links[] = & $link; + + // Cleanup garbage. + unset($link->menutype); + } + } + + return $menuTypes; + } + else + { + return $links; + } + } + + /** + * Get the associations + * + * @param integer $pk Menu item id + * + * @return array + * + * @since 3.0 + */ + public static function getAssociations($pk) + { + $langAssociations = JLanguageAssociations::getAssociations('com_menus', '#__menu', 'com_menus.item', $pk, 'id', '', ''); + $associations = array(); + + foreach ($langAssociations as $langAssociation) + { + $associations[$langAssociation->language] = $langAssociation->id; + } + + return $associations; + } + + /** + * Load the menu items from database for the given menutype + * + * @param string $menutype The selected menu type + * @param boolean $enabledOnly Whether to load only enabled/published menu items. + * @param int[] $exclude The menu items to exclude from the list + * + * @return array + * + * @since 3.8.0 + */ + public static function getMenuItems($menutype, $enabledOnly = false, $exclude = array()) + { + $db = JFactory::getDbo(); + $query = $db->getQuery(true); + + // Prepare the query. + $query->select('m.*') + ->from('#__menu AS m') + ->where('m.menutype = ' . $db->q($menutype)) + ->where('m.client_id = 1') + ->where('m.id > 1'); + + if ($enabledOnly) + { + $query->where('m.published = 1'); + } + + // Filter on the enabled states. + $query->select('e.element') + ->join('LEFT', '#__extensions AS e ON m.component_id = e.extension_id') + ->where('(e.enabled = 1 OR e.enabled IS NULL)'); + + if (count($exclude)) + { + $exId = array_filter($exclude, 'is_numeric'); + $exEl = array_filter($exclude, 'is_string'); + + if ($exId) + { + $query->where('m.id NOT IN (' . implode(', ', array_map('intval', $exId)) . ')'); + $query->where('m.parent_id NOT IN (' . implode(', ', array_map('intval', $exId)) . ')'); + } + + if ($exEl) + { + $query->where('e.element NOT IN (' . implode(', ', $db->quote($exEl)) . ')'); + } + } + + // Order by lft. + $query->order('m.lft'); + + $db->setQuery($query); + + try + { + $menuItems = $db->loadObjectList(); + + foreach ($menuItems as &$menuitem) + { + $menuitem->params = new Registry($menuitem->params); + } + } + catch (RuntimeException $e) + { + $menuItems = array(); + + JFactory::getApplication()->enqueueMessage(JText::_('JERROR_AN_ERROR_HAS_OCCURRED'), 'error'); + } + + return $menuItems; + } + + /** + * Method to install a preset menu into database and link them to the given menutype + * + * @param string $preset The preset name + * @param string $menutype The target menutype + * + * @return void + * + * @throws Exception + * + * @since 3.8.0 + */ + public static function installPreset($preset, $menutype) + { + $items = MenuHelper::loadPreset($preset, false); + + if (count($items) == 0) + { + throw new Exception(JText::_('COM_MENUS_PRESET_LOAD_FAILED')); + } + + static::installPresetItems($items, $menutype, 1); + } + + /** + * Method to install a preset menu item into database and link it to the given menutype + * + * @param stdClass[] $items The single menuitem instance with a list of its descendants + * @param string $menutype The target menutype + * @param int $parent The parent id or object + * + * @return void + * + * @throws Exception + * + * @since 3.8.0 + */ + protected static function installPresetItems(&$items, $menutype, $parent = 1) + { + $db = JFactory::getDbo(); + $query = $db->getQuery(true); + + static $components = array(); + + if (!$components) + { + $query->select('extension_id, element')->from('#__extensions')->where('type = ' . $db->q('component')); + $components = $db->setQuery($query)->loadObjectList(); + $components = ArrayHelper::getColumn((array) $components, 'element', 'extension_id'); + } + + $dispatcher = JEventDispatcher::getInstance(); + $dispatcher->trigger('onPreprocessMenuItems', array('com_menus.administrator.import', &$items, null, true)); + + foreach ($items as &$item) + { + /** @var JTableMenu $table */ + $table = JTable::getInstance('Menu'); + + $item->alias = $menutype . '-' . $item->title; + + if ($item->type == 'separator') + { + // Do not reuse a separator + $item->title = $item->title ?: '-'; + $item->alias = microtime(true); + } + elseif ($item->type == 'heading' || $item->type == 'container') + { + // Try to match an existing record to have minimum collision for a heading + $keys = array( + 'menutype' => $menutype, + 'type' => $item->type, + 'title' => $item->title, + 'parent_id' => $parent, + 'client_id' => 1, + ); + $table->load($keys); + } + elseif ($item->type == 'url' || $item->type == 'component') + { + if (substr($item->link, 0, 8) === 'special:') + { + $special = substr($item->link, 8); + + if ($special === 'language-forum') + { + $item->link = 'index.php?option=com_admin&view=help&layout=langforum'; + } + elseif ($special === 'custom-forum') + { + $item->link = ''; + } + } + + // Try to match an existing record to have minimum collision for a link + $keys = array( + 'menutype' => $menutype, + 'type' => $item->type, + 'link' => $item->link, + 'parent_id' => $parent, + 'client_id' => 1, + ); + $table->load($keys); + } + + // Translate "hideitems" param value from "element" into "menu-item-id" + if ($item->type == 'container' && count($hideitems = (array) $item->params->get('hideitems'))) + { + foreach ($hideitems as &$hel) + { + if (!is_numeric($hel)) + { + $hel = array_search($hel, $components); + } + } + + $query->clear()->select('id')->from('#__menu')->where('component_id IN (' . implode(', ', $hideitems) . ')'); + $hideitems = $db->setQuery($query)->loadColumn(); + + $item->params->set('hideitems', $hideitems); + } + + $record = array( + 'menutype' => $menutype, + 'title' => $item->title, + 'alias' => $item->alias, + 'type' => $item->type, + 'link' => $item->link, + 'browserNav' => $item->browserNav ? 1 : 0, + 'img' => $item->class, + 'access' => $item->access, + 'component_id' => array_search($item->element, $components), + 'parent_id' => $parent, + 'client_id' => 1, + 'published' => 1, + 'language' => '*', + 'home' => 0, + 'params' => (string) $item->params, + ); + + if (!$table->bind($record)) + { + throw new Exception('Bind failed: ' . $table->getError()); + } + + $table->setLocation($parent, 'last-child'); + + if (!$table->check()) + { + throw new Exception('Check failed: ' . $table->getError()); + } + + if (!$table->store()) + { + throw new Exception('Saved failed: ' . $table->getError()); + } + + $item->id = $table->get('id'); + + if (!empty($item->submenu)) + { + static::installPresetItems($item->submenu, $menutype, $item->id); + } + } + } +} diff --git a/Sites/pages/administrator/components/com_menus/layouts/joomla/menu/edit_modules.php b/Sites/pages/administrator/components/com_menus/layouts/joomla/menu/edit_modules.php new file mode 100644 index 00000000..65eb9eac --- /dev/null +++ b/Sites/pages/administrator/components/com_menus/layouts/joomla/menu/edit_modules.php @@ -0,0 +1,70 @@ +getForm(); +$input = $app->input; +$component = $input->getCmd('option', 'com_content'); + +if ($component == 'com_categories') +{ + $extension = $input->getCmd('extension', 'com_content'); + $parts = explode('.', $extension); + $component = $parts[0]; +} + +$saveHistory = JComponentHelper::getParams($component)->get('save_history', 0); + +$fields = $displayData->get('fields') ?: array( + array('parent', 'parent_id'), + array('published', 'state', 'enabled'), + array('category', 'catid'), + 'featured', + 'sticky', + 'access', + 'language', + 'tags', + 'note', + 'version_note', +); + +$hiddenFields = $displayData->get('hidden_fields') ?: array(); + +if (!$saveHistory) +{ + $hiddenFields[] = 'version_note'; +} + +$html = array(); +$html[] = '
      '; + +foreach ($fields as $field) +{ + $field = is_array($field) ? $field : array($field); + + foreach ($field as $f) + { + if ($form->getField($f)) + { + if (in_array($f, $hiddenFields)) + { + $form->setFieldAttribute($f, 'type', 'hidden'); + } + + $html[] = '
    • ' . $form->renderField($f) . '
    • '; + break; + } + } +} + +$html[] = '
    '; + +echo implode('', $html); diff --git a/Sites/pages/administrator/components/com_menus/layouts/joomla/searchtools/default.php b/Sites/pages/administrator/components/com_menus/layouts/joomla/searchtools/default.php new file mode 100644 index 00000000..0b5491a1 --- /dev/null +++ b/Sites/pages/administrator/components/com_menus/layouts/joomla/searchtools/default.php @@ -0,0 +1,83 @@ +addStyleDeclaration(" + /* Fixed filter field in search bar */ + .js-stools .js-stools-menutype, + .js-stools .js-stools-client_id { + float: left; + margin-right: 10px; + min-width: 220px; + } + html[dir=rtl] .js-stools .js-stools-menutype, + html[dir=rtl] .js-stools .js-stools-client_id { + float: right; + margin-left: 10px + margin-right: 0; + } + .js-stools .js-stools-container-bar .js-stools-field-filter .chzn-container { + padding: 3px 0; + } + "); + + // Client selector doesn't have to activate the filter bar. + unset($data['view']->activeFilters['client_id']); + + // Menutype filter doesn't have to activate the filter bar + unset($data['view']->activeFilters['menutype']); +} + +// Set some basic options +$customOptions = array( + 'filtersHidden' => isset($data['options']['filtersHidden']) ? $data['options']['filtersHidden'] : empty($data['view']->activeFilters), + 'defaultLimit' => isset($data['options']['defaultLimit']) ? $data['options']['defaultLimit'] : JFactory::getApplication()->get('list_limit', 20), + 'searchFieldSelector' => '#filter_search', + 'orderFieldSelector' => '#list_fullordering', + 'totalResults' => isset($data['options']['totalResults']) ? $data['options']['totalResults'] : -1, + 'noResultsText' => isset($data['options']['noResultsText']) ? $data['options']['noResultsText'] : JText::_('JGLOBAL_NO_MATCHING_RESULTS'), +); + +$data['options'] = array_merge($customOptions, $data['options']); + +$formSelector = !empty($data['options']['formSelector']) ? $data['options']['formSelector'] : '#adminForm'; + +// Load search tools +JHtml::_('searchtools.form', $formSelector, $data['options']); + +$filtersClass = isset($data['view']->activeFilters) && $data['view']->activeFilters ? ' js-stools-container-filters-visible' : ''; +?> +
    +
    +
    + +
    +
    + +
    +
    + +
    + +
    +
    + + + diff --git a/Sites/pages/administrator/components/com_menus/layouts/joomla/searchtools/default/bar.php b/Sites/pages/administrator/components/com_menus/layouts/joomla/searchtools/default/bar.php new file mode 100644 index 00000000..edaa509b --- /dev/null +++ b/Sites/pages/administrator/components/com_menus/layouts/joomla/searchtools/default/bar.php @@ -0,0 +1,46 @@ +filterForm->getField('menutype'); + + // Add the client selector before the form filters. + $clientIdField = $data['view']->filterForm->getField('client_id'); + + if ($clientIdField): ?> +
    + input; ?> +
    + + +
    + input; ?> +
    + filterForm->getField('client_id'); + ?> +
    + input; ?> +
    + 'none')); diff --git a/Sites/pages/administrator/components/com_menus/menus.php b/Sites/pages/administrator/components/com_menus/menus.php new file mode 100644 index 00000000..17764479 --- /dev/null +++ b/Sites/pages/administrator/components/com_menus/menus.php @@ -0,0 +1,19 @@ +authorise('core.manage', 'com_menus')) +{ + throw new JAccessExceptionNotallowed(JText::_('JERROR_ALERTNOAUTHOR'), 403); +} + +$controller = JControllerLegacy::getInstance('Menus'); +$controller->execute(JFactory::getApplication()->input->get('task')); +$controller->redirect(); diff --git a/Sites/pages/administrator/components/com_menus/menus.xml b/Sites/pages/administrator/components/com_menus/menus.xml new file mode 100644 index 00000000..b58e9434 --- /dev/null +++ b/Sites/pages/administrator/components/com_menus/menus.xml @@ -0,0 +1,28 @@ + + + com_menus + Joomla! Project + April 2006 + (C) 2005 - 2020 Open Source Matters. All rights reserved. + GNU General Public License version 2 or later; see LICENSE.txt + admin@joomla.org + www.joomla.org + 3.0.0 + COM_MENUS_XML_DESCRIPTION + + + config.xml + controller.php + menus.php + controllers + helpers + models + views + presets + + + language/en-GB.com_menus.ini + language/en-GB.com_menus.sys.ini + + + diff --git a/Sites/pages/administrator/components/com_menus/models/fields/componentscategory.php b/Sites/pages/administrator/components/com_menus/models/fields/componentscategory.php new file mode 100644 index 00000000..e48f3571 --- /dev/null +++ b/Sites/pages/administrator/components/com_menus/models/fields/componentscategory.php @@ -0,0 +1,76 @@ +getQuery(true) + ->select('DISTINCT a.name AS text, a.element AS value') + ->from('#__extensions as a') + ->where('a.enabled >= 1') + ->where('a.type =' . $db->quote('component')) + ->join('INNER', '#__categories as b ON a.element=b.extension'); + + $items = $db->setQuery($query)->loadObjectList(); + + if (count($items)) + { + $lang = JFactory::getLanguage(); + + foreach ($items as &$item) + { + // Load language + $extension = $item->value; + $source = JPATH_ADMINISTRATOR . '/components/' . $extension; + $lang->load("$extension.sys", JPATH_ADMINISTRATOR, null, false, true) + || $lang->load("$extension.sys", $source, null, false, true); + + // Translate component name + $item->text = JText::_($item->text); + } + + // Sort by component name + $items = ArrayHelper::sortObjects($items, 'text', 1, true, true); + } + + // Merge any additional options in the XML definition. + $options = array_merge(parent::getOptions(), $items); + + return $options; + } +} diff --git a/Sites/pages/administrator/components/com_menus/models/fields/menuitembytype.php b/Sites/pages/administrator/components/com_menus/models/fields/menuitembytype.php new file mode 100644 index 00000000..045b5fbe --- /dev/null +++ b/Sites/pages/administrator/components/com_menus/models/fields/menuitembytype.php @@ -0,0 +1,278 @@ +$name; + } + + return parent::__get($name); + } + + /** + * Method to set certain otherwise inaccessible properties of the form field object. + * + * @param string $name The property name for which to set the value. + * @param mixed $value The value of the property. + * + * @return void + * + * @since 3.8.0 + */ + public function __set($name, $value) + { + switch ($name) + { + case 'menuType': + $this->menuType = (string) $value; + break; + + case 'clientId': + $this->clientId = (int) $value; + break; + + case 'language': + case 'published': + case 'disable': + $value = (string) $value; + $this->$name = $value ? explode(',', $value) : array(); + break; + + default: + parent::__set($name, $value); + } + } + + /** + * Method to attach a JForm object to the field. + * + * @param SimpleXMLElement $element The SimpleXMLElement object representing the `` tag for the form field object. + * @param mixed $value The form field value to validate. + * @param string $group The field name group control value. This acts as an array container for the field. + * For example if the field has name="foo" and the group value is set to "bar" then the + * full field name would end up being "bar[foo]". + * + * @return boolean True on success. + * + * @see JFormField::setup() + * @since 3.8.0 + */ + public function setup(SimpleXMLElement $element, $value, $group = null) + { + $result = parent::setup($element, $value, $group); + + if ($result == true) + { + $menuType = (string) $this->element['menu_type']; + + if (!$menuType) + { + $app = JFactory::getApplication('administrator'); + $currentMenuType = $app->getUserState('com_menus.items.menutype', ''); + $menuType = $app->input->getString('menutype', $currentMenuType); + } + + $this->menuType = $menuType; + $this->clientId = (int) $this->element['client_id']; + $this->published = $this->element['published'] ? explode(',', (string) $this->element['published']) : array(); + $this->disable = $this->element['disable'] ? explode(',', (string) $this->element['disable']) : array(); + $this->language = $this->element['language'] ? explode(',', (string) $this->element['language']) : array(); + } + + return $result; + } + + /** + * Method to get the field option groups. + * + * @return array The field option objects as a nested array in groups. + * + * @since 3.8.0 + */ + protected function getGroups() + { + $groups = array(); + + $menuType = $this->menuType; + + // Get the menu items. + $items = MenusHelper::getMenuLinks($menuType, 0, 0, $this->published, $this->language, $this->clientId); + + // Build group for a specific menu type. + if ($menuType) + { + // If the menutype is empty, group the items by menutype. + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->select($db->quoteName('title')) + ->from($db->quoteName('#__menu_types')) + ->where($db->quoteName('menutype') . ' = ' . $db->quote($menuType)); + $db->setQuery($query); + + try + { + $menuTitle = $db->loadResult(); + } + catch (RuntimeException $e) + { + $menuTitle = $menuType; + } + + // Initialize the group. + $groups[$menuTitle] = array(); + + // Build the options array. + foreach ($items as $key => $link) + { + // Unset if item is menu_item_root + if ($link->text === 'Menu_Item_Root') + { + unset($items[$key]); + continue; + } + + $levelPrefix = str_repeat('- ', max(0, $link->level - 1)); + + // Displays language code if not set to All + if ($link->language !== '*') + { + $lang = ' (' . $link->language . ')'; + } + else + { + $lang = ''; + } + + $groups[$menuTitle][] = JHtml::_('select.option', + $link->value, $levelPrefix . $link->text . $lang, + 'value', + 'text', + in_array($link->type, $this->disable) + ); + } + } + // Build groups for all menu types. + else + { + // Build the groups arrays. + foreach ($items as $menu) + { + // Initialize the group. + $groups[$menu->title] = array(); + + // Build the options array. + foreach ($menu->links as $link) + { + $levelPrefix = str_repeat('- ', max(0, $link->level - 1)); + + // Displays language code if not set to All + if ($link->language !== '*') + { + $lang = ' (' . $link->language . ')'; + } + else + { + $lang = ''; + } + + $groups[$menu->title][] = JHtml::_('select.option', + $link->value, + $levelPrefix . $link->text . $lang, + 'value', + 'text', + in_array($link->type, $this->disable) + ); + } + } + } + + // Merge any additional groups in the XML definition. + $groups = array_merge(parent::getGroups(), $groups); + + return $groups; + } +} diff --git a/Sites/pages/administrator/components/com_menus/models/fields/menuordering.php b/Sites/pages/administrator/components/com_menus/models/fields/menuordering.php new file mode 100644 index 00000000..5bd395f5 --- /dev/null +++ b/Sites/pages/administrator/components/com_menus/models/fields/menuordering.php @@ -0,0 +1,119 @@ +form->getValue('parent_id', 0); + + if (empty($parent_id)) + { + return false; + } + + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->select('a.id AS value, a.title AS text, a.client_id AS ' . $db->quoteName('clientId')) + ->from('#__menu AS a') + + ->where('a.published >= 0') + ->where('a.parent_id =' . (int) $parent_id); + + if ($menuType = $this->form->getValue('menutype')) + { + $query->where('a.menutype = ' . $db->quote($menuType)); + } + else + { + $query->where('a.menutype != ' . $db->quote('')); + } + + $query->order('a.lft ASC'); + + // Get the options. + $db->setQuery($query); + + try + { + $options = $db->loadObjectList(); + } + catch (RuntimeException $e) + { + JError::raiseWarning(500, $e->getMessage()); + } + + // Allow translation of custom admin menus + foreach ($options as &$option) + { + if ($option->clientId != 0) + { + $option->text = JText::_($option->text); + } + } + + $options = array_merge( + array(array('value' => '-1', 'text' => JText::_('COM_MENUS_ITEM_FIELD_ORDERING_VALUE_FIRST'))), + $options, + array(array('value' => '-2', 'text' => JText::_('COM_MENUS_ITEM_FIELD_ORDERING_VALUE_LAST'))) + ); + + // Merge any additional options in the XML definition. + $options = array_merge(parent::getOptions(), $options); + + return $options; + } + + /** + * Method to get the field input markup. + * + * @return string The field input markup. + * + * @since 1.7 + */ + protected function getInput() + { + if ($this->form->getValue('id', 0) == 0) + { + return '' . JText::_('COM_MENUS_ITEM_FIELD_ORDERING_TEXT') . ''; + } + else + { + return parent::getInput(); + } + } +} diff --git a/Sites/pages/administrator/components/com_menus/models/fields/menuparent.php b/Sites/pages/administrator/components/com_menus/models/fields/menuparent.php new file mode 100644 index 00000000..e70c1db0 --- /dev/null +++ b/Sites/pages/administrator/components/com_menus/models/fields/menuparent.php @@ -0,0 +1,106 @@ +getQuery(true) + ->select('DISTINCT(a.id) AS value, a.title AS text, a.level, a.lft') + ->from('#__menu AS a'); + + // Filter by menu type. + if ($menuType = $this->form->getValue('menutype')) + { + $query->where('a.menutype = ' . $db->quote($menuType)); + } + else + { + // Skip special menu types + $query->where('a.menutype != ' . $db->quote('')); + $query->where('a.menutype != ' . $db->quote('main')); + } + + // Filter by client id. + $clientId = $this->getAttribute('clientid'); + + if (!is_null($clientId)) + { + $query->where($db->quoteName('a.client_id') . ' = ' . (int) $clientId); + } + + // Prevent parenting to children of this item. + if ($id = $this->form->getValue('id')) + { + $query->join('LEFT', $db->quoteName('#__menu') . ' AS p ON p.id = ' . (int) $id) + ->where('NOT(a.lft >= p.lft AND a.rgt <= p.rgt)'); + } + + $query->where('a.published != -2') + ->order('a.lft ASC'); + + // Get the options. + $db->setQuery($query); + + try + { + $options = $db->loadObjectList(); + } + catch (RuntimeException $e) + { + JError::raiseWarning(500, $e->getMessage()); + } + + // Pad the option text with spaces using depth level as a multiplier. + for ($i = 0, $n = count($options); $i < $n; $i++) + { + if ($clientId != 0) + { + // Allow translation of custom admin menus + $options[$i]->text = str_repeat('- ', $options[$i]->level) . JText::_($options[$i]->text); + } + else + { + $options[$i]->text = str_repeat('- ', $options[$i]->level) . $options[$i]->text; + } + } + + // Merge any additional options in the XML definition. + $options = array_merge(parent::getOptions(), $options); + + return $options; + } +} diff --git a/Sites/pages/administrator/components/com_menus/models/fields/menupreset.php b/Sites/pages/administrator/components/com_menus/models/fields/menupreset.php new file mode 100644 index 00000000..f0983916 --- /dev/null +++ b/Sites/pages/administrator/components/com_menus/models/fields/menupreset.php @@ -0,0 +1,51 @@ +name, JText::_($preset->title)); + } + + return array_merge(parent::getOptions(), $options); + } +} diff --git a/Sites/pages/administrator/components/com_menus/models/fields/menutype.php b/Sites/pages/administrator/components/com_menus/models/fields/menutype.php new file mode 100644 index 00000000..8ae342f2 --- /dev/null +++ b/Sites/pages/administrator/components/com_menus/models/fields/menutype.php @@ -0,0 +1,120 @@ +form->getValue('id'); + $size = (string) ($v = $this->element['size']) ? ' size="' . $v . '"' : ''; + $class = (string) ($v = $this->element['class']) ? ' class="' . $v . '"' : 'class="text_area"'; + $required = (string) $this->element['required'] ? ' required="required"' : ''; + $clientId = (int) $this->element['clientid'] ?: 0; + + // Get a reverse lookup of the base link URL to Title + switch ($this->value) + { + case 'url': + $value = JText::_('COM_MENUS_TYPE_EXTERNAL_URL'); + break; + + case 'alias': + $value = JText::_('COM_MENUS_TYPE_ALIAS'); + break; + + case 'separator': + $value = JText::_('COM_MENUS_TYPE_SEPARATOR'); + break; + + case 'heading': + $value = JText::_('COM_MENUS_TYPE_HEADING'); + break; + + case 'container': + $value = JText::_('COM_MENUS_TYPE_CONTAINER'); + break; + + default: + $link = $this->form->getValue('link'); + + /** @var MenusModelMenutypes $model */ + $model = JModelLegacy::getInstance('Menutypes', 'MenusModel', array('ignore_request' => true)); + $model->setState('client_id', $clientId); + + $rlu = $model->getReverseLookup(); + + // Clean the link back to the option, view and layout + $value = JText::_(ArrayHelper::getValue($rlu, MenusHelper::getLinkKey($link))); + break; + } + + // Include jQuery + JHtml::_('jquery.framework'); + + // Add the script to the document head. + JFactory::getDocument()->addScriptDeclaration(' + function jSelectPosition_' . $this->id . '(name) { + document.getElementById("' . $this->id . '").value = name; + } + ' + ); + + $link = JRoute::_('index.php?option=com_menus&view=menutypes&tmpl=component&client_id=' . $clientId . '&recordId=' . $recordId); + $html[] = ''; + $html[] = ''; + $html[] = JHtml::_( + 'bootstrap.renderModal', + 'menuTypeModal', + array( + 'url' => $link, + 'title' => JText::_('COM_MENUS_ITEM_FIELD_TYPE_LABEL'), + 'width' => '800px', + 'height' => '300px', + 'modalWidth' => '80', + 'bodyHeight' => '70', + 'footer' => '' + ) + ); + $html[] = ''; + + return implode("\n", $html); + } +} diff --git a/Sites/pages/administrator/components/com_menus/models/fields/modal/menu.php b/Sites/pages/administrator/components/com_menus/models/fields/modal/menu.php new file mode 100644 index 00000000..a6ba767a --- /dev/null +++ b/Sites/pages/administrator/components/com_menus/models/fields/modal/menu.php @@ -0,0 +1,442 @@ +$name; + } + + return parent::__get($name); + } + + /** + * Method to set certain otherwise inaccessible properties of the form field object. + * + * @param string $name The property name for which to set the value. + * @param mixed $value The value of the property. + * + * @return void + * + * @since 3.7.0 + */ + public function __set($name, $value) + { + switch ($name) + { + case 'allowSelect': + case 'allowClear': + case 'allowNew': + case 'allowEdit': + case 'allowPropagate': + $value = (string) $value; + $this->$name = !($value === 'false' || $value === 'off' || $value === '0'); + break; + + default: + parent::__set($name, $value); + } + } + + /** + * Method to attach a JForm object to the field. + * + * @param SimpleXMLElement $element The SimpleXMLElement object representing the `` tag for the form field object. + * @param mixed $value The form field value to validate. + * @param string $group The field name group control value. This acts as an array container for the field. + * For example if the field has name="foo" and the group value is set to "bar" then the + * full field name would end up being "bar[foo]". + * + * @return boolean True on success. + * + * @see JFormField::setup() + * @since 3.7.0 + */ + public function setup(SimpleXMLElement $element, $value, $group = null) + { + $return = parent::setup($element, $value, $group); + + if ($return) + { + $this->allowSelect = ((string) $this->element['select']) !== 'false'; + $this->allowClear = ((string) $this->element['clear']) !== 'false'; + $this->allowPropagate = ((string) $this->element['propagate']) === 'true'; + + // Creating/editing menu items is not supported in frontend. + $isAdministrator = JFactory::getApplication()->isClient('administrator'); + $this->allowNew = $isAdministrator ? ((string) $this->element['new']) === 'true' : false; + $this->allowEdit = $isAdministrator ? ((string) $this->element['edit']) === 'true' : false; + } + + return $return; + } + + /** + * Method to get the field input markup. + * + * @return string The field input markup. + * + * @since 3.7.0 + */ + protected function getInput() + { + $clientId = (int) $this->element['clientid']; + $languages = LanguageHelper::getContentLanguages(array(0, 1)); + + // Load language + JFactory::getLanguage()->load('com_menus', JPATH_ADMINISTRATOR); + + // The active article id field. + $value = (int) $this->value > 0 ? (int) $this->value : ''; + + // Create the modal id. + $modalId = 'Item_' . $this->id; + + // Add the modal field script to the document head. + JHtml::_('jquery.framework'); + JHtml::_('script', 'system/modal-fields.js', array('version' => 'auto', 'relative' => true)); + + // Script to proxy the select modal function to the modal-fields.js file. + if ($this->allowSelect) + { + static $scriptSelect = null; + + if (is_null($scriptSelect)) + { + $scriptSelect = array(); + } + + if (!isset($scriptSelect[$this->id])) + { + JFactory::getDocument()->addScriptDeclaration(" + function jSelectMenu_" . $this->id . "(id, title, object) { + window.processModalSelect('Item', '" . $this->id . "', id, title, '', object); + } + " + ); + + JText::script('JGLOBAL_ASSOCIATIONS_PROPAGATE_FAILED'); + + $scriptSelect[$this->id] = true; + } + } + + // Setup variables for display. + $linkSuffix = '&layout=modal&client_id=' . $clientId . '&tmpl=component&' . JSession::getFormToken() . '=1'; + $linkItems = 'index.php?option=com_menus&view=items' . $linkSuffix; + $linkItem = 'index.php?option=com_menus&view=item' . $linkSuffix; + $modalTitle = JText::_('COM_MENUS_CHANGE_MENUITEM'); + + if (isset($this->element['language'])) + { + $linkItems .= '&forcedLanguage=' . $this->element['language']; + $linkItem .= '&forcedLanguage=' . $this->element['language']; + $modalTitle .= ' — ' . $this->element['label']; + } + + $urlSelect = $linkItems . '&function=jSelectMenu_' . $this->id; + $urlEdit = $linkItem . '&task=item.edit&id=\' + document.getElementById("' . $this->id . '_id").value + \''; + $urlNew = $linkItem . '&task=item.add'; + + if ($value) + { + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->select($db->quoteName('title')) + ->from($db->quoteName('#__menu')) + ->where($db->quoteName('id') . ' = ' . (int) $value); + + $db->setQuery($query); + + try + { + $title = $db->loadResult(); + } + catch (RuntimeException $e) + { + JError::raiseWarning(500, $e->getMessage()); + } + } + + // Placeholder if option is present or not + if (empty($title)) + { + if ($this->element->option && (string) $this->element->option['value'] == '') + { + $title_holder = JText::_($this->element->option); + } + else + { + $title_holder = JText::_('COM_MENUS_SELECT_A_MENUITEM'); + } + } + + $title = empty($title) ? $title_holder : htmlspecialchars($title, ENT_QUOTES, 'UTF-8'); + + // The current menu item display field. + $html = ''; + $html .= ''; + + // Select menu item button + if ($this->allowSelect) + { + $html .= '' + . ' ' . JText::_('JSELECT') + . ''; + } + + // New menu item button + if ($this->allowNew) + { + $html .= '' + . ' ' . JText::_('JACTION_CREATE') + . ''; + } + + // Edit menu item button + if ($this->allowEdit) + { + $html .= '' + . ' ' . JText::_('JACTION_EDIT') + . ''; + } + + // Clear menu item button + if ($this->allowClear) + { + $html .= '' + . '' . JText::_('JCLEAR') + . ''; + } + + // Propagate menu item button + if ($this->allowPropagate && count($languages) > 2) + { + // Strip off language tag at the end + $tagLength = (int) strlen($this->element['language']); + $callbackFunctionStem = substr("jSelectMenu_" . $this->id, 0, -$tagLength); + + $html .= '' + . '' . JText::_('JGLOBAL_ASSOCIATIONS_PROPAGATE_BUTTON') + . ''; + } + + $html .= ''; + + + // Select menu item modal + if ($this->allowSelect) + { + $html .= JHtml::_( + 'bootstrap.renderModal', + 'ModalSelect' . $modalId, + array( + 'title' => $modalTitle, + 'url' => $urlSelect, + 'height' => '400px', + 'width' => '800px', + 'bodyHeight' => '70', + 'modalWidth' => '80', + 'footer' => '', + ) + ); + } + + // New menu item modal + if ($this->allowNew) + { + $html .= JHtml::_( + 'bootstrap.renderModal', + 'ModalNew' . $modalId, + array( + 'title' => JText::_('COM_MENUS_NEW_MENUITEM'), + 'backdrop' => 'static', + 'keyboard' => false, + 'closeButton' => false, + 'url' => $urlNew, + 'height' => '400px', + 'width' => '800px', + 'bodyHeight' => '70', + 'modalWidth' => '80', + 'footer' => '' + . '' + . '', + ) + ); + } + + // Edit menu item modal + if ($this->allowEdit) + { + $html .= JHtml::_( + 'bootstrap.renderModal', + 'ModalEdit' . $modalId, + array( + 'title' => JText::_('COM_MENUS_EDIT_MENUITEM'), + 'backdrop' => 'static', + 'keyboard' => false, + 'closeButton' => false, + 'url' => $urlEdit, + 'height' => '400px', + 'width' => '800px', + 'bodyHeight' => '70', + 'modalWidth' => '80', + 'footer' => '' + . '' + . '', + ) + ); + } + + // Note: class='required' for client side validation. + $class = $this->required ? ' class="required modal-value"' : ''; + + // Placeholder if option is present or not when clearing field + if ($this->element->option && (string) $this->element->option['value'] == '') + { + $title_holder = JText::_($this->element->option); + } + else + { + $title_holder = JText::_('COM_MENUS_SELECT_A_MENUITEM'); + } + + $html .= ''; + + return $html; + } + + /** + * Method to get the field label markup. + * + * @return string The field label markup. + * + * @since 3.7.0 + */ + protected function getLabel() + { + return str_replace($this->id, $this->id . '_id', parent::getLabel()); + } +} diff --git a/Sites/pages/administrator/components/com_menus/models/forms/filter_items.xml b/Sites/pages/administrator/components/com_menus/models/forms/filter_items.xml new file mode 100644 index 00000000..be5c50a9 --- /dev/null +++ b/Sites/pages/administrator/components/com_menus/models/forms/filter_items.xml @@ -0,0 +1,129 @@ + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    diff --git a/Sites/pages/administrator/components/com_menus/models/forms/filter_itemsadmin.xml b/Sites/pages/administrator/components/com_menus/models/forms/filter_itemsadmin.xml new file mode 100644 index 00000000..a72f293c --- /dev/null +++ b/Sites/pages/administrator/components/com_menus/models/forms/filter_itemsadmin.xml @@ -0,0 +1,94 @@ + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    diff --git a/Sites/pages/administrator/components/com_menus/models/forms/filter_menus.xml b/Sites/pages/administrator/components/com_menus/models/forms/filter_menus.xml new file mode 100644 index 00000000..717cf680 --- /dev/null +++ b/Sites/pages/administrator/components/com_menus/models/forms/filter_menus.xml @@ -0,0 +1,49 @@ + +
    + + + + + + + + + + + + + + + + + +
    diff --git a/Sites/pages/administrator/components/com_menus/models/forms/item.xml b/Sites/pages/administrator/components/com_menus/models/forms/item.xml new file mode 100644 index 00000000..fd9a057c --- /dev/null +++ b/Sites/pages/administrator/components/com_menus/models/forms/item.xml @@ -0,0 +1,241 @@ + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    diff --git a/Sites/pages/administrator/components/com_menus/models/forms/item_alias.xml b/Sites/pages/administrator/components/com_menus/models/forms/item_alias.xml new file mode 100644 index 00000000..72d65a36 --- /dev/null +++ b/Sites/pages/administrator/components/com_menus/models/forms/item_alias.xml @@ -0,0 +1,95 @@ + +
    + + + + +
    + + + + + + +
    + +
    + + + + + + + + + + + + + + + + + + +
    +
    + + diff --git a/Sites/pages/administrator/components/com_menus/models/forms/item_component.xml b/Sites/pages/administrator/components/com_menus/models/forms/item_component.xml new file mode 100644 index 00000000..84f1abd9 --- /dev/null +++ b/Sites/pages/administrator/components/com_menus/models/forms/item_component.xml @@ -0,0 +1,148 @@ + +
    + +
    + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + + + + + + + +
    + +
    + + + + + + + + + + + + + + + + + +
    + +
    + +
    diff --git a/Sites/pages/administrator/components/com_menus/models/forms/item_heading.xml b/Sites/pages/administrator/components/com_menus/models/forms/item_heading.xml new file mode 100644 index 00000000..39a36e7b --- /dev/null +++ b/Sites/pages/administrator/components/com_menus/models/forms/item_heading.xml @@ -0,0 +1,63 @@ + +
    + +
    + + + + + + + + + + + + + + + + + +
    +
    + + diff --git a/Sites/pages/administrator/components/com_menus/models/forms/item_separator.xml b/Sites/pages/administrator/components/com_menus/models/forms/item_separator.xml new file mode 100644 index 00000000..7bdb02fa --- /dev/null +++ b/Sites/pages/administrator/components/com_menus/models/forms/item_separator.xml @@ -0,0 +1,57 @@ + +
    + +
    + + + + + + + + + + + + + + + + +
    +
    + + diff --git a/Sites/pages/administrator/components/com_menus/models/forms/item_url.xml b/Sites/pages/administrator/components/com_menus/models/forms/item_url.xml new file mode 100644 index 00000000..3d788f33 --- /dev/null +++ b/Sites/pages/administrator/components/com_menus/models/forms/item_url.xml @@ -0,0 +1,88 @@ + +
    + +
    + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + diff --git a/Sites/pages/administrator/components/com_menus/models/forms/itemadmin.xml b/Sites/pages/administrator/components/com_menus/models/forms/itemadmin.xml new file mode 100644 index 00000000..4ef196c7 --- /dev/null +++ b/Sites/pages/administrator/components/com_menus/models/forms/itemadmin.xml @@ -0,0 +1,196 @@ + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    diff --git a/Sites/pages/administrator/components/com_menus/models/forms/itemadmin_alias.xml b/Sites/pages/administrator/components/com_menus/models/forms/itemadmin_alias.xml new file mode 100644 index 00000000..1cfc97e3 --- /dev/null +++ b/Sites/pages/administrator/components/com_menus/models/forms/itemadmin_alias.xml @@ -0,0 +1,81 @@ + +
    + + +
    + +
    + +
    + + + + + + + + + + + + + + + + + + +
    +
    + + diff --git a/Sites/pages/administrator/components/com_menus/models/forms/itemadmin_component.xml b/Sites/pages/administrator/components/com_menus/models/forms/itemadmin_component.xml new file mode 100644 index 00000000..7a297a36 --- /dev/null +++ b/Sites/pages/administrator/components/com_menus/models/forms/itemadmin_component.xml @@ -0,0 +1,63 @@ + +
    + +
    + + + + + + + + + + + + + + + + + + +
    +
    +
    diff --git a/Sites/pages/administrator/components/com_menus/models/forms/itemadmin_container.xml b/Sites/pages/administrator/components/com_menus/models/forms/itemadmin_container.xml new file mode 100644 index 00000000..54f506c3 --- /dev/null +++ b/Sites/pages/administrator/components/com_menus/models/forms/itemadmin_container.xml @@ -0,0 +1,82 @@ + +
    +
    + + + + +
    + + +
    + + + + + + + + + + + + + + + + + +
    + +
    + + diff --git a/Sites/pages/administrator/components/com_menus/models/forms/itemadmin_heading.xml b/Sites/pages/administrator/components/com_menus/models/forms/itemadmin_heading.xml new file mode 100644 index 00000000..68c4d6a2 --- /dev/null +++ b/Sites/pages/administrator/components/com_menus/models/forms/itemadmin_heading.xml @@ -0,0 +1,75 @@ + +
    +
    + + + + +
    + + +
    + + + + + + + + + + + + + + + + + +
    +
    + + diff --git a/Sites/pages/administrator/components/com_menus/models/forms/itemadmin_separator.xml b/Sites/pages/administrator/components/com_menus/models/forms/itemadmin_separator.xml new file mode 100644 index 00000000..6130cfa8 --- /dev/null +++ b/Sites/pages/administrator/components/com_menus/models/forms/itemadmin_separator.xml @@ -0,0 +1,33 @@ + +
    +
    + + + + + + + + + + + +
    + + + diff --git a/Sites/pages/administrator/components/com_menus/models/forms/itemadmin_url.xml b/Sites/pages/administrator/components/com_menus/models/forms/itemadmin_url.xml new file mode 100644 index 00000000..29bab562 --- /dev/null +++ b/Sites/pages/administrator/components/com_menus/models/forms/itemadmin_url.xml @@ -0,0 +1,82 @@ + +
    + +
    + + + + + + + + + + + + + + + + + + + + + +
    +
    + + diff --git a/Sites/pages/administrator/components/com_menus/models/forms/menu.xml b/Sites/pages/administrator/components/com_menus/models/forms/menu.xml new file mode 100644 index 00000000..b2199b31 --- /dev/null +++ b/Sites/pages/administrator/components/com_menus/models/forms/menu.xml @@ -0,0 +1,78 @@ + +
    +
    + + + + + + + + + + + + + +
    +
    diff --git a/Sites/pages/administrator/components/com_menus/models/item.php b/Sites/pages/administrator/components/com_menus/models/item.php new file mode 100644 index 00000000..38f2a11d --- /dev/null +++ b/Sites/pages/administrator/components/com_menus/models/item.php @@ -0,0 +1,1770 @@ + 'batchAccess', + 'language_id' => 'batchLanguage' + ); + + /** + * Method to test whether a record can be deleted. + * + * @param object $record A record object. + * + * @return boolean True if allowed to delete the record. Defaults to the permission set in the component. + * + * @since 1.6 + */ + protected function canDelete($record) + { + if (empty($record->id) || $record->published != -2) + { + return false; + } + + $menuTypeId = 0; + + if (!empty($record->menutype)) + { + $menuTypeId = $this->getMenuTypeId($record->menutype); + } + + return JFactory::getUser()->authorise('core.delete', 'com_menus.menu.' . (int) $menuTypeId); + } + + /** + * Method to test whether the state of a record can be edited. + * + * @param object $record A record object. + * + * @return boolean True if allowed to change the state of the record. Defaults to the permission for the component. + * + * @since 3.6 + */ + protected function canEditState($record) + { + $menuTypeId = !empty($record->menutype) ? $this->getMenuTypeId($record->menutype) : 0; + $assetKey = $menuTypeId ? 'com_menus.menu.' . (int) $menuTypeId : 'com_menus'; + + return JFactory::getUser()->authorise('core.edit.state', $assetKey); + } + + /** + * Batch copy menu items to a new menu or parent. + * + * @param integer $value The new menu or sub-item. + * @param array $pks An array of row IDs. + * @param array $contexts An array of item contexts. + * + * @return mixed An array of new IDs on success, boolean false on failure. + * + * @since 1.6 + */ + protected function batchCopy($value, $pks, $contexts) + { + // $value comes as {menutype}.{parent_id} + $parts = explode('.', $value); + $menuType = $parts[0]; + $parentId = ArrayHelper::getValue($parts, 1, 0, 'int'); + + $table = $this->getTable(); + $db = $this->getDbo(); + $query = $db->getQuery(true); + $newIds = array(); + + // Check that the parent exists + if ($parentId) + { + if (!$table->load($parentId)) + { + if ($error = $table->getError()) + { + // Fatal error + $this->setError($error); + + return false; + } + else + { + // Non-fatal error + $this->setError(JText::_('JGLOBAL_BATCH_MOVE_PARENT_NOT_FOUND')); + $parentId = 0; + } + } + } + + // If the parent is 0, set it to the ID of the root item in the tree + if (empty($parentId)) + { + if (!$parentId = $table->getRootId()) + { + $this->setError($db->getErrorMsg()); + + return false; + } + } + + // Check that user has create permission for menus + $user = JFactory::getUser(); + + $menuTypeId = (int) $this->getMenuTypeId($menuType); + + if (!$user->authorise('core.create', 'com_menus.menu.' . $menuTypeId)) + { + $this->setError(JText::_('COM_MENUS_BATCH_MENU_ITEM_CANNOT_CREATE')); + + return false; + } + + // We need to log the parent ID + $parents = array(); + + // Calculate the emergency stop count as a precaution against a runaway loop bug + $query->select('COUNT(id)') + ->from($db->quoteName('#__menu')); + $db->setQuery($query); + + try + { + $count = $db->loadResult(); + } + catch (RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + + // Parent exists so we let's proceed + while (!empty($pks) && $count > 0) + { + // Pop the first id off the stack + $pk = array_shift($pks); + + $table->reset(); + + // Check that the row actually exists + if (!$table->load($pk)) + { + if ($error = $table->getError()) + { + // Fatal error + $this->setError($error); + + return false; + } + else + { + // Not fatal error + $this->setError(JText::sprintf('JGLOBAL_BATCH_MOVE_ROW_NOT_FOUND', $pk)); + continue; + } + } + + // Copy is a bit tricky, because we also need to copy the children + $query->clear() + ->select('id') + ->from($db->quoteName('#__menu')) + ->where('lft > ' . (int) $table->lft) + ->where('rgt < ' . (int) $table->rgt); + $db->setQuery($query); + $childIds = $db->loadColumn(); + + // Add child ID's to the array only if they aren't already there. + foreach ($childIds as $childId) + { + if (!in_array($childId, $pks)) + { + $pks[] = $childId; + } + } + + // Make a copy of the old ID and Parent ID + $oldId = $table->id; + $oldParentId = $table->parent_id; + + // Reset the id because we are making a copy. + $table->id = 0; + + // If we a copying children, the Old ID will turn up in the parents list + // otherwise it's a new top level item + $table->parent_id = isset($parents[$oldParentId]) ? $parents[$oldParentId] : $parentId; + $table->menutype = $menuType; + + // Set the new location in the tree for the node. + $table->setLocation($table->parent_id, 'last-child'); + + // TODO: Deal with ordering? + // $table->ordering = 1; + $table->level = null; + $table->lft = null; + $table->rgt = null; + $table->home = 0; + + // Alter the title & alias + list($title, $alias) = $this->generateNewTitle($table->parent_id, $table->alias, $table->title); + $table->title = $title; + $table->alias = $alias; + + // Check the row. + if (!$table->check()) + { + $this->setError($table->getError()); + + return false; + } + + // Store the row. + if (!$table->store()) + { + $this->setError($table->getError()); + + return false; + } + + // Get the new item ID + $newId = $table->get('id'); + + // Add the new ID to the array + $newIds[$pk] = $newId; + + // Now we log the old 'parent' to the new 'parent' + $parents[$oldId] = $table->id; + $count--; + } + + // Rebuild the hierarchy. + if (!$table->rebuild()) + { + $this->setError($table->getError()); + + return false; + } + + // Rebuild the tree path. + if (!$table->rebuildPath($table->id)) + { + $this->setError($table->getError()); + + return false; + } + + // Clean the cache + $this->cleanCache(); + + return $newIds; + } + + /** + * Batch move menu items to a new menu or parent. + * + * @param integer $value The new menu or sub-item. + * @param array $pks An array of row IDs. + * @param array $contexts An array of item contexts. + * + * @return boolean True on success. + * + * @since 1.6 + */ + protected function batchMove($value, $pks, $contexts) + { + // $value comes as {menutype}.{parent_id} + $parts = explode('.', $value); + $menuType = $parts[0]; + $parentId = ArrayHelper::getValue($parts, 1, 0, 'int'); + + $table = $this->getTable(); + $db = $this->getDbo(); + $query = $db->getQuery(true); + + // Check that the parent exists. + if ($parentId) + { + if (!$table->load($parentId)) + { + if ($error = $table->getError()) + { + // Fatal error + $this->setError($error); + + return false; + } + else + { + // Non-fatal error + $this->setError(JText::_('JGLOBAL_BATCH_MOVE_PARENT_NOT_FOUND')); + $parentId = 0; + } + } + } + + // Check that user has create and edit permission for menus + $user = JFactory::getUser(); + + $menuTypeId = (int) $this->getMenuTypeId($menuType); + + if (!$user->authorise('core.create', 'com_menus.menu.' . $menuTypeId)) + { + $this->setError(JText::_('COM_MENUS_BATCH_MENU_ITEM_CANNOT_CREATE')); + + return false; + } + + if (!$user->authorise('core.edit', 'com_menus.menu.' . $menuTypeId)) + { + $this->setError(JText::_('COM_MENUS_BATCH_MENU_ITEM_CANNOT_EDIT')); + + return false; + } + + // We are going to store all the children and just moved the menutype + $children = array(); + + // Parent exists so we let's proceed + foreach ($pks as $pk) + { + // Check that the row actually exists + if (!$table->load($pk)) + { + if ($error = $table->getError()) + { + // Fatal error + $this->setError($error); + + return false; + } + else + { + // Not fatal error + $this->setError(JText::sprintf('JGLOBAL_BATCH_MOVE_ROW_NOT_FOUND', $pk)); + continue; + } + } + + // Set the new location in the tree for the node. + $table->setLocation($parentId, 'last-child'); + + // Set the new Parent Id + $table->parent_id = $parentId; + + // Check if we are moving to a different menu + if ($menuType != $table->menutype) + { + // Add the child node ids to the children array. + $query->clear() + ->select($db->quoteName('id')) + ->from($db->quoteName('#__menu')) + ->where($db->quoteName('lft') . ' BETWEEN ' . (int) $table->lft . ' AND ' . (int) $table->rgt); + $db->setQuery($query); + $children = array_merge($children, (array) $db->loadColumn()); + } + + // Check the row. + if (!$table->check()) + { + $this->setError($table->getError()); + + return false; + } + + // Store the row. + if (!$table->store()) + { + $this->setError($table->getError()); + + return false; + } + + // Rebuild the tree path. + if (!$table->rebuildPath()) + { + $this->setError($table->getError()); + + return false; + } + } + + // Process the child rows + if (!empty($children)) + { + // Remove any duplicates and sanitize ids. + $children = array_unique($children); + $children = ArrayHelper::toInteger($children); + + // Update the menutype field in all nodes where necessary. + $query->clear() + ->update($db->quoteName('#__menu')) + ->set($db->quoteName('menutype') . ' = ' . $db->quote($menuType)) + ->where($db->quoteName('id') . ' IN (' . implode(',', $children) . ')'); + $db->setQuery($query); + + try + { + $db->execute(); + } + catch (RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + } + + // Clean the cache + $this->cleanCache(); + + return true; + } + + /** + * Method to check if you can save a record. + * + * @param array $data An array of input data. + * @param string $key The name of the key for the primary key. + * + * @return boolean + * + * @since 1.6 + */ + protected function canSave($data = array(), $key = 'id') + { + return JFactory::getUser()->authorise('core.edit', $this->option); + } + + /** + * Method to get the row form. + * + * @param array $data Data for the form. + * @param boolean $loadData True if the form is to load its own data (default case), false if not. + * + * @return mixed A JForm object on success, false on failure + * + * @since 1.6 + */ + public function getForm($data = array(), $loadData = true) + { + // The folder and element vars are passed when saving the form. + if (empty($data)) + { + $item = $this->getItem(); + + // The type should already be set. + $this->setState('item.link', $item->link); + } + else + { + $this->setState('item.link', ArrayHelper::getValue($data, 'link')); + $this->setState('item.type', ArrayHelper::getValue($data, 'type')); + } + + $clientId = $this->getState('item.client_id'); + + // Get the form. + if ($clientId == 1) + { + $form = $this->loadForm('com_menus.item.admin', 'itemadmin', array('control' => 'jform', 'load_data' => $loadData), true); + } + else + { + $form = $this->loadForm('com_menus.item', 'item', array('control' => 'jform', 'load_data' => $loadData), true); + } + + if (empty($form)) + { + return false; + } + + if ($loadData) + { + $data = $this->loadFormData(); + } + + // Modify the form based on access controls. + if (!$this->canEditState((object) $data)) + { + // Disable fields for display. + $form->setFieldAttribute('menuordering', 'disabled', 'true'); + $form->setFieldAttribute('published', 'disabled', 'true'); + + // Disable fields while saving. + // The controller has already verified this is an article you can edit. + $form->setFieldAttribute('menuordering', 'filter', 'unset'); + $form->setFieldAttribute('published', 'filter', 'unset'); + } + + // Filter available menus + $action = $this->getState('item.id') > 0 ? 'edit' : 'create'; + + $form->setFieldAttribute('menutype', 'accesstype', $action); + $form->setFieldAttribute('type', 'clientid', $clientId); + + return $form; + } + + /** + * Method to get the data that should be injected in the form. + * + * @return mixed The data for the form. + * + * @since 1.6 + */ + protected function loadFormData() + { + + // Check the session for previously entered form data, providing it has an ID and it is the same. + $itemData = (array) $this->getItem(); + $sessionData = (array) JFactory::getApplication()->getUserState('com_menus.edit.item.data', array()); + + // Only merge if there is a session and itemId or itemid is null. + if (isset($sessionData['id']) && isset($itemData['id']) && $sessionData['id'] === $itemData['id'] + || is_null($itemData['id'])) + { + $data = array_merge($itemData, $sessionData); + } + else + { + $data = $itemData; + } + + // For a new menu item, pre-select some filters (Status, Language, Access) in edit form if those have been selected in Menu Manager + if ($this->getItem()->id == 0) + { + // Get selected fields + $filters = JFactory::getApplication()->getUserState('com_menus.items.filter'); + $data['parent_id'] = (isset($filters['parent_id']) ? $filters['parent_id'] : null); + $data['published'] = (isset($filters['published']) ? $filters['published'] : null); + $data['language'] = (isset($filters['language']) ? $filters['language'] : null); + $data['access'] = (!empty($filters['access']) ? $filters['access'] : JFactory::getConfig()->get('access')); + } + + if (isset($data['menutype']) && !$this->getState('item.menutypeid')) + { + $menuTypeId = (int) $this->getMenuTypeId($data['menutype']); + + $this->setState('item.menutypeid', $menuTypeId); + } + + $data = (object) $data; + + $this->preprocessData('com_menus.item', $data); + + return $data; + } + + /** + * Get the necessary data to load an item help screen. + * + * @return object An object with key, url, and local properties for loading the item help screen. + * + * @since 1.6 + */ + public function getHelp() + { + return (object) array('key' => $this->helpKey, 'url' => $this->helpURL, 'local' => $this->helpLocal); + } + + /** + * Method to get a menu item. + * + * @param integer $pk An optional id of the object to get, otherwise the id from the model state is used. + * + * @return mixed Menu item data object on success, false on failure. + * + * @since 1.6 + */ + public function getItem($pk = null) + { + $pk = (!empty($pk)) ? $pk : (int) $this->getState('item.id'); + + // Get a level row instance. + $table = $this->getTable(); + + // Attempt to load the row. + $table->load($pk); + + // Check for a table object error. + if ($error = $table->getError()) + { + $this->setError($error); + + return false; + } + + // Prime required properties. + + if ($type = $this->getState('item.type')) + { + $table->type = $type; + } + + if (empty($table->id)) + { + $table->parent_id = $this->getState('item.parent_id'); + $table->menutype = $this->getState('item.menutype'); + $table->client_id = $this->getState('item.client_id'); + $table->params = '{}'; + } + + // If the link has been set in the state, possibly changing link type. + if ($link = $this->getState('item.link')) + { + // Check if we are changing away from the actual link type. + if (MenusHelper::getLinkKey($table->link) !== MenusHelper::getLinkKey($link) && (int) $table->id === (int) $this->getState('item.id')) + { + $table->link = $link; + } + } + + switch ($table->type) + { + case 'alias': + $table->component_id = 0; + $args = array(); + + parse_str(parse_url($table->link, PHP_URL_QUERY), $args); + break; + + case 'separator': + case 'heading': + case 'container': + $table->link = ''; + $table->component_id = 0; + break; + + case 'url': + $table->component_id = 0; + + $args = array(); + parse_str(parse_url($table->link, PHP_URL_QUERY), $args); + break; + + case 'component': + default: + // Enforce a valid type. + $table->type = 'component'; + + // Ensure the integrity of the component_id field is maintained, particularly when changing the menu item type. + $args = array(); + parse_str(parse_url($table->link, PHP_URL_QUERY), $args); + + if (isset($args['option'])) + { + // Load the language file for the component. + $lang = JFactory::getLanguage(); + $lang->load($args['option'], JPATH_ADMINISTRATOR, null, false, true) + || $lang->load($args['option'], JPATH_ADMINISTRATOR . '/components/' . $args['option'], null, false, true); + + // Determine the component id. + $component = JComponentHelper::getComponent($args['option']); + + if (isset($component->id)) + { + $table->component_id = $component->id; + } + } + break; + } + + // We have a valid type, inject it into the state for forms to use. + $this->setState('item.type', $table->type); + + // Convert to the JObject before adding the params. + $properties = $table->getProperties(1); + $result = ArrayHelper::toObject($properties); + + // Convert the params field to an array. + $registry = new Registry($table->params); + $result->params = $registry->toArray(); + + // Merge the request arguments in to the params for a component. + if ($table->type == 'component') + { + // Note that all request arguments become reserved parameter names. + $result->request = $args; + $result->params = array_merge($result->params, $args); + + // Special case for the Login menu item. + // Display the login or logout redirect URL fields if not empty + if ($table->link == 'index.php?option=com_users&view=login') + { + if (!empty($result->params['login_redirect_url'])) + { + $result->params['loginredirectchoice'] = '0'; + } + + if (!empty($result->params['logout_redirect_url'])) + { + $result->params['logoutredirectchoice'] = '0'; + } + } + } + + if ($table->type == 'alias') + { + // Note that all request arguments become reserved parameter names. + $result->params = array_merge($result->params, $args); + } + + if ($table->type == 'url') + { + // Note that all request arguments become reserved parameter names. + $result->params = array_merge($result->params, $args); + } + + // Load associated menu items, only supported for frontend for now + if ($this->getState('item.client_id') == 0 && JLanguageAssociations::isEnabled()) + { + if ($pk != null) + { + $result->associations = MenusHelper::getAssociations($pk); + } + else + { + $result->associations = array(); + } + } + + $result->menuordering = $pk; + + return $result; + } + + /** + * Get the list of modules not in trash. + * + * @return mixed An array of module records (id, title, position), or false on error. + * + * @since 1.6 + */ + public function getModules() + { + $db = $this->getDbo(); + $query = $db->getQuery(true); + + // Currently any setting that affects target page for a backend menu is not supported, hence load no modules. + if ($this->getState('item.client_id') == 1) + { + return false; + } + + /** + * Join on the module-to-menu mapping table. + * We are only interested if the module is displayed on ALL or THIS menu item (or the inverse ID number). + * sqlsrv changes for modulelink to menu manager + */ + $query->select('a.id, a.title, a.position, a.published, map.menuid') + ->from('#__modules AS a') + ->join('LEFT', sprintf('#__modules_menu AS map ON map.moduleid = a.id AND map.menuid IN (0, %1$d, -%1$d)', $this->getState('item.id'))) + ->select('(SELECT COUNT(*) FROM #__modules_menu WHERE moduleid = a.id AND menuid < 0) AS ' . $db->quoteName('except')); + + // Join on the asset groups table. + $query->select('ag.title AS access_title') + ->join('LEFT', '#__viewlevels AS ag ON ag.id = a.access') + ->where('a.published >= 0') + ->where('a.client_id = ' . (int) $this->getState('item.client_id')) + ->order('a.position, a.ordering'); + + $db->setQuery($query); + + try + { + $result = $db->loadObjectList(); + } + catch (RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + + return $result; + } + + /** + * Get the list of all view levels + * + * @return array|boolean An array of all view levels (id, title). + * + * @since 3.4 + */ + public function getViewLevels() + { + $db = $this->getDbo(); + $query = $db->getQuery(true); + + // Get all the available view levels + $query->select($db->quoteName('id')) + ->select($db->quoteName('title')) + ->from($db->quoteName('#__viewlevels')) + ->order($db->quoteName('id')); + + $db->setQuery($query); + + try + { + $result = $db->loadObjectList(); + } + catch (RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + + return $result; + } + + /** + * A protected method to get the where clause for the reorder. + * This ensures that the row will be moved relative to a row with the same menutype. + * + * @param JTableMenu $table instance. + * + * @return array An array of conditions to add to add to ordering queries. + * + * @since 1.6 + */ + protected function getReorderConditions($table) + { + return array('menutype = ' . $this->_db->quote($table->get('menutype'))); + } + + /** + * Returns a Table object, always creating it + * + * @param string $type The table type to instantiate. + * @param string $prefix A prefix for the table class name. Optional. + * @param array $config Configuration array for model. Optional. + * + * @return JTable|JTableNested A database object. + * + * @since 1.6 + */ + public function getTable($type = 'Menu', $prefix = 'MenusTable', $config = array()) + { + return JTable::getInstance($type, $prefix, $config); + } + + /** + * Auto-populate the model state. + * + * Note. Calling getState in this method will result in recursion. + * + * @return void + * + * @since 1.6 + */ + protected function populateState() + { + $app = JFactory::getApplication('administrator'); + + // Load the User state. + $pk = $app->input->getInt('id'); + $this->setState('item.id', $pk); + + if (!($parentId = $app->getUserState('com_menus.edit.item.parent_id'))) + { + $parentId = $app->input->getInt('parent_id'); + } + + $this->setState('item.parent_id', $parentId); + + $menuType = $app->getUserStateFromRequest('com_menus.items.menutype', 'menutype', '', 'string'); + + // If we have a menutype we take client_id from there, unless forced otherwise + if ($menuType) + { + $menuTypeObj = $this->getMenuType($menuType); + + // An invalid menutype will be handled as clientId = 0 and menuType = '' + $menuType = (string) $menuTypeObj->menutype; + $menuTypeId = (int) $menuTypeObj->client_id; + $clientId = (int) $menuTypeObj->client_id; + } + else + { + $menuTypeId = 0; + $clientId = $app->getUserState('com_menus.items.client_id', 0); + } + + // Forced client id will override/clear menuType if conflicted + $forcedClientId = $app->input->get('client_id', null, 'string'); + + // Current item if not new, we don't allow changing client id at all + if ($pk) + { + $table = $this->getTable(); + $table->load($pk); + $forcedClientId = $table->get('client_id', $forcedClientId); + } + + if (isset($forcedClientId) && $forcedClientId != $clientId) + { + $clientId = $forcedClientId; + $menuType = ''; + $menuTypeId = 0; + } + + // Set the menu type and client id on the list view state, so we return to this menu after saving. + $app->setUserState('com_menus.items.menutype', $menuType); + $app->setUserState('com_menus.items.client_id', $clientId); + + $this->setState('item.menutype', $menuType); + $this->setState('item.client_id', $clientId); + $this->setState('item.menutypeid', $menuTypeId); + + if (!($type = $app->getUserState('com_menus.edit.item.type'))) + { + $type = $app->input->get('type'); + + /** + * Note: a new menu item will have no field type. + * The field is required so the user has to change it. + */ + } + + $this->setState('item.type', $type); + + if ($link = $app->getUserState('com_menus.edit.item.link')) + { + $this->setState('item.link', $link); + } + + // Load the parameters. + $params = JComponentHelper::getParams('com_menus'); + $this->setState('params', $params); + } + + /** + * Loads the menutype object by a given menutype string + * + * @param string $menutype The given menutype + * + * @return stdClass + * + * @since 3.7.0 + */ + protected function getMenuType($menutype) + { + $table = $this->getTable('MenuType', 'JTable'); + + $table->load(array('menutype' => $menutype)); + + return (object) $table->getProperties(); + } + + /** + * Loads the menutype ID by a given menutype string + * + * @param string $menutype The given menutype + * + * @return integer + * + * @since 3.6 + */ + protected function getMenuTypeId($menutype) + { + $menu = $this->getMenuType($menutype); + + return (int) $menu->id; + } + + /** + * Method to preprocess the form. + * + * @param JForm $form A JForm object. + * @param mixed $data The data expected for the form. + * @param string $group The name of the plugin group to import. + * + * @return void + * + * @since 1.6 + * @throws Exception if there is an error in the form event. + */ + protected function preprocessForm(JForm $form, $data, $group = 'content') + { + $link = $this->getState('item.link'); + $type = $this->getState('item.type'); + $clientId = $this->getState('item.client_id'); + $formFile = false; + + // Load the specific type file + $typeFile = $clientId == 1 ? 'itemadmin_' . $type : 'item_' . $type; + $clientInfo = JApplicationHelper::getClientInfo($clientId); + + // Initialise form with component view params if available. + if ($type == 'component') + { + $link = htmlspecialchars_decode($link); + + // Parse the link arguments. + $args = array(); + parse_str(parse_url(htmlspecialchars_decode($link), PHP_URL_QUERY), $args); + + // Confirm that the option is defined. + $option = ''; + $base = ''; + + if (isset($args['option'])) + { + // The option determines the base path to work with. + $option = $args['option']; + $base = $clientInfo->path . '/components/' . $option; + } + + if (isset($args['view'])) + { + $view = $args['view']; + + // Determine the layout to search for. + if (isset($args['layout'])) + { + $layout = $args['layout']; + } + else + { + $layout = 'default'; + } + + // Check for the layout XML file. Use standard xml file if it exists. + $tplFolders = array( + $base . '/views/' . $view . '/tmpl', + $base . '/view/' . $view . '/tmpl' + ); + $path = JPath::find($tplFolders, $layout . '.xml'); + + if (is_file($path)) + { + $formFile = $path; + } + + // If custom layout, get the xml file from the template folder + // template folder is first part of file name -- template:folder + if (!$formFile && (strpos($layout, ':') > 0)) + { + list($altTmpl, $altLayout) = explode(':', $layout); + + $templatePath = JPath::clean($clientInfo->path . '/templates/' . $altTmpl . '/html/' . $option . '/' . $view . '/' . $altLayout . '.xml'); + + if (is_file($templatePath)) + { + $formFile = $templatePath; + } + } + } + + // Now check for a view manifest file + if (!$formFile) + { + if (isset($view)) + { + $metadataFolders = array( + $base . '/view/' . $view, + $base . '/views/' . $view + ); + $metaPath = JPath::find($metadataFolders, 'metadata.xml'); + + if (is_file($path = JPath::clean($metaPath))) + { + $formFile = $path; + } + } + else + { + // Now check for a component manifest file + $path = JPath::clean($base . '/metadata.xml'); + + if (is_file($path)) + { + $formFile = $path; + } + } + } + } + + if ($formFile) + { + // If an XML file was found in the component, load it first. + // We need to qualify the full path to avoid collisions with component file names. + + if ($form->loadFile($formFile, true, '/metadata') == false) + { + throw new Exception(JText::_('JERROR_LOADFILE_FAILED')); + } + + // Attempt to load the xml file. + if (!$xml = simplexml_load_file($formFile)) + { + throw new Exception(JText::_('JERROR_LOADFILE_FAILED')); + } + + // Get the help data from the XML file if present. + $help = $xml->xpath('/metadata/layout/help'); + } + else + { + // We don't have a component. Load the form XML to get the help path + $xmlFile = JPath::find(JPATH_ADMINISTRATOR . '/components/com_menus/models/forms', $typeFile . '.xml'); + + if ($xmlFile) + { + if (!$xml = simplexml_load_file($xmlFile)) + { + throw new Exception(JText::_('JERROR_LOADFILE_FAILED')); + } + + // Get the help data from the XML file if present. + $help = $xml->xpath('/form/help'); + } + } + + if (!empty($help)) + { + $helpKey = trim((string) $help[0]['key']); + $helpURL = trim((string) $help[0]['url']); + $helpLoc = trim((string) $help[0]['local']); + + $this->helpKey = $helpKey ?: $this->helpKey; + $this->helpURL = $helpURL ?: $this->helpURL; + $this->helpLocal = (($helpLoc == 'true') || ($helpLoc == '1') || ($helpLoc == 'local')) ? true : false; + } + + if (!$form->loadFile($typeFile, true, false)) + { + throw new Exception(JText::_('JERROR_LOADFILE_FAILED')); + } + + // Association menu items, we currently do not support this for admin menu… may be later + if ($clientId == 0 && JLanguageAssociations::isEnabled()) + { + $languages = JLanguageHelper::getContentLanguages(false, true, null, 'ordering', 'asc'); + + if (count($languages) > 1) + { + $addform = new SimpleXMLElement('
    '); + $fields = $addform->addChild('fields'); + $fields->addAttribute('name', 'associations'); + $fieldset = $fields->addChild('fieldset'); + $fieldset->addAttribute('name', 'item_associations'); + + foreach ($languages as $language) + { + $field = $fieldset->addChild('field'); + $field->addAttribute('name', $language->lang_code); + $field->addAttribute('type', 'modal_menu'); + $field->addAttribute('language', $language->lang_code); + $field->addAttribute('label', $language->title); + $field->addAttribute('translate_label', 'false'); + $field->addAttribute('select', 'true'); + $field->addAttribute('new', 'true'); + $field->addAttribute('edit', 'true'); + $field->addAttribute('clear', 'true'); + $field->addAttribute('propagate', 'true'); + $option = $field->addChild('option', 'COM_MENUS_ITEM_FIELD_ASSOCIATION_NO_VALUE'); + $option->addAttribute('value', ''); + } + + $form->load($addform, false); + } + } + + // Trigger the default form events. + parent::preprocessForm($form, $data, $group); + } + + /** + * Method rebuild the entire nested set tree. + * + * @return boolean|JException Boolean true on success, boolean false or JException instance on error + * + * @since 1.6 + */ + public function rebuild() + { + // Initialise variables. + $db = $this->getDbo(); + $query = $db->getQuery(true); + $table = $this->getTable(); + + try + { + $rebuildResult = $table->rebuild(); + } + catch (Exception $e) + { + $this->setError($e->getMessage()); + + return false; + } + + if (!$rebuildResult) + { + $this->setError($table->getError()); + + return false; + } + + $query->select('id, params') + ->from('#__menu') + ->where('params NOT LIKE ' . $db->quote('{%')) + ->where('params <> ' . $db->quote('')); + $db->setQuery($query); + + try + { + $items = $db->loadObjectList(); + } + catch (RuntimeException $e) + { + return JError::raiseWarning(500, $e->getMessage()); + } + + foreach ($items as &$item) + { + $registry = new Registry($item->params); + $params = (string) $registry; + + $query->clear(); + $query->update('#__menu') + ->set('params = ' . $db->quote($params)) + ->where('id = ' . $item->id); + + try + { + $db->setQuery($query)->execute(); + } + catch (RuntimeException $e) + { + return JError::raiseWarning(500, $e->getMessage()); + } + + unset($registry); + } + + // Clean the cache + $this->cleanCache(); + + return true; + } + + /** + * Method to save the form data. + * + * @param array $data The form data. + * + * @return boolean True on success. + * + * @since 1.6 + */ + public function save($data) + { + $dispatcher = JEventDispatcher::getInstance(); + $pk = (!empty($data['id'])) ? $data['id'] : (int) $this->getState('item.id'); + $isNew = true; + $table = $this->getTable(); + $context = $this->option . '.' . $this->name; + + // Include the plugins for the on save events. + JPluginHelper::importPlugin($this->events_map['save']); + + // Load the row if saving an existing item. + if ($pk > 0) + { + $table->load($pk); + $isNew = false; + } + + if (!$isNew) + { + if ($table->parent_id == $data['parent_id']) + { + // If first is chosen make the item the first child of the selected parent. + if ($data['menuordering'] == -1) + { + $table->setLocation($data['parent_id'], 'first-child'); + } + // If last is chosen make it the last child of the selected parent. + elseif ($data['menuordering'] == -2) + { + $table->setLocation($data['parent_id'], 'last-child'); + } + // Don't try to put an item after itself. All other ones put after the selected item. + // $data['id'] is empty means it's a save as copy + elseif ($data['menuordering'] && $table->id != $data['menuordering'] || empty($data['id'])) + { + $table->setLocation($data['menuordering'], 'after'); + } + // Just leave it where it is if no change is made. + elseif ($data['menuordering'] && $table->id == $data['menuordering']) + { + unset($data['menuordering']); + } + } + // Set the new parent id if parent id not matched and put in last position + else + { + $table->setLocation($data['parent_id'], 'last-child'); + } + } + // We have a new item, so it is not a change. + else + { + $menuType = $this->getMenuType($data['menutype']); + + $data['client_id'] = $menuType->client_id; + + $table->setLocation($data['parent_id'], 'last-child'); + } + + // Bind the data. + if (!$table->bind($data)) + { + $this->setError($table->getError()); + + return false; + } + + // Alter the title & alias for save as copy. Also, unset the home record. + if (!$isNew && $data['id'] == 0) + { + list($title, $alias) = $this->generateNewTitle($table->parent_id, $table->alias, $table->title); + + $table->title = $title; + $table->alias = $alias; + $table->published = 0; + $table->home = 0; + } + + // Check the data. + if (!$table->check()) + { + $this->setError($table->getError()); + + return false; + } + + // Trigger the before save event. + $result = $dispatcher->trigger($this->event_before_save, array($context, &$table, $isNew)); + + // Store the data. + if (in_array(false, $result, true)|| !$table->store()) + { + $this->setError($table->getError()); + + return false; + } + + // Trigger the after save event. + $dispatcher->trigger($this->event_after_save, array($context, &$table, $isNew)); + + // Rebuild the tree path. + if (!$table->rebuildPath($table->id)) + { + $this->setError($table->getError()); + + return false; + } + + $this->setState('item.id', $table->id); + $this->setState('item.menutype', $table->menutype); + + // Load associated menu items, for now not supported for admin menu… may be later + if ($table->get('client_id') == 0 && JLanguageAssociations::isEnabled()) + { + // Adding self to the association + $associations = isset($data['associations']) ? $data['associations'] : array(); + + // Unset any invalid associations + $associations = Joomla\Utilities\ArrayHelper::toInteger($associations); + + foreach ($associations as $tag => $id) + { + if (!$id) + { + unset($associations[$tag]); + } + } + + // Detecting all item menus + $all_language = $table->language == '*'; + + if ($all_language && !empty($associations)) + { + JError::raiseNotice(403, JText::_('COM_MENUS_ERROR_ALL_LANGUAGE_ASSOCIATED')); + } + + // Get associationskey for edited item + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select($db->quoteName('key')) + ->from($db->quoteName('#__associations')) + ->where($db->quoteName('context') . ' = ' . $db->quote($this->associationsContext)) + ->where($db->quoteName('id') . ' = ' . (int) $table->id); + $db->setQuery($query); + $old_key = $db->loadResult(); + + // Deleting old associations for the associated items + $query = $db->getQuery(true) + ->delete($db->quoteName('#__associations')) + ->where($db->quoteName('context') . ' = ' . $db->quote($this->associationsContext)); + + if ($associations) + { + $query->where('(' . $db->quoteName('id') . ' IN (' . implode(',', $associations) . ') OR ' + . $db->quoteName('key') . ' = ' . $db->quote($old_key) . ')' + ); + } + else + { + $query->where($db->quoteName('key') . ' = ' . $db->quote($old_key)); + } + + $db->setQuery($query); + + try + { + $db->execute(); + } + catch (RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + + // Adding self to the association + if (!$all_language) + { + $associations[$table->language] = (int) $table->id; + } + + if (count($associations) > 1) + { + // Adding new association for these items + $key = md5(json_encode($associations)); + $query->clear() + ->insert('#__associations'); + + foreach ($associations as $id) + { + $query->values(((int) $id) . ',' . $db->quote($this->associationsContext) . ',' . $db->quote($key)); + } + + $db->setQuery($query); + + try + { + $db->execute(); + } + catch (RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + } + } + + // Clean the cache + $this->cleanCache(); + + if (isset($data['link'])) + { + $base = JUri::base(); + $juri = JUri::getInstance($base . $data['link']); + $option = $juri->getVar('option'); + + // Clean the cache + parent::cleanCache($option); + } + + if (Factory::getApplication()->input->get('task') == 'editAssociations') + { + return $this->redirectToAssociations($data); + } + + return true; + } + + /** + * Method to save the reordered nested set tree. + * First we save the new order values in the lft values of the changed ids. + * Then we invoke the table rebuild to implement the new ordering. + * + * @param array $idArray Rows identifiers to be reordered + * @param array $lftArray lft values of rows to be reordered + * + * @return boolean false on failure or error, true otherwise. + * + * @since 1.6 + */ + public function saveorder($idArray = null, $lftArray = null) + { + // Get an instance of the table object. + $table = $this->getTable(); + + if (!$table->saveorder($idArray, $lftArray)) + { + $this->setError($table->getError()); + + return false; + } + + // Clean the cache + $this->cleanCache(); + + return true; + } + + /** + * Method to change the home state of one or more items. + * + * @param array $pks A list of the primary keys to change. + * @param integer $value The value of the home state. + * + * @return boolean True on success. + * + * @since 1.6 + */ + public function setHome(&$pks, $value = 1) + { + $table = $this->getTable(); + $pks = (array) $pks; + + $languages = array(); + $onehome = false; + + // Remember that we can set a home page for different languages, + // so we need to loop through the primary key array. + foreach ($pks as $i => $pk) + { + if ($table->load($pk)) + { + if (!array_key_exists($table->language, $languages)) + { + $languages[$table->language] = true; + + if ($table->home == $value) + { + unset($pks[$i]); + JError::raiseNotice(403, JText::_('COM_MENUS_ERROR_ALREADY_HOME')); + } + elseif ($table->menutype == 'main') + { + // Prune items that you can't change. + unset($pks[$i]); + JError::raiseWarning(403, JText::_('COM_MENUS_ERROR_MENUTYPE_HOME')); + } + else + { + $table->home = $value; + + if ($table->language == '*') + { + $table->published = 1; + } + + if (!$this->canSave($table)) + { + // Prune items that you can't change. + unset($pks[$i]); + JError::raiseWarning(403, JText::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED')); + } + elseif (!$table->check()) + { + // Prune the items that failed pre-save checks. + unset($pks[$i]); + JError::raiseWarning(403, $table->getError()); + } + elseif (!$table->store()) + { + // Prune the items that could not be stored. + unset($pks[$i]); + JError::raiseWarning(403, $table->getError()); + } + } + } + else + { + unset($pks[$i]); + + if (!$onehome) + { + $onehome = true; + JError::raiseNotice(403, JText::sprintf('COM_MENUS_ERROR_ONE_HOME')); + } + } + } + } + + // Clean the cache + $this->cleanCache(); + + return true; + } + + /** + * Method to change the published state of one or more records. + * + * @param array $pks A list of the primary keys to change. + * @param integer $value The value of the published state. + * + * @return boolean True on success. + * + * @since 1.6 + */ + public function publish(&$pks, $value = 1) + { + $table = $this->getTable(); + $pks = (array) $pks; + + // Default menu item existence checks. + if ($value != 1) + { + foreach ($pks as $i => $pk) + { + if ($table->load($pk) && $table->home && $table->language == '*') + { + // Prune items that you can't change. + JError::raiseWarning(403, JText::_('JLIB_DATABASE_ERROR_MENU_UNPUBLISH_DEFAULT_HOME')); + unset($pks[$i]); + break; + } + } + } + + // Clean the cache + $this->cleanCache(); + + // Ensure that previous checks doesn't empty the array + if (empty($pks)) + { + return true; + } + + return parent::publish($pks, $value); + } + + /** + * Method to change the title & alias. + * + * @param integer $parentId The id of the parent. + * @param string $alias The alias. + * @param string $title The title. + * + * @return array Contains the modified title and alias. + * + * @since 1.6 + */ + protected function generateNewTitle($parentId, $alias, $title) + { + // Alter the title & alias + $table = $this->getTable(); + + while ($table->load(array('alias' => $alias, 'parent_id' => $parentId))) + { + if ($title == $table->title) + { + $title = StringHelper::increment($title); + } + + $alias = StringHelper::increment($alias, 'dash'); + } + + return array($title, $alias); + } + + /** + * Custom clean the cache + * + * @param string $group Cache group name. + * @param integer $clientId Application client id. + * + * @return void + * + * @since 1.6 + */ + protected function cleanCache($group = null, $clientId = 0) + { + parent::cleanCache('com_menus', 0); + parent::cleanCache('com_modules'); + parent::cleanCache('mod_menu', 0); + parent::cleanCache('mod_menu', 1); + } +} diff --git a/Sites/pages/administrator/components/com_menus/models/items.php b/Sites/pages/administrator/components/com_menus/models/items.php new file mode 100644 index 00000000..0c48c4c7 --- /dev/null +++ b/Sites/pages/administrator/components/com_menus/models/items.php @@ -0,0 +1,576 @@ +input->get('forcedLanguage', '', 'cmd'); + + // Adjust the context to support modal layouts. + if ($layout = $app->input->get('layout')) + { + $this->context .= '.' . $layout; + } + + // Adjust the context to support forced languages. + if ($forcedLanguage) + { + $this->context .= '.' . $forcedLanguage; + } + + $search = $this->getUserStateFromRequest($this->context . '.search', 'filter_search'); + $this->setState('filter.search', $search); + + $published = $this->getUserStateFromRequest($this->context . '.published', 'filter_published', ''); + $this->setState('filter.published', $published); + + $access = $this->getUserStateFromRequest($this->context . '.filter.access', 'filter_access'); + $this->setState('filter.access', $access); + + $parentId = $this->getUserStateFromRequest($this->context . '.filter.parent_id', 'filter_parent_id'); + $this->setState('filter.parent_id', $parentId); + + $level = $this->getUserStateFromRequest($this->context . '.filter.level', 'filter_level'); + $this->setState('filter.level', $level); + + // Watch changes in client_id and menutype and keep sync whenever needed. + $currentClientId = $app->getUserState($this->context . '.client_id', 0); + $clientId = $app->input->getInt('client_id', $currentClientId); + + // Load mod_menu.ini file when client is administrator + if ($clientId == 1) + { + JFactory::getLanguage()->load('mod_menu', JPATH_ADMINISTRATOR, null, false, true); + } + + $currentMenuType = $app->getUserState($this->context . '.menutype', ''); + $menuType = $app->input->getString('menutype', $currentMenuType); + + // If client_id changed clear menutype and reset pagination + if ($clientId != $currentClientId) + { + $menuType = ''; + + $app->input->set('limitstart', 0); + $app->input->set('menutype', ''); + } + + // If menutype changed reset pagination. + if ($menuType != $currentMenuType) + { + $app->input->set('limitstart', 0); + } + + if (!$menuType) + { + $app->setUserState($this->context . '.menutype', ''); + $this->setState('menutypetitle', ''); + $this->setState('menutypeid', ''); + } + // Special menu types, if selected explicitly, will be allowed as a filter + elseif ($menuType == 'main') + { + // Adjust client_id to match the menutype. This is safe as client_id was not changed in this request. + $app->input->set('client_id', 1); + + $app->setUserState($this->context . '.menutype', $menuType); + $this->setState('menutypetitle', ucfirst($menuType)); + $this->setState('menutypeid', -1); + } + // Get the menutype object with appropriate checks. + elseif ($cMenu = $this->getMenu($menuType, true)) + { + // Adjust client_id to match the menutype. This is safe as client_id was not changed in this request. + $app->input->set('client_id', $cMenu->client_id); + + $app->setUserState($this->context . '.menutype', $menuType); + $this->setState('menutypetitle', $cMenu->title); + $this->setState('menutypeid', $cMenu->id); + } + // This menutype does not exist, leave client id unchanged but reset menutype and pagination + else + { + $menuType = ''; + + $app->input->set('limitstart', 0); + $app->input->set('menutype', $menuType); + + $app->setUserState($this->context . '.menutype', $menuType); + $this->setState('menutypetitle', ''); + $this->setState('menutypeid', ''); + } + + // Client id filter + $clientId = (int) $this->getUserStateFromRequest($this->context . '.client_id', 'client_id', 0, 'int'); + $this->setState('filter.client_id', $clientId); + + // Use a different filter file when client is administrator + if ($clientId == 1) + { + $this->filterFormName = 'filter_itemsadmin'; + } + + $this->setState('filter.menutype', $menuType); + + $language = $this->getUserStateFromRequest($this->context . '.filter.language', 'filter_language', ''); + $this->setState('filter.language', $language); + + // Component parameters. + $params = JComponentHelper::getParams('com_menus'); + $this->setState('params', $params); + + // List state information. + parent::populateState($ordering, $direction); + + // Force a language. + if (!empty($forcedLanguage)) + { + $this->setState('filter.language', $forcedLanguage); + } + } + + /** + * Method to get a store id based on model configuration state. + * + * This is necessary because the model is used by the component and + * different modules that might need different sets of data or different + * ordering requirements. + * + * @param string $id A prefix for the store id. + * + * @return string A store id. + * + * @since 1.6 + */ + protected function getStoreId($id = '') + { + // Compile the store id. + $id .= ':' . $this->getState('filter.access'); + $id .= ':' . $this->getState('filter.published'); + $id .= ':' . $this->getState('filter.language'); + $id .= ':' . $this->getState('filter.search'); + $id .= ':' . $this->getState('filter.parent_id'); + $id .= ':' . $this->getState('filter.menutype'); + $id .= ':' . $this->getState('filter.client_id'); + + return parent::getStoreId($id); + } + + /** + * Builds an SQL query to load the list data. + * + * @return JDatabaseQuery A query object. + * + * @since 1.6 + */ + protected function getListQuery() + { + // Create a new query object. + $db = $this->getDbo(); + $query = $db->getQuery(true); + $user = JFactory::getUser(); + $app = JFactory::getApplication(); + + // Select all fields from the table. + $query->select( + $this->getState( + 'list.select', + $db->quoteName( + array( + 'a.id', 'a.menutype', 'a.title', 'a.alias', 'a.note', 'a.path', 'a.link', 'a.type', 'a.parent_id', + 'a.level', 'a.published', 'a.component_id', 'a.checked_out', 'a.checked_out_time', 'a.browserNav', + 'a.access', 'a.img', 'a.template_style_id', 'a.params', 'a.lft', 'a.rgt', 'a.home', 'a.language', 'a.client_id' + ), + array( + null, null, null, null, null, null, null, null, null, + null, 'a.published', null, null, null, null, + null, null, null, null, null, null, null, null, null + ) + ) + ) + ); + $query->select( + 'CASE ' . + ' WHEN a.type = ' . $db->quote('component') . ' THEN a.published+2*(e.enabled-1) ' . + ' WHEN a.type = ' . $db->quote('url') . ' AND a.published != -2 THEN a.published+2 ' . + ' WHEN a.type = ' . $db->quote('url') . ' AND a.published = -2 THEN a.published-1 ' . + ' WHEN a.type = ' . $db->quote('alias') . ' AND a.published != -2 THEN a.published+4 ' . + ' WHEN a.type = ' . $db->quote('alias') . ' AND a.published = -2 THEN a.published-1 ' . + ' WHEN a.type = ' . $db->quote('separator') . ' AND a.published != -2 THEN a.published+6 ' . + ' WHEN a.type = ' . $db->quote('separator') . ' AND a.published = -2 THEN a.published-1 ' . + ' WHEN a.type = ' . $db->quote('heading') . ' AND a.published != -2 THEN a.published+8 ' . + ' WHEN a.type = ' . $db->quote('heading') . ' AND a.published = -2 THEN a.published-1 ' . + ' WHEN a.type = ' . $db->quote('container') . ' AND a.published != -2 THEN a.published+8 ' . + ' WHEN a.type = ' . $db->quote('container') . ' AND a.published = -2 THEN a.published-1 ' . + ' END AS published ' + ); + $query->from($db->quoteName('#__menu') . ' AS a'); + + // Join over the language + $query->select('l.title AS language_title, l.image AS language_image, l.sef AS language_sef') + ->join('LEFT', $db->quoteName('#__languages') . ' AS l ON l.lang_code = a.language'); + + // Join over the users. + $query->select('u.name AS editor') + ->join('LEFT', $db->quoteName('#__users') . ' AS u ON u.id = a.checked_out'); + + // Join over components + $query->select('c.element AS componentname') + ->join('LEFT', $db->quoteName('#__extensions') . ' AS c ON c.extension_id = a.component_id'); + + // Join over the asset groups. + $query->select('ag.title AS access_level') + ->join('LEFT', '#__viewlevels AS ag ON ag.id = a.access'); + + // Join over the menu types. + $query->select($db->quoteName(array('mt.id', 'mt.title'), array('menutype_id', 'menutype_title'))) + ->join('LEFT', $db->quoteName('#__menu_types', 'mt') . ' ON ' . $db->qn('mt.menutype') . ' = ' . $db->qn('a.menutype')); + + // Join over the associations. + $assoc = JLanguageAssociations::isEnabled(); + + if ($assoc) + { + $subQuery = $db->getQuery(true) + ->select('COUNT(' . $db->quoteName('asso1.id') . ') > 1') + ->from($db->quoteName('#__associations', 'asso1')) + ->join('INNER', $db->quoteName('#__associations', 'asso2') . ' ON ' . $db->quoteName('asso1.key') . ' = ' . $db->quoteName('asso2.key')) + ->where( + array( + $db->quoteName('asso1.id') . ' = ' . $db->quoteName('a.id'), + $db->quoteName('asso1.context') . ' = ' . $db->quote('com_menus.item'), + ) + ); + + $query->select('(' . $subQuery . ') AS ' . $db->quoteName('association')); + } + + // Join over the extensions + $query->select('e.name AS name') + ->join('LEFT', '#__extensions AS e ON e.extension_id = a.component_id'); + + // Exclude the root category. + $query->where('a.id > 1') + ->where('a.client_id = ' . (int) $this->getState('filter.client_id')); + + // Filter on the published state. + $published = $this->getState('filter.published'); + + if (is_numeric($published)) + { + $query->where('a.published = ' . (int) $published); + } + elseif ($published === '') + { + $query->where('a.published IN (0, 1)'); + } + + // Filter by search in title, alias or id + if ($search = trim($this->getState('filter.search'))) + { + if (stripos($search, 'id:') === 0) + { + $query->where('a.id = ' . (int) substr($search, 3)); + } + elseif (stripos($search, 'link:') === 0) + { + if ($search = substr($search, 5)) + { + $search = $db->quote('%' . str_replace(' ', '%', $db->escape(trim($search), true) . '%')); + $query->where('a.link LIKE ' . $search); + } + } + else + { + $search = $db->quote('%' . str_replace(' ', '%', $db->escape(trim($search), true) . '%')); + $query->where('(' . 'a.title LIKE ' . $search . ' OR a.alias LIKE ' . $search . ' OR a.note LIKE ' . $search . ')'); + } + } + + // Filter the items over the parent id if set. + $parentId = $this->getState('filter.parent_id'); + + if (!empty($parentId)) + { + $level = $this->getState('filter.level'); + + // Create a subquery for the sub-items list + $subQuery = $db->getQuery(true) + ->select('sub.id') + ->from('#__menu as sub') + ->join('INNER', '#__menu as this ON sub.lft > this.lft AND sub.rgt < this.rgt') + ->where('this.id = ' . (int) $parentId); + + if ($level) + { + $subQuery->where('sub.level <= this.level + ' . (int) ($level - 1)); + } + + // Add the subquery to the main query + $query->where('(a.parent_id = ' . (int) $parentId . ' OR a.parent_id IN (' . (string) $subQuery . '))'); + } + + // Filter on the level. + elseif ($level = $this->getState('filter.level')) + { + $query->where('a.level <= ' . (int) $level); + } + + // Filter the items over the menu id if set. + $menuType = $this->getState('filter.menutype'); + + // A value "" means all + if ($menuType == '') + { + // Load all menu types we have manage access + $query2 = $this->getDbo()->getQuery(true) + ->select($this->getDbo()->qn(array('id', 'menutype'))) + ->from('#__menu_types') + ->where('client_id = ' . (int) $this->getState('filter.client_id')) + ->order('title'); + + // Show protected items on explicit filter only + $query->where('a.menutype != ' . $db->q('main')); + + $menuTypes = $this->getDbo()->setQuery($query2)->loadObjectList(); + + if ($menuTypes) + { + $types = array(); + + foreach ($menuTypes as $type) + { + if ($user->authorise('core.manage', 'com_menus.menu.' . (int) $type->id)) + { + $types[] = $query->q($type->menutype); + } + } + + $query->where($types ? 'a.menutype IN(' . implode(',', $types) . ')' : 0); + } + } + // Default behavior => load all items from a specific menu + elseif (strlen($menuType)) + { + $query->where('a.menutype = ' . $db->quote($menuType)); + } + // Empty menu type => error + else + { + $query->where('1 != 1'); + } + + // Filter on the access level. + if ($access = $this->getState('filter.access')) + { + $query->where('a.access = ' . (int) $access); + } + + // Implement View Level Access + if (!$user->authorise('core.admin')) + { + $groups = $user->getAuthorisedViewLevels(); + + if (!empty($groups)) + { + $query->where('a.access IN (' . implode(',', $groups) . ')'); + } + } + + // Filter on the language. + if ($language = $this->getState('filter.language')) + { + $query->where('a.language = ' . $db->quote($language)); + } + + // Add the list ordering clause. + $query->order($db->escape($this->getState('list.ordering', 'a.lft')) . ' ' . $db->escape($this->getState('list.direction', 'ASC'))); + + return $query; + } + + /** + * Method to allow derived classes to preprocess the form. + * + * @param JForm $form A JForm object. + * @param mixed $data The data expected for the form. + * @param string $group The name of the plugin group to import (defaults to "content"). + * + * @return void + * + * @since 3.2 + * @throws Exception if there is an error in the form event. + */ + protected function preprocessForm(JForm $form, $data, $group = 'content') + { + $name = $form->getName(); + + if ($name == 'com_menus.items.filter') + { + $clientId = $this->getState('filter.client_id'); + $form->setFieldAttribute('menutype', 'clientid', $clientId); + } + elseif (false !== strpos($name, 'com_menus.items.modal.')) + { + $form->removeField('client_id'); + + $clientId = $this->getState('filter.client_id'); + $form->setFieldAttribute('menutype', 'clientid', $clientId); + } + } + + /** + * Get the client id for a menu + * + * @param string $menuType The menutype identifier for the menu + * @param boolean $check Flag whether to perform check against ACL as well as existence + * + * @return integer + * + * @since 3.7.0 + */ + protected function getMenu($menuType, $check = false) + { + $query = $this->_db->getQuery(true); + + $query->select('a.*') + ->from($this->_db->qn('#__menu_types', 'a')) + ->where('menutype = ' . $this->_db->q($menuType)); + + $cMenu = $this->_db->setQuery($query)->loadObject(); + + if ($check) + { + // Check if menu type exists. + if (!$cMenu) + { + JLog::add(JText::_('COM_MENUS_ERROR_MENUTYPE_NOT_FOUND'), JLog::ERROR, 'jerror'); + + return false; + } + // Check if menu type is valid against ACL. + elseif (!JFactory::getUser()->authorise('core.manage', 'com_menus.menu.' . $cMenu->id)) + { + JLog::add(JText::_('JERROR_ALERTNOAUTHOR'), JLog::ERROR, 'jerror'); + + return false; + } + } + + return $cMenu; + } + + /** + * Method to get an array of data items. + * + * @return mixed An array of data items on success, false on failure. + * + * @since 3.0.1 + */ + public function getItems() + { + $store = $this->getStoreId(); + + if (!isset($this->cache[$store])) + { + $items = parent::getItems(); + $lang = JFactory::getLanguage(); + $client = $this->state->get('filter.client_id'); + + if ($items) + { + foreach ($items as $item) + { + if ($extension = $item->componentname) + { + $lang->load("$extension.sys", JPATH_ADMINISTRATOR, null, false, true) + || $lang->load("$extension.sys", JPATH_ADMINISTRATOR . '/components/' . $extension, null, false, true); + } + + // Translate component name + if ($client === 1) + { + $item->title = JText::_($item->title); + } + } + } + + $this->cache[$store] = $items; + } + + return $this->cache[$store]; + } +} diff --git a/Sites/pages/administrator/components/com_menus/models/menu.php b/Sites/pages/administrator/components/com_menus/models/menu.php new file mode 100644 index 00000000..18c93599 --- /dev/null +++ b/Sites/pages/administrator/components/com_menus/models/menu.php @@ -0,0 +1,386 @@ +authorise('core.delete', 'com_menus.menu.' . (int) $record->id); + } + + /** + * Method to test whether the state of a record can be edited. + * + * @param object $record A record object. + * + * @return boolean True if allowed to change the state of the record. Defaults to the permission set in the component. + * + * @since 1.6 + */ + protected function canEditState($record) + { + $user = JFactory::getUser(); + + return $user->authorise('core.edit.state', 'com_menus.menu.' . (int) $record->id); + } + + /** + * Returns a Table object, always creating it + * + * @param string $type The table type to instantiate + * @param string $prefix A prefix for the table class name. Optional. + * @param array $config Configuration array for model. Optional. + * + * @return JTable A database object + * + * @since 1.6 + */ + public function getTable($type = 'MenuType', $prefix = 'JTable', $config = array()) + { + return JTable::getInstance($type, $prefix, $config); + } + + /** + * Auto-populate the model state. + * + * Note. Calling getState in this method will result in recursion. + * + * @return void + * + * @since 1.6 + */ + protected function populateState() + { + $app = JFactory::getApplication('administrator'); + + // Load the User state. + $id = $app->input->getInt('id'); + $this->setState('menu.id', $id); + + // Load the parameters. + $params = JComponentHelper::getParams('com_menus'); + $this->setState('params', $params); + } + + /** + * Method to get a menu item. + * + * @param integer $itemId The id of the menu item to get. + * + * @return mixed Menu item data object on success, false on failure. + * + * @since 1.6 + */ + public function &getItem($itemId = null) + { + $itemId = (!empty($itemId)) ? $itemId : (int) $this->getState('menu.id'); + + // Get a menu item row instance. + $table = $this->getTable(); + + // Attempt to load the row. + $return = $table->load($itemId); + + // Check for a table object error. + if ($return === false && $table->getError()) + { + $this->setError($table->getError()); + + return false; + } + + $properties = $table->getProperties(1); + $value = ArrayHelper::toObject($properties, 'JObject'); + + return $value; + } + + /** + * Method to get the menu item form. + * + * @param array $data Data for the form. + * @param boolean $loadData True if the form is to load its own data (default case), false if not. + * + * @return JForm A JForm object on success, false on failure + * + * @since 1.6 + */ + public function getForm($data = array(), $loadData = true) + { + // Get the form. + $form = $this->loadForm('com_menus.menu', 'menu', array('control' => 'jform', 'load_data' => $loadData)); + + if (empty($form)) + { + return false; + } + + return $form; + } + + /** + * Method to get the data that should be injected in the form. + * + * @return mixed The data for the form. + * + * @since 1.6 + */ + protected function loadFormData() + { + // Check the session for previously entered form data. + $data = JFactory::getApplication()->getUserState('com_menus.edit.menu.data', array()); + + if (empty($data)) + { + $data = $this->getItem(); + } + else + { + unset($data['preset']); + } + + $this->preprocessData('com_menus.menu', $data); + + return $data; + } + + /** + * Method to validate the form data. + * + * @param JForm $form The form to validate against. + * @param array $data The data to validate. + * @param string $group The name of the field group to validate. + * + * @return array|boolean Array of filtered data if valid, false otherwise. + * + * @see JFormRule + * @see JFilterInput + * @since 3.9.23 + */ + public function validate($form, $data, $group = null) + { + if (!JFactory::getUser()->authorise('core.admin', 'com_menus')) + { + if (isset($data['rules'])) + { + unset($data['rules']); + } + } + + return parent::validate($form, $data, $group); + } + + /** + * Method to save the form data. + * + * @param array $data The form data. + * + * @return boolean True on success. + * + * @since 1.6 + */ + public function save($data) + { + $dispatcher = JEventDispatcher::getInstance(); + $id = (!empty($data['id'])) ? $data['id'] : (int) $this->getState('menu.id'); + $isNew = true; + + // Get a row instance. + $table = $this->getTable(); + + // Include the plugins for the save events. + JPluginHelper::importPlugin('content'); + + // Load the row if saving an existing item. + if ($id > 0) + { + $isNew = false; + $table->load($id); + } + + // Bind the data. + if (!$table->bind($data)) + { + $this->setError($table->getError()); + + return false; + } + + // Check the data. + if (!$table->check()) + { + $this->setError($table->getError()); + + return false; + } + + // Trigger the before event. + $result = $dispatcher->trigger('onContentBeforeSave', array($this->_context, &$table, $isNew)); + + // Store the data. + if (in_array(false, $result, true) || !$table->store()) + { + $this->setError($table->getError()); + + return false; + } + + // Trigger the after save event. + $dispatcher->trigger('onContentAfterSave', array($this->_context, &$table, $isNew)); + + $this->setState('menu.id', $table->id); + + // Clean the cache + $this->cleanCache(); + + return true; + } + + /** + * Method to delete groups. + * + * @param array $itemIds An array of item ids. + * + * @return boolean Returns true on success, false on failure. + * + * @since 1.6 + */ + public function delete($itemIds) + { + $dispatcher = JEventDispatcher::getInstance(); + + // Sanitize the ids. + $itemIds = ArrayHelper::toInteger((array) $itemIds); + + // Get a group row instance. + $table = $this->getTable(); + + // Include the plugins for the delete events. + JPluginHelper::importPlugin('content'); + + // Iterate the items to delete each one. + foreach ($itemIds as $itemId) + { + if ($table->load($itemId)) + { + // Trigger the before delete event. + $result = $dispatcher->trigger('onContentBeforeDelete', array($this->_context, $table)); + + if (in_array(false, $result, true) || !$table->delete($itemId)) + { + $this->setError($table->getError()); + + return false; + } + + // Trigger the after delete event. + $dispatcher->trigger('onContentAfterDelete', array($this->_context, $table)); + + // TODO: Delete the menu associations - Menu items and Modules + } + } + + // Clean the cache + $this->cleanCache(); + + return true; + } + + /** + * Gets a list of all mod_mainmenu modules and collates them by menutype + * + * @return array + * + * @since 1.6 + */ + public function &getModules() + { + $db = $this->getDbo(); + + $query = $db->getQuery(true) + ->from('#__modules as a') + ->select('a.id, a.title, a.params, a.position') + ->where('module = ' . $db->quote('mod_menu')) + ->select('ag.title AS access_title') + ->join('LEFT', '#__viewlevels AS ag ON ag.id = a.access'); + $db->setQuery($query); + + $modules = $db->loadObjectList(); + + $result = array(); + + foreach ($modules as &$module) + { + $params = new Registry($module->params); + + $menuType = $params->get('menutype'); + + if (!isset($result[$menuType])) + { + $result[$menuType] = array(); + } + + $result[$menuType][] = & $module; + } + + return $result; + } + + /** + * Custom clean the cache + * + * @param string $group Cache group name. + * @param integer $clientId Application client id. + * + * @return void + * + * @since 1.6 + */ + protected function cleanCache($group = null, $clientId = 0) + { + parent::cleanCache('com_menus', 0); + parent::cleanCache('com_modules'); + parent::cleanCache('mod_menu', 0); + parent::cleanCache('mod_menu', 1); + } +} diff --git a/Sites/pages/administrator/components/com_menus/models/menus.php b/Sites/pages/administrator/components/com_menus/models/menus.php new file mode 100644 index 00000000..4aee4b0f --- /dev/null +++ b/Sites/pages/administrator/components/com_menus/models/menus.php @@ -0,0 +1,245 @@ +getStoreId('getItems'); + + // Try to load the data from internal storage. + if (!empty($this->cache[$store])) + { + return $this->cache[$store]; + } + + // Load the list items. + $items = parent::getItems(); + + // If empty or an error, just return. + if (empty($items)) + { + return array(); + } + + // Getting the following metric by joins is WAY TOO SLOW. + // Faster to do three queries for very large menu trees. + + // Get the menu types of menus in the list. + $db = $this->getDbo(); + $menuTypes = ArrayHelper::getColumn((array) $items, 'menutype'); + + // Quote the strings. + $menuTypes = implode( + ',', + array_map(array($db, 'quote'), $menuTypes) + ); + + // Get the published menu counts. + $query = $db->getQuery(true) + ->select('m.menutype, COUNT(DISTINCT m.id) AS count_published') + ->from('#__menu AS m') + ->where('m.published = 1') + ->where('m.menutype IN (' . $menuTypes . ')') + ->group('m.menutype'); + + $db->setQuery($query); + + try + { + $countPublished = $db->loadAssocList('menutype', 'count_published'); + } + catch (RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + + // Get the unpublished menu counts. + $query->clear('where') + ->where('m.published = 0') + ->where('m.menutype IN (' . $menuTypes . ')'); + $db->setQuery($query); + + try + { + $countUnpublished = $db->loadAssocList('menutype', 'count_published'); + } + catch (RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + + // Get the trashed menu counts. + $query->clear('where') + ->where('m.published = -2') + ->where('m.menutype IN (' . $menuTypes . ')'); + $db->setQuery($query); + + try + { + $countTrashed = $db->loadAssocList('menutype', 'count_published'); + } + catch (RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + + // Inject the values back into the array. + foreach ($items as $item) + { + $item->count_published = isset($countPublished[$item->menutype]) ? $countPublished[$item->menutype] : 0; + $item->count_unpublished = isset($countUnpublished[$item->menutype]) ? $countUnpublished[$item->menutype] : 0; + $item->count_trashed = isset($countTrashed[$item->menutype]) ? $countTrashed[$item->menutype] : 0; + } + + // Add the items to the internal cache. + $this->cache[$store] = $items; + + return $this->cache[$store]; + } + + /** + * Method to build an SQL query to load the list data. + * + * @return string An SQL query + * + * @since 1.6 + */ + protected function getListQuery() + { + // Create a new query object. + $db = $this->getDbo(); + $query = $db->getQuery(true); + + // Select all fields from the table. + $query->select($this->getState('list.select', 'a.id, a.menutype, a.title, a.description, a.client_id')) + ->from($db->quoteName('#__menu_types') . ' AS a') + ->where('a.id > 0'); + + $query->where('a.client_id = ' . (int) $this->getState('client_id')); + + // Filter by search in title or menutype + if ($search = trim($this->getState('filter.search'))) + { + $search = $db->quote('%' . str_replace(' ', '%', $db->escape(trim($search), true) . '%')); + $query->where('(' . 'a.title LIKE ' . $search . ' OR a.menutype LIKE ' . $search . ')'); + } + + // Add the list ordering clause. + $query->order($db->escape($this->getState('list.ordering', 'a.id')) . ' ' . $db->escape($this->getState('list.direction', 'ASC'))); + + return $query; + } + + /** + * Method to auto-populate the model state. + * + * Note. Calling getState in this method will result in recursion. + * + * @param string $ordering An optional ordering field. + * @param string $direction An optional direction (asc|desc). + * + * @return void + * + * @since 1.6 + */ + protected function populateState($ordering = 'a.title', $direction = 'asc') + { + $search = $this->getUserStateFromRequest($this->context . '.search', 'filter_search'); + $this->setState('filter.search', $search); + + $clientId = (int) $this->getUserStateFromRequest($this->context . '.client_id', 'client_id', 0, 'int'); + $this->setState('client_id', $clientId); + + // List state information. + parent::populateState($ordering, $direction); + } + + /** + * Gets the extension id of the core mod_menu module. + * + * @return integer + * + * @since 2.5 + */ + public function getModMenuId() + { + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select('e.extension_id') + ->from('#__extensions AS e') + ->where('e.type = ' . $db->quote('module')) + ->where('e.element = ' . $db->quote('mod_menu')) + ->where('e.client_id = ' . (int) $this->getState('client_id')); + $db->setQuery($query); + + return $db->loadResult(); + } + + /** + * Gets a list of all mod_mainmenu modules and collates them by menutype + * + * @return array + * + * @since 1.6 + */ + public function &getModules() + { + $model = JModelLegacy::getInstance('Menu', 'MenusModel', array('ignore_request' => true)); + $result = $model->getModules(); + + return $result; + } +} diff --git a/Sites/pages/administrator/components/com_menus/models/menutypes.php b/Sites/pages/administrator/components/com_menus/models/menutypes.php new file mode 100644 index 00000000..e30cd53d --- /dev/null +++ b/Sites/pages/administrator/components/com_menus/models/menutypes.php @@ -0,0 +1,621 @@ +input->get('client_id', 0); + + $this->state->set('client_id', $clientId); + } + + /** + * Method to get the reverse lookup of the base link URL to Title + * + * @return array Array of reverse lookup of the base link URL to Title + * + * @since 1.6 + */ + public function getReverseLookup() + { + if (empty($this->rlu)) + { + $this->getTypeOptions(); + } + + return $this->rlu; + } + + /** + * Method to get the available menu item type options. + * + * @return array Array of groups with menu item types. + * + * @since 1.6 + */ + public function getTypeOptions() + { + jimport('joomla.filesystem.file'); + + $lang = JFactory::getLanguage(); + $list = array(); + + // Get the list of components. + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select('name, element AS ' . $db->quoteName('option')) + ->from('#__extensions') + ->where('type = ' . $db->quote('component')) + ->where('enabled = 1') + ->order('name ASC'); + $db->setQuery($query); + $components = $db->loadObjectList(); + + foreach ($components as $component) + { + $options = $this->getTypeOptionsByComponent($component->option); + + if ($options) + { + $list[$component->name] = $options; + + // Create the reverse lookup for link-to-name. + foreach ($options as $option) + { + if (isset($option->request)) + { + $this->addReverseLookupUrl($option); + + if (isset($option->request['option'])) + { + $componentLanguageFolder = JPATH_ADMINISTRATOR . '/components/' . $option->request['option']; + $lang->load($option->request['option'] . '.sys', JPATH_ADMINISTRATOR, null, false, true) + || $lang->load($option->request['option'] . '.sys', $componentLanguageFolder, null, false, true); + } + } + } + } + } + + // Allow a system plugin to insert dynamic menu types to the list shown in menus: + JEventDispatcher::getInstance()->trigger('onAfterGetMenuTypeOptions', array(&$list, $this)); + + return $list; + } + + /** + * Method to create the reverse lookup for link-to-name. + * (can be used from onAfterGetMenuTypeOptions handlers) + * + * @param JObject $option with request array or string and title public variables + * + * @return void + * + * @since 3.1 + */ + public function addReverseLookupUrl($option) + { + $this->rlu[MenusHelper::getLinkKey($option->request)] = $option->get('title'); + } + + /** + * Get menu types by component. + * + * @param string $component Component URL option. + * + * @return array + * + * @since 1.6 + */ + protected function getTypeOptionsByComponent($component) + { + $options = array(); + $client = JApplicationHelper::getClientInfo($this->getState('client_id')); + $mainXML = $client->path . '/components/' . $component . '/metadata.xml'; + + if (is_file($mainXML)) + { + $options = $this->getTypeOptionsFromXml($mainXML, $component); + } + + if (empty($options)) + { + $options = $this->getTypeOptionsFromMvc($component); + } + + if ($client->id == 1 && empty($options)) + { + $options = $this->getTypeOptionsFromManifest($component); + } + + return $options; + } + + /** + * Get the menu types from an XML file + * + * @param string $file File path + * @param string $component Component option as in URL + * + * @return array|boolean + * + * @since 1.6 + */ + protected function getTypeOptionsFromXml($file, $component) + { + $options = array(); + + // Attempt to load the xml file. + if (!$xml = simplexml_load_file($file)) + { + return false; + } + + // Look for the first menu node off of the root node. + if (!$menu = $xml->xpath('menu[1]')) + { + return false; + } + else + { + $menu = $menu[0]; + } + + // If we have no options to parse, just add the base component to the list of options. + if (!empty($menu['options']) && $menu['options'] == 'none') + { + // Create the menu option for the component. + $o = new JObject; + $o->title = (string) $menu['name']; + $o->description = (string) $menu['msg']; + $o->request = array('option' => $component); + + $options[] = $o; + + return $options; + } + + // Look for the first options node off of the menu node. + if (!$optionsNode = $menu->xpath('options[1]')) + { + return false; + } + else + { + $optionsNode = $optionsNode[0]; + } + + // Make sure the options node has children. + if (!$children = $optionsNode->children()) + { + return false; + } + + // Process each child as an option. + foreach ($children as $child) + { + if ($child->getName() == 'option') + { + // Create the menu option for the component. + $o = new JObject; + $o->title = (string) $child['name']; + $o->description = (string) $child['msg']; + $o->request = array('option' => $component, (string) $optionsNode['var'] => (string) $child['value']); + + $options[] = $o; + } + elseif ($child->getName() == 'default') + { + // Create the menu option for the component. + $o = new JObject; + $o->title = (string) $child['name']; + $o->description = (string) $child['msg']; + $o->request = array('option' => $component); + + $options[] = $o; + } + } + + return $options; + } + + /** + * Get menu types from MVC + * + * @param string $component Component option like in URLs + * + * @return array|boolean + * + * @since 1.6 + */ + protected function getTypeOptionsFromMvc($component) + { + $options = array(); + $client = JApplicationHelper::getClientInfo($this->getState('client_id')); + + // Get the views for this component. + if (is_dir($client->path . '/components/' . $component)) + { + $folders = JFolder::folders($client->path . '/components/' . $component, '^view[s]?$', false, true); + } + + $path = ''; + + if (!empty($folders[0])) + { + $path = $folders[0]; + } + + if (is_dir($path)) + { + $views = JFolder::folders($path); + } + else + { + return false; + } + + foreach ($views as $view) + { + // Ignore private views. + if (strpos($view, '_') !== 0) + { + // Determine if a metadata file exists for the view. + $file = $path . '/' . $view . '/metadata.xml'; + + if (is_file($file)) + { + // Attempt to load the xml file. + if ($xml = simplexml_load_file($file)) + { + // Look for the first view node off of the root node. + if ($menu = $xml->xpath('view[1]')) + { + $menu = $menu[0]; + + // If the view is hidden from the menu, discard it and move on to the next view. + if (!empty($menu['hidden']) && $menu['hidden'] == 'true') + { + unset($xml); + continue; + } + + // Do we have an options node or should we process layouts? + // Look for the first options node off of the menu node. + if ($optionsNode = $menu->xpath('options[1]')) + { + $optionsNode = $optionsNode[0]; + + // Make sure the options node has children. + if ($children = $optionsNode->children()) + { + // Process each child as an option. + foreach ($children as $child) + { + if ($child->getName() == 'option') + { + // Create the menu option for the component. + $o = new JObject; + $o->title = (string) $child['name']; + $o->description = (string) $child['msg']; + $o->request = array('option' => $component, 'view' => $view, (string) $optionsNode['var'] => (string) $child['value']); + + $options[] = $o; + } + elseif ($child->getName() == 'default') + { + // Create the menu option for the component. + $o = new JObject; + $o->title = (string) $child['name']; + $o->description = (string) $child['msg']; + $o->request = array('option' => $component, 'view' => $view); + + $options[] = $o; + } + } + } + } + else + { + $options = array_merge($options, (array) $this->getTypeOptionsFromLayouts($component, $view)); + } + } + + unset($xml); + } + } + else + { + $options = array_merge($options, (array) $this->getTypeOptionsFromLayouts($component, $view)); + } + } + } + + return $options; + } + + /** + * Get menu types from Component manifest + * + * @param string $component Component option like in URLs + * + * @return array|boolean + * + * @since 3.7.0 + */ + protected function getTypeOptionsFromManifest($component) + { + // Load the component manifest + $fileName = JPATH_ADMINISTRATOR . '/components/' . $component . '/' . str_replace('com_', '', $component) . '.xml'; + + if (!is_file($fileName)) + { + return false; + } + + if (!($manifest = simplexml_load_file($fileName))) + { + return false; + } + + // Check for a valid XML root tag. + if ($manifest->getName() != 'extension') + { + return false; + } + + $options = array(); + + // Start with the component root menu. + $rootMenu = $manifest->administration->menu; + + // If the menu item doesn't exist or is hidden do nothing. + if (!$rootMenu || in_array((string) $rootMenu['hidden'], array('true', 'hidden'))) + { + return $options; + } + + // Create the root menu option. + $ro = new stdClass; + $ro->title = (string) trim($rootMenu); + $ro->description = ''; + $ro->request = array('option' => $component); + + // Process submenu options. + $submenu = $manifest->administration->submenu; + + if (!$submenu) + { + return $options; + } + + foreach ($submenu->menu as $child) + { + $attributes = $child->attributes(); + + $o = new stdClass; + $o->title = (string) trim($child); + $o->description = ''; + + if ((string) $attributes->link) + { + parse_str((string) $attributes->link, $request); + } + else + { + $request = array(); + + $request['option'] = $component; + $request['act'] = (string) $attributes->act; + $request['task'] = (string) $attributes->task; + $request['controller'] = (string) $attributes->controller; + $request['view'] = (string) $attributes->view; + $request['layout'] = (string) $attributes->layout; + $request['sub'] = (string) $attributes->sub; + } + + $o->request = array_filter($request, 'strlen'); + $options[] = new JObject($o); + + // Do not repeat the default view link (index.php?option=com_abc). + if (count($o->request) == 1) + { + $ro = null; + } + } + + if ($ro) + { + $options[] = new JObject($ro); + } + + return $options; + } + + /** + * Get the menu types from component layouts + * + * @param string $component Component option as in URLs + * @param string $view Name of the view + * + * @return array + * + * @since 1.6 + */ + protected function getTypeOptionsFromLayouts($component, $view) + { + $options = array(); + $layouts = array(); + $layoutNames = array(); + $lang = JFactory::getLanguage(); + $path = ''; + $client = JApplicationHelper::getClientInfo($this->getState('client_id')); + + // Get the views for this component. + if (is_dir($client->path . '/components/' . $component)) + { + $folders = JFolder::folders($client->path . '/components/' . $component, '^view[s]?$', false, true); + } + + if (!empty($folders[0])) + { + $path = $folders[0] . '/' . $view . '/tmpl'; + } + + if (is_dir($path)) + { + $layouts = array_merge($layouts, JFolder::files($path, '.xml$', false, true)); + } + else + { + return $options; + } + + // Build list of standard layout names + foreach ($layouts as $layout) + { + // Ignore private layouts. + if (strpos(basename($layout), '_') === false) + { + // Get the layout name. + $layoutNames[] = basename($layout, '.xml'); + } + } + + // Get the template layouts + // TODO: This should only search one template -- the current template for this item (default of specified) + $folders = JFolder::folders($client->path . '/templates', '', false, true); + + // Array to hold association between template file names and templates + $templateName = array(); + + foreach ($folders as $folder) + { + if (is_dir($folder . '/html/' . $component . '/' . $view)) + { + $template = basename($folder); + $lang->load('tpl_' . $template . '.sys', $client->path, null, false, true) + || $lang->load('tpl_' . $template . '.sys', $client->path . '/templates/' . $template, null, false, true); + + $templateLayouts = JFolder::files($folder . '/html/' . $component . '/' . $view, '.xml$', false, true); + + foreach ($templateLayouts as $layout) + { + // Get the layout name. + $templateLayoutName = basename($layout, '.xml'); + + // Add to the list only if it is not a standard layout + if (array_search($templateLayoutName, $layoutNames) === false) + { + $layouts[] = $layout; + + // Set template name array so we can get the right template for the layout + $templateName[$layout] = basename($folder); + } + } + } + } + + // Process the found layouts. + foreach ($layouts as $layout) + { + // Ignore private layouts. + if (strpos(basename($layout), '_') === false) + { + $file = $layout; + + // Get the layout name. + $layout = basename($layout, '.xml'); + + // Create the menu option for the layout. + $o = new JObject; + $o->title = ucfirst($layout); + $o->description = ''; + $o->request = array('option' => $component, 'view' => $view); + + // Only add the layout request argument if not the default layout. + if ($layout != 'default') + { + // If the template is set, add in format template:layout so we save the template name + $o->request['layout'] = isset($templateName[$file]) ? $templateName[$file] . ':' . $layout : $layout; + } + + // Load layout metadata if it exists. + if (is_file($file)) + { + // Attempt to load the xml file. + if ($xml = simplexml_load_file($file)) + { + // Look for the first view node off of the root node. + if ($menu = $xml->xpath('layout[1]')) + { + $menu = $menu[0]; + + // If the view is hidden from the menu, discard it and move on to the next view. + if (!empty($menu['hidden']) && $menu['hidden'] == 'true') + { + unset($xml); + unset($o); + continue; + } + + // Populate the title and description if they exist. + if (!empty($menu['title'])) + { + $o->title = trim((string) $menu['title']); + } + + if (!empty($menu->message[0])) + { + $o->description = trim((string) $menu->message[0]); + } + } + } + } + + // Add the layout to the options array. + $options[] = $o; + } + } + + return $options; + } +} diff --git a/Sites/pages/administrator/components/com_menus/presets/joomla.xml b/Sites/pages/administrator/components/com_menus/presets/joomla.xml new file mode 100644 index 00000000..b775355f --- /dev/null +++ b/Sites/pages/administrator/components/com_menus/presets/joomla.xml @@ -0,0 +1,599 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Sites/pages/administrator/components/com_menus/presets/menu.xsd b/Sites/pages/administrator/components/com_menus/presets/menu.xsd new file mode 100644 index 00000000..01d4d07a --- /dev/null +++ b/Sites/pages/administrator/components/com_menus/presets/menu.xsd @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Sites/pages/administrator/components/com_menus/presets/modern.xml b/Sites/pages/administrator/components/com_menus/presets/modern.xml new file mode 100644 index 00000000..a2951cb2 --- /dev/null +++ b/Sites/pages/administrator/components/com_menus/presets/modern.xml @@ -0,0 +1,629 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Sites/pages/administrator/components/com_menus/tables/menu.php b/Sites/pages/administrator/components/com_menus/tables/menu.php new file mode 100644 index 00000000..51489163 --- /dev/null +++ b/Sites/pages/administrator/components/com_menus/tables/menu.php @@ -0,0 +1,46 @@ +getQuery(true) + ->delete($db->quoteName('#__modules_menu')) + ->where($db->quoteName('menuid') . ' = ' . $pk); + $db->setQuery($query); + $db->execute(); + } + + return $return; + } +} diff --git a/Sites/pages/administrator/components/com_menus/views/item/tmpl/edit.php b/Sites/pages/administrator/components/com_menus/views/item/tmpl/edit.php new file mode 100644 index 00000000..cb31d563 --- /dev/null +++ b/Sites/pages/administrator/components/com_menus/views/item/tmpl/edit.php @@ -0,0 +1,244 @@ + JText::_('JGLOBAL_TYPE_OR_SELECT_SOME_TAGS'))); +JHtml::_('formbehavior.chosen', 'select'); +JHtml::_('behavior.keepalive'); + +JText::script('ERROR'); +JText::script('JGLOBAL_VALIDATION_FORM_FAILED'); + +$assoc = JLanguageAssociations::isEnabled(); + +// Ajax for parent items +$script = " +jQuery(document).ready(function ($){ + $('#jform_menutype').change(function(){ + var menutype = $(this).val(); + $.ajax({ + url: 'index.php?option=com_menus&task=item.getParentItem&menutype=' + menutype, + dataType: 'json' + }).done(function(data) { + $('#jform_parent_id option').each(function() { + if ($(this).val() != '1') { + $(this).remove(); + } + }); + + $.each(data, function (i, val) { + var option = $('
    diff --git a/Sites/pages/administrator/components/com_menus/views/item/tmpl/edit.xml b/Sites/pages/administrator/components/com_menus/views/item/tmpl/edit.xml new file mode 100755 index 00000000..cd8bb713 --- /dev/null +++ b/Sites/pages/administrator/components/com_menus/views/item/tmpl/edit.xml @@ -0,0 +1,21 @@ + + + + + + + +
    + + + + + +
    +
    diff --git a/Sites/pages/administrator/components/com_menus/views/item/tmpl/edit_associations.php b/Sites/pages/administrator/components/com_menus/views/item/tmpl/edit_associations.php new file mode 100644 index 00000000..d19d8d97 --- /dev/null +++ b/Sites/pages/administrator/components/com_menus/views/item/tmpl/edit_associations.php @@ -0,0 +1,12 @@ + 'auto', 'relative' => true)); + +$script = <<<'JS' + jQuery(document).ready(function ($) { + var propagate = function () { + var $this = $(this); + var sub = $this.closest('li').find('.treeselect-sub [type="checkbox"]'); + sub.prop('checked', this.checked); + if ($this.val() == 1) + sub.each(propagate); + else + sub.attr('disabled', this.checked ? 'disabled' : null); + }; + $('.treeselect') + .on('click', '[type="checkbox"]', propagate) + .find('[type="checkbox"]:checked').each(propagate); + }); +JS; + +$style = <<<'CSS' + .checkbox-toggle { + display: none !important; + } + .checkbox-toggle[disabled] ~ .btn-hide { + opacity: 0.5; + } + .checkbox-toggle ~ .btn-show { + display: inline; + } + .checkbox-toggle ~ .btn-hide { + display: none; + } + .checkbox-toggle:checked ~ .btn-show { + display: none; + } + .checkbox-toggle:checked ~ .btn-hide { + display: inline; + } +CSS; + +JFactory::getDocument()->addScriptDeclaration($script); +JFactory::getDocument()->addStyleDeclaration($style); +?> + diff --git a/Sites/pages/administrator/components/com_menus/views/item/tmpl/edit_modules.php b/Sites/pages/administrator/components/com_menus/views/item/tmpl/edit_modules.php new file mode 100644 index 00000000..8c13e392 --- /dev/null +++ b/Sites/pages/administrator/components/com_menus/views/item/tmpl/edit_modules.php @@ -0,0 +1,181 @@ +levels as $key => $value) { + $allLevels[$value->id] = $value->title; +} + +JFactory::getDocument()->addScriptDeclaration(' + var viewLevels = ' . json_encode($allLevels) . ', + menuId = parseInt(' . (int) $this->item->id . '); + + jQuery(function($) { + var baseLink = "index.php?option=com_modules&client_id=0&task=module.edit&tmpl=component&view=module&layout=modal&id=", + iFrameAttr = "class=\"iframe jviewport-height70\""; + + $(document) + .on("click", "input:radio[id^=\'jform_toggle_modules_assigned1\']", function (event) { + $(".table tr.no").hide(); + }) + .on("click", "input:radio[id^=\'jform_toggle_modules_assigned0\']", function (event) { + $(".table tr.no").show(); + }) + .on("click", "input:radio[id^=\'jform_toggle_modules_published1\']", function (event) { + $(".table tr.unpublished").hide(); + }) + .on("click", "input:radio[id^=\'jform_toggle_modules_published0\']", function (event) { + $(".table tr.unpublished").show(); + }) + .on("click", ".module-edit-link", function () { + var link = baseLink + $(this).data("moduleId"), + iFrame = $(""); + + $("#moduleEditModal").modal() + .find(".modal-body").empty().prepend(iFrame); + }) + .on("click", "#moduleEditModal .modal-footer .btn", function () { + var target = $(this).data("target"); + + if (target) { + $("#moduleEditModal iframe").contents().find(target).click(); + } + }); + }); +'); + +JFactory::getDocument()->addStyleDeclaration(' +ul.horizontal-buttons li { + display: inline-block; + padding-right: 10%; +} +'); + +// Set up the bootstrap modal that will be used for all module editors +echo JHtml::_( + 'bootstrap.renderModal', + 'moduleEditModal', + array( + 'title' => JText::_('COM_MENUS_EDIT_MODULE_SETTINGS'), + 'backdrop' => 'static', + 'keyboard' => false, + 'closeButton' => false, + 'bodyHeight' => '70', + 'modalWidth' => '80', + 'footer' => '' + . '' + . '', + ) +); + +?> +fields = array('toggle_modules_assigned','toggle_modules_published'); + +echo JLayoutHelper::render('joomla.menu.edit_modules', $this); ?> + + + + + + + + + + + + + modules as $i => &$module) : ?> + menuid)) : ?> + except || $module->menuid < 0) : ?> + + + + + + + + published) : ?> + + + + + + + + + + + + + +
    + + + + + + + + + +
    + + + escape($module->access_title); ?> + + escape($module->position); ?> + + published) : ?> + + + + + + + + +
    diff --git a/Sites/pages/administrator/components/com_menus/views/item/tmpl/edit_options.php b/Sites/pages/administrator/components/com_menus/views/item/tmpl/edit_options.php new file mode 100644 index 00000000..13cc4211 --- /dev/null +++ b/Sites/pages/administrator/components/com_menus/views/item/tmpl/edit_options.php @@ -0,0 +1,44 @@ + + 'collapse0')); + $fieldSets = $this->form->getFieldsets('params'); + $i = 0; + + foreach ($fieldSets as $name => $fieldSet) : + if (!(($this->item->link == 'index.php?option=com_wrapper&view=wrapper') && $fieldSet->name == 'request') + && !($this->item->link == 'index.php?Itemid=' && $fieldSet->name == 'aliasoptions')) : + $label = !empty($fieldSet->label) ? $fieldSet->label : 'COM_MENUS_' . $name . '_FIELDSET_LABEL'; + echo JHtml::_('bootstrap.addSlide', 'menuOptions', JText::_($label), 'collapse' . ($i++)); + if (isset($fieldSet->description) && trim($fieldSet->description)) : + echo '

    ' . $this->escape(JText::_($fieldSet->description)) . '

    '; + endif; + ?> + form->getFieldset($name) as $field) : ?> + +
    + +
    + label; ?> +
    +
    + input; ?> +
    + +
    + + 'bottom')); + +// @deprecated 4.0 the function parameter, the inline js and the buttons are not needed since 3.7.0. +$function = JFactory::getApplication()->input->getCmd('function', 'jEditMenu_' . (int) $this->item->id); + +// Function to update input title when changed +JFactory::getDocument()->addScriptDeclaration(' + function jEditMenuModal() { + if (window.parent && document.formvalidator.isValid(document.getElementById("item-form"))) { + return window.parent.' . $this->escape($function) . '(document.getElementById("jform_title").value); + } + } +'); +?> + + + + +
    + setLayout('edit'); ?> + loadTemplate(); ?> +
    diff --git a/Sites/pages/administrator/components/com_menus/views/item/tmpl/modal_associations.php b/Sites/pages/administrator/components/com_menus/views/item/tmpl/modal_associations.php new file mode 100644 index 00000000..d19d8d97 --- /dev/null +++ b/Sites/pages/administrator/components/com_menus/views/item/tmpl/modal_associations.php @@ -0,0 +1,12 @@ + + 'collapse0')); + $fieldSets = $this->form->getFieldsets('params'); + $i = 0; + + foreach ($fieldSets as $name => $fieldSet) : + if (!(($this->item->link == 'index.php?option=com_wrapper&view=wrapper') && $fieldSet->name == 'request') + && !($this->item->link == 'index.php?Itemid=' && $fieldSet->name == 'aliasoptions')) : + $label = !empty($fieldSet->label) ? $fieldSet->label : 'COM_MENUS_' . $name . '_FIELDSET_LABEL'; + echo JHtml::_('bootstrap.addSlide', 'menuOptions', JText::_($label), 'collapse' . ($i++)); + if (isset($fieldSet->description) && trim($fieldSet->description)) : + echo '

    ' . $this->escape(JText::_($fieldSet->description)) . '

    '; + endif; + ?> + form->getFieldset($name) as $field) : ?> + +
    + +
    + label; ?> +
    +
    + input; ?> +
    + +
    + +state = $this->get('State'); + $this->form = $this->get('Form'); + $this->item = $this->get('Item'); + $this->modules = $this->get('Modules'); + $this->levels = $this->get('ViewLevels'); + $this->canDo = JHelperContent::getActions('com_menus', 'menu', (int) $this->state->get('item.menutypeid')); + + // Check if we're allowed to edit this item + // No need to check for create, because then the moduletype select is empty + if (!empty($this->item->id) && !$this->canDo->get('core.edit')) + { + throw new Exception(JText::_('JERROR_ALERTNOAUTHOR'), 403); + } + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + JError::raiseError(500, implode("\n", $errors)); + + return; + } + + // If we are forcing a language in modal (used for associations). + if ($this->getLayout() === 'modal' && $forcedLanguage = JFactory::getApplication()->input->get('forcedLanguage', '', 'cmd')) + { + // Set the language field to the forcedLanguage and disable changing it. + $this->form->setValue('language', null, $forcedLanguage); + $this->form->setFieldAttribute('language', 'readonly', 'true'); + + // Only allow to select categories with All language or with the forced language. + $this->form->setFieldAttribute('parent_id', 'language', '*,' . $forcedLanguage); + } + + parent::display($tpl); + $this->addToolbar(); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + $input = JFactory::getApplication()->input; + $input->set('hidemainmenu', true); + + $user = JFactory::getUser(); + $isNew = ($this->item->id == 0); + $checkedOut = !($this->item->checked_out == 0 || $this->item->checked_out == $user->get('id')); + $canDo = $this->canDo; + $clientId = $this->state->get('item.client_id', 0); + + JToolbarHelper::title(JText::_($isNew ? 'COM_MENUS_VIEW_NEW_ITEM_TITLE' : 'COM_MENUS_VIEW_EDIT_ITEM_TITLE'), 'list menu-add'); + + // If a new item, can save the item. Allow users with edit permissions to apply changes to prevent returning to grid. + if ($isNew && $canDo->get('core.create')) + { + if ($canDo->get('core.edit')) + { + JToolbarHelper::apply('item.apply'); + } + + JToolbarHelper::save('item.save'); + } + + // If not checked out, can save the item. + if (!$isNew && !$checkedOut && $canDo->get('core.edit')) + { + JToolbarHelper::apply('item.apply'); + JToolbarHelper::save('item.save'); + } + + // If the user can create new items, allow them to see Save & New + if ($canDo->get('core.create')) + { + JToolbarHelper::save2new('item.save2new'); + } + + // If an existing item, can save to a copy only if we have create rights. + if (!$isNew && $canDo->get('core.create')) + { + JToolbarHelper::save2copy('item.save2copy'); + } + + if (!$isNew && JLanguageAssociations::isEnabled() && JComponentHelper::isEnabled('com_associations') && $clientId != 1) + { + JToolbarHelper::custom('item.editAssociations', 'contract', 'contract', 'JTOOLBAR_ASSOCIATIONS', false, false); + } + + if ($isNew) + { + JToolbarHelper::cancel('item.cancel'); + } + else + { + JToolbarHelper::cancel('item.cancel', 'JTOOLBAR_CLOSE'); + } + + JToolbarHelper::divider(); + + // Get the help information for the menu item. + $lang = JFactory::getLanguage(); + + $help = $this->get('Help'); + + if ($lang->hasKey($help->url)) + { + $debug = $lang->setDebug(false); + $url = JText::_($help->url); + $lang->setDebug($debug); + } + else + { + $url = $help->url; + } + + JToolbarHelper::help($help->key, $help->local, $url); + } +} diff --git a/Sites/pages/administrator/components/com_menus/views/items/tmpl/default.php b/Sites/pages/administrator/components/com_menus/views/items/tmpl/default.php new file mode 100644 index 00000000..83a14fa0 --- /dev/null +++ b/Sites/pages/administrator/components/com_menus/views/items/tmpl/default.php @@ -0,0 +1,281 @@ +get('id'); +$listOrder = $this->escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$ordering = ($listOrder == 'a.lft'); +$saveOrder = ($listOrder == 'a.lft' && strtolower($listDirn) == 'asc'); +$menuType = (string) $app->getUserState('com_menus.items.menutype', '', 'string'); + +if ($saveOrder && $menuType) +{ + $saveOrderingUrl = 'index.php?option=com_menus&task=items.saveOrderAjax&tmpl=component'; + JHtml::_('sortablelist.sortable', 'itemList', 'adminForm', strtolower($listDirn), $saveOrderingUrl, false, true); +} + +$assoc = JLanguageAssociations::isEnabled() && $this->state->get('filter.client_id') == 0; +$colSpan = $assoc ? 10 : 9; + +if ($menuType == '') +{ + $colSpan--; +} +?> + +
    +sidebar)) : ?> +
    + sidebar; ?> +
    +
    + +
    + + $this, 'options' => array('selectorFieldName' => 'menutype'))); ?> + items)) : ?> +
    + +
    + + + + + + + + + + + + state->get('filter.client_id') == 0) : ?> + + + state->get('filter.client_id') == 0) : ?> + + + + + + state->get('filter.client_id') == 0) : ?> + + + + + + + + + + + + + items as $i => $item) : + $orderkey = array_search($item->id, $this->ordering[$item->parent_id]); + $canCreate = $user->authorise('core.create', 'com_menus.menu.' . $item->menutype_id); + $canEdit = $user->authorise('core.edit', 'com_menus.menu.' . $item->menutype_id); + $canCheckin = $user->authorise('core.manage', 'com_checkin') || $item->checked_out == $user->get('id')|| $item->checked_out == 0; + $canChange = $user->authorise('core.edit.state', 'com_menus.menu.' . $item->menutype_id) && $canCheckin; + + // Get the parents of item for sorting + if ($item->level > 1) + { + $parentsStr = ''; + $_currentParentId = $item->parent_id; + $parentsStr = ' ' . $_currentParentId; + + for ($j = 0; $j < $item->level; $j++) + { + foreach ($this->ordering as $k => $v) + { + $v = implode('-', $v); + $v = '-' . $v . '-'; + + if (strpos($v, '-' . $_currentParentId . '-') !== false) + { + $parentsStr .= ' ' . $k; + $_currentParentId = $k; + break; + } + } + } + } + else + { + $parentsStr = ''; + } + ?> + + + + + + + + + state->get('filter.client_id') == 0) : ?> + + + state->get('filter.client_id') == 0) : ?> + + + + + + state->get('filter.client_id') == 0) : ?> + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    + pagination->getListFooter(); ?> +
    + + + + + + + + + id); ?> + + protected ? 3 : $item->published; + echo JHtml::_('MenusHtml.Menus.state', $published, $i, $canChange && !$item->protected, 'cb'); ?> + + $item->level)); ?> + + checked_out) : ?> + editor, $item->checked_out_time, 'items.', $canCheckin); ?> + + protected) : ?> + + escape($item->title); ?> + + escape($item->title); ?> + + + type != 'url') : ?> + note)) : ?> + escape($item->alias)); ?> + + escape($item->alias), $this->escape($item->note)); ?> + + type == 'url' && $item->note) : ?> + escape($item->note)); ?> + + + params); ?> +
    + + + escape($item->item_type); ?> +
    +
    + escape($item->menutype_title ?: ucwords($item->menutype)); ?> + + type == 'component') : ?> + language == '*' || $item->home == '0') : ?> + home, $i, 'items.', ($item->language != '*' || !$item->home) && $canChange && !$item->protected); ?> + + + language_image) : ?> + language_image . '.gif', $item->language_title, array('title' => JText::sprintf('COM_MENUS_GRID_UNSET_LANGUAGE', $item->language_title)), true); ?> + + language_sef; ?> + + + + language_image) : ?> + language_image . '.gif', $item->language_title, array('title' => $item->language_title), true); ?> + + language_sef; ?> + + + + + escape($item->access_level); ?> + + association) : ?> + id); ?> + + + + + + id; ?> + +
    + + authorise('core.create', 'com_menus') || $user->authorise('core.edit', 'com_menus')) : ?> + JText::_('COM_MENUS_BATCH_OPTIONS'), + 'footer' => $this->loadTemplate('batch_footer') + ), + $this->loadTemplate('batch_body') + ); ?> + + + + + + +
    + diff --git a/Sites/pages/administrator/components/com_menus/views/items/tmpl/default.xml b/Sites/pages/administrator/components/com_menus/views/items/tmpl/default.xml new file mode 100755 index 00000000..f584706c --- /dev/null +++ b/Sites/pages/administrator/components/com_menus/views/items/tmpl/default.xml @@ -0,0 +1,21 @@ + + + + + + + +
    + + + + + +
    +
    diff --git a/Sites/pages/administrator/components/com_menus/views/items/tmpl/default_batch_body.php b/Sites/pages/administrator/components/com_menus/views/items/tmpl/default_batch_body.php new file mode 100644 index 00000000..433cb6e2 --- /dev/null +++ b/Sites/pages/administrator/components/com_menus/views/items/tmpl/default_batch_body.php @@ -0,0 +1,90 @@ +state->get('filter.published'); +$clientId = (int) $this->state->get('filter.client_id'); +$menuType = JFactory::getApplication()->getUserState('com_menus.items.menutype'); +if ($clientId == 1) : + JFactory::getDocument()->addScriptDeclaration( + ' + jQuery(document).ready(function($){ + if ($("#batch-menu-id").length){var batchSelector = $("#batch-menu-id");} + if ($("#batch-copy-move").length) { + $("#batch-copy-move").hide(); + batchSelector.on("change", function(){ + if (batchSelector.val() != 0 || batchSelector.val() != "") { + $("#batch-copy-move").show(); + } else { + $("#batch-copy-move").hide(); + } + }); + } + }); + ' + ); +endif; + +?> +
    + + +
    +
    +
    + +
    +
    +
    +
    + +
    +
    +
    + +
    + = 0) : ?> +
    + +
    + +
    +
    +
    + + +
    + + + +

    + +
    + +
    +

    +
    + +
    diff --git a/Sites/pages/administrator/components/com_menus/views/items/tmpl/default_batch_footer.php b/Sites/pages/administrator/components/com_menus/views/items/tmpl/default_batch_footer.php new file mode 100644 index 00000000..24857af9 --- /dev/null +++ b/Sites/pages/administrator/components/com_menus/views/items/tmpl/default_batch_footer.php @@ -0,0 +1,21 @@ +state->get('filter.published'); +$clientId = $this->state->get('filter.client_id'); +$menuType = JFactory::getApplication()->getUserState('com_menus.items.menutype'); +?> + + 0 && $clientId == 1)): ?> + + diff --git a/Sites/pages/administrator/components/com_menus/views/items/tmpl/modal.php b/Sites/pages/administrator/components/com_menus/views/items/tmpl/modal.php new file mode 100644 index 00000000..21a0c680 --- /dev/null +++ b/Sites/pages/administrator/components/com_menus/views/items/tmpl/modal.php @@ -0,0 +1,182 @@ +isClient('site')) +{ + JSession::checkToken('get') or die(JText::_('JINVALID_TOKEN')); +} + +JHtml::addIncludePath(JPATH_COMPONENT_ADMINISTRATOR . '/helpers/html'); + +JHtml::_('behavior.core'); +JHtml::_('behavior.polyfill', array('event'), 'lt IE 9'); +JHtml::_('script', 'com_menus/admin-items-modal.min.js', array('version' => 'auto', 'relative' => true)); +JHtml::_('bootstrap.tooltip', '.hasTooltip', array('placement' => 'bottom')); +JHtml::_('bootstrap.popover', '.hasPopover', array('placement' => 'bottom')); +JHtml::_('formbehavior.chosen', 'select'); + +// Special case for the search field tooltip. +$searchFilterDesc = $this->filterForm->getFieldAttribute('search', 'description', null, 'filter'); +JHtml::_('bootstrap.tooltip', '#filter_search', array('title' => JText::_($searchFilterDesc), 'placement' => 'bottom')); + +$function = $app->input->get('function', 'jSelectMenuItem', 'cmd'); +$editor = $app->input->getCmd('editor', ''); +$listOrder = $this->escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$link = 'index.php?option=com_menus&view=items&layout=modal&tmpl=component&' . JSession::getFormToken() . '=1'; + +if (!empty($editor)) +{ + // This view is used also in com_menus. Load the xtd script only if the editor is set! + JFactory::getDocument()->addScriptOptions('xtd-menus', array('editor' => $editor)); + $onclick = "jSelectMenuItem"; + $link = 'index.php?option=com_menus&view=items&layout=modal&tmpl=component&editor=' . $editor . '&' . JSession::getFormToken() . '=1'; +} +?> +
    + +
    + + $this, 'options' => array('selectorFieldName' => 'menutype'))); ?> + + items)) : ?> +
    + +
    + + + + + + + + + + + + + + + + + + + + items as $i => $item) : ?> + type, array('separator', 'heading', 'alias', 'url', 'container')); ?> + language && JLanguageMultilang::isEnabled()) + { + if ($item->language !== '*') + { + $language = $item->language; + } + else + { + $language = ''; + } + } + elseif (!JLanguageMultilang::isEnabled()) + { + $language = ''; + } + ?> + + + + + + + + + + + +
    + + + + + + + + + + + + + +
    + pagination->getListFooter(); ?> +
    + published, $i, 0); ?> + + $item->level)); ?> + + + + escape($item->title); ?> + + + escape($item->title); ?> + + + note)) : ?> + escape($item->alias)); ?> + + escape($item->alias), $this->escape($item->note)); ?> + + +
    + + + escape($item->item_type); ?> +
    +
    + escape($item->menutype_title); ?> + + type == 'component') : ?> + language == '*' || $item->home == '0') : ?> + home, $i, 'items.', ($item->language != '*' || !$item->home) && 0); ?> + + language_image) : ?> + language_image . '.gif', $item->language_title, array('title' => $item->language_title), true); ?> + + language_sef; ?> + + + + + escape($item->access_level); ?> + + language == '') : ?> + + language == '*') : ?> + + + + + + + id; ?> + +
    + + + + + + + + +
    +
    diff --git a/Sites/pages/administrator/components/com_menus/views/items/view.html.php b/Sites/pages/administrator/components/com_menus/views/items/view.html.php new file mode 100644 index 00000000..9b5a07ce --- /dev/null +++ b/Sites/pages/administrator/components/com_menus/views/items/view.html.php @@ -0,0 +1,383 @@ +items = $this->get('Items'); + $this->pagination = $this->get('Pagination'); + $this->total = $this->get('Total'); + $this->state = $this->get('State'); + $this->filterForm = $this->get('FilterForm'); + $this->activeFilters = $this->get('ActiveFilters'); + + // We don't need toolbar in the modal window. + if ($this->getLayout() !== 'modal') + { + MenusHelper::addSubmenu('items'); + } + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + $this->ordering = array(); + + // Preprocess the list of items to find ordering divisions. + foreach ($this->items as $item) + { + $this->ordering[$item->parent_id][] = $item->id; + + // Item type text + switch ($item->type) + { + case 'url': + $value = JText::_('COM_MENUS_TYPE_EXTERNAL_URL'); + break; + + case 'alias': + $value = JText::_('COM_MENUS_TYPE_ALIAS'); + break; + + case 'separator': + $value = JText::_('COM_MENUS_TYPE_SEPARATOR'); + break; + + case 'heading': + $value = JText::_('COM_MENUS_TYPE_HEADING'); + break; + + case 'container': + $value = JText::_('COM_MENUS_TYPE_CONTAINER'); + break; + + case 'component': + default: + // Load language + $lang->load($item->componentname . '.sys', JPATH_ADMINISTRATOR, null, false, true) + || $lang->load($item->componentname . '.sys', JPATH_ADMINISTRATOR . '/components/' . $item->componentname, null, false, true); + + if (!empty($item->componentname)) + { + $titleParts = array(); + $titleParts[] = JText::_($item->componentname); + $vars = null; + + parse_str($item->link, $vars); + + if (isset($vars['view'])) + { + // Attempt to load the view xml file. + $file = JPATH_SITE . '/components/' . $item->componentname . '/views/' . $vars['view'] . '/metadata.xml'; + + if (!is_file($file)) + { + $file = JPATH_SITE . '/components/' . $item->componentname . '/view/' . $vars['view'] . '/metadata.xml'; + } + + if (is_file($file) && $xml = simplexml_load_file($file)) + { + // Look for the first view node off of the root node. + if ($view = $xml->xpath('view[1]')) + { + // Add view title if present. + if (!empty($view[0]['title'])) + { + $viewTitle = trim((string) $view[0]['title']); + + // Check if the key is valid. Needed due to B/C so we don't show untranslated keys. This check should be removed with Joomla 4. + if ($lang->hasKey($viewTitle)) + { + $titleParts[] = JText::_($viewTitle); + } + } + } + } + + $vars['layout'] = isset($vars['layout']) ? $vars['layout'] : 'default'; + + // Attempt to load the layout xml file. + // If Alternative Menu Item, get template folder for layout file + if (strpos($vars['layout'], ':') > 0) + { + // Use template folder for layout file + $temp = explode(':', $vars['layout']); + $file = JPATH_SITE . '/templates/' . $temp[0] . '/html/' . $item->componentname . '/' . $vars['view'] . '/' . $temp[1] . '.xml'; + + // Load template language file + $lang->load('tpl_' . $temp[0] . '.sys', JPATH_SITE, null, false, true) + || $lang->load('tpl_' . $temp[0] . '.sys', JPATH_SITE . '/templates/' . $temp[0], null, false, true); + } + else + { + // Get XML file from component folder for standard layouts + $file = JPATH_SITE . '/components/' . $item->componentname . '/views/' . $vars['view'] . '/tmpl/' . $vars['layout'] . '.xml'; + + if (!file_exists($file)) + { + $file = JPATH_SITE . '/components/' . $item->componentname . '/view/' . $vars['view'] . '/tmpl/' . $vars['layout'] . '.xml'; + } + } + + if (is_file($file) && $xml = simplexml_load_file($file)) + { + // Look for the first view node off of the root node. + if ($layout = $xml->xpath('layout[1]')) + { + if (!empty($layout[0]['title'])) + { + $titleParts[] = JText::_(trim((string) $layout[0]['title'])); + } + } + + if (!empty($layout[0]->message[0])) + { + $item->item_type_desc = JText::_(trim((string) $layout[0]->message[0])); + } + } + + unset($xml); + + // Special case if neither a view nor layout title is found + if (count($titleParts) == 1) + { + $titleParts[] = $vars['view']; + } + } + + $value = implode(' » ', $titleParts); + } + else + { + if (preg_match("/^index.php\?option=([a-zA-Z\-0-9_]*)/", $item->link, $result)) + { + $value = JText::sprintf('COM_MENUS_TYPE_UNEXISTING', $result[1]); + } + else + { + $value = JText::_('COM_MENUS_TYPE_UNKNOWN'); + } + } + break; + } + + $item->item_type = $value; + $item->protected = $item->menutype == 'main'; + } + + // Levels filter. + $options = array(); + $options[] = JHtml::_('select.option', '1', JText::_('J1')); + $options[] = JHtml::_('select.option', '2', JText::_('J2')); + $options[] = JHtml::_('select.option', '3', JText::_('J3')); + $options[] = JHtml::_('select.option', '4', JText::_('J4')); + $options[] = JHtml::_('select.option', '5', JText::_('J5')); + $options[] = JHtml::_('select.option', '6', JText::_('J6')); + $options[] = JHtml::_('select.option', '7', JText::_('J7')); + $options[] = JHtml::_('select.option', '8', JText::_('J8')); + $options[] = JHtml::_('select.option', '9', JText::_('J9')); + $options[] = JHtml::_('select.option', '10', JText::_('J10')); + + $this->f_levels = $options; + + // We don't need toolbar in the modal window. + if ($this->getLayout() !== 'modal') + { + $this->addToolbar(); + $this->sidebar = JHtmlSidebar::render(); + } + else + { + // In menu associations modal we need to remove language filter if forcing a language. + if ($forcedLanguage = JFactory::getApplication()->input->get('forcedLanguage', '', 'CMD')) + { + // If the language is forced we can't allow to select the language, so transform the language selector filter into a hidden field. + $languageXml = new SimpleXMLElement(''); + $this->filterForm->setField($languageXml, 'filter', true); + + // Also, unset the active language filter so the search tools is not open by default with this filter. + unset($this->activeFilters['language']); + } + } + + // Allow a system plugin to insert dynamic menu types to the list shown in menus: + JEventDispatcher::getInstance()->trigger('onBeforeRenderMenuItems', array($this)); + + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + $menutypeId = (int) $this->state->get('menutypeid'); + + $canDo = JHelperContent::getActions('com_menus', 'menu', (int) $menutypeId); + $user = JFactory::getUser(); + + // Get the menu title + $menuTypeTitle = $this->get('State')->get('menutypetitle'); + + // Get the toolbar object instance + $bar = JToolbar::getInstance('toolbar'); + + if ($menuTypeTitle) + { + JToolbarHelper::title(JText::sprintf('COM_MENUS_VIEW_ITEMS_MENU_TITLE', $menuTypeTitle), 'list menumgr'); + } + else + { + JToolbarHelper::title(JText::_('COM_MENUS_VIEW_ITEMS_ALL_TITLE'), 'list menumgr'); + } + + if ($canDo->get('core.create')) + { + JToolbarHelper::addNew('item.add'); + } + + $protected = $this->state->get('filter.menutype') == 'main'; + + if ($canDo->get('core.edit') && !$protected) + { + JToolbarHelper::editList('item.edit'); + } + + if ($canDo->get('core.edit.state') && !$protected) + { + JToolbarHelper::publish('items.publish', 'JTOOLBAR_PUBLISH', true); + JToolbarHelper::unpublish('items.unpublish', 'JTOOLBAR_UNPUBLISH', true); + } + + if (JFactory::getUser()->authorise('core.admin') && !$protected) + { + JToolbarHelper::checkin('items.checkin', 'JTOOLBAR_CHECKIN', true); + } + + if ($canDo->get('core.edit.state') && $this->state->get('filter.client_id') == 0) + { + JToolbarHelper::makeDefault('items.setDefault', 'COM_MENUS_TOOLBAR_SET_HOME'); + } + + if (JFactory::getUser()->authorise('core.admin')) + { + JToolbarHelper::custom('items.rebuild', 'refresh.png', 'refresh_f2.png', 'JToolbar_Rebuild', false); + } + + // Add a batch button + if (!$protected && $user->authorise('core.create', 'com_menus') + && $user->authorise('core.edit', 'com_menus') + && $user->authorise('core.edit.state', 'com_menus')) + { + $title = JText::_('JTOOLBAR_BATCH'); + + // Instantiate a new JLayoutFile instance and render the batch button + $layout = new JLayoutFile('joomla.toolbar.batch'); + + $dhtml = $layout->render(array('title' => $title)); + $bar->appendButton('Custom', $dhtml, 'batch'); + } + + if (!$protected && $this->state->get('filter.published') == -2 && $canDo->get('core.delete')) + { + JToolbarHelper::deleteList('JGLOBAL_CONFIRM_DELETE', 'items.delete', 'JTOOLBAR_EMPTY_TRASH'); + } + elseif (!$protected && $canDo->get('core.edit.state')) + { + JToolbarHelper::trash('items.trash'); + } + + if ($canDo->get('core.admin') || $canDo->get('core.options')) + { + JToolbarHelper::divider(); + JToolbarHelper::preferences('com_menus'); + } + + JToolbarHelper::help('JHELP_MENUS_MENU_ITEM_MANAGER'); + } + + /** + * Returns an array of fields the table can be sorted by + * + * @return array Array containing the field name to sort by as the key and display text as value + * + * @since 3.0 + */ + protected function getSortFields() + { + $this->state = $this->get('State'); + + if ($this->state->get('filter.client_id') == 0) + { + return array( + 'a.lft' => JText::_('JGRID_HEADING_ORDERING'), + 'a.published' => JText::_('JSTATUS'), + 'a.title' => JText::_('JGLOBAL_TITLE'), + 'a.home' => JText::_('COM_MENUS_HEADING_HOME'), + 'a.access' => JText::_('JGRID_HEADING_ACCESS'), + 'association' => JText::_('COM_MENUS_HEADING_ASSOCIATION'), + 'language' => JText::_('JGRID_HEADING_LANGUAGE'), + 'a.id' => JText::_('JGRID_HEADING_ID') + ); + } + else + { + return array( + 'a.lft' => JText::_('JGRID_HEADING_ORDERING'), + 'a.published' => JText::_('JSTATUS'), + 'a.title' => JText::_('JGLOBAL_TITLE'), + 'a.id' => JText::_('JGRID_HEADING_ID') + ); + } + } +} diff --git a/Sites/pages/administrator/components/com_menus/views/menu/tmpl/edit.php b/Sites/pages/administrator/components/com_menus/views/menu/tmpl/edit.php new file mode 100644 index 00000000..7bede2c3 --- /dev/null +++ b/Sites/pages/administrator/components/com_menus/views/menu/tmpl/edit.php @@ -0,0 +1,64 @@ +addScriptDeclaration(" + Joomla.submitbutton = function(task) + { + var form = document.getElementById('item-form'); + if (task == 'menu.cancel' || document.formvalidator.isValid(form)) + { + Joomla.submitform(task, form); + } + }; +"); +?> +
    + + + +
    + 'details')); ?> + + + + form->renderField('menutype'); + + echo $this->form->renderField('description'); + + echo $this->form->renderField('client_id'); + + echo $this->form->renderField('preset'); + ?> + + + + canDo->get('core.admin')) : ?> + + form->getInput('rules'); ?> + + + + + + + +
    +
    diff --git a/Sites/pages/administrator/components/com_menus/views/menu/tmpl/edit.xml b/Sites/pages/administrator/components/com_menus/views/menu/tmpl/edit.xml new file mode 100755 index 00000000..9765a0da --- /dev/null +++ b/Sites/pages/administrator/components/com_menus/views/menu/tmpl/edit.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/Sites/pages/administrator/components/com_menus/views/menu/view.html.php b/Sites/pages/administrator/components/com_menus/views/menu/view.html.php new file mode 100644 index 00000000..0f7afa9e --- /dev/null +++ b/Sites/pages/administrator/components/com_menus/views/menu/view.html.php @@ -0,0 +1,119 @@ +form = $this->get('Form'); + $this->item = $this->get('Item'); + $this->state = $this->get('State'); + + $this->canDo = JHelperContent::getActions('com_menus', 'menu', $this->item->id); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + parent::display($tpl); + $this->addToolbar(); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + $input = JFactory::getApplication()->input; + $input->set('hidemainmenu', true); + + $isNew = ($this->item->id == 0); + + JToolbarHelper::title(JText::_($isNew ? 'COM_MENUS_VIEW_NEW_MENU_TITLE' : 'COM_MENUS_VIEW_EDIT_MENU_TITLE'), 'list menu'); + + // If a new item, can save the item. Allow users with edit permissions to apply changes to prevent returning to grid. + if ($isNew && $this->canDo->get('core.create')) + { + if ($this->canDo->get('core.edit')) + { + JToolbarHelper::apply('menu.apply'); + } + + JToolbarHelper::save('menu.save'); + } + + // If user can edit, can save the item. + if (!$isNew && $this->canDo->get('core.edit')) + { + JToolbarHelper::apply('menu.apply'); + JToolbarHelper::save('menu.save'); + } + + // If the user can create new items, allow them to see Save & New + if ($this->canDo->get('core.create')) + { + JToolbarHelper::save2new('menu.save2new'); + } + + if ($isNew) + { + JToolbarHelper::cancel('menu.cancel'); + } + else + { + JToolbarHelper::cancel('menu.cancel', 'JTOOLBAR_CLOSE'); + } + + JToolbarHelper::divider(); + JToolbarHelper::help('JHELP_MENUS_MENU_MANAGER_EDIT'); + } +} diff --git a/Sites/pages/administrator/components/com_menus/views/menu/view.xml.php b/Sites/pages/administrator/components/com_menus/views/menu/view.xml.php new file mode 100644 index 00000000..baff2fbd --- /dev/null +++ b/Sites/pages/administrator/components/com_menus/views/menu/view.xml.php @@ -0,0 +1,170 @@ +input->getCmd('menutype'); + + if ($menutype) + { + $items = MenusHelper::getMenuItems($menutype, true); + } + + if (empty($items)) + { + JLog::add(JText::_('COM_MENUS_SELECT_MENU_FIRST_EXPORT'), JLog::WARNING, 'jerror'); + + $app->redirect(JRoute::_('index.php?option=com_menus&view=menus', false)); + + return; + } + + $this->items = MenuHelper::createLevels($items); + + $xml = new SimpleXMLElement('' + ); + + foreach ($this->items as $item) + { + $this->addXmlChild($xml, $item); + } + + if (headers_sent($file, $line)) + { + JLog::add("Headers already sent at $file:$line.", JLog::ERROR, 'jerror'); + + return; + } + + header('content-type: application/xml'); + header('content-disposition: attachment; filename="' . $menutype . '.xml"'); + header("Cache-Control: no-cache, must-revalidate"); + header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); + header('Pragma: private'); + + $dom = new DOMDocument; + $dom->preserveWhiteSpace = true; + $dom->formatOutput = true; + $dom->loadXML($xml->asXML()); + + echo $dom->saveXML(); + + $app->close(); + } + + /** + * Add a child node to the xml + * + * @param SimpleXMLElement $xml The current XML node which would become the parent to the new node + * @param stdClass $item The menuitem object to create the child XML node from + * + * @return void + * + * @since 3.8.0 + */ + protected function addXmlChild($xml, $item) + { + $node = $xml->addChild('menuitem'); + + $node['type'] = $item->type; + + if ($item->title) + { + $node['title'] = $item->title; + } + + if ($item->link) + { + $node['link'] = $item->link; + } + + if ($item->element) + { + $node['element'] = $item->element; + } + + if ($item->class) + { + $node['class'] = $item->class; + } + + if ($item->access) + { + $node['access'] = $item->access; + } + + if ($item->browserNav) + { + $node['target'] = '_blank'; + } + + if (count($item->params)) + { + $hideitems = $item->params->get('hideitems'); + + if (count($hideitems)) + { + $db = JFactory::getDbo(); + $query = $db->getQuery(true); + + $query->select('e.element')->from('#__extensions e') + ->join('inner', '#__menu m ON m.component_id = e.extension_id') + ->where('m.id IN (' . implode(', ', $db->quote($hideitems)) . ')'); + + $hideitems = $db->setQuery($query)->loadColumn(); + + $item->params->set('hideitems', $hideitems); + } + + $node->addChild('params', (string) $item->params); + } + + foreach ($item->submenu as $sub) + { + $this->addXmlChild($node, $sub); + } + } +} diff --git a/Sites/pages/administrator/components/com_menus/views/menus/tmpl/default.php b/Sites/pages/administrator/components/com_menus/views/menus/tmpl/default.php new file mode 100644 index 00000000..bfad4ccb --- /dev/null +++ b/Sites/pages/administrator/components/com_menus/views/menus/tmpl/default.php @@ -0,0 +1,256 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$modMenuId = (int) $this->get('ModMenuId'); + +$script = array(); +$script[] = 'jQuery(document).ready(function() {'; + +foreach ($this->items as $item) : + if ($user->authorise('core.edit', 'com_menus')) : + $script[] = ' function jSelectPosition_' . $item->id . '(name) {'; + $script[] = ' document.getElementById("' . $item->id . '").value = name;'; + $script[] = ' jQuery(".modal").modal("hide");'; + $script[] = ' };'; + endif; +endforeach; + +$script[] = ' jQuery(".modal").on("hidden", function () {'; +$script[] = ' setTimeout(function(){'; +$script[] = ' window.parent.location.reload();'; +$script[] = ' },1000);'; +$script[] = ' });'; +$script[] = '});'; +$script[] = ' + (function (originalFn) { + Joomla.submitform = function(task, form) { + originalFn(task, form); + if (task == "menu.exportXml") { + document.adminForm.task.value = ""; + } + }; + })(Joomla.submitform); +'; + +JFactory::getDocument()->addScriptDeclaration(implode("\n", $script)); +?> +
    +sidebar)) : ?> +
    + sidebar; ?> +
    +
    + +
    + + $this, 'options' => array('filterButton' => false))); ?> +
    + items)) : ?> +
    + +
    + + + + + + + + + + + + + + + + + + + + items as $i => $item) : + $canEdit = $user->authorise('core.edit', 'com_menus.menu.' . (int) $item->id); + $canManageItems = $user->authorise('core.manage', 'com_menus.menu.' . (int) $item->id); + ?> + + + + + + + + + + + + + + + + + +
    + diff --git a/Sites/pages/administrator/components/com_menus/views/menus/tmpl/default.xml b/Sites/pages/administrator/components/com_menus/views/menus/tmpl/default.xml new file mode 100755 index 00000000..7a64aba9 --- /dev/null +++ b/Sites/pages/administrator/components/com_menus/views/menus/tmpl/default.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/Sites/pages/administrator/components/com_menus/views/menus/view.html.php b/Sites/pages/administrator/components/com_menus/views/menus/view.html.php new file mode 100644 index 00000000..20310574 --- /dev/null +++ b/Sites/pages/administrator/components/com_menus/views/menus/view.html.php @@ -0,0 +1,119 @@ +items = $this->get('Items'); + $this->modules = $this->get('Modules'); + $this->pagination = $this->get('Pagination'); + $this->state = $this->get('State'); + + if ($this->getLayout() == 'default') + { + $this->filterForm = $this->get('FilterForm'); + $this->activeFilters = $this->get('ActiveFilters'); + } + + MenusHelper::addSubmenu('menus'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + $this->addToolbar(); + $this->sidebar = JHtmlSidebar::render(); + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + $canDo = JHelperContent::getActions('com_menus'); + + JToolbarHelper::title(JText::_('COM_MENUS_VIEW_MENUS_TITLE'), 'list menumgr'); + + if ($canDo->get('core.create')) + { + JToolbarHelper::addNew('menu.add'); + } + + if ($canDo->get('core.edit')) + { + JToolbarHelper::editList('menu.edit'); + } + + if ($canDo->get('core.delete')) + { + JToolbarHelper::divider(); + JToolbarHelper::deleteList('COM_MENUS_MENU_CONFIRM_DELETE', 'menus.delete', 'JTOOLBAR_DELETE'); + } + + JToolbarHelper::custom('menus.rebuild', 'refresh.png', 'refresh_f2.png', 'JTOOLBAR_REBUILD', false); + + if ($canDo->get('core.admin') && $this->state->get('client_id') == 1) + { + JToolbarHelper::custom('menu.exportXml', 'download', 'download', 'COM_MENUS_MENU_EXPORT_BUTTON', true); + } + + if ($canDo->get('core.admin') || $canDo->get('core.options')) + { + JToolbarHelper::divider(); + JToolbarHelper::preferences('com_menus'); + } + + JToolbarHelper::divider(); + JToolbarHelper::help('JHELP_MENUS_MENU_MANAGER'); + } +} diff --git a/Sites/pages/administrator/components/com_menus/views/menutypes/tmpl/default.php b/Sites/pages/administrator/components/com_menus/views/menutypes/tmpl/default.php new file mode 100644 index 00000000..b94b1f04 --- /dev/null +++ b/Sites/pages/administrator/components/com_menus/views/menutypes/tmpl/default.php @@ -0,0 +1,56 @@ +input; + +// Checking if loaded via index.php or component.php +$tmpl = ($input->getCmd('tmpl') != '') ? '1' : ''; + +JHtml::_('behavior.core'); +JFactory::getDocument()->addScriptDeclaration(' + setmenutype = function(type) { + var tmpl = ' . json_encode($tmpl) . '; + if (tmpl) + { + window.parent.Joomla.submitbutton("item.setType", type); + window.parent.jQuery("#menuTypeModal").modal("hide"); + } + else + { + window.location="index.php?option=com_menus&view=item&task=item.setType&layout=edit&type=" + type; + } + }; +'); + +?> + 'slide1')); ?> + + types as $name => $list) : ?> + + + + + +recordId = $app->input->getInt('recordId'); + + $types = $this->get('TypeOptions'); + + $this->addCustomTypes($types); + + $sortedTypes = array(); + + foreach ($types as $name => $list) + { + $tmp = array(); + + foreach ($list as $item) + { + $tmp[JText::_($item->title)] = $item; + } + + uksort($tmp, 'strcasecmp'); + $sortedTypes[JText::_($name)] = $tmp; + } + + uksort($sortedTypes, 'strcasecmp'); + + $this->types = $sortedTypes; + + $this->addToolbar(); + + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 3.0 + */ + protected function addToolbar() + { + // Add page title + JToolbarHelper::title(JText::_('COM_MENUS'), 'list menumgr'); + + // Get the toolbar object instance + $bar = JToolbar::getInstance('toolbar'); + + // Cancel + $title = JText::_('JTOOLBAR_CANCEL'); + $dhtml = ""; + $bar->appendButton('Custom', $dhtml, 'new'); + } + + /** + * Method to add system link types to the link types array + * + * @param array $types The list of link types + * + * @return void + * + * @since 3.7.0 + */ + protected function addCustomTypes(&$types) + { + if (empty($types)) + { + $types = array(); + } + + // Adding System Links + $list = array(); + $o = new JObject; + $o->title = 'COM_MENUS_TYPE_EXTERNAL_URL'; + $o->type = 'url'; + $o->description = 'COM_MENUS_TYPE_EXTERNAL_URL_DESC'; + $o->request = null; + $list[] = $o; + + $o = new JObject; + $o->title = 'COM_MENUS_TYPE_ALIAS'; + $o->type = 'alias'; + $o->description = 'COM_MENUS_TYPE_ALIAS_DESC'; + $o->request = null; + $list[] = $o; + + $o = new JObject; + $o->title = 'COM_MENUS_TYPE_SEPARATOR'; + $o->type = 'separator'; + $o->description = 'COM_MENUS_TYPE_SEPARATOR_DESC'; + $o->request = null; + $list[] = $o; + + $o = new JObject; + $o->title = 'COM_MENUS_TYPE_HEADING'; + $o->type = 'heading'; + $o->description = 'COM_MENUS_TYPE_HEADING_DESC'; + $o->request = null; + $list[] = $o; + + if ($this->get('state')->get('client_id') == 1) + { + $o = new JObject; + $o->title = 'COM_MENUS_TYPE_CONTAINER'; + $o->type = 'container'; + $o->description = 'COM_MENUS_TYPE_CONTAINER_DESC'; + $o->request = null; + $list[] = $o; + } + + $types['COM_MENUS_TYPE_SYSTEM'] = $list; + } +} diff --git a/Sites/pages/administrator/components/com_messages/access.xml b/Sites/pages/administrator/components/com_messages/access.xml new file mode 100644 index 00000000..db0d1992 --- /dev/null +++ b/Sites/pages/administrator/components/com_messages/access.xml @@ -0,0 +1,10 @@ + + +
    + + + + + +
    +
    diff --git a/Sites/pages/administrator/components/com_messages/config.xml b/Sites/pages/administrator/components/com_messages/config.xml new file mode 100644 index 00000000..ddb9b37b --- /dev/null +++ b/Sites/pages/administrator/components/com_messages/config.xml @@ -0,0 +1,19 @@ + + +
    + + +
    +
    diff --git a/Sites/pages/administrator/components/com_messages/controller.php b/Sites/pages/administrator/components/com_messages/controller.php new file mode 100644 index 00000000..0271d55f --- /dev/null +++ b/Sites/pages/administrator/components/com_messages/controller.php @@ -0,0 +1,52 @@ +input->get('view', 'messages'); + $layout = $this->input->get('layout', 'default'); + $id = $this->input->getInt('id'); + + // Check for edit form. + if ($view == 'message' && $layout == 'edit' && !$this->checkEditId('com_messages.edit.message', $id)) + { + // Somehow the person just went to the form - we don't allow that. + $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id)); + $this->setMessage($this->getError(), 'error'); + $this->setRedirect(JRoute::_('index.php?option=com_messages&view=messages', false)); + + return false; + } + + // Load the submenu. + MessagesHelper::addSubmenu($this->input->get('view', 'messages')); + parent::display(); + } +} diff --git a/Sites/pages/administrator/components/com_messages/controllers/config.php b/Sites/pages/administrator/components/com_messages/controllers/config.php new file mode 100644 index 00000000..3f020b3f --- /dev/null +++ b/Sites/pages/administrator/components/com_messages/controllers/config.php @@ -0,0 +1,88 @@ +checkToken(); + + $app = JFactory::getApplication(); + $model = $this->getModel('Config', 'MessagesModel'); + $data = $this->input->post->get('jform', array(), 'array'); + + // Validate the posted data. + $form = $model->getForm(); + + if (!$form) + { + JError::raiseError(500, $model->getError()); + + return false; + } + + $data = $model->validate($form, $data); + + // Check for validation errors. + if ($data === false) + { + // Get the validation messages. + $errors = $model->getErrors(); + + // Push up to three validation messages out to the user. + for ($i = 0, $n = count($errors); $i < $n && $i < 3; $i++) + { + if ($errors[$i] instanceof Exception) + { + $app->enqueueMessage($errors[$i]->getMessage(), 'warning'); + } + else + { + $app->enqueueMessage($errors[$i], 'warning'); + } + } + + // Redirect back to the main list. + $this->setRedirect(JRoute::_('index.php?option=com_messages&view=messages', false)); + + return false; + } + + // Attempt to save the data. + if (!$model->save($data)) + { + // Redirect back to the main list. + $this->setMessage(JText::sprintf('JERROR_SAVE_FAILED', $model->getError()), 'warning'); + $this->setRedirect(JRoute::_('index.php?option=com_messages&view=messages', false)); + + return false; + } + + // Redirect to the list screen. + $this->setMessage(JText::_('COM_MESSAGES_CONFIG_SAVED')); + $this->setRedirect(JRoute::_('index.php?option=com_messages&view=messages', false)); + + return true; + } +} diff --git a/Sites/pages/administrator/components/com_messages/controllers/message.php b/Sites/pages/administrator/components/com_messages/controllers/message.php new file mode 100644 index 00000000..263e0a06 --- /dev/null +++ b/Sites/pages/administrator/components/com_messages/controllers/message.php @@ -0,0 +1,57 @@ +input->getInt('reply_id')) + { + $this->setRedirect('index.php?option=com_messages&view=message&layout=edit&reply_id=' . $replyId); + } + else + { + $this->setMessage(JText::_('COM_MESSAGES_INVALID_REPLY_ID')); + $this->setRedirect('index.php?option=com_messages&view=messages'); + } + } +} diff --git a/Sites/pages/administrator/components/com_messages/controllers/messages.php b/Sites/pages/administrator/components/com_messages/controllers/messages.php new file mode 100644 index 00000000..391a77ad --- /dev/null +++ b/Sites/pages/administrator/components/com_messages/controllers/messages.php @@ -0,0 +1,34 @@ + true)) + { + return parent::getModel($name, $prefix, $config); + } +} diff --git a/Sites/pages/administrator/components/com_messages/helpers/html/messages.php b/Sites/pages/administrator/components/com_messages/helpers/html/messages.php new file mode 100644 index 00000000..ba81f13b --- /dev/null +++ b/Sites/pages/administrator/components/com_messages/helpers/html/messages.php @@ -0,0 +1,97 @@ + array('trash', 'messages.unpublish', 'JTRASHED', 'COM_MESSAGES_MARK_AS_UNREAD'), + 1 => array('publish', 'messages.unpublish', 'COM_MESSAGES_OPTION_READ', 'COM_MESSAGES_MARK_AS_UNREAD'), + 0 => array('unpublish', 'messages.publish', 'COM_MESSAGES_OPTION_UNREAD', 'COM_MESSAGES_MARK_AS_READ'), + ); + + $state = ArrayHelper::getValue($states, (int) $value, $states[0]); + $icon = $state[0]; + + if ($canChange) + { + $html = ''; + } + + return $html; + } +} diff --git a/Sites/pages/administrator/components/com_messages/helpers/messages.php b/Sites/pages/administrator/components/com_messages/helpers/messages.php new file mode 100644 index 00000000..78317c80 --- /dev/null +++ b/Sites/pages/administrator/components/com_messages/helpers/messages.php @@ -0,0 +1,87 @@ +authorise('core.manage', 'com_messages')) +{ + throw new JAccessExceptionNotallowed(JText::_('JERROR_ALERTNOAUTHOR'), 403); +} + +$task = JFactory::getApplication()->input->get('task'); +$controller = JControllerLegacy::getInstance('Messages'); +$controller->execute(JFactory::getApplication()->input->get('task')); +$controller->redirect(); diff --git a/Sites/pages/administrator/components/com_messages/messages.xml b/Sites/pages/administrator/components/com_messages/messages.xml new file mode 100644 index 00000000..eea4046c --- /dev/null +++ b/Sites/pages/administrator/components/com_messages/messages.xml @@ -0,0 +1,31 @@ + + + com_messages + Joomla! Project + April 2006 + (C) 2005 - 2020 Open Source Matters. All rights reserved. + GNU General Public License version 2 or later; see LICENSE.txt + admin@joomla.org + www.joomla.org + 3.0.0 + COM_MESSAGES_XML_DESCRIPTION + + language/en-GB.com_messages.ini + + + + config.xml + controller.php + messages.php + controllers + helpers + models + tables + views + + + language/en-GB.com_messages.ini + language/en-GB.com_messages.sys.ini + + + diff --git a/Sites/pages/administrator/components/com_messages/models/config.php b/Sites/pages/administrator/components/com_messages/models/config.php new file mode 100644 index 00000000..ab7897b7 --- /dev/null +++ b/Sites/pages/administrator/components/com_messages/models/config.php @@ -0,0 +1,171 @@ +setState('user.id', $user->get('id')); + + // Load the parameters. + $params = JComponentHelper::getParams('com_messages'); + $this->setState('params', $params); + } + + /** + * Method to get a single record. + * + * @return mixed Object on success, false on failure. + * + * @since 1.6 + */ + public function &getItem() + { + $item = new JObject; + + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select('cfg_name, cfg_value') + ->from('#__messages_cfg') + ->where($db->quoteName('user_id') . ' = ' . (int) $this->getState('user.id')); + + $db->setQuery($query); + + try + { + $rows = $db->loadObjectList(); + } + catch (RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + + foreach ($rows as $row) + { + $item->set($row->cfg_name, $row->cfg_value); + } + + $this->preprocessData('com_messages.config', $item); + + return $item; + } + + /** + * Method to get the record form. + * + * @param array $data Data for the form. + * @param boolean $loadData True if the form is to load its own data (default case), false if not. + * + * @return JForm A JForm object on success, false on failure + * + * @since 1.6 + */ + public function getForm($data = array(), $loadData = true) + { + // Get the form. + $form = $this->loadForm('com_messages.config', 'config', array('control' => 'jform', 'load_data' => $loadData)); + + if (empty($form)) + { + return false; + } + + return $form; + } + + /** + * Method to save the form data. + * + * @param array $data The form data. + * + * @return boolean True on success. + * + * @since 1.6 + */ + public function save($data) + { + $db = $this->getDbo(); + + if ($userId = (int) $this->getState('user.id')) + { + $query = $db->getQuery(true) + ->delete($db->quoteName('#__messages_cfg')) + ->where($db->quoteName('user_id') . '=' . (int) $userId); + $db->setQuery($query); + + try + { + $db->execute(); + } + catch (RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + + if (count($data)) + { + $query = $db->getQuery(true) + ->insert($db->quoteName('#__messages_cfg')) + ->columns($db->quoteName(array('user_id', 'cfg_name', 'cfg_value'))); + + foreach ($data as $k => $v) + { + $query->values($userId . ', ' . $db->quote($k) . ', ' . $db->quote($v)); + } + + $db->setQuery($query); + + try + { + $db->execute(); + } + catch (RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + } + + return true; + } + else + { + $this->setError('COM_MESSAGES_ERR_INVALID_USER'); + + return false; + } + } +} diff --git a/Sites/pages/administrator/components/com_messages/models/fields/messagestates.php b/Sites/pages/administrator/components/com_messages/models/fields/messagestates.php new file mode 100644 index 00000000..3ef0cf36 --- /dev/null +++ b/Sites/pages/administrator/components/com_messages/models/fields/messagestates.php @@ -0,0 +1,43 @@ +getQuery(true) + ->select('id') + ->from('#__usergroups'); + $db->setQuery($query); + + try + { + $groups = $db->loadColumn(); + } + catch (RuntimeException $e) + { + JError::raiseNotice(500, $e->getMessage()); + + return null; + } + + foreach ($groups as $i => $group) + { + if (JAccess::checkGroup($group, 'core.admin')) + { + continue; + } + + if (!JAccess::checkGroup($group, 'core.manage', 'com_messages')) + { + unset($groups[$i]); + continue; + } + + if (!JAccess::checkGroup($group, 'core.login.admin')) + { + unset($groups[$i]); + continue; + } + } + + return array_values($groups); + } + + /** + * Method to get the users to exclude from the list of users + * + * @return array|null array of users to exclude or null to to not exclude them + * + * @since 1.6 + */ + protected function getExcluded() + { + return array(JFactory::getUser()->id); + } +} diff --git a/Sites/pages/administrator/components/com_messages/models/forms/config.xml b/Sites/pages/administrator/components/com_messages/models/forms/config.xml new file mode 100644 index 00000000..3f162a72 --- /dev/null +++ b/Sites/pages/administrator/components/com_messages/models/forms/config.xml @@ -0,0 +1,37 @@ + +
    +
    + + + + + + + + + + + +
    +
    diff --git a/Sites/pages/administrator/components/com_messages/models/forms/filter_messages.xml b/Sites/pages/administrator/components/com_messages/models/forms/filter_messages.xml new file mode 100644 index 00000000..15531c8b --- /dev/null +++ b/Sites/pages/administrator/components/com_messages/models/forms/filter_messages.xml @@ -0,0 +1,53 @@ + +
    + + + + + + + + + + + + + + + + + + + + + +
    diff --git a/Sites/pages/administrator/components/com_messages/models/forms/message.xml b/Sites/pages/administrator/components/com_messages/models/forms/message.xml new file mode 100644 index 00000000..2d1054a7 --- /dev/null +++ b/Sites/pages/administrator/components/com_messages/models/forms/message.xml @@ -0,0 +1,31 @@ + +
    +
    + + + + + +
    +
    diff --git a/Sites/pages/administrator/components/com_messages/models/message.php b/Sites/pages/administrator/components/com_messages/models/message.php new file mode 100644 index 00000000..5b74f4b3 --- /dev/null +++ b/Sites/pages/administrator/components/com_messages/models/message.php @@ -0,0 +1,534 @@ +input; + + $user = JFactory::getUser(); + $this->setState('user.id', $user->get('id')); + + $messageId = (int) $input->getInt('message_id'); + $this->setState('message.id', $messageId); + + $replyId = (int) $input->getInt('reply_id'); + $this->setState('reply.id', $replyId); + } + + /** + * Check that recipient user is the one trying to delete and then call parent delete method + * + * @param array &$pks An array of record primary keys. + * + * @return boolean True if successful, false if an error occurs. + * + * @since 3.1 + */ + public function delete(&$pks) + { + $pks = (array) $pks; + $table = $this->getTable(); + $user = JFactory::getUser(); + + // Iterate the items to delete each one. + foreach ($pks as $i => $pk) + { + if ($table->load($pk)) + { + if ($table->user_id_to != $user->id) + { + // Prune items that you can't change. + unset($pks[$i]); + + try + { + JLog::add(JText::_('JLIB_APPLICATION_ERROR_DELETE_NOT_PERMITTED'), JLog::WARNING, 'jerror'); + } + catch (RuntimeException $exception) + { + JFactory::getApplication()->enqueueMessage(JText::_('JLIB_APPLICATION_ERROR_DELETE_NOT_PERMITTED'), 'warning'); + } + + return false; + } + } + else + { + $this->setError($table->getError()); + + return false; + } + } + + return parent::delete($pks); + } + + /** + * Returns a Table object, always creating it. + * + * @param type $type The table type to instantiate + * @param string $prefix A prefix for the table class name. Optional. + * @param array $config Configuration array for model. Optional. + * + * @return JTable A database object + * + * @since 1.6 + */ + public function getTable($type = 'Message', $prefix = 'MessagesTable', $config = array()) + { + return JTable::getInstance($type, $prefix, $config); + } + + /** + * Method to get a single record. + * + * @param integer $pk The id of the primary key. + * + * @return mixed Object on success, false on failure. + * + * @since 1.6 + */ + public function getItem($pk = null) + { + if (!isset($this->item)) + { + if ($this->item = parent::getItem($pk)) + { + // Invalid message_id returns 0 + if ($this->item->user_id_to === '0') + { + $this->setError(JText::_('JERROR_ALERTNOAUTHOR')); + + return false; + } + + // Prime required properties. + if (empty($this->item->message_id)) + { + // Prepare data for a new record. + if ($replyId = $this->getState('reply.id')) + { + // If replying to a message, preload some data. + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select($db->quoteName(array('subject', 'user_id_from', 'user_id_to'))) + ->from($db->quoteName('#__messages')) + ->where($db->quoteName('message_id') . ' = ' . (int) $replyId); + + try + { + $message = $db->setQuery($query)->loadObject(); + } + catch (RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + + if (!$message || $message->user_id_to != JFactory::getUser()->id) + { + $this->setError(JText::_('JERROR_ALERTNOAUTHOR')); + + return false; + } + + $this->item->set('user_id_to', $message->user_id_from); + $re = JText::_('COM_MESSAGES_RE'); + + if (stripos($message->subject, $re) !== 0) + { + $this->item->set('subject', $re . ' ' . $message->subject); + } + } + } + elseif ($this->item->user_id_to != JFactory::getUser()->id) + { + $this->setError(JText::_('JERROR_ALERTNOAUTHOR')); + + return false; + } + else + { + // Mark message read + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->update($db->quoteName('#__messages')) + ->set($db->quoteName('state') . ' = 1') + ->where($db->quoteName('message_id') . ' = ' . $this->item->message_id); + $db->setQuery($query)->execute(); + } + } + + // Get the user name for an existing message. + if ($this->item->user_id_from && $fromUser = new JUser($this->item->user_id_from)) + { + $this->item->set('from_user_name', $fromUser->name); + } + } + + return $this->item; + } + + /** + * Method to get the record form. + * + * @param array $data Data for the form. + * @param boolean $loadData True if the form is to load its own data (default case), false if not. + * + * @return JForm A JForm object on success, false on failure + * + * @since 1.6 + */ + public function getForm($data = array(), $loadData = true) + { + // Get the form. + $form = $this->loadForm('com_messages.message', 'message', array('control' => 'jform', 'load_data' => $loadData)); + + if (empty($form)) + { + return false; + } + + return $form; + } + + /** + * Method to get the data that should be injected in the form. + * + * @return mixed The data for the form. + * + * @since 1.6 + */ + protected function loadFormData() + { + // Check the session for previously entered form data. + $data = JFactory::getApplication()->getUserState('com_messages.edit.message.data', array()); + + if (empty($data)) + { + $data = $this->getItem(); + } + + $this->preprocessData('com_messages.message', $data); + + return $data; + } + + /** + * Checks that the current user matches the message recipient and calls the parent publish method + * + * @param array &$pks A list of the primary keys to change. + * @param integer $value The value of the published state. + * + * @return boolean True on success. + * + * @since 3.1 + */ + public function publish(&$pks, $value = 1) + { + $user = JFactory::getUser(); + $table = $this->getTable(); + $pks = (array) $pks; + + // Check that the recipient matches the current user + foreach ($pks as $i => $pk) + { + $table->reset(); + + if ($table->load($pk)) + { + if ($table->user_id_to != $user->id) + { + // Prune items that you can't change. + unset($pks[$i]); + + try + { + JLog::add(JText::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED'), JLog::WARNING, 'jerror'); + } + catch (RuntimeException $exception) + { + JFactory::getApplication()->enqueueMessage(JText::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED'), 'warning'); + } + + return false; + } + } + } + + return parent::publish($pks, $value); + } + + /** + * Method to save the form data. + * + * @param array $data The form data. + * + * @return boolean True on success. + * + * @since 1.6 + */ + public function save($data) + { + $table = $this->getTable(); + + // Bind the data. + if (!$table->bind($data)) + { + $this->setError($table->getError()); + + return false; + } + + // Assign empty values. + if (empty($table->user_id_from)) + { + $table->user_id_from = JFactory::getUser()->get('id'); + } + + if ((int) $table->date_time == 0) + { + $table->date_time = JFactory::getDate()->toSql(); + } + + // Check the data. + if (!$table->check()) + { + $this->setError($table->getError()); + + return false; + } + + // Load the user details (already valid from table check). + $toUser = \JUser::getInstance($table->user_id_to); + + // Check if recipient can access com_messages. + if (!$toUser->authorise('core.login.admin') || !$toUser->authorise('core.manage', 'com_messages')) + { + $this->setError(\JText::_('COM_MESSAGES_ERROR_RECIPIENT_NOT_AUTHORISED')); + + return false; + } + + // Load the recipient user configuration. + $model = JModelLegacy::getInstance('Config', 'MessagesModel', array('ignore_request' => true)); + $model->setState('user.id', $table->user_id_to); + $config = $model->getItem(); + + if (empty($config)) + { + $this->setError($model->getError()); + + return false; + } + + if ($config->get('lock', false)) + { + $this->setError(JText::_('COM_MESSAGES_ERR_SEND_FAILED')); + + return false; + } + + // Store the data. + if (!$table->store()) + { + $this->setError($table->getError()); + + return false; + } + + if ($config->get('mail_on_new', true)) + { + $fromUser = JUser::getInstance($table->user_id_from); + $debug = JFactory::getConfig()->get('debug_lang'); + $default_language = JComponentHelper::getParams('com_languages')->get('administrator'); + $lang = JLanguage::getInstance($toUser->getParam('admin_language', $default_language), $debug); + $lang->load('com_messages', JPATH_ADMINISTRATOR); + + // Build the email subject and message + $app = JFactory::getApplication(); + $linkMode = $app->get('force_ssl', 0) >= 1 ? Route::TLS_FORCE : Route::TLS_IGNORE; + $sitename = $app->get('sitename'); + $fromName = $fromUser->get('name'); + $siteURL = JRoute::link('administrator', 'index.php?option=com_messages&view=message&message_id=' . $table->message_id, false, $linkMode, true); + $subject = html_entity_decode($table->subject, ENT_COMPAT, 'UTF-8'); + $message = strip_tags(html_entity_decode($table->message, ENT_COMPAT, 'UTF-8')); + + $subj = sprintf($lang->_('COM_MESSAGES_NEW_MESSAGE'), $fromName, $sitename); + $msg = $subject . "\n\n" . $message . "\n\n" . sprintf($lang->_('COM_MESSAGES_PLEASE_LOGIN'), $siteURL); + + // Send the email + $mailer = JFactory::getMailer(); + + if (!$mailer->addReplyTo($fromUser->email, $fromUser->name)) + { + try + { + JLog::add(JText::_('COM_MESSAGES_ERROR_COULD_NOT_SEND_INVALID_REPLYTO'), JLog::WARNING, 'jerror'); + } + catch (RuntimeException $exception) + { + JFactory::getApplication()->enqueueMessage(JText::_('COM_MESSAGES_ERROR_COULD_NOT_SEND_INVALID_REPLYTO'), 'warning'); + } + + // The message is still saved in the database, we do not allow this failure to cause the entire save routine to fail + return true; + } + + if (!$mailer->addRecipient($toUser->email, $toUser->name)) + { + try + { + JLog::add(JText::_('COM_MESSAGES_ERROR_COULD_NOT_SEND_INVALID_RECIPIENT'), JLog::WARNING, 'jerror'); + } + catch (RuntimeException $exception) + { + JFactory::getApplication()->enqueueMessage(JText::_('COM_MESSAGES_ERROR_COULD_NOT_SEND_INVALID_RECIPIENT'), 'warning'); + } + + // The message is still saved in the database, we do not allow this failure to cause the entire save routine to fail + return true; + } + + $mailer->setSubject($subj); + $mailer->setBody($msg); + + // The Send method will raise an error via JError on a failure, we do not need to check it ourselves here + $mailer->Send(); + } + + return true; + } + + /** + * Sends a message to the site's super users + * + * @param string $subject The message subject + * @param string $message The message + * + * @return boolean + * + * @since 3.9.0 + */ + public function notifySuperUsers($subject, $message, $fromUser = null) + { + $db = $this->getDbo(); + + try + { + /** @var JTableAsset $table */ + $table = $this->getTable('Asset', 'JTable'); + $rootId = $table->getRootId(); + + /** @var JAccessRule[] $rules */ + $rules = JAccess::getAssetRules($rootId)->getData(); + $rawGroups = $rules['core.admin']->getData(); + + if (empty($rawGroups)) + { + $this->setError(JText::_('COM_MESSAGES_ERROR_MISSING_ROOT_ASSET_GROUPS')); + + return false; + } + + $groups = array(); + + foreach ($rawGroups as $g => $enabled) + { + if ($enabled) + { + $groups[] = $db->quote($g); + } + } + + if (empty($groups)) + { + $this->setError(JText::_('COM_MESSAGES_ERROR_NO_GROUPS_SET_AS_SUPER_USER')); + + return false; + } + + $query = $db->getQuery(true) + ->select($db->quoteName('map.user_id')) + ->from($db->quoteName('#__user_usergroup_map', 'map')) + ->join('LEFT', $db->quoteName('#__users', 'u') . ' ON ' . $db->quoteName('u.id') . ' = ' . $db->quoteName('map.user_id')) + ->where($db->quoteName('map.group_id') . ' IN(' . implode(',', $groups) . ')') + ->where($db->quoteName('u.block') . ' = 0') + ->where($db->quoteName('u.sendEmail') . ' = 1'); + + $userIDs = $db->setQuery($query)->loadColumn(0); + + if (empty($userIDs)) + { + $this->setError(JText::_('COM_MESSAGES_ERROR_NO_USERS_SET_AS_SUPER_USER')); + + return false; + } + + foreach ($userIDs as $id) + { + /* + * All messages must have a valid from user, we have use cases where an unauthenticated user may trigger this + * so we will set the from user as the to user + */ + $data = array( + 'user_id_from' => $id, + 'user_id_to' => $id, + 'subject' => $subject, + 'message' => $message, + ); + + if (!$this->save($data)) + { + return false; + } + } + + return true; + } + catch (Exception $exception) + { + $this->setError($exception->getMessage()); + + return false; + } + } +} diff --git a/Sites/pages/administrator/components/com_messages/models/messages.php b/Sites/pages/administrator/components/com_messages/models/messages.php new file mode 100644 index 00000000..aff573c7 --- /dev/null +++ b/Sites/pages/administrator/components/com_messages/models/messages.php @@ -0,0 +1,148 @@ +setState('filter.search', $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search', '', 'string')); + + $this->setState('filter.state', $this->getUserStateFromRequest($this->context . '.filter.state', 'filter_state', '', 'cmd')); + + // List state information. + parent::populateState($ordering, $direction); + } + + /** + * Method to get a store id based on model configuration state. + * + * This is necessary because the model is used by the component and + * different modules that might need different sets of data or different + * ordering requirements. + * + * @param string $id A prefix for the store id. + * + * @return string A store id. + * + * @since 1.6 + */ + protected function getStoreId($id = '') + { + // Compile the store id. + $id .= ':' . $this->getState('filter.search'); + $id .= ':' . $this->getState('filter.state'); + + return parent::getStoreId($id); + } + + /** + * Build an SQL query to load the list data. + * + * @return JDatabaseQuery + * + * @since 1.6 + */ + protected function getListQuery() + { + // Create a new query object. + $db = $this->getDbo(); + $query = $db->getQuery(true); + $user = JFactory::getUser(); + + // Select the required fields from the table. + $query->select( + $this->getState( + 'list.select', + 'a.*, ' . + 'u.name AS user_from' + ) + ); + $query->from('#__messages AS a'); + + // Join over the users for message owner. + $query->join('INNER', '#__users AS u ON u.id = a.user_id_from') + ->where('a.user_id_to = ' . (int) $user->get('id')); + + // Filter by published state. + $state = $this->getState('filter.state'); + + if (is_numeric($state)) + { + $query->where('a.state = ' . (int) $state); + } + elseif ($state !== '*') + { + $query->where('(a.state IN (0, 1))'); + } + + // Filter by search in subject or message. + $search = $this->getState('filter.search'); + + if (!empty($search)) + { + $search = $db->quote('%' . str_replace(' ', '%', $db->escape(trim($search), true) . '%')); + $query->where('(a.subject LIKE ' . $search . ' OR a.message LIKE ' . $search . ')'); + } + + // Add the list ordering clause. + $query->order($db->escape($this->getState('list.ordering', 'a.date_time')) . ' ' . $db->escape($this->getState('list.direction', 'DESC'))); + + return $query; + } +} diff --git a/Sites/pages/administrator/components/com_messages/tables/message.php b/Sites/pages/administrator/components/com_messages/tables/message.php new file mode 100644 index 00000000..8276153b --- /dev/null +++ b/Sites/pages/administrator/components/com_messages/tables/message.php @@ -0,0 +1,149 @@ +setColumnAlias('published', 'state'); + } + + /** + * Validation and filtering. + * + * @return boolean + * + * @since 1.5 + */ + public function check() + { + // Check the to and from users. + $user = new JUser($this->user_id_from); + + if (empty($user->id)) + { + $this->setError(JText::_('COM_MESSAGES_ERROR_INVALID_FROM_USER')); + + return false; + } + + $user = new JUser($this->user_id_to); + + if (empty($user->id)) + { + $this->setError(JText::_('COM_MESSAGES_ERROR_INVALID_TO_USER')); + + return false; + } + + if (empty($this->subject)) + { + $this->setError(JText::_('COM_MESSAGES_ERROR_INVALID_SUBJECT')); + + return false; + } + + if (empty($this->message)) + { + $this->setError(JText::_('COM_MESSAGES_ERROR_INVALID_MESSAGE')); + + return false; + } + + return true; + } + + /** + * Method to set the publishing state for a row or list of rows in the database + * table. The method respects checked out rows by other users and will attempt + * to checkin rows that it can after adjustments are made. + * + * @param mixed $pks An optional array of primary key values to update. If not + * set the instance property value is used. + * @param integer $state The publishing state. eg. [0 = unpublished, 1 = published] + * @param integer $userId The user id of the user performing the operation. + * + * @return boolean True on success. + * + * @since 1.6 + */ + public function publish($pks = null, $state = 1, $userId = 0) + { + $k = $this->_tbl_key; + + // Sanitize input. + $pks = ArrayHelper::toInteger($pks); + $state = (int) $state; + + // If there are no primary keys set check to see if the instance key is set. + if (empty($pks)) + { + if ($this->$k) + { + $pks = array($this->$k); + } + // Nothing to set publishing state on, return false. + else + { + $this->setError(JText::_('JLIB_DATABASE_ERROR_NO_ROWS_SELECTED')); + + return false; + } + } + + // Build the WHERE clause for the primary keys. + $where = $k . ' IN (' . implode(',', $pks) . ')'; + + // Update the publishing state for rows with the given primary keys. + $this->_db->setQuery( + 'UPDATE ' . $this->_db->quoteName($this->_tbl) + . ' SET ' . $this->_db->quoteName('state') . ' = ' . (int) $state + . ' WHERE (' . $where . ')' + ); + + try + { + $this->_db->execute(); + } + catch (RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + + // If the JTable instance value is in the list of primary keys that were set, set the instance. + if (in_array($this->$k, $pks)) + { + $this->state = $state; + } + + $this->setError(''); + + return true; + } +} diff --git a/Sites/pages/administrator/components/com_messages/views/config/tmpl/default.php b/Sites/pages/administrator/components/com_messages/views/config/tmpl/default.php new file mode 100644 index 00000000..ee008bcc --- /dev/null +++ b/Sites/pages/administrator/components/com_messages/views/config/tmpl/default.php @@ -0,0 +1,43 @@ + 'bottom')); + +JFactory::getDocument()->addScriptDeclaration( + " + Joomla.submitbutton = function(task) + { + if (task == 'config.cancel' || document.formvalidator.isValid(document.getElementById('config-form'))) + { + Joomla.submitform(task, document.getElementById('config-form')); + } + }; + " +); +?> +
    +
    +
    + form->renderField('lock'); ?> + form->renderField('mail_on_new'); ?> + form->renderField('auto_purge'); ?> +
    + + + + +
    +
    diff --git a/Sites/pages/administrator/components/com_messages/views/config/view.html.php b/Sites/pages/administrator/components/com_messages/views/config/view.html.php new file mode 100644 index 00000000..6554edda --- /dev/null +++ b/Sites/pages/administrator/components/com_messages/views/config/view.html.php @@ -0,0 +1,51 @@ +form = $this->get('Form'); + $this->item = $this->get('Item'); + $this->state = $this->get('State'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + // Bind the record to the form. + $this->form->bind($this->item); + + parent::display($tpl); + } +} diff --git a/Sites/pages/administrator/components/com_messages/views/message/tmpl/default.php b/Sites/pages/administrator/components/com_messages/views/message/tmpl/default.php new file mode 100644 index 00000000..6bc533c2 --- /dev/null +++ b/Sites/pages/administrator/components/com_messages/views/message/tmpl/default.php @@ -0,0 +1,53 @@ + +
    +
    +
    +
    + +
    +
    + item->get('from_user_name'); ?> +
    +
    +
    +
    + +
    +
    + item->date_time, JText::_('DATE_FORMAT_LC2')); ?> +
    +
    +
    +
    + +
    +
    + item->subject; ?> +
    +
    +
    +
    + +
    +
    + item->message; ?> +
    +
    + + + +
    +
    diff --git a/Sites/pages/administrator/components/com_messages/views/message/tmpl/edit.php b/Sites/pages/administrator/components/com_messages/views/message/tmpl/edit.php new file mode 100644 index 00000000..f314688b --- /dev/null +++ b/Sites/pages/administrator/components/com_messages/views/message/tmpl/edit.php @@ -0,0 +1,57 @@ +addScriptDeclaration(" + Joomla.submitbutton = function(task) + { + if (task == 'message.cancel' || document.formvalidator.isValid(document.getElementById('message-form'))) + { + Joomla.submitform(task, document.getElementById('message-form')); + } + }; +"); +?> +
    +
    +
    +
    + form->getLabel('user_id_to'); ?> +
    +
    + form->getInput('user_id_to'); ?> +
    +
    +
    +
    + form->getLabel('subject'); ?> +
    +
    + form->getInput('subject'); ?> +
    +
    +
    +
    + form->getLabel('message'); ?> +
    +
    + form->getInput('message'); ?> +
    +
    +
    + + +
    diff --git a/Sites/pages/administrator/components/com_messages/views/message/view.html.php b/Sites/pages/administrator/components/com_messages/views/message/view.html.php new file mode 100644 index 00000000..e07dc5ea --- /dev/null +++ b/Sites/pages/administrator/components/com_messages/views/message/view.html.php @@ -0,0 +1,81 @@ +form = $this->get('Form'); + $this->item = $this->get('Item'); + $this->state = $this->get('State'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + parent::display($tpl); + $this->addToolbar(); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + if ($this->getLayout() == 'edit') + { + JFactory::getApplication()->input->set('hidemainmenu', true); + JToolbarHelper::title(JText::_('COM_MESSAGES_WRITE_PRIVATE_MESSAGE'), 'envelope-opened new-privatemessage'); + JToolbarHelper::save('message.save', 'COM_MESSAGES_TOOLBAR_SEND'); + JToolbarHelper::cancel('message.cancel'); + JToolbarHelper::help('JHELP_COMPONENTS_MESSAGING_WRITE'); + } + else + { + JToolbarHelper::title(JText::_('COM_MESSAGES_VIEW_PRIVATE_MESSAGE'), 'envelope inbox'); + $sender = JUser::getInstance($this->item->user_id_from); + + if ($sender->authorise('core.admin') || $sender->authorise('core.manage', 'com_messages') && $sender->authorise('core.login.admin')) + { + JToolbarHelper::custom('message.reply', 'redo', null, 'COM_MESSAGES_TOOLBAR_REPLY', false); + } + + JToolbarHelper::cancel('message.cancel'); + JToolbarHelper::help('JHELP_COMPONENTS_MESSAGING_READ'); + } + } +} diff --git a/Sites/pages/administrator/components/com_messages/views/messages/tmpl/default.php b/Sites/pages/administrator/components/com_messages/views/messages/tmpl/default.php new file mode 100644 index 00000000..95f597a6 --- /dev/null +++ b/Sites/pages/administrator/components/com_messages/views/messages/tmpl/default.php @@ -0,0 +1,110 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); + +JFactory::getDocument()->addStyleDeclaration( + ' + @media (min-width: 768px) { + div.modal { + left: none; + width: 500px; + margin-left: -250px; + } + } + ' +); +?> +
    + sidebar)) : ?> +
    + sidebar; ?> +
    +
    + +
    + + $this)); ?> +
    + items)) : ?> +
    + +
    + + + + + + + + + + + + + + + + + + items as $i => $item) : + $canChange = $user->authorise('core.edit.state', 'com_messages'); + ?> + + + + + + + + + +
    + + + + + + + + + +
    + pagination->getListFooter(); ?> +
    + message_id); ?> + + + escape($item->subject); ?> + + state, $canChange); ?> + + user_from; ?> + + date_time, JText::_('DATE_FORMAT_LC2')); ?> +
    + +
    + + + +
    +
    + diff --git a/Sites/pages/administrator/components/com_messages/views/messages/view.html.php b/Sites/pages/administrator/components/com_messages/views/messages/view.html.php new file mode 100644 index 00000000..4df58cbf --- /dev/null +++ b/Sites/pages/administrator/components/com_messages/views/messages/view.html.php @@ -0,0 +1,121 @@ +items = $this->get('Items'); + $this->pagination = $this->get('Pagination'); + $this->state = $this->get('State'); + $this->filterForm = $this->get('FilterForm'); + $this->activeFilters = $this->get('ActiveFilters'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + JError::raiseError(500, implode("\n", $errors)); + + return false; + } + + $this->addToolbar(); + + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + $state = $this->get('State'); + $canDo = JHelperContent::getActions('com_messages'); + JToolbarHelper::title(JText::_('COM_MESSAGES_MANAGER_MESSAGES'), 'envelope inbox'); + + if ($canDo->get('core.create')) + { + JToolbarHelper::addNew('message.add'); + } + + if ($canDo->get('core.edit.state')) + { + JToolbarHelper::divider(); + JToolbarHelper::publish('messages.publish', 'COM_MESSAGES_TOOLBAR_MARK_AS_READ', true); + JToolbarHelper::unpublish('messages.unpublish', 'COM_MESSAGES_TOOLBAR_MARK_AS_UNREAD', true); + } + + JToolbarHelper::divider(); + $bar = JToolBar::getInstance('toolbar'); + $bar->appendButton( + 'Popup', + 'cog', + 'COM_MESSAGES_TOOLBAR_MY_SETTINGS', + 'index.php?option=com_messages&view=config&tmpl=component', + 500, + 250, + 0, + 0, + '', + '', + '' + . '' + ); + + if ($state->get('filter.state') == -2 && $canDo->get('core.delete')) + { + JToolbarHelper::divider(); + JToolbarHelper::deleteList('JGLOBAL_CONFIRM_DELETE', 'messages.delete', 'JTOOLBAR_EMPTY_TRASH'); + } + elseif ($canDo->get('core.edit.state')) + { + JToolbarHelper::divider(); + JToolbarHelper::trash('messages.trash'); + } + + if ($canDo->get('core.admin')) + { + JToolbarHelper::preferences('com_messages'); + } + + JToolbarHelper::divider(); + JToolbarHelper::help('JHELP_COMPONENTS_MESSAGING_INBOX'); + } +} diff --git a/Sites/pages/administrator/components/com_modules/access.xml b/Sites/pages/administrator/components/com_modules/access.xml new file mode 100644 index 00000000..6acf5f1e --- /dev/null +++ b/Sites/pages/administrator/components/com_modules/access.xml @@ -0,0 +1,18 @@ + + +
    + + + + + + + +
    +
    + + + + +
    +
    \ No newline at end of file diff --git a/Sites/pages/administrator/components/com_modules/config.xml b/Sites/pages/administrator/components/com_modules/config.xml new file mode 100644 index 00000000..3eb9b198 --- /dev/null +++ b/Sites/pages/administrator/components/com_modules/config.xml @@ -0,0 +1,54 @@ + + +
    + + + + +
    + +
    + + + + +
    + +
    + +
    +
    diff --git a/Sites/pages/administrator/components/com_modules/controller.php b/Sites/pages/administrator/components/com_modules/controller.php new file mode 100644 index 00000000..c6f5436b --- /dev/null +++ b/Sites/pages/administrator/components/com_modules/controller.php @@ -0,0 +1,123 @@ +input->getInt('id'); + + $document = JFactory::getDocument(); + + // For JSON requests + if ($document->getType() == 'json') + { + $view = new ModulesViewModule; + + // Get/Create the model + if ($model = new ModulesModelModule) + { + // Checkin table entry + if (!$model->checkout($id)) + { + JFactory::getApplication()->enqueueMessage(JText::_('JLIB_APPLICATION_ERROR_CHECKIN_USER_MISMATCH'), 'error'); + + return false; + } + + // Push the model into the view (as default) + $view->setModel($model, true); + } + + $view->document = $document; + + return $view->display(); + } + + JLoader::register('ModulesHelper', JPATH_ADMINISTRATOR . '/components/com_modules/helpers/modules.php'); + + $layout = $this->input->get('layout', 'edit'); + $id = $this->input->getInt('id'); + + // Check for edit form. + if ($layout == 'edit' && !$this->checkEditId('com_modules.edit.module', $id)) + { + // Somehow the person just went to the form - we don't allow that. + $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id)); + $this->setMessage($this->getError(), 'error'); + $this->setRedirect(JRoute::_('index.php?option=com_modules&view=modules', false)); + + return false; + } + + // Load the submenu. + ModulesHelper::addSubmenu($this->input->get('view', 'modules')); + + // Check custom administrator menu modules + if (JModuleHelper::isAdminMultilang()) + { + $languages = JLanguageHelper::getInstalledLanguages(1, true); + $langCodes = array(); + + foreach ($languages as $language) + { + if (isset($language->metadata['nativeName'])) + { + $languageName = $language->metadata['nativeName']; + } + else + { + $languageName = $language->metadata['name']; + } + + $langCodes[$language->metadata['tag']] = $languageName; + } + + $db = JFactory::getDbo(); + $query = $db->getQuery(true); + + $query->select($db->qn('m.language')) + ->from($db->qn('#__modules', 'm')) + ->where($db->qn('m.module') . ' = ' . $db->quote('mod_menu')) + ->where($db->qn('m.published') . ' = 1') + ->where($db->qn('m.client_id') . ' = 1') + ->group($db->qn('m.language')); + + $mLanguages = $db->setQuery($query)->loadColumn(); + + // Check if we have a mod_menu module set to All languages or a mod_menu module for each admin language. + if (!in_array('*', $mLanguages) && count($langMissing = array_diff(array_keys($langCodes), $mLanguages))) + { + $app = JFactory::getApplication(); + $langMissing = array_intersect_key($langCodes, array_flip($langMissing)); + + $app->enqueueMessage(JText::sprintf('JMENU_MULTILANG_WARNING_MISSING_MODULES', implode(', ', $langMissing)), 'warning'); + } + } + + return parent::display(); + } +} diff --git a/Sites/pages/administrator/components/com_modules/controllers/module.php b/Sites/pages/administrator/components/com_modules/controllers/module.php new file mode 100644 index 00000000..38a7fe9f --- /dev/null +++ b/Sites/pages/administrator/components/com_modules/controllers/module.php @@ -0,0 +1,318 @@ +input->get('eid', 0, 'int'); + + if (empty($extensionId)) + { + $redirectUrl = 'index.php?option=' . $this->option . '&view=' . $this->view_item . '&layout=edit'; + + $this->setRedirect(JRoute::_($redirectUrl, false)); + + return JError::raiseWarning(500, JText::_('COM_MODULES_ERROR_INVALID_EXTENSION')); + } + + $app->setUserState('com_modules.add.module.extension_id', $extensionId); + $app->setUserState('com_modules.add.module.params', null); + + // Parameters could be coming in for a new item, so let's set them. + $params = $app->input->get('params', array(), 'array'); + $app->setUserState('com_modules.add.module.params', $params); + } + + /** + * Override parent cancel method to reset the add module state. + * + * @param string $key The name of the primary key of the URL variable. + * + * @return boolean True if access level checks pass, false otherwise. + * + * @since 1.6 + */ + public function cancel($key = null) + { + $app = JFactory::getApplication(); + + $result = parent::cancel(); + + $app->setUserState('com_modules.add.module.extension_id', null); + $app->setUserState('com_modules.add.module.params', null); + + return $result; + } + + /** + * Override parent allowSave method. + * + * @param array $data An array of input data. + * @param string $key The name of the key for the primary key. + * + * @return boolean + * + * @since 1.6 + */ + protected function allowSave($data, $key = 'id') + { + // Use custom position if selected + if (isset($data['custom_position'])) + { + if (empty($data['position'])) + { + $data['position'] = $data['custom_position']; + } + + unset($data['custom_position']); + } + + return parent::allowSave($data, $key); + } + + /** + * Method override to check if you can edit an existing record. + * + * @param array $data An array of input data. + * @param string $key The name of the key for the primary key. + * + * @return boolean + * + * @since 3.2 + */ + protected function allowEdit($data = array(), $key = 'id') + { + // Initialise variables. + $recordId = (int) isset($data[$key]) ? $data[$key] : 0; + $user = JFactory::getUser(); + + // Zero record (id:0), return component edit permission by calling parent controller method + if (!$recordId) + { + return parent::allowEdit($data, $key); + } + + // Check edit on the record asset (explicit or inherited) + if ($user->authorise('core.edit', 'com_modules.module.' . $recordId)) + { + return true; + } + + return false; + } + + /** + * Method to run batch operations. + * + * @param string $model The model + * + * @return boolean True on success. + * + * @since 1.7 + */ + public function batch($model = null) + { + $this->checkToken(); + + // Set the model + $model = $this->getModel('Module', '', array()); + + // Preset the redirect + $redirectUrl = 'index.php?option=com_modules&view=modules' . $this->getRedirectToListAppend(); + + $this->setRedirect(JRoute::_($redirectUrl, false)); + + return parent::batch($model); + } + + /** + * Function that allows child controller access to model data after the data has been saved. + * + * @param JModelLegacy $model The data model object. + * @param array $validData The validated data. + * + * @return void + * + * @since 1.6 + */ + protected function postSaveHook(JModelLegacy $model, $validData = array()) + { + $app = JFactory::getApplication(); + $task = $this->getTask(); + + switch ($task) + { + case 'save2new': + $app->setUserState('com_modules.add.module.extension_id', $model->getState('module.extension_id')); + break; + + default: + $app->setUserState('com_modules.add.module.extension_id', null); + break; + } + + $app->setUserState('com_modules.add.module.params', null); + } + + /** + * Method to save a record. + * + * @param string $key The name of the primary key of the URL variable. + * @param string $urlVar The name of the URL variable if different from the primary key + * + * @return boolean True if successful, false otherwise. + */ + public function save($key = null, $urlVar = null) + { + $this->checkToken(); + + if (JFactory::getDocument()->getType() == 'json') + { + $model = $this->getModel(); + $data = $this->input->post->get('jform', array(), 'array'); + $item = $model->getItem($this->input->get('id')); + $properties = $item->getProperties(); + + if (isset($data['params'])) + { + unset($properties['params']); + } + + // Replace changed properties + $data = array_replace_recursive($properties, $data); + + if (!empty($data['assigned'])) + { + $data['assigned'] = array_map('abs', $data['assigned']); + } + + // Add new data to input before process by parent save() + $this->input->post->set('jform', $data); + + // Add path of forms directory + JForm::addFormPath(JPATH_ADMINISTRATOR . '/components/com_modules/models/forms'); + } + + parent::save($key, $urlVar); + + } + + /** + * Method to get the other modules in the same position + * + * @return string The data for the Ajax request. + * + * @since 3.6.3 + */ + public function orderPosition() + { + $app = JFactory::getApplication(); + + // Send json mime type. + $app->mimeType = 'application/json'; + $app->setHeader('Content-Type', $app->mimeType . '; charset=' . $app->charSet); + $app->sendHeaders(); + + // Check if user token is valid. + if (!JSession::checkToken('get')) + { + $app->enqueueMessage(JText::_('JINVALID_TOKEN_NOTICE'), 'error'); + echo new JResponseJson; + $app->close(); + } + + $jinput = $app->input; + $clientId = $jinput->getValue('client_id'); + $position = $jinput->getValue('position'); + $moduleId = $jinput->getValue('module_id'); + + // Access check. + if (!JFactory::getUser()->authorise('core.create', 'com_modules') + && !JFactory::getUser()->authorise('core.edit.state', 'com_modules') + && ($moduleId && !JFactory::getUser()->authorise('core.edit.state', 'com_modules.module.' . $moduleId))) + { + $app->enqueueMessage(\JText::_('JLIB_APPLICATION_ERROR_ACCESS_FORBIDDEN'), 'error'); + echo new JResponseJson; + $app->close(); + } + + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->select('position, ordering, title') + ->from('#__modules') + ->where('client_id = ' . (int) $clientId . ' AND position = ' . $db->q($position)) + ->order('ordering'); + + $db->setQuery($query); + + try + { + $orders = $db->loadObjectList(); + } + catch (RuntimeException $e) + { + JError::raiseWarning(500, $e->getMessage()); + + return ''; + } + + $orders2 = array(); + $n = count($orders); + + if ($n > 0) + { + for ($i = 0, $n; $i < $n; $i++) + { + if (!isset($orders2[$orders[$i]->position])) + { + $orders2[$orders[$i]->position] = 0; + } + + $orders2[$orders[$i]->position]++; + $ord = $orders2[$orders[$i]->position]; + $title = JText::sprintf('COM_MODULES_OPTION_ORDER_POSITION', $ord, htmlspecialchars($orders[$i]->title, ENT_QUOTES, 'UTF-8')); + + $html[] = $orders[$i]->position . ',' . $ord . ',' . $title; + } + } + else + { + $html[] = $position . ',' . 1 . ',' . JText::_('JNONE'); + } + + echo new JResponseJson($html); + $app->close(); + } +} diff --git a/Sites/pages/administrator/components/com_modules/controllers/modules.php b/Sites/pages/administrator/components/com_modules/controllers/modules.php new file mode 100644 index 00000000..88e707dd --- /dev/null +++ b/Sites/pages/administrator/components/com_modules/controllers/modules.php @@ -0,0 +1,70 @@ +checkToken(); + + $pks = $this->input->post->get('cid', array(), 'array'); + $pks = ArrayHelper::toInteger($pks); + + try + { + if (empty($pks)) + { + throw new Exception(JText::_('COM_MODULES_ERROR_NO_MODULES_SELECTED')); + } + + $model = $this->getModel(); + $model->duplicate($pks); + $this->setMessage(JText::plural('COM_MODULES_N_MODULES_DUPLICATED', count($pks))); + } + catch (Exception $e) + { + JError::raiseWarning(500, $e->getMessage()); + } + + $this->setRedirect('index.php?option=com_modules&view=modules'); + } + + /** + * Method to get a model object, loading it if required. + * + * @param string $name The model name. Optional. + * @param string $prefix The class prefix. Optional. + * @param array $config Configuration array for model. Optional. + * + * @return object The model. + * + * @since 1.6 + */ + public function getModel($name = 'Module', $prefix = 'ModulesModel', $config = array('ignore_request' => true)) + { + return parent::getModel($name, $prefix, $config); + } +} diff --git a/Sites/pages/administrator/components/com_modules/helpers/html/modules.php b/Sites/pages/administrator/components/com_modules/helpers/html/modules.php new file mode 100644 index 00000000..f65c8633 --- /dev/null +++ b/Sites/pages/administrator/components/com_modules/helpers/html/modules.php @@ -0,0 +1,245 @@ +element, $template->name); + } + + return $options; + } + + /** + * Builds an array of template type options + * + * @return array + */ + public static function types() + { + $options = array(); + $options[] = JHtml::_('select.option', 'user', 'COM_MODULES_OPTION_POSITION_USER_DEFINED'); + $options[] = JHtml::_('select.option', 'template', 'COM_MODULES_OPTION_POSITION_TEMPLATE_DEFINED'); + + return $options; + } + + /** + * Builds an array of template state options + * + * @return array + */ + public static function templateStates() + { + $options = array(); + $options[] = JHtml::_('select.option', '1', 'JENABLED'); + $options[] = JHtml::_('select.option', '0', 'JDISABLED'); + + return $options; + } + + /** + * Returns a published state on a grid + * + * @param integer $value The state value. + * @param integer $i The row index + * @param boolean $enabled An optional setting for access control on the action. + * @param string $checkbox An optional prefix for checkboxes. + * + * @return string The Html code + * + * @see JHtmlJGrid::state + * @since 1.7.1 + */ + public static function state($value, $i, $enabled = true, $checkbox = 'cb') + { + $states = array( + 1 => array( + 'unpublish', + 'COM_MODULES_EXTENSION_PUBLISHED_ENABLED', + 'COM_MODULES_HTML_UNPUBLISH_ENABLED', + 'COM_MODULES_EXTENSION_PUBLISHED_ENABLED', + true, + 'publish', + 'publish', + ), + 0 => array( + 'publish', + 'COM_MODULES_EXTENSION_UNPUBLISHED_ENABLED', + 'COM_MODULES_HTML_PUBLISH_ENABLED', + 'COM_MODULES_EXTENSION_UNPUBLISHED_ENABLED', + true, + 'unpublish', + 'unpublish', + ), + -1 => array( + 'unpublish', + 'COM_MODULES_EXTENSION_PUBLISHED_DISABLED', + 'COM_MODULES_HTML_UNPUBLISH_DISABLED', + 'COM_MODULES_EXTENSION_PUBLISHED_DISABLED', + true, + 'warning', + 'warning', + ), + -2 => array( + 'publish', + 'COM_MODULES_EXTENSION_UNPUBLISHED_DISABLED', + 'COM_MODULES_HTML_PUBLISH_DISABLED', + 'COM_MODULES_EXTENSION_UNPUBLISHED_DISABLED', + true, + 'unpublish', + 'unpublish', + ), + ); + + return JHtml::_('jgrid.state', $states, $value, $i, 'modules.', $enabled, true, $checkbox); + } + + /** + * Display a batch widget for the module position selector. + * + * @param integer $clientId The client ID. + * @param integer $state The state of the module (enabled, unenabled, trashed). + * @param string $selectedPosition The currently selected position for the module. + * + * @return string The necessary positions for the widget. + * + * @since 2.5 + */ + public static function positions($clientId, $state = 1, $selectedPosition = '') + { + JLoader::register('TemplatesHelper', JPATH_ADMINISTRATOR . '/components/com_templates/helpers/templates.php'); + + $templates = array_keys(ModulesHelper::getTemplates($clientId, $state)); + $templateGroups = array(); + + // Add an empty value to be able to deselect a module position + $option = ModulesHelper::createOption(); + $templateGroups[''] = ModulesHelper::createOptionGroup('', array($option)); + + // Add positions from templates + $isTemplatePosition = false; + + foreach ($templates as $template) + { + $options = array(); + + $positions = TemplatesHelper::getPositions($clientId, $template); + + if (is_array($positions)) + { + foreach ($positions as $position) + { + $text = ModulesHelper::getTranslatedModulePosition($clientId, $template, $position) . ' [' . $position . ']'; + $options[] = ModulesHelper::createOption($position, $text); + + if (!$isTemplatePosition && $selectedPosition === $position) + { + $isTemplatePosition = true; + } + } + + $options = ArrayHelper::sortObjects($options, 'text'); + } + + $templateGroups[$template] = ModulesHelper::createOptionGroup(ucfirst($template), $options); + } + + // Add custom position to options + $customGroupText = JText::_('COM_MODULES_CUSTOM_POSITION'); + + $editPositions = true; + $customPositions = ModulesHelper::getPositions($clientId, $editPositions); + $templateGroups[$customGroupText] = ModulesHelper::createOptionGroup($customGroupText, $customPositions); + + return $templateGroups; + } + + /** + * Get a select with the batch action options + * + * @return void + */ + public static function batchOptions() + { + // Create the copy/move options. + $options = array( + JHtml::_('select.option', 'c', JText::_('JLIB_HTML_BATCH_COPY')), + JHtml::_('select.option', 'm', JText::_('JLIB_HTML_BATCH_MOVE')) + ); + + echo JHtml::_('select.radiolist', $options, 'batch[move_copy]', '', 'value', 'text', 'm'); + } + + /** + * Method to get the field options. + * + * @param integer $clientId The client ID + * + * @return array The field option objects. + * + * @since 2.5 + */ + public static function positionList($clientId = 0) + { + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->select('DISTINCT(position) as value') + ->select('position as text') + ->from($db->quoteName('#__modules')) + ->where($db->quoteName('client_id') . ' = ' . (int) $clientId) + ->order('position'); + + // Get the options. + $db->setQuery($query); + + try + { + $options = $db->loadObjectList(); + } + catch (RuntimeException $e) + { + JError::raiseWarning(500, $e->getMessage()); + } + + // Pop the first item off the array if it's blank + if (count($options)) + { + if (strlen($options[0]->text) < 1) + { + array_shift($options); + } + } + + return $options; + } +} diff --git a/Sites/pages/administrator/components/com_modules/helpers/modules.php b/Sites/pages/administrator/components/com_modules/helpers/modules.php new file mode 100644 index 00000000..b87a4f8e --- /dev/null +++ b/Sites/pages/administrator/components/com_modules/helpers/modules.php @@ -0,0 +1,359 @@ +getQuery(true) + ->select('DISTINCT(position)') + ->from('#__modules') + ->where($db->quoteName('client_id') . ' = ' . (int) $clientId) + ->order('position'); + + $db->setQuery($query); + + try + { + $positions = $db->loadColumn(); + $positions = is_array($positions) ? $positions : array(); + } + catch (RuntimeException $e) + { + JError::raiseWarning(500, $e->getMessage()); + + return; + } + + // Build the list + $options = array(); + + foreach ($positions as $position) + { + if (!$position && !$editPositions) + { + $options[] = JHtml::_('select.option', 'none', JText::_('COM_MODULES_NONE')); + } + else + { + $options[] = JHtml::_('select.option', $position, $position); + } + } + + return $options; + } + + /** + * Return a list of templates + * + * @param integer $clientId Client ID + * @param string $state State + * @param string $template Template name + * + * @return array List of templates + */ + public static function getTemplates($clientId = 0, $state = '', $template = '') + { + $db = JFactory::getDbo(); + + // Get the database object and a new query object. + $query = $db->getQuery(true); + + // Build the query. + $query->select('element, name, enabled') + ->from('#__extensions') + ->where('client_id = ' . (int) $clientId) + ->where('type = ' . $db->quote('template')); + + if ($state != '') + { + $query->where('enabled = ' . $db->quote($state)); + } + + if ($template != '') + { + $query->where('element = ' . $db->quote($template)); + } + + // Set the query and load the templates. + $db->setQuery($query); + $templates = $db->loadObjectList('element'); + + return $templates; + } + + /** + * Get a list of the unique modules installed in the client application. + * + * @param int $clientId The client id. + * + * @return array Array of unique modules + */ + public static function getModules($clientId) + { + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->select('element AS value, name AS text') + ->from('#__extensions as e') + ->where('e.client_id = ' . (int) $clientId) + ->where('type = ' . $db->quote('module')) + ->join('LEFT', '#__modules as m ON m.module=e.element AND m.client_id=e.client_id') + ->where('m.module IS NOT NULL') + ->group('element,name'); + + $db->setQuery($query); + $modules = $db->loadObjectList(); + $lang = JFactory::getLanguage(); + + foreach ($modules as $i => $module) + { + $extension = $module->value; + $path = $clientId ? JPATH_ADMINISTRATOR : JPATH_SITE; + $source = $path . "/modules/$extension"; + $lang->load("$extension.sys", $path, null, false, true) + || $lang->load("$extension.sys", $source, null, false, true); + $modules[$i]->text = JText::_($module->text); + } + + $modules = ArrayHelper::sortObjects($modules, 'text', 1, true, true); + + return $modules; + } + + /** + * Get a list of the assignment options for modules to menus. + * + * @param int $clientId The client id. + * + * @return array + */ + public static function getAssignmentOptions($clientId) + { + $options = array(); + $options[] = JHtml::_('select.option', '0', 'COM_MODULES_OPTION_MENU_ALL'); + $options[] = JHtml::_('select.option', '-', 'COM_MODULES_OPTION_MENU_NONE'); + + if ($clientId == 0) + { + $options[] = JHtml::_('select.option', '1', 'COM_MODULES_OPTION_MENU_INCLUDE'); + $options[] = JHtml::_('select.option', '-1', 'COM_MODULES_OPTION_MENU_EXCLUDE'); + } + + return $options; + } + + /** + * Return a translated module position name + * + * @param integer $clientId Application client id 0: site | 1: admin + * @param string $template Template name + * @param string $position Position name + * + * @return string Return a translated position name + * + * @since 3.0 + */ + public static function getTranslatedModulePosition($clientId, $template, $position) + { + // Template translation + $lang = JFactory::getLanguage(); + $path = $clientId ? JPATH_ADMINISTRATOR : JPATH_SITE; + + $loaded = $lang->getPaths('tpl_' . $template . '.sys'); + + // Only load the template's language file if it hasn't been already + if (!$loaded) + { + $lang->load('tpl_' . $template . '.sys', $path, null, false, false) + || $lang->load('tpl_' . $template . '.sys', $path . '/templates/' . $template, null, false, false) + || $lang->load('tpl_' . $template . '.sys', $path, $lang->getDefault(), false, false) + || $lang->load('tpl_' . $template . '.sys', $path . '/templates/' . $template, $lang->getDefault(), false, false); + } + + $langKey = strtoupper('TPL_' . $template . '_POSITION_' . $position); + $text = JText::_($langKey); + + // Avoid untranslated strings + if (!self::isTranslatedText($langKey, $text)) + { + // Modules component translation + $langKey = strtoupper('COM_MODULES_POSITION_' . $position); + $text = JText::_($langKey); + + // Avoid untranslated strings + if (!self::isTranslatedText($langKey, $text)) + { + // Try to humanize the position name + $text = ucfirst(preg_replace('/^' . $template . '\-/', '', $position)); + $text = ucwords(str_replace(array('-', '_'), ' ', $text)); + } + } + + return $text; + } + + /** + * Check if the string was translated + * + * @param string $langKey Language file text key + * @param string $text The "translated" text to be checked + * + * @return boolean Return true for translated text + * + * @since 3.0 + */ + public static function isTranslatedText($langKey, $text) + { + return $text !== $langKey; + } + + /** + * Create and return a new Option + * + * @param string $value The option value [optional] + * @param string $text The option text [optional] + * + * @return object The option as an object (stdClass instance) + * + * @since 3.0 + */ + public static function createOption($value = '', $text = '') + { + if (empty($text)) + { + $text = $value; + } + + $option = new stdClass; + $option->value = $value; + $option->text = $text; + + return $option; + } + + /** + * Create and return a new Option Group + * + * @param string $label Value and label for group [optional] + * @param array $options Array of options to insert into group [optional] + * + * @return array Return the new group as an array + * + * @since 3.0 + */ + public static function createOptionGroup($label = '', $options = array()) + { + $group = array(); + $group['value'] = $label; + $group['text'] = $label; + $group['items'] = $options; + + return $group; + } +} diff --git a/Sites/pages/administrator/components/com_modules/helpers/xml.php b/Sites/pages/administrator/components/com_modules/helpers/xml.php new file mode 100644 index 00000000..6253820a --- /dev/null +++ b/Sites/pages/administrator/components/com_modules/helpers/xml.php @@ -0,0 +1,62 @@ + $row) + { + if ($row->module == '') + { + $rows[$i]->name = 'custom'; + $rows[$i]->module = 'custom'; + $rows[$i]->descrip = 'Custom created module, using Module Manager New function'; + } + else + { + $data = JInstaller::parseXMLInstallFile($row->path . '/' . $row->file); + + if ($data['type'] == 'module') + { + $rows[$i]->name = $data['name']; + $rows[$i]->descrip = $data['description']; + } + } + } + } +} diff --git a/Sites/pages/administrator/components/com_modules/layouts/toolbar/cancelselect.php b/Sites/pages/administrator/components/com_modules/layouts/toolbar/cancelselect.php new file mode 100644 index 00000000..5e792b32 --- /dev/null +++ b/Sites/pages/administrator/components/com_modules/layouts/toolbar/cancelselect.php @@ -0,0 +1,16 @@ + + diff --git a/Sites/pages/administrator/components/com_modules/layouts/toolbar/newmodule.php b/Sites/pages/administrator/components/com_modules/layouts/toolbar/newmodule.php new file mode 100644 index 00000000..21f3b39e --- /dev/null +++ b/Sites/pages/administrator/components/com_modules/layouts/toolbar/newmodule.php @@ -0,0 +1,17 @@ + + diff --git a/Sites/pages/administrator/components/com_modules/models/fields/modulesmodule.php b/Sites/pages/administrator/components/com_modules/models/fields/modulesmodule.php new file mode 100644 index 00000000..d1485bf5 --- /dev/null +++ b/Sites/pages/administrator/components/com_modules/models/fields/modulesmodule.php @@ -0,0 +1,44 @@ +getUserState('com_modules.modules.client_id', 0)); + + return array_merge(parent::getOptions(), $options); + } +} diff --git a/Sites/pages/administrator/components/com_modules/models/fields/modulesposition.php b/Sites/pages/administrator/components/com_modules/models/fields/modulesposition.php new file mode 100644 index 00000000..a15cb8dd --- /dev/null +++ b/Sites/pages/administrator/components/com_modules/models/fields/modulesposition.php @@ -0,0 +1,44 @@ +getUserState('com_modules.modules.client_id', 0)); + + return array_merge(parent::getOptions(), $options); + } +} diff --git a/Sites/pages/administrator/components/com_modules/models/forms/advanced.xml b/Sites/pages/administrator/components/com_modules/models/forms/advanced.xml new file mode 100644 index 00000000..eee1a2dc --- /dev/null +++ b/Sites/pages/administrator/components/com_modules/models/forms/advanced.xml @@ -0,0 +1,50 @@ + +
    + +
    + + + + + + + + + + +
    +
    +
    diff --git a/Sites/pages/administrator/components/com_modules/models/forms/filter_modules.xml b/Sites/pages/administrator/components/com_modules/models/forms/filter_modules.xml new file mode 100644 index 00000000..57c095c6 --- /dev/null +++ b/Sites/pages/administrator/components/com_modules/models/forms/filter_modules.xml @@ -0,0 +1,122 @@ + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Sites/pages/administrator/components/com_modules/models/forms/filter_modulesadmin.xml b/Sites/pages/administrator/components/com_modules/models/forms/filter_modulesadmin.xml new file mode 100644 index 00000000..f3b4cc6e --- /dev/null +++ b/Sites/pages/administrator/components/com_modules/models/forms/filter_modulesadmin.xml @@ -0,0 +1,111 @@ + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Sites/pages/administrator/components/com_modules/models/forms/module.xml b/Sites/pages/administrator/components/com_modules/models/forms/module.xml new file mode 100644 index 00000000..ea43b185 --- /dev/null +++ b/Sites/pages/administrator/components/com_modules/models/forms/module.xml @@ -0,0 +1,172 @@ + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    diff --git a/Sites/pages/administrator/components/com_modules/models/forms/moduleadmin.xml b/Sites/pages/administrator/components/com_modules/models/forms/moduleadmin.xml new file mode 100644 index 00000000..5766d1ca --- /dev/null +++ b/Sites/pages/administrator/components/com_modules/models/forms/moduleadmin.xml @@ -0,0 +1,166 @@ + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    diff --git a/Sites/pages/administrator/components/com_modules/models/module.php b/Sites/pages/administrator/components/com_modules/models/module.php new file mode 100644 index 00000000..afdc2e9c --- /dev/null +++ b/Sites/pages/administrator/components/com_modules/models/module.php @@ -0,0 +1,1142 @@ + 'batchAccess', + 'language_id' => 'batchLanguage', + ); + + /** + * Constructor. + * + * @param array $config An optional associative array of configuration settings. + */ + public function __construct($config = array()) + { + $config = array_merge( + array( + 'event_after_delete' => 'onExtensionAfterDelete', + 'event_after_save' => 'onExtensionAfterSave', + 'event_before_delete' => 'onExtensionBeforeDelete', + 'event_before_save' => 'onExtensionBeforeSave', + 'events_map' => array( + 'save' => 'extension', + 'delete' => 'extension' + ) + ), $config + ); + + parent::__construct($config); + } + + /** + * Method to auto-populate the model state. + * + * Note. Calling getState in this method will result in recursion. + * + * @return void + * + * @since 1.6 + */ + protected function populateState() + { + $app = JFactory::getApplication('administrator'); + + // Load the User state. + $pk = $app->input->getInt('id'); + + if (!$pk) + { + if ($extensionId = (int) $app->getUserState('com_modules.add.module.extension_id')) + { + $this->setState('extension.id', $extensionId); + } + } + + $this->setState('module.id', $pk); + + // Load the parameters. + $params = JComponentHelper::getParams('com_modules'); + $this->setState('params', $params); + } + + /** + * Batch copy modules to a new position or current. + * + * @param integer $value The new value matching a module position. + * @param array $pks An array of row IDs. + * @param array $contexts An array of item contexts. + * + * @return boolean True if successful, false otherwise and internal error is set. + * + * @since 2.5 + */ + protected function batchCopy($value, $pks, $contexts) + { + // Set the variables + $user = JFactory::getUser(); + $table = $this->getTable(); + $newIds = array(); + + foreach ($pks as $pk) + { + if ($user->authorise('core.create', 'com_modules')) + { + $table->reset(); + $table->load($pk); + + // Set the new position + if ($value == 'noposition') + { + $position = ''; + } + elseif ($value == 'nochange') + { + $position = $table->position; + } + else + { + $position = $value; + } + + $table->position = $position; + + // Copy of the Asset ID + $oldAssetId = $table->asset_id; + + // Alter the title if necessary + $data = $this->generateNewTitle(0, $table->title, $table->position); + $table->title = $data['0']; + + // Reset the ID because we are making a copy + $table->id = 0; + + // Unpublish the new module + $table->published = 0; + + if (!$table->store()) + { + $this->setError($table->getError()); + + return false; + } + + // Get the new item ID + $newId = $table->get('id'); + + // Add the new ID to the array + $newIds[$pk] = $newId; + + // Now we need to handle the module assignments + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select($db->quoteName('menuid')) + ->from($db->quoteName('#__modules_menu')) + ->where($db->quoteName('moduleid') . ' = ' . $pk); + $db->setQuery($query); + $menus = $db->loadColumn(); + + // Insert the new records into the table + foreach ($menus as $menu) + { + $query->clear() + ->insert($db->quoteName('#__modules_menu')) + ->columns(array($db->quoteName('moduleid'), $db->quoteName('menuid'))) + ->values($newId . ', ' . $menu); + $db->setQuery($query); + $db->execute(); + } + + // Copy rules + $query->clear() + ->update($db->quoteName('#__assets', 't')) + ->join('INNER', $db->quoteName('#__assets', 's') . + ' ON ' . $db->quoteName('s.id') . ' = ' . $oldAssetId + ) + ->set($db->quoteName('t.rules') . ' = ' . $db->quoteName('s.rules')) + ->where($db->quoteName('t.id') . ' = ' . $table->asset_id); + + $db->setQuery($query)->execute(); + } + else + { + $this->setError(JText::_('JLIB_APPLICATION_ERROR_BATCH_CANNOT_CREATE')); + + return false; + } + } + + // Clean the cache + $this->cleanCache(); + + return $newIds; + } + + /** + * Batch move modules to a new position or current. + * + * @param integer $value The new value matching a module position. + * @param array $pks An array of row IDs. + * @param array $contexts An array of item contexts. + * + * @return boolean True if successful, false otherwise and internal error is set. + * + * @since 2.5 + */ + protected function batchMove($value, $pks, $contexts) + { + // Set the variables + $user = JFactory::getUser(); + $table = $this->getTable(); + + foreach ($pks as $pk) + { + if ($user->authorise('core.edit', 'com_modules')) + { + $table->reset(); + $table->load($pk); + + // Set the new position + if ($value == 'noposition') + { + $position = ''; + } + elseif ($value == 'nochange') + { + $position = $table->position; + } + else + { + $position = $value; + } + + $table->position = $position; + + if (!$table->store()) + { + $this->setError($table->getError()); + + return false; + } + } + else + { + $this->setError(JText::_('JLIB_APPLICATION_ERROR_BATCH_CANNOT_EDIT')); + + return false; + } + } + + // Clean the cache + $this->cleanCache(); + + return true; + } + + /** + * Method to test whether a record can have its state edited. + * + * @param object $record A record object. + * + * @return boolean True if allowed to change the state of the record. Defaults to the permission set in the component. + * + * @since 3.2 + */ + protected function canEditState($record) + { + // Check for existing module. + if (!empty($record->id)) + { + return JFactory::getUser()->authorise('core.edit.state', 'com_modules.module.' . (int) $record->id); + } + + // Default to component settings if module not known. + return parent::canEditState($record); + } + + /** + * Method to delete rows. + * + * @param array &$pks An array of item ids. + * + * @return boolean Returns true on success, false on failure. + * + * @since 1.6 + * @throws Exception + */ + public function delete(&$pks) + { + $dispatcher = JEventDispatcher::getInstance(); + $pks = (array) $pks; + $user = JFactory::getUser(); + $table = $this->getTable(); + $context = $this->option . '.' . $this->name; + + // Include the plugins for the on delete events. + JPluginHelper::importPlugin($this->events_map['delete']); + + // Iterate the items to delete each one. + foreach ($pks as $pk) + { + if ($table->load($pk)) + { + // Access checks. + if (!$user->authorise('core.delete', 'com_modules.module.' . (int) $pk) || $table->published != -2) + { + JError::raiseWarning(403, JText::_('JERROR_CORE_DELETE_NOT_PERMITTED')); + + return; + } + + // Trigger the before delete event. + $result = $dispatcher->trigger($this->event_before_delete, array($context, $table)); + + if (in_array(false, $result, true) || !$table->delete($pk)) + { + throw new Exception($table->getError()); + } + else + { + // Delete the menu assignments + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->delete('#__modules_menu') + ->where('moduleid=' . (int) $pk); + $db->setQuery($query); + $db->execute(); + + // Trigger the after delete event. + $dispatcher->trigger($this->event_after_delete, array($context, $table)); + } + + // Clear module cache + parent::cleanCache($table->module, $table->client_id); + } + else + { + throw new Exception($table->getError()); + } + } + + // Clear modules cache + $this->cleanCache(); + + return true; + } + + /** + * Method to duplicate modules. + * + * @param array &$pks An array of primary key IDs. + * + * @return boolean|JException Boolean true on success, JException instance on error + * + * @since 1.6 + * @throws Exception + */ + public function duplicate(&$pks) + { + $user = JFactory::getUser(); + $db = $this->getDbo(); + + // Access checks. + if (!$user->authorise('core.create', 'com_modules')) + { + throw new Exception(JText::_('JERROR_CORE_CREATE_NOT_PERMITTED')); + } + + $table = $this->getTable(); + + foreach ($pks as $pk) + { + if ($table->load($pk, true)) + { + // Reset the id to create a new record. + $table->id = 0; + + // Alter the title. + $m = null; + + if (preg_match('#\((\d+)\)$#', $table->title, $m)) + { + $table->title = preg_replace('#\(\d+\)$#', '(' . ($m[1] + 1) . ')', $table->title); + } + + $data = $this->generateNewTitle(0, $table->title, $table->position); + $table->title = $data[0]; + + // Unpublish duplicate module + $table->published = 0; + + if (!$table->check() || !$table->store()) + { + throw new Exception($table->getError()); + } + + $query = $db->getQuery(true) + ->select($db->quoteName('menuid')) + ->from($db->quoteName('#__modules_menu')) + ->where($db->quoteName('moduleid') . ' = ' . (int) $pk); + + $db->setQuery($query); + $rows = $db->loadColumn(); + + foreach ($rows as $menuid) + { + $tuples[] = (int) $table->id . ',' . (int) $menuid; + } + } + else + { + throw new Exception($table->getError()); + } + } + + if (!empty($tuples)) + { + // Module-Menu Mapping: Do it in one query + $query = $db->getQuery(true) + ->insert($db->quoteName('#__modules_menu')) + ->columns($db->quoteName(array('moduleid', 'menuid'))) + ->values($tuples); + + $db->setQuery($query); + + try + { + $db->execute(); + } + catch (RuntimeException $e) + { + return JError::raiseWarning(500, $e->getMessage()); + } + } + + // Clear modules cache + $this->cleanCache(); + + return true; + } + + /** + * Method to change the title. + * + * @param integer $categoryId The id of the category. Not used here. + * @param string $title The title. + * @param string $position The position. + * + * @return array Contains the modified title. + * + * @since 2.5 + */ + protected function generateNewTitle($categoryId, $title, $position) + { + // Alter the title & alias + $table = $this->getTable(); + + while ($table->load(array('position' => $position, 'title' => $title))) + { + $title = StringHelper::increment($title); + } + + return array($title); + } + + /** + * Method to get the client object + * + * @return void + * + * @since 1.6 + */ + public function &getClient() + { + return $this->_client; + } + + /** + * Method to get the record form. + * + * @param array $data Data for the form. + * @param boolean $loadData True if the form is to load its own data (default case), false if not. + * + * @return JForm A JForm object on success, false on failure + * + * @since 1.6 + */ + public function getForm($data = array(), $loadData = true) + { + // The folder and element vars are passed when saving the form. + if (empty($data)) + { + $item = $this->getItem(); + $clientId = $item->client_id; + $module = $item->module; + $id = $item->id; + } + else + { + $clientId = ArrayHelper::getValue($data, 'client_id'); + $module = ArrayHelper::getValue($data, 'module'); + $id = ArrayHelper::getValue($data, 'id'); + } + + // Add the default fields directory + $baseFolder = $clientId ? JPATH_ADMINISTRATOR : JPATH_SITE; + JForm::addFieldPath($baseFolder . '/modules' . '/' . $module . '/field'); + + // These variables are used to add data from the plugin XML files. + $this->setState('item.client_id', $clientId); + $this->setState('item.module', $module); + + // Get the form. + if ($clientId == 1) + { + $form = $this->loadForm('com_modules.module.admin', 'moduleadmin', array('control' => 'jform', 'load_data' => $loadData), true); + + // Display language field to filter admin custom menus per language + if (!JModuleHelper::isAdminMultilang()) + { + $form->setFieldAttribute('language', 'type', 'hidden'); + } + } + else + { + $form = $this->loadForm('com_modules.module', 'module', array('control' => 'jform', 'load_data' => $loadData), true); + } + + if (empty($form)) + { + return false; + } + + $form->setFieldAttribute('position', 'client', $this->getState('item.client_id') == 0 ? 'site' : 'administrator'); + + $user = JFactory::getUser(); + + /** + * Check for existing module + * Modify the form based on Edit State access controls. + */ + if ($id != 0 && (!$user->authorise('core.edit.state', 'com_modules.module.' . (int) $id)) + || ($id == 0 && !$user->authorise('core.edit.state', 'com_modules')) ) + { + // Disable fields for display. + $form->setFieldAttribute('ordering', 'disabled', 'true'); + $form->setFieldAttribute('published', 'disabled', 'true'); + $form->setFieldAttribute('publish_up', 'disabled', 'true'); + $form->setFieldAttribute('publish_down', 'disabled', 'true'); + + // Disable fields while saving. + // The controller has already verified this is a record you can edit. + $form->setFieldAttribute('ordering', 'filter', 'unset'); + $form->setFieldAttribute('published', 'filter', 'unset'); + $form->setFieldAttribute('publish_up', 'filter', 'unset'); + $form->setFieldAttribute('publish_down', 'filter', 'unset'); + } + + return $form; + } + + /** + * Method to get the data that should be injected in the form. + * + * @return mixed The data for the form. + * + * @since 1.6 + */ + protected function loadFormData() + { + $app = JFactory::getApplication(); + + // Check the session for previously entered form data. + $data = $app->getUserState('com_modules.edit.module.data', array()); + + if (empty($data)) + { + $data = $this->getItem(); + + // Pre-select some filters (Status, Module Position, Language, Access Level) in edit form if those have been selected in Module Manager + if (!$data->id) + { + $filters = (array) $app->getUserState('com_modules.modules.filter'); + $data->set('published', $app->input->getInt('published', ((isset($filters['state']) && $filters['state'] !== '') ? $filters['state'] : null))); + $data->set('position', $app->input->getInt('position', (!empty($filters['position']) ? $filters['position'] : null))); + $data->set('language', $app->input->getString('language', (!empty($filters['language']) ? $filters['language'] : null))); + $data->set('access', $app->input->getInt('access', (!empty($filters['access']) ? $filters['access'] : JFactory::getConfig()->get('access')))); + } + + // Avoid to delete params of a second module opened in a new browser tab while new one is not saved yet. + if (empty($data->params)) + { + // This allows us to inject parameter settings into a new module. + $params = $app->getUserState('com_modules.add.module.params'); + + if (is_array($params)) + { + $data->set('params', $params); + } + } + } + + $this->preprocessData('com_modules.module', $data); + + return $data; + } + + /** + * Method to get a single record. + * + * @param integer $pk The id of the primary key. + * + * @return mixed Object on success, false on failure. + * + * @since 1.6 + */ + public function getItem($pk = null) + { + $pk = (!empty($pk)) ? (int) $pk : (int) $this->getState('module.id'); + $db = $this->getDbo(); + + if (!isset($this->_cache[$pk])) + { + // Get a row instance. + $table = $this->getTable(); + + // Attempt to load the row. + $return = $table->load($pk); + + // Check for a table object error. + if ($return === false && $error = $table->getError()) + { + $this->setError($error); + + return false; + } + + // Check if we are creating a new extension. + if (empty($pk)) + { + if ($extensionId = (int) $this->getState('extension.id')) + { + $query = $db->getQuery(true) + ->select('element, client_id') + ->from('#__extensions') + ->where('extension_id = ' . $extensionId) + ->where('type = ' . $db->quote('module')); + $db->setQuery($query); + + try + { + $extension = $db->loadObject(); + } + catch (RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + + if (empty($extension)) + { + $this->setError('COM_MODULES_ERROR_CANNOT_FIND_MODULE'); + + return false; + } + + // Extension found, prime some module values. + $table->module = $extension->element; + $table->client_id = $extension->client_id; + } + else + { + JFactory::getApplication()->redirect(JRoute::_('index.php?option=com_modules&view=modules', false)); + + return false; + } + } + + // Convert to the JObject before adding other data. + $properties = $table->getProperties(1); + $this->_cache[$pk] = ArrayHelper::toObject($properties, 'JObject'); + + // Convert the params field to an array. + $registry = new Registry($table->params); + $this->_cache[$pk]->params = $registry->toArray(); + + // Determine the page assignment mode. + $query = $db->getQuery(true) + ->select($db->quoteName('menuid')) + ->from($db->quoteName('#__modules_menu')) + ->where($db->quoteName('moduleid') . ' = ' . (int) $pk); + $db->setQuery($query); + $assigned = $db->loadColumn(); + + if (empty($pk)) + { + // If this is a new module, assign to all pages. + $assignment = 0; + } + elseif (empty($assigned)) + { + // For an existing module it is assigned to none. + $assignment = '-'; + } + else + { + if ($assigned[0] > 0) + { + $assignment = 1; + } + elseif ($assigned[0] < 0) + { + $assignment = -1; + } + else + { + $assignment = 0; + } + } + + $this->_cache[$pk]->assigned = $assigned; + $this->_cache[$pk]->assignment = $assignment; + + // Get the module XML. + $client = JApplicationHelper::getClientInfo($table->client_id); + $path = JPath::clean($client->path . '/modules/' . $table->module . '/' . $table->module . '.xml'); + + if (file_exists($path)) + { + $this->_cache[$pk]->xml = simplexml_load_file($path); + } + else + { + $this->_cache[$pk]->xml = null; + } + } + + return $this->_cache[$pk]; + } + + /** + * Get the necessary data to load an item help screen. + * + * @return object An object with key, url, and local properties for loading the item help screen. + * + * @since 1.6 + */ + public function getHelp() + { + return (object) array('key' => $this->helpKey, 'url' => $this->helpURL); + } + + /** + * Returns a reference to the a Table object, always creating it. + * + * @param string $type The table type to instantiate + * @param string $prefix A prefix for the table class name. Optional. + * @param array $config Configuration array for model. Optional. + * + * @return JTable A database object + * + * @since 1.6 + */ + public function getTable($type = 'Module', $prefix = 'JTable', $config = array()) + { + return JTable::getInstance($type, $prefix, $config); + } + + /** + * Prepare and sanitise the table prior to saving. + * + * @param JTable $table The database object + * + * @return void + * + * @since 1.6 + */ + protected function prepareTable($table) + { + $table->title = htmlspecialchars_decode($table->title, ENT_QUOTES); + $table->position = trim($table->position); + } + + /** + * Method to preprocess the form + * + * @param JForm $form A form object. + * @param mixed $data The data expected for the form. + * @param string $group The name of the plugin group to import (defaults to "content"). + * + * @return void + * + * @since 1.6 + * @throws Exception if there is an error loading the form. + */ + protected function preprocessForm(JForm $form, $data, $group = 'content') + { + jimport('joomla.filesystem.path'); + + $lang = JFactory::getLanguage(); + $clientId = $this->getState('item.client_id'); + $module = $this->getState('item.module'); + + $client = JApplicationHelper::getClientInfo($clientId); + $formFile = JPath::clean($client->path . '/modules/' . $module . '/' . $module . '.xml'); + + // Load the core and/or local language file(s). + $lang->load($module, $client->path, null, false, true) + || $lang->load($module, $client->path . '/modules/' . $module, null, false, true); + + if (file_exists($formFile)) + { + // Get the module form. + if (!$form->loadFile($formFile, false, '//config')) + { + throw new Exception(JText::_('JERROR_LOADFILE_FAILED')); + } + + // Attempt to load the xml file. + if (!$xml = simplexml_load_file($formFile)) + { + throw new Exception(JText::_('JERROR_LOADFILE_FAILED')); + } + + // Get the help data from the XML file if present. + $help = $xml->xpath('/extension/help'); + + if (!empty($help)) + { + $helpKey = trim((string) $help[0]['key']); + $helpURL = trim((string) $help[0]['url']); + + $this->helpKey = $helpKey ?: $this->helpKey; + $this->helpURL = $helpURL ?: $this->helpURL; + } + } + + // Load the default advanced params + JForm::addFormPath(JPATH_ADMINISTRATOR . '/components/com_modules/models/forms'); + $form->loadFile('advanced', false); + + // Trigger the default form events. + parent::preprocessForm($form, $data, $group); + } + + /** + * Loads ContentHelper for filters before validating data. + * + * @param object $form The form to validate against. + * @param array $data The data to validate. + * @param string $group The name of the group(defaults to null). + * + * @return mixed Array of filtered data if valid, false otherwise. + * + * @since 1.1 + */ + public function validate($form, $data, $group = null) + { + JLoader::register('ContentHelper', JPATH_ADMINISTRATOR . '/components/com_content/helpers/content.php'); + + if (!JFactory::getUser()->authorise('core.admin', 'com_modules')) + { + if (isset($data['rules'])) + { + unset($data['rules']); + } + } + + return parent::validate($form, $data, $group); + } + + /** + * Method to save the form data. + * + * @param array $data The form data. + * + * @return boolean True on success. + * + * @since 1.6 + */ + public function save($data) + { + $dispatcher = JEventDispatcher::getInstance(); + $input = JFactory::getApplication()->input; + $table = $this->getTable(); + $pk = (!empty($data['id'])) ? $data['id'] : (int) $this->getState('module.id'); + $isNew = true; + $context = $this->option . '.' . $this->name; + + // Include the plugins for the save event. + JPluginHelper::importPlugin($this->events_map['save']); + + // Load the row if saving an existing record. + if ($pk > 0) + { + $table->load($pk); + $isNew = false; + } + + // Alter the title and published state for Save as Copy + if ($input->get('task') == 'save2copy') + { + $orig_table = clone $this->getTable(); + $orig_table->load((int) $input->getInt('id')); + $data['published'] = 0; + + if ($data['title'] == $orig_table->title) + { + $data['title'] = StringHelper::increment($data['title']); + } + } + + // Bind the data. + if (!$table->bind($data)) + { + $this->setError($table->getError()); + + return false; + } + + // Prepare the row for saving + $this->prepareTable($table); + + // Check the data. + if (!$table->check()) + { + $this->setError($table->getError()); + + return false; + } + + // Trigger the before save event. + $result = $dispatcher->trigger($this->event_before_save, array($context, &$table, $isNew)); + + if (in_array(false, $result, true)) + { + $this->setError($table->getError()); + + return false; + } + + // Store the data. + if (!$table->store()) + { + $this->setError($table->getError()); + + return false; + } + + // Process the menu link mappings. + $assignment = isset($data['assignment']) ? $data['assignment'] : 0; + + // Delete old module to menu item associations + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->delete('#__modules_menu') + ->where('moduleid = ' . (int) $table->id); + $db->setQuery($query); + + try + { + $db->execute(); + } + catch (RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + + // If the assignment is numeric, then something is selected (otherwise it's none). + if (is_numeric($assignment)) + { + // Variable is numeric, but could be a string. + $assignment = (int) $assignment; + + // Logic check: if no module excluded then convert to display on all. + if ($assignment == -1 && empty($data['assigned'])) + { + $assignment = 0; + } + + // Check needed to stop a module being assigned to `All` + // and other menu items resulting in a module being displayed twice. + if ($assignment === 0) + { + // Assign new module to `all` menu item associations. + $query->clear() + ->insert('#__modules_menu') + ->columns(array($db->quoteName('moduleid'), $db->quoteName('menuid'))) + ->values((int) $table->id . ', 0'); + $db->setQuery($query); + + try + { + $db->execute(); + } + catch (RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + } + elseif (!empty($data['assigned'])) + { + // Get the sign of the number. + $sign = $assignment < 0 ? -1 : 1; + + $query->clear() + ->insert($db->quoteName('#__modules_menu')) + ->columns($db->quoteName(array('moduleid', 'menuid'))); + + foreach ($data['assigned'] as &$pk) + { + $query->values((int) $table->id . ',' . (int) $pk * $sign); + } + + $db->setQuery($query); + + try + { + $db->execute(); + } + catch (RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + } + } + + // Trigger the after save event. + $dispatcher->trigger($this->event_after_save, array($context, &$table, $isNew)); + + // Compute the extension id of this module in case the controller wants it. + $query->clear() + ->select($db->quoteName('extension_id')) + ->from($db->quoteName('#__extensions', 'e')) + ->join( + 'LEFT', + $db->quoteName('#__modules', 'm') . ' ON ' . $db->quoteName('e.client_id') . ' = ' . (int) $table->client_id . + ' AND ' . $db->quoteName('e.element') . ' = ' . $db->quoteName('m.module') + ) + ->where($db->quoteName('m.id') . ' = ' . (int) $table->id); + $db->setQuery($query); + + try + { + $extensionId = $db->loadResult(); + } + catch (RuntimeException $e) + { + JError::raiseWarning(500, $e->getMessage()); + + return false; + } + + $this->setState('module.extension_id', $extensionId); + $this->setState('module.id', $table->id); + + // Clear modules cache + $this->cleanCache(); + + // Clean module cache + parent::cleanCache($table->module, $table->client_id); + + return true; + } + + /** + * A protected method to get a set of ordering conditions. + * + * @param object $table A record object. + * + * @return array An array of conditions to add to add to ordering queries. + * + * @since 1.6 + */ + protected function getReorderConditions($table) + { + $condition = array(); + $condition[] = 'client_id = ' . (int) $table->client_id; + $condition[] = 'position = ' . $this->_db->quote($table->position); + + return $condition; + } + + /** + * Custom clean cache method for different clients + * + * @param string $group The name of the plugin group to import (defaults to null). + * @param integer $clientId The client ID. [optional] + * + * @return void + * + * @since 1.6 + */ + protected function cleanCache($group = null, $clientId = 0) + { + parent::cleanCache('com_modules', $this->getClient()); + } +} diff --git a/Sites/pages/administrator/components/com_modules/models/modules.php b/Sites/pages/administrator/components/com_modules/models/modules.php new file mode 100644 index 00000000..1c304080 --- /dev/null +++ b/Sites/pages/administrator/components/com_modules/models/modules.php @@ -0,0 +1,427 @@ +input->get('layout', '', 'cmd'); + + // Adjust the context to support modal layouts. + if ($layout) + { + $this->context .= '.' . $layout; + } + + // Load the filter state. + $this->setState('filter.search', $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search', '', 'string')); + $this->setState('filter.position', $this->getUserStateFromRequest($this->context . '.filter.position', 'filter_position', '', 'string')); + $this->setState('filter.module', $this->getUserStateFromRequest($this->context . '.filter.module', 'filter_module', '', 'string')); + $this->setState('filter.menuitem', $this->getUserStateFromRequest($this->context . '.filter.menuitem', 'filter_menuitem', '', 'cmd')); + $this->setState('filter.access', $this->getUserStateFromRequest($this->context . '.filter.access', 'filter_access', '', 'cmd')); + + // If in modal layout on the frontend, state and language are always forced. + if ($app->isClient('site') && $layout === 'modal') + { + $this->setState('filter.language', 'current'); + $this->setState('filter.state', 1); + } + // If in backend (modal or not) we get the same fields from the user request. + else + { + $this->setState('filter.language', $this->getUserStateFromRequest($this->context . '.filter.language', 'filter_language', '', 'string')); + $this->setState('filter.state', $this->getUserStateFromRequest($this->context . '.filter.state', 'filter_state', '', 'string')); + } + + // Special case for the client id. + if ($app->isClient('site') || $layout === 'modal') + { + $this->setState('client_id', 0); + $clientId = 0; + } + else + { + $clientId = (int) $this->getUserStateFromRequest($this->context . '.client_id', 'client_id', 0, 'int'); + $clientId = (!in_array($clientId, array (0, 1))) ? 0 : $clientId; + $this->setState('client_id', $clientId); + } + + // Use a different filter file when client is administrator + if ($clientId == 1) + { + $this->filterFormName = 'filter_modulesadmin'; + } + + // Load the parameters. + $params = JComponentHelper::getParams('com_modules'); + $this->setState('params', $params); + + // List state information. + parent::populateState($ordering, $direction); + } + + /** + * Method to get a store id based on model configuration state. + * + * This is necessary because the model is used by the component and + * different modules that might need different sets of data or different + * ordering requirements. + * + * @param string $id A prefix for the store id. + * + * @return string A store id. + */ + protected function getStoreId($id = '') + { + // Compile the store id. + $id .= ':' . $this->getState('client_id'); + $id .= ':' . $this->getState('filter.search'); + $id .= ':' . $this->getState('filter.state'); + $id .= ':' . $this->getState('filter.position'); + $id .= ':' . $this->getState('filter.module'); + $id .= ':' . $this->getState('filter.menuitem'); + $id .= ':' . $this->getState('filter.access'); + $id .= ':' . $this->getState('filter.language'); + + return parent::getStoreId($id); + } + + /** + * Returns an object list + * + * @param string $query The query + * @param int $limitstart Offset + * @param int $limit The number of records + * + * @return array + */ + protected function _getList($query, $limitstart = 0, $limit = 0) + { + $listOrder = $this->getState('list.ordering', 'a.position'); + $listDirn = $this->getState('list.direction', 'asc'); + + // If ordering by fields that need translate we need to sort the array of objects after translating them. + if (in_array($listOrder, array('pages', 'name'))) + { + // Fetch the results. + $this->_db->setQuery($query); + $result = $this->_db->loadObjectList(); + + // Translate the results. + $this->translate($result); + + // Sort the array of translated objects. + $result = ArrayHelper::sortObjects($result, $listOrder, strtolower($listDirn) == 'desc' ? -1 : 1, true, true); + + // Process pagination. + $total = count($result); + $this->cache[$this->getStoreId('getTotal')] = $total; + + if ($total < $limitstart) + { + $limitstart = 0; + $this->setState('list.start', 0); + } + + return array_slice($result, $limitstart, $limit ?: null); + } + + // If ordering by fields that doesn't need translate just order the query. + if ($listOrder === 'a.ordering') + { + $query->order($this->_db->quoteName('a.position') . ' ASC') + ->order($this->_db->quoteName($listOrder) . ' ' . $this->_db->escape($listDirn)); + } + elseif ($listOrder === 'a.position') + { + $query->order($this->_db->quoteName($listOrder) . ' ' . $this->_db->escape($listDirn)) + ->order($this->_db->quoteName('a.ordering') . ' ASC'); + } + else + { + $query->order($this->_db->quoteName($listOrder) . ' ' . $this->_db->escape($listDirn)); + } + + // Process pagination. + $result = parent::_getList($query, $limitstart, $limit); + + // Translate the results. + $this->translate($result); + + return $result; + } + + /** + * Translate a list of objects + * + * @param array &$items The array of objects + * + * @return array The array of translated objects + */ + protected function translate(&$items) + { + $lang = JFactory::getLanguage(); + $clientPath = $this->getState('client_id') ? JPATH_ADMINISTRATOR : JPATH_SITE; + + foreach ($items as $item) + { + $extension = $item->module; + $source = $clientPath . "/modules/$extension"; + $lang->load("$extension.sys", $clientPath, null, false, true) + || $lang->load("$extension.sys", $source, null, false, true); + $item->name = JText::_($item->name); + + if (is_null($item->pages)) + { + $item->pages = JText::_('JNONE'); + } + elseif ($item->pages < 0) + { + $item->pages = JText::_('COM_MODULES_ASSIGNED_VARIES_EXCEPT'); + } + elseif ($item->pages > 0) + { + $item->pages = JText::_('COM_MODULES_ASSIGNED_VARIES_ONLY'); + } + else + { + $item->pages = JText::_('JALL'); + } + } + } + + /** + * Build an SQL query to load the list data. + * + * @return JDatabaseQuery + */ + protected function getListQuery() + { + $app = JFactory::getApplication(); + + // Create a new query object. + $db = $this->getDbo(); + $query = $db->getQuery(true); + + // Select the required fields. + $query->select( + $this->getState( + 'list.select', + 'a.id, a.title, a.note, a.position, a.module, a.language,' . + 'a.checked_out, a.checked_out_time, a.published AS published, e.enabled AS enabled, a.access, a.ordering, a.publish_up, a.publish_down' + ) + ); + + // From modules table. + $query->from($db->quoteName('#__modules', 'a')); + + // Join over the language + $query->select($db->quoteName('l.title', 'language_title')) + ->select($db->quoteName('l.image', 'language_image')) + ->join('LEFT', $db->quoteName('#__languages', 'l') . ' ON ' . $db->quoteName('l.lang_code') . ' = ' . $db->quoteName('a.language')); + + // Join over the users for the checked out user. + $query->select($db->quoteName('uc.name', 'editor')) + ->join('LEFT', $db->quoteName('#__users', 'uc') . ' ON ' . $db->quoteName('uc.id') . ' = ' . $db->quoteName('a.checked_out')); + + // Join over the asset groups. + $query->select($db->quoteName('ag.title', 'access_level')) + ->join('LEFT', $db->quoteName('#__viewlevels', 'ag') . ' ON ' . $db->quoteName('ag.id') . ' = ' . $db->quoteName('a.access')); + + // Join over the module menus + $query->select('MIN(mm.menuid) AS pages') + ->join('LEFT', $db->quoteName('#__modules_menu', 'mm') . ' ON ' . $db->quoteName('mm.moduleid') . ' = ' . $db->quoteName('a.id')); + + // Join over the extensions + $query->select($db->quoteName('e.name', 'name')) + ->join('LEFT', $db->quoteName('#__extensions', 'e') . ' ON ' . $db->quoteName('e.element') . ' = ' . $db->quoteName('a.module')); + + // Group (careful with PostgreSQL) + $query->group( + 'a.id, a.title, a.note, a.position, a.module, a.language, a.checked_out, ' + . 'a.checked_out_time, a.published, a.access, a.ordering, l.title, l.image, uc.name, ag.title, e.name, ' + . 'l.lang_code, uc.id, ag.id, mm.moduleid, e.element, a.publish_up, a.publish_down, e.enabled' + ); + + // Filter by client. + $clientId = $this->getState('client_id'); + $query->where($db->quoteName('a.client_id') . ' = ' . (int) $clientId . ' AND ' . $db->quoteName('e.client_id') . ' = ' . (int) $clientId); + + // Filter by current user access level. + $user = JFactory::getUser(); + + // Get the current user for authorisation checks + if ($user->authorise('core.admin') !== true) + { + $groups = implode(',', $user->getAuthorisedViewLevels()); + $query->where('a.access IN (' . $groups . ')'); + } + + // Filter by access level. + if ($access = $this->getState('filter.access')) + { + $query->where($db->quoteName('a.access') . ' = ' . (int) $access); + } + + // Filter by published state. + $state = $this->getState('filter.state'); + + if (is_numeric($state)) + { + $query->where($db->quoteName('a.published') . ' = ' . (int) $state); + } + elseif ($state === '') + { + $query->where($db->quoteName('a.published') . ' IN (0, 1)'); + } + + // Filter by position. + if ($position = $this->getState('filter.position')) + { + $query->where($db->quoteName('a.position') . ' = ' . $db->quote(($position === 'none') ? '' : $position)); + } + + // Filter by module. + if ($module = $this->getState('filter.module')) + { + $query->where($db->quoteName('a.module') . ' = ' . $db->quote($module)); + } + + // Filter by menuitem id (only for site client). + if ((int) $clientId === 0 && $menuItemId = $this->getState('filter.menuitem')) + { + // If user selected the modules not assigned to any page (menu item). + if ((int) $menuItemId === -1) + { + $query->having('MIN(' . $db->quoteName('mm.menuid') . ') IS NULL'); + } + // If user selected the modules assigned to some particular page (menu item). + else + { + // Modules in "All" pages. + $subQuery1 = $db->getQuery(true); + $subQuery1->select('MIN(' . $db->quoteName('menuid') . ')') + ->from($db->quoteName('#__modules_menu')) + ->where($db->quoteName('moduleid') . ' = ' . $db->quoteName('a.id')); + + // Modules in "Selected" pages that have the chosen menu item id. + $subQuery2 = $db->getQuery(true); + $subQuery2->select($db->quoteName('moduleid')) + ->from($db->quoteName('#__modules_menu')) + ->where($db->quoteName('menuid') . ' = ' . (int) $menuItemId); + + // Modules in "All except selected" pages that doesn't have the chosen menu item id. + $subQuery3 = $db->getQuery(true); + $subQuery3->select($db->quoteName('moduleid')) + ->from($db->quoteName('#__modules_menu')) + ->where($db->quoteName('menuid') . ' = -' . (int) $menuItemId); + + // Filter by modules assigned to the selected menu item. + $query->where('( + (' . $subQuery1 . ') = 0 + OR ((' . $subQuery1 . ') > 0 AND ' . $db->quoteName('a.id') . ' IN (' . $subQuery2 . ')) + OR ((' . $subQuery1 . ') < 0 AND ' . $db->quoteName('a.id') . ' NOT IN (' . $subQuery3 . ')) + )' + ); + } + } + + // Filter by search in title or note or id:. + $search = $this->getState('filter.search'); + + if (!empty($search)) + { + if (stripos($search, 'id:') === 0) + { + $query->where($db->quoteName('a.id') . ' = ' . (int) substr($search, 3)); + } + else + { + $search = $db->quote('%' . StringHelper::strtolower($search) . '%'); + $query->where('(LOWER(a.title) LIKE ' . $search . ' OR LOWER(a.note) LIKE ' . $search . ')'); + } + } + + // Filter on the language. + if ($language = $this->getState('filter.language')) + { + if ($language === 'current') + { + $query->where($db->quoteName('a.language') . ' IN (' . $db->quote(JFactory::getLanguage()->getTag()) . ',' . $db->quote('*') . ')'); + } + else + { + $query->where($db->quoteName('a.language') . ' = ' . $db->quote($language)); + } + } + + return $query; + } +} diff --git a/Sites/pages/administrator/components/com_modules/models/positions.php b/Sites/pages/administrator/components/com_modules/models/positions.php new file mode 100644 index 00000000..ca2d1530 --- /dev/null +++ b/Sites/pages/administrator/components/com_modules/models/positions.php @@ -0,0 +1,244 @@ +getUserStateFromRequest($this->context . '.filter.search', 'filter_search'); + $this->setState('filter.search', $search); + + $state = $this->getUserStateFromRequest($this->context . '.filter.state', 'filter_state', '', 'string'); + $this->setState('filter.state', $state); + + $template = $this->getUserStateFromRequest($this->context . '.filter.template', 'filter_template', '', 'string'); + $this->setState('filter.template', $template); + + $type = $this->getUserStateFromRequest($this->context . '.filter.type', 'filter_type', '', 'string'); + $this->setState('filter.type', $type); + + // Special case for the client id. + $clientId = (int) $this->getUserStateFromRequest($this->context . '.client_id', 'client_id', 0, 'int'); + $clientId = (!in_array((int) $clientId, array (0, 1))) ? 0 : (int) $clientId; + $this->setState('client_id', $clientId); + + // Load the parameters. + $params = JComponentHelper::getParams('com_modules'); + $this->setState('params', $params); + + // List state information. + parent::populateState($ordering, $direction); + } + + /** + * Method to get an array of data items. + * + * @return mixed An array of data items on success, false on failure. + * + * @since 1.6 + */ + public function getItems() + { + if (!isset($this->items)) + { + $lang = JFactory::getLanguage(); + $search = $this->getState('filter.search'); + $state = $this->getState('filter.state'); + $clientId = $this->getState('client_id'); + $filter_template = $this->getState('filter.template'); + $type = $this->getState('filter.type'); + $ordering = $this->getState('list.ordering'); + $direction = $this->getState('list.direction'); + $limitstart = $this->getState('list.start'); + $limit = $this->getState('list.limit'); + $client = JApplicationHelper::getClientInfo($clientId); + + if ($type != 'template') + { + // Get the database object and a new query object. + $query = $this->_db->getQuery(true) + ->select('DISTINCT(position) as value') + ->from('#__modules') + ->where($this->_db->quoteName('client_id') . ' = ' . (int) $clientId); + + if ($search) + { + $search = $this->_db->quote('%' . str_replace(' ', '%', $this->_db->escape(trim($search), true) . '%')); + $query->where('position LIKE ' . $search); + } + + $this->_db->setQuery($query); + + try + { + $positions = $this->_db->loadObjectList('value'); + } + catch (RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + + foreach ($positions as $value => $position) + { + $positions[$value] = array(); + } + } + else + { + $positions = array(); + } + + // Load the positions from the installed templates. + foreach (ModulesHelper::getTemplates($clientId) as $template) + { + $path = JPath::clean($client->path . '/templates/' . $template->element . '/templateDetails.xml'); + + if (file_exists($path)) + { + $xml = simplexml_load_file($path); + + if (isset($xml->positions[0])) + { + $lang->load('tpl_' . $template->element . '.sys', $client->path, null, false, true) + || $lang->load('tpl_' . $template->element . '.sys', $client->path . '/templates/' . $template->element, null, false, true); + + foreach ($xml->positions[0] as $position) + { + $value = (string) $position['value']; + $label = (string) $position; + + if (!$value) + { + $value = $label; + $label = preg_replace('/[^a-zA-Z0-9_\-]/', '_', 'TPL_' . $template->element . '_POSITION_' . $value); + $altlabel = preg_replace('/[^a-zA-Z0-9_\-]/', '_', 'COM_MODULES_POSITION_' . $value); + + if (!$lang->hasKey($label) && $lang->hasKey($altlabel)) + { + $label = $altlabel; + } + } + + if ($type == 'user' || ($state != '' && $state != $template->enabled)) + { + unset($positions[$value]); + } + elseif (preg_match(chr(1) . $search . chr(1) . 'i', $value) && ($filter_template == '' || $filter_template == $template->element)) + { + if (!isset($positions[$value])) + { + $positions[$value] = array(); + } + + $positions[$value][$template->name] = $label; + } + } + } + } + } + + $this->total = count($positions); + + if ($limitstart >= $this->total) + { + $limitstart = $limitstart < $limit ? 0 : $limitstart - $limit; + $this->setState('list.start', $limitstart); + } + + if ($ordering == 'value') + { + if ($direction == 'asc') + { + ksort($positions); + } + else + { + krsort($positions); + } + } + else + { + if ($direction == 'asc') + { + asort($positions); + } + else + { + arsort($positions); + } + } + + $this->items = array_slice($positions, $limitstart, $limit ?: null); + } + + return $this->items; + } + + /** + * Method to get the total number of items. + * + * @return integer The total number of items. + * + * @since 1.6 + */ + public function getTotal() + { + if (!isset($this->total)) + { + $this->getItems(); + } + + return $this->total; + } +} diff --git a/Sites/pages/administrator/components/com_modules/models/select.php b/Sites/pages/administrator/components/com_modules/models/select.php new file mode 100644 index 00000000..133f7e49 --- /dev/null +++ b/Sites/pages/administrator/components/com_modules/models/select.php @@ -0,0 +1,157 @@ +getUserState('com_modules.modules.client_id', 0); + $this->setState('client_id', (int) $clientId); + + // Load the parameters. + $params = JComponentHelper::getParams('com_modules'); + $this->setState('params', $params); + + // Manually set limits to get all modules. + $this->setState('list.limit', 0); + $this->setState('list.start', 0); + $this->setState('list.ordering', 'a.name'); + $this->setState('list.direction', 'ASC'); + } + + /** + * Method to get a store id based on model configuration state. + * + * This is necessary because the model is used by the component and + * different modules that might need different sets of data or different + * ordering requirements. + * + * @param string $id A prefix for the store id. + * + * @return string A store id. + */ + protected function getStoreId($id = '') + { + // Compile the store id. + $id .= ':' . $this->getState('client_id'); + + return parent::getStoreId($id); + } + + /** + * Build an SQL query to load the list data. + * + * @return JDatabaseQuery + */ + protected function getListQuery() + { + // Create a new query object. + $db = $this->getDbo(); + $query = $db->getQuery(true); + + // Select the required fields from the table. + $query->select( + $this->getState( + 'list.select', + 'a.extension_id, a.name, a.element AS module' + ) + ); + $query->from($db->quoteName('#__extensions') . ' AS a'); + + // Filter by module + $query->where('a.type = ' . $db->quote('module')); + + // Filter by client. + $clientId = $this->getState('client_id'); + $query->where('a.client_id = ' . (int) $clientId); + + // Filter by enabled + $query->where('a.enabled = 1'); + + // Add the list ordering clause. + $query->order($db->escape($this->getState('list.ordering', 'a.ordering')) . ' ' . $db->escape($this->getState('list.direction', 'ASC'))); + + return $query; + } + + /** + * Method to get a list of items. + * + * @return mixed An array of objects on success, false on failure. + */ + public function getItems() + { + // Get the list of items from the database. + $items = parent::getItems(); + + $client = JApplicationHelper::getClientInfo($this->getState('client_id', 0)); + $lang = JFactory::getLanguage(); + + // Loop through the results to add the XML metadata, + // and load language support. + foreach ($items as &$item) + { + $path = JPath::clean($client->path . '/modules/' . $item->module . '/' . $item->module . '.xml'); + + if (file_exists($path)) + { + $item->xml = simplexml_load_file($path); + } + else + { + $item->xml = null; + } + + // 1.5 Format; Core files or language packs then + // 1.6 3PD Extension Support + $lang->load($item->module . '.sys', $client->path, null, false, true) + || $lang->load($item->module . '.sys', $client->path . '/modules/' . $item->module, null, false, true); + $item->name = JText::_($item->name); + + if (isset($item->xml) && $text = trim($item->xml->description)) + { + $item->desc = JText::_($text); + } + else + { + $item->desc = JText::_('COM_MODULES_NODESCRIPTION'); + } + } + + $items = ArrayHelper::sortObjects($items, 'name', 1, true, true); + + // TODO: Use the cached XML from the extensions table? + + return $items; + } +} diff --git a/Sites/pages/administrator/components/com_modules/modules.php b/Sites/pages/administrator/components/com_modules/modules.php new file mode 100644 index 00000000..f42adc67 --- /dev/null +++ b/Sites/pages/administrator/components/com_modules/modules.php @@ -0,0 +1,24 @@ +input; + +if (($input->get('layout') !== 'modal' && $input->get('view') !== 'modules') + && !$user->authorise('core.manage', 'com_modules')) +{ + throw new JAccessExceptionNotallowed(JText::_('JERROR_ALERTNOAUTHOR'), 403); +} + +$controller = JControllerLegacy::getInstance('Modules'); +$controller->execute(JFactory::getApplication()->input->get('task')); +$controller->redirect(); diff --git a/Sites/pages/administrator/components/com_modules/modules.xml b/Sites/pages/administrator/components/com_modules/modules.xml new file mode 100644 index 00000000..94eb1d0a --- /dev/null +++ b/Sites/pages/administrator/components/com_modules/modules.xml @@ -0,0 +1,27 @@ + + + com_modules + Joomla! Project + April 2006 + (C) 2005 - 2020 Open Source Matters. All rights reserved. + GNU General Public License version 2 or later; see LICENSE.txt + admin@joomla.org + www.joomla.org + 3.0.0 + COM_MODULES_XML_DESCRIPTION + + + config.xml + controller.php + modules.php + controllers + helpers + models + views + + + language/en-GB.com_modules.ini + language/en-GB.com_modules.sys.ini + + + diff --git a/Sites/pages/administrator/components/com_modules/views/module/tmpl/edit.php b/Sites/pages/administrator/components/com_modules/views/module/tmpl/edit.php new file mode 100644 index 00000000..0e90feb0 --- /dev/null +++ b/Sites/pages/administrator/components/com_modules/views/module/tmpl/edit.php @@ -0,0 +1,296 @@ + 0 )); +JHtml::_('formbehavior.chosen', '.multipleCategories', null, array('placeholder_text_multiple' => JText::_('JOPTION_SELECT_CATEGORY'))); +JHtml::_('formbehavior.chosen', '.multipleTags', null, array('placeholder_text_multiple' => JText::_('JOPTION_SELECT_TAG'))); +JHtml::_('formbehavior.chosen', '.multipleAuthors', null, array('placeholder_text_multiple' => JText::_('JOPTION_SELECT_AUTHOR'))); +JHtml::_('formbehavior.chosen', '.multipleAuthorAliases', null, array('placeholder_text_multiple' => JText::_('JOPTION_SELECT_AUTHOR_ALIAS'))); +JHtml::_('formbehavior.chosen', 'select'); + +$hasContent = isset($this->item->xml->customContent); +$hasContentFieldName = 'content'; + +// For a later improvement +if ($hasContent) +{ + $hasContentFieldName = 'content'; +} + +// Get Params Fieldsets +$this->fieldsets = $this->form->getFieldsets('params'); + +$script = " + Joomla.submitbutton = function(task) { + if (task == 'module.cancel' || document.formvalidator.isValid(document.getElementById('module-form'))) + { +"; +if ($hasContent) +{ + $script .= $this->form->getField($hasContentFieldName)->save(); +} +$script .= " + Joomla.submitform(task, document.getElementById('module-form')); + + jQuery('#permissions-sliders select').attr('disabled', 'disabled'); + + if (self != top) + { + if (parent.viewLevels) + { + var updPosition = jQuery('#jform_position').chosen().val(), + updTitle = jQuery('#jform_title').val(), + updMenus = jQuery('#jform_assignment').chosen().val(), + updStatus = jQuery('#jform_published').chosen().val(), + updAccess = jQuery('#jform_access').chosen().val(), + tmpMenu = jQuery('#menus-" . $this->item->id . "', parent.document), + tmpRow = jQuery('#tr-" . $this->item->id . "', parent.document); + tmpStatus = jQuery('#status-" . $this->item->id . "', parent.document); + window.parent.inMenus = new Array(); + window.parent.numMenus = jQuery(':input[name=\"jform[assigned][]\"]').length; + + jQuery('input[name=\"jform[assigned][]\"]').each(function(){ + if (updMenus > 0 ) + { + if (jQuery(this).is(':checked')) + { + window.parent.inMenus.push(parseInt(jQuery(this).val())); + } + } + if (updMenus < 0 ) + { + if (!jQuery(this).is(':checked')) + { + window.parent.inMenus.push(parseInt(jQuery(this).val())); + } + } + }); + if (updMenus == 0) { + tmpMenu.html('" . JText::_('JALL') . "'); + if (tmpRow.hasClass('no')) { tmpRow.removeClass('no '); } + } + if (updMenus == '-') { + tmpMenu.html('" . JText::_('JNO') . "'); + if (!tmpRow.hasClass('no') || tmpRow.hasClass('')) { tmpRow.addClass('no '); } + } + if (updMenus > 0) { + if (window.parent.inMenus.indexOf(parent.menuId) >= 0) + { + if (window.parent.numMenus == window.parent.inMenus.length) + { + tmpMenu.html('" . JText::_('JALL') . "'); + if (tmpRow.hasClass('no') || tmpRow.hasClass('')) { tmpRow.removeClass('no'); } + } + else + { + tmpMenu.html('" . JText::_('JYES') . "'); + if (tmpRow.hasClass('no')) { tmpRow.removeClass('no'); } + } + } + if (window.parent.inMenus.indexOf(parent.menuId) < 0) + { + tmpMenu.html('" . JText::_('JNO') . "'); + if (!tmpRow.hasClass('no')) { tmpRow.addClass('no'); } + } + } + if (updMenus < 0) { + if (window.parent.inMenus.indexOf(parent.menuId) >= 0) + { + if (window.parent.numMenus == window.parent.inMenus.length) + { + tmpMenu.html('" . JText::_('JALL') . "'); + if (tmpRow.hasClass('no')) { tmpRow.removeClass('no'); } + } + else + { + tmpMenu.html('" . JText::_('JYES') . "'); + if (tmpRow.hasClass('no')) { tmpRow.removeClass('no'); } + } + } + if (window.parent.inMenus.indexOf(parent.menuId) < 0) + { + tmpMenu.html('" . JText::_('JNO') . "'); + if (!tmpRow.hasClass('no') || tmpRow.hasClass('')) { tmpRow.addClass('no'); } + } + } + if (updStatus == 1) { + tmpStatus.html('" . JText::_('JYES') . "'); + if (tmpRow.hasClass('unpublished')) { tmpRow.removeClass('unpublished '); } + } + if (updStatus == 0) { + tmpStatus.html('" . JText::_('JNO') . "'); + if (!tmpRow.hasClass('unpublished') || tmpRow.hasClass('')) { tmpRow.addClass('unpublished'); } + } + if (updStatus == -2) { + tmpStatus.html('" . JText::_('JTRASHED') . "'); + if (!tmpRow.hasClass('unpublished') || tmpRow.hasClass('')) { tmpRow.addClass('unpublished'); } + } + if (document.formvalidator.isValid(document.getElementById('module-form'))) { + jQuery('#title-" . $this->item->id . "', parent.document).text(updTitle); + jQuery('#position-" . $this->item->id . "', parent.document).text(updPosition); + jQuery('#access-" . $this->item->id . "', parent.document).html(parent.viewLevels[updAccess]); + } + } + } + + if (task !== 'module.apply') + { + window.parent.jQuery('#module" . ((int) $this->item->id == 0 ? 'Add' : 'Edit' . (int) $this->item->id) . "Modal').modal('hide'); + } + } + };"; + +JFactory::getDocument()->addScriptDeclaration($script); + +$input = JFactory::getApplication()->input; + +// In case of modal +$isModal = $input->get('layout') == 'modal' ? true : false; +$layout = $isModal ? 'modal' : 'edit'; +$tmpl = $isModal || $input->get('tmpl', '', 'cmd') === 'component' ? '&tmpl=component' : ''; +?> + +
    + + + +
    + 'general')); ?> + + + +
    +
    + item->xml) : ?> + item->xml->description) : ?> +

    + item->xml) + { + echo ($text = (string) $this->item->xml->name) ? JText::_($text) : $this->item->module; + } + else + { + echo JText::_('COM_MODULES_ERR_XML'); + } + ?> +

    +
    + + item->client_id == 0 ? JText::_('JSITE') : JText::_('JADMINISTRATOR'); ?> + +
    +
    + item->xml->description); + $this->fieldset = 'description'; + $long_description = JLayoutHelper::render('joomla.edit.fieldset', $this); + if (!$long_description) { + $truncated = JHtml::_('string.truncate', $short_description, 550, true, false); + if (strlen($truncated) > 500) { + $long_description = $short_description; + $short_description = JHtml::_('string.truncate', $truncated, 250); + if ($short_description == $long_description) { + $long_description = ''; + } + } + } + ?> +

    + +

    + + + +

    + +
    + + +
    + + form->getInput($hasContentFieldName); + } + $this->fieldset = 'basic'; + $html = JLayoutHelper::render('joomla.edit.fieldset', $this); + echo $html ? '
    ' . $html : ''; + ?> +
    +
    +
    + form->renderField('showtitle'); ?> +
    +
    + form->getLabel('position'); ?> +
    +
    + loadTemplate('positions'); ?> +
    +
    +
    + fields = array( + 'published', + 'publish_up', + 'publish_down', + 'access', + 'ordering', + 'language', + 'note' + ); + + ?> + +
    +
    + + + + + + + + + item->client_id == 0) : ?> + + loadTemplate('assignment'); ?> + + + + fieldsets = array(); + $this->ignore_fieldsets = array('basic', 'description'); + echo JLayoutHelper::render('joomla.edit.params', $this); + ?> + + canDo->get('core.admin')) : ?> + + form->getInput('rules'); ?> + + + + + + + + form->getInput('module'); ?> + form->getInput('client_id'); ?> +
    +
    diff --git a/Sites/pages/administrator/components/com_modules/views/module/tmpl/edit_assignment.php b/Sites/pages/administrator/components/com_modules/views/module/tmpl/edit_assignment.php new file mode 100644 index 00000000..fd73b8fb --- /dev/null +++ b/Sites/pages/administrator/components/com_modules/views/module/tmpl/edit_assignment.php @@ -0,0 +1,172 @@ + 'auto', 'relative' => true)); + +$script = " + jQuery(document).ready(function() + { + menuHide(jQuery('#jform_assignment').val()); + jQuery('#jform_assignment').change(function() + { + menuHide(jQuery(this).val()); + }) + }); + function menuHide(val) + { + if (val == 0 || val == '-') + { + jQuery('#menuselect-group').hide(); + } + else + { + jQuery('#menuselect-group').show(); + } + } +"; + +// Add the script to the document head +JFactory::getDocument()->addScriptDeclaration($script); +?> +
    + + +
    + +
    +
    + diff --git a/Sites/pages/administrator/components/com_modules/views/module/tmpl/edit_options.php b/Sites/pages/administrator/components/com_modules/views/module/tmpl/edit_options.php new file mode 100644 index 00000000..cb6d8ebf --- /dev/null +++ b/Sites/pages/administrator/components/com_modules/views/module/tmpl/edit_options.php @@ -0,0 +1,38 @@ + + 'collapse0')); + $fieldSets = $this->form->getFieldsets('params'); + $i = 0; + + foreach ($fieldSets as $name => $fieldSet) : + $label = !empty($fieldSet->label) ? $fieldSet->label : 'COM_MODULES_' . $name . '_FIELDSET_LABEL'; + $class = isset($fieldSet->class) && !empty($fieldSet->class) ? $fieldSet->class : ''; + + echo JHtml::_('bootstrap.addSlide', 'moduleOptions', JText::_($label), 'collapse' . ($i++), $class); + if (isset($fieldSet->description) && trim($fieldSet->description)) : + echo '

    ' . $this->escape(JText::_($fieldSet->description)) . '

    '; + endif; + ?> + form->getFieldset($name) as $field) : ?> +
    +
    + label; ?> +
    +
    + input; ?> +
    +
    + item->client_id; +$state = 1; +$selectedPosition = $this->item->position; +$positions = JHtml::_('modules.positions', $clientId, $state, $selectedPosition); + + +// Add custom position to options +$customGroupText = JText::_('COM_MODULES_CUSTOM_POSITION'); + +// Build field +$attr = array( + 'id' => 'jform_position', + 'list.select' => $this->item->position, + 'list.attr' => 'class="chzn-custom-value" ' + . 'data-custom_group_text="' . $customGroupText . '" ' + . 'data-no_results_text="' . JText::_('COM_MODULES_ADD_CUSTOM_POSITION') . '" ' + . 'data-placeholder="' . JText::_('COM_MODULES_TYPE_OR_SELECT_POSITION') . '" ' +); + +echo JHtml::_('select.groupedlist', $positions, 'jform[position]', $attr); diff --git a/Sites/pages/administrator/components/com_modules/views/module/tmpl/modal.php b/Sites/pages/administrator/components/com_modules/views/module/tmpl/modal.php new file mode 100644 index 00000000..8172ef2e --- /dev/null +++ b/Sites/pages/administrator/components/com_modules/views/module/tmpl/modal.php @@ -0,0 +1,21 @@ + 'bottom')); +?> + + + + +
    + setLayout('edit'); ?> + loadTemplate(); ?> +
    diff --git a/Sites/pages/administrator/components/com_modules/views/module/view.html.php b/Sites/pages/administrator/components/com_modules/views/module/view.html.php new file mode 100644 index 00000000..51c62307 --- /dev/null +++ b/Sites/pages/administrator/components/com_modules/views/module/view.html.php @@ -0,0 +1,121 @@ +form = $this->get('Form'); + $this->item = $this->get('Item'); + $this->state = $this->get('State'); + $this->canDo = JHelperContent::getActions('com_modules', 'module', $this->item->id); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + $this->addToolbar(); + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + JFactory::getApplication()->input->set('hidemainmenu', true); + + $user = JFactory::getUser(); + $isNew = ($this->item->id == 0); + $checkedOut = !($this->item->checked_out == 0 || $this->item->checked_out == $user->get('id')); + $canDo = $this->canDo; + + JToolbarHelper::title(JText::sprintf('COM_MODULES_MANAGER_MODULE', JText::_($this->item->module)), 'cube module'); + + // For new records, check the create permission. + if ($isNew && $canDo->get('core.create')) + { + JToolbarHelper::apply('module.apply'); + JToolbarHelper::save('module.save'); + JToolbarHelper::save2new('module.save2new'); + JToolbarHelper::cancel('module.cancel'); + } + else + { + // Can't save the record if it's checked out. + if (!$checkedOut) + { + // Since it's an existing record, check the edit permission. + if ($canDo->get('core.edit')) + { + JToolbarHelper::apply('module.apply'); + JToolbarHelper::save('module.save'); + + // We can save this record, but check the create permission to see if we can return to make a new one. + if ($canDo->get('core.create')) + { + JToolbarHelper::save2new('module.save2new'); + } + } + } + + // If checked out, we can still save + if ($canDo->get('core.create')) + { + JToolbarHelper::save2copy('module.save2copy'); + } + + JToolbarHelper::cancel('module.cancel', 'JTOOLBAR_CLOSE'); + } + + // Get the help information for the menu item. + $lang = JFactory::getLanguage(); + + $help = $this->get('Help'); + + if ($lang->hasKey($help->url)) + { + $debug = $lang->setDebug(false); + $url = JText::_($help->url); + $lang->setDebug($debug); + } + else + { + $url = null; + } + + JToolbarHelper::help($help->key, false, $url); + } +} diff --git a/Sites/pages/administrator/components/com_modules/views/module/view.json.php b/Sites/pages/administrator/components/com_modules/views/module/view.json.php new file mode 100644 index 00000000..b2cd4b0d --- /dev/null +++ b/Sites/pages/administrator/components/com_modules/views/module/view.json.php @@ -0,0 +1,58 @@ +item = $this->get('Item'); + } + catch (Exception $e) + { + $app->enqueueMessage($e->getMessage(), 'error'); + + return false; + } + + $paramsList = $this->item->getProperties(); + + unset($paramsList['xml']); + + $paramsList = json_encode($paramsList); + + return $paramsList; + + } +} diff --git a/Sites/pages/administrator/components/com_modules/views/modules/tmpl/default.php b/Sites/pages/administrator/components/com_modules/views/modules/tmpl/default.php new file mode 100644 index 00000000..155a86bb --- /dev/null +++ b/Sites/pages/administrator/components/com_modules/views/modules/tmpl/default.php @@ -0,0 +1,232 @@ +state->get('client_id', 0); +$user = JFactory::getUser(); +$listOrder = $this->escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$saveOrder = ($listOrder == 'a.ordering'); +if ($saveOrder) +{ + $saveOrderingUrl = 'index.php?option=com_modules&task=modules.saveOrderAjax&tmpl=component'; + JHtml::_('sortablelist.sortable', 'moduleList', 'adminForm', strtolower($listDirn), $saveOrderingUrl); +} +$colSpan = $clientId === 1 ? 8 : 10; +?> +
    +sidebar)) : ?> +
    + sidebar; ?> +
    +
    + +
    + + $this)); ?> + total > 0) : ?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + items as $i => $item) : + $ordering = ($listOrder == 'a.ordering'); + $canCreate = $user->authorise('core.create', 'com_modules'); + $canEdit = $user->authorise('core.edit', 'com_modules.module.' . $item->id); + $canCheckin = $user->authorise('core.manage', 'com_checkin') || $item->checked_out == $user->get('id')|| $item->checked_out == 0; + $canChange = $user->authorise('core.edit.state', 'com_modules.module.' . $item->id) && $canCheckin; + ?> + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + +
    + pagination->getListFooter(); ?> +
    + + + + + + + + + enabled > 0) : ?> + id); ?> + + +
    + + enabled > 0) : ?> + published, $i, 'modules.', $canChange, 'cb', $item->publish_up, $item->publish_down); ?> + published === -2 ? 'un' : '') . 'trash', 'cb' . $i, 'modules'); + } + if ($canCreate || $canChange) + { + echo JHtml::_('actionsdropdown.render', $this->escape($item->title)); + } + ?> + + + + +
    +
    +
    + checked_out) : ?> + editor, $item->checked_out_time, 'modules.', $canCheckin); ?> + + + + escape($item->title); ?> + + escape($item->title); ?> + + + note)) : ?> +
    + escape($item->note)); ?> +
    + +
    +
    + position) : ?> + + position; ?> + + + + + + + + name; ?> + + pages; ?> + + escape($item->access_level); ?> + + + + language == ''):?> + + language == '*'):?> + + + escape($item->language); ?> + + + id; ?> +
    + + + + authorise('core.create', 'com_modules') + && $user->authorise('core.edit', 'com_modules') + && $user->authorise('core.edit.state', 'com_modules')) : ?> + JText::_('COM_MODULES_BATCH_OPTIONS'), + 'footer' => $this->loadTemplate('batch_footer'), + ), + $this->loadTemplate('batch_body') + ); ?> + + + + +
    + diff --git a/Sites/pages/administrator/components/com_modules/views/modules/tmpl/default.xml b/Sites/pages/administrator/components/com_modules/views/modules/tmpl/default.xml new file mode 100755 index 00000000..4d323670 --- /dev/null +++ b/Sites/pages/administrator/components/com_modules/views/modules/tmpl/default.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/Sites/pages/administrator/components/com_modules/views/modules/tmpl/default_batch_body.php b/Sites/pages/administrator/components/com_modules/views/modules/tmpl/default_batch_body.php new file mode 100644 index 00000000..a638e4e3 --- /dev/null +++ b/Sites/pages/administrator/components/com_modules/views/modules/tmpl/default_batch_body.php @@ -0,0 +1,72 @@ +state->get('client_id'); + +// Show only Module Positions of published Templates +$published = 1; +$positions = JHtml::_('modules.positions', $clientId, $published); +$positions['']['items'][] = ModulesHelper::createOption('nochange', JText::_('COM_MODULES_BATCH_POSITION_NOCHANGE')); +$positions['']['items'][] = ModulesHelper::createOption('noposition', JText::_('COM_MODULES_BATCH_POSITION_NOPOSITION')); + +// Add custom position to options +$customGroupText = JText::_('COM_MODULES_CUSTOM_POSITION'); + +// Build field +$attr = array( + 'id' => 'batch-position-id', + 'list.attr' => 'class="chzn-custom-value input-xlarge" ' + . 'data-custom_group_text="' . $customGroupText . '" ' + . 'data-no_results_text="' . JText::_('COM_MODULES_ADD_CUSTOM_POSITION') . '" ' + . 'data-placeholder="' . JText::_('COM_MODULES_TYPE_OR_SELECT_POSITION') . '" ' +); + +?> +
    +

    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    +
    + = 0) : ?> +
    +
    + +
    + +
    + +
    +
    +
    +
    + +
    +
    diff --git a/Sites/pages/administrator/components/com_modules/views/modules/tmpl/default_batch_footer.php b/Sites/pages/administrator/components/com_modules/views/modules/tmpl/default_batch_footer.php new file mode 100644 index 00000000..a549ef95 --- /dev/null +++ b/Sites/pages/administrator/components/com_modules/views/modules/tmpl/default_batch_footer.php @@ -0,0 +1,17 @@ + + + diff --git a/Sites/pages/administrator/components/com_modules/views/modules/tmpl/modal.php b/Sites/pages/administrator/components/com_modules/views/modules/tmpl/modal.php new file mode 100644 index 00000000..51a3c82e --- /dev/null +++ b/Sites/pages/administrator/components/com_modules/views/modules/tmpl/modal.php @@ -0,0 +1,136 @@ +isClient('site')) +{ + JSession::checkToken('get') or die(JText::_('JINVALID_TOKEN')); +} + +// Load needed scripts +JHtml::_('behavior.core'); +JHtml::_('bootstrap.tooltip', '.hasTooltip', array('placement' => 'bottom')); +JHtml::_('bootstrap.popover', '.hasPopover', array('placement' => 'bottom')); +JHtml::_('formbehavior.chosen', 'select'); + +// Scripts for the modules xtd-button +JHtml::_('behavior.polyfill', array('event'), 'lt IE 9'); +JHtml::_('script', 'com_modules/admin-modules-modal.min.js', array('version' => 'auto', 'relative' => true)); + +// Special case for the search field tooltip. +$searchFilterDesc = $this->filterForm->getFieldAttribute('search', 'description', null, 'filter'); +JHtml::_('bootstrap.tooltip', '#filter_search', array('title' => JText::_($searchFilterDesc), 'placement' => 'bottom')); + +$listOrder = $this->escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$editor = JFactory::getApplication()->input->get('editor', '', 'cmd'); +$link = 'index.php?option=com_modules&view=modules&layout=modal&tmpl=component&' . JSession::getFormToken() . '=1'; + +if (!empty($editor)) +{ + $link = 'index.php?option=com_modules&view=modules&layout=modal&tmpl=component&editor=' . $editor . '&' . JSession::getFormToken() . '=1'; +} +?> +
    + +
    + + $this)); ?> + total > 0) : ?> + + + + + + + + + + + + + + + + + + + + 'icon-trash', + 0 => 'icon-unpublish', + 1 => 'icon-publish', + 2 => 'icon-archive', + ); + foreach ($this->items as $i => $item) : + ?> + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + +
    + pagination->getListFooter(); ?> +
    + + + + escape($item->title); ?> + + + position) : ?> + escape($item->position); ?> + + + + + name; ?> + + pages; ?> + + escape($item->access_level); ?> + + + + id; ?> +
    + + + + + + + +
    +
    diff --git a/Sites/pages/administrator/components/com_modules/views/modules/view.html.php b/Sites/pages/administrator/components/com_modules/views/modules/view.html.php new file mode 100644 index 00000000..85e2f7cb --- /dev/null +++ b/Sites/pages/administrator/components/com_modules/views/modules/view.html.php @@ -0,0 +1,232 @@ +items = $this->get('Items'); + $this->pagination = $this->get('Pagination'); + $this->state = $this->get('State'); + $this->total = $this->get('Total'); + $this->filterForm = $this->get('FilterForm'); + $this->activeFilters = $this->get('ActiveFilters'); + $this->clientId = $this->state->get('client_id'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + // We do not need the Language filter when modules are not filtered + if ($this->clientId == 1 && !JModuleHelper::isAdminMultilang()) + { + unset($this->activeFilters['language']); + $this->filterForm->removeField('language', 'filter'); + } + + // We don't need the toolbar in the modal window. + if ($this->getLayout() !== 'modal') + { + $this->addToolbar(); + } + // If in modal layout. + else + { + // Client id selector should not exist. + $this->filterForm->removeField('client_id', ''); + + // If in the frontend state and language should not activate the search tools. + if (JFactory::getApplication()->isClient('site')) + { + unset($this->activeFilters['state']); + unset($this->activeFilters['language']); + } + } + + // Include the component HTML helpers. + JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html'); + + return parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + $state = $this->get('State'); + $canDo = JHelperContent::getActions('com_modules'); + $user = JFactory::getUser(); + + // Get the toolbar object instance + $bar = JToolbar::getInstance('toolbar'); + + if ($state->get('client_id') == 1) + { + JToolbarHelper::title(JText::_('COM_MODULES_MANAGER_MODULES_ADMIN'), 'cube module'); + } + else + { + JToolbarHelper::title(JText::_('COM_MODULES_MANAGER_MODULES_SITE'), 'cube module'); + } + + if ($canDo->get('core.create')) + { + // Instantiate a new JLayoutFile instance and render the layout + $layout = new JLayoutFile('toolbar.newmodule'); + + $bar->appendButton('Custom', $layout->render(array()), 'new'); + } + + if ($canDo->get('core.edit')) + { + JToolbarHelper::editList('module.edit'); + } + + if ($canDo->get('core.create')) + { + JToolbarHelper::custom('modules.duplicate', 'copy.png', 'copy_f2.png', 'JTOOLBAR_DUPLICATE', true); + } + + if ($canDo->get('core.edit.state')) + { + JToolbarHelper::publish('modules.publish', 'JTOOLBAR_PUBLISH', true); + JToolbarHelper::unpublish('modules.unpublish', 'JTOOLBAR_UNPUBLISH', true); + JToolbarHelper::checkin('modules.checkin'); + } + + // Add a batch button + if ($user->authorise('core.create', 'com_modules') && $user->authorise('core.edit', 'com_modules') + && $user->authorise('core.edit.state', 'com_modules')) + { + JHtml::_('bootstrap.renderModal', 'collapseModal'); + $title = JText::_('JTOOLBAR_BATCH'); + + // Instantiate a new JLayoutFile instance and render the batch button + $layout = new JLayoutFile('joomla.toolbar.batch'); + + $dhtml = $layout->render(array('title' => $title)); + $bar->appendButton('Custom', $dhtml, 'batch'); + } + + if ($state->get('filter.state') == -2 && $canDo->get('core.delete')) + { + JToolbarHelper::deleteList('JGLOBAL_CONFIRM_DELETE', 'modules.delete', 'JTOOLBAR_EMPTY_TRASH'); + } + elseif ($canDo->get('core.edit.state')) + { + JToolbarHelper::trash('modules.trash'); + } + + if ($canDo->get('core.admin')) + { + JToolbarHelper::preferences('com_modules'); + } + + JToolbarHelper::help('JHELP_EXTENSIONS_MODULE_MANAGER'); + + if (JHtmlSidebar::getEntries()) + { + $this->sidebar = JHtmlSidebar::render(); + } + } + + /** + * Returns an array of fields the table can be sorted by + * + * @return array Array containing the field name to sort by as the key and display text as value + * + * @since 3.0 + */ + protected function getSortFields() + { + $this->state = $this->get('State'); + + if ($this->state->get('client_id') == 0) + { + if ($this->getLayout() == 'default') + { + return array( + 'ordering' => JText::_('JGRID_HEADING_ORDERING'), + 'a.published' => JText::_('JSTATUS'), + 'a.title' => JText::_('JGLOBAL_TITLE'), + 'position' => JText::_('COM_MODULES_HEADING_POSITION'), + 'name' => JText::_('COM_MODULES_HEADING_MODULE'), + 'pages' => JText::_('COM_MODULES_HEADING_PAGES'), + 'a.access' => JText::_('JGRID_HEADING_ACCESS'), + 'language_title' => JText::_('JGRID_HEADING_LANGUAGE'), + 'a.id' => JText::_('JGRID_HEADING_ID') + ); + } + + return array( + 'a.title' => JText::_('JGLOBAL_TITLE'), + 'position' => JText::_('COM_MODULES_HEADING_POSITION'), + 'name' => JText::_('COM_MODULES_HEADING_MODULE'), + 'pages' => JText::_('COM_MODULES_HEADING_PAGES'), + 'a.access' => JText::_('JGRID_HEADING_ACCESS'), + 'language_title' => JText::_('JGRID_HEADING_LANGUAGE'), + 'a.id' => JText::_('JGRID_HEADING_ID') + ); + } + else + { + if ($this->getLayout() == 'default') + { + return array( + 'ordering' => JText::_('JGRID_HEADING_ORDERING'), + 'a.published' => JText::_('JSTATUS'), + 'a.title' => JText::_('JGLOBAL_TITLE'), + 'position' => JText::_('COM_MODULES_HEADING_POSITION'), + 'name' => JText::_('COM_MODULES_HEADING_MODULE'), + 'a.access' => JText::_('JGRID_HEADING_ACCESS'), + 'a.language' => JText::_('JGRID_HEADING_LANGUAGE'), + 'a.id' => JText::_('JGRID_HEADING_ID') + ); + } + + return array( + 'a.title' => JText::_('JGLOBAL_TITLE'), + 'position' => JText::_('COM_MODULES_HEADING_POSITION'), + 'name' => JText::_('COM_MODULES_HEADING_MODULE'), + 'a.access' => JText::_('JGRID_HEADING_ACCESS'), + 'a.language' => JText::_('JGRID_HEADING_LANGUAGE'), + 'a.id' => JText::_('JGRID_HEADING_ID') + ); + } + } +} diff --git a/Sites/pages/administrator/components/com_modules/views/positions/tmpl/modal.php b/Sites/pages/administrator/components/com_modules/views/positions/tmpl/modal.php new file mode 100644 index 00000000..295894c2 --- /dev/null +++ b/Sites/pages/administrator/components/com_modules/views/positions/tmpl/modal.php @@ -0,0 +1,106 @@ +input->getCmd('function', 'jSelectPosition'); +$lang = JFactory::getLanguage(); +$ordering = $this->escape($this->state->get('list.ordering')); +$direction = $this->escape($this->state->get('list.direction')); +$clientId = $this->state->get('client_id'); +$state = $this->state->get('filter.state'); +$template = $this->state->get('filter.template'); +$type = $this->state->get('filter.type'); +?> +
    +
    +
    + + + + + +
    + +
    + + + + + +
    +
    + + + + + + + + + + + + + + + items as $value => $templates) : ?> + + + + + + +
    + + + +
    + pagination->getListFooter(); ?> +
    + escape($value); ?> + + + +
      + $label) : ?> +
    • hasKey($label) ? JText::sprintf('COM_MODULES_MODULE_TEMPLATE_POSITION', JText::_($template), JText::_($label)) : JText::_($template); ?>
    • + +
    +
    + +
    + +
    + + + + + +
    +
    diff --git a/Sites/pages/administrator/components/com_modules/views/positions/view.html.php b/Sites/pages/administrator/components/com_modules/views/positions/view.html.php new file mode 100644 index 00000000..d81ac698 --- /dev/null +++ b/Sites/pages/administrator/components/com_modules/views/positions/view.html.php @@ -0,0 +1,48 @@ +items = $this->get('Items'); + $this->pagination = $this->get('Pagination'); + $this->state = $this->get('State'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + parent::display($tpl); + } +} diff --git a/Sites/pages/administrator/components/com_modules/views/preview/tmpl/default.php b/Sites/pages/administrator/components/com_modules/views/preview/tmpl/default.php new file mode 100644 index 00000000..2bc8bca8 --- /dev/null +++ b/Sites/pages/administrator/components/com_modules/views/preview/tmpl/default.php @@ -0,0 +1,34 @@ +addScriptDeclaration( + ' + var form = window.top.document.adminForm + var title = form.title.value; + var alltext = window.top.' . $this->editor->getContent('text') . '; + + jQuery(document).ready(function() { + document.getElementById("td-title").innerHTML = title; + document.getElementById("td-text").innerHTML = alltext; + });' +); +?> + + + + + + + + +
    diff --git a/Sites/pages/administrator/components/com_modules/views/preview/view.html.php b/Sites/pages/administrator/components/com_modules/views/preview/view.html.php new file mode 100644 index 00000000..3e25772e --- /dev/null +++ b/Sites/pages/administrator/components/com_modules/views/preview/view.html.php @@ -0,0 +1,36 @@ +get('editor'); + + $this->editor = JEditor::getInstance($editor); + + parent::display($tpl); + } +} diff --git a/Sites/pages/administrator/components/com_modules/views/select/tmpl/default.php b/Sites/pages/administrator/components/com_modules/views/select/tmpl/default.php new file mode 100644 index 00000000..11b9f238 --- /dev/null +++ b/Sites/pages/administrator/components/com_modules/views/select/tmpl/default.php @@ -0,0 +1,33 @@ + + +

    +
      +items as &$item) : ?> + + extension_id; ?> + escape($item->name); ?> + escape(strip_tags($item->desc)), 200); ?> + escape(strip_tags($item->desc)), 90); ?> +
    • + + + +
    • + +
    +
    diff --git a/Sites/pages/administrator/components/com_modules/views/select/view.html.php b/Sites/pages/administrator/components/com_modules/views/select/view.html.php new file mode 100644 index 00000000..cd241081 --- /dev/null +++ b/Sites/pages/administrator/components/com_modules/views/select/view.html.php @@ -0,0 +1,77 @@ +get('State'); + $items = $this->get('Items'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + $this->state = &$state; + $this->items = &$items; + + $this->addToolbar(); + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + $state = $this->get('State'); + + // Add page title + if ($state->get('client_id') == 1) + { + JToolbarHelper::title(JText::_('COM_MODULES_MANAGER_MODULES_ADMIN'), 'cube module'); + } + else + { + JToolbarHelper::title(JText::_('COM_MODULES_MANAGER_MODULES_SITE'), 'cube module'); + } + + // Get the toolbar object instance + $bar = JToolbar::getInstance('toolbar'); + + // Instantiate a new JLayoutFile instance and render the layout + $layout = new JLayoutFile('toolbar.cancelselect'); + + $bar->appendButton('Custom', $layout->render(array()), 'new'); + } +} diff --git a/Sites/pages/administrator/components/com_newsfeeds/access.xml b/Sites/pages/administrator/components/com_newsfeeds/access.xml new file mode 100644 index 00000000..0cf23a39 --- /dev/null +++ b/Sites/pages/administrator/components/com_newsfeeds/access.xml @@ -0,0 +1,20 @@ + + +
    + + + + + + + + +
    +
    + + + + + +
    +
    \ No newline at end of file diff --git a/Sites/pages/administrator/components/com_newsfeeds/config.xml b/Sites/pages/administrator/components/com_newsfeeds/config.xml new file mode 100644 index 00000000..9f9ec163 --- /dev/null +++ b/Sites/pages/administrator/components/com_newsfeeds/config.xml @@ -0,0 +1,482 @@ + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + + + + + + + + +
    + +
    + + +
    +
    diff --git a/Sites/pages/administrator/components/com_newsfeeds/controller.php b/Sites/pages/administrator/components/com_newsfeeds/controller.php new file mode 100644 index 00000000..10114ae2 --- /dev/null +++ b/Sites/pages/administrator/components/com_newsfeeds/controller.php @@ -0,0 +1,50 @@ +input->get('view', 'newsfeeds'); + $layout = $this->input->get('layout', 'default'); + $id = $this->input->getInt('id'); + + // Check for edit form. + if ($view == 'newsfeed' && $layout == 'edit' && !$this->checkEditId('com_newsfeeds.edit.newsfeed', $id)) + { + // Somehow the person just went to the form - we don't allow that. + $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id)); + $this->setMessage($this->getError(), 'error'); + $this->setRedirect(JRoute::_('index.php?option=com_newsfeeds&view=newsfeeds', false)); + + return false; + } + + return parent::display(); + } +} diff --git a/Sites/pages/administrator/components/com_newsfeeds/controllers/ajax.json.php b/Sites/pages/administrator/components/com_newsfeeds/controllers/ajax.json.php new file mode 100644 index 00000000..b0949ed0 --- /dev/null +++ b/Sites/pages/administrator/components/com_newsfeeds/controllers/ajax.json.php @@ -0,0 +1,87 @@ +input; + + $assocId = $input->getInt('assocId', 0); + + if ($assocId == 0) + { + echo new JResponseJson(null, JText::sprintf('JLIB_FORM_VALIDATE_FIELD_INVALID', 'assocId'), true); + + return; + } + + $excludeLang = $input->get('excludeLang', '', 'STRING'); + + $associations = JLanguageAssociations::getAssociations('com_newsfeeds', '#__newsfeeds', 'com_newsfeeds.item', (int) $assocId); + + unset($associations[$excludeLang]); + + // Add the title to each of the associated records + JTable::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_newsfeeds/tables'); + $newsfeedsTable = JTable::getInstance('Newsfeed', 'NewsfeedsTable'); + + foreach ($associations as $lang => $association) + { + $newsfeedsTable->load($association->id); + $associations[$lang]->title = $newsfeedsTable->name; + } + + $countContentLanguages = count(LanguageHelper::getContentLanguages(array(0, 1))); + + if (count($associations) == 0) + { + $message = JText::_('JGLOBAL_ASSOCIATIONS_PROPAGATE_MESSAGE_NONE'); + } + elseif ($countContentLanguages > count($associations) + 2) + { + $tags = implode(', ', array_keys($associations)); + $message = JText::sprintf('JGLOBAL_ASSOCIATIONS_PROPAGATE_MESSAGE_SOME', $tags); + } + else + { + $message = JText::_('JGLOBAL_ASSOCIATIONS_PROPAGATE_MESSAGE_ALL'); + } + + echo new JResponseJson($associations, $message); + } + } +} diff --git a/Sites/pages/administrator/components/com_newsfeeds/controllers/newsfeed.php b/Sites/pages/administrator/components/com_newsfeeds/controllers/newsfeed.php new file mode 100644 index 00000000..cf2f9f8d --- /dev/null +++ b/Sites/pages/administrator/components/com_newsfeeds/controllers/newsfeed.php @@ -0,0 +1,126 @@ +input->getInt('filter_category_id'), 'int'); + $allow = null; + + if ($categoryId) + { + // If the category has been passed in the URL check it. + $allow = JFactory::getUser()->authorise('core.create', $this->option . '.category.' . $categoryId); + } + + if ($allow === null) + { + // In the absence of better information, revert to the component permissions. + return parent::allowAdd($data); + } + else + { + return $allow; + } + } + + /** + * Method to check if you can edit a record. + * + * @param array $data An array of input data. + * @param string $key The name of the key for the primary key. + * + * @return boolean + * + * @since 1.6 + */ + protected function allowEdit($data = array(), $key = 'id') + { + $recordId = (int) isset($data[$key]) ? $data[$key] : 0; + + // Since there is no asset tracking, fallback to the component permissions. + if (!$recordId) + { + return parent::allowEdit($data, $key); + } + + // Get the item. + $item = $this->getModel()->getItem($recordId); + + // Since there is no item, return false. + if (empty($item)) + { + return false; + } + + $user = JFactory::getUser(); + + // Check if can edit own core.edit.own. + $canEditOwn = $user->authorise('core.edit.own', $this->option . '.category.' . (int) $item->catid) && $item->created_by == $user->id; + + // Check the category core.edit permissions. + return $canEditOwn || $user->authorise('core.edit', $this->option . '.category.' . (int) $item->catid); + } + + /** + * Method to run batch operations. + * + * @param object $model The model. + * + * @return boolean True if successful, false otherwise and internal error is set. + * + * @since 2.5 + */ + public function batch($model = null) + { + $this->checkToken(); + + // Set the model + $model = $this->getModel('Newsfeed', '', array()); + + // Preset the redirect + $this->setRedirect(JRoute::_('index.php?option=com_newsfeeds&view=newsfeeds' . $this->getRedirectToListAppend(), false)); + + return parent::batch($model); + } + + /** + * Function that allows child controller access to model data after the data has been saved. + * + * @param JModelLegacy $model The data model object. + * @param array $validData The validated data. + * + * @return void + * + * @since 3.1 + */ + protected function postSaveHook(JModelLegacy $model, $validData = array()) + { + + } +} diff --git a/Sites/pages/administrator/components/com_newsfeeds/controllers/newsfeeds.php b/Sites/pages/administrator/components/com_newsfeeds/controllers/newsfeeds.php new file mode 100644 index 00000000..ffb797c0 --- /dev/null +++ b/Sites/pages/administrator/components/com_newsfeeds/controllers/newsfeeds.php @@ -0,0 +1,49 @@ + true)) + { + return parent::getModel($name, $prefix, $config); + } + + /** + * Function that allows child controller access to model data + * after the item has been deleted. + * + * @param JModelLegacy $model The data model object. + * @param integer $ids The validated data. + * + * @return void + * + * @since 3.1 + */ + protected function postDeleteHook(JModelLegacy $model, $ids = null) + { + } +} diff --git a/Sites/pages/administrator/components/com_newsfeeds/helpers/associations.php b/Sites/pages/administrator/components/com_newsfeeds/helpers/associations.php new file mode 100644 index 00000000..fe5e67ae --- /dev/null +++ b/Sites/pages/administrator/components/com_newsfeeds/helpers/associations.php @@ -0,0 +1,193 @@ +getType($typeName); + + $context = $this->extension . '.item'; + $catidField = 'catid'; + + if ($typeName === 'category') + { + $context = 'com_categories.item'; + $catidField = ''; + } + + // Get the associations. + $associations = JLanguageAssociations::getAssociations( + $this->extension, + $type['tables']['a'], + $context, + $id, + 'id', + 'alias', + $catidField + ); + + return $associations; + } + + /** + * Get item information + * + * @param string $typeName The item type + * @param int $id The id of item for which we need the associated items + * + * @return JTable|null + * + * @since 3.7.0 + */ + public function getItem($typeName, $id) + { + if (empty($id)) + { + return null; + } + + $table = null; + + switch ($typeName) + { + case 'newsfeed': + $table = JTable::getInstance('Newsfeed', 'NewsfeedsTable'); + break; + + case 'category': + $table = JTable::getInstance('Category'); + break; + } + + if (empty($table)) + { + return null; + } + + $table->load($id); + + return $table; + } + + /** + * Get information about the type + * + * @param string $typeName The item type + * + * @return array Array of item types + * + * @since 3.7.0 + */ + public function getType($typeName = '') + { + $fields = $this->getFieldsTemplate(); + $tables = array(); + $joins = array(); + $support = $this->getSupportTemplate(); + $title = ''; + + if (in_array($typeName, $this->itemTypes)) + { + switch ($typeName) + { + case 'newsfeed': + $fields['title'] = 'a.name'; + $fields['state'] = 'a.published'; + + $support['state'] = true; + $support['acl'] = true; + $support['checkout'] = true; + $support['category'] = true; + $support['save2copy'] = true; + + $tables = array( + 'a' => '#__newsfeeds' + ); + $title = 'newsfeed'; + break; + + case 'category': + $fields['created_user_id'] = 'a.created_user_id'; + $fields['ordering'] = 'a.lft'; + $fields['level'] = 'a.level'; + $fields['catid'] = ''; + $fields['state'] = 'a.published'; + + $support['state'] = true; + $support['acl'] = true; + $support['checkout'] = true; + $support['level'] = true; + + $tables = array( + 'a' => '#__categories' + ); + + $title = 'category'; + break; + } + } + + return array( + 'fields' => $fields, + 'support' => $support, + 'tables' => $tables, + 'joins' => $joins, + 'title' => $title + ); + } +} diff --git a/Sites/pages/administrator/components/com_newsfeeds/helpers/html/newsfeed.php b/Sites/pages/administrator/components/com_newsfeeds/helpers/html/newsfeed.php new file mode 100644 index 00000000..ec1a8dcd --- /dev/null +++ b/Sites/pages/administrator/components/com_newsfeeds/helpers/html/newsfeed.php @@ -0,0 +1,89 @@ + $associated) + { + $associations[$tag] = (int) $associated->id; + } + + // Get the associated newsfeed items + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->select('c.id, c.name as title') + ->select('l.sef as lang_sef, lang_code') + ->from('#__newsfeeds as c') + ->select('cat.title as category_title') + ->join('LEFT', '#__categories as cat ON cat.id=c.catid') + ->where('c.id IN (' . implode(',', array_values($associations)) . ')') + ->where('c.id != ' . $newsfeedid) + ->join('LEFT', '#__languages as l ON c.language=l.lang_code') + ->select('l.image') + ->select('l.title as language_title'); + $db->setQuery($query); + + try + { + $items = $db->loadObjectList('id'); + } + catch (RuntimeException $e) + { + throw new Exception($e->getMessage(), 500); + } + + if ($items) + { + foreach ($items as &$item) + { + $text = strtoupper($item->lang_sef); + $url = JRoute::_('index.php?option=com_newsfeeds&task=newsfeed.edit&id=' . (int) $item->id); + $tooltip = htmlspecialchars($item->title, ENT_QUOTES, 'UTF-8') . '
    ' . JText::sprintf('JCATEGORY_SPRINTF', $item->category_title); + $classes = 'hasPopover label label-association label-' . $item->lang_sef; + + $item->link = '' + . $text . ''; + } + } + + JHtml::_('bootstrap.popover'); + + $html = JLayoutHelper::render('joomla.content.associations', $items); + } + + return $html; + } +} diff --git a/Sites/pages/administrator/components/com_newsfeeds/helpers/newsfeeds.php b/Sites/pages/administrator/components/com_newsfeeds/helpers/newsfeeds.php new file mode 100644 index 00000000..4c0b2d2e --- /dev/null +++ b/Sites/pages/administrator/components/com_newsfeeds/helpers/newsfeeds.php @@ -0,0 +1,89 @@ + 'newsfeeds', + 'state_col' => 'published', + 'group_col' => 'catid', + 'relation_type' => 'category_or_group', + ); + + return parent::countRelations($items, $config); + } + + /** + * Adds Count Items for Tag Manager. + * + * @param stdClass[] &$items The tag objects + * @param string $extension The name of the active view. + * + * @return stdClass[] + * + * @since 3.6 + */ + public static function countTagItems(&$items, $extension) + { + $parts = explode('.', $extension); + $section = count($parts) > 1 ? $parts[1] : null; + + $config = (object) array( + 'related_tbl' => ($section === 'category' ? 'categories' : 'newsfeeds'), + 'state_col' => 'published', + 'group_col' => 'tag_id', + 'extension' => $extension, + 'relation_type' => 'tag_assigments', + ); + + return parent::countRelations($items, $config); + } +} diff --git a/Sites/pages/administrator/components/com_newsfeeds/models/fields/modal/newsfeed.php b/Sites/pages/administrator/components/com_newsfeeds/models/fields/modal/newsfeed.php new file mode 100644 index 00000000..95b847f8 --- /dev/null +++ b/Sites/pages/administrator/components/com_newsfeeds/models/fields/modal/newsfeed.php @@ -0,0 +1,300 @@ +element['new'] == 'true'); + $allowEdit = ((string) $this->element['edit'] == 'true'); + $allowClear = ((string) $this->element['clear'] != 'false'); + $allowSelect = ((string) $this->element['select'] != 'false'); + $allowPropagate = ((string) $this->element['propagate'] == 'true'); + + $languages = LanguageHelper::getContentLanguages(array(0, 1)); + + // Load language + JFactory::getLanguage()->load('com_newsfeeds', JPATH_ADMINISTRATOR); + + // The active newsfeed id field. + $value = (int) $this->value > 0 ? (int) $this->value : ''; + + // Create the modal id. + $modalId = 'Newsfeed_' . $this->id; + + // Add the modal field script to the document head. + JHtml::_('jquery.framework'); + JHtml::_('script', 'system/modal-fields.js', array('version' => 'auto', 'relative' => true)); + + // Script to proxy the select modal function to the modal-fields.js file. + if ($allowSelect) + { + static $scriptSelect = null; + + if (is_null($scriptSelect)) + { + $scriptSelect = array(); + } + + if (!isset($scriptSelect[$this->id])) + { + JFactory::getDocument()->addScriptDeclaration(" + function jSelectNewsfeed_" . $this->id . "(id, title, object) { + window.processModalSelect('Newsfeed', '" . $this->id . "', id, title, '', object); + } + " + ); + + JText::script('JGLOBAL_ASSOCIATIONS_PROPAGATE_FAILED'); + + $scriptSelect[$this->id] = true; + } + } + + // Setup variables for display. + $linkNewsfeeds = 'index.php?option=com_newsfeeds&view=newsfeeds&layout=modal&tmpl=component&' . JSession::getFormToken() . '=1'; + $linkNewsfeed = 'index.php?option=com_newsfeeds&view=newsfeed&layout=modal&tmpl=component&' . JSession::getFormToken() . '=1'; + $modalTitle = JText::_('COM_NEWSFEEDS_CHANGE_FEED'); + + if (isset($this->element['language'])) + { + $linkNewsfeeds .= '&forcedLanguage=' . $this->element['language']; + $linkNewsfeed .= '&forcedLanguage=' . $this->element['language']; + $modalTitle .= ' — ' . $this->element['label']; + } + + $urlSelect = $linkNewsfeeds . '&function=jSelectNewsfeed_' . $this->id; + $urlEdit = $linkNewsfeed . '&task=newsfeed.edit&id=\' + document.getElementById("' . $this->id . '_id").value + \''; + $urlNew = $linkNewsfeed . '&task=newsfeed.add'; + + if ($value) + { + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->select($db->quoteName('name')) + ->from($db->quoteName('#__newsfeeds')) + ->where($db->quoteName('id') . ' = ' . (int) $value); + $db->setQuery($query); + + try + { + $title = $db->loadResult(); + } + catch (RuntimeException $e) + { + JError::raiseWarning(500, $e->getMessage()); + } + } + + $title = empty($title) ? JText::_('COM_NEWSFEEDS_SELECT_A_FEED') : htmlspecialchars($title, ENT_QUOTES, 'UTF-8'); + + // The current newsfeed display field. + $html = ''; + $html .= ''; + + // Select newsfeed button + if ($allowSelect) + { + $html .= '' + . ' ' . JText::_('JSELECT') + . ''; + } + + // New newsfeed button + if ($allowNew) + { + $html .= '' + . ' ' . JText::_('JACTION_CREATE') + . ''; + } + + // Edit newsfeed button + if ($allowEdit) + { + $html .= '' + . ' ' . JText::_('JACTION_EDIT') + . ''; + } + + // Clear newsfeed button + if ($allowClear) + { + $html .= '' + . '' . JText::_('JCLEAR') + . ''; + } + + // Propagate newsfeed button + if ($allowPropagate && count($languages) > 2) + { + // Strip off language tag at the end + $tagLength = (int) strlen($this->element['language']); + $callbackFunctionStem = substr("jSelectNewsfeed_" . $this->id, 0, -$tagLength); + + $html .= '' + . '' . JText::_('JGLOBAL_ASSOCIATIONS_PROPAGATE_BUTTON') + . ''; + } + + $html .= ''; + + // Select newsfeed modal + if ($allowSelect) + { + $html .= JHtml::_( + 'bootstrap.renderModal', + 'ModalSelect' . $modalId, + array( + 'title' => $modalTitle, + 'url' => $urlSelect, + 'height' => '400px', + 'width' => '800px', + 'bodyHeight' => '70', + 'modalWidth' => '80', + 'footer' => '', + ) + ); + } + + // New newsfeed modal + if ($allowNew) + { + $html .= JHtml::_( + 'bootstrap.renderModal', + 'ModalNew' . $modalId, + array( + 'title' => JText::_('COM_NEWSFEEDS_NEW_NEWSFEED'), + 'backdrop' => 'static', + 'keyboard' => false, + 'closeButton' => false, + 'url' => $urlNew, + 'height' => '400px', + 'width' => '800px', + 'bodyHeight' => '70', + 'modalWidth' => '80', + 'footer' => '' + . '' + . '', + ) + ); + } + + // Edit newsfeed modal. + if ($allowEdit) + { + $html .= JHtml::_( + 'bootstrap.renderModal', + 'ModalEdit' . $modalId, + array( + 'title' => JText::_('COM_NEWSFEEDS_EDIT_NEWSFEED'), + 'backdrop' => 'static', + 'keyboard' => false, + 'closeButton' => false, + 'url' => $urlEdit, + 'height' => '400px', + 'width' => '800px', + 'bodyHeight' => '70', + 'modalWidth' => '80', + 'footer' => '' + . '' + . '', + ) + ); + } + + // Add class='required' for client side validation + $class = $this->required ? ' class="required modal-value"' : ''; + + $html .= ''; + + return $html; + } + + /** + * Method to get the field label markup. + * + * @return string The field label markup. + * + * @since 3.4 + */ + protected function getLabel() + { + return str_replace($this->id, $this->id . '_id', parent::getLabel()); + } +} diff --git a/Sites/pages/administrator/components/com_newsfeeds/models/fields/newsfeeds.php b/Sites/pages/administrator/components/com_newsfeeds/models/fields/newsfeeds.php new file mode 100644 index 00000000..4448da52 --- /dev/null +++ b/Sites/pages/administrator/components/com_newsfeeds/models/fields/newsfeeds.php @@ -0,0 +1,63 @@ +getQuery(true) + ->select('id As value, name As text') + ->from('#__newsfeeds AS a') + ->order('a.name'); + + // Get the options. + $db->setQuery($query); + + try + { + $options = $db->loadObjectList(); + } + catch (RuntimeException $e) + { + JError::raiseWarning(500, $db->getMessage()); + } + + // Merge any additional options in the XML definition. + $options = array_merge(parent::getOptions(), $options); + + return $options; + } +} diff --git a/Sites/pages/administrator/components/com_newsfeeds/models/forms/filter_newsfeeds.xml b/Sites/pages/administrator/components/com_newsfeeds/models/forms/filter_newsfeeds.xml new file mode 100644 index 00000000..8e60abac --- /dev/null +++ b/Sites/pages/administrator/components/com_newsfeeds/models/forms/filter_newsfeeds.xml @@ -0,0 +1,137 @@ + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    diff --git a/Sites/pages/administrator/components/com_newsfeeds/models/forms/newsfeed.xml b/Sites/pages/administrator/components/com_newsfeeds/models/forms/newsfeed.xml new file mode 100644 index 00000000..6153e839 --- /dev/null +++ b/Sites/pages/administrator/components/com_newsfeeds/models/forms/newsfeed.xml @@ -0,0 +1,494 @@ + +
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    + + + + + + + + + + + + +
    +
    +
    diff --git a/Sites/pages/administrator/components/com_newsfeeds/models/newsfeed.php b/Sites/pages/administrator/components/com_newsfeeds/models/newsfeed.php new file mode 100644 index 00000000..3de3dc45 --- /dev/null +++ b/Sites/pages/administrator/components/com_newsfeeds/models/newsfeed.php @@ -0,0 +1,483 @@ +id) || $record->published != -2) + { + return false; + } + + if (!empty($record->catid)) + { + return JFactory::getUser()->authorise('core.delete', 'com_newsfeed.category.' . (int) $record->catid); + } + + return parent::canDelete($record); + } + + /** + * Method to test whether a record can have its state changed. + * + * @param object $record A record object. + * + * @return boolean True if allowed to change the state of the record. Defaults to the permission set in the component. + * + * @since 1.6 + */ + protected function canEditState($record) + { + if (!empty($record->catid)) + { + return JFactory::getUser()->authorise('core.edit.state', 'com_newsfeeds.category.' . (int) $record->catid); + } + + return parent::canEditState($record); + } + + /** + * Returns a Table object, always creating it. + * + * @param string $type The table type to instantiate + * @param string $prefix A prefix for the table class name. Optional. + * @param array $config Configuration array for model. Optional. + * + * @return JTable A database object + * + * @since 1.6 + */ + public function getTable($type = 'Newsfeed', $prefix = 'NewsfeedsTable', $config = array()) + { + return JTable::getInstance($type, $prefix, $config); + } + + /** + * Method to get the record form. + * + * @param array $data Data for the form. + * @param boolean $loadData True if the form is to load its own data (default case), false if not. + * + * @return JForm A JForm object on success, false on failure + * + * @since 1.6 + */ + public function getForm($data = array(), $loadData = true) + { + // Get the form. + $form = $this->loadForm('com_newsfeeds.newsfeed', 'newsfeed', array('control' => 'jform', 'load_data' => $loadData)); + + if (empty($form)) + { + return false; + } + + // Determine correct permissions to check. + if ($this->getState('newsfeed.id')) + { + // Existing record. Can only edit in selected categories. + $form->setFieldAttribute('catid', 'action', 'core.edit'); + } + else + { + // New record. Can only create in selected categories. + $form->setFieldAttribute('catid', 'action', 'core.create'); + } + + // Modify the form based on access controls. + if (!$this->canEditState((object) $data)) + { + // Disable fields for display. + $form->setFieldAttribute('ordering', 'disabled', 'true'); + $form->setFieldAttribute('published', 'disabled', 'true'); + $form->setFieldAttribute('publish_up', 'disabled', 'true'); + $form->setFieldAttribute('publish_down', 'disabled', 'true'); + + // Disable fields while saving. + // The controller has already verified this is a record you can edit. + $form->setFieldAttribute('ordering', 'filter', 'unset'); + $form->setFieldAttribute('published', 'filter', 'unset'); + $form->setFieldAttribute('publish_up', 'filter', 'unset'); + $form->setFieldAttribute('publish_down', 'filter', 'unset'); + } + + return $form; + } + + /** + * Method to get the data that should be injected in the form. + * + * @return mixed The data for the form. + * + * @since 1.6 + */ + protected function loadFormData() + { + // Check the session for previously entered form data. + $data = JFactory::getApplication()->getUserState('com_newsfeeds.edit.newsfeed.data', array()); + + if (empty($data)) + { + $data = $this->getItem(); + + // Prime some default values. + if ($this->getState('newsfeed.id') == 0) + { + $app = JFactory::getApplication(); + $data->set('catid', $app->input->get('catid', $app->getUserState('com_newsfeeds.newsfeeds.filter.category_id'), 'int')); + } + } + + $this->preprocessData('com_newsfeeds.newsfeed', $data); + + return $data; + } + + /** + * Method to save the form data. + * + * @param array $data The form data. + * + * @return boolean True on success. + * + * @since 3.0 + */ + public function save($data) + { + $input = JFactory::getApplication()->input; + + JLoader::register('CategoriesHelper', JPATH_ADMINISTRATOR . '/components/com_categories/helpers/categories.php'); + + // Create new category, if needed. + $createCategory = true; + + // If category ID is provided, check if it's valid. + if (is_numeric($data['catid']) && $data['catid']) + { + $createCategory = !CategoriesHelper::validateCategoryId($data['catid'], 'com_newsfeeds'); + } + + // Save New Category + if ($createCategory && $this->canCreateCategory()) + { + $table = array(); + + // Remove #new# prefix, if exists. + $table['title'] = strpos($data['catid'], '#new#') === 0 ? substr($data['catid'], 5) : $data['catid']; + $table['parent_id'] = 1; + $table['extension'] = 'com_newsfeeds'; + $table['language'] = $data['language']; + $table['published'] = 1; + + // Create new category and get catid back + $data['catid'] = CategoriesHelper::createCategory($table); + } + + // Alter the name for save as copy + if ($input->get('task') == 'save2copy') + { + $origTable = clone $this->getTable(); + $origTable->load($input->getInt('id')); + + if ($data['name'] == $origTable->name) + { + list($name, $alias) = $this->generateNewTitle($data['catid'], $data['alias'], $data['name']); + $data['name'] = $name; + $data['alias'] = $alias; + } + else + { + if ($data['alias'] == $origTable->alias) + { + $data['alias'] = ''; + } + } + + $data['published'] = 0; + } + + return parent::save($data); + } + + /** + * Method to get a single record. + * + * @param integer $pk The id of the primary key. + * + * @return mixed Object on success, false on failure. + * + * @since 1.6 + */ + public function getItem($pk = null) + { + if ($item = parent::getItem($pk)) + { + // Convert the params field to an array. + $registry = new Registry($item->metadata); + $item->metadata = $registry->toArray(); + + // Convert the images field to an array. + $registry = new Registry($item->images); + $item->images = $registry->toArray(); + } + + // Load associated newsfeeds items + $app = JFactory::getApplication(); + $assoc = JLanguageAssociations::isEnabled(); + + if ($assoc) + { + $item->associations = array(); + + if ($item->id != null) + { + $associations = JLanguageAssociations::getAssociations('com_newsfeeds', '#__newsfeeds', 'com_newsfeeds.item', $item->id); + + foreach ($associations as $tag => $association) + { + $item->associations[$tag] = $association->id; + } + } + } + + if (!empty($item->id)) + { + $item->tags = new JHelperTags; + $item->tags->getTagIds($item->id, 'com_newsfeeds.newsfeed'); + $item->metadata['tags'] = $item->tags; + } + + return $item; + } + + /** + * Prepare and sanitise the table prior to saving. + * + * @param JTable $table The table object + * + * @return void + */ + protected function prepareTable($table) + { + $date = JFactory::getDate(); + $user = JFactory::getUser(); + + $table->name = htmlspecialchars_decode($table->name, ENT_QUOTES); + $table->alias = JApplicationHelper::stringURLSafe($table->alias, $table->language); + + if (empty($table->alias)) + { + $table->alias = JApplicationHelper::stringURLSafe($table->name, $table->language); + } + + if (empty($table->id)) + { + // Set the values + $table->created = $date->toSql(); + + // Set ordering to the last item if not set + if (empty($table->ordering)) + { + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select('MAX(ordering)') + ->from($db->quoteName('#__newsfeeds')); + $db->setQuery($query); + $max = $db->loadResult(); + + $table->ordering = $max + 1; + } + } + else + { + // Set the values + $table->modified = $date->toSql(); + $table->modified_by = $user->get('id'); + } + + // Increment the content version number. + $table->version++; + } + + /** + * Method to change the published state of one or more records. + * + * @param array &$pks A list of the primary keys to change. + * @param integer $value The value of the published state. + * + * @return boolean True on success. + * + * @since 1.6 + */ + public function publish(&$pks, $value = 1) + { + $result = parent::publish($pks, $value); + + // Clean extra cache for newsfeeds + $this->cleanCache('feed_parser'); + + return $result; + } + + /** + * A protected method to get a set of ordering conditions. + * + * @param object $table A record object. + * + * @return array An array of conditions to add to add to ordering queries. + * + * @since 1.6 + */ + protected function getReorderConditions($table) + { + $condition = array(); + $condition[] = 'catid = ' . (int) $table->catid; + + return $condition; + } + + /** + * A protected method to get a set of ordering conditions. + * + * @param JForm $form The form object. + * @param array $data The data to be injected into the form + * @param string $group The plugin group to process + * + * @return array An array of conditions to add to add to ordering queries. + * + * @since 1.6 + */ + protected function preprocessForm(JForm $form, $data, $group = 'content') + { + if ($this->canCreateCategory()) + { + $form->setFieldAttribute('catid', 'allowAdd', 'true'); + + // Add a prefix for categories created on the fly. + $form->setFieldAttribute('catid', 'customPrefix', '#new#'); + } + + // Association newsfeeds items + if (JLanguageAssociations::isEnabled()) + { + $languages = JLanguageHelper::getContentLanguages(false, true, null, 'ordering', 'asc'); + + if (count($languages) > 1) + { + $addform = new SimpleXMLElement('
    '); + $fields = $addform->addChild('fields'); + $fields->addAttribute('name', 'associations'); + $fieldset = $fields->addChild('fieldset'); + $fieldset->addAttribute('name', 'item_associations'); + + foreach ($languages as $language) + { + $field = $fieldset->addChild('field'); + $field->addAttribute('name', $language->lang_code); + $field->addAttribute('type', 'modal_newsfeed'); + $field->addAttribute('language', $language->lang_code); + $field->addAttribute('label', $language->title); + $field->addAttribute('translate_label', 'false'); + $field->addAttribute('select', 'true'); + $field->addAttribute('new', 'true'); + $field->addAttribute('edit', 'true'); + $field->addAttribute('clear', 'true'); + $field->addAttribute('propagate', 'true'); + } + + $form->load($addform, false); + } + } + + parent::preprocessForm($form, $data, $group); + } + + /** + * Is the user allowed to create an on the fly category? + * + * @return boolean + * + * @since 3.6.1 + */ + private function canCreateCategory() + { + return JFactory::getUser()->authorise('core.create', 'com_newsfeeds'); + } + + /** + * Method to validate the form data. + * + * @param JForm $form The form to validate against. + * @param array $data The data to validate. + * @param string $group The name of the field group to validate. + * + * @return array|boolean Array of filtered data if valid, false otherwise. + * + * @see JFormRule + * @see JFilterInput + * @since __DEPLOY_VERSION__ + */ + public function validate($form, $data, $group = null) + { + // Don't allow to change the users if not allowed to access com_users. + if (!JFactory::getUser()->authorise('core.manage', 'com_users')) + { + if (isset($data['created_by'])) + { + unset($data['created_by']); + } + } + + return parent::validate($form, $data, $group); + } +} diff --git a/Sites/pages/administrator/components/com_newsfeeds/models/newsfeeds.php b/Sites/pages/administrator/components/com_newsfeeds/models/newsfeeds.php new file mode 100644 index 00000000..613880fc --- /dev/null +++ b/Sites/pages/administrator/components/com_newsfeeds/models/newsfeeds.php @@ -0,0 +1,320 @@ +input->get('forcedLanguage', '', 'cmd'); + + // Adjust the context to support modal layouts. + if ($layout = $app->input->get('layout')) + { + $this->context .= '.' . $layout; + } + + // Adjust the context to support forced languages. + if ($forcedLanguage) + { + $this->context .= '.' . $forcedLanguage; + } + + // Load the filter state. + $this->setState('filter.search', $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search', '', 'string')); + $this->setState('filter.published', $this->getUserStateFromRequest($this->context . '.filter.published', 'filter_published', '', 'string')); + $this->setState('filter.category_id', $this->getUserStateFromRequest($this->context . '.filter.category_id', 'filter_category_id', '', 'cmd')); + $this->setState('filter.access', $this->getUserStateFromRequest($this->context . '.filter.access', 'filter_access', '', 'cmd')); + $this->setState('filter.language', $this->getUserStateFromRequest($this->context . '.filter.language', 'filter_language', '', 'string')); + $this->setState('filter.tag', $this->getUserStateFromRequest($this->context . '.filter.tag', 'filter_tag', '', 'string')); + $this->setState('filter.level', $this->getUserStateFromRequest($this->context . '.filter.level', 'filter_level', null, 'int')); + + // Load the parameters. + $params = JComponentHelper::getParams('com_newsfeeds'); + $this->setState('params', $params); + + // List state information. + parent::populateState($ordering, $direction); + + // Force a language. + if (!empty($forcedLanguage)) + { + $this->setState('filter.language', $forcedLanguage); + } + } + + /** + * Method to get a store id based on model configuration state. + * + * This is necessary because the model is used by the component and + * different modules that might need different sets of data or different + * ordering requirements. + * + * @param string $id A prefix for the store id. + * + * @return string A store id. + */ + protected function getStoreId($id = '') + { + // Compile the store id. + $id .= ':' . $this->getState('filter.search'); + $id .= ':' . $this->getState('filter.published'); + $id .= ':' . $this->getState('filter.category_id'); + $id .= ':' . $this->getState('filter.access'); + $id .= ':' . $this->getState('filter.language'); + $id .= ':' . $this->getState('filter.level'); + $id .= ':' . serialize($this->getState('filter.tag')); + + return parent::getStoreId($id); + } + + /** + * Build an SQL query to load the list data. + * + * @return JDatabaseQuery + */ + protected function getListQuery() + { + // Create a new query object. + $db = $this->getDbo(); + $query = $db->getQuery(true); + $user = JFactory::getUser(); + $app = JFactory::getApplication(); + + // Select the required fields from the table. + $query->select( + $this->getState( + 'list.select', + 'a.id, a.name, a.alias, a.checked_out, a.checked_out_time, a.catid,' . + ' a.numarticles, a.cache_time, a.created_by,' . + ' a.published, a.access, a.ordering, a.language, a.publish_up, a.publish_down' + ) + ); + $query->from($db->quoteName('#__newsfeeds', 'a')); + + // Join over the language + $query->select($db->quoteName('l.title', 'language_title')) + ->select($db->quoteName('l.image', 'language_image')) + ->join('LEFT', $db->quoteName('#__languages', 'l') . ' ON ' . $db->qn('l.lang_code') . ' = ' . $db->qn('a.language')); + + // Join over the users for the checked out user. + $query->select($db->quoteName('uc.name', 'editor')) + ->join('LEFT', $db->quoteName('#__users', 'uc') . ' ON ' . $db->qn('uc.id') . ' = ' . $db->qn('a.checked_out')); + + // Join over the asset groups. + $query->select($db->quoteName('ag.title', 'access_level')) + ->join('LEFT', $db->quoteName('#__viewlevels', 'ag') . ' ON ' . $db->qn('ag.id') . ' = ' . $db->qn('a.access')); + + // Join over the categories. + $query->select($db->quoteName('c.title', 'category_title')) + ->join('LEFT', $db->quoteName('#__categories', 'c') . ' ON ' . $db->qn('c.id') . ' = ' . $db->qn('a.catid')); + + // Join over the associations. + $assoc = JLanguageAssociations::isEnabled(); + + if ($assoc) + { + $subQuery = $db->getQuery(true) + ->select('COUNT(' . $db->quoteName('asso1.id') . ') > 1') + ->from($db->quoteName('#__associations', 'asso1')) + ->join('INNER', $db->quoteName('#__associations', 'asso2') . ' ON ' . $db->quoteName('asso1.key') . ' = ' . $db->quoteName('asso2.key')) + ->where( + array( + $db->quoteName('asso1.id') . ' = ' . $db->quoteName('a.id'), + $db->quoteName('asso1.context') . ' = ' . $db->quote('com_newsfeeds.item'), + ) + ); + + $query->select('(' . $subQuery . ') AS ' . $db->quoteName('association')); + } + + // Filter by access level. + if ($access = $this->getState('filter.access')) + { + $query->where($db->quoteName('a.access') . ' = ' . (int) $access); + } + + // Implement View Level Access + if (!$user->authorise('core.admin')) + { + $query->where($db->quoteName('a.access') . ' IN (' . implode(',', $user->getAuthorisedViewLevels()) . ')'); + } + + // Filter by published state. + $published = $this->getState('filter.published'); + + if (is_numeric($published)) + { + $query->where($db->quoteName('a.published') . ' = ' . (int) $published); + } + elseif ($published === '') + { + $query->where($db->quoteName('a.published') . ' IN (0, 1)'); + } + + // Filter by category. + $categoryId = $this->getState('filter.category_id'); + + if (is_numeric($categoryId)) + { + $query->where($db->quoteName('a.catid') . ' = ' . (int) $categoryId); + } + + // Filter on the level. + if ($level = $this->getState('filter.level')) + { + $query->where($db->quoteName('c.level') . ' <= ' . (int) $level); + } + + // Filter by search in title + $search = $this->getState('filter.search'); + + if (!empty($search)) + { + if (stripos($search, 'id:') === 0) + { + $query->where($db->quoteName('a.id') . ' = ' . (int) substr($search, 3)); + } + else + { + $search = $db->quote('%' . str_replace(' ', '%', $db->escape(trim($search), true) . '%')); + $query->where('(a.name LIKE ' . $search . ' OR a.alias LIKE ' . $search . ')'); + } + } + + // Filter on the language. + if ($language = $this->getState('filter.language')) + { + $query->where($db->quoteName('a.language') . ' = ' . $db->quote($language)); + } + + // Filter by a single or group of tags. + $tag = $this->getState('filter.tag'); + + // Run simplified query when filtering by one tag. + if (\is_array($tag) && \count($tag) === 1) + { + $tag = $tag[0]; + } + + if ($tag && \is_array($tag)) + { + $tag = ArrayHelper::toInteger($tag); + + $subQuery = $db->getQuery(true) + ->select('DISTINCT ' . $db->quoteName('content_item_id')) + ->from($db->quoteName('#__contentitem_tag_map')) + ->where( + array( + $db->quoteName('tag_id') . ' IN (' . implode(',', $tag) . ')', + $db->quoteName('type_alias') . ' = ' . $db->quote('com_newsfeeds.newsfeed'), + ) + ); + + $query->join( + 'INNER', + '(' . $subQuery . ') AS ' . $db->quoteName('tagmap') + . ' ON ' . $db->quoteName('tagmap.content_item_id') . ' = ' . $db->quoteName('a.id') + ); + } + elseif ($tag = (int) $tag) + { + $query->join( + 'INNER', + $db->quoteName('#__contentitem_tag_map', 'tagmap') + . ' ON ' . $db->quoteName('tagmap.content_item_id') . ' = ' . $db->quoteName('a.id') + ) + ->where( + array( + $db->quoteName('tagmap.tag_id') . ' = ' . $tag, + $db->quoteName('tagmap.type_alias') . ' = ' . $db->quote('com_newsfeeds.newsfeed'), + ) + ); + } + + // Add the list ordering clause. + $orderCol = $this->state->get('list.ordering', 'a.name'); + $orderDirn = $this->state->get('list.direction', 'ASC'); + + if ($orderCol == 'a.ordering' || $orderCol == 'category_title') + { + $orderCol = 'c.title ' . $orderDirn . ', a.ordering'; + } + + $query->order($db->escape($orderCol . ' ' . $orderDirn)); + + return $query; + } +} diff --git a/Sites/pages/administrator/components/com_newsfeeds/newsfeeds.php b/Sites/pages/administrator/components/com_newsfeeds/newsfeeds.php new file mode 100644 index 00000000..c311b2ae --- /dev/null +++ b/Sites/pages/administrator/components/com_newsfeeds/newsfeeds.php @@ -0,0 +1,20 @@ +authorise('core.manage', 'com_newsfeeds')) +{ + throw new JAccessExceptionNotallowed(JText::_('JERROR_ALERTNOAUTHOR'), 403); +} + +$controller = JControllerLegacy::getInstance('Newsfeeds'); +$controller->execute(JFactory::getApplication()->input->get('task')); +$controller->redirect(); diff --git a/Sites/pages/administrator/components/com_newsfeeds/newsfeeds.xml b/Sites/pages/administrator/components/com_newsfeeds/newsfeeds.xml new file mode 100644 index 00000000..889fec62 --- /dev/null +++ b/Sites/pages/administrator/components/com_newsfeeds/newsfeeds.xml @@ -0,0 +1,64 @@ + + + com_newsfeeds + Joomla! Project + April 2006 + (C) 2005 - 2020 Open Source Matters. All rights reserved. + GNU General Public License version 2 or later; see LICENSE.txt + admin@joomla.org + www.joomla.org + 3.0.0 + COM_NEWSFEEDS_XML_DESCRIPTION + + + sql/install.mysql.utf8.sql + + + + + sql/uninstall.mysql.utf8.sql + + + + + controller.php + metadata.xml + newsfeeds.php + router.php + helpers + models + views + + + language/en-GB.com_newsfeeds.ini + + + com_newsfeeds + + + com_newsfeeds_feeds + com_newsfeeds_categories + + + access.xml + config.xml + controller.php + newsfeeds.php + controllers + elements + helpers + models + tables + views + + + language/en-GB.com_newsfeeds.ini + language/en-GB.com_newsfeeds.sys.ini + + + diff --git a/Sites/pages/administrator/components/com_newsfeeds/sql/install.mysql.utf8.sql b/Sites/pages/administrator/components/com_newsfeeds/sql/install.mysql.utf8.sql new file mode 100644 index 00000000..da029c00 --- /dev/null +++ b/Sites/pages/administrator/components/com_newsfeeds/sql/install.mysql.utf8.sql @@ -0,0 +1,44 @@ +-- +-- Table structure for table `#__newsfeeds` +-- + +CREATE TABLE IF NOT EXISTS `#__newsfeeds` ( + `catid` int(11) NOT NULL DEFAULT 0, + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(100) NOT NULL DEFAULT '', + `alias` varchar(400) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL DEFAULT '', + `link` varchar(2048) NOT NULL DEFAULT '', + `published` tinyint(1) NOT NULL DEFAULT 0, + `numarticles` int(10) unsigned NOT NULL DEFAULT 1, + `cache_time` int(10) unsigned NOT NULL DEFAULT 3600, + `checked_out` int(10) unsigned NOT NULL DEFAULT 0, + `checked_out_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `ordering` int(11) NOT NULL DEFAULT 0, + `rtl` tinyint(4) NOT NULL DEFAULT 0, + `access` int(10) unsigned NOT NULL DEFAULT 0, + `language` char(7) NOT NULL DEFAULT '', + `params` text NOT NULL, + `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `created_by` int(10) unsigned NOT NULL DEFAULT 0, + `created_by_alias` varchar(255) NOT NULL DEFAULT '', + `modified` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `modified_by` int(10) unsigned NOT NULL DEFAULT 0, + `metakey` text NOT NULL, + `metadesc` text NOT NULL, + `metadata` text NOT NULL, + `xreference` varchar(50) NOT NULL COMMENT 'A reference to enable linkages to external data sets.', + `publish_up` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `publish_down` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `description` text NOT NULL, + `version` int(10) unsigned NOT NULL DEFAULT 1, + `hits` int(10) unsigned NOT NULL DEFAULT 0, + `images` text NOT NULL, + PRIMARY KEY (`id`), + KEY `idx_access` (`access`), + KEY `idx_checkout` (`checked_out`), + KEY `idx_state` (`published`), + KEY `idx_catid` (`catid`), + KEY `idx_createdby` (`created_by`), + KEY `idx_language` (`language`), + KEY `idx_xreference` (`xreference`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_unicode_ci; diff --git a/Sites/pages/administrator/components/com_newsfeeds/sql/uninstall.mysql.utf8.sql b/Sites/pages/administrator/components/com_newsfeeds/sql/uninstall.mysql.utf8.sql new file mode 100644 index 00000000..f29779aa --- /dev/null +++ b/Sites/pages/administrator/components/com_newsfeeds/sql/uninstall.mysql.utf8.sql @@ -0,0 +1,2 @@ +DROP TABLE IF EXISTS `#__newsfeeds`; + diff --git a/Sites/pages/administrator/components/com_newsfeeds/tables/newsfeed.php b/Sites/pages/administrator/components/com_newsfeeds/tables/newsfeed.php new file mode 100644 index 00000000..677ec338 --- /dev/null +++ b/Sites/pages/administrator/components/com_newsfeeds/tables/newsfeed.php @@ -0,0 +1,168 @@ +setColumnAlias('title', 'name'); + + JTableObserverTags::createObserver($this, array('typeAlias' => 'com_newsfeeds.newsfeed')); + JTableObserverContenthistory::createObserver($this, array('typeAlias' => 'com_newsfeeds.newsfeed')); + } + + /** + * Overloaded check method to ensure data integrity. + * + * @return boolean True on success. + */ + public function check() + { + // Check for valid name. + if (trim($this->name) == '') + { + $this->setError(JText::_('COM_NEWSFEEDS_WARNING_PROVIDE_VALID_NAME')); + + return false; + } + + if (empty($this->alias)) + { + $this->alias = $this->name; + } + + $this->alias = JApplicationHelper::stringURLSafe($this->alias, $this->language); + + if (trim(str_replace('-', '', $this->alias)) == '') + { + $this->alias = JFactory::getDate()->format('Y-m-d-H-i-s'); + } + + // Check the publish down date is not earlier than publish up. + if ((int) $this->publish_down > 0 && $this->publish_down < $this->publish_up) + { + $this->setError(JText::_('JGLOBAL_START_PUBLISH_AFTER_FINISH')); + + return false; + } + + // Clean up keywords -- eliminate extra spaces between phrases + // and cr (\r) and lf (\n) characters from string if not empty + if (!empty($this->metakey)) + { + // Array of characters to remove + $bad_characters = array("\n", "\r", "\"", '<', '>'); + + // Remove bad characters + $after_clean = StringHelper::str_ireplace($bad_characters, '', $this->metakey); + + // Create array using commas as delimiter + $keys = explode(',', $after_clean); + $clean_keys = array(); + + foreach ($keys as $key) + { + if (trim($key)) + { + // Ignore blank keywords + $clean_keys[] = trim($key); + } + } + + // Put array back together delimited by ", " + $this->metakey = implode(', ', $clean_keys); + } + + // Clean up description -- eliminate quotes and <> brackets + if (!empty($this->metadesc)) + { + // Only process if not empty + $bad_characters = array("\"", '<', '>'); + $this->metadesc = StringHelper::str_ireplace($bad_characters, '', $this->metadesc); + } + + return true; + } + + /** + * Overriden JTable::store to set modified data. + * + * @param boolean $updateNulls True to update fields even if they are null. + * + * @return boolean True on success. + * + * @since 1.6 + */ + public function store($updateNulls = false) + { + $date = JFactory::getDate(); + $user = JFactory::getUser(); + + $this->modified = $date->toSql(); + + if ($this->id) + { + // Existing item + $this->modified_by = $user->get('id'); + } + else + { + // New newsfeed. A feed created and created_by field can be set by the user, + // so we don't touch either of these if they are set. + if (!(int) $this->created) + { + $this->created = $date->toSql(); + } + + if (empty($this->created_by)) + { + $this->created_by = $user->get('id'); + } + } + + // Verify that the alias is unique + $table = JTable::getInstance('Newsfeed', 'NewsfeedsTable', array('dbo' => $this->_db)); + + if ($table->load(array('alias' => $this->alias, 'catid' => $this->catid)) && ($table->id != $this->id || $this->id == 0)) + { + $this->setError(JText::_('COM_NEWSFEEDS_ERROR_UNIQUE_ALIAS')); + + return false; + } + + // Save links as punycode. + $this->link = JStringPunycode::urlToPunycode($this->link); + + return parent::store($updateNulls); + } +} diff --git a/Sites/pages/administrator/components/com_newsfeeds/views/newsfeed/tmpl/edit.php b/Sites/pages/administrator/components/com_newsfeeds/views/newsfeed/tmpl/edit.php new file mode 100644 index 00000000..40874ac5 --- /dev/null +++ b/Sites/pages/administrator/components/com_newsfeeds/views/newsfeed/tmpl/edit.php @@ -0,0 +1,112 @@ + 0 )); +JHtml::_('formbehavior.chosen', '#jform_tags', null, array('placeholder_text_multiple' => JText::_('JGLOBAL_TYPE_OR_SELECT_SOME_TAGS'))); +JHtml::_('formbehavior.chosen', 'select'); + +$app = JFactory::getApplication(); +$input = $app->input; + +$assoc = JLanguageAssociations::isEnabled(); + +JFactory::getDocument()->addScriptDeclaration(' + Joomla.submitbutton = function(task) + { + if (task == "newsfeed.cancel" || document.formvalidator.isValid(document.getElementById("newsfeed-form"))) { + Joomla.submitform(task, document.getElementById("newsfeed-form")); + + // @deprecated 4.0 The following js is not needed since 3.7.0. + if (task !== "newsfeed.apply") + { + window.parent.jQuery("#newsfeedEdit' . $this->item->id . 'Modal").modal("hide"); + } + } + }; +'); + +// Fieldsets to not automatically render by /layouts/joomla/edit/params.php +$this->ignore_fieldsets = array('images', 'jbasic', 'jmetadata', 'item_associations'); + +// In case of modal +$isModal = $input->get('layout') == 'modal' ? true : false; +$layout = $isModal ? 'modal' : 'edit'; +$tmpl = $isModal || $input->get('tmpl', '', 'cmd') === 'component' ? '&tmpl=component' : ''; +?> + + + + + +
    + 'details')); ?> + + item->id) ? JText::_('COM_NEWSFEEDS_NEW_NEWSFEED') : JText::_('COM_NEWSFEEDS_EDIT_NEWSFEED')); ?> +
    +
    +
    + form->renderField('link'); ?> + form->renderField('description'); ?> +
    +
    +
    + +
    +
    + + + +
    +
    + form->renderField('images'); ?> + form->getGroup('images') as $field) : ?> + renderField(); ?> + +
    +
    + + + + loadTemplate('display'); ?> + + + + + +
    +
    + +
    +
    + +
    +
    + + + + + loadTemplate('associations'); ?> + + + + + + +
    + + + +
    diff --git a/Sites/pages/administrator/components/com_newsfeeds/views/newsfeed/tmpl/edit_associations.php b/Sites/pages/administrator/components/com_newsfeeds/views/newsfeed/tmpl/edit_associations.php new file mode 100644 index 00000000..714c7988 --- /dev/null +++ b/Sites/pages/administrator/components/com_newsfeeds/views/newsfeed/tmpl/edit_associations.php @@ -0,0 +1,12 @@ +fieldset = 'jbasic'; +echo JLayoutHelper::render('joomla.edit.fieldset', $this); diff --git a/Sites/pages/administrator/components/com_newsfeeds/views/newsfeed/tmpl/edit_metadata.php b/Sites/pages/administrator/components/com_newsfeeds/views/newsfeed/tmpl/edit_metadata.php new file mode 100644 index 00000000..de9a65a4 --- /dev/null +++ b/Sites/pages/administrator/components/com_newsfeeds/views/newsfeed/tmpl/edit_metadata.php @@ -0,0 +1,12 @@ +form->getFieldsets('params'); +foreach ($fieldSets as $name => $fieldSet) : + ?> +
    + description) && trim($fieldSet->description)) : ?> +

    escape(JText::_($fieldSet->description)); ?>

    + + form->getFieldset($name) as $field) : ?> +
    +
    label; ?>
    +
    input; ?>
    +
    + +
    + diff --git a/Sites/pages/administrator/components/com_newsfeeds/views/newsfeed/tmpl/modal.php b/Sites/pages/administrator/components/com_newsfeeds/views/newsfeed/tmpl/modal.php new file mode 100644 index 00000000..73ab0854 --- /dev/null +++ b/Sites/pages/administrator/components/com_newsfeeds/views/newsfeed/tmpl/modal.php @@ -0,0 +1,33 @@ + 'bottom')); + +// @deprecated 4.0 the function parameter, the inline js and the buttons are not needed since 3.7.0. +$function = JFactory::getApplication()->input->getCmd('function', 'jEditNewsfeed_' . (int) $this->item->id); + +// Function to update input title when changed +JFactory::getDocument()->addScriptDeclaration(' + function jEditNewsfeedModal() { + if (window.parent && document.formvalidator.isValid(document.getElementById("newsfeed-form"))) { + return window.parent.' . $this->escape($function) . '(document.getElementById("jform_name").value); + } + } +'); +?> + + + + +
    + setLayout('edit'); ?> + loadTemplate(); ?> +
    diff --git a/Sites/pages/administrator/components/com_newsfeeds/views/newsfeed/tmpl/modal_associations.php b/Sites/pages/administrator/components/com_newsfeeds/views/newsfeed/tmpl/modal_associations.php new file mode 100644 index 00000000..714c7988 --- /dev/null +++ b/Sites/pages/administrator/components/com_newsfeeds/views/newsfeed/tmpl/modal_associations.php @@ -0,0 +1,12 @@ +fieldset = 'jbasic'; +echo JLayoutHelper::render('joomla.edit.fieldset', $this); diff --git a/Sites/pages/administrator/components/com_newsfeeds/views/newsfeed/tmpl/modal_metadata.php b/Sites/pages/administrator/components/com_newsfeeds/views/newsfeed/tmpl/modal_metadata.php new file mode 100644 index 00000000..de9a65a4 --- /dev/null +++ b/Sites/pages/administrator/components/com_newsfeeds/views/newsfeed/tmpl/modal_metadata.php @@ -0,0 +1,12 @@ +form->getFieldsets('params'); +foreach ($fieldSets as $name => $fieldSet) : + ?> +
    + description) && trim($fieldSet->description)) : ?> +

    escape(JText::_($fieldSet->description)); ?>

    + + form->getFieldset($name) as $field) : ?> +
    +
    label; ?>
    +
    input; ?>
    +
    + +
    + diff --git a/Sites/pages/administrator/components/com_newsfeeds/views/newsfeed/view.html.php b/Sites/pages/administrator/components/com_newsfeeds/views/newsfeed/view.html.php new file mode 100644 index 00000000..8fe64b24 --- /dev/null +++ b/Sites/pages/administrator/components/com_newsfeeds/views/newsfeed/view.html.php @@ -0,0 +1,142 @@ +state = $this->get('State'); + $this->item = $this->get('Item'); + $this->form = $this->get('Form'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + // If we are forcing a language in modal (used for associations). + if ($this->getLayout() === 'modal' && $forcedLanguage = JFactory::getApplication()->input->get('forcedLanguage', '', 'cmd')) + { + // Set the language field to the forcedLanguage and disable changing it. + $this->form->setValue('language', null, $forcedLanguage); + $this->form->setFieldAttribute('language', 'readonly', 'true'); + + // Only allow to select categories with All language or with the forced language. + $this->form->setFieldAttribute('catid', 'language', '*,' . $forcedLanguage); + + // Only allow to select tags with All language or with the forced language. + $this->form->setFieldAttribute('tags', 'language', '*,' . $forcedLanguage); + } + + $this->addToolbar(); + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + JFactory::getApplication()->input->set('hidemainmenu', true); + + $user = JFactory::getUser(); + $isNew = ($this->item->id == 0); + $checkedOut = !($this->item->checked_out == 0 || $this->item->checked_out == $user->get('id')); + + // Since we don't track these assets at the item level, use the category id. + $canDo = JHelperContent::getActions('com_newsfeeds', 'category', $this->item->catid); + + JToolbarHelper::title($isNew ? JText::_('COM_NEWSFEEDS_MANAGER_NEWSFEED_NEW') : JText::_('COM_NEWSFEEDS_MANAGER_NEWSFEED_EDIT'), 'feed newsfeeds'); + + // If not checked out, can save the item. + if (!$checkedOut && ($canDo->get('core.edit') || count($user->getAuthorisedCategories('com_newsfeeds', 'core.create')) > 0)) + { + JToolbarHelper::apply('newsfeed.apply'); + JToolbarHelper::save('newsfeed.save'); + } + + if (!$checkedOut && count($user->getAuthorisedCategories('com_newsfeeds', 'core.create')) > 0) + { + JToolbarHelper::save2new('newsfeed.save2new'); + } + + // If an existing item, can save to a copy. + if (!$isNew && $canDo->get('core.create')) + { + JToolbarHelper::save2copy('newsfeed.save2copy'); + } + + if (!$isNew && JLanguageAssociations::isEnabled() && JComponentHelper::isEnabled('com_associations')) + { + JToolbarHelper::custom('newsfeed.editAssociations', 'contract', 'contract', 'JTOOLBAR_ASSOCIATIONS', false, false); + } + + if (empty($this->item->id)) + { + JToolbarHelper::cancel('newsfeed.cancel'); + } + else + { + if (JComponentHelper::isEnabled('com_contenthistory') && $this->state->params->get('save_history', 0) && $canDo->get('core.edit')) + { + JToolbarHelper::versions('com_newsfeeds.newsfeed', $this->item->id); + } + + JToolbarHelper::cancel('newsfeed.cancel', 'JTOOLBAR_CLOSE'); + } + + JToolbarHelper::divider(); + JToolbarHelper::help('JHELP_COMPONENTS_NEWSFEEDS_FEEDS_EDIT'); + } +} diff --git a/Sites/pages/administrator/components/com_newsfeeds/views/newsfeeds/tmpl/default.php b/Sites/pages/administrator/components/com_newsfeeds/views/newsfeeds/tmpl/default.php new file mode 100644 index 00000000..1a24b67d --- /dev/null +++ b/Sites/pages/administrator/components/com_newsfeeds/views/newsfeeds/tmpl/default.php @@ -0,0 +1,200 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$saveOrder = $listOrder == 'a.ordering'; +$assoc = JLanguageAssociations::isEnabled(); + +if ($saveOrder) +{ + $saveOrderingUrl = 'index.php?option=com_newsfeeds&task=newsfeeds.saveOrderAjax&tmpl=component'; + JHtml::_('sortablelist.sortable', 'newsfeedList', 'adminForm', strtolower($listDirn), $saveOrderingUrl); +} +?> +
    + sidebar)) : ?> +
    + sidebar; ?> +
    +
    + +
    + + $this)); ?> +
    + items)) : ?> +
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + items as $i => $item) : + $ordering = ($listOrder == 'a.ordering'); + $canCreate = $user->authorise('core.create', 'com_newsfeeds.category.' . $item->catid); + $canEdit = $user->authorise('core.edit', 'com_newsfeeds.category.' . $item->catid); + $canCheckin = $user->authorise('core.manage', 'com_checkin') || $item->checked_out == $user->get('id') || $item->checked_out == 0; + $canEditOwn = $user->authorise('core.edit.own', 'com_newsfeeds.category.' . $item->catid) && $item->created_by == $user->id; + $canChange = $user->authorise('core.edit.state', 'com_newsfeeds.category.' . $item->catid) && $canCheckin; + ?> + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    + pagination->getListFooter(); ?> +
    + + + + + + + + + id); ?> + +
    + published, $i, 'newsfeeds.', $canChange, 'cb', $item->publish_up, $item->publish_down); ?> + published === 2 ? 'un' : '') . 'archive', 'cb' . $i, 'newsfeeds'); + JHtml::_('actionsdropdown.' . ((int) $item->published === -2 ? 'un' : '') . 'trash', 'cb' . $i, 'newsfeeds'); + echo JHtml::_('actionsdropdown.render', $this->escape($item->name)); + } + ?> +
    +
    +
    + checked_out) : ?> + editor, $item->checked_out_time, 'newsfeeds.', $canCheckin); ?> + + + + escape($item->name); ?> + + escape($item->name); ?> + + + escape($item->alias)); ?> + +
    + escape($item->category_title); ?> +
    +
    +
    + escape($item->access_level); ?> + + numarticles; ?> + + cache_time; ?> + + association) : ?> + id); ?> + + + + + id; ?> +
    + + authorise('core.create', 'com_newsfeeds') + && $user->authorise('core.edit', 'com_newsfeeds') + && $user->authorise('core.edit.state', 'com_newsfeeds')) : ?> + JText::_('COM_NEWSFEEDS_BATCH_OPTIONS'), + 'footer' => $this->loadTemplate('batch_footer'), + ), + $this->loadTemplate('batch_body') + ); ?> + + + + + +
    + diff --git a/Sites/pages/administrator/components/com_newsfeeds/views/newsfeeds/tmpl/default_batch_body.php b/Sites/pages/administrator/components/com_newsfeeds/views/newsfeeds/tmpl/default_batch_body.php new file mode 100644 index 00000000..fb3c9f37 --- /dev/null +++ b/Sites/pages/administrator/components/com_newsfeeds/views/newsfeeds/tmpl/default_batch_body.php @@ -0,0 +1,40 @@ +state->get('filter.published'); +?> + +
    +
    +
    +
    + +
    +
    +
    +
    + +
    +
    +
    +
    + = 0) : ?> +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    +
    diff --git a/Sites/pages/administrator/components/com_newsfeeds/views/newsfeeds/tmpl/default_batch_footer.php b/Sites/pages/administrator/components/com_newsfeeds/views/newsfeeds/tmpl/default_batch_footer.php new file mode 100644 index 00000000..2fced9f9 --- /dev/null +++ b/Sites/pages/administrator/components/com_newsfeeds/views/newsfeeds/tmpl/default_batch_footer.php @@ -0,0 +1,17 @@ + + + diff --git a/Sites/pages/administrator/components/com_newsfeeds/views/newsfeeds/tmpl/modal.php b/Sites/pages/administrator/components/com_newsfeeds/views/newsfeeds/tmpl/modal.php new file mode 100644 index 00000000..6e53f1a5 --- /dev/null +++ b/Sites/pages/administrator/components/com_newsfeeds/views/newsfeeds/tmpl/modal.php @@ -0,0 +1,131 @@ + 'bottom')); +JHtml::_('bootstrap.popover', '.hasPopover', array('placement' => 'bottom')); +JHtml::_('formbehavior.chosen', 'select'); + +// Special case for the search field tooltip. +$searchFilterDesc = $this->filterForm->getFieldAttribute('search', 'description', null, 'filter'); +JHtml::_('bootstrap.tooltip', '#filter_search', array('title' => JText::_($searchFilterDesc), 'placement' => 'bottom')); + +$app = JFactory::getApplication(); + +$function = $app->input->getCmd('function', 'jSelectNewsfeed'); +$listOrder = $this->escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +?> +
    + +
    + + $this)); ?> + + items)) : ?> +
    + +
    + + + + + + + + + + + + + + + + + + 'icon-trash', + 0 => 'icon-unpublish', + 1 => 'icon-publish', + 2 => 'icon-archive', + ); + ?> + items as $i => $item) : ?> + language && JLanguageMultilang::isEnabled()) + { + $tag = strlen($item->language); + if ($tag == 5) + { + $lang = substr($item->language, 0, 2); + } + elseif ($tag == 6) + { + $lang = substr($item->language, 0, 3); + } + else { + $lang = ''; + } + } + elseif (!JLanguageMultilang::isEnabled()) + { + $lang = ''; + } + ?> + + + + + + + + + +
    + + + + + + + + + +
    + pagination->getListFooter(); ?> +
    + + + + escape($item->name); ?> +
    + escape($item->category_title); ?> +
    +
    + escape($item->access_level); ?> + + + + id; ?> +
    + + + + + + + +
    +
    diff --git a/Sites/pages/administrator/components/com_newsfeeds/views/newsfeeds/view.html.php b/Sites/pages/administrator/components/com_newsfeeds/views/newsfeeds/view.html.php new file mode 100644 index 00000000..a43c7328 --- /dev/null +++ b/Sites/pages/administrator/components/com_newsfeeds/views/newsfeeds/view.html.php @@ -0,0 +1,192 @@ +items = $this->get('Items'); + $this->pagination = $this->get('Pagination'); + $this->state = $this->get('State'); + $this->filterForm = $this->get('FilterForm'); + $this->activeFilters = $this->get('ActiveFilters'); + + // Modal layout doesn't need the submenu. + if ($this->getLayout() !== 'modal') + { + NewsfeedsHelper::addSubmenu('newsfeeds'); + } + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + JError::raiseError(500, implode("\n", $errors)); + + return false; + } + + // We don't need toolbar in the modal layout. + if ($this->getLayout() !== 'modal') + { + $this->addToolbar(); + $this->sidebar = JHtmlSidebar::render(); + } + else + { + // In article associations modal we need to remove language filter if forcing a language. + // We also need to change the category filter to show show categories with All or the forced language. + if ($forcedLanguage = JFactory::getApplication()->input->get('forcedLanguage', '', 'CMD')) + { + // If the language is forced we can't allow to select the language, so transform the language selector filter into a hidden field. + $languageXml = new SimpleXMLElement(''); + $this->filterForm->setField($languageXml, 'filter', true); + + // Also, unset the active language filter so the search tools is not open by default with this filter. + unset($this->activeFilters['language']); + + // One last changes needed is to change the category filter to just show categories with All language or with the forced language. + $this->filterForm->setFieldAttribute('category_id', 'language', '*,' . $forcedLanguage, 'filter'); + } + } + + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + $state = $this->get('State'); + $canDo = JHelperContent::getActions('com_newsfeeds', 'category', $state->get('filter.category_id')); + $user = JFactory::getUser(); + + // Get the toolbar object instance + $bar = JToolbar::getInstance('toolbar'); + JToolbarHelper::title(JText::_('COM_NEWSFEEDS_MANAGER_NEWSFEEDS'), 'feed newsfeeds'); + + if (count($user->getAuthorisedCategories('com_newsfeeds', 'core.create')) > 0) + { + JToolbarHelper::addNew('newsfeed.add'); + } + + if ($canDo->get('core.edit') || $canDo->get('core.edit.own')) + { + JToolbarHelper::editList('newsfeed.edit'); + } + + if ($canDo->get('core.edit.state')) + { + JToolbarHelper::publish('newsfeeds.publish', 'JTOOLBAR_PUBLISH', true); + JToolbarHelper::unpublish('newsfeeds.unpublish', 'JTOOLBAR_UNPUBLISH', true); + JToolbarHelper::archiveList('newsfeeds.archive'); + } + + if ($canDo->get('core.admin')) + { + JToolbarHelper::checkin('newsfeeds.checkin'); + } + + // Add a batch button + if ($user->authorise('core.create', 'com_newsfeeds') + && $user->authorise('core.edit', 'com_newsfeeds') + && $user->authorise('core.edit.state', 'com_newsfeeds')) + { + $title = JText::_('JTOOLBAR_BATCH'); + + // Instantiate a new JLayoutFile instance and render the batch button + $layout = new JLayoutFile('joomla.toolbar.batch'); + + $dhtml = $layout->render(array('title' => $title)); + $bar->appendButton('Custom', $dhtml, 'batch'); + } + + if ($state->get('filter.published') == -2 && $canDo->get('core.delete')) + { + JToolbarHelper::deleteList('JGLOBAL_CONFIRM_DELETE', 'newsfeeds.delete', 'JTOOLBAR_EMPTY_TRASH'); + } + elseif ($canDo->get('core.edit.state')) + { + JToolbarHelper::trash('newsfeeds.trash'); + } + + if ($user->authorise('core.admin', 'com_newsfeeds') || $user->authorise('core.options', 'com_newsfeeds')) + { + JToolbarHelper::preferences('com_newsfeeds'); + } + + JToolbarHelper::help('JHELP_COMPONENTS_NEWSFEEDS_FEEDS'); + } + + /** + * Returns an array of fields the table can be sorted by + * + * @return array Array containing the field name to sort by as the key and display text as value + * + * @since 3.0 + */ + protected function getSortFields() + { + return array( + 'a.ordering' => JText::_('JGRID_HEADING_ORDERING'), + 'a.published' => JText::_('JSTATUS'), + 'a.name' => JText::_('JGLOBAL_TITLE'), + 'category_title' => JText::_('JCATEGORY'), + 'a.access' => JText::_('JGRID_HEADING_ACCESS'), + 'numarticles' => JText::_('COM_NEWSFEEDS_NUM_ARTICLES_HEADING'), + 'a.cache_time' => JText::_('COM_NEWSFEEDS_CACHE_TIME_HEADING'), + 'a.language' => JText::_('JGRID_HEADING_LANGUAGE'), + 'a.id' => JText::_('JGRID_HEADING_ID') + ); + } +} diff --git a/Sites/pages/administrator/components/com_pages/language/en-GB/en-GB.com_pages.ini b/Sites/pages/administrator/components/com_pages/language/en-GB/en-GB.com_pages.ini new file mode 100644 index 00000000..1512ff08 --- /dev/null +++ b/Sites/pages/administrator/components/com_pages/language/en-GB/en-GB.com_pages.ini @@ -0,0 +1,6 @@ +; Copyright (C) 2018 Timble CVBA. (http://www.timble.net) +; GNU GPLv3 +; Note : All ini files need to be saved as UTF-8 + +COM_PAGES="Pages" +COM_PAGES_XML_DESCRIPTION="" \ No newline at end of file diff --git a/Sites/pages/administrator/components/com_pages/language/en-GB/en-GB.com_pages.sys.ini b/Sites/pages/administrator/components/com_pages/language/en-GB/en-GB.com_pages.sys.ini new file mode 100644 index 00000000..1512ff08 --- /dev/null +++ b/Sites/pages/administrator/components/com_pages/language/en-GB/en-GB.com_pages.sys.ini @@ -0,0 +1,6 @@ +; Copyright (C) 2018 Timble CVBA. (http://www.timble.net) +; GNU GPLv3 +; Note : All ini files need to be saved as UTF-8 + +COM_PAGES="Pages" +COM_PAGES_XML_DESCRIPTION="" \ No newline at end of file diff --git a/Sites/pages/administrator/components/com_pages/pages.xml b/Sites/pages/administrator/components/com_pages/pages.xml new file mode 100644 index 00000000..90b0e392 --- /dev/null +++ b/Sites/pages/administrator/components/com_pages/pages.xml @@ -0,0 +1,44 @@ + + + com:pages + com_pages + Joomlatools + March 2021 + Copyright (C) 2018 Timble CVBA (http://www.timble.net) + GNU GPLv3 - http://www.gnu.org/licenses/gpl.html + support@joomlatools.com + www.joomlatools.com + 0.19.8 + COM_PAGES_XML_DESCRIPTION + + + pages.php + config.php + + class + controller + data + database + dispatcher + event + http + model + object + page + resources + template + view + + + + com_pages + + + + + version.php + + language + + + \ No newline at end of file diff --git a/Sites/pages/administrator/components/com_pages/version.php b/Sites/pages/administrator/components/com_pages/version.php new file mode 100644 index 00000000..fceba8a3 --- /dev/null +++ b/Sites/pages/administrator/components/com_pages/version.php @@ -0,0 +1,22 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ +class ComPagesVersion extends KObject +{ + const VERSION = '0.19.8'; + + public function getVersion() + { + return self::VERSION; + } + + public function __toString() + { + return $this->getVersion(); + } +} \ No newline at end of file diff --git a/Sites/pages/administrator/components/com_plugins/access.xml b/Sites/pages/administrator/components/com_plugins/access.xml new file mode 100644 index 00000000..c7e06d05 --- /dev/null +++ b/Sites/pages/administrator/components/com_plugins/access.xml @@ -0,0 +1,9 @@ + + +
    + + + + +
    +
    diff --git a/Sites/pages/administrator/components/com_plugins/config.xml b/Sites/pages/administrator/components/com_plugins/config.xml new file mode 100644 index 00000000..f95a4f66 --- /dev/null +++ b/Sites/pages/administrator/components/com_plugins/config.xml @@ -0,0 +1,18 @@ + + +
    + + +
    +
    diff --git a/Sites/pages/administrator/components/com_plugins/controller.php b/Sites/pages/administrator/components/com_plugins/controller.php new file mode 100644 index 00000000..d943c7ca --- /dev/null +++ b/Sites/pages/administrator/components/com_plugins/controller.php @@ -0,0 +1,53 @@ +input->get('view', 'plugins')); + + $view = $this->input->get('view', 'plugins'); + $layout = $this->input->get('layout', 'default'); + $id = $this->input->getInt('extension_id'); + + // Check for edit form. + if ($view == 'plugin' && $layout == 'edit' && !$this->checkEditId('com_plugins.edit.plugin', $id)) + { + // Somehow the person just went to the form - we don't allow that. + $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id)); + $this->setMessage($this->getError(), 'error'); + $this->setRedirect(JRoute::_('index.php?option=com_plugins&view=plugins', false)); + + return false; + } + + parent::display(); + } +} diff --git a/Sites/pages/administrator/components/com_plugins/controllers/plugin.php b/Sites/pages/administrator/components/com_plugins/controllers/plugin.php new file mode 100644 index 00000000..43881c9c --- /dev/null +++ b/Sites/pages/administrator/components/com_plugins/controllers/plugin.php @@ -0,0 +1,19 @@ + true)) + { + return parent::getModel($name, $prefix, $config); + } +} diff --git a/Sites/pages/administrator/components/com_plugins/helpers/plugins.php b/Sites/pages/administrator/components/com_plugins/helpers/plugins.php new file mode 100644 index 00000000..76ad66e2 --- /dev/null +++ b/Sites/pages/administrator/components/com_plugins/helpers/plugins.php @@ -0,0 +1,163 @@ +getQuery(true) + ->select('DISTINCT(folder) AS value, folder AS text') + ->from('#__extensions') + ->where($db->quoteName('type') . ' = ' . $db->quote('plugin')) + ->order('folder'); + + $db->setQuery($query); + + try + { + $options = $db->loadObjectList(); + } + catch (RuntimeException $e) + { + JError::raiseWarning(500, $e->getMessage()); + } + + return $options; + } + + /** + * Returns a list of elements filter options. + * + * @return string The HTML code for the select tag + */ + public static function elementOptions() + { + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->select('DISTINCT(element) AS value, element AS text') + ->from('#__extensions') + ->where($db->quoteName('type') . ' = ' . $db->quote('plugin')) + ->order('element'); + + $db->setQuery($query); + + try + { + $options = $db->loadObjectList(); + } + catch (RuntimeException $e) + { + JError::raiseWarning(500, $e->getMessage()); + } + + return $options; + } + + /** + * Parse the template file. + * + * @param string $templateBaseDir Base path to the template directory. + * @param string $templateDir Template directory. + * + * @return JObject + */ + public function parseXMLTemplateFile($templateBaseDir, $templateDir) + { + $data = new JObject; + + // Check of the xml file exists. + $filePath = JPath::clean($templateBaseDir . '/templates/' . $templateDir . '/templateDetails.xml'); + + if (is_file($filePath)) + { + $xml = JInstaller::parseXMLInstallFile($filePath); + + if ($xml['type'] != 'template') + { + return false; + } + + foreach ($xml as $key => $value) + { + $data->set($key, $value); + } + } + + return $data; + } +} diff --git a/Sites/pages/administrator/components/com_plugins/models/fields/pluginelement.php b/Sites/pages/administrator/components/com_plugins/models/fields/pluginelement.php new file mode 100644 index 00000000..30e4d24d --- /dev/null +++ b/Sites/pages/administrator/components/com_plugins/models/fields/pluginelement.php @@ -0,0 +1,44 @@ +form->getValue('folder'); + + // Build the query for the ordering list. + $query = $db->getQuery(true) + ->select( + array( + $db->quoteName('ordering', 'value'), + $db->quoteName('name', 'text'), + $db->quoteName('type'), + $db->quote('folder'), + $db->quote('extension_id') + ) + ) + ->from($db->quoteName('#__extensions')) + ->where('(type =' . $db->quote('plugin') . 'AND folder=' . $db->quote($folder) . ')') + ->order('ordering'); + + return $query; + } + + /** + * Retrieves the current Item's Id. + * + * @return integer The current item ID. + */ + protected function getItemId() + { + return (int) $this->form->getValue('extension_id'); + } +} diff --git a/Sites/pages/administrator/components/com_plugins/models/fields/plugintype.php b/Sites/pages/administrator/components/com_plugins/models/fields/plugintype.php new file mode 100644 index 00000000..8bb20234 --- /dev/null +++ b/Sites/pages/administrator/components/com_plugins/models/fields/plugintype.php @@ -0,0 +1,44 @@ + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Sites/pages/administrator/components/com_plugins/models/forms/plugin.xml b/Sites/pages/administrator/components/com_plugins/models/forms/plugin.xml new file mode 100644 index 00000000..271fc20e --- /dev/null +++ b/Sites/pages/administrator/components/com_plugins/models/forms/plugin.xml @@ -0,0 +1,71 @@ + +
    +
    + + + + + + + + + + + + + + + + +
    +
    diff --git a/Sites/pages/administrator/components/com_plugins/models/plugin.php b/Sites/pages/administrator/components/com_plugins/models/plugin.php new file mode 100644 index 00000000..54852b11 --- /dev/null +++ b/Sites/pages/administrator/components/com_plugins/models/plugin.php @@ -0,0 +1,370 @@ + 'onExtensionAfterSave', + 'event_before_save' => 'onExtensionBeforeSave', + 'events_map' => array( + 'save' => 'extension' + ) + ), $config + ); + + parent::__construct($config); + } + + /** + * Method to get the record form. + * + * @param array $data Data for the form. + * @param boolean $loadData True if the form is to load its own data (default case), false if not. + * + * @return JForm A JForm object on success, false on failure. + * + * @since 1.6 + */ + public function getForm($data = array(), $loadData = true) + { + // The folder and element vars are passed when saving the form. + if (empty($data)) + { + $item = $this->getItem(); + $folder = $item->folder; + $element = $item->element; + } + else + { + $folder = ArrayHelper::getValue($data, 'folder', '', 'cmd'); + $element = ArrayHelper::getValue($data, 'element', '', 'cmd'); + } + + // Add the default fields directory + JForm::addFieldPath(JPATH_PLUGINS . '/' . $folder . '/' . $element . '/field'); + + // These variables are used to add data from the plugin XML files. + $this->setState('item.folder', $folder); + $this->setState('item.element', $element); + + // Get the form. + $form = $this->loadForm('com_plugins.plugin', 'plugin', array('control' => 'jform', 'load_data' => $loadData)); + + if (empty($form)) + { + return false; + } + + // Modify the form based on access controls. + if (!$this->canEditState((object) $data)) + { + // Disable fields for display. + $form->setFieldAttribute('ordering', 'disabled', 'true'); + $form->setFieldAttribute('enabled', 'disabled', 'true'); + + // Disable fields while saving. + // The controller has already verified this is a record you can edit. + $form->setFieldAttribute('ordering', 'filter', 'unset'); + $form->setFieldAttribute('enabled', 'filter', 'unset'); + } + + return $form; + } + + /** + * Method to get the data that should be injected in the form. + * + * @return mixed The data for the form. + * + * @since 1.6 + */ + protected function loadFormData() + { + // Check the session for previously entered form data. + $data = JFactory::getApplication()->getUserState('com_plugins.edit.plugin.data', array()); + + if (empty($data)) + { + $data = $this->getItem(); + } + + $this->preprocessData('com_plugins.plugin', $data); + + return $data; + } + + /** + * Method to get a single record. + * + * @param integer $pk The id of the primary key. + * + * @return mixed Object on success, false on failure. + */ + public function getItem($pk = null) + { + $pk = (!empty($pk)) ? $pk : (int) $this->getState('plugin.id'); + + if (!isset($this->_cache[$pk])) + { + // Get a row instance. + $table = $this->getTable(); + + // Attempt to load the row. + $return = $table->load($pk); + + // Check for a table object error. + if ($return === false && $table->getError()) + { + $this->setError($table->getError()); + + return false; + } + + // Convert to the JObject before adding other data. + $properties = $table->getProperties(1); + $this->_cache[$pk] = ArrayHelper::toObject($properties, 'JObject'); + + // Convert the params field to an array. + $registry = new Registry($table->params); + $this->_cache[$pk]->params = $registry->toArray(); + + // Get the plugin XML. + $path = JPath::clean(JPATH_PLUGINS . '/' . $table->folder . '/' . $table->element . '/' . $table->element . '.xml'); + + if (file_exists($path)) + { + $this->_cache[$pk]->xml = simplexml_load_file($path); + } + else + { + $this->_cache[$pk]->xml = null; + } + } + + return $this->_cache[$pk]; + } + + /** + * Returns a reference to the Table object, always creating it. + * + * @param string $type The table type to instantiate. + * @param string $prefix A prefix for the table class name. Optional. + * @param array $config Configuration array for model. Optional. + * + * @return JTable A database object + */ + public function getTable($type = 'Extension', $prefix = 'JTable', $config = array()) + { + return JTable::getInstance($type, $prefix, $config); + } + + /** + * Auto-populate the model state. + * + * Note. Calling getState in this method will result in recursion. + * + * @return void + * + * @since 1.6 + */ + protected function populateState() + { + // Execute the parent method. + parent::populateState(); + + $app = JFactory::getApplication('administrator'); + + // Load the User state. + $pk = $app->input->getInt('extension_id'); + $this->setState('plugin.id', $pk); + } + + /** + * Preprocess the form. + * + * @param JForm $form A form object. + * @param mixed $data The data expected for the form. + * @param string $group Cache group name. + * + * @return mixed True if successful. + * + * @throws Exception if there is an error in the form event. + * @since 1.6 + */ + protected function preprocessForm(JForm $form, $data, $group = 'content') + { + jimport('joomla.filesystem.path'); + + $folder = $this->getState('item.folder'); + $element = $this->getState('item.element'); + $lang = JFactory::getLanguage(); + + // Load the core and/or local language sys file(s) for the ordering field. + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select($db->quoteName('element')) + ->from($db->quoteName('#__extensions')) + ->where($db->quoteName('type') . ' = ' . $db->quote('plugin')) + ->where($db->quoteName('folder') . ' = ' . $db->quote($folder)); + $db->setQuery($query); + $elements = $db->loadColumn(); + + foreach ($elements as $elementa) + { + $lang->load('plg_' . $folder . '_' . $elementa . '.sys', JPATH_ADMINISTRATOR, null, false, true) + || $lang->load('plg_' . $folder . '_' . $elementa . '.sys', JPATH_PLUGINS . '/' . $folder . '/' . $elementa, null, false, true); + } + + if (empty($folder) || empty($element)) + { + $app = JFactory::getApplication(); + $app->redirect(JRoute::_('index.php?option=com_plugins&view=plugins', false)); + } + + $formFile = JPath::clean(JPATH_PLUGINS . '/' . $folder . '/' . $element . '/' . $element . '.xml'); + + if (!file_exists($formFile)) + { + throw new Exception(JText::sprintf('COM_PLUGINS_ERROR_FILE_NOT_FOUND', $element . '.xml')); + } + + // Load the core and/or local language file(s). + $lang->load('plg_' . $folder . '_' . $element, JPATH_ADMINISTRATOR, null, false, true) + || $lang->load('plg_' . $folder . '_' . $element, JPATH_PLUGINS . '/' . $folder . '/' . $element, null, false, true); + + if (file_exists($formFile)) + { + // Get the plugin form. + if (!$form->loadFile($formFile, false, '//config')) + { + throw new Exception(JText::_('JERROR_LOADFILE_FAILED')); + } + } + + // Attempt to load the xml file. + if (!$xml = simplexml_load_file($formFile)) + { + throw new Exception(JText::_('JERROR_LOADFILE_FAILED')); + } + + // Get the help data from the XML file if present. + $help = $xml->xpath('/extension/help'); + + if (!empty($help)) + { + $helpKey = trim((string) $help[0]['key']); + $helpURL = trim((string) $help[0]['url']); + + $this->helpKey = $helpKey ?: $this->helpKey; + $this->helpURL = $helpURL ?: $this->helpURL; + } + + // Trigger the default form events. + parent::preprocessForm($form, $data, $group); + } + + /** + * A protected method to get a set of ordering conditions. + * + * @param object $table A record object. + * + * @return array An array of conditions to add to add to ordering queries. + * + * @since 1.6 + */ + protected function getReorderConditions($table) + { + $condition = array(); + $condition[] = 'type = ' . $this->_db->quote($table->type); + $condition[] = 'folder = ' . $this->_db->quote($table->folder); + + return $condition; + } + + /** + * Override method to save the form data. + * + * @param array $data The form data. + * + * @return boolean True on success. + * + * @since 1.6 + */ + public function save($data) + { + // Setup type. + $data['type'] = 'plugin'; + + return parent::save($data); + } + + /** + * Get the necessary data to load an item help screen. + * + * @return object An object with key, url, and local properties for loading the item help screen. + * + * @since 1.6 + */ + public function getHelp() + { + return (object) array('key' => $this->helpKey, 'url' => $this->helpURL); + } + + /** + * Custom clean cache method, plugins are cached in 2 places for different clients. + * + * @param string $group Cache group name. + * @param integer $clientId Application client id. + * + * @return void + * + * @since 1.6 + */ + protected function cleanCache($group = null, $clientId = 0) + { + parent::cleanCache('com_plugins', 0); + parent::cleanCache('com_plugins', 1); + } +} diff --git a/Sites/pages/administrator/components/com_plugins/models/plugins.php b/Sites/pages/administrator/components/com_plugins/models/plugins.php new file mode 100644 index 00000000..5551f921 --- /dev/null +++ b/Sites/pages/administrator/components/com_plugins/models/plugins.php @@ -0,0 +1,303 @@ +getUserStateFromRequest($this->context . '.filter.search', 'filter_search', '', 'string'); + $this->setState('filter.search', $search); + + $accessId = $this->getUserStateFromRequest($this->context . '.filter.access', 'filter_access', '', 'cmd'); + $this->setState('filter.access', $accessId); + + $state = $this->getUserStateFromRequest($this->context . '.filter.enabled', 'filter_enabled', '', 'cmd'); + $this->setState('filter.enabled', $state); + + $folder = $this->getUserStateFromRequest($this->context . '.filter.folder', 'filter_folder', '', 'string'); + $this->setState('filter.folder', $folder); + + $element = $this->getUserStateFromRequest($this->context . '.filter.element', 'filter_element', '', 'string'); + $this->setState('filter.element', $element); + + // Load the parameters. + $params = JComponentHelper::getParams('com_plugins'); + $this->setState('params', $params); + + // List state information. + parent::populateState($ordering, $direction); + } + + /** + * Method to get a store id based on model configuration state. + * + * This is necessary because the model is used by the component and + * different modules that might need different sets of data or different + * ordering requirements. + * + * @param string $id A prefix for the store id. + * + * @return string A store id. + */ + protected function getStoreId($id = '') + { + // Compile the store id. + $id .= ':' . $this->getState('filter.search'); + $id .= ':' . $this->getState('filter.access'); + $id .= ':' . $this->getState('filter.enabled'); + $id .= ':' . $this->getState('filter.folder'); + $id .= ':' . $this->getState('filter.element'); + + return parent::getStoreId($id); + } + + /** + * Returns an object list. + * + * @param JDatabaseQuery $query A database query object. + * @param integer $limitstart Offset. + * @param integer $limit The number of records. + * + * @return array + */ + protected function _getList($query, $limitstart = 0, $limit = 0) + { + $search = $this->getState('filter.search'); + $ordering = $this->getState('list.ordering', 'ordering'); + + // If "Sort Table By:" is not set, set ordering to name + if ($ordering == '') + { + $ordering = 'name'; + } + + if ($ordering == 'name' || (!empty($search) && stripos($search, 'id:') !== 0)) + { + $this->_db->setQuery($query); + $result = $this->_db->loadObjectList(); + $this->translate($result); + + if (!empty($search)) + { + $escapedSearchString = $this->refineSearchStringToRegex($search, '/'); + + foreach ($result as $i => $item) + { + if (!preg_match("/$escapedSearchString/i", $item->name)) + { + unset($result[$i]); + } + } + } + + $orderingDirection = strtolower($this->getState('list.direction')); + $direction = ($orderingDirection == 'desc') ? -1 : 1; + $result = ArrayHelper::sortObjects($result, $ordering, $direction, true, true); + + $total = count($result); + $this->cache[$this->getStoreId('getTotal')] = $total; + + if ($total < $limitstart) + { + $limitstart = 0; + $this->setState('list.start', 0); + } + + return array_slice($result, $limitstart, $limit ?: null); + } + else + { + if ($ordering == 'ordering') + { + $query->order('a.folder ASC'); + $ordering = 'a.ordering'; + } + + $query->order($this->_db->quoteName($ordering) . ' ' . $this->getState('list.direction')); + + if ($ordering == 'folder') + { + $query->order('a.ordering ASC'); + } + + $result = parent::_getList($query, $limitstart, $limit); + $this->translate($result); + + return $result; + } + } + + /** + * Translate a list of objects. + * + * @param array &$items The array of objects. + * + * @return array The array of translated objects. + */ + protected function translate(&$items) + { + $lang = JFactory::getLanguage(); + + foreach ($items as &$item) + { + $source = JPATH_PLUGINS . '/' . $item->folder . '/' . $item->element; + $extension = 'plg_' . $item->folder . '_' . $item->element; + $lang->load($extension . '.sys', JPATH_ADMINISTRATOR, null, false, true) + || $lang->load($extension . '.sys', $source, null, false, true); + $item->name = JText::_($item->name); + } + } + + /** + * Build an SQL query to load the list data. + * + * @return JDatabaseQuery + */ + protected function getListQuery() + { + // Create a new query object. + $db = $this->getDbo(); + $query = $db->getQuery(true); + + // Select the required fields from the table. + $query->select( + $this->getState( + 'list.select', + 'a.extension_id , a.name, a.element, a.folder, a.checked_out, a.checked_out_time,' . + ' a.enabled, a.access, a.ordering' + ) + ) + ->from($db->quoteName('#__extensions') . ' AS a') + ->where($db->quoteName('type') . ' = ' . $db->quote('plugin')); + + // Join over the users for the checked out user. + $query->select('uc.name AS editor') + ->join('LEFT', '#__users AS uc ON uc.id=a.checked_out'); + + // Join over the asset groups. + $query->select('ag.title AS access_level') + ->join('LEFT', '#__viewlevels AS ag ON ag.id = a.access'); + + // Filter by access level. + if ($access = $this->getState('filter.access')) + { + $query->where('a.access = ' . (int) $access); + } + + // Filter by published state. + $published = $this->getState('filter.enabled'); + + if (is_numeric($published)) + { + $query->where('a.enabled = ' . (int) $published); + } + elseif ($published === '') + { + $query->where('(a.enabled IN (0, 1))'); + } + + // Filter by state. + $query->where('a.state >= 0'); + + // Filter by folder. + if ($folder = $this->getState('filter.folder')) + { + $query->where('a.folder = ' . $db->quote($folder)); + } + + // Filter by element. + if ($element = $this->getState('filter.element')) + { + $query->where('a.element = ' . $db->quote($element)); + } + + // Filter by search in name or id. + $search = $this->getState('filter.search'); + + if (!empty($search)) + { + if (stripos($search, 'id:') === 0) + { + $query->where('a.extension_id = ' . (int) substr($search, 3)); + } + } + + return $query; + } + + /** + * Method to get the data that should be injected in the form. + * + * @return mixed The data for the form. + * + * @since 3.5 + */ + protected function loadFormData() + { + $data = parent::loadFormData(); + + // Set the selected filter values for pages that use the JLayouts for filtering + $data->list['sortTable'] = $this->state->get('list.ordering'); + $data->list['directionTable'] = $this->state->get('list.direction'); + + return $data; + } +} diff --git a/Sites/pages/administrator/components/com_plugins/plugins.php b/Sites/pages/administrator/components/com_plugins/plugins.php new file mode 100644 index 00000000..3c2cb8cc --- /dev/null +++ b/Sites/pages/administrator/components/com_plugins/plugins.php @@ -0,0 +1,20 @@ +authorise('core.manage', 'com_plugins')) +{ + throw new JAccessExceptionNotallowed(JText::_('JERROR_ALERTNOAUTHOR'), 403); +} + +$controller = JControllerLegacy::getInstance('Plugins'); +$controller->execute(JFactory::getApplication()->input->get('task')); +$controller->redirect(); diff --git a/Sites/pages/administrator/components/com_plugins/plugins.xml b/Sites/pages/administrator/components/com_plugins/plugins.xml new file mode 100644 index 00000000..6556e49d --- /dev/null +++ b/Sites/pages/administrator/components/com_plugins/plugins.xml @@ -0,0 +1,27 @@ + + + com_plugins + Joomla! Project + April 2006 + (C) 2005 - 2020 Open Source Matters. All rights reserved. + GNU General Public License version 2 or later; see LICENSE.txt + admin@joomla.org + www.joomla.org + 3.0.0 + COM_PLUGINS_XML_DESCRIPTION + + + config.xml + controller.php + plugins.php + controllers + helpers + models + views + + + language/en-GB.com_plugins.ini + language/en-GB.com_plugins.sys.ini + + + diff --git a/Sites/pages/administrator/components/com_plugins/views/plugin/tmpl/edit.php b/Sites/pages/administrator/components/com_plugins/views/plugin/tmpl/edit.php new file mode 100644 index 00000000..c2e051ee --- /dev/null +++ b/Sites/pages/administrator/components/com_plugins/views/plugin/tmpl/edit.php @@ -0,0 +1,160 @@ +fieldsets = $this->form->getFieldsets('params'); + +$input = JFactory::getApplication()->input; + +// In case of modal +$isModal = $input->get('layout') === 'modal' ? true : false; +$layout = $isModal ? 'modal' : 'edit'; +$tmpl = $isModal || $input->get('tmpl', '', 'cmd') === 'component' ? '&tmpl=component' : ''; + +JFactory::getDocument()->addScriptDeclaration(" + Joomla.submitbutton = function(task) { + if (task === 'plugin.cancel' || document.formvalidator.isValid(document.getElementById('style-form'))) { + Joomla.submitform(task, document.getElementById('style-form')); + + if (task !== 'plugin.apply') { + if (self !== top ) { + window.top.setTimeout('window.parent.location = window.top.location.href', 1000); + window.parent.jQuery('#plugin" . $this->item->extension_id . "Modal').modal('hide'); + } + } + } + }; +"); +?> + +
    +
    + + 'general')); ?> + + + +
    +
    + item->xml) : ?> + item->xml->description) : ?> +

    + item->xml) + { + echo ($text = (string) $this->item->xml->name) ? JText::_($text) : $this->item->name; + } + else + { + echo JText::_('COM_PLUGINS_XML_ERR'); + } + ?> +

    +
    + + form->getValue('folder'); ?> + / + + form->getValue('element'); ?> + +
    +
    + item->xml->description); + $this->fieldset = 'description'; + $long_description = JLayoutHelper::render('joomla.edit.fieldset', $this); + if (!$long_description) { + $truncated = JHtml::_('string.truncate', $short_description, 550, true, false); + if (strlen($truncated) > 500) { + $long_description = $short_description; + $short_description = JHtml::_('string.truncate', $truncated, 250); + if ($short_description == $long_description) { + $long_description = ''; + } + } + } + ?> +

    + +

    + + + +

    + +
    + + +
    + + + fieldset = 'basic'; + $html = JLayoutHelper::render('joomla.edit.fieldset', $this); + echo $html ? '
    ' . $html : ''; + ?> +
    +
    + +
    +
    +
    + form->getLabel('ordering'); ?> +
    +
    + form->getInput('ordering'); ?> +
    +
    +
    +
    + form->getLabel('folder'); ?> +
    +
    + form->getInput('folder'); ?> +
    +
    +
    +
    + form->getLabel('element'); ?> +
    +
    + form->getInput('element'); ?> +
    +
    +
    +
    +
    + + + + + + + + + fieldsets = array(); + $this->ignore_fieldsets = array('basic', 'description'); + echo JLayoutHelper::render('joomla.edit.params', $this); + ?> + + +
    + + + +
    + diff --git a/Sites/pages/administrator/components/com_plugins/views/plugin/tmpl/edit_options.php b/Sites/pages/administrator/components/com_plugins/views/plugin/tmpl/edit_options.php new file mode 100644 index 00000000..113e3ae5 --- /dev/null +++ b/Sites/pages/administrator/components/com_plugins/views/plugin/tmpl/edit_options.php @@ -0,0 +1,51 @@ +fieldsets as $name => $fieldset) +{ + if (!isset($fieldset->repeat) || isset($fieldset->repeat) && $fieldset->repeat == false) + { + $label = !empty($fieldset->label) ? JText::_($fieldset->label) : JText::_('COM_PLUGINS_' . $fieldset->name . '_FIELDSET_LABEL', true); + $optionsname = 'options-' . $fieldset->name; + echo JHtml::_('bootstrap.addTab', 'myTab', $optionsname, $label); + + if (isset($fieldset->description) && trim($fieldset->description)) + { + echo '

    ' . $this->escape(JText::_($fieldset->description)) . '

    '; + } + + $hidden_fields = ''; + + foreach ($this->form->getFieldset($name) as $field) + { + if (!$field->hidden) + { + ?> +
    +
    + label; ?> +
    +
    + input; ?> +
    +
    + input; + } + } + echo $hidden_fields; + + echo JHtml::_('bootstrap.endTab'); + } +} diff --git a/Sites/pages/administrator/components/com_plugins/views/plugin/tmpl/modal.php b/Sites/pages/administrator/components/com_plugins/views/plugin/tmpl/modal.php new file mode 100644 index 00000000..8232377f --- /dev/null +++ b/Sites/pages/administrator/components/com_plugins/views/plugin/tmpl/modal.php @@ -0,0 +1,29 @@ +addScriptDeclaration(' + window.parent.jQuery(".modal").on("hidden", function () { + if (typeof window.parent.jQuery("#plugin' . $this->item->extension_id . 'Modal iframe").contents().find("#closeBtn") !== "undefined") { + window.parent.jQuery("#plugin' . $this->item->extension_id . 'Modal iframe").contents().find("#closeBtn").click(); + } + }); +'); +?> + + + + +
    + setLayout('edit'); ?> + loadTemplate(); ?> +
    + diff --git a/Sites/pages/administrator/components/com_plugins/views/plugin/view.html.php b/Sites/pages/administrator/components/com_plugins/views/plugin/view.html.php new file mode 100644 index 00000000..b0ff3a02 --- /dev/null +++ b/Sites/pages/administrator/components/com_plugins/views/plugin/view.html.php @@ -0,0 +1,91 @@ +state = $this->get('State'); + $this->item = $this->get('Item'); + $this->form = $this->get('Form'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + $this->addToolbar(); + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + JFactory::getApplication()->input->set('hidemainmenu', true); + + $canDo = JHelperContent::getActions('com_plugins'); + + JToolbarHelper::title(JText::sprintf('COM_PLUGINS_MANAGER_PLUGIN', JText::_($this->item->name)), 'power-cord plugin'); + + // If not checked out, can save the item. + if ($canDo->get('core.edit')) + { + JToolbarHelper::apply('plugin.apply'); + JToolbarHelper::save('plugin.save'); + } + + JToolbarHelper::cancel('plugin.cancel', 'JTOOLBAR_CLOSE'); + JToolbarHelper::divider(); + + // Get the help information for the plugin item. + $lang = JFactory::getLanguage(); + + $help = $this->get('Help'); + + if ($lang->hasKey($help->url)) + { + $debug = $lang->setDebug(false); + $url = JText::_($help->url); + $lang->setDebug($debug); + } + else + { + $url = null; + } + + JToolbarHelper::help($help->key, false, $url); + } +} diff --git a/Sites/pages/administrator/components/com_plugins/views/plugins/tmpl/default.php b/Sites/pages/administrator/components/com_plugins/views/plugins/tmpl/default.php new file mode 100644 index 00000000..baf92b85 --- /dev/null +++ b/Sites/pages/administrator/components/com_plugins/views/plugins/tmpl/default.php @@ -0,0 +1,148 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$saveOrder = $listOrder == 'ordering'; + +if ($saveOrder) +{ + $saveOrderingUrl = 'index.php?option=com_plugins&task=plugins.saveOrderAjax&tmpl=component'; + JHtml::_('sortablelist.sortable', 'pluginList', 'adminForm', strtolower($listDirn), $saveOrderingUrl); +} +?> +
    +sidebar)) : ?> +
    + sidebar; ?> +
    +
    + +
    + + $this)); ?> +
    + items)) : ?> +
    + +
    + + + + + + + + + + + + + + + + + + + + + items as $i => $item) : + $ordering = ($listOrder == 'ordering'); + $canEdit = $user->authorise('core.edit', 'com_plugins'); + $canCheckin = $user->authorise('core.manage', 'com_checkin') || $item->checked_out == $user->get('id') || $item->checked_out == 0; + $canChange = $user->authorise('core.edit.state', 'com_plugins') && $canCheckin; + ?> + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + +
    + pagination->getListFooter(); ?> +
    + + + + + + + + + extension_id); ?> + + enabled, $i, 'plugins.', $canChange); ?> + + checked_out) : ?> + editor, $item->checked_out_time, 'plugins.', $canCheckin); ?> + + + + name; ?> + + name; ?> + + + escape($item->folder); ?> + + escape($item->element); ?> + + escape($item->access_level); ?> + + extension_id; ?> +
    + + + + + +
    + diff --git a/Sites/pages/administrator/components/com_plugins/views/plugins/tmpl/default.xml b/Sites/pages/administrator/components/com_plugins/views/plugins/tmpl/default.xml new file mode 100755 index 00000000..9d181a9f --- /dev/null +++ b/Sites/pages/administrator/components/com_plugins/views/plugins/tmpl/default.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/Sites/pages/administrator/components/com_plugins/views/plugins/view.html.php b/Sites/pages/administrator/components/com_plugins/views/plugins/view.html.php new file mode 100644 index 00000000..1c57fc39 --- /dev/null +++ b/Sites/pages/administrator/components/com_plugins/views/plugins/view.html.php @@ -0,0 +1,104 @@ +items = $this->get('Items'); + $this->pagination = $this->get('Pagination'); + $this->state = $this->get('State'); + $this->filterForm = $this->get('FilterForm'); + $this->activeFilters = $this->get('ActiveFilters'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + $this->addToolbar(); + + return parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + $canDo = JHelperContent::getActions('com_plugins'); + + JToolbarHelper::title(JText::_('COM_PLUGINS_MANAGER_PLUGINS'), 'power-cord plugin'); + + if ($canDo->get('core.edit')) + { + JToolbarHelper::editList('plugin.edit'); + } + + if ($canDo->get('core.edit.state')) + { + JToolbarHelper::publish('plugins.publish', 'JTOOLBAR_ENABLE', true); + JToolbarHelper::unpublish('plugins.unpublish', 'JTOOLBAR_DISABLE', true); + JToolbarHelper::checkin('plugins.checkin'); + } + + if ($canDo->get('core.admin')) + { + JToolbarHelper::preferences('com_plugins'); + } + + JToolbarHelper::help('JHELP_EXTENSIONS_PLUGIN_MANAGER'); + + } + + /** + * Returns an array of fields the table can be sorted by. + * + * @return array Array containing the field name to sort by as the key and display text as value. + * + * @since 3.0 + */ + protected function getSortFields() + { + return array( + 'ordering' => JText::_('JGRID_HEADING_ORDERING'), + 'enabled' => JText::_('JSTATUS'), + 'name' => JText::_('JGLOBAL_TITLE'), + 'folder' => JText::_('COM_PLUGINS_FOLDER_HEADING'), + 'element' => JText::_('COM_PLUGINS_ELEMENT_HEADING'), + 'access' => JText::_('JGRID_HEADING_ACCESS'), + 'extension_id' => JText::_('JGRID_HEADING_ID'), + ); + } +} diff --git a/Sites/pages/administrator/components/com_postinstall/access.xml b/Sites/pages/administrator/components/com_postinstall/access.xml new file mode 100644 index 00000000..70c6eb67 --- /dev/null +++ b/Sites/pages/administrator/components/com_postinstall/access.xml @@ -0,0 +1,7 @@ + + +
    + + +
    +
    diff --git a/Sites/pages/administrator/components/com_postinstall/config.xml b/Sites/pages/administrator/components/com_postinstall/config.xml new file mode 100644 index 00000000..620bddaa --- /dev/null +++ b/Sites/pages/administrator/components/com_postinstall/config.xml @@ -0,0 +1,18 @@ + + +
    + + +
    +
    \ No newline at end of file diff --git a/Sites/pages/administrator/components/com_postinstall/controllers/message.php b/Sites/pages/administrator/components/com_postinstall/controllers/message.php new file mode 100644 index 00000000..f024bd43 --- /dev/null +++ b/Sites/pages/administrator/components/com_postinstall/controllers/message.php @@ -0,0 +1,123 @@ +_csrfProtection(); + + /** @var PostinstallModelMessages $model */ + $model = $this->getThisModel(); + + $eid = (int) $model->getState('eid', '700', 'int'); + + if (empty($eid)) + { + $eid = 700; + } + + $model->resetMessages($eid); + + $this->setRedirect('index.php?option=com_postinstall&eid=' . $eid); + } + + /** + * Hides all post-installation messages of the specified extension. + * + * @return void + * + * @since 3.8.7 + */ + public function hideAll() + { + // CSRF prevention. + $this->_csrfProtection(); + + /** @var PostinstallModelMessages $model */ + $model = $this->getThisModel(); + + $eid = (int) $model->getState('eid', '700', 'int'); + + if (empty($eid)) + { + $eid = 700; + } + + $model->hideMessages($eid); + + $this->setRedirect('index.php?option=com_postinstall&eid=' . $eid); + } + + /** + * Executes the action associated with an item. + * + * @return void + * + * @since 3.2 + */ + public function action() + { + // CSRF prevention. + $this->_csrfProtection(); + + $model = $this->getThisModel(); + + if (!$model->getId()) + { + $model->setIDsFromRequest(); + } + + $item = $model->getItem(); + + switch ($item->type) + { + case 'link': + $this->setRedirect($item->action); + + return; + + break; + + case 'action': + jimport('joomla.filesystem.file'); + + $file = FOFTemplateUtils::parsePath($item->action_file, true); + + if (JFile::exists($file)) + { + require_once $file; + + call_user_func($item->action); + } + break; + + case 'message': + default: + break; + } + + $this->setRedirect('index.php?option=com_postinstall'); + } +} diff --git a/Sites/pages/administrator/components/com_postinstall/fof.xml b/Sites/pages/administrator/components/com_postinstall/fof.xml new file mode 100644 index 00000000..6e1ccce4 --- /dev/null +++ b/Sites/pages/administrator/components/com_postinstall/fof.xml @@ -0,0 +1,18 @@ + + + + + + + + + core.edit.state + + + browse + browse + browse + + + + diff --git a/Sites/pages/administrator/components/com_postinstall/models/messages.php b/Sites/pages/administrator/components/com_postinstall/models/messages.php new file mode 100644 index 00000000..146f9972 --- /dev/null +++ b/Sites/pages/administrator/components/com_postinstall/models/messages.php @@ -0,0 +1,487 @@ +getDbo(); + + // Add a forced extension filtering to the list + $eid = $this->getState('eid', 700); + $query->where($db->qn('extension_id') . ' = ' . $db->q($eid)); + + // Force filter only enabled messages + $published = $this->getState('published', 1, 'int'); + $query->where($db->qn('enabled') . ' = ' . (int) $published); + + return $query; + } + + /** + * Returns the name of an extension, as registered in the #__extensions table + * + * @param integer $eid The extension ID + * + * @return string The extension name + * + * @since 3.2 + */ + public function getExtensionName($eid) + { + // Load the extension's information from the database + $db = $this->getDbo(); + + $query = $db->getQuery(true) + ->select(array('name', 'element', 'client_id')) + ->from($db->qn('#__extensions')) + ->where($db->qn('extension_id') . ' = ' . (int) $eid); + + $db->setQuery($query, 0, 1); + + $extension = $db->loadObject(); + + if (!is_object($extension)) + { + return ''; + } + + // Load language files + $basePath = JPATH_ADMINISTRATOR; + + if ($extension->client_id == 0) + { + $basePath = JPATH_SITE; + } + + $lang = JFactory::getLanguage(); + $lang->load($extension->element, $basePath); + + // Return the localised name + return JText::_(strtoupper($extension->name)); + } + + /** + * Resets all messages for an extension + * + * @param integer $eid The extension ID whose messages we'll reset + * + * @return mixed False if we fail, a db cursor otherwise + * + * @since 3.2 + */ + public function resetMessages($eid) + { + $db = $this->getDbo(); + + $query = $db->getQuery(true) + ->update($db->qn('#__postinstall_messages')) + ->set($db->qn('enabled') . ' = 1') + ->where($db->qn('extension_id') . ' = ' . (int) $eid); + $db->setQuery($query); + + return $db->execute(); + } + + /** + * Hides all messages for an extension + * + * @param integer $eid The extension ID whose messages we'll hide + * + * @return mixed False if we fail, a db cursor otherwise + * + * @since 3.8.7 + */ + public function hideMessages($eid) + { + $db = $this->getDbo(); + + $query = $db->getQuery(true) + ->update($db->qn('#__postinstall_messages')) + ->set($db->qn('enabled') . ' = 0') + ->where($db->qn('extension_id') . ' = ' . (int) $eid); + $db->setQuery($query); + + return $db->execute(); + } + + /** + * List post-processing. This is used to run the programmatic display + * conditions against each list item and decide if we have to show it or + * not. + * + * Do note that this a core method of the RAD Layer which operates directly + * on the list it's being fed. A little touch of modern magic. + * + * @param array &$resultArray A list of items to process + * + * @return void + * + * @since 3.2 + */ + protected function onProcessList(&$resultArray) + { + $unset_keys = array(); + $language_extensions = array(); + + // Order the results DESC so the newest is on the top. + $resultArray = array_reverse($resultArray); + + foreach ($resultArray as $key => $item) + { + // Filter out messages based on dynamically loaded programmatic conditions. + if (!empty($item->condition_file) && !empty($item->condition_method)) + { + jimport('joomla.filesystem.file'); + + $file = FOFTemplateUtils::parsePath($item->condition_file, true); + + if (JFile::exists($file)) + { + require_once $file; + + $result = call_user_func($item->condition_method); + + if ($result === false) + { + $unset_keys[] = $key; + } + } + } + + // Load the necessary language files. + if (!empty($item->language_extension)) + { + $hash = $item->language_client_id . '-' . $item->language_extension; + + if (!in_array($hash, $language_extensions)) + { + $language_extensions[] = $hash; + JFactory::getLanguage()->load($item->language_extension, $item->language_client_id == 0 ? JPATH_SITE : JPATH_ADMINISTRATOR); + } + } + } + + if (!empty($unset_keys)) + { + foreach ($unset_keys as $key) + { + unset($resultArray[$key]); + } + } + } + + /** + * Get the dropdown options for the list of component with post-installation messages + * + * @since 3.4 + * + * @return array Compatible with JHtmlSelect::genericList + */ + public function getComponentOptions() + { + $db = $this->getDbo(); + + $query = $db->getQuery(true) + ->select('extension_id') + ->from($db->qn('#__postinstall_messages')) + ->group(array($db->qn('extension_id'))); + $db->setQuery($query); + $extension_ids = $db->loadColumn(); + + $options = array(); + + JFactory::getLanguage()->load('files_joomla.sys', JPATH_SITE, null, false, false); + + foreach ($extension_ids as $eid) + { + $options[] = JHtml::_('select.option', $eid, $this->getExtensionName($eid)); + } + + return $options; + } + + /** + * Adds or updates a post-installation message (PIM) definition. You can use this in your post-installation script using this code: + * + * require_once JPATH_LIBRARIES . '/fof/include.php'; + * FOFModel::getTmpInstance('Messages', 'PostinstallModel')->addPostInstallationMessage($options); + * + * The $options array contains the following mandatory keys: + * + * extension_id The numeric ID of the extension this message is for (see the #__extensions table) + * + * type One of message, link or action. Their meaning is: + * message Informative message. The user can dismiss it. + * link The action button links to a URL. The URL is defined in the action parameter. + * action A PHP action takes place when the action button is clicked. You need to specify the action_file + * (RAD path to the PHP file) and action (PHP function name) keys. See below for more information. + * + * title_key The JText language key for the title of this PIM. + * Example: COM_FOOBAR_POSTINSTALL_MESSAGEONE_TITLE + * + * description_key The JText language key for the main body (description) of this PIM + * Example: COM_FOOBAR_POSTINSTALL_MESSAGEONE_DESCRIPTION + * + * action_key The JText language key for the action button. Ignored and not required when type=message + * Example: COM_FOOBAR_POSTINSTALL_MESSAGEONE_ACTION + * + * language_extension The extension name which holds the language keys used above. + * For example, com_foobar, mod_something, plg_system_whatever, tpl_mytemplate + * + * language_client_id Should we load the frontend (0) or backend (1) language keys? + * + * version_introduced Which was the version of your extension where this message appeared for the first time? + * Example: 3.2.1 + * + * enabled Must be 1 for this message to be enabled. If you omit it, it defaults to 1. + * + * condition_file The RAD path to a PHP file containing a PHP function which determines whether this message should be shown to + * the user. @see FOFTemplateUtils::parsePath() for RAD path format. Joomla! will include this file before calling + * the condition_method. + * Example: admin://components/com_foobar/helpers/postinstall.php + * + * condition_method The name of a PHP function which will be used to determine whether to show this message to the user. This must be + * a simple PHP user function (not a class method, static method etc) which returns true to show the message and false + * to hide it. This function is defined in the condition_file. + * Example: com_foobar_postinstall_messageone_condition + * + * When type=message no additional keys are required. + * + * When type=link the following additional keys are required: + * + * action The URL which will open when the user clicks on the PIM's action button + * Example: index.php?option=com_foobar&view=tools&task=installSampleData + * + * When type=action the following additional keys are required: + * + * action_file The RAD path to a PHP file containing a PHP function which performs the action of this PIM. @see FOFTemplateUtils::parsePath() + * for RAD path format. Joomla! will include this file before calling the function defined in the action key below. + * Example: admin://components/com_foobar/helpers/postinstall.php + * + * action The name of a PHP function which will be used to run the action of this PIM. This must be a simple PHP user function + * (not a class method, static method etc) which returns no result. + * Example: com_foobar_postinstall_messageone_action + * + * @param array $options See description + * + * @return $this + * + * @throws Exception + */ + public function addPostInstallationMessage(array $options) + { + // Make sure there are options set + if (!is_array($options)) + { + throw new Exception('Post-installation message definitions must be of type array', 500); + } + + // Initialise array keys + $defaultOptions = array( + 'extension_id' => '', + 'type' => '', + 'title_key' => '', + 'description_key' => '', + 'action_key' => '', + 'language_extension' => '', + 'language_client_id' => '', + 'action_file' => '', + 'action' => '', + 'condition_file' => '', + 'condition_method' => '', + 'version_introduced' => '', + 'enabled' => '1', + ); + + $options = array_merge($defaultOptions, $options); + + // Array normalisation. Removes array keys not belonging to a definition. + $defaultKeys = array_keys($defaultOptions); + $allKeys = array_keys($options); + $extraKeys = array_diff($allKeys, $defaultKeys); + + if (!empty($extraKeys)) + { + foreach ($extraKeys as $key) + { + unset($options[$key]); + } + } + + // Normalisation of integer values + $options['extension_id'] = (int) $options['extension_id']; + $options['language_client_id'] = (int) $options['language_client_id']; + $options['enabled'] = (int) $options['enabled']; + + // Normalisation of 0/1 values + foreach (array('language_client_id', 'enabled') as $key) + { + $options[$key] = $options[$key] ? 1 : 0; + } + + // Make sure there's an extension_id + if (!(int) $options['extension_id']) + { + throw new Exception('Post-installation message definitions need an extension_id', 500); + } + + // Make sure there's a valid type + if (!in_array($options['type'], array('message', 'link', 'action'))) + { + throw new Exception('Post-installation message definitions need to declare a type of message, link or action', 500); + } + + // Make sure there's a title key + if (empty($options['title_key'])) + { + throw new Exception('Post-installation message definitions need a title key', 500); + } + + // Make sure there's a description key + if (empty($options['description_key'])) + { + throw new Exception('Post-installation message definitions need a description key', 500); + } + + // If the type is anything other than message you need an action key + if (($options['type'] != 'message') && empty($options['action_key'])) + { + throw new Exception('Post-installation message definitions need an action key when they are of type "' . $options['type'] . '"', 500); + } + + // You must specify the language extension + if (empty($options['language_extension'])) + { + throw new Exception('Post-installation message definitions need to specify which extension contains their language keys', 500); + } + + // The action file and method are only required for the "action" type + if ($options['type'] == 'action') + { + if (empty($options['action_file'])) + { + throw new Exception('Post-installation message definitions need an action file when they are of type "action"', 500); + } + + $file_path = FOFTemplateUtils::parsePath($options['action_file'], true); + + if (!@is_file($file_path)) + { + throw new Exception('The action file ' . $options['action_file'] . ' of your post-installation message definition does not exist', 500); + } + + if (empty($options['action'])) + { + throw new Exception('Post-installation message definitions need an action (function name) when they are of type "action"', 500); + } + } + + if ($options['type'] == 'link') + { + if (empty($options['link'])) + { + throw new Exception('Post-installation message definitions need an action (URL) when they are of type "link"', 500); + } + } + + // The condition file and method are only required when the type is not "message" + if ($options['type'] != 'message') + { + if (empty($options['condition_file'])) + { + throw new Exception('Post-installation message definitions need a condition file when they are of type "' . $options['type'] . '"', 500); + } + + $file_path = FOFTemplateUtils::parsePath($options['condition_file'], true); + + if (!@is_file($file_path)) + { + throw new Exception('The condition file ' . $options['condition_file'] . ' of your post-installation message definition does not exist', 500); + } + + if (empty($options['condition_method'])) + { + throw new Exception( + 'Post-installation message definitions need a condition method (function name) when they are of type "' + . $options['type'] . '"', + 500 + ); + } + } + + // Check if the definition exists + $table = $this->getTable(); + $tableName = $table->getTableName(); + + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select('*') + ->from($db->qn($tableName)) + ->where($db->qn('extension_id') . ' = ' . (int) $options['extension_id']) + ->where($db->qn('type') . ' = ' . $db->q($options['type'])) + ->where($db->qn('title_key') . ' = ' . $db->q($options['title_key'])); + + $existingRow = $db->setQuery($query)->loadAssoc(); + + // Is the existing definition the same as the one we're trying to save? + if (!empty($existingRow)) + { + $same = true; + + foreach ($options as $k => $v) + { + if ($existingRow[$k] != $v) + { + $same = false; + break; + } + } + + // Trying to add the same row as the existing one; quit + if ($same) + { + return $this; + } + + // Otherwise it's not the same row. Remove the old row before insert a new one. + $query = $db->getQuery(true) + ->delete($db->qn($tableName)) + ->where($db->q('extension_id') . ' = ' . (int) $options['extension_id']) + ->where($db->q('type') . ' = ' . $db->q($options['type'])) + ->where($db->q('title_key') . ' = ' . $db->q($options['title_key'])); + + $db->setQuery($query)->execute(); + } + + // Insert the new row + $options = (object) $options; + $db->insertObject($tableName, $options); + + return $this; + } +} diff --git a/Sites/pages/administrator/components/com_postinstall/postinstall.php b/Sites/pages/administrator/components/com_postinstall/postinstall.php new file mode 100644 index 00000000..7520b0ea --- /dev/null +++ b/Sites/pages/administrator/components/com_postinstall/postinstall.php @@ -0,0 +1,13 @@ +dispatch(); diff --git a/Sites/pages/administrator/components/com_postinstall/postinstall.xml b/Sites/pages/administrator/components/com_postinstall/postinstall.xml new file mode 100644 index 00000000..81f14a2c --- /dev/null +++ b/Sites/pages/administrator/components/com_postinstall/postinstall.xml @@ -0,0 +1,28 @@ + + + com_postinstall + Joomla! Project + September 2013 + (C) 2005 - 2020 Open Source Matters. All rights reserved. + GNU General Public License version 2 or later; see LICENSE.txt + admin@joomla.org + www.joomla.org + 3.2.0 + COM_POSTINSTALL_XML_DESCRIPTION + + + access.xml + config.xml + fof.xml + postinstall.php + toolbar.php + controllers + models + views + + + language/en-GB.com_postinstall.ini + language/en-GB.com_postinstall.sys.ini + + + diff --git a/Sites/pages/administrator/components/com_postinstall/toolbar.php b/Sites/pages/administrator/components/com_postinstall/toolbar.php new file mode 100644 index 00000000..349be47b --- /dev/null +++ b/Sites/pages/administrator/components/com_postinstall/toolbar.php @@ -0,0 +1,31 @@ +config['option'], 550, 875); + JToolbarHelper::help('JHELP_COMPONENTS_POST_INSTALLATION_MESSAGES'); + } +} diff --git a/Sites/pages/administrator/components/com_postinstall/views/messages/tmpl/default.php b/Sites/pages/administrator/components/com_postinstall/views/messages/tmpl/default.php new file mode 100644 index 00000000..c37e0451 --- /dev/null +++ b/Sites/pages/administrator/components/com_postinstall/views/messages/tmpl/default.php @@ -0,0 +1,86 @@ +loadRenderer('module'); +$options = array('style' => 'raw'); +$mod = JModuleHelper::getModule('mod_feed'); +$param = array( + 'rssurl' => 'https://www.joomla.org/announcements/release-news.feed?type=rss', + 'rsstitle' => 0, + 'rssdesc' => 0, + 'rssimage' => 1, + 'rssitems' => 5, + 'rssitemdesc' => 1, + 'rssitemdate' => 1, + 'rssrtl' => $lang->isRtl() ? 1 : 0, + 'word_count' => 200, + 'cache' => 0, + ); +$params = array('params' => json_encode($param)); + +JHtml::_('formbehavior.chosen', 'select'); +?> + +
    + + + + + extension_options, 'eid', array('onchange' => 'this.form.submit()', 'class' => 'input-xlarge'), 'value', 'text', $this->eid, 'eid'); ?> +
    + +eid == 700) : ?> +
    +
    + + items)) : ?> +
    +

    +

    + + + + +
    + + items as $item) : ?> +
    + title_key); ?> +

    + version_introduced); ?> +

    +
    + description_key); ?> + type !== 'message') : ?> + + action_key); ?> + + + authorise('core.edit.state', 'com_postinstall')) : ?> + + + + +
    +
    + + +eid == 700) : ?> +
    +
    isRtl()) : ?> style="padding-right: 20px;"> +

    + render($mod, $params, $options); ?> +
    +
    + diff --git a/Sites/pages/administrator/components/com_postinstall/views/messages/tmpl/default.xml b/Sites/pages/administrator/components/com_postinstall/views/messages/tmpl/default.xml new file mode 100755 index 00000000..f4b7d574 --- /dev/null +++ b/Sites/pages/administrator/components/com_postinstall/views/messages/tmpl/default.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/Sites/pages/administrator/components/com_postinstall/views/messages/view.html.php b/Sites/pages/administrator/components/com_postinstall/views/messages/view.html.php new file mode 100644 index 00000000..9d1b39ca --- /dev/null +++ b/Sites/pages/administrator/components/com_postinstall/views/messages/view.html.php @@ -0,0 +1,68 @@ +getModel(); + + $this->eid = (int) $model->getState('eid', '700', 'int'); + + if (empty($this->eid)) + { + $this->eid = 700; + } + + $this->token = JFactory::getSession()->getFormToken(); + $this->extension_options = $model->getComponentOptions(); + + JToolBarHelper::title(JText::sprintf('COM_POSTINSTALL_MESSAGES_TITLE', $model->getExtensionName($this->eid))); + + return parent::onBrowse($tpl); + } + + /** + * Executes on display of the page + * + * @param string $tpl Subtemplate to use + * + * @return boolean Return true to allow rendering of the page + * + * @since 3.8.7 + */ + protected function onDisplay($tpl = null) + { + $return = parent::onDisplay($tpl); + + if (!empty($this->items)) + { + JToolbarHelper::custom('hideAll', 'unpublish.png', 'unpublish_f2.png', 'COM_POSTINSTALL_HIDE_ALL_MESSAGES', false); + } + + return $return; + } +} diff --git a/Sites/pages/administrator/components/com_privacy/config.xml b/Sites/pages/administrator/components/com_privacy/config.xml new file mode 100644 index 00000000..833d1a28 --- /dev/null +++ b/Sites/pages/administrator/components/com_privacy/config.xml @@ -0,0 +1,22 @@ + + +
    + + + +
    +
    diff --git a/Sites/pages/administrator/components/com_privacy/controller.php b/Sites/pages/administrator/components/com_privacy/controller.php new file mode 100644 index 00000000..987b0698 --- /dev/null +++ b/Sites/pages/administrator/components/com_privacy/controller.php @@ -0,0 +1,140 @@ +input->get('view', $this->default_view); + $vFormat = $document->getType(); + $lName = $this->input->get('layout', 'default', 'string'); + + // Get and render the view. + if ($view = $this->getView($vName, $vFormat)) + { + $model = $this->getModel($vName); + $view->setModel($model, true); + + // For the dashboard view, we need to also push the requests model into the view + if ($vName === 'dashboard') + { + $requestsModel = $this->getModel('Requests'); + + $view->setModel($requestsModel, false); + } + + if ($vName === 'request') + { + // For the default layout, we need to also push the action logs model into the view + if ($lName === 'default') + { + JLoader::register('ActionlogsHelper', JPATH_ADMINISTRATOR . '/components/com_actionlogs/helpers/actionlogs.php'); + JModelLegacy::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_actionlogs/models', 'ActionlogsModel'); + + $logsModel = $this->getModel('Actionlogs', 'ActionlogsModel'); + + // Set default ordering for the context + $logsModel->setState('list.fullordering', 'a.log_date DESC'); + + // And push the model into the view + $view->setModel($logsModel, false); + } + + // For the edit layout, if mail sending is disabled then redirect back to the list view as the form is unusable in this state + if ($lName === 'edit' && !JFactory::getConfig()->get('mailonline', 1)) + { + $this->setRedirect( + JRoute::_('index.php?option=com_privacy&view=requests', false), + JText::_('COM_PRIVACY_WARNING_CANNOT_CREATE_REQUEST_WHEN_SENDMAIL_DISABLED'), + 'warning' + ); + + return $this; + } + } + + $view->setLayout($lName); + + // Push document object into the view. + $view->document = $document; + + // Load the submenu. + PrivacyHelper::addSubmenu($this->input->get('view', $this->default_view)); + + $view->display(); + } + + return $this; + } + + /** + * Fetch and report number urgent privacy requests in JSON format, for AJAX requests + * + * @return void + * + * @since 3.9.0 + */ + public function getNumberUrgentRequests() + { + $app = Factory::getApplication(); + + // Check for a valid token. If invalid, send a 403 with the error message. + if (!Session::checkToken('get')) + { + $app->setHeader('status', 403, true); + $app->sendHeaders(); + echo new JsonResponse(new \Exception(Text::_('JINVALID_TOKEN'), 403)); + $app->close(); + } + + /** @var PrivacyModelRequests $model */ + $model = $this->getModel('requests'); + $numberUrgentRequests = $model->getNumberUrgentRequests(); + + echo new JResponseJson(array('number_urgent_requests' => $numberUrgentRequests)); + + $app->close(); + } +} diff --git a/Sites/pages/administrator/components/com_privacy/controllers/consents.php b/Sites/pages/administrator/components/com_privacy/controllers/consents.php new file mode 100644 index 00000000..eb1ba5d5 --- /dev/null +++ b/Sites/pages/administrator/components/com_privacy/controllers/consents.php @@ -0,0 +1,92 @@ +input->get('cid', array(), 'array'); + + if (empty($ids)) + { + $this->setError(JText::_('JERROR_NO_ITEMS_SELECTED')); + } + else + { + // Get the model. + /** @var PrivacyModelConsents $model */ + $model = $this->getModel(); + + // Publish the items. + if (!$model->invalidate($ids)) + { + $this->setError($model->getError()); + } + + $message = JText::plural('COM_PRIVACY_N_CONSENTS_INVALIDATED', count($ids)); + } + + $this->setRedirect(JRoute::_('index.php?option=com_privacy&view=consents', false), $message); + } + + /** + * Method to invalidate all consents of a specific subject. + * + * @return boolean + * + * @since 3.9.0 + */ + public function invalidateAll() + { + // Check for request forgeries + JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + + $filters = $this->input->get('filter', array(), 'array'); + + if (isset($filters['subject']) && $filters['subject'] != '') + { + $subject = $filters['subject']; + } + else + { + $this->setError(JText::_('JERROR_NO_ITEMS_SELECTED')); + } + + // Get the model. + /** @var PrivacyModelConsents $model */ + $model = $this->getModel(); + + // Publish the items. + if (!$model->invalidateAll($subject)) + { + $this->setError($model->getError()); + } + + $message = JText::_('COM_PRIVACY_CONSENTS_INVALIDATED_ALL'); + + $this->setRedirect(JRoute::_('index.php?option=com_privacy&view=consents', false), $message); + } +} diff --git a/Sites/pages/administrator/components/com_privacy/controllers/request.php b/Sites/pages/administrator/components/com_privacy/controllers/request.php new file mode 100644 index 00000000..9fa20e22 --- /dev/null +++ b/Sites/pages/administrator/components/com_privacy/controllers/request.php @@ -0,0 +1,401 @@ +getModel(); + + /** @var PrivacyTableRequest $table */ + $table = $model->getTable(); + + // Determine the name of the primary key for the data. + if (empty($key)) + { + $key = $table->getKeyName(); + } + + // To avoid data collisions the urlVar may be different from the primary key. + if (empty($urlVar)) + { + $urlVar = $key; + } + + $recordId = $this->input->getInt($urlVar); + + $item = $model->getItem($recordId); + + // Ensure this record can transition to the requested state + if (!$this->canTransition($item, '2')) + { + $this->setError(\JText::_('COM_PRIVACY_ERROR_COMPLETE_TRANSITION_NOT_PERMITTED')); + $this->setMessage($this->getError(), 'error'); + + $this->setRedirect( + \JRoute::_( + 'index.php?option=com_privacy&view=request&id=' . $recordId, false + ) + ); + + return false; + } + + // Build the data array for the update + $data = array( + $key => $recordId, + 'status' => '2', + ); + + // Access check. + if (!$this->allowSave($data, $key)) + { + $this->setError(\JText::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED')); + $this->setMessage($this->getError(), 'error'); + + $this->setRedirect( + \JRoute::_( + 'index.php?option=com_privacy&view=request&id=' . $recordId, false + ) + ); + + return false; + } + + // Attempt to save the data. + if (!$model->save($data)) + { + // Redirect back to the edit screen. + $this->setError(\JText::sprintf('JLIB_APPLICATION_ERROR_SAVE_FAILED', $model->getError())); + $this->setMessage($this->getError(), 'error'); + + $this->setRedirect( + \JRoute::_( + 'index.php?option=com_privacy&view=request&id=' . $recordId, false + ) + ); + + return false; + } + + // Log the request completed + $model->logRequestCompleted($recordId); + + $this->setMessage(\JText::_('COM_PRIVACY_REQUEST_COMPLETED')); + + $url = 'index.php?option=com_privacy&view=requests'; + + // Check if there is a return value + $return = $this->input->get('return', null, 'base64'); + + if (!is_null($return) && \JUri::isInternal(base64_decode($return))) + { + $url = base64_decode($return); + } + + // Redirect to the list screen. + $this->setRedirect(\JRoute::_($url, false)); + + return true; + } + + /** + * Method to email the data export for a request. + * + * @return boolean + * + * @since 3.9.0 + */ + public function emailexport() + { + // Check for request forgeries. + $this->checkToken('get'); + + /** @var PrivacyModelExport $model */ + $model = $this->getModel('Export'); + + $recordId = $this->input->getUint('id'); + + if (!$model->emailDataExport($recordId)) + { + // Redirect back to the edit screen. + $this->setError(\JText::sprintf('COM_PRIVACY_ERROR_EXPORT_EMAIL_FAILED', $model->getError())); + $this->setMessage($this->getError(), 'error'); + } + else + { + $this->setMessage(\JText::_('COM_PRIVACY_EXPORT_EMAILED')); + } + + $url = 'index.php?option=com_privacy&view=requests'; + + // Check if there is a return value + $return = $this->input->get('return', null, 'base64'); + + if (!is_null($return) && \JUri::isInternal(base64_decode($return))) + { + $url = base64_decode($return); + } + + // Redirect to the list screen. + $this->setRedirect(\JRoute::_($url, false)); + + return true; + } + + /** + * Method to invalidate a request. + * + * @param string $key The name of the primary key of the URL variable. + * @param string $urlVar The name of the URL variable if different from the primary key (sometimes required to avoid router collisions). + * + * @return boolean + * + * @since 3.9.0 + */ + public function invalidate($key = null, $urlVar = null) + { + // Check for request forgeries. + JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + + /** @var PrivacyModelRequest $model */ + $model = $this->getModel(); + + /** @var PrivacyTableRequest $table */ + $table = $model->getTable(); + + // Determine the name of the primary key for the data. + if (empty($key)) + { + $key = $table->getKeyName(); + } + + // To avoid data collisions the urlVar may be different from the primary key. + if (empty($urlVar)) + { + $urlVar = $key; + } + + $recordId = $this->input->getInt($urlVar); + + $item = $model->getItem($recordId); + + // Ensure this record can transition to the requested state + if (!$this->canTransition($item, '-1')) + { + $this->setError(\JText::_('COM_PRIVACY_ERROR_INVALID_TRANSITION_NOT_PERMITTED')); + $this->setMessage($this->getError(), 'error'); + + $this->setRedirect( + \JRoute::_( + 'index.php?option=com_privacy&view=request&id=' . $recordId, false + ) + ); + + return false; + } + + // Build the data array for the update + $data = array( + $key => $recordId, + 'status' => '-1', + ); + + // Access check. + if (!$this->allowSave($data, $key)) + { + $this->setError(\JText::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED')); + $this->setMessage($this->getError(), 'error'); + + $this->setRedirect( + \JRoute::_( + 'index.php?option=com_privacy&view=request&id=' . $recordId, false + ) + ); + + return false; + } + + // Attempt to save the data. + if (!$model->save($data)) + { + // Redirect back to the edit screen. + $this->setError(\JText::sprintf('JLIB_APPLICATION_ERROR_SAVE_FAILED', $model->getError())); + $this->setMessage($this->getError(), 'error'); + + $this->setRedirect( + \JRoute::_( + 'index.php?option=com_privacy&view=request&id=' . $recordId, false + ) + ); + + return false; + } + + // Log the request invalidated + $model->logRequestInvalidated($recordId); + + $this->setMessage(\JText::_('COM_PRIVACY_REQUEST_INVALIDATED')); + + $url = 'index.php?option=com_privacy&view=requests'; + + // Check if there is a return value + $return = $this->input->get('return', null, 'base64'); + + if (!is_null($return) && \JUri::isInternal(base64_decode($return))) + { + $url = base64_decode($return); + } + + // Redirect to the list screen. + $this->setRedirect(\JRoute::_($url, false)); + + return true; + } + + /** + * Method to remove the user data for a privacy remove request. + * + * @return boolean + * + * @since 3.9.0 + */ + public function remove() + { + // Check for request forgeries. + $this->checkToken('request'); + + /** @var PrivacyModelRemove $model */ + $model = $this->getModel('Remove'); + + $recordId = $this->input->getUint('id'); + + if (!$model->removeDataForRequest($recordId)) + { + // Redirect back to the edit screen. + $this->setError(\JText::sprintf('COM_PRIVACY_ERROR_REMOVE_DATA_FAILED', $model->getError())); + $this->setMessage($this->getError(), 'error'); + + $this->setRedirect( + \JRoute::_( + 'index.php?option=com_privacy&view=request&id=' . $recordId, false + ) + ); + + return false; + } + + $this->setMessage(\JText::_('COM_PRIVACY_DATA_REMOVED')); + + $url = 'index.php?option=com_privacy&view=requests'; + + // Check if there is a return value + $return = $this->input->get('return', null, 'base64'); + + if (!is_null($return) && \JUri::isInternal(base64_decode($return))) + { + $url = base64_decode($return); + } + + // Redirect to the list screen. + $this->setRedirect(\JRoute::_($url, false)); + + return true; + } + + /** + * Function that allows child controller access to model data after the data has been saved. + * + * @param \JModelLegacy $model The data model object. + * @param array $validData The validated data. + * + * @return void + * + * @since 3.9.0 + */ + protected function postSaveHook(\JModelLegacy $model, $validData = array()) + { + // This hook only processes new items + if (!$model->getState($model->getName() . '.new', false)) + { + return; + } + + if (!$model->logRequestCreated($model->getState($model->getName() . '.id'))) + { + if ($error = $model->getError()) + { + JFactory::getApplication()->enqueueMessage($error, 'warning'); + } + } + + if (!$model->notifyUserAdminCreatedRequest($model->getState($model->getName() . '.id'))) + { + if ($error = $model->getError()) + { + JFactory::getApplication()->enqueueMessage($error, 'warning'); + } + } + else + { + JFactory::getApplication()->enqueueMessage(JText::_('COM_PRIVACY_MSG_CONFIRM_EMAIL_SENT_TO_USER')); + } + } + + /** + * Method to determine if an item can transition to the specified status. + * + * @param object $item The item being updated. + * @param string $newStatus The new status of the item. + * + * @return boolean + * + * @since 3.9.0 + */ + private function canTransition($item, $newStatus) + { + switch ($item->status) + { + case '0': + // A pending item can only move to invalid through this controller due to the requirement for a user to confirm the request + return $newStatus === '-1'; + + case '1': + // A confirmed item can be marked completed or invalid + return in_array($newStatus, array('-1', '2'), true); + + // An item which is already in an invalid or complete state cannot transition, likewise if we don't know the state don't change anything + case '-1': + case '2': + default: + return false; + } + } +} diff --git a/Sites/pages/administrator/components/com_privacy/controllers/request.xml.php b/Sites/pages/administrator/components/com_privacy/controllers/request.xml.php new file mode 100644 index 00000000..1aee825d --- /dev/null +++ b/Sites/pages/administrator/components/com_privacy/controllers/request.xml.php @@ -0,0 +1,32 @@ +input->set('view', 'export'); + + return $this->display(); + } +} diff --git a/Sites/pages/administrator/components/com_privacy/controllers/requests.php b/Sites/pages/administrator/components/com_privacy/controllers/requests.php new file mode 100644 index 00000000..66750d64 --- /dev/null +++ b/Sites/pages/administrator/components/com_privacy/controllers/requests.php @@ -0,0 +1,34 @@ + true)) + { + return parent::getModel($name, $prefix, $config); + } +} diff --git a/Sites/pages/administrator/components/com_privacy/helpers/export/domain.php b/Sites/pages/administrator/components/com_privacy/helpers/export/domain.php new file mode 100644 index 00000000..7ed3894c --- /dev/null +++ b/Sites/pages/administrator/components/com_privacy/helpers/export/domain.php @@ -0,0 +1,72 @@ +items[] = $item; + } + + /** + * Get the domain's items + * + * @return PrivacyExportItem[] + * + * @since 3.9.0 + */ + public function getItems() + { + return $this->items; + } +} diff --git a/Sites/pages/administrator/components/com_privacy/helpers/export/field.php b/Sites/pages/administrator/components/com_privacy/helpers/export/field.php new file mode 100644 index 00000000..cb7d7d8b --- /dev/null +++ b/Sites/pages/administrator/components/com_privacy/helpers/export/field.php @@ -0,0 +1,34 @@ +fields[] = $field; + } + + /** + * Get the item's fields + * + * @return PrivacyExportField[] + * + * @since 3.9.0 + */ + public function getFields() + { + return $this->fields; + } +} diff --git a/Sites/pages/administrator/components/com_privacy/helpers/html/helper.php b/Sites/pages/administrator/components/com_privacy/helpers/html/helper.php new file mode 100644 index 00000000..735fea32 --- /dev/null +++ b/Sites/pages/administrator/components/com_privacy/helpers/html/helper.php @@ -0,0 +1,46 @@ +' . JText::_('COM_PRIVACY_STATUS_COMPLETED') . ''; + + case 1: + return '' . JText::_('COM_PRIVACY_STATUS_CONFIRMED') . ''; + + case -1: + return '' . JText::_('COM_PRIVACY_STATUS_INVALID') . ''; + + default: + case 0: + return '' . JText::_('COM_PRIVACY_STATUS_PENDING') . ''; + } + } +} diff --git a/Sites/pages/administrator/components/com_privacy/helpers/plugin.php b/Sites/pages/administrator/components/com_privacy/helpers/plugin.php new file mode 100644 index 00000000..548f15ca --- /dev/null +++ b/Sites/pages/administrator/components/com_privacy/helpers/plugin.php @@ -0,0 +1,167 @@ +name = $name; + $domain->description = $description; + + return $domain; + } + + /** + * Create an item object for an array + * + * @param array $data The array data to convert + * @param integer|null $itemId The ID of this item + * + * @return PrivacyExportItem + * + * @since 3.9.0 + */ + protected function createItemFromArray(array $data, $itemId = null) + { + $item = new PrivacyExportItem; + $item->id = $itemId; + + foreach ($data as $key => $value) + { + if (is_object($value)) + { + $value = (array) $value; + } + + if (is_array($value)) + { + $value = print_r($value, true); + } + + $field = new PrivacyExportField; + $field->name = $key; + $field->value = $value; + + $item->addField($field); + } + + return $item; + } + + /** + * Create an item object for a JTable object + * + * @param JTable $table The JTable object to convert + * + * @return PrivacyExportItem + * + * @since 3.9.0 + */ + protected function createItemForTable($table) + { + $data = array(); + + foreach (array_keys($table->getFields()) as $fieldName) + { + $data[$fieldName] = $table->$fieldName; + } + + return $this->createItemFromArray($data, $table->{$table->getKeyName(false)}); + } + + /** + * Helper function to create the domain for the items custom fields. + * + * @param string $context The context + * @param array $items The items + * + * @return PrivacyExportDomain + * + * @since 3.9.0 + */ + protected function createCustomFieldsDomain($context, $items = array()) + { + if (!is_array($items)) + { + $items = array($items); + } + + $parts = FieldsHelper::extract($context); + + if (!$parts) + { + return array(); + } + + $type = str_replace('com_', '', $parts[0]); + + $domain = $this->createDomain($type . '_' . $parts[1] . '_custom_fields', 'joomla_' . $type . '_' . $parts[1] . '_custom_fields_data'); + + foreach ($items as $item) + { + // Get item's fields, also preparing their value property for manual display + $fields = FieldsHelper::getFields($parts[0] . '.' . $parts[1], $item); + + foreach ($fields as $field) + { + $fieldValue = is_array($field->value) ? implode(', ', $field->value) : $field->value; + + $data = array( + $type . '_id' => $item->id, + 'field_name' => $field->name, + 'field_title' => $field->title, + 'field_value' => $fieldValue, + ); + + $domain->addItem($this->createItemFromArray($data)); + } + } + + return $domain; + } +} diff --git a/Sites/pages/administrator/components/com_privacy/helpers/privacy.php b/Sites/pages/administrator/components/com_privacy/helpers/privacy.php new file mode 100644 index 00000000..ba0b5718 --- /dev/null +++ b/Sites/pages/administrator/components/com_privacy/helpers/privacy.php @@ -0,0 +1,128 @@ +'); + + foreach ($exportData as $domain) + { + $xmlDomain = $export->addChild('domain'); + $xmlDomain->addAttribute('name', $domain->name); + $xmlDomain->addAttribute('description', $domain->description); + + foreach ($domain->getItems() as $item) + { + $xmlItem = $xmlDomain->addChild('item'); + + if ($item->id) + { + $xmlItem->addAttribute('id', $item->id); + } + + foreach ($item->getFields() as $field) + { + $xmlItem->{$field->name} = $field->value; + } + } + } + + $dom = new DOMDocument; + $dom->loadXML($export->asXML()); + $dom->formatOutput = true; + + return $dom->saveXML(); + } + + /** + * Gets the privacyconsent system plugin extension id. + * + * @return integer The privacyconsent system plugin extension id. + * + * @since 3.9.2 + */ + public static function getPrivacyConsentPluginId() + { + $db = Factory::getDbo(); + $query = $db->getQuery(true) + ->select($db->quoteName('extension_id')) + ->from($db->quoteName('#__extensions')) + ->where($db->quoteName('folder') . ' = ' . $db->quote('system')) + ->where($db->quoteName('element') . ' = ' . $db->quote('privacyconsent')); + + $db->setQuery($query); + + try + { + $result = (int) $db->loadResult(); + } + catch (RuntimeException $e) + { + JError::raiseWarning(500, $e->getMessage()); + } + + return $result; + } +} diff --git a/Sites/pages/administrator/components/com_privacy/helpers/removal/status.php b/Sites/pages/administrator/components/com_privacy/helpers/removal/status.php new file mode 100644 index 00000000..60a494e4 --- /dev/null +++ b/Sites/pages/administrator/components/com_privacy/helpers/removal/status.php @@ -0,0 +1,36 @@ + array( + JText::_('COM_PRIVACY_CORE_CAPABILITY_SESSION_IP_ADDRESS_AND_COOKIE'), + JText::sprintf('COM_PRIVACY_CORE_CAPABILITY_LOGGING_IP_ADDRESS', $app->get('log_path', JPATH_ADMINISTRATOR . '/logs')), + JText::_('COM_PRIVACY_CORE_CAPABILITY_COMMUNICATION_WITH_JOOMLA_ORG'), + ) + ); + + /* + * We will search for capabilities from the following plugin groups: + * + * - Authentication: These plugins by design process user information and may have capabilities such as creating cookies + * - Captcha: These plugins may communicate information to third party systems + * - Installer: These plugins can add additional install capabilities to the Extension Manager, such as the Install from Web service + * - Privacy: These plugins are the primary integration point into this component + * - User: These plugins are intended to extend the user management system + * + * This is in addition to plugin groups which are imported before this method is triggered, generally this is the system group. + */ + + JPluginHelper::importPlugin('authentication'); + JPluginHelper::importPlugin('captcha'); + JPluginHelper::importPlugin('installer'); + JPluginHelper::importPlugin('privacy'); + JPluginHelper::importPlugin('user'); + + $pluginResults = $app->triggerEvent('onPrivacyCollectAdminCapabilities'); + + // We are going to "cheat" here and include this component's capabilities without using a plugin + $extensionCapabilities = array( + JText::_('COM_PRIVACY') => array( + JText::_('COM_PRIVACY_EXTENSION_CAPABILITY_PERSONAL_INFO'), + ) + ); + + foreach ($pluginResults as $pluginResult) + { + $extensionCapabilities += $pluginResult; + } + + // Sort the extension list alphabetically + ksort($extensionCapabilities); + + // Always prepend the core capabilities to the array + return $coreCapabilities + $extensionCapabilities; + } + + /** + * Method to auto-populate the model state. + * + * @return void + * + * @since 3.9.0 + */ + protected function populateState() + { + // Load the parameters. + $this->setState('params', JComponentHelper::getParams('com_privacy')); + } +} diff --git a/Sites/pages/administrator/components/com_privacy/models/consents.php b/Sites/pages/administrator/components/com_privacy/models/consents.php new file mode 100644 index 00000000..0c448402 --- /dev/null +++ b/Sites/pages/administrator/components/com_privacy/models/consents.php @@ -0,0 +1,226 @@ +getDbo(); + $query = $db->getQuery(true); + + // Select the required fields from the table. + $query->select($this->getState('list.select', 'a.*')); + $query->from($db->quoteName('#__privacy_consents', 'a')); + + // Join over the users for the username. + $query->select($db->quoteName('u.username', 'username')); + $query->join('LEFT', $db->quoteName('#__users', 'u') . ' ON u.id = a.user_id'); + + // Filter by search in email + $search = $this->getState('filter.search'); + + if (!empty($search)) + { + if (stripos($search, 'id:') === 0) + { + $query->where($db->quoteName('a.id') . ' = ' . (int) substr($search, 3)); + } + elseif (stripos($search, 'uid:') === 0) + { + $query->where($db->quoteName('a.user_id') . ' = ' . (int) substr($search, 4)); + } + else + { + $search = $db->quote('%' . $db->escape($search, true) . '%'); + $query->where('(' . $db->quoteName('u.username') . ' LIKE ' . $search . ')'); + } + } + + $state = $this->getState('filter.state'); + + if ($state != '') + { + $query->where($db->quoteName('a.state') . ' = ' . (int) $state); + } + + // Handle the list ordering. + $ordering = $this->getState('list.ordering'); + $direction = $this->getState('list.direction'); + + if (!empty($ordering)) + { + $query->order($db->escape($ordering) . ' ' . $db->escape($direction)); + } + + return $query; + } + + /** + * Method to get a store id based on model configuration state. + * + * This is necessary because the model is used by the component and + * different modules that might need different sets of data or different + * ordering requirements. + * + * @param string $id A prefix for the store id. + * + * @return string + * + * @since 3.9.0 + */ + protected function getStoreId($id = '') + { + // Compile the store id. + $id .= ':' . $this->getState('filter.search'); + + return parent::getStoreId($id); + } + + /** + * Method to auto-populate the model state. + * + * Note. Calling getState in this method will result in recursion. + * + * @param string $ordering An optional ordering field. + * @param string $direction An optional direction (asc|desc). + * + * @return void + * + * @since 3.9.0 + */ + protected function populateState($ordering = 'a.id', $direction = 'desc') + { + // Load the filter state. + $this->setState( + 'filter.search', + $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search') + ); + + $this->setState( + 'filter.subject', + $this->getUserStateFromRequest($this->context . '.filter.subject', 'filter_subject') + ); + + $this->setState( + 'filter.state', + $this->getUserStateFromRequest($this->context . '.filter.state', 'filter_state') + ); + + // Load the parameters. + $this->setState('params', JComponentHelper::getParams('com_privacy')); + + // List state information. + parent::populateState($ordering, $direction); + } + + /** + * Method to invalidate specific consents. + * + * @param array $pks The ids of the consents to invalidate. + * + * @return boolean True on success. + */ + public function invalidate($pks) + { + // Sanitize the ids. + $pks = (array) $pks; + $pks = ArrayHelper::toInteger($pks); + + try + { + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->update($db->quoteName('#__privacy_consents')) + ->set($db->quoteName('state') . ' = -1') + ->where($db->quoteName('id') . ' IN (' . implode(',', $pks) . ')') + ->where($db->quoteName('state') . ' = 1'); + $db->setQuery($query); + $db->execute(); + } + catch (JDatabaseExceptionExecuting $e) + { + $this->setError($e->getMessage()); + + return false; + } + + return true; + } + + /** + * Method to invalidate a group of specific consents. + * + * @param array $subject The subject of the consents to invalidate. + * + * @return boolean True on success. + */ + public function invalidateAll($subject) + { + try + { + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->update($db->quoteName('#__privacy_consents')) + ->set($db->quoteName('state') . ' = -1') + ->where($db->quoteName('subject') . ' = ' . $db->quote($subject)) + ->where($db->quoteName('state') . ' = 1'); + $db->setQuery($query); + $db->execute(); + } + catch (JDatabaseExceptionExecuting $e) + { + $this->setError($e->getMessage()); + + return false; + } + + return true; + } +} diff --git a/Sites/pages/administrator/components/com_privacy/models/dashboard.php b/Sites/pages/administrator/components/com_privacy/models/dashboard.php new file mode 100644 index 00000000..ef2925b2 --- /dev/null +++ b/Sites/pages/administrator/components/com_privacy/models/dashboard.php @@ -0,0 +1,158 @@ + false, + 'articlePublished' => false, + 'editLink' => '', + ); + + /* + * Prior to 3.9.0 it was common for a plugin such as the User - Profile plugin to define a privacy policy or + * terms of service article, therefore we will also import the user plugin group to process this event. + */ + JPluginHelper::importPlugin('privacy'); + JPluginHelper::importPlugin('user'); + + JFactory::getApplication()->triggerEvent('onPrivacyCheckPrivacyPolicyPublished', array(&$policy)); + + return $policy; + } + + /** + * Get a count of the active information requests grouped by type and status + * + * @return array Array containing site privacy requests + * + * @since 3.9.0 + */ + public function getRequestCounts() + { + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select( + array( + 'COUNT(*) AS count', + $db->quoteName('status'), + $db->quoteName('request_type'), + ) + ) + ->from($db->quoteName('#__privacy_requests')) + ->group($db->quoteName('status')) + ->group($db->quoteName('request_type')); + + $db->setQuery($query); + + return $db->loadObjectList(); + } + + /** + * Check whether there is a menu item for the request form + * + * @return array Array containing a status of whether a menu is published for the request form and its current link + * + * @since 3.9.0 + */ + public function getRequestFormPublished() + { + $status = array( + 'exists' => false, + 'published' => false, + 'link' => '', + ); + + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select($db->quoteName('id') . ', ' . $db->quoteName('published') . ', ' . $db->quoteName('language')) + ->from($db->quoteName('#__menu')) + ->where($db->quoteName('client_id') . ' = 0') + ->where($db->quoteName('link') . ' = ' . $db->quote('index.php?option=com_privacy&view=request')); + $db->setQuery($query); + + $menuItem = $db->loadObject(); + + // Check if the menu item exists in database + if ($menuItem) + { + $status['exists'] = true; + + // Check if the menu item is published + if ($menuItem->published == 1) + { + $status['published'] = true; + } + + // Add language to the url if the site is multilingual + if (JLanguageMultilang::isEnabled() && $menuItem->language && $menuItem->language !== '*') + { + $lang = '&lang=' . $menuItem->language; + } + else + { + $lang = ''; + } + } + + $linkMode = JFactory::getApplication()->get('force_ssl', 0) == 2 ? Route::TLS_FORCE : Route::TLS_IGNORE; + + if (!$menuItem) + { + if (JLanguageMultilang::isEnabled()) + { + // Find the Itemid of the home menu item tagged to the site default language + $params = JComponentHelper::getParams('com_languages'); + $defaultSiteLanguage = $params->get('site'); + + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select($db->quoteName('id')) + ->from($db->quoteName('#__menu')) + ->where($db->quoteName('client_id') . ' = 0') + ->where($db->quoteName('home') . ' = 1') + ->where($db->quoteName('language') . ' = ' . $db->quote($defaultSiteLanguage)); + $db->setQuery($query); + + $homeId = (int) $db->loadResult(); + $itemId = $homeId ? '&Itemid=' . $homeId : ''; + } + else + { + $itemId = ''; + } + + $status['link'] = JRoute::link('site', 'index.php?option=com_privacy&view=request' . $itemId, true, $linkMode); + } + else + { + $status['link'] = JRoute::link('site', 'index.php?Itemid=' . $menuItem->id . $lang, true, $linkMode); + } + + return $status; + } +} diff --git a/Sites/pages/administrator/components/com_privacy/models/export.php b/Sites/pages/administrator/components/com_privacy/models/export.php new file mode 100644 index 00000000..34cb29c5 --- /dev/null +++ b/Sites/pages/administrator/components/com_privacy/models/export.php @@ -0,0 +1,340 @@ +getState($this->getName() . '.request_id'); + + if (!$id) + { + $this->setError(JText::_('COM_PRIVACY_ERROR_REQUEST_ID_REQUIRED_FOR_EXPORT')); + + return false; + } + + /** @var PrivacyTableRequest $table */ + $table = $this->getTable(); + + if (!$table->load($id)) + { + $this->setError($table->getError()); + + return false; + } + + if ($table->request_type !== 'export') + { + $this->setError(JText::_('COM_PRIVACY_ERROR_REQUEST_TYPE_NOT_EXPORT')); + + return false; + } + + if ($table->status != 1) + { + $this->setError(JText::_('COM_PRIVACY_ERROR_CANNOT_EXPORT_UNCONFIRMED_REQUEST')); + + return false; + } + + // If there is a user account associated with the email address, load it here for use in the plugins + $db = $this->getDbo(); + + $userId = (int) $db->setQuery( + $db->getQuery(true) + ->select('id') + ->from($db->quoteName('#__users')) + ->where('LOWER(' . $db->quoteName('email') . ') = LOWER(' . $db->quote($table->email) . ')'), + 0, + 1 + )->loadResult(); + + $user = $userId ? JUser::getInstance($userId) : null; + + // Log the export + $this->logExport($table); + + JPluginHelper::importPlugin('privacy'); + + $pluginResults = JFactory::getApplication()->triggerEvent('onPrivacyExportRequest', array($table, $user)); + + $domains = array(); + + foreach ($pluginResults as $pluginDomains) + { + $domains = array_merge($domains, $pluginDomains); + } + + return $domains; + } + + /** + * Email the data export to the user. + * + * @param integer $id The request ID to process + * + * @return boolean + * + * @since 3.9.0 + */ + public function emailDataExport($id = null) + { + $id = !empty($id) ? $id : (int) $this->getState($this->getName() . '.request_id'); + + if (!$id) + { + $this->setError(JText::_('COM_PRIVACY_ERROR_REQUEST_ID_REQUIRED_FOR_EXPORT')); + + return false; + } + + $exportData = $this->collectDataForExportRequest($id); + + if ($exportData === false) + { + // Error is already set, we just need to bail + return false; + } + + /** @var PrivacyTableRequest $table */ + $table = $this->getTable(); + + if (!$table->load($id)) + { + $this->setError($table->getError()); + + return false; + } + + if ($table->request_type !== 'export') + { + $this->setError(JText::_('COM_PRIVACY_ERROR_REQUEST_TYPE_NOT_EXPORT')); + + return false; + } + + if ($table->status != 1) + { + $this->setError(JText::_('COM_PRIVACY_ERROR_CANNOT_EXPORT_UNCONFIRMED_REQUEST')); + + return false; + } + + // Log the email + $this->logExportEmailed($table); + + /* + * If there is an associated user account, we will attempt to send this email in the user's preferred language. + * Because of this, it is expected that Language::_() is directly called and that the Text class is NOT used + * for translating all messages. + * + * Error messages will still be displayed to the administrator, so those messages should continue to use the Text class. + */ + + $lang = JFactory::getLanguage(); + + $db = $this->getDbo(); + + $userId = (int) $db->setQuery( + $db->getQuery(true) + ->select('id') + ->from($db->quoteName('#__users')) + ->where('LOWER(' . $db->quoteName('email') . ') = LOWER(' . $db->quote($table->email) . ')'), + 0, + 1 + )->loadResult(); + + if ($userId) + { + $receiver = JUser::getInstance($userId); + + /* + * We don't know if the user has admin access, so we will check if they have an admin language in their parameters, + * falling back to the site language, falling back to the currently active language + */ + + $langCode = $receiver->getParam('admin_language', ''); + + if (!$langCode) + { + $langCode = $receiver->getParam('language', $lang->getTag()); + } + + $lang = JLanguage::getInstance($langCode, $lang->getDebug()); + } + + // Ensure the right language files have been loaded + $lang->load('com_privacy', JPATH_ADMINISTRATOR, null, false, true) + || $lang->load('com_privacy', JPATH_ADMINISTRATOR . '/components/com_privacy', null, false, true); + + // The mailer can be set to either throw Exceptions or return boolean false, account for both + try + { + $app = JFactory::getApplication(); + + $substitutions = array( + '[SITENAME]' => $app->get('sitename'), + '[URL]' => JUri::root(), + '\\n' => "\n", + ); + + $emailSubject = $lang->_('COM_PRIVACY_EMAIL_DATA_EXPORT_COMPLETED_SUBJECT'); + $emailBody = $lang->_('COM_PRIVACY_EMAIL_DATA_EXPORT_COMPLETED_BODY'); + + foreach ($substitutions as $k => $v) + { + $emailSubject = str_replace($k, $v, $emailSubject); + $emailBody = str_replace($k, $v, $emailBody); + } + + $mailer = JFactory::getMailer(); + $mailer->setSubject($emailSubject); + $mailer->setBody($emailBody); + $mailer->addRecipient($table->email); + $mailer->addStringAttachment( + PrivacyHelper::renderDataAsXml($exportData), + 'user-data_' . JUri::getInstance()->toString(array('host')) . '.xml' + ); + + $mailResult = $mailer->Send(); + + if ($mailResult instanceof JException) + { + // JError was already called so we just need to return now + return false; + } + elseif ($mailResult === false) + { + $this->setError($mailer->ErrorInfo); + + return false; + } + + return true; + } + catch (phpmailerException $exception) + { + $this->setError($exception->getMessage()); + + return false; + } + + return true; + } + + /** + * Method to get a table object, load it if necessary. + * + * @param string $name The table name. Optional. + * @param string $prefix The class prefix. Optional. + * @param array $options Configuration array for model. Optional. + * + * @return JTable A JTable object + * + * @since 3.9.0 + * @throws \Exception + */ + public function getTable($name = 'Request', $prefix = 'PrivacyTable', $options = array()) + { + return parent::getTable($name, $prefix, $options); + } + + /** + * Log the data export to the action log system. + * + * @param PrivacyTableRequest $request The request record being processed + * + * @return void + * + * @since 3.9.0 + */ + public function logExport(PrivacyTableRequest $request) + { + JModelLegacy::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_actionlogs/models', 'ActionlogsModel'); + + $user = JFactory::getUser(); + + $message = array( + 'action' => 'export', + 'id' => $request->id, + 'itemlink' => 'index.php?option=com_privacy&view=request&id=' . $request->id, + 'userid' => $user->id, + 'username' => $user->username, + 'accountlink' => 'index.php?option=com_users&task=user.edit&id=' . $user->id, + ); + + /** @var ActionlogsModelActionlog $model */ + $model = JModelLegacy::getInstance('Actionlog', 'ActionlogsModel'); + $model->addLog(array($message), 'COM_PRIVACY_ACTION_LOG_EXPORT', 'com_privacy.request', $user->id); + } + + /** + * Log the data export email to the action log system. + * + * @param PrivacyTableRequest $request The request record being processed + * + * @return void + * + * @since 3.9.0 + */ + public function logExportEmailed(PrivacyTableRequest $request) + { + JModelLegacy::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_actionlogs/models', 'ActionlogsModel'); + + $user = JFactory::getUser(); + + $message = array( + 'action' => 'export_emailed', + 'id' => $request->id, + 'itemlink' => 'index.php?option=com_privacy&view=request&id=' . $request->id, + 'userid' => $user->id, + 'username' => $user->username, + 'accountlink' => 'index.php?option=com_users&task=user.edit&id=' . $user->id, + ); + + /** @var ActionlogsModelActionlog $model */ + $model = JModelLegacy::getInstance('Actionlog', 'ActionlogsModel'); + $model->addLog(array($message), 'COM_PRIVACY_ACTION_LOG_EXPORT_EMAILED', 'com_privacy.request', $user->id); + } + + /** + * Method to auto-populate the model state. + * + * @return void + * + * @since 3.9.0 + */ + protected function populateState() + { + // Get the pk of the record from the request. + $this->setState($this->getName() . '.request_id', JFactory::getApplication()->input->getUint('id')); + + // Load the parameters. + $this->setState('params', JComponentHelper::getParams('com_privacy')); + } +} diff --git a/Sites/pages/administrator/components/com_privacy/models/fields/requeststatus.php b/Sites/pages/administrator/components/com_privacy/models/fields/requeststatus.php new file mode 100644 index 00000000..e38b616e --- /dev/null +++ b/Sites/pages/administrator/components/com_privacy/models/fields/requeststatus.php @@ -0,0 +1,41 @@ + 'COM_PRIVACY_STATUS_INVALID', + '0' => 'COM_PRIVACY_STATUS_PENDING', + '1' => 'COM_PRIVACY_STATUS_CONFIRMED', + '2' => 'COM_PRIVACY_STATUS_COMPLETED', + ); +} diff --git a/Sites/pages/administrator/components/com_privacy/models/fields/requesttype.php b/Sites/pages/administrator/components/com_privacy/models/fields/requesttype.php new file mode 100644 index 00000000..444f9e17 --- /dev/null +++ b/Sites/pages/administrator/components/com_privacy/models/fields/requesttype.php @@ -0,0 +1,39 @@ + 'COM_PRIVACY_HEADING_REQUEST_TYPE_TYPE_EXPORT', + 'remove' => 'COM_PRIVACY_HEADING_REQUEST_TYPE_TYPE_REMOVE', + ); +} diff --git a/Sites/pages/administrator/components/com_privacy/models/forms/filter_consents.xml b/Sites/pages/administrator/components/com_privacy/models/forms/filter_consents.xml new file mode 100644 index 00000000..b5adeec9 --- /dev/null +++ b/Sites/pages/administrator/components/com_privacy/models/forms/filter_consents.xml @@ -0,0 +1,75 @@ + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Sites/pages/administrator/components/com_privacy/models/forms/filter_requests.xml b/Sites/pages/administrator/components/com_privacy/models/forms/filter_requests.xml new file mode 100644 index 00000000..e60aa2e8 --- /dev/null +++ b/Sites/pages/administrator/components/com_privacy/models/forms/filter_requests.xml @@ -0,0 +1,65 @@ + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Sites/pages/administrator/components/com_privacy/models/forms/request.xml b/Sites/pages/administrator/components/com_privacy/models/forms/request.xml new file mode 100644 index 00000000..0ee1e6f9 --- /dev/null +++ b/Sites/pages/administrator/components/com_privacy/models/forms/request.xml @@ -0,0 +1,54 @@ + +
    +
    + + + + + + + + + + + + + + + + +
    +
    diff --git a/Sites/pages/administrator/components/com_privacy/models/remove.php b/Sites/pages/administrator/components/com_privacy/models/remove.php new file mode 100644 index 00000000..a5a958ae --- /dev/null +++ b/Sites/pages/administrator/components/com_privacy/models/remove.php @@ -0,0 +1,204 @@ +getState($this->getName() . '.request_id'); + + if (!$id) + { + $this->setError(JText::_('COM_PRIVACY_ERROR_REQUEST_ID_REQUIRED_FOR_REMOVE')); + + return false; + } + + /** @var PrivacyTableRequest $table */ + $table = $this->getTable(); + + if (!$table->load($id)) + { + $this->setError($table->getError()); + + return false; + } + + if ($table->request_type !== 'remove') + { + $this->setError(JText::_('COM_PRIVACY_ERROR_REQUEST_TYPE_NOT_REMOVE')); + + return false; + } + + if ($table->status != 1) + { + $this->setError(JText::_('COM_PRIVACY_ERROR_CANNOT_REMOVE_UNCONFIRMED_REQUEST')); + + return false; + } + + // If there is a user account associated with the email address, load it here for use in the plugins + $db = $this->getDbo(); + + $userId = (int) $db->setQuery( + $db->getQuery(true) + ->select('id') + ->from($db->quoteName('#__users')) + ->where('LOWER(' . $db->quoteName('email') . ') = LOWER(' . $db->quote($table->email) . ')'), + 0, + 1 + )->loadResult(); + + $user = $userId ? JUser::getInstance($userId) : null; + + $canRemove = true; + + JPluginHelper::importPlugin('privacy'); + + /** @var PrivacyRemovalStatus[] $pluginResults */ + $pluginResults = JFactory::getApplication()->triggerEvent('onPrivacyCanRemoveData', array($table, $user)); + + foreach ($pluginResults as $status) + { + if (!$status->canRemove) + { + $this->setError($status->reason ?: JText::_('COM_PRIVACY_ERROR_CANNOT_REMOVE_DATA')); + + $canRemove = false; + } + } + + if (!$canRemove) + { + $this->logRemoveBlocked($table, $this->getErrors()); + + return false; + } + + // Log the removal + $this->logRemove($table); + + JFactory::getApplication()->triggerEvent('onPrivacyRemoveData', array($table, $user)); + + return true; + } + + /** + * Method to get a table object, load it if necessary. + * + * @param string $name The table name. Optional. + * @param string $prefix The class prefix. Optional. + * @param array $options Configuration array for model. Optional. + * + * @return JTable A JTable object + * + * @since 3.9.0 + * @throws \Exception + */ + public function getTable($name = 'Request', $prefix = 'PrivacyTable', $options = array()) + { + return parent::getTable($name, $prefix, $options); + } + + /** + * Log the data removal to the action log system. + * + * @param PrivacyTableRequest $request The request record being processed + * + * @return void + * + * @since 3.9.0 + */ + public function logRemove(PrivacyTableRequest $request) + { + JModelLegacy::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_actionlogs/models', 'ActionlogsModel'); + + $user = JFactory::getUser(); + + $message = array( + 'action' => 'remove', + 'id' => $request->id, + 'itemlink' => 'index.php?option=com_privacy&view=request&id=' . $request->id, + 'userid' => $user->id, + 'username' => $user->username, + 'accountlink' => 'index.php?option=com_users&task=user.edit&id=' . $user->id, + ); + + /** @var ActionlogsModelActionlog $model */ + $model = JModelLegacy::getInstance('Actionlog', 'ActionlogsModel'); + $model->addLog(array($message), 'COM_PRIVACY_ACTION_LOG_REMOVE', 'com_privacy.request', $user->id); + } + + /** + * Log the data removal being blocked to the action log system. + * + * @param PrivacyTableRequest $request The request record being processed + * @param string[] $reasons The reasons given why the record could not be removed. + * + * @return void + * + * @since 3.9.0 + */ + public function logRemoveBlocked(PrivacyTableRequest $request, array $reasons) + { + JModelLegacy::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_actionlogs/models', 'ActionlogsModel'); + + $user = JFactory::getUser(); + + $message = array( + 'action' => 'remove-blocked', + 'id' => $request->id, + 'itemlink' => 'index.php?option=com_privacy&view=request&id=' . $request->id, + 'userid' => $user->id, + 'username' => $user->username, + 'accountlink' => 'index.php?option=com_users&task=user.edit&id=' . $user->id, + 'reasons' => implode('; ', $reasons), + ); + + /** @var ActionlogsModelActionlog $model */ + $model = JModelLegacy::getInstance('Actionlog', 'ActionlogsModel'); + $model->addLog(array($message), 'COM_PRIVACY_ACTION_LOG_REMOVE_BLOCKED', 'com_privacy.request', $user->id); + } + + /** + * Method to auto-populate the model state. + * + * @return void + * + * @since 3.9.0 + */ + protected function populateState() + { + // Get the pk of the record from the request. + $this->setState($this->getName() . '.request_id', JFactory::getApplication()->input->getUint('id')); + + // Load the parameters. + $this->setState('params', JComponentHelper::getParams('com_privacy')); + } +} diff --git a/Sites/pages/administrator/components/com_privacy/models/request.php b/Sites/pages/administrator/components/com_privacy/models/request.php new file mode 100644 index 00000000..6d762c1c --- /dev/null +++ b/Sites/pages/administrator/components/com_privacy/models/request.php @@ -0,0 +1,459 @@ +loadForm('com_privacy.request', 'request', array('control' => 'jform', 'load_data' => $loadData)); + + if (empty($form)) + { + return false; + } + + return $form; + } + + /** + * Method to get a table object, load it if necessary. + * + * @param string $name The table name. Optional. + * @param string $prefix The class prefix. Optional. + * @param array $options Configuration array for model. Optional. + * + * @return JTable A JTable object + * + * @since 3.9.0 + * @throws \Exception + */ + public function getTable($name = 'Request', $prefix = 'PrivacyTable', $options = array()) + { + return parent::getTable($name, $prefix, $options); + } + + /** + * Method to get the data that should be injected in the form. + * + * @return array The default data is an empty array. + * + * @since 3.9.0 + */ + protected function loadFormData() + { + // Check the session for previously entered form data. + $data = JFactory::getApplication()->getUserState('com_privacy.edit.request.data', array()); + + if (empty($data)) + { + $data = $this->getItem(); + } + + return $data; + } + + /** + * Log the completion of a request to the action log system. + * + * @param integer $id The ID of the request to process. + * + * @return boolean + * + * @since 3.9.0 + */ + public function logRequestCompleted($id) + { + /** @var PrivacyTableRequest $table */ + $table = $this->getTable(); + + if (!$table->load($id)) + { + $this->setError($table->getError()); + + return false; + } + + JModelLegacy::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_actionlogs/models', 'ActionlogsModel'); + + $user = JFactory::getUser(); + + $message = array( + 'action' => 'request-completed', + 'requesttype' => $table->request_type, + 'subjectemail' => $table->email, + 'id' => $table->id, + 'itemlink' => 'index.php?option=com_privacy&view=request&id=' . $table->id, + 'userid' => $user->id, + 'username' => $user->username, + 'accountlink' => 'index.php?option=com_users&task=user.edit&id=' . $user->id, + ); + + /** @var ActionlogsModelActionlog $model */ + $model = JModelLegacy::getInstance('Actionlog', 'ActionlogsModel'); + $model->addLog(array($message), 'COM_PRIVACY_ACTION_LOG_ADMIN_COMPLETED_REQUEST', 'com_privacy.request', $user->id); + + return true; + } + + /** + * Log the creation of a request to the action log system. + * + * @param integer $id The ID of the request to process. + * + * @return boolean + * + * @since 3.9.0 + */ + public function logRequestCreated($id) + { + /** @var PrivacyTableRequest $table */ + $table = $this->getTable(); + + if (!$table->load($id)) + { + $this->setError($table->getError()); + + return false; + } + + JModelLegacy::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_actionlogs/models', 'ActionlogsModel'); + + $user = JFactory::getUser(); + + $message = array( + 'action' => 'request-created', + 'requesttype' => $table->request_type, + 'subjectemail' => $table->email, + 'id' => $table->id, + 'itemlink' => 'index.php?option=com_privacy&view=request&id=' . $table->id, + 'userid' => $user->id, + 'username' => $user->username, + 'accountlink' => 'index.php?option=com_users&task=user.edit&id=' . $user->id, + ); + + /** @var ActionlogsModelActionlog $model */ + $model = JModelLegacy::getInstance('Actionlog', 'ActionlogsModel'); + $model->addLog(array($message), 'COM_PRIVACY_ACTION_LOG_ADMIN_CREATED_REQUEST', 'com_privacy.request', $user->id); + + return true; + } + + /** + * Log the invalidation of a request to the action log system. + * + * @param integer $id The ID of the request to process. + * + * @return boolean + * + * @since 3.9.0 + */ + public function logRequestInvalidated($id) + { + /** @var PrivacyTableRequest $table */ + $table = $this->getTable(); + + if (!$table->load($id)) + { + $this->setError($table->getError()); + + return false; + } + + JModelLegacy::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_actionlogs/models', 'ActionlogsModel'); + + $user = JFactory::getUser(); + + $message = array( + 'action' => 'request-invalidated', + 'requesttype' => $table->request_type, + 'subjectemail' => $table->email, + 'id' => $table->id, + 'itemlink' => 'index.php?option=com_privacy&view=request&id=' . $table->id, + 'userid' => $user->id, + 'username' => $user->username, + 'accountlink' => 'index.php?option=com_users&task=user.edit&id=' . $user->id, + ); + + /** @var ActionlogsModelActionlog $model */ + $model = JModelLegacy::getInstance('Actionlog', 'ActionlogsModel'); + $model->addLog(array($message), 'COM_PRIVACY_ACTION_LOG_ADMIN_INVALIDATED_REQUEST', 'com_privacy.request', $user->id); + + return true; + } + + /** + * Notifies the user that an information request has been created by a site administrator. + * + * Because confirmation tokens are stored in the database as a hashed value, this method will generate a new confirmation token + * for the request. + * + * @param integer $id The ID of the request to process. + * + * @return boolean + * + * @since 3.9.0 + */ + public function notifyUserAdminCreatedRequest($id) + { + /** @var PrivacyTableRequest $table */ + $table = $this->getTable(); + + if (!$table->load($id)) + { + $this->setError($table->getError()); + + return false; + } + + /* + * If there is an associated user account, we will attempt to send this email in the user's preferred language. + * Because of this, it is expected that Language::_() is directly called and that the Text class is NOT used + * for translating all messages. + * + * Error messages will still be displayed to the administrator, so those messages should continue to use the Text class. + */ + + $lang = JFactory::getLanguage(); + + $db = $this->getDbo(); + + $userId = (int) $db->setQuery( + $db->getQuery(true) + ->select('id') + ->from($db->quoteName('#__users')) + ->where('LOWER(' . $db->quoteName('email') . ') = LOWER(' . $db->quote($table->email) . ')'), + 0, + 1 + )->loadResult(); + + if ($userId) + { + $receiver = JUser::getInstance($userId); + + /* + * We don't know if the user has admin access, so we will check if they have an admin language in their parameters, + * falling back to the site language, falling back to the currently active language + */ + + $langCode = $receiver->getParam('admin_language', ''); + + if (!$langCode) + { + $langCode = $receiver->getParam('language', $lang->getTag()); + } + + $lang = JLanguage::getInstance($langCode, $lang->getDebug()); + } + + // Ensure the right language files have been loaded + $lang->load('com_privacy', JPATH_ADMINISTRATOR, null, false, true) + || $lang->load('com_privacy', JPATH_ADMINISTRATOR . '/components/com_privacy', null, false, true); + + // Regenerate the confirmation token + $token = JApplicationHelper::getHash(JUserHelper::genRandomPassword()); + $hashedToken = JUserHelper::hashPassword($token); + + $table->confirm_token = $hashedToken; + $table->confirm_token_created_at = JFactory::getDate()->toSql(); + + try + { + $table->store(); + } + catch (JDatabaseException $exception) + { + $this->setError($exception->getMessage()); + + return false; + } + + // The mailer can be set to either throw Exceptions or return boolean false, account for both + try + { + $app = JFactory::getApplication(); + + $linkMode = $app->get('force_ssl', 0) == 2 ? Route::TLS_FORCE : Route::TLS_IGNORE; + + $substitutions = array( + '[SITENAME]' => $app->get('sitename'), + '[URL]' => JUri::root(), + '[TOKENURL]' => JRoute::link('site', 'index.php?option=com_privacy&view=confirm&confirm_token=' . $token, false, $linkMode, true), + '[FORMURL]' => JRoute::link('site', 'index.php?option=com_privacy&view=confirm', false, $linkMode, true), + '[TOKEN]' => $token, + '\\n' => "\n", + ); + + switch ($table->request_type) + { + case 'export': + $emailSubject = $lang->_('COM_PRIVACY_EMAIL_ADMIN_REQUEST_SUBJECT_EXPORT_REQUEST'); + $emailBody = $lang->_('COM_PRIVACY_EMAIL_ADMIN_REQUEST_BODY_EXPORT_REQUEST'); + + break; + + case 'remove': + $emailSubject = $lang->_('COM_PRIVACY_EMAIL_ADMIN_REQUEST_SUBJECT_REMOVE_REQUEST'); + $emailBody = $lang->_('COM_PRIVACY_EMAIL_ADMIN_REQUEST_BODY_REMOVE_REQUEST'); + + break; + + default: + $this->setError(JText::_('COM_PRIVACY_ERROR_UNKNOWN_REQUEST_TYPE')); + + return false; + } + + foreach ($substitutions as $k => $v) + { + $emailSubject = str_replace($k, $v, $emailSubject); + $emailBody = str_replace($k, $v, $emailBody); + } + + $mailer = JFactory::getMailer(); + $mailer->setSubject($emailSubject); + $mailer->setBody($emailBody); + $mailer->addRecipient($table->email); + + $mailResult = $mailer->Send(); + + if ($mailResult instanceof JException) + { + // JError was already called so we just need to return now + return false; + } + elseif ($mailResult === false) + { + $this->setError($mailer->ErrorInfo); + + return false; + } + + return true; + } + catch (phpmailerException $exception) + { + $this->setError($exception->getMessage()); + + return false; + } + } + + /** + * Method to save the form data. + * + * @param array $data The form data. + * + * @return boolean True on success, False on error. + * + * @since 3.9.0 + */ + public function save($data) + { + $table = $this->getTable(); + $key = $table->getKeyName(); + $pk = !empty($data[$key]) ? $data[$key] : (int) $this->getState($this->getName() . '.id'); + + if (!$pk && !JFactory::getConfig()->get('mailonline', 1)) + { + $this->setError(JText::_('COM_PRIVACY_ERROR_CANNOT_CREATE_REQUEST_WHEN_SENDMAIL_DISABLED')); + + return false; + } + + return parent::save($data); + } + + /** + * Method to validate the form data. + * + * @param JForm $form The form to validate against. + * @param array $data The data to validate. + * @param string $group The name of the field group to validate. + * + * @return array|boolean Array of filtered data if valid, false otherwise. + * + * @see JFormRule + * @see JFilterInput + * @since 3.9.0 + */ + public function validate($form, $data, $group = null) + { + $validatedData = parent::validate($form, $data, $group); + + // If parent validation failed there's no point in doing our extended validation + if ($validatedData === false) + { + return false; + } + + // The user cannot create a request for their own account + if (strtolower(JFactory::getUser()->email) === strtolower($validatedData['email'])) + { + $this->setError(JText::_('COM_PRIVACY_ERROR_CANNOT_CREATE_REQUEST_FOR_SELF')); + + return false; + } + + // Check for an active request for this email address + $db = $this->getDbo(); + + $query = $db->getQuery(true) + ->select('COUNT(id)') + ->from('#__privacy_requests') + ->where('email = ' . $db->quote($validatedData['email'])) + ->where('request_type = ' . $db->quote($validatedData['request_type'])) + ->where('status IN (0, 1)'); + + $activeRequestCount = (int) $db->setQuery($query)->loadResult(); + + if ($activeRequestCount > 0) + { + $this->setError(JText::_('COM_PRIVACY_ERROR_ACTIVE_REQUEST_FOR_EMAIL')); + + return false; + } + + return $validatedData; + } +} diff --git a/Sites/pages/administrator/components/com_privacy/models/requests.php b/Sites/pages/administrator/components/com_privacy/models/requests.php new file mode 100644 index 00000000..771fab5b --- /dev/null +++ b/Sites/pages/administrator/components/com_privacy/models/requests.php @@ -0,0 +1,190 @@ +getDbo(); + $query = $db->getQuery(true); + + // Select the required fields from the table. + $query->select($this->getState('list.select', 'a.*')); + $query->from($db->quoteName('#__privacy_requests', 'a')); + + // Filter by status + $status = $this->getState('filter.status'); + + if (is_numeric($status)) + { + $query->where('a.status = ' . (int) $status); + } + + // Filter by request type + $requestType = $this->getState('filter.request_type', ''); + + if ($requestType) + { + $query->where('a.request_type = ' . $db->quote($db->escape($requestType, true))); + } + + // Filter by search in email + $search = $this->getState('filter.search'); + + if (!empty($search)) + { + if (stripos($search, 'id:') === 0) + { + $query->where($db->quoteName('a.id') . ' = ' . (int) substr($search, 3)); + } + else + { + $search = $db->quote('%' . $db->escape($search, true) . '%'); + $query->where('(' . $db->quoteName('a.email') . ' LIKE ' . $search . ')'); + } + } + + // Handle the list ordering. + $ordering = $this->getState('list.ordering'); + $direction = $this->getState('list.direction'); + + if (!empty($ordering)) + { + $query->order($db->escape($ordering) . ' ' . $db->escape($direction)); + } + + return $query; + } + + /** + * Method to get a store id based on model configuration state. + * + * This is necessary because the model is used by the component and + * different modules that might need different sets of data or different + * ordering requirements. + * + * @param string $id A prefix for the store id. + * + * @return string + * + * @since 3.9.0 + */ + protected function getStoreId($id = '') + { + // Compile the store id. + $id .= ':' . $this->getState('filter.search'); + $id .= ':' . $this->getState('filter.status'); + $id .= ':' . $this->getState('filter.request_type'); + + return parent::getStoreId($id); + } + + /** + * Method to auto-populate the model state. + * + * Note. Calling getState in this method will result in recursion. + * + * @param string $ordering An optional ordering field. + * @param string $direction An optional direction (asc|desc). + * + * @return void + * + * @since 3.9.0 + */ + protected function populateState($ordering = 'a.id', $direction = 'desc') + { + // Load the filter state. + $this->setState( + 'filter.search', + $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search') + ); + + $this->setState( + 'filter.status', + $this->getUserStateFromRequest($this->context . '.filter.status', 'filter_status', '', 'int') + ); + + $this->setState( + 'filter.request_type', + $this->getUserStateFromRequest($this->context . '.filter.request_type', 'filter_request_type', '', 'string') + ); + + // Load the parameters. + $this->setState('params', JComponentHelper::getParams('com_privacy')); + + // List state information. + parent::populateState($ordering, $direction); + } + + /** + * Method to return number privacy requests older than X days. + * + * @return integer + * + * @since 3.9.0 + */ + public function getNumberUrgentRequests() + { + // Load the parameters. + $params = ComponentHelper::getComponent('com_privacy')->getParams(); + $notify = (int) $params->get('notify', 14); + $now = JFactory::getDate()->toSql(); + $period = '-' . $notify; + + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select('COUNT(*)'); + $query->from($db->quoteName('#__privacy_requests')); + $query->where($db->quoteName('status') . ' = 1 '); + $query->where($query->dateAdd($db->quote($now), $period, 'DAY') . ' > ' . $db->quoteName('requested_at')); + $db->setQuery($query); + + return (int) $db->loadResult(); + } +} diff --git a/Sites/pages/administrator/components/com_privacy/privacy.php b/Sites/pages/administrator/components/com_privacy/privacy.php new file mode 100644 index 00000000..01df3efc --- /dev/null +++ b/Sites/pages/administrator/components/com_privacy/privacy.php @@ -0,0 +1,20 @@ +authorise('core.admin')) +{ + throw new JAccessExceptionNotallowed(JText::_('JERROR_ALERTNOAUTHOR'), 403); +} + +$controller = JControllerLegacy::getInstance('Privacy'); +$controller->execute(JFactory::getApplication()->input->get('task')); +$controller->redirect(); diff --git a/Sites/pages/administrator/components/com_privacy/privacy.xml b/Sites/pages/administrator/components/com_privacy/privacy.xml new file mode 100644 index 00000000..323caf07 --- /dev/null +++ b/Sites/pages/administrator/components/com_privacy/privacy.xml @@ -0,0 +1,40 @@ + + + com_privacy + Joomla! Project + May 2018 + (C) 2005 - 2020 Open Source Matters. All rights reserved. + GNU General Public License version 2 or later; see LICENSE.txt + admin@joomla.org + www.joomla.org + 3.9.0 + COM_PRIVACY_XML_DESCRIPTION + + controller.php + privacy.php + router.php + controllers + models + views + + + language/en-GB.com_privacy.ini + + + + config.xml + controller.php + privacy.php + controllers + helpers + models + tables + views + + + language/en-GB.com_privacy.ini + language/en-GB.com_privacy.sys.ini + + + + diff --git a/Sites/pages/administrator/components/com_privacy/tables/consent.php b/Sites/pages/administrator/components/com_privacy/tables/consent.php new file mode 100644 index 00000000..86f80cd2 --- /dev/null +++ b/Sites/pages/administrator/components/com_privacy/tables/consent.php @@ -0,0 +1,65 @@ +id) + { + if (!$this->remind) + { + $this->remind = '0'; + } + + if (!$this->created) + { + $this->created = $date->toSql(); + } + } + + return parent::store($updateNulls); + } +} diff --git a/Sites/pages/administrator/components/com_privacy/tables/request.php b/Sites/pages/administrator/components/com_privacy/tables/request.php new file mode 100644 index 00000000..c9503626 --- /dev/null +++ b/Sites/pages/administrator/components/com_privacy/tables/request.php @@ -0,0 +1,68 @@ +id) + { + if (!$this->status) + { + $this->status = '0'; + } + + if (!$this->requested_at) + { + $this->requested_at = $date->toSql(); + } + } + + return parent::store($updateNulls); + } +} diff --git a/Sites/pages/administrator/components/com_privacy/views/capabilities/tmpl/default.php b/Sites/pages/administrator/components/com_privacy/views/capabilities/tmpl/default.php new file mode 100644 index 00000000..870a7d6a --- /dev/null +++ b/Sites/pages/administrator/components/com_privacy/views/capabilities/tmpl/default.php @@ -0,0 +1,54 @@ + +sidebar)) : ?> +
    + sidebar; ?> +
    +
    + +
    + +
    +

    + +
    + capabilities)) : ?> +
    + +
    + + + 'slide-0')); ?> + + capabilities as $extension => $capabilities) : ?> + + +
    + +
    + +
      + +
    • + +
    + + + + + + + +
    diff --git a/Sites/pages/administrator/components/com_privacy/views/capabilities/view.html.php b/Sites/pages/administrator/components/com_privacy/views/capabilities/view.html.php new file mode 100644 index 00000000..446531b3 --- /dev/null +++ b/Sites/pages/administrator/components/com_privacy/views/capabilities/view.html.php @@ -0,0 +1,88 @@ +capabilities = $this->get('Capabilities'); + $this->state = $this->get('State'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + $this->addToolbar(); + + $this->sidebar = JHtmlSidebar::render(); + + return parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 3.9.0 + */ + protected function addToolbar() + { + JToolbarHelper::title(JText::_('COM_PRIVACY_VIEW_CAPABILITIES'), 'lock'); + + JToolbarHelper::preferences('com_privacy'); + + JToolbarHelper::help('JHELP_COMPONENTS_PRIVACY_CAPABILITIES'); + } +} diff --git a/Sites/pages/administrator/components/com_privacy/views/consents/tmpl/default.php b/Sites/pages/administrator/components/com_privacy/views/consents/tmpl/default.php new file mode 100644 index 00000000..e955a6c8 --- /dev/null +++ b/Sites/pages/administrator/components/com_privacy/views/consents/tmpl/default.php @@ -0,0 +1,118 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$now = JFactory::getDate(); +$stateIcons = array(-1 => 'trash', 0 => 'archive', 1 => 'publish'); +$stateMsgs = array(-1 => JText::_('COM_PRIVACY_CONSENTS_STATE_INVALIDATED'), 0 => JText::_('COM_PRIVACY_CONSENTS_STATE_OBSOLETE'), 1 => JText::_('COM_PRIVACY_CONSENTS_STATE_VALID')); + +?> +
    + sidebar)) : ?> +
    + sidebar; ?> +
    +
    + +
    + + $this)); ?> +
    + items)) : ?> +
    + +
    + + + + + + + + + + + + + + + + + + + + + items as $i => $item) : ?> + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + +
    + pagination->getListFooter(); ?> +
    + id); ?> + + + + username; ?> + + user_id; ?> + + subject); ?> + + body; ?> + + + created), null, $now); ?> + + + id; ?> +
    + + + + + +
    + diff --git a/Sites/pages/administrator/components/com_privacy/views/consents/tmpl/default.xml b/Sites/pages/administrator/components/com_privacy/views/consents/tmpl/default.xml new file mode 100644 index 00000000..b36c1cde --- /dev/null +++ b/Sites/pages/administrator/components/com_privacy/views/consents/tmpl/default.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/Sites/pages/administrator/components/com_privacy/views/consents/view.html.php b/Sites/pages/administrator/components/com_privacy/views/consents/view.html.php new file mode 100644 index 00000000..bf4134a5 --- /dev/null +++ b/Sites/pages/administrator/components/com_privacy/views/consents/view.html.php @@ -0,0 +1,142 @@ +items = $this->get('Items'); + $this->pagination = $this->get('Pagination'); + $this->state = $this->get('State'); + $this->filterForm = $this->get('FilterForm'); + $this->activeFilters = $this->get('ActiveFilters'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + $this->addToolbar(); + + $this->sidebar = JHtmlSidebar::render(); + + return parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 3.9.0 + */ + protected function addToolbar() + { + JToolbarHelper::title(JText::_('COM_PRIVACY_VIEW_CONSENTS'), 'lock'); + + $bar = JToolbar::getInstance('toolbar'); + + // Add a button to invalidate a consent + $bar->appendButton( + 'Confirm', + 'COM_PRIVACY_CONSENTS_TOOLBAR_INVALIDATE_CONFIRM_MSG', + 'trash', + 'COM_PRIVACY_CONSENTS_TOOLBAR_INVALIDATE', + 'consents.invalidate', + true + ); + + // If the filter is restricted to a specific subject, show the "Invalidate all" button + if ($this->state->get('filter.subject') != '') + { + $bar->appendButton( + 'Confirm', + 'COM_PRIVACY_CONSENTS_TOOLBAR_INVALIDATE_ALL_CONFIRM_MSG', + 'cancel', + 'COM_PRIVACY_CONSENTS_TOOLBAR_INVALIDATE_ALL', + 'consents.invalidateAll', + false + ); + } + + JToolbarHelper::preferences('com_privacy'); + + JToolbarHelper::help('JHELP_COMPONENTS_PRIVACY_CONSENTS'); + } +} diff --git a/Sites/pages/administrator/components/com_privacy/views/dashboard/tmpl/default.php b/Sites/pages/administrator/components/com_privacy/views/dashboard/tmpl/default.php new file mode 100644 index 00000000..661c970d --- /dev/null +++ b/Sites/pages/administrator/components/com_privacy/views/dashboard/tmpl/default.php @@ -0,0 +1,186 @@ + +sidebar)) : ?> +
    + sidebar; ?> +
    +
    + +
    + +
    +
    +
    + +
    + requestCounts)) : ?> +
    +
    +
    +
    +
    + requestCounts as $row) : ?> +
    + +
    status); ?>
    +
    count; ?>
    +
    + status, array(0, 1))) : ?> + count; ?> + + count; ?> + +
    +
    +
    +
    + +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    + privacyPolicyInfo['published'] && $this->privacyPolicyInfo['articlePublished']) : ?> + + + + + privacyPolicyInfo['published'] && !$this->privacyPolicyInfo['articlePublished']) : ?> + + + + + + + + + + +
    +
    +
    + privacyPolicyInfo['editLink'] !== '') : ?> + + + privacyConsentPluginId); ?> + + +
    +
    +
    +
    + requestFormPublished['published'] && $this->requestFormPublished['exists']) : ?> + + + + + requestFormPublished['published'] && $this->requestFormPublished['exists']) : ?> + + + + + + + + + + +
    +
    +
    + requestFormPublished['link'] !== '') : ?> + requestFormPublished['link']; ?> + +
    +
    +
    +
    + numberOfUrgentRequests === 0) : ?> + + + + + + + + + + +
    +
    +
    + urgentRequestDays); ?> + numberOfUrgentRequests > 0) : ?> + + +
    +
    +
    +
    + sendMailEnabled) : ?> + + + + + + + + + + +
    +
    + sendMailEnabled) : ?> +
    + + +
    + +
    +
    +
    +
    +
    +
    +
    diff --git a/Sites/pages/administrator/components/com_privacy/views/dashboard/tmpl/default.xml b/Sites/pages/administrator/components/com_privacy/views/dashboard/tmpl/default.xml new file mode 100644 index 00000000..f9a24bf3 --- /dev/null +++ b/Sites/pages/administrator/components/com_privacy/views/dashboard/tmpl/default.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/Sites/pages/administrator/components/com_privacy/views/dashboard/view.html.php b/Sites/pages/administrator/components/com_privacy/views/dashboard/view.html.php new file mode 100644 index 00000000..e00abd76 --- /dev/null +++ b/Sites/pages/administrator/components/com_privacy/views/dashboard/view.html.php @@ -0,0 +1,134 @@ +privacyConsentPluginId = PrivacyHelper::getPrivacyConsentPluginId(); + $this->privacyPolicyInfo = $this->get('PrivacyPolicyInfo'); + $this->requestCounts = $this->get('RequestCounts'); + $this->requestFormPublished = $this->get('RequestFormPublished'); + $this->sendMailEnabled = (bool) Factory::getConfig()->get('mailonline', 1); + + /** @var PrivacyModelRequests $requestsModel */ + $requestsModel = $this->getModel('requests'); + + $this->numberOfUrgentRequests = $requestsModel->getNumberUrgentRequests(); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + $this->urgentRequestDays = (int) ComponentHelper::getParams('com_privacy')->get('notify', 14); + + $this->addToolbar(); + + $this->sidebar = JHtmlSidebar::render(); + + return parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 3.9.0 + */ + protected function addToolbar() + { + JToolbarHelper::title(Text::_('COM_PRIVACY_VIEW_DASHBOARD'), 'lock'); + + JToolbarHelper::preferences('com_privacy'); + + JToolbarHelper::help('JHELP_COMPONENTS_PRIVACY_DASHBOARD'); + } +} diff --git a/Sites/pages/administrator/components/com_privacy/views/export/view.xml.php b/Sites/pages/administrator/components/com_privacy/views/export/view.xml.php new file mode 100644 index 00000000..84e757a3 --- /dev/null +++ b/Sites/pages/administrator/components/com_privacy/views/export/view.xml.php @@ -0,0 +1,55 @@ +getModel(); + + $exportData = $model->collectDataForExportRequest(); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + $requestId = $model->getState($model->getName() . '.request_id'); + + // This document should always be downloaded + $this->document->setDownload(true); + $this->document->setName('export-request-' . $requestId); + + echo PrivacyHelper::renderDataAsXml($exportData); + } +} diff --git a/Sites/pages/administrator/components/com_privacy/views/request/tmpl/default.php b/Sites/pages/administrator/components/com_privacy/views/request/tmpl/default.php new file mode 100644 index 00000000..ca28affb --- /dev/null +++ b/Sites/pages/administrator/components/com_privacy/views/request/tmpl/default.php @@ -0,0 +1,90 @@ +addScriptDeclaration($js); +?> + +
    +
    +
    +

    +
    +
    :
    +
    item->email; ?>
    + +
    :
    +
    item->status); ?>
    + +
    :
    +
    item->request_type); ?>
    + +
    :
    +
    item->requested_at, JText::_('DATE_FORMAT_LC6')); ?>
    +
    +
    +
    +

    + actionlogs)) : ?> +
    + +
    + + + + + + + + + actionlogs as $i => $item) : ?> + + + + + + + +
    + + + + + +
    + + + log_date, JText::_('DATE_FORMAT_LC6')); ?> + + name; ?> +
    + +
    +
    + + + +
    diff --git a/Sites/pages/administrator/components/com_privacy/views/request/tmpl/edit.php b/Sites/pages/administrator/components/com_privacy/views/request/tmpl/edit.php new file mode 100644 index 00000000..f6bc4843 --- /dev/null +++ b/Sites/pages/administrator/components/com_privacy/views/request/tmpl/edit.php @@ -0,0 +1,44 @@ +addScriptDeclaration($js); +?> + +
    +
    +
    +
    +
    + form->renderField('email'); ?> + form->renderField('status'); ?> + form->renderField('request_type'); ?> +
    +
    +
    + + + +
    +
    diff --git a/Sites/pages/administrator/components/com_privacy/views/request/view.html.php b/Sites/pages/administrator/components/com_privacy/views/request/view.html.php new file mode 100644 index 00000000..03ae9e15 --- /dev/null +++ b/Sites/pages/administrator/components/com_privacy/views/request/view.html.php @@ -0,0 +1,173 @@ +item = $this->get('Item'); + $this->state = $this->get('State'); + + // Variables only required for the default layout + if ($this->getLayout() === 'default') + { + /** @var ActionlogsModelActionlogs $logsModel */ + $logsModel = $this->getModel('actionlogs'); + + $this->actionlogs = $logsModel->getLogsForItem('com_privacy.request', $this->item->id); + + // Load the com_actionlogs language strings for use in the layout + $lang = JFactory::getLanguage(); + $lang->load('com_actionlogs', JPATH_ADMINISTRATOR, null, false, true) + || $lang->load('com_actionlogs', JPATH_ADMINISTRATOR . '/components/com_actionlogs', null, false, true); + } + + // Variables only required for the edit layout + if ($this->getLayout() === 'edit') + { + $this->form = $this->get('Form'); + } + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + $this->addToolbar(); + + return parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 3.9.0 + */ + protected function addToolbar() + { + JFactory::getApplication('administrator')->set('hidemainmenu', true); + + // Set the title and toolbar based on the layout + if ($this->getLayout() === 'edit') + { + JToolbarHelper::title(JText::_('COM_PRIVACY_VIEW_REQUEST_ADD_REQUEST'), 'lock'); + + JToolbarHelper::apply('request.save'); + JToolbarHelper::cancel('request.cancel'); + JToolbarHelper::help('JHELP_COMPONENTS_PRIVACY_REQUEST_EDIT'); + } + else + { + JToolbarHelper::title(JText::_('COM_PRIVACY_VIEW_REQUEST_SHOW_REQUEST'), 'lock'); + + $bar = JToolbar::getInstance('toolbar'); + + // Add transition and action buttons based on item status + switch ($this->item->status) + { + case '0': + $bar->appendButton('Standard', 'cancel-circle', 'COM_PRIVACY_TOOLBAR_INVALIDATE', 'request.invalidate', false); + + break; + + case '1': + $return = '&return=' . base64_encode('index.php?option=com_privacy&view=request&id=' . (int) $this->item->id); + + $bar->appendButton('Standard', 'apply', 'COM_PRIVACY_TOOLBAR_COMPLETE', 'request.complete', false); + $bar->appendButton('Standard', 'cancel-circle', 'COM_PRIVACY_TOOLBAR_INVALIDATE', 'request.invalidate', false); + + if ($this->item->request_type === 'export') + { + JToolbarHelper::link( + JRoute::_('index.php?option=com_privacy&task=request.export&format=xml&id=' . (int) $this->item->id . $return), + 'COM_PRIVACY_ACTION_EXPORT_DATA', + 'download' + ); + + if (JFactory::getConfig()->get('mailonline', 1)) + { + JToolbarHelper::link( + JRoute::_('index.php?option=com_privacy&task=request.emailexport&id=' . (int) $this->item->id . $return), + 'COM_PRIVACY_ACTION_EMAIL_EXPORT_DATA', + 'mail' + ); + } + } + + if ($this->item->request_type === 'remove') + { + $bar->appendButton('Standard', 'delete', 'COM_PRIVACY_ACTION_DELETE_DATA', 'request.remove', false); + } + + break; + + // Item is in a "locked" state and cannot transition + default: + break; + } + + JToolbarHelper::cancel('request.cancel', 'JTOOLBAR_CLOSE'); + JToolbarHelper::help('JHELP_COMPONENTS_PRIVACY_REQUEST'); + } + } +} diff --git a/Sites/pages/administrator/components/com_privacy/views/requests/tmpl/default.php b/Sites/pages/administrator/components/com_privacy/views/requests/tmpl/default.php new file mode 100644 index 00000000..4488eb9a --- /dev/null +++ b/Sites/pages/administrator/components/com_privacy/views/requests/tmpl/default.php @@ -0,0 +1,127 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$now = JFactory::getDate(); + +$urgentRequestDate= clone $now; +$urgentRequestDate->sub(new DateInterval('P' . $this->urgentRequestAge . 'D')); +?> +
    + sidebar)) : ?> +
    + sidebar; ?> +
    +
    + +
    + + $this)); ?> +
    + items)) : ?> +
    + +
    + + + + + + + + + + + + + + + + + + + items as $i => $item) : ?> + requested_at); + ?> + + + + + + + + + + +
    + + + + + + + + + + + +
    + pagination->getListFooter(); ?> +
    +
    + status == 1 && $item->request_type === 'export') : ?> + + sendMailEnabled) : ?> + + + + status == 1 && $item->request_type === 'remove') : ?> + + +
    +
    + status); ?> + + status == 1 && $urgentRequestDate >= $itemRequestedAt) : ?> + + + + escape($item->email)); ?> + + + request_type); ?> + + + + + + id; ?> +
    + + + + + +
    + diff --git a/Sites/pages/administrator/components/com_privacy/views/requests/tmpl/default.xml b/Sites/pages/administrator/components/com_privacy/views/requests/tmpl/default.xml new file mode 100644 index 00000000..4c624d27 --- /dev/null +++ b/Sites/pages/administrator/components/com_privacy/views/requests/tmpl/default.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/Sites/pages/administrator/components/com_privacy/views/requests/view.html.php b/Sites/pages/administrator/components/com_privacy/views/requests/view.html.php new file mode 100644 index 00000000..3d0ba16a --- /dev/null +++ b/Sites/pages/administrator/components/com_privacy/views/requests/view.html.php @@ -0,0 +1,141 @@ +items = $this->get('Items'); + $this->pagination = $this->get('Pagination'); + $this->state = $this->get('State'); + $this->filterForm = $this->get('FilterForm'); + $this->activeFilters = $this->get('ActiveFilters'); + $this->urgentRequestAge = (int) JComponentHelper::getParams('com_privacy')->get('notify', 14); + $this->sendMailEnabled = (bool) JFactory::getConfig()->get('mailonline', 1); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + $this->addToolbar(); + + $this->sidebar = JHtmlSidebar::render(); + + return parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 3.9.0 + */ + protected function addToolbar() + { + JToolbarHelper::title(JText::_('COM_PRIVACY_VIEW_REQUESTS'), 'lock'); + + // Requests can only be created if mail sending is enabled + if (JFactory::getConfig()->get('mailonline', 1)) + { + JToolbarHelper::addNew('request.add'); + } + + JToolbarHelper::preferences('com_privacy'); + JToolbarHelper::help('JHELP_COMPONENTS_PRIVACY_REQUESTS'); + + } +} diff --git a/Sites/pages/administrator/components/com_redirect/access.xml b/Sites/pages/administrator/components/com_redirect/access.xml new file mode 100644 index 00000000..ddf5198b --- /dev/null +++ b/Sites/pages/administrator/components/com_redirect/access.xml @@ -0,0 +1,12 @@ + + +
    + + + + + + + +
    +
    diff --git a/Sites/pages/administrator/components/com_redirect/config.xml b/Sites/pages/administrator/components/com_redirect/config.xml new file mode 100644 index 00000000..9c87ece0 --- /dev/null +++ b/Sites/pages/administrator/components/com_redirect/config.xml @@ -0,0 +1,53 @@ + + +
    + + + + + + + + + +
    + +
    + +
    +
    diff --git a/Sites/pages/administrator/components/com_redirect/controller.php b/Sites/pages/administrator/components/com_redirect/controller.php new file mode 100644 index 00000000..d403384c --- /dev/null +++ b/Sites/pages/administrator/components/com_redirect/controller.php @@ -0,0 +1,59 @@ +input->get('view', 'links')); + + $view = $this->input->get('view', 'links'); + $layout = $this->input->get('layout', 'default'); + $id = $this->input->getInt('id'); + + // Check for edit form. + if ($view == 'link' && $layout == 'edit' && !$this->checkEditId('com_redirect.edit.link', $id)) + { + // Somehow the person just went to the form - we don't allow that. + $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id)); + $this->setMessage($this->getError(), 'error'); + $this->setRedirect(JRoute::_('index.php?option=com_redirect&view=links', false)); + + return false; + } + + parent::display(); + } +} diff --git a/Sites/pages/administrator/components/com_redirect/controllers/link.php b/Sites/pages/administrator/components/com_redirect/controllers/link.php new file mode 100644 index 00000000..9762c2cc --- /dev/null +++ b/Sites/pages/administrator/components/com_redirect/controllers/link.php @@ -0,0 +1,20 @@ +checkToken(); + + $ids = $this->input->get('cid', array(), 'array'); + $newUrl = $this->input->getString('new_url'); + $comment = $this->input->getString('comment'); + + if (empty($ids)) + { + JError::raiseWarning(500, JText::_('COM_REDIRECT_NO_ITEM_SELECTED')); + } + else + { + // Get the model. + $model = $this->getModel(); + + $ids = ArrayHelper::toInteger($ids); + + // Remove the items. + if (!$model->activate($ids, $newUrl, $comment)) + { + JError::raiseWarning(500, $model->getError()); + } + else + { + $this->setMessage(JText::plural('COM_REDIRECT_N_LINKS_UPDATED', count($ids))); + } + } + + $this->setRedirect('index.php?option=com_redirect&view=links'); + } + + /** + * Method to duplicate URLs in records. + * + * @return void + * + * @since 3.6.0 + */ + public function duplicateUrls() + { + // Check for request forgeries. + $this->checkToken(); + + $ids = $this->input->get('cid', array(), 'array'); + $newUrl = $this->input->getString('new_url'); + $comment = $this->input->getString('comment'); + + if (empty($ids)) + { + JError::raiseWarning(500, JText::_('COM_REDIRECT_NO_ITEM_SELECTED')); + } + else + { + // Get the model. + $model = $this->getModel(); + + $ids = ArrayHelper::toInteger($ids); + + // Remove the items. + if (!$model->duplicateUrls($ids, $newUrl, $comment)) + { + JError::raiseWarning(500, $model->getError()); + } + else + { + $this->setMessage(JText::plural('COM_REDIRECT_N_LINKS_UPDATED', count($ids))); + } + } + + $this->setRedirect('index.php?option=com_redirect&view=links'); + } + + /** + * Proxy for getModel. + * + * @param string $name The name of the model. + * @param string $prefix The prefix of the model. + * @param array $config An array of settings. + * + * @return JModel instance + * + * @since 1.6 + */ + public function getModel($name = 'Link', $prefix = 'RedirectModel', $config = array('ignore_request' => true)) + { + return parent::getModel($name, $prefix, $config); + } + + /** + * Executes the batch process to add URLs to the database + * + * @return void + */ + public function batch() + { + // Check for request forgeries. + $this->checkToken(); + + $batch_urls_request = $this->input->post->get('batch_urls', array(), 'array'); + $batch_urls_lines = array_map('trim', explode("\n", $batch_urls_request[0])); + + $batch_urls = array(); + + foreach ($batch_urls_lines as $batch_urls_line) + { + if (!empty($batch_urls_line)) + { + $params = JComponentHelper::getParams('com_redirect'); + $separator = $params->get('separator', '|'); + + // Basic check to make sure the correct separator is being used + if (!\Joomla\String\StringHelper::strpos($batch_urls_line, $separator)) + { + $this->setMessage(JText::sprintf('COM_REDIRECT_NO_SEPARATOR_FOUND', $separator), 'error'); + $this->setRedirect('index.php?option=com_redirect&view=links'); + + return false; + } + + $batch_urls[] = array_map('trim', explode($separator, $batch_urls_line)); + } + } + + // Set default message on error - overwrite if successful + $this->setMessage(JText::_('COM_REDIRECT_NO_ITEM_ADDED'), 'error'); + + if (!empty($batch_urls)) + { + $model = $this->getModel('Links'); + + // Execute the batch process + if ($model->batchProcess($batch_urls)) + { + $this->setMessage(JText::plural('COM_REDIRECT_N_LINKS_ADDED', count($batch_urls))); + } + } + + $this->setRedirect('index.php?option=com_redirect&view=links'); + } + + /** + * Clean out the unpublished links. + * + * @return void + * + * @since 3.5 + */ + public function purge() + { + // Check for request forgeries. + $this->checkToken(); + + $model = $this->getModel('Links'); + + if ($model->purge()) + { + $message = JText::_('COM_REDIRECT_CLEAR_SUCCESS'); + } + else + { + $message = JText::_('COM_REDIRECT_CLEAR_FAIL'); + } + + $this->setRedirect('index.php?option=com_redirect&view=links', $message); + } +} diff --git a/Sites/pages/administrator/components/com_redirect/helpers/html/redirect.php b/Sites/pages/administrator/components/com_redirect/helpers/html/redirect.php new file mode 100644 index 00000000..7169d5ac --- /dev/null +++ b/Sites/pages/administrator/components/com_redirect/helpers/html/redirect.php @@ -0,0 +1,62 @@ + array('publish', 'links.unpublish', 'JENABLED', 'COM_REDIRECT_DISABLE_LINK'), + 0 => array('unpublish', 'links.publish', 'JDISABLED', 'COM_REDIRECT_ENABLE_LINK'), + 2 => array('archive', 'links.unpublish', 'JARCHIVED', 'JUNARCHIVE'), + -2 => array('trash', 'links.publish', 'JTRASHED', 'COM_REDIRECT_ENABLE_LINK'), + ); + + $state = ArrayHelper::getValue($states, (int) $value, $states[0]); + $icon = $state[0]; + + if ($canChange) + { + $html = ''; + } + + return $html; + } +} diff --git a/Sites/pages/administrator/components/com_redirect/helpers/redirect.php b/Sites/pages/administrator/components/com_redirect/helpers/redirect.php new file mode 100644 index 00000000..b2c9c0a9 --- /dev/null +++ b/Sites/pages/administrator/components/com_redirect/helpers/redirect.php @@ -0,0 +1,132 @@ +getQuery(true) + ->select($db->quoteName('extension_id')) + ->from($db->quoteName('#__extensions')) + ->where($db->quoteName('folder') . ' = ' . $db->quote('system')) + ->where($db->quoteName('element') . ' = ' . $db->quote('redirect')); + $db->setQuery($query); + + try + { + $result = (int) $db->loadResult(); + } + catch (RuntimeException $e) + { + JError::raiseWarning(500, $e->getMessage()); + } + + return $result; + } + + /** + * Checks whether the option "Collect URLs" is enabled for the output message + * + * @return boolean + * + * @since 3.4 + */ + public static function collectUrlsEnabled() + { + $collect_urls = false; + + if (JPluginHelper::isEnabled('system', 'redirect')) + { + $params = new Registry(JPluginHelper::getPlugin('system', 'redirect')->params); + $collect_urls = (bool) $params->get('collect_urls', 1); + } + + return $collect_urls; + } +} diff --git a/Sites/pages/administrator/components/com_redirect/layouts/toolbar/batch.php b/Sites/pages/administrator/components/com_redirect/layouts/toolbar/batch.php new file mode 100644 index 00000000..58c75607 --- /dev/null +++ b/Sites/pages/administrator/components/com_redirect/layouts/toolbar/batch.php @@ -0,0 +1,20 @@ + + diff --git a/Sites/pages/administrator/components/com_redirect/models/fields/redirect.php b/Sites/pages/administrator/components/com_redirect/models/fields/redirect.php new file mode 100644 index 00000000..32ceb9cb --- /dev/null +++ b/Sites/pages/administrator/components/com_redirect/models/fields/redirect.php @@ -0,0 +1,123 @@ + 'HTTP/1.1 100 Continue', + 101 => 'HTTP/1.1 101 Switching Protocols', + 102 => 'HTTP/1.1 102 Processing', + 200 => 'HTTP/1.1 200 OK', + 201 => 'HTTP/1.1 201 Created', + 202 => 'HTTP/1.1 202 Accepted', + 203 => 'HTTP/1.1 203 Non-Authoritative Information', + 204 => 'HTTP/1.1 204 No Content', + 205 => 'HTTP/1.1 205 Reset Content', + 206 => 'HTTP/1.1 206 Partial Content', + 207 => 'HTTP/1.1 207 Multi-Status', + 208 => 'HTTP/1.1 208 Already Reported', + 226 => 'HTTP/1.1 226 IM Used', + 300 => 'HTTP/1.1 300 Multiple Choices', + 301 => 'HTTP/1.1 301 Moved Permanently', + 302 => 'HTTP/1.1 302 Found', + 303 => 'HTTP/1.1 303 See other', + 304 => 'HTTP/1.1 304 Not Modified', + 305 => 'HTTP/1.1 305 Use Proxy', + 306 => 'HTTP/1.1 306 (Unused)', + 307 => 'HTTP/1.1 307 Temporary Redirect', + 308 => 'HTTP/1.1 308 Permanent Redirect', + 400 => 'HTTP/1.1 400 Bad Request', + 401 => 'HTTP/1.1 401 Unauthorized', + 402 => 'HTTP/1.1 402 Payment Required', + 403 => 'HTTP/1.1 403 Forbidden', + 404 => 'HTTP/1.1 404 Not Found', + 405 => 'HTTP/1.1 405 Method Not Allowed', + 406 => 'HTTP/1.1 406 Not Acceptable', + 407 => 'HTTP/1.1 407 Proxy Authentication Required', + 408 => 'HTTP/1.1 408 Request Timeout', + 409 => 'HTTP/1.1 409 Conflict', + 410 => 'HTTP/1.1 410 Gone', + 411 => 'HTTP/1.1 411 Length Required', + 412 => 'HTTP/1.1 412 Precondition Failed', + 413 => 'HTTP/1.1 413 Payload Too Large', + 414 => 'HTTP/1.1 414 URI Too Long', + 415 => 'HTTP/1.1 415 Unsupported Media Type', + 416 => 'HTTP/1.1 416 Requested Range Not Satisfiable', + 417 => 'HTTP/1.1 417 Expectation Failed', + 418 => 'HTTP/1.1 418 I\'m a teapot', + 422 => 'HTTP/1.1 422 Unprocessable Entity', + 423 => 'HTTP/1.1 423 Locked', + 424 => 'HTTP/1.1 424 Failed Dependency', + 425 => 'HTTP/1.1 425 Reserved for WebDAV advanced collections expired proposal', + 426 => 'HTTP/1.1 426 Upgrade Required', + 428 => 'HTTP/1.1 428 Precondition Required', + 429 => 'HTTP/1.1 429 Too Many Requests', + 431 => 'HTTP/1.1 431 Request Header Fields Too Large', + 451 => 'HTTP/1.1 451 Unavailable For Legal Reasons', + 500 => 'HTTP/1.1 500 Internal Server Error', + 501 => 'HTTP/1.1 501 Not Implemented', + 502 => 'HTTP/1.1 502 Bad Gateway', + 503 => 'HTTP/1.1 503 Service Unavailable', + 504 => 'HTTP/1.1 504 Gateway Timeout', + 505 => 'HTTP/1.1 505 HTTP Version Not Supported', + 506 => 'HTTP/1.1 506 Variant Also Negotiates (Experimental)', + 507 => 'HTTP/1.1 507 Insufficient Storage', + 508 => 'HTTP/1.1 508 Loop Detected', + 510 => 'HTTP/1.1 510 Not Extended', + 511 => 'HTTP/1.1 511 Network Authentication Required', + ); + + /** + * Method to get the field input markup. + * + * @return string The field input markup. + * + * @since 3.4 + */ + protected function getOptions() + { + $options = array(); + + foreach ($this->responseMap as $key => $value) + { + $options[] = JHtml::_('select.option', $key, $value); + } + + // Merge any additional options in the XML definition. + $options = array_merge(parent::getOptions(), $options); + + return $options; + } +} diff --git a/Sites/pages/administrator/components/com_redirect/models/forms/filter_links.xml b/Sites/pages/administrator/components/com_redirect/models/forms/filter_links.xml new file mode 100644 index 00000000..4d1bd3df --- /dev/null +++ b/Sites/pages/administrator/components/com_redirect/models/forms/filter_links.xml @@ -0,0 +1,69 @@ + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    diff --git a/Sites/pages/administrator/components/com_redirect/models/forms/link.xml b/Sites/pages/administrator/components/com_redirect/models/forms/link.xml new file mode 100644 index 00000000..981b0bfd --- /dev/null +++ b/Sites/pages/administrator/components/com_redirect/models/forms/link.xml @@ -0,0 +1,109 @@ + +
    +
    + + + + + + + + + + + + + + + + + + + + + + +
    +
    + +
    +
    diff --git a/Sites/pages/administrator/components/com_redirect/models/link.php b/Sites/pages/administrator/components/com_redirect/models/link.php new file mode 100644 index 00000000..84c7ad85 --- /dev/null +++ b/Sites/pages/administrator/components/com_redirect/models/link.php @@ -0,0 +1,246 @@ +published != -2) + { + return false; + } + + return parent::canDelete($record); + } + + /** + * Returns a reference to the a Table object, always creating it. + * + * @param string $type The table type to instantiate + * @param string $prefix A prefix for the table class name. Optional. + * @param array $config Configuration array for model. Optional. + * + * @return JTable A database object + * + * @since 1.6 + */ + public function getTable($type = 'Link', $prefix = 'RedirectTable', $config = array()) + { + return JTable::getInstance($type, $prefix, $config); + } + + /** + * Method to get the record form. + * + * @param array $data Data for the form. + * @param boolean $loadData True if the form is to load its own data (default case), false if not. + * + * @return JForm A JForm object on success, false on failure + * + * @since 1.6 + */ + public function getForm($data = array(), $loadData = true) + { + // Get the form. + $form = $this->loadForm('com_redirect.link', 'link', array('control' => 'jform', 'load_data' => $loadData)); + + if (empty($form)) + { + return false; + } + + // Modify the form based on access controls. + if ($this->canEditState((object) $data) != true) + { + // Disable fields for display. + $form->setFieldAttribute('published', 'disabled', 'true'); + + // Disable fields while saving. + // The controller has already verified this is a record you can edit. + $form->setFieldAttribute('published', 'filter', 'unset'); + } + + // If in advanced mode then we make sure the new URL field is not compulsory and the header + // field compulsory in case people select non-3xx redirects + if (JComponentHelper::getParams('com_redirect')->get('mode', 0) == true) + { + $form->setFieldAttribute('new_url', 'required', 'false'); + $form->setFieldAttribute('header', 'required', 'true'); + } + + return $form; + } + + /** + * Method to get the data that should be injected in the form. + * + * @return mixed The data for the form. + * + * @since 1.6 + */ + protected function loadFormData() + { + // Check the session for previously entered form data. + $data = JFactory::getApplication()->getUserState('com_redirect.edit.link.data', array()); + + if (empty($data)) + { + $data = $this->getItem(); + } + + $this->preprocessData('com_redirect.link', $data); + + return $data; + } + + /** + * Method to activate links. + * + * @param array &$pks An array of link ids. + * @param string $url The new URL to set for the redirect. + * @param string $comment A comment for the redirect links. + * + * @return boolean Returns true on success, false on failure. + * + * @since 1.6 + */ + public function activate(&$pks, $url, $comment = null) + { + $user = JFactory::getUser(); + $db = $this->getDbo(); + + // Sanitize the ids. + $pks = (array) $pks; + $pks = ArrayHelper::toInteger($pks); + + // Populate default comment if necessary. + $comment = (!empty($comment)) ? $comment : JText::sprintf('COM_REDIRECT_REDIRECTED_ON', JHtml::_('date', time())); + + // Access checks. + if (!$user->authorise('core.edit', 'com_redirect')) + { + $pks = array(); + $this->setError(JText::_('JLIB_APPLICATION_ERROR_EDIT_NOT_PERMITTED')); + + return false; + } + + if (!empty($pks)) + { + // Update the link rows. + $query = $db->getQuery(true) + ->update($db->quoteName('#__redirect_links')) + ->set($db->quoteName('new_url') . ' = ' . $db->quote($url)) + ->set($db->quoteName('published') . ' = ' . (int) 1) + ->set($db->quoteName('comment') . ' = ' . $db->quote($comment)) + ->where($db->quoteName('id') . ' IN (' . implode(',', $pks) . ')'); + $db->setQuery($query); + + try + { + $db->execute(); + } + catch (RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + } + + return true; + } + + /** + * Method to batch update URLs to have new redirect urls and comments. Note will publish any unpublished URLs. + * + * @param array &$pks An array of link ids. + * @param string $url The new URL to set for the redirect. + * @param string $comment A comment for the redirect links. + * + * @return boolean Returns true on success, false on failure. + * + * @since 3.6.0 + */ + public function duplicateUrls(&$pks, $url, $comment = null) + { + $user = JFactory::getUser(); + $db = $this->getDbo(); + + // Sanitize the ids. + $pks = (array) $pks; + $pks = ArrayHelper::toInteger($pks); + + // Access checks. + if (!$user->authorise('core.edit', 'com_redirect')) + { + $pks = array(); + $this->setError(JText::_('JLIB_APPLICATION_ERROR_EDIT_NOT_PERMITTED')); + + return false; + } + + if (!empty($pks)) + { + $date = JFactory::getDate()->toSql(); + + // Update the link rows. + $query = $db->getQuery(true) + ->update($db->quoteName('#__redirect_links')) + ->set($db->quoteName('new_url') . ' = ' . $db->quote($url)) + ->set($db->quoteName('modified_date') . ' = ' . $db->quote($date)) + ->set($db->quoteName('published') . ' = ' . 1) + ->where($db->quoteName('id') . ' IN (' . implode(',', $pks) . ')'); + + if (!empty($comment)) + { + $query->set($db->quoteName('comment') . ' = ' . $db->quote($comment)); + } + + $db->setQuery($query); + + try + { + $db->execute(); + } + catch (RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + } + + return true; + } +} diff --git a/Sites/pages/administrator/components/com_redirect/models/links.php b/Sites/pages/administrator/components/com_redirect/models/links.php new file mode 100644 index 00000000..1cd171cd --- /dev/null +++ b/Sites/pages/administrator/components/com_redirect/models/links.php @@ -0,0 +1,244 @@ +getDbo(); + + $query = $db->getQuery(true); + + $query->delete('#__redirect_links')->where($db->qn('published') . '= 0'); + + $db->setQuery($query); + + try + { + $db->execute(); + } + catch (Exception $e) + { + return false; + } + + return true; + } + + /** + * Method to auto-populate the model state. + * + * Note. Calling getState in this method will result in recursion. + * + * @param string $ordering An optional ordering field. + * @param string $direction An optional direction (asc|desc). + * + * @return void + * + * @since 1.6 + */ + protected function populateState($ordering = 'a.old_url', $direction = 'asc') + { + // Load the filter state. + $this->setState('filter.search', $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search', '', 'string')); + $this->setState('filter.state', $this->getUserStateFromRequest($this->context . '.filter.state', 'filter_state', '', 'string')); + $this->setState('filter.http_status', $this->getUserStateFromRequest($this->context . '.filter.http_status', 'filter_http_status', '', 'cmd')); + + // Load the parameters. + $params = JComponentHelper::getParams('com_redirect'); + $this->setState('params', $params); + + // List state information. + parent::populateState($ordering, $direction); + } + + /** + * Method to get a store id based on model configuration state. + * + * This is necessary because the model is used by the component and + * different modules that might need different sets of data or different + * ordering requirements. + * + * @param string $id A prefix for the store id. + * + * @return string A store id. + * + * @since 1.6 + */ + protected function getStoreId($id = '') + { + // Compile the store id. + $id .= ':' . $this->getState('filter.search'); + $id .= ':' . $this->getState('filter.state'); + $id .= ':' . $this->getState('filter.http_status'); + + return parent::getStoreId($id); + } + + /** + * Build an SQL query to load the list data. + * + * @return JDatabaseQuery + * + * @since 1.6 + */ + protected function getListQuery() + { + // Create a new query object. + $db = $this->getDbo(); + $query = $db->getQuery(true); + + // Select the required fields from the table. + $query->select( + $this->getState( + 'list.select', + 'a.*' + ) + ); + $query->from($db->quoteName('#__redirect_links', 'a')); + + // Filter by published state + $state = $this->getState('filter.state'); + + if (is_numeric($state)) + { + $query->where($db->quoteName('a.published') . ' = ' . (int) $state); + } + elseif ($state === '') + { + $query->where($db->quoteName('a.published') . ' IN (0,1)'); + } + + // Filter the items over the HTTP status code header. + if ($httpStatusCode = $this->getState('filter.http_status')) + { + $query->where($db->quoteName('a.header') . ' = ' . (int) $httpStatusCode); + } + + // Filter the items over the search string if set. + $search = $this->getState('filter.search'); + + if (!empty($search)) + { + if (stripos($search, 'id:') === 0) + { + $query->where($db->quoteName('a.id') . ' = ' . (int) substr($search, 3)); + } + else + { + $search = $db->quote('%' . str_replace(' ', '%', $db->escape(trim($search), true) . '%')); + $query->where( + '(' . $db->quoteName('old_url') . ' LIKE ' . $search . + ' OR ' . $db->quoteName('new_url') . ' LIKE ' . $search . + ' OR ' . $db->quoteName('comment') . ' LIKE ' . $search . + ' OR ' . $db->quoteName('referer') . ' LIKE ' . $search . ')' + ); + } + } + + // Add the list ordering clause. + $query->order($db->escape($this->getState('list.ordering', 'a.old_url')) . ' ' . $db->escape($this->getState('list.direction', 'ASC'))); + + return $query; + } + + /** + * Add the entered URLs into the database + * + * @param array $batchUrls Array of URLs to enter into the database + * + * @return boolean + */ + public function batchProcess($batchUrls) + { + $db = JFactory::getDbo(); + $query = $db->getQuery(true); + + $params = JComponentHelper::getParams('com_redirect'); + $state = (int) $params->get('defaultImportState', 0); + + $columns = array( + $db->quoteName('old_url'), + $db->quoteName('new_url'), + $db->quoteName('referer'), + $db->quoteName('comment'), + $db->quoteName('hits'), + $db->quoteName('published'), + $db->quoteName('created_date') + ); + + $query->columns($columns); + + foreach ($batchUrls as $batch_url) + { + $old_url = $batch_url[0]; + + // Destination URL can also be an external URL + if (!empty($batch_url[1])) + { + $new_url = $batch_url[1]; + } + else + { + $new_url = ''; + } + + $query->insert($db->quoteName('#__redirect_links'), false) + ->values( + $db->quote($old_url) . ', ' . $db->quote($new_url) . ' ,' . $db->quote('') . ', ' . $db->quote('') . ', 0, ' . $state . ', ' . + $db->quote(JFactory::getDate()->toSql()) + ); + } + + $db->setQuery($query); + $db->execute(); + + return true; + } +} diff --git a/Sites/pages/administrator/components/com_redirect/redirect.php b/Sites/pages/administrator/components/com_redirect/redirect.php new file mode 100644 index 00000000..7d179dd1 --- /dev/null +++ b/Sites/pages/administrator/components/com_redirect/redirect.php @@ -0,0 +1,19 @@ +authorise('core.manage', 'com_redirect')) +{ + throw new JAccessExceptionNotallowed(JText::_('JERROR_ALERTNOAUTHOR'), 403); +} + +$controller = JControllerLegacy::getInstance('Redirect'); +$controller->execute(JFactory::getApplication()->input->get('task')); +$controller->redirect(); diff --git a/Sites/pages/administrator/components/com_redirect/redirect.xml b/Sites/pages/administrator/components/com_redirect/redirect.xml new file mode 100644 index 00000000..84036413 --- /dev/null +++ b/Sites/pages/administrator/components/com_redirect/redirect.xml @@ -0,0 +1,30 @@ + + + com_redirect + Joomla! Project + April 2006 + (C) 2005 - 2020 Open Source Matters. All rights reserved. + GNU General Public License version 2 or later; see LICENSE.txt + admin@joomla.org + www.joomla.org + 3.0.0 + COM_REDIRECT_XML_DESCRIPTION + + Redirect + + + config.xml + controller.php + redirect.php + controllers + helpers + models + tables + views + + + language/en-GB.com_redirect.ini + language/en-GB.com_redirect.sys.ini + + + diff --git a/Sites/pages/administrator/components/com_redirect/tables/link.php b/Sites/pages/administrator/components/com_redirect/tables/link.php new file mode 100644 index 00000000..f5a9c0c8 --- /dev/null +++ b/Sites/pages/administrator/components/com_redirect/tables/link.php @@ -0,0 +1,130 @@ +old_url = trim(rawurldecode($this->old_url)); + $this->new_url = trim(rawurldecode($this->new_url)); + + // Check for valid name. + if (empty($this->old_url)) + { + $this->setError(JText::_('COM_REDIRECT_ERROR_SOURCE_URL_REQUIRED')); + + return false; + } + + // Check for NOT NULL. + if (empty($this->referer)) + { + $this->referer = ''; + } + + // Check for valid name if not in advanced mode. + if (empty($this->new_url) && JComponentHelper::getParams('com_redirect')->get('mode', 0) == false) + { + $this->setError(JText::_('COM_REDIRECT_ERROR_DESTINATION_URL_REQUIRED')); + + return false; + } + elseif (empty($this->new_url) && JComponentHelper::getParams('com_redirect')->get('mode', 0) == true) + { + // Else if an empty URL and in redirect mode only throw the same error if the code is a 3xx status code + if ($this->header < 400 && $this->header >= 300) + { + $this->setError(JText::_('COM_REDIRECT_ERROR_DESTINATION_URL_REQUIRED')); + + return false; + } + } + + // Check for duplicates + if ($this->old_url == $this->new_url) + { + $this->setError(JText::_('COM_REDIRECT_ERROR_DUPLICATE_URLS')); + + return false; + } + + $db = $this->getDbo(); + + // Check for existing name + $query = $db->getQuery(true) + ->select($db->quoteName('id')) + ->select($db->quoteName('old_url')) + ->from('#__redirect_links') + ->where($db->quoteName('old_url') . ' = ' . $db->quote($this->old_url)); + $db->setQuery($query); + $urls = $db->loadAssocList(); + + foreach ($urls as $url) + { + if ($url['old_url'] === $this->old_url && (int) $url['id'] != (int) $this->id) + { + $this->setError(JText::_('COM_REDIRECT_ERROR_DUPLICATE_OLD_URL')); + + return false; + } + } + + return true; + } + + /** + * Overriden store method to set dates. + * + * @param boolean $updateNulls True to update fields even if they are null. + * + * @return boolean True on success. + * + * @since 1.6 + */ + public function store($updateNulls = false) + { + $date = JFactory::getDate()->toSql(); + + $this->modified_date = $date; + + if (!$this->id) + { + // New record. + $this->created_date = $date; + } + + return parent::store($updateNulls); + } +} diff --git a/Sites/pages/administrator/components/com_redirect/views/link/tmpl/edit.php b/Sites/pages/administrator/components/com_redirect/views/link/tmpl/edit.php new file mode 100644 index 00000000..371044e7 --- /dev/null +++ b/Sites/pages/administrator/components/com_redirect/views/link/tmpl/edit.php @@ -0,0 +1,51 @@ +addScriptDeclaration(" + Joomla.submitbutton = function(task) + { + if (task == 'link.cancel' || document.formvalidator.isValid(document.getElementById('link-form'))) + { + Joomla.submitform(task, document.getElementById('link-form')); + } + }; +"); +?> + + diff --git a/Sites/pages/administrator/components/com_redirect/views/link/view.html.php b/Sites/pages/administrator/components/com_redirect/views/link/view.html.php new file mode 100644 index 00000000..2f0f24f7 --- /dev/null +++ b/Sites/pages/administrator/components/com_redirect/views/link/view.html.php @@ -0,0 +1,94 @@ +form = $this->get('Form'); + $this->item = $this->get('Item'); + $this->state = $this->get('State'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + $this->addToolbar(); + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + JFactory::getApplication()->input->set('hidemainmenu', true); + + $isNew = ($this->item->id == 0); + $canDo = JHelperContent::getActions('com_redirect'); + + JToolbarHelper::title($isNew ? JText::_('COM_REDIRECT_MANAGER_LINK_NEW') : JText::_('COM_REDIRECT_MANAGER_LINK_EDIT'), 'refresh redirect'); + + // If not checked out, can save the item. + if ($canDo->get('core.edit')) + { + JToolbarHelper::apply('link.apply'); + JToolbarHelper::save('link.save'); + } + + /** + * This component does not support Save as Copy due to uniqueness checks. + * While it can be done, it causes too much confusion if the user does + * not change the Old URL. + */ + if ($canDo->get('core.edit') && $canDo->get('core.create')) + { + JToolbarHelper::save2new('link.save2new'); + } + + if (empty($this->item->id)) + { + JToolbarHelper::cancel('link.cancel'); + } + else + { + JToolbarHelper::cancel('link.cancel', 'JTOOLBAR_CLOSE'); + } + + JToolbarHelper::help('JHELP_COMPONENTS_REDIRECT_MANAGER_EDIT'); + } +} diff --git a/Sites/pages/administrator/components/com_redirect/views/links/tmpl/default.php b/Sites/pages/administrator/components/com_redirect/views/links/tmpl/default.php new file mode 100644 index 00000000..2114aa26 --- /dev/null +++ b/Sites/pages/administrator/components/com_redirect/views/links/tmpl/default.php @@ -0,0 +1,172 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +?> +
    +
    + $this)); ?> + redirectPluginId) : ?> + redirectPluginId . '&tmpl=component&layout=modal'); ?> + redirectPluginId . 'Modal', + array( + 'url' => $link, + 'title' => JText::_('COM_REDIRECT_EDIT_PLUGIN_SETTINGS'), + 'height' => '400px', + 'width' => '800px', + 'bodyHeight' => '70', + 'modalWidth' => '80', + 'closeButton' => false, + 'backdrop' => 'static', + 'keyboard' => false, + 'footer' => '' + . '' + . '' + ) + ); ?> + + + items)) : ?> +
    + +
    + + + + + + + + + + + + + + + + + + + + + + items as $i => $item) : + $canEdit = $user->authorise('core.edit', 'com_redirect'); + $canChange = $user->authorise('core.edit.state', 'com_redirect'); + ?> + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + +
    + pagination->getListFooter(); ?> +
    + id); ?> + +
    + published, $i); ?> + published === 2 ? 'un' : '') . 'archive', 'cb' . $i, 'links'); + JHtml::_('actionsdropdown.' . ((int) $item->published === -2 ? 'un' : '') . 'trash', 'cb' . $i, 'links'); + echo JHtml::_('actionsdropdown.render', $this->escape($item->old_url)); + } + ?> +
    +
    + + + escape(str_replace(JUri::root(), '', rawurldecode($item->old_url))); ?> + + escape(str_replace(JUri::root(), '', rawurldecode($item->old_url))); ?> + + + escape(rawurldecode($item->new_url)); ?> + + escape($item->referer); ?> + + created_date, JText::_('DATE_FORMAT_LC4')); ?> + + hits; ?> + + header; ?> + + id; ?> +
    + + + items)) : ?> + loadTemplate('addform'); ?> + + + authorise('core.create', 'com_redirect') + && $user->authorise('core.edit', 'com_redirect') + && $user->authorise('core.edit.state', 'com_redirect')) : ?> + JText::_('COM_REDIRECT_BATCH_OPTIONS'), + 'footer' => $this->loadTemplate('batch_footer'), + ), + $this->loadTemplate('batch_body') + ); ?> + + + + + +
    +
    diff --git a/Sites/pages/administrator/components/com_redirect/views/links/tmpl/default.xml b/Sites/pages/administrator/components/com_redirect/views/links/tmpl/default.xml new file mode 100644 index 00000000..2158f363 --- /dev/null +++ b/Sites/pages/administrator/components/com_redirect/views/links/tmpl/default.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/Sites/pages/administrator/components/com_redirect/views/links/tmpl/default_addform.php b/Sites/pages/administrator/components/com_redirect/views/links/tmpl/default_addform.php new file mode 100644 index 00000000..ee1b3457 --- /dev/null +++ b/Sites/pages/administrator/components/com_redirect/views/links/tmpl/default_addform.php @@ -0,0 +1,40 @@ + +
    +
    +
    + + + +
    +
    +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    + +
    +
    +
    +
    +
    diff --git a/Sites/pages/administrator/components/com_redirect/views/links/tmpl/default_batch_body.php b/Sites/pages/administrator/components/com_redirect/views/links/tmpl/default_batch_body.php new file mode 100644 index 00000000..7d13a8d9 --- /dev/null +++ b/Sites/pages/administrator/components/com_redirect/views/links/tmpl/default_batch_body.php @@ -0,0 +1,24 @@ +state->get('filter.published'); +$params = $this->params; +$separator = $params->get('separator', '|'); +?> + +
    +
    +
    +

    +
    + +
    +
    +
    +
    diff --git a/Sites/pages/administrator/components/com_redirect/views/links/tmpl/default_batch_footer.php b/Sites/pages/administrator/components/com_redirect/views/links/tmpl/default_batch_footer.php new file mode 100644 index 00000000..29b04640 --- /dev/null +++ b/Sites/pages/administrator/components/com_redirect/views/links/tmpl/default_batch_footer.php @@ -0,0 +1,17 @@ + + + diff --git a/Sites/pages/administrator/components/com_redirect/views/links/view.html.php b/Sites/pages/administrator/components/com_redirect/views/links/view.html.php new file mode 100644 index 00000000..383a6503 --- /dev/null +++ b/Sites/pages/administrator/components/com_redirect/views/links/view.html.php @@ -0,0 +1,190 @@ +enabled = JPluginHelper::isEnabled('system', 'redirect'); + $this->collect_urls_enabled = RedirectHelper::collectUrlsEnabled(); + $this->items = $this->get('Items'); + $this->pagination = $this->get('Pagination'); + $this->state = $this->get('State'); + $this->filterForm = $this->get('FilterForm'); + $this->activeFilters = $this->get('ActiveFilters'); + $this->params = JComponentHelper::getParams('com_redirect'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + // Show messages about the enabled plugin and if the plugin should collect URLs + if ($this->enabled && $this->collect_urls_enabled) + { + $app->enqueueMessage(JText::sprintf('COM_REDIRECT_COLLECT_URLS_ENABLED', JText::_('COM_REDIRECT_PLUGIN_ENABLED')), 'notice'); + } + else + { + $this->redirectPluginId = RedirectHelper::getRedirectPluginId(); + + $link = JHtml::_( + 'link', + '#plugin' . $this->redirectPluginId . 'Modal', + JText::_('COM_REDIRECT_SYSTEM_PLUGIN'), + 'class="alert-link" data-toggle="modal" id="title-' . $this->redirectPluginId . '"' + ); + + // To be removed in Joomla 4 + if (JFactory::getApplication()->getTemplate() === 'hathor') + { + $link = JHtml::_( + 'link', + JRoute::_('index.php?option=com_plugins&task=plugin.edit&extension_id=' . RedirectHelper::getRedirectPluginId()), + JText::_('COM_REDIRECT_SYSTEM_PLUGIN') + ); + } + + if ($this->enabled && !$this->collect_urls_enabled) + { + $app->enqueueMessage(JText::sprintf('COM_REDIRECT_COLLECT_MODAL_URLS_DISABLED', JText::_('COM_REDIRECT_PLUGIN_ENABLED'), $link), 'notice'); + } + else + { + $app->enqueueMessage(JText::sprintf('COM_REDIRECT_PLUGIN_MODAL_DISABLED', $link), 'error'); + } + } + + $this->addToolbar(); + + return parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + $state = $this->get('State'); + $canDo = JHelperContent::getActions('com_redirect'); + + JToolbarHelper::title(JText::_('COM_REDIRECT_MANAGER_LINKS'), 'refresh redirect'); + + if ($canDo->get('core.create')) + { + JToolbarHelper::addNew('link.add'); + } + + if ($canDo->get('core.edit')) + { + JToolbarHelper::editList('link.edit'); + } + + if ($canDo->get('core.edit.state')) + { + if ($state->get('filter.state') != 2) + { + JToolbarHelper::divider(); + JToolbarHelper::publish('links.publish', 'JTOOLBAR_ENABLE', true); + JToolbarHelper::unpublish('links.unpublish', 'JTOOLBAR_DISABLE', true); + } + + if ($state->get('filter.state') != -1) + { + JToolbarHelper::divider(); + + if ($state->get('filter.state') != 2) + { + JToolbarHelper::archiveList('links.archive'); + } + elseif ($state->get('filter.state') == 2) + { + JToolbarHelper::unarchiveList('links.publish', 'JTOOLBAR_UNARCHIVE'); + } + } + } + + if ($canDo->get('core.create')) + { + // Get the toolbar object instance + $bar = JToolbar::getInstance('toolbar'); + + $title = JText::_('JTOOLBAR_BULK_IMPORT'); + + JHtml::_('bootstrap.modal', 'collapseModal'); + + // Instantiate a new JLayoutFile instance and render the batch button + $layout = new JLayoutFile('toolbar.batch'); + + $dhtml = $layout->render(array('title' => $title)); + $bar->appendButton('Custom', $dhtml, 'batch'); + } + + if ($state->get('filter.state') == -2 && $canDo->get('core.delete')) + { + JToolbarHelper::deleteList('JGLOBAL_CONFIRM_DELETE', 'links.delete', 'JTOOLBAR_EMPTY_TRASH'); + JToolbarHelper::divider(); + } + elseif ($canDo->get('core.edit.state')) + { + JToolbarHelper::custom('links.purge', 'delete', 'delete', 'COM_REDIRECT_TOOLBAR_PURGE', false); + JToolbarHelper::trash('links.trash'); + JToolbarHelper::divider(); + } + + if ($canDo->get('core.admin') || $canDo->get('core.options')) + { + JToolbarHelper::preferences('com_redirect'); + JToolbarHelper::divider(); + } + + JToolbarHelper::help('JHELP_COMPONENTS_REDIRECT_MANAGER'); + } +} diff --git a/Sites/pages/administrator/components/com_search/access.xml b/Sites/pages/administrator/components/com_search/access.xml new file mode 100644 index 00000000..9b65a750 --- /dev/null +++ b/Sites/pages/administrator/components/com_search/access.xml @@ -0,0 +1,9 @@ + + +
    + + + + +
    +
    diff --git a/Sites/pages/administrator/components/com_search/config.xml b/Sites/pages/administrator/components/com_search/config.xml new file mode 100644 index 00000000..1e735fd8 --- /dev/null +++ b/Sites/pages/administrator/components/com_search/config.xml @@ -0,0 +1,91 @@ + + +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + +
    +
    diff --git a/Sites/pages/administrator/components/com_search/controller.php b/Sites/pages/administrator/components/com_search/controller.php new file mode 100644 index 00000000..7aa1cbf0 --- /dev/null +++ b/Sites/pages/administrator/components/com_search/controller.php @@ -0,0 +1,44 @@ +input->get('view', 'searches')); + + return parent::display(); + } +} diff --git a/Sites/pages/administrator/components/com_search/controllers/searches.php b/Sites/pages/administrator/components/com_search/controllers/searches.php new file mode 100644 index 00000000..a866a891 --- /dev/null +++ b/Sites/pages/administrator/components/com_search/controllers/searches.php @@ -0,0 +1,58 @@ +checkToken(); + + $model = $this->getModel('Searches'); + + if (!$model->reset()) + { + JError::raiseWarning(500, $model->getError()); + } + + $this->setRedirect('index.php?option=com_search&view=searches'); + } + + /** + * Method to toggle the view of results. + * + * @return boolean + */ + public function toggleResults() + { + // Check for request forgeries. + $this->checkToken(); + + if ($this->getModel('Searches')->getState('show_results', 1, 'int') === 0) + { + $this->setRedirect('index.php?option=com_search&view=searches&show_results=1'); + } + else + { + $this->setRedirect('index.php?option=com_search&view=searches&show_results=0'); + } + } +} diff --git a/Sites/pages/administrator/components/com_search/helpers/search.php b/Sites/pages/administrator/components/com_search/helpers/search.php new file mode 100644 index 00000000..a096b90b --- /dev/null +++ b/Sites/pages/administrator/components/com_search/helpers/search.php @@ -0,0 +1,360 @@ +getTag(); + $search_ignore = $lang->getIgnoredSearchWords(); + + // Deprecated in 1.6 use $lang->getIgnoredSearchWords instead. + $ignoreFile = JLanguageHelper::getLanguagePath() . '/' . $tag . '/' . $tag . '.ignore.php'; + + if (file_exists($ignoreFile)) + { + include $ignoreFile; + } + + // Check for words to ignore. + $aterms = explode(' ', StringHelper::strtolower($searchword)); + + // First case is single ignored word. + if (count($aterms) == 1 && in_array(StringHelper::strtolower($searchword), $search_ignore)) + { + $ignored = true; + } + + // Filter out search terms that are too small. + $lower_limit = $lang->getLowerLimitSearchWord(); + + foreach ($aterms as $aterm) + { + if (StringHelper::strlen($aterm) < $lower_limit) + { + $search_ignore[] = $aterm; + } + } + + // Next is to remove ignored words from type 'all' or 'any' (not exact) searches with multiple words. + if (count($aterms) > 1 && $searchphrase != 'exact') + { + $pruned = array_diff($aterms, $search_ignore); + $searchword = implode(' ', $pruned); + } + + return $ignored; + } + + /** + * Does search word need to be limited? + * + * @param string &$searchword Search word to be checked. + * + * @return boolean True if search word should be limited; false otherwise. + * + * @since 1.5 + */ + public static function limitSearchWord(&$searchword) + { + $restriction = false; + + $lang = JFactory::getLanguage(); + + // Limit searchword to a maximum of characters. + $upper_limit = $lang->getUpperLimitSearchWord(); + + if (StringHelper::strlen($searchword) > $upper_limit) + { + $searchword = StringHelper::substr($searchword, 0, $upper_limit - 1); + $restriction = true; + } + + // Searchword must contain a minimum of characters. + if ($searchword && StringHelper::strlen($searchword) < $lang->getLowerLimitSearchWord()) + { + $searchword = ''; + $restriction = true; + } + + return $restriction; + } + + /** + * Logs a search term. + * + * @param string $searchTerm The term being searched. + * + * @return void + * + * @since 1.5 + * @deprecated 4.0 Use \Joomla\CMS\Helper\SearchHelper::logSearch() instead. + */ + public static function logSearch($searchTerm) + { + try + { + JLog::add( + sprintf('%s() is deprecated. Use \Joomla\CMS\Helper\SearchHelper::logSearch() instead.', __METHOD__), + JLog::WARNING, + 'deprecated' + ); + } + catch (RuntimeException $exception) + { + // Informational log only + } + + \Joomla\CMS\Helper\SearchHelper::logSearch($searchTerm, 'com_search'); + } + + /** + * Prepares results from search for display. + * + * @param string $text The source string. + * @param string $searchword The searchword to select around. + * + * @return string + * + * @since 1.5 + */ + public static function prepareSearchContent($text, $searchword) + { + // Strips tags won't remove the actual jscript. + $text = preg_replace("']*>.*?'si", '', $text); + $text = preg_replace('/{.+?}/', '', $text); + + // $text = preg_replace('/]*>([^<]+)<\/a>/is','\2', $text); + + // Replace line breaking tags with whitespace. + $text = preg_replace("'<(br[^/>]*?/|hr[^/>]*?/|/(div|h[1-6]|li|p|td))>'si", ' ', $text); + + return self::_smartSubstr(strip_tags($text), $searchword); + } + + /** + * Checks an object for search terms (after stripping fields of HTML). + * + * @param object $object The object to check. + * @param string $searchTerm Search words to check for. + * @param array $fields List of object variables to check against. + * + * @return boolean True if searchTerm is in object, false otherwise. + */ + public static function checkNoHtml($object, $searchTerm, $fields) + { + $searchRegex = array( + '#]*>.*?#si', + '#]*>.*?#si', + '##si', + '#<[^>]*>#i' + ); + $terms = explode(' ', $searchTerm); + + if (empty($fields)) + { + return false; + } + + foreach ($fields as $field) + { + if (!isset($object->$field)) + { + continue; + } + + $text = self::remove_accents($object->$field); + + foreach ($searchRegex as $regex) + { + $text = preg_replace($regex, '', $text); + } + + foreach ($terms as $term) + { + $term = self::remove_accents($term); + + if (StringHelper::stristr($text, $term) !== false) + { + return true; + } + } + } + + return false; + } + + /** + * Transliterates given text to ASCII. + * + * @param string $str String to remove accents from. + * + * @return string + * + * @since 3.2 + */ + public static function remove_accents($str) + { + $str = JLanguageTransliterate::utf8_latin_to_ascii($str); + + // @TODO: remove other prefixes as well? + return preg_replace("/[\"'^]([a-z])/ui", '\1', $str); + } + + /** + * Returns substring of characters around a searchword. + * + * @param string $text The source string. + * @param integer $searchword Number of chars to return. + * + * @return string + * + * @since 1.5 + */ + public static function _smartSubstr($text, $searchword) + { + $lang = JFactory::getLanguage(); + $length = $lang->getSearchDisplayedCharactersNumber(); + $ltext = self::remove_accents($text); + $textlen = StringHelper::strlen($ltext); + $lsearchword = StringHelper::strtolower(self::remove_accents($searchword)); + $wordfound = false; + $pos = 0; + $length = $length > $textlen ? $textlen : $length; + + while ($wordfound === false && $pos + $length < $textlen) + { + if (($wordpos = @StringHelper::strpos($ltext, ' ', $pos + $length)) !== false) + { + $chunk_size = $wordpos - $pos; + } + else + { + $chunk_size = $length; + } + + $chunk = StringHelper::substr($ltext, $pos, $chunk_size); + $wordfound = StringHelper::strpos(StringHelper::strtolower($chunk), $lsearchword); + + if ($wordfound === false) + { + $pos += $chunk_size + 1; + } + } + + if ($wordfound !== false) + { + // Check if original text is different length than searched text (changed by function self::remove_accents) + // Displayed text only, adjust $chunk_size + if ($pos === 0) + { + $iOriLen = StringHelper::strlen(StringHelper::substr($text, 0, $pos + $chunk_size)); + $iModLen = StringHelper::strlen(self::remove_accents(StringHelper::substr($text, 0, $pos + $chunk_size))); + + $chunk_size += $iOriLen - $iModLen; + } + else + { + $iOriSkippedLen = StringHelper::strlen(StringHelper::substr($text, 0, $pos)); + $iModSkippedLen = StringHelper::strlen(self::remove_accents(StringHelper::substr($text, 0, $pos))); + + // Adjust starting position $pos + if ($iOriSkippedLen !== $iModSkippedLen) + { + $pos += $iOriSkippedLen - $iModSkippedLen; + } + + $iOriReturnLen = StringHelper::strlen(StringHelper::substr($text, $pos, $chunk_size)); + $iModReturnLen = StringHelper::strlen(self::remove_accents(StringHelper::substr($text, $pos, $chunk_size))); + + if ($iOriReturnLen !== $iModReturnLen) + { + $chunk_size += $iOriReturnLen - $iModReturnLen; + } + } + + $sPre = $pos > 0 ? '... ' : ''; + $sPost = ($pos + $chunk_size) >= StringHelper::strlen($text) ? '' : ' ...'; + + return $sPre . StringHelper::substr($text, $pos, $chunk_size) . $sPost; + } + else + { + if (($wordpos = @StringHelper::strpos($text, ' ', $length)) !== false) + { + return StringHelper::substr($text, 0, $wordpos) . ' ...'; + } + else + { + return StringHelper::substr($text, 0, $length); + } + } + } +} diff --git a/Sites/pages/administrator/components/com_search/helpers/site.php b/Sites/pages/administrator/components/com_search/helpers/site.php new file mode 100644 index 00000000..ea98e36c --- /dev/null +++ b/Sites/pages/administrator/components/com_search/helpers/site.php @@ -0,0 +1,44 @@ + +
    + + + + + + + + + + + + + +
    diff --git a/Sites/pages/administrator/components/com_search/models/searches.php b/Sites/pages/administrator/components/com_search/models/searches.php new file mode 100644 index 00000000..d3cb76f9 --- /dev/null +++ b/Sites/pages/administrator/components/com_search/models/searches.php @@ -0,0 +1,191 @@ +setState('filter.search', $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search', '', 'string')); + + // Special state for toggle results button. + $this->setState('show_results', $this->getUserStateFromRequest($this->context . '.show_results', 'show_results', 1, 'int')); + + // Load the parameters. + $params = JComponentHelper::getParams('com_search'); + $this->setState('params', $params); + + // List state information. + parent::populateState($ordering, $direction); + } + + /** + * Method to get a store id based on model configuration state. + * + * This is necessary because the model is used by the component and + * different modules that might need different sets of data or different + * ordering requirements. + * + * @param string $id A prefix for the store id. + * + * @return string A store id. + * + * @since 1.6 + */ + protected function getStoreId($id = '') + { + // Compile the store id. + $id .= ':' . $this->getState('show_results'); + $id .= ':' . $this->getState('filter.search'); + + return parent::getStoreId($id); + } + + /** + * Build an SQL query to load the list data. + * + * @return JDatabaseQuery + * + * @since 1.6 + */ + protected function getListQuery() + { + // Create a new query object. + $db = $this->getDbo(); + $query = $db->getQuery(true); + + // Select the required fields from the table. + $query->select( + $this->getState( + 'list.select', + 'a.*' + ) + ); + $query->from($db->quoteName('#__core_log_searches', 'a')); + + // Filter by search in title + if ($search = $this->getState('filter.search')) + { + $search = $db->quote('%' . str_replace(' ', '%', $db->escape(trim($search), true) . '%')); + $query->where($db->quoteName('a.search_term') . ' LIKE ' . $search); + } + + // Add the list ordering clause. + $query->order($db->escape($this->getState('list.ordering', 'a.hits')) . ' ' . $db->escape($this->getState('list.direction', 'ASC'))); + + return $query; + } + + /** + * Override the parent getItems to inject optional data. + * + * @return mixed An array of objects on success, false on failure. + * + * @since 1.6 + */ + public function getItems() + { + $items = parent::getItems(); + + // Determine if number of results for search item should be calculated + // by default it is `off` as it is highly query intensive + if ($this->getState('show_results')) + { + JPluginHelper::importPlugin('search'); + $app = JFactory::getApplication(); + + if (!class_exists('JSite')) + { + // This fools the routers in the search plugins into thinking it's in the frontend + JLoader::register('JSite', JPATH_ADMINISTRATOR . '/components/com_search/helpers/site.php'); + } + + foreach ($items as &$item) + { + $results = $app->triggerEvent('onContentSearch', array($item->search_term)); + $item->returns = 0; + + foreach ($results as $result) + { + $item->returns += count($result); + } + } + } + + return $items; + } + + /** + * Method to reset the search log table. + * + * @return boolean + * + * @since 1.6 + */ + public function reset() + { + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->delete($db->quoteName('#__core_log_searches')); + $db->setQuery($query); + + try + { + $db->execute(); + } + catch (RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + + return true; + } +} diff --git a/Sites/pages/administrator/components/com_search/search.php b/Sites/pages/administrator/components/com_search/search.php new file mode 100644 index 00000000..50818f40 --- /dev/null +++ b/Sites/pages/administrator/components/com_search/search.php @@ -0,0 +1,19 @@ +authorise('core.manage', 'com_search')) +{ + throw new JAccessExceptionNotallowed(JText::_('JERROR_ALERTNOAUTHOR'), 403); +} + +$controller = JControllerLegacy::getInstance('Search'); +$controller->execute(JFactory::getApplication()->input->get('task')); +$controller->redirect(); diff --git a/Sites/pages/administrator/components/com_search/search.xml b/Sites/pages/administrator/components/com_search/search.xml new file mode 100644 index 00000000..6a55617d --- /dev/null +++ b/Sites/pages/administrator/components/com_search/search.xml @@ -0,0 +1,38 @@ + + + com_search + Joomla! Project + April 2006 + (C) 2005 - 2020 Open Source Matters. All rights reserved. + GNU General Public License version 2 or later; see LICENSE.txt + admin@joomla.org + www.joomla.org + 3.0.0 + COM_SEARCH_XML_DESCRIPTION + + controller.php + router.php + search.php + models + views + + + language/en-GB.com_search.ini + + + Search + + config.xml + controller.php + search.php + controllers + helpers + models + views + + + language/en-GB.com_search.ini + language/en-GB.com_search.sys.ini + + + diff --git a/Sites/pages/administrator/components/com_search/views/searches/tmpl/default.php b/Sites/pages/administrator/components/com_search/views/searches/tmpl/default.php new file mode 100644 index 00000000..8a055320 --- /dev/null +++ b/Sites/pages/administrator/components/com_search/views/searches/tmpl/default.php @@ -0,0 +1,88 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +?> +
    + sidebar)) : ?> +
    + sidebar; ?> +
    +
    + +
    + + $this, 'options' => array('filterButton' => false))); ?> +
    + items)) : ?> +
    + +
    + + + + + + + + + + + + + + + + items as $i => $item) : ?> + + + + state->get('show_results')) : ?> + + + + + + + + +
    + + + + + +
    + pagination->getListFooter(); ?> +
    + escape($item->search_term); ?> + + hits; ?> + + + returns; ?> + + +
    + + + + +
    + diff --git a/Sites/pages/administrator/components/com_search/views/searches/tmpl/default.xml b/Sites/pages/administrator/components/com_search/views/searches/tmpl/default.xml new file mode 100644 index 00000000..ff4f089e --- /dev/null +++ b/Sites/pages/administrator/components/com_search/views/searches/tmpl/default.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/Sites/pages/administrator/components/com_search/views/searches/view.html.php b/Sites/pages/administrator/components/com_search/views/searches/view.html.php new file mode 100644 index 00000000..ff1f6299 --- /dev/null +++ b/Sites/pages/administrator/components/com_search/views/searches/view.html.php @@ -0,0 +1,104 @@ +items = $this->get('Items'); + $this->pagination = $this->get('Pagination'); + $this->state = $this->get('State'); + $this->filterForm = $this->get('FilterForm'); + $this->activeFilters = $this->get('ActiveFilters'); + $this->enabled = $this->state->params->get('enabled'); + $this->canDo = JHelperContent::getActions('com_search'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + // Check if plugin is enabled + if ($this->enabled) + { + $app->enqueueMessage(JText::_('COM_SEARCH_LOGGING_ENABLED'), 'notice'); + } + else + { + $app->enqueueMessage(JText::_('COM_SEARCH_LOGGING_DISABLED'), 'warning'); + } + + $this->addToolbar(); + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + $canDo = $this->canDo; + + JToolbarHelper::title(JText::_('COM_SEARCH_MANAGER_SEARCHES'), 'search'); + + $showResults = $this->state->get('show_results', 1, 'int'); + + if ($showResults === 0) + { + JToolbarHelper::custom('searches.toggleresults', 'zoom-in.png', null, 'COM_SEARCH_SHOW_SEARCH_RESULTS', false); + } + else + { + JToolbarHelper::custom('searches.toggleresults', 'zoom-out.png', null, 'COM_SEARCH_HIDE_SEARCH_RESULTS', false); + } + + if ($canDo->get('core.edit.state')) + { + JToolbarHelper::custom('searches.reset', 'refresh.png', 'refresh_f2.png', 'JSEARCH_RESET', false); + } + + JToolbarHelper::divider(); + + if ($canDo->get('core.admin') || $canDo->get('core.options')) + { + JToolbarHelper::preferences('com_search'); + } + + JToolbarHelper::divider(); + JToolbarHelper::help('JHELP_COMPONENTS_SEARCH'); + } +} diff --git a/Sites/pages/administrator/components/com_tags/access.xml b/Sites/pages/administrator/components/com_tags/access.xml new file mode 100644 index 00000000..c4f8083a --- /dev/null +++ b/Sites/pages/administrator/components/com_tags/access.xml @@ -0,0 +1,12 @@ + + +
    + + + + + + + +
    +
    diff --git a/Sites/pages/administrator/components/com_tags/config.xml b/Sites/pages/administrator/components/com_tags/config.xml new file mode 100644 index 00000000..30623cfa --- /dev/null +++ b/Sites/pages/administrator/components/com_tags/config.xml @@ -0,0 +1,437 @@ + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + +
    + +
    + + + + + + + +
    + +
    + + +
    +
    diff --git a/Sites/pages/administrator/components/com_tags/controller.php b/Sites/pages/administrator/components/com_tags/controller.php new file mode 100644 index 00000000..a1e93a77 --- /dev/null +++ b/Sites/pages/administrator/components/com_tags/controller.php @@ -0,0 +1,50 @@ +input->get('view', 'tags'); + $layout = $this->input->get('layout', 'default'); + $id = $this->input->getInt('id'); + + // Check for edit form. + if ($view == 'tag' && $layout == 'edit' && !$this->checkEditId('com_tags.edit.tag', $id)) + { + // Somehow the person just went to the form - we don't allow that. + $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id)); + $this->setMessage($this->getError(), 'error'); + $this->setRedirect(JRoute::_('index.php?option=com_tags&view=tags', false)); + + return false; + } + + parent::display(); + + return $this; + } +} diff --git a/Sites/pages/administrator/components/com_tags/controllers/tag.php b/Sites/pages/administrator/components/com_tags/controllers/tag.php new file mode 100644 index 00000000..8b4f9dfa --- /dev/null +++ b/Sites/pages/administrator/components/com_tags/controllers/tag.php @@ -0,0 +1,72 @@ +authorise('core.create', 'com_tags'); + } + + /** + * Method to check if you can edit a record. + * + * @param array $data An array of input data. + * @param string $key The name of the key for the primary key. + * + * @return boolean + * + * @since 3.1 + */ + protected function allowEdit($data = array(), $key = 'id') + { + // Since there is no asset tracking and no categories, revert to the component permissions. + return parent::allowEdit($data, $key); + } + + /** + * Method to run batch operations. + * + * @param object $model The model. + * + * @return boolean True if successful, false otherwise and internal error is set. + * + * @since 3.1 + */ + public function batch($model = null) + { + $this->checkToken(); + + // Set the model + $model = $this->getModel('Tag'); + + // Preset the redirect + $this->setRedirect('index.php?option=com_tags&view=tags'); + + return parent::batch($model); + } +} diff --git a/Sites/pages/administrator/components/com_tags/controllers/tags.php b/Sites/pages/administrator/components/com_tags/controllers/tags.php new file mode 100644 index 00000000..94f35155 --- /dev/null +++ b/Sites/pages/administrator/components/com_tags/controllers/tags.php @@ -0,0 +1,65 @@ + true)) + { + return parent::getModel($name, $prefix, $config); + } + + /** + * Rebuild the nested set tree. + * + * @return boolean False on failure or error, true on success. + * + * @since 3.1 + */ + public function rebuild() + { + $this->checkToken(); + + $this->setRedirect(JRoute::_('index.php?option=com_tags&view=tags', false)); + + $model = $this->getModel(); + + if ($model->rebuild()) + { + // Rebuild succeeded. + $this->setMessage(JText::_('COM_TAGS_REBUILD_SUCCESS')); + + return true; + } + else + { + // Rebuild failed. + $this->setMessage(JText::_('COM_TAGS_REBUILD_FAILURE')); + + return false; + } + } +} diff --git a/Sites/pages/administrator/components/com_tags/helpers/tags.php b/Sites/pages/administrator/components/com_tags/helpers/tags.php new file mode 100644 index 00000000..b674de42 --- /dev/null +++ b/Sites/pages/administrator/components/com_tags/helpers/tags.php @@ -0,0 +1,63 @@ +/language + $lang->load($component, JPATH_BASE, null, false, true) + || $lang->load($component, JPath::clean(JPATH_ADMINISTRATOR . '/components/' . $component), null, false, true); + } + } + } + } +} diff --git a/Sites/pages/administrator/components/com_tags/models/forms/filter_tags.xml b/Sites/pages/administrator/components/com_tags/models/forms/filter_tags.xml new file mode 100644 index 00000000..58641d6a --- /dev/null +++ b/Sites/pages/administrator/components/com_tags/models/forms/filter_tags.xml @@ -0,0 +1,96 @@ + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    diff --git a/Sites/pages/administrator/components/com_tags/models/forms/tag.xml b/Sites/pages/administrator/components/com_tags/models/forms/tag.xml new file mode 100644 index 00000000..028e184f --- /dev/null +++ b/Sites/pages/administrator/components/com_tags/models/forms/tag.xml @@ -0,0 +1,367 @@ + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + +
    +
    + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + +
    + + + + + + + + + + +
    +
    + diff --git a/Sites/pages/administrator/components/com_tags/models/tag.php b/Sites/pages/administrator/components/com_tags/models/tag.php new file mode 100644 index 00000000..d2e0f130 --- /dev/null +++ b/Sites/pages/administrator/components/com_tags/models/tag.php @@ -0,0 +1,439 @@ + 'batchAccess', + 'language_id' => 'batchLanguage', + ); + + /** + * Method to test whether a record can be deleted. + * + * @param object $record A record object. + * + * @return boolean True if allowed to delete the record. Defaults to the permission set in the component. + * + * @since 3.1 + */ + protected function canDelete($record) + { + if (empty($record->id) || $record->published != -2) + { + return false; + } + + return parent::canDelete($record); + } + + /** + * Method to get a table object, load it if necessary. + * + * @param string $type The table name. Optional. + * @param string $prefix The class prefix. Optional. + * @param array $config Configuration array for model. Optional. + * + * @return JTable A JTable object + * + * @since 3.1 + */ + public function getTable($type = 'Tag', $prefix = 'TagsTable', $config = array()) + { + return JTable::getInstance($type, $prefix, $config); + } + + /** + * Auto-populate the model state. + * + * @note Calling getState in this method will result in recursion. + * + * @return void + * + * @since 3.1 + */ + protected function populateState() + { + $app = JFactory::getApplication('administrator'); + + $parentId = $app->input->getInt('parent_id'); + $this->setState('tag.parent_id', $parentId); + + // Load the User state. + $pk = $app->input->getInt('id'); + $this->setState($this->getName() . '.id', $pk); + + // Load the parameters. + $params = JComponentHelper::getParams('com_tags'); + $this->setState('params', $params); + } + + /** + * Method to get a tag. + * + * @param integer $pk An optional id of the object to get, otherwise the id from the model state is used. + * + * @return mixed Tag data object on success, false on failure. + * + * @since 3.1 + */ + public function getItem($pk = null) + { + if ($result = parent::getItem($pk)) + { + // Prime required properties. + if (empty($result->id)) + { + $result->parent_id = $this->getState('tag.parent_id'); + } + + // Convert the metadata field to an array. + $registry = new Registry($result->metadata); + $result->metadata = $registry->toArray(); + + // Convert the images field to an array. + $registry = new Registry($result->images); + $result->images = $registry->toArray(); + + // Convert the urls field to an array. + $registry = new Registry($result->urls); + $result->urls = $registry->toArray(); + + // Convert the created and modified dates to local user time for display in the form. + $tz = new DateTimeZone(JFactory::getApplication()->get('offset')); + + if ((int) $result->created_time) + { + $date = new JDate($result->created_time); + $date->setTimezone($tz); + $result->created_time = $date->toSql(true); + } + else + { + $result->created_time = null; + } + + if ((int) $result->modified_time) + { + $date = new JDate($result->modified_time); + $date->setTimezone($tz); + $result->modified_time = $date->toSql(true); + } + else + { + $result->modified_time = null; + } + } + + return $result; + } + + /** + * Method to get the row form. + * + * @param array $data Data for the form. + * @param boolean $loadData True if the form is to load its own data (default case), false if not. + * + * @return mixed A JForm object on success, false on failure + * + * @since 3.1 + */ + public function getForm($data = array(), $loadData = true) + { + $jinput = JFactory::getApplication()->input; + + // Get the form. + $form = $this->loadForm('com_tags.tag', 'tag', array('control' => 'jform', 'load_data' => $loadData)); + + if (empty($form)) + { + return false; + } + + $user = JFactory::getUser(); + + if (!$user->authorise('core.edit.state', 'com_tags' . $jinput->get('id'))) + { + // Disable fields for display. + $form->setFieldAttribute('ordering', 'disabled', 'true'); + $form->setFieldAttribute('published', 'disabled', 'true'); + + // Disable fields while saving. + // The controller has already verified this is a record you can edit. + $form->setFieldAttribute('ordering', 'filter', 'unset'); + $form->setFieldAttribute('published', 'filter', 'unset'); + } + + return $form; + } + + /** + * Method to get the data that should be injected in the form. + * + * @return mixed The data for the form. + * + * @since 3.1 + */ + protected function loadFormData() + { + // Check the session for previously entered form data. + $data = JFactory::getApplication()->getUserState('com_tags.edit.tag.data', array()); + + if (empty($data)) + { + $data = $this->getItem(); + } + + $this->preprocessData('com_tags.tag', $data); + + return $data; + } + + /** + * Method to save the form data. + * + * @param array $data The form data. + * + * @return boolean True on success. + * + * @since 3.1 + */ + public function save($data) + { + $dispatcher = JEventDispatcher::getInstance(); + $table = $this->getTable(); + $input = JFactory::getApplication()->input; + $pk = (!empty($data['id'])) ? $data['id'] : (int) $this->getState($this->getName() . '.id'); + $isNew = true; + $context = $this->option . '.' . $this->name; + + // Include the plugins for the save events. + JPluginHelper::importPlugin($this->events_map['save']); + + // Load the row if saving an existing tag. + if ($pk > 0) + { + $table->load($pk); + $isNew = false; + } + + // Set the new parent id if parent id not matched OR while New/Save as Copy . + if ($table->parent_id != $data['parent_id'] || $data['id'] == 0) + { + $table->setLocation($data['parent_id'], 'last-child'); + } + + if (isset($data['images']) && is_array($data['images'])) + { + $registry = new Registry($data['images']); + $data['images'] = (string) $registry; + } + + if (isset($data['urls']) && is_array($data['urls'])) + { + $registry = new Registry($data['urls']); + $data['urls'] = (string) $registry; + } + + // Alter the title for save as copy + if ($input->get('task') == 'save2copy') + { + $origTable = $this->getTable(); + $origTable->load($input->getInt('id')); + + if ($data['title'] == $origTable->title) + { + list($title, $alias) = $this->generateNewTitle($data['parent_id'], $data['alias'], $data['title']); + $data['title'] = $title; + $data['alias'] = $alias; + } + elseif ($data['alias'] == $origTable->alias) + { + $data['alias'] = ''; + } + + $data['published'] = 0; + } + + // Bind the data. + if (!$table->bind($data)) + { + $this->setError($table->getError()); + + return false; + } + + // Bind the rules. + if (isset($data['rules'])) + { + $rules = new JAccessRules($data['rules']); + $table->setRules($rules); + } + + // Check the data. + if (!$table->check()) + { + $this->setError($table->getError()); + + return false; + } + + // Trigger the before save event. + $result = $dispatcher->trigger($this->event_before_save, array($context, &$table, $isNew)); + + if (in_array(false, $result, true)) + { + $this->setError($table->getError()); + + return false; + } + + // Store the data. + if (!$table->store()) + { + $this->setError($table->getError()); + + return false; + } + + // Trigger the after save event. + $dispatcher->trigger($this->event_after_save, array($context, &$table, $isNew)); + + // Rebuild the path for the tag: + if (!$table->rebuildPath($table->id)) + { + $this->setError($table->getError()); + + return false; + } + + // Rebuild the paths of the tag's children: + if (!$table->rebuild($table->id, $table->lft, $table->level, $table->path)) + { + $this->setError($table->getError()); + + return false; + } + + $this->setState($this->getName() . '.id', $table->id); + + // Clear the cache + $this->cleanCache(); + + return true; + } + + /** + * Method rebuild the entire nested set tree. + * + * @return boolean False on failure or error, true otherwise. + * + * @since 3.1 + */ + public function rebuild() + { + // Get an instance of the table object. + $table = $this->getTable(); + + if (!$table->rebuild()) + { + $this->setError($table->getError()); + + return false; + } + + // Clear the cache + $this->cleanCache(); + + return true; + } + + /** + * Method to save the reordered nested set tree. + * First we save the new order values in the lft values of the changed ids. + * Then we invoke the table rebuild to implement the new ordering. + * + * @param array $idArray An array of primary key ids. + * @param integer $lftArray The lft value + * + * @return boolean False on failure or error, True otherwise + * + * @since 3.1 + */ + public function saveorder($idArray = null, $lftArray = null) + { + // Get an instance of the table object. + $table = $this->getTable(); + + if (!$table->saveorder($idArray, $lftArray)) + { + $this->setError($table->getError()); + + return false; + } + + // Clear the cache + $this->cleanCache(); + + return true; + } + + /** + * Method to change the title & alias. + * + * @param integer $parentId The id of the parent. + * @param string $alias The alias. + * @param string $title The title. + * + * @return array Contains the modified title and alias. + * + * @since 3.1 + */ + protected function generateNewTitle($parentId, $alias, $title) + { + // Alter the title & alias + $table = $this->getTable(); + + while ($table->load(array('alias' => $alias, 'parent_id' => $parentId))) + { + $title = ($table->title != $title) ? $title : StringHelper::increment($title); + $alias = StringHelper::increment($alias, 'dash'); + } + + return array($title, $alias); + } +} diff --git a/Sites/pages/administrator/components/com_tags/models/tags.php b/Sites/pages/administrator/components/com_tags/models/tags.php new file mode 100644 index 00000000..3d581e2d --- /dev/null +++ b/Sites/pages/administrator/components/com_tags/models/tags.php @@ -0,0 +1,385 @@ +getUserStateFromRequest($this->context . '.filter.search', 'filter_search'); + $this->setState('filter.search', $search); + + $level = $this->getUserStateFromRequest($this->context . '.filter.level', 'filter_level', ''); + $this->setState('filter.level', $level); + + $access = $this->getUserStateFromRequest($this->context . '.filter.access', 'filter_access', ''); + $this->setState('filter.access', $access); + + $published = $this->getUserStateFromRequest($this->context . '.filter.published', 'filter_published', ''); + $this->setState('filter.published', $published); + + $language = $this->getUserStateFromRequest($this->context . '.filter.language', 'filter_language', ''); + $this->setState('filter.language', $language); + + $extension = $this->getUserStateFromRequest($this->context . '.filter.extension', 'extension', 'com_content', 'cmd'); + + $this->setState('filter.extension', $extension); + $parts = explode('.', $extension); + + // Extract the component name + $this->setState('filter.component', $parts[0]); + + // Extract the optional section name + $this->setState('filter.section', (count($parts) > 1) ? $parts[1] : null); + + // Load the parameters. + $params = JComponentHelper::getParams('com_tags'); + $this->setState('params', $params); + + // List state information. + parent::populateState($ordering, $direction); + } + + /** + * Method to get a store id based on model configuration state. + * + * This is necessary because the model is used by the component and + * different modules that might need different sets of data or different + * ordering requirements. + * + * @param string $id A prefix for the store id. + * + * @return string A store id. + * + * @since 3.1 + */ + protected function getStoreId($id = '') + { + // Compile the store id. + $id .= ':' . $this->getState('filter.extension'); + $id .= ':' . $this->getState('filter.search'); + $id .= ':' . $this->getState('filter.level'); + $id .= ':' . $this->getState('filter.access'); + $id .= ':' . $this->getState('filter.published'); + $id .= ':' . $this->getState('filter.language'); + + return parent::getStoreId($id); + } + + /** + * Method to create a query for a list of items. + * + * @return string + * + * @since 3.1 + */ + protected function getListQuery() + { + // Create a new query object. + $db = $this->getDbo(); + $query = $db->getQuery(true); + $user = JFactory::getUser(); + + // Select the required fields from the table. + $query->select( + $this->getState( + 'list.select', + 'a.id, a.title, a.alias, a.note, a.published, a.access, a.description' . + ', a.checked_out, a.checked_out_time, a.created_user_id' . + ', a.path, a.parent_id, a.level, a.lft, a.rgt' . + ', a.language' + ) + ); + $query->from('#__tags AS a') + ->where('a.alias <> ' . $db->quote('root')); + + // Join over the language + $query->select('l.title AS language_title, l.image AS language_image') + ->join('LEFT', $db->quoteName('#__languages') . ' AS l ON l.lang_code = a.language'); + + // Join over the users for the checked out user. + $query->select('uc.name AS editor') + ->join('LEFT', '#__users AS uc ON uc.id=a.checked_out'); + + // Join over the users for the author. + $query->select('ua.name AS author_name') + ->join('LEFT', '#__users AS ua ON ua.id = a.created_user_id') + + ->select('ug.title AS access_title') + ->join('LEFT', '#__viewlevels AS ug on ug.id = a.access'); + + // Filter on the level. + if ($level = $this->getState('filter.level')) + { + $query->where('a.level <= ' . (int) $level); + } + + // Filter by access level. + if ($access = $this->getState('filter.access')) + { + $query->where('a.access = ' . (int) $access); + } + + // Implement View Level Access + if (!$user->authorise('core.admin')) + { + $groups = implode(',', $user->getAuthorisedViewLevels()); + $query->where('a.access IN (' . $groups . ')'); + } + + // Filter by published state + $published = $this->getState('filter.published'); + + if (is_numeric($published)) + { + $query->where('a.published = ' . (int) $published); + } + elseif ($published === '') + { + $query->where('(a.published IN (0, 1))'); + } + + // Filter by search in title + $search = $this->getState('filter.search'); + + if (!empty($search)) + { + if (stripos($search, 'id:') === 0) + { + $query->where('a.id = ' . (int) substr($search, 3)); + } + else + { + $search = $db->quote('%' . str_replace(' ', '%', $db->escape(trim($search), true) . '%')); + $query->where('(a.title LIKE ' . $search . ' OR a.alias LIKE ' . $search . ' OR a.note LIKE ' . $search . ')'); + } + } + + // Filter on the language. + if ($language = $this->getState('filter.language')) + { + $query->where('a.language = ' . $db->quote($language)); + } + + // Add the list ordering clause + $listOrdering = $this->getState('list.ordering', 'a.lft'); + $listDirn = $db->escape($this->getState('list.direction', 'ASC')); + + if ($listOrdering == 'a.access') + { + $query->order('a.access ' . $listDirn . ', a.lft ' . $listDirn); + } + else + { + $query->order($db->escape($listOrdering) . ' ' . $listDirn); + } + + return $query; + } + + /** + * Method override to check-in a record or an array of record + * + * @param mixed $pks The ID of the primary key or an array of IDs + * + * @return mixed Boolean false if there is an error, otherwise the count of records checked in. + * + * @since 3.0.1 + */ + public function checkin($pks = array()) + { + $pks = (array) $pks; + $table = $this->getTable(); + $count = 0; + + if (empty($pks)) + { + $pks = array((int) $this->getState($this->getName() . '.id')); + } + + // Check in all items. + foreach ($pks as $pk) + { + if ($table->load($pk)) + { + if ($table->checked_out > 0) + { + // Only attempt to check the row in if it exists. + if ($pk) + { + $user = JFactory::getUser(); + + // Get an instance of the row to checkin. + $table = $this->getTable(); + + if (!$table->load($pk)) + { + $this->setError($table->getError()); + + return false; + } + + // Check if this is the user having previously checked out the row. + if ($table->checked_out > 0 && $table->checked_out != $user->get('id') && !$user->authorise('core.admin', 'com_checkin')) + { + $this->setError(JText::_('JLIB_APPLICATION_ERROR_CHECKIN_USER_MISMATCH')); + + return false; + } + + // Attempt to check the row in. + if (!$table->checkin($pk)) + { + $this->setError($table->getError()); + + return false; + } + } + + $count++; + } + } + else + { + $this->setError($table->getError()); + + return false; + } + } + + return $count; + } + + /** + * Method to get a table object, load it if necessary. + * + * @param string $type The table name. Optional. + * @param string $prefix The class prefix. Optional. + * @param array $config Configuration array for model. Optional. + * + * @return JTable A JTable object + * + * @since 3.1 + */ + public function getTable($type = 'Tag', $prefix = 'TagsTable', $config = array()) + { + return JTable::getInstance($type, $prefix, $config); + } + + /** + * Method to get an array of data items. + * + * @return mixed An array of data items on success, false on failure. + * + * @since 3.0.1 + */ + public function getItems() + { + $items = parent::getItems(); + + if ($items != false) + { + $extension = $this->getState('filter.extension'); + + $this->countItems($items, $extension); + } + + return $items; + } + + /** + * Method to load the countItems method from the extensions + * + * @param stdClass[] &$items The category items + * @param string $extension The category extension + * + * @return void + * + * @since 3.5 + */ + public function countItems(&$items, $extension) + { + $parts = explode('.', $extension); + $component = $parts[0]; + $section = null; + + if (count($parts) < 2) + { + return; + } + + // Try to find the component helper. + $eName = str_replace('com_', '', $component); + $file = JPath::clean(JPATH_ADMINISTRATOR . '/components/' . $component . '/helpers/' . $eName . '.php'); + + if (file_exists($file)) + { + $prefix = ucfirst(str_replace('com_', '', $component)); + $cName = $prefix . 'Helper'; + + JLoader::register($cName, $file); + + if (class_exists($cName) && is_callable(array($cName, 'countTagItems'))) + { + $cName::countTagItems($items, $extension); + } + } + } +} diff --git a/Sites/pages/administrator/components/com_tags/tables/tag.php b/Sites/pages/administrator/components/com_tags/tables/tag.php new file mode 100644 index 00000000..06fada99 --- /dev/null +++ b/Sites/pages/administrator/components/com_tags/tables/tag.php @@ -0,0 +1,277 @@ + 'com_tags.tag')); + } + + /** + * Overloaded bind function + * + * @param array $array Named array + * @param mixed $ignore An optional array or space separated list of properties + * to ignore while binding. + * + * @return mixed Null if operation was satisfactory, otherwise returns an error string + * + * @see JTable::bind + * @since 3.1 + */ + public function bind($array, $ignore = '') + { + if (isset($array['params']) && is_array($array['params'])) + { + $registry = new Registry($array['params']); + $array['params'] = (string) $registry; + } + + if (isset($array['metadata']) && is_array($array['metadata'])) + { + $registry = new Registry($array['metadata']); + $array['metadata'] = (string) $registry; + } + + if (isset($array['urls']) && is_array($array['urls'])) + { + $registry = new Registry($array['urls']); + $array['urls'] = (string) $registry; + } + + if (isset($array['images']) && is_array($array['images'])) + { + $registry = new Registry($array['images']); + $array['images'] = (string) $registry; + } + + return parent::bind($array, $ignore); + } + + /** + * Overloaded check method to ensure data integrity. + * + * @return boolean True on success. + * + * @since 3.1 + * @throws UnexpectedValueException + */ + public function check() + { + // Check for valid name. + if (trim($this->title) == '') + { + throw new UnexpectedValueException(sprintf('The title is empty')); + } + + if (empty($this->alias)) + { + $this->alias = $this->title; + } + + $this->alias = JApplicationHelper::stringURLSafe($this->alias, $this->language); + + if (trim(str_replace('-', '', $this->alias)) == '') + { + $this->alias = JFactory::getDate()->format('Y-m-d-H-i-s'); + } + + // Check the publish down date is not earlier than publish up. + if ((int) $this->publish_down > 0 && $this->publish_down < $this->publish_up) + { + throw new UnexpectedValueException(sprintf('End publish date is before start publish date.')); + } + + // Clean up keywords -- eliminate extra spaces between phrases + // and cr (\r) and lf (\n) characters from string + if (!empty($this->metakey)) + { + // Only process if not empty + // Define array of characters to remove + $bad_characters = array("\n", "\r", "\"", '<', '>'); + + // Remove bad characters + $after_clean = StringHelper::str_ireplace($bad_characters, '', $this->metakey); + + // Create array using commas as delimiter + $keys = explode(',', $after_clean); + $clean_keys = array(); + + foreach ($keys as $key) + { + if (trim($key)) + { + // Ignore blank keywords + $clean_keys[] = trim($key); + } + } + + // Put array back together delimited by ", " + $this->metakey = implode(', ', $clean_keys); + } + + // Clean up description -- eliminate quotes and <> brackets + if (!empty($this->metadesc)) + { + // Only process if not empty + $bad_characters = array("\"", '<', '>'); + $this->metadesc = StringHelper::str_ireplace($bad_characters, '', $this->metadesc); + } + + // Not Null sanity check + $date = JFactory::getDate(); + + if (empty($this->params)) + { + $this->params = '{}'; + } + + if (empty($this->metadesc)) + { + $this->metadesc = ''; + } + + if (empty($this->metakey)) + { + $this->metakey = ''; + } + + if (empty($this->metadata)) + { + $this->metadata = '{}'; + } + + if (empty($this->urls)) + { + $this->urls = '{}'; + } + + if (empty($this->images)) + { + $this->images = '{}'; + } + + if (!(int) $this->checked_out_time) + { + $this->checked_out_time = $date->toSql(); + } + + if (!(int) $this->modified_time) + { + $this->modified_time = $date->toSql(); + } + + if (!(int) $this->modified_time) + { + $this->modified_time = $date->toSql(); + } + + if (!(int) $this->publish_up) + { + $this->publish_up = $date->toSql(); + } + + if (!(int) $this->publish_down) + { + $this->publish_down = $date->toSql(); + } + + return true; + } + + /** + * Overriden JTable::store to set modified data and user id. + * + * @param boolean $updateNulls True to update fields even if they are null. + * + * @return boolean True on success. + * + * @since 3.1 + */ + public function store($updateNulls = false) + { + $date = JFactory::getDate(); + $user = JFactory::getUser(); + + $this->modified_time = $date->toSql(); + + if ($this->id) + { + // Existing item + $this->modified_user_id = $user->get('id'); + } + else + { + // New tag. A tag created and created_by field can be set by the user, + // so we don't touch either of these if they are set. + if (!(int) $this->created_time) + { + $this->created_time = $date->toSql(); + } + + if (empty($this->created_user_id)) + { + $this->created_user_id = $user->get('id'); + } + } + + // Verify that the alias is unique + $table = JTable::getInstance('Tag', 'TagsTable', array('dbo' => $this->_db)); + + if ($table->load(array('alias' => $this->alias)) && ($table->id != $this->id || $this->id == 0)) + { + $this->setError(JText::_('COM_TAGS_ERROR_UNIQUE_ALIAS')); + + return false; + } + + return parent::store($updateNulls); + } + + /** + * Method to delete a node and, optionally, its child nodes from the table. + * + * @param integer $pk The primary key of the node to delete. + * @param boolean $children True to delete child nodes, false to move them up a level. + * + * @return boolean True on success. + * + * @since 3.1 + */ + public function delete($pk = null, $children = false) + { + $return = parent::delete($pk, $children); + + if ($return) + { + $helper = new JHelperTags; + $helper->tagDeleteInstances($pk); + } + + return $return; + } +} diff --git a/Sites/pages/administrator/components/com_tags/tags.php b/Sites/pages/administrator/components/com_tags/tags.php new file mode 100644 index 00000000..74f54288 --- /dev/null +++ b/Sites/pages/administrator/components/com_tags/tags.php @@ -0,0 +1,20 @@ +authorise('core.manage', 'com_tags')) +{ + throw new JAccessExceptionNotallowed(JText::_('JERROR_ALERTNOAUTHOR'), 403); +} + +$controller = JControllerLegacy::getInstance('Tags'); +$controller->execute(JFactory::getApplication()->input->get('task')); +$controller->redirect(); diff --git a/Sites/pages/administrator/components/com_tags/tags.xml b/Sites/pages/administrator/components/com_tags/tags.xml new file mode 100644 index 00000000..5d2a8eec --- /dev/null +++ b/Sites/pages/administrator/components/com_tags/tags.xml @@ -0,0 +1,42 @@ + + + com_tags + Joomla! Project + December 2013 + (C) 2005 - 2020 Open Source Matters. All rights reserved. + GNU General Public License version 2 or later; see LICENSE.txt + admin@joomla.org + www.joomla.org + 3.1.0 + COM_TAGS_XML_DESCRIPTION + + + controller.php + metadata.xml + newsfeeds.php + router.php + helpers + models + views + + + language/en-GB.com_tags.ini + + + + tags.php + config.xml + controller.php + controllers + helpers + models + views + + + language/en-GB.com_tags.ini + language/en-GB.com_tags.sys.ini + + com_tags + + + diff --git a/Sites/pages/administrator/components/com_tags/views/tag/tmpl/edit.php b/Sites/pages/administrator/components/com_tags/views/tag/tmpl/edit.php new file mode 100644 index 00000000..d80e5884 --- /dev/null +++ b/Sites/pages/administrator/components/com_tags/views/tag/tmpl/edit.php @@ -0,0 +1,67 @@ +addScriptDeclaration(" + Joomla.submitbutton = function(task) + { + if (task == 'tag.cancel' || document.formvalidator.isValid(document.getElementById('item-form'))) { + " . $this->form->getField('description')->save() . " + Joomla.submitform(task, document.getElementById('item-form')); + } + }; +"); + +// Fieldsets to not automatically render by /layouts/joomla/edit/params.php +$this->ignore_fieldsets = array('jmetadata'); +?> + +
    + + + +
    + 'details')); ?> + + +
    +
    +
    + form->renderField('description'); ?> +
    +
    +
    + +
    +
    + + + + + +
    +
    + +
    +
    + +
    +
    + + + +
    + + +
    diff --git a/Sites/pages/administrator/components/com_tags/views/tag/tmpl/edit_metadata.php b/Sites/pages/administrator/components/com_tags/views/tag/tmpl/edit_metadata.php new file mode 100644 index 00000000..08fd6950 --- /dev/null +++ b/Sites/pages/administrator/components/com_tags/views/tag/tmpl/edit_metadata.php @@ -0,0 +1,33 @@ + +
    + form->getLabel('metadesc'); ?> +
    + form->getInput('metadesc'); ?> +
    +
    +
    + form->getLabel('metakey'); ?> +
    + form->getInput('metakey'); ?> +
    +
    +form->getGroup('metadata') as $field) : ?> +
    + hidden) : ?> + label; ?> + +
    + input; ?> +
    +
    + diff --git a/Sites/pages/administrator/components/com_tags/views/tag/tmpl/edit_options.php b/Sites/pages/administrator/components/com_tags/views/tag/tmpl/edit_options.php new file mode 100644 index 00000000..22b69df3 --- /dev/null +++ b/Sites/pages/administrator/components/com_tags/views/tag/tmpl/edit_options.php @@ -0,0 +1,63 @@ + + 'collapse0')); + $fieldSets = $this->form->getFieldsets('params'); + $i = 0; + + foreach ($fieldSets as $name => $fieldSet) : + $label = !empty($fieldSet->label) ? $fieldSet->label : 'COM_TAGS_' . $name . '_FIELDSET_LABEL'; + echo JHtml::_('bootstrap.addSlide', 'categoryOptions', JText::_($label), 'collapse' . ($i++)); + if (isset($fieldSet->description) && trim($fieldSet->description)) : + echo '

    ' . $this->escape(JText::_($fieldSet->description)) . '

    '; + endif; + ?> + form->getFieldset($name) as $field) : ?> +
    +
    + label; ?> +
    +
    + input; ?> +
    +
    + + + +
    +
    + form->getLabel('note'); ?> +
    +
    + form->getInput('note'); ?> +
    +
    +
    +
    + form->getLabel('tag_layout'); ?> +
    +
    + form->getInput('tag_layout'); ?> +
    +
    +
    +
    + form->getLabel('tag_link_class'); ?> +
    +
    + form->getInput('tag_link_class'); ?> +
    +
    + form = $this->get('Form'); + $this->item = $this->get('Item'); + $this->state = $this->get('State'); + $this->canDo = JHelperContent::getActions('com_tags'); + $this->assoc = $this->get('Assoc'); + + $input = JFactory::getApplication()->input; + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + $input->set('hidemainmenu', true); + $this->addToolbar(); + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @since 3.1 + * + * @return void + */ + protected function addToolbar() + { + $user = JFactory::getUser(); + $userId = $user->get('id'); + $isNew = ($this->item->id == 0); + $checkedOut = !($this->item->checked_out == 0 || $this->item->checked_out == $userId); + + // Need to load the menu language file as mod_menu hasn't been loaded yet. + $lang = JFactory::getLanguage(); + $lang->load('com_tags', JPATH_BASE, null, false, true) + || $lang->load('com_tags', JPATH_ADMINISTRATOR . '/components/com_tags', null, false, true); + + // Get the results for each action. + $canDo = $this->canDo; + $title = JText::_('COM_TAGS_BASE_' . ($isNew ? 'ADD' : 'EDIT') . '_TITLE'); + + /** + * Prepare the toolbar. + * If it is new we get: `tag tag-add add` + * else we get `tag tag-edit edit` + */ + JToolbarHelper::title($title, 'tag tag-' . ($isNew ? 'add add' : 'edit edit')); + + // For new records, check the create permission. + if ($isNew) + { + JToolbarHelper::apply('tag.apply'); + JToolbarHelper::save('tag.save'); + JToolbarHelper::save2new('tag.save2new'); + JToolbarHelper::cancel('tag.cancel'); + } + + // If not checked out, can save the item. + else + { + // Since it's an existing record, check the edit permission, or fall back to edit own if the owner. + $itemEditable = $canDo->get('core.edit') || ($canDo->get('core.edit.own') && $this->item->created_user_id == $userId); + + // Can't save the record if it's checked out and editable + if (!$checkedOut && $itemEditable) + { + JToolbarHelper::apply('tag.apply'); + JToolbarHelper::save('tag.save'); + + if ($canDo->get('core.create')) + { + JToolbarHelper::save2new('tag.save2new'); + } + } + + // If an existing item, can save to a copy. + if ($canDo->get('core.create')) + { + JToolbarHelper::save2copy('tag.save2copy'); + } + + if (JComponentHelper::isEnabled('com_contenthistory') && $this->state->params->get('save_history', 0) && $itemEditable) + { + JToolbarHelper::versions('com_tags.tag', $this->item->id); + } + + JToolbarHelper::cancel('tag.cancel', 'JTOOLBAR_CLOSE'); + } + + JToolbarHelper::divider(); + JToolbarHelper::help('JHELP_COMPONENTS_TAGS_MANAGER_EDIT'); + JToolbarHelper::divider(); + } +} diff --git a/Sites/pages/administrator/components/com_tags/views/tags/tmpl/default.php b/Sites/pages/administrator/components/com_tags/views/tags/tmpl/default.php new file mode 100644 index 00000000..13209452 --- /dev/null +++ b/Sites/pages/administrator/components/com_tags/views/tags/tmpl/default.php @@ -0,0 +1,287 @@ +get('id'); +$listOrder = $this->escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$saveOrder = ($listOrder == 'a.lft' && strtolower($listDirn) == 'asc'); +$extension = $this->escape($this->state->get('filter.extension')); +$parts = explode('.', $extension); +$component = $parts[0]; +$section = null; +$mode = false; +$columns = 7; + +if (count($parts) > 1) +{ + $section = $parts[1]; + $inflector = Inflector::getInstance(); + + if (!$inflector->isPlural($section)) + { + $section = $inflector->toPlural($section); + } +} + +if ($section === 'categories') +{ + $mode = true; + $section = $component; + $component = 'com_categories'; +} + +if ($saveOrder) +{ + $saveOrderingUrl = 'index.php?option=com_tags&task=tags.saveOrderAjax'; + JHtml::_('sortablelist.sortable', 'categoryList', 'adminForm', strtolower($listDirn), $saveOrderingUrl, false, true); +} +?> +
    +sidebar)) : ?> +
    + sidebar; ?> +
    +
    + +
    + + $this)); + ?> + items)) : ?> +
    + +
    + + + + + + + + + + items[0]) && property_exists($this->items[0], 'count_published')) : ?> + + + + items[0]) && property_exists($this->items[0], 'count_unpublished')) : ?> + + + + items[0]) && property_exists($this->items[0], 'count_archived')) : ?> + + + + items[0]) && property_exists($this->items[0], 'count_trashed')) : ?> + + + + + + + + + + + + + + + + items as $i => $item) : + $orderkey = array_search($item->id, $this->ordering[$item->parent_id]); + $canCreate = $user->authorise('core.create', 'com_tags'); + $canEdit = $user->authorise('core.edit', 'com_tags'); + $canCheckin = $user->authorise('core.manage', 'com_checkin') || $item->checked_out == $user->get('id')|| $item->checked_out == 0; + $canChange = $user->authorise('core.edit.state', 'com_tags') && $canCheckin; + + // Get the parents of item for sorting + if ($item->level > 1) + { + $parentsStr = ''; + $_currentParentId = $item->parent_id; + $parentsStr = ' ' . $_currentParentId; + for ($j = 0; $j < $item->level; $j++) + { + foreach ($this->ordering as $k => $v) + { + $v = implode('-', $v); + $v = '-' . $v . '-'; + if (strpos($v, '-' . $_currentParentId . '-') !== false) + { + $parentsStr .= ' ' . $k; + $_currentParentId = $k; + break; + } + } + } + } + else + { + $parentsStr = ''; + } + ?> + + + + + + + items[0]) && property_exists($this->items[0], 'count_published')) : ?> + + + items[0]) && property_exists($this->items[0], 'count_unpublished')) : ?> + + + items[0]) && property_exists($this->items[0], 'count_archived')) : ?> + + + items[0]) && property_exists($this->items[0], 'count_trashed')) : ?> + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + state->get('list.direction'), $this->state->get('list.ordering')); ?> + + +
    + pagination->getListFooter(); ?> +
    + + + + + + + + + id); ?> + +
    + published, $i, 'tags.', $canChange); ?> + published === 2 ? 'un' : '') . 'archive', 'cb' . $i, 'tags'); + JHtml::_('actionsdropdown.' . ((int) $item->published === -2 ? 'un' : '') . 'trash', 'cb' . $i, 'tags'); + echo JHtml::_('actionsdropdown.render', $this->escape($item->title)); + } + ?> +
    +
    + $item->level)); ?> + checked_out) : ?> + editor, $item->checked_out_time, 'tags.', $canCheckin); ?> + + + + escape($item->title); ?> + + escape($item->title); ?> + + + note)) : ?> + escape($item->alias)); ?> + + escape($item->alias), $this->escape($item->note)); ?> + + + + + count_published; ?> + + + count_unpublished; ?> + + + count_archived; ?> + + + count_trashed; ?> + + escape($item->access_title); ?> + + + + + id; ?> +
    + + authorise('core.create', 'com_tags') + && $user->authorise('core.edit', 'com_tags') + && $user->authorise('core.edit.state', 'com_tags')) : ?> + JText::_('COM_TAGS_BATCH_OPTIONS'), + 'footer' => $this->loadTemplate('batch_footer'), + ), + $this->loadTemplate('batch_body') + ); ?> + + + + + + +
    + diff --git a/Sites/pages/administrator/components/com_tags/views/tags/tmpl/default.xml b/Sites/pages/administrator/components/com_tags/views/tags/tmpl/default.xml new file mode 100644 index 00000000..7cbc9e36 --- /dev/null +++ b/Sites/pages/administrator/components/com_tags/views/tags/tmpl/default.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/Sites/pages/administrator/components/com_tags/views/tags/tmpl/default_batch_body.php b/Sites/pages/administrator/components/com_tags/views/tags/tmpl/default_batch_body.php new file mode 100644 index 00000000..53b2248d --- /dev/null +++ b/Sites/pages/administrator/components/com_tags/views/tags/tmpl/default_batch_body.php @@ -0,0 +1,26 @@ +state->get('filter.published'); +?> + +
    +
    +
    +
    + +
    +
    +
    +
    + +
    +
    +
    +
    \ No newline at end of file diff --git a/Sites/pages/administrator/components/com_tags/views/tags/tmpl/default_batch_footer.php b/Sites/pages/administrator/components/com_tags/views/tags/tmpl/default_batch_footer.php new file mode 100644 index 00000000..44e67c93 --- /dev/null +++ b/Sites/pages/administrator/components/com_tags/views/tags/tmpl/default_batch_footer.php @@ -0,0 +1,17 @@ + + + diff --git a/Sites/pages/administrator/components/com_tags/views/tags/view.html.php b/Sites/pages/administrator/components/com_tags/views/tags/view.html.php new file mode 100644 index 00000000..33a2e6d4 --- /dev/null +++ b/Sites/pages/administrator/components/com_tags/views/tags/view.html.php @@ -0,0 +1,165 @@ +items = $this->get('Items'); + $this->pagination = $this->get('Pagination'); + $this->state = $this->get('State'); + $this->filterForm = $this->get('FilterForm'); + $this->activeFilters = $this->get('ActiveFilters'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + // Preprocess the list of items to find ordering divisions. + foreach ($this->items as &$item) + { + $this->ordering[$item->parent_id][] = $item->id; + } + + // Levels filter. + $options = array(); + $options[] = JHtml::_('select.option', '1', JText::_('J1')); + $options[] = JHtml::_('select.option', '2', JText::_('J2')); + $options[] = JHtml::_('select.option', '3', JText::_('J3')); + $options[] = JHtml::_('select.option', '4', JText::_('J4')); + $options[] = JHtml::_('select.option', '5', JText::_('J5')); + $options[] = JHtml::_('select.option', '6', JText::_('J6')); + $options[] = JHtml::_('select.option', '7', JText::_('J7')); + $options[] = JHtml::_('select.option', '8', JText::_('J8')); + $options[] = JHtml::_('select.option', '9', JText::_('J9')); + $options[] = JHtml::_('select.option', '10', JText::_('J10')); + + $this->f_levels = $options; + + // We don't need toolbar in the modal window. + if ($this->getLayout() !== 'modal') + { + $this->addToolbar(); + } + + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 3.1 + */ + protected function addToolbar() + { + $state = $this->get('State'); + $canDo = JHelperContent::getActions('com_tags'); + $user = JFactory::getUser(); + + // Get the toolbar object instance + $bar = JToolbar::getInstance('toolbar'); + + JToolbarHelper::title(JText::_('COM_TAGS_MANAGER_TAGS'), 'tags'); + + if ($canDo->get('core.create')) + { + JToolbarHelper::addNew('tag.add'); + } + + if ($canDo->get('core.edit')) + { + JToolbarHelper::editList('tag.edit'); + } + + if ($canDo->get('core.edit.state')) + { + JToolbarHelper::publish('tags.publish', 'JTOOLBAR_PUBLISH', true); + JToolbarHelper::unpublish('tags.unpublish', 'JTOOLBAR_UNPUBLISH', true); + JToolbarHelper::archiveList('tags.archive'); + } + + if ($canDo->get('core.admin')) + { + JToolbarHelper::checkin('tags.checkin'); + } + + // Add a batch button + if ($user->authorise('core.create', 'com_tags') + && $user->authorise('core.edit', 'com_tags') + && $user->authorise('core.edit.state', 'com_tags')) + { + $title = JText::_('JTOOLBAR_BATCH'); + + // Instantiate a new JLayoutFile instance and render the batch button + $layout = new JLayoutFile('joomla.toolbar.batch'); + + $dhtml = $layout->render(array('title' => $title)); + $bar->appendButton('Custom', $dhtml, 'batch'); + } + + if ($state->get('filter.published') == -2 && $canDo->get('core.delete')) + { + JToolbarHelper::deleteList('JGLOBAL_CONFIRM_DELETE', 'tags.delete', 'JTOOLBAR_EMPTY_TRASH'); + } + elseif ($canDo->get('core.edit.state')) + { + JToolbarHelper::trash('tags.trash'); + } + + if ($canDo->get('core.admin') || $canDo->get('core.options')) + { + JToolbarHelper::preferences('com_tags'); + } + + JToolbarHelper::help('JHELP_COMPONENTS_TAGS_MANAGER'); + } + + /** + * Returns an array of fields the table can be sorted by + * + * @return array Array containing the field name to sort by as the key and display text as value + * + * @since 3.0 + */ + protected function getSortFields() + { + return array( + 'a.lft' => JText::_('JGRID_HEADING_ORDERING'), + 'a.state' => JText::_('JSTATUS'), + 'a.title' => JText::_('JGLOBAL_TITLE'), + 'a.access' => JText::_('JGRID_HEADING_ACCESS'), + 'a.language' => JText::_('JGRID_HEADING_LANGUAGE'), + 'a.id' => JText::_('JGRID_HEADING_ID') + ); + } +} diff --git a/Sites/pages/administrator/components/com_templates/access.xml b/Sites/pages/administrator/components/com_templates/access.xml new file mode 100644 index 00000000..085a53d7 --- /dev/null +++ b/Sites/pages/administrator/components/com_templates/access.xml @@ -0,0 +1,12 @@ + + +
    + + + + + + + +
    +
    diff --git a/Sites/pages/administrator/components/com_templates/config.xml b/Sites/pages/administrator/components/com_templates/config.xml new file mode 100644 index 00000000..9309e86e --- /dev/null +++ b/Sites/pages/administrator/components/com_templates/config.xml @@ -0,0 +1,86 @@ + + +
    + + + + + + + + + + + + + + + + + +
    + +
    + +
    +
    diff --git a/Sites/pages/administrator/components/com_templates/controller.php b/Sites/pages/administrator/components/com_templates/controller.php new file mode 100644 index 00000000..95248624 --- /dev/null +++ b/Sites/pages/administrator/components/com_templates/controller.php @@ -0,0 +1,75 @@ +input->get('view', 'styles'); + $layout = $this->input->get('layout', 'default'); + $id = $this->input->getInt('id'); + + $document = JFactory::getDocument(); + + // For JSON requests + if ($document->getType() == 'json') + { + $view = new TemplatesViewStyle; + + // Get/Create the model + if ($model = new TemplatesModelStyle) + { + $model->addTablePath(JPATH_ADMINISTRATOR . '/components/com_templates/tables'); + + // Push the model into the view (as default) + $view->setModel($model, true); + } + + $view->document = $document; + + return $view->display(); + } + + // Check for edit form. + if ($view == 'style' && $layout == 'edit' && !$this->checkEditId('com_templates.edit.style', $id)) + { + // Somehow the person just went to the form - we don't allow that. + $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id)); + $this->setMessage($this->getError(), 'error'); + $this->setRedirect(JRoute::_('index.php?option=com_templates&view=styles', false)); + + return false; + } + + return parent::display(); + } +} diff --git a/Sites/pages/administrator/components/com_templates/controllers/style.php b/Sites/pages/administrator/components/com_templates/controllers/style.php new file mode 100644 index 00000000..2f3dfbe3 --- /dev/null +++ b/Sites/pages/administrator/components/com_templates/controllers/style.php @@ -0,0 +1,157 @@ +checkToken(); + + $document = JFactory::getDocument(); + + if ($document->getType() === 'json') + { + $app = JFactory::getApplication(); + $lang = JFactory::getLanguage(); + $model = $this->getModel(); + $table = $model->getTable(); + $data = $this->input->post->get('params', array(), 'array'); + $checkin = property_exists($table, 'checked_out'); + $context = $this->option . '.edit.' . $this->context; + $task = $this->getTask(); + + $item = $model->getItem($app->getTemplate(true)->id); + + // Setting received params + $item->set('params', $data); + + $data = $item->getProperties(); + unset($data['xml']); + + $key = $table->getKeyName(); + + // Access check. + if (!$this->allowSave($data, $key)) + { + $app->enqueueMessage(JText::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'error'); + + return false; + } + + JForm::addFormPath(JPATH_ADMINISTRATOR . '/components/com_templates/models/forms'); + + // Validate the posted data. + // Sometimes the form needs some posted data, such as for plugins and modules. + $form = $model->getForm($data, false); + + if (!$form) + { + $app->enqueueMessage($model->getError(), 'error'); + + return false; + } + + // Test whether the data is valid. + $validData = $model->validate($form, $data); + + if ($validData === false) + { + // Get the validation messages. + $errors = $model->getErrors(); + + // Push up to three validation messages out to the user. + for ($i = 0, $n = count($errors); $i < $n && $i < 3; $i++) + { + if ($errors[$i] instanceof Exception) + { + $app->enqueueMessage($errors[$i]->getMessage(), 'warning'); + } + else + { + $app->enqueueMessage($errors[$i], 'warning'); + } + } + + // Save the data in the session. + $app->setUserState($context . '.data', $data); + + return false; + } + + if (!isset($validData['tags'])) + { + $validData['tags'] = null; + } + + // Attempt to save the data. + if (!$model->save($validData)) + { + // Save the data in the session. + $app->setUserState($context . '.data', $validData); + + $app->enqueueMessage(JText::sprintf('JLIB_APPLICATION_ERROR_SAVE_FAILED', $model->getError()), 'error'); + + return false; + } + + // Save succeeded, so check-in the record. + if ($checkin && $model->checkin($validData[$key]) === false) + { + // Save the data in the session. + $app->setUserState($context . '.data', $validData); + + // Check-in failed, so go back to the record and display a notice. + $app->enqueueMessage(JText::sprintf('JLIB_APPLICATION_ERROR_CHECKIN_FAILED', $model->getError()), 'error'); + + return false; + } + + // Redirect the user and adjust session state + // Set the record data in the session. + $recordId = $model->getState($this->context . '.id'); + $this->holdEditId($context, $recordId); + $app->setUserState($context . '.data', null); + $model->checkout($recordId); + + // Invoke the postSave method to allow for the child class to access the model. + $this->postSaveHook($model, $validData); + + return true; + } + else + { + parent::save($key, $urlVar); + } + } +} diff --git a/Sites/pages/administrator/components/com_templates/controllers/styles.php b/Sites/pages/administrator/components/com_templates/controllers/styles.php new file mode 100644 index 00000000..cc856501 --- /dev/null +++ b/Sites/pages/administrator/components/com_templates/controllers/styles.php @@ -0,0 +1,142 @@ +checkToken(); + + $pks = $this->input->post->get('cid', array(), 'array'); + + try + { + if (empty($pks)) + { + throw new Exception(JText::_('COM_TEMPLATES_NO_TEMPLATE_SELECTED')); + } + + $pks = ArrayHelper::toInteger($pks); + + $model = $this->getModel(); + $model->duplicate($pks); + $this->setMessage(JText::_('COM_TEMPLATES_SUCCESS_DUPLICATED')); + } + catch (Exception $e) + { + JError::raiseWarning(500, $e->getMessage()); + } + + $this->setRedirect('index.php?option=com_templates&view=styles'); + } + + /** + * Proxy for getModel. + * + * @param string $name The model name. Optional. + * @param string $prefix The class prefix. Optional. + * @param array $config Configuration array for model. Optional. + * + * @return JModelLegacy + * + * @since 1.6 + */ + public function getModel($name = 'Style', $prefix = 'TemplatesModel', $config = array()) + { + return parent::getModel($name, $prefix, array('ignore_request' => true)); + } + + /** + * Method to set the home template for a client. + * + * @return void + * + * @since 1.6 + */ + public function setDefault() + { + // Check for request forgeries + $this->checkToken(); + + $pks = $this->input->post->get('cid', array(), 'array'); + + try + { + if (empty($pks)) + { + throw new Exception(JText::_('COM_TEMPLATES_NO_TEMPLATE_SELECTED')); + } + + $pks = ArrayHelper::toInteger($pks); + + // Pop off the first element. + $id = array_shift($pks); + $model = $this->getModel(); + $model->setHome($id); + $this->setMessage(JText::_('COM_TEMPLATES_SUCCESS_HOME_SET')); + } + catch (Exception $e) + { + JError::raiseWarning(500, $e->getMessage()); + } + + $this->setRedirect('index.php?option=com_templates&view=styles'); + } + + /** + * Method to unset the default template for a client and for a language + * + * @return void + * + * @since 1.6 + */ + public function unsetDefault() + { + // Check for request forgeries + $this->checkToken('request'); + + $pks = $this->input->get->get('cid', array(), 'array'); + $pks = ArrayHelper::toInteger($pks); + + try + { + if (empty($pks)) + { + throw new Exception(JText::_('COM_TEMPLATES_NO_TEMPLATE_SELECTED')); + } + + // Pop off the first element. + $id = array_shift($pks); + $model = $this->getModel(); + $model->unsetHome($id); + $this->setMessage(JText::_('COM_TEMPLATES_SUCCESS_HOME_UNSET')); + } + catch (Exception $e) + { + JError::raiseWarning(500, $e->getMessage()); + } + + $this->setRedirect('index.php?option=com_templates&view=styles'); + } +} diff --git a/Sites/pages/administrator/components/com_templates/controllers/template.php b/Sites/pages/administrator/components/com_templates/controllers/template.php new file mode 100644 index 00000000..87ec2610 --- /dev/null +++ b/Sites/pages/administrator/components/com_templates/controllers/template.php @@ -0,0 +1,856 @@ +registerTask('apply', 'save'); + } + + /** + * Method for closing the template. + * + * @return void + * + * @since 3.2 + */ + public function cancel() + { + $this->setRedirect(JRoute::_('index.php?option=com_templates&view=templates', false)); + } + + /** + * Method for closing a file. + * + * @return void + * + * @since 3.2 + */ + public function close() + { + $app = JFactory::getApplication(); + $file = base64_encode('home'); + $id = (int) $app->input->get('id', 0, 'int'); + $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; + $this->setRedirect(JRoute::_($url, false)); + } + + /** + * Method for copying the template. + * + * @return boolean true on success, false otherwise + * + * @since 3.2 + */ + public function copy() + { + // Check for request forgeries + $this->checkToken(); + + $app = JFactory::getApplication(); + $this->input->set('installtype', 'folder'); + $newName = (string) $this->input->get('new_name', null, 'cmd'); + $newNameRaw = (string) $this->input->get('new_name', null, 'string'); + $templateID = (int) $this->input->get('id', 0, 'int'); + $file = (string) $this->input->get('file', '', 'cmd'); + + // Access check. + if (!$this->allowEdit()) + { + $app->enqueueMessage(JText::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'error'); + + return false; + } + + $this->setRedirect('index.php?option=com_templates&view=template&id=' . $templateID . '&file=' . $file); + $model = $this->getModel('Template', 'TemplatesModel'); + $model->setState('new_name', $newName); + $model->setState('tmp_prefix', uniqid('template_copy_')); + $model->setState('to_path', JFactory::getConfig()->get('tmp_path') . '/' . $model->getState('tmp_prefix')); + + // Process only if we have a new name entered + if (strlen($newName) > 0) + { + if (!JFactory::getUser()->authorise('core.create', 'com_templates')) + { + // User is not authorised to delete + $app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_CREATE_NOT_PERMITTED'), 'error'); + + return false; + } + + // Set FTP credentials, if given + JClientHelper::setCredentialsFromRequest('ftp'); + + // Check that new name is valid + if (($newNameRaw !== null) && ($newName !== $newNameRaw)) + { + $app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_INVALID_TEMPLATE_NAME'), 'error'); + + return false; + } + + // Check that new name doesn't already exist + if (!$model->checkNewName()) + { + $app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_DUPLICATE_TEMPLATE_NAME'), 'error'); + + return false; + } + + // Check that from name does exist and get the folder name + $fromName = $model->getFromName(); + + if (!$fromName) + { + $app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_INVALID_FROM_NAME'), 'error'); + + return false; + } + + // Call model's copy method + if (!$model->copy()) + { + $app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_COULD_NOT_COPY'), 'error'); + + return false; + } + + // Call installation model + $this->input->set('install_directory', JFactory::getConfig()->get('tmp_path') . '/' . $model->getState('tmp_prefix')); + $installModel = $this->getModel('Install', 'InstallerModel'); + JFactory::getLanguage()->load('com_installer'); + + if (!$installModel->install()) + { + $app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_COULD_NOT_INSTALL'), 'error'); + + return false; + } + + $this->setMessage(JText::sprintf('COM_TEMPLATES_COPY_SUCCESS', $newName)); + $model->cleanup(); + + return true; + } + } + + /** + * Method to get a model object, loading it if required. + * + * @param string $name The model name. Optional. + * @param string $prefix The class prefix. Optional. + * @param array $config Configuration array for model. Optional (note, the empty array is atypical compared to other models). + * + * @return JModelLegacy The model. + * + * @since 3.2 + */ + public function getModel($name = 'Template', $prefix = 'TemplatesModel', $config = array()) + { + return parent::getModel($name, $prefix, $config); + } + + /** + * Method to check if the user can modify template files + * + * @return boolean + * + * @since 3.2 + */ + protected function allowEdit() + { + return JFactory::getUser()->authorise('core.admin'); + } + + /** + * Saves a template source file. + * + * @return void + * + * @since 3.2 + */ + public function save() + { + // Check for request forgeries. + $this->checkToken(); + + $app = JFactory::getApplication(); + $data = $this->input->post->get('jform', array(), 'array'); + $task = $this->getTask(); + $model = $this->getModel(); + $fileName = (string) $app->input->get('file', '', 'cmd'); + $explodeArray = explode(':', base64_decode($fileName)); + + // Access check. + if (!$this->allowEdit()) + { + $app->enqueueMessage(JText::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'error'); + + return false; + } + + // Match the stored id's with the submitted. + if (empty($data['extension_id']) || empty($data['filename'])) + { + $app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_SOURCE_ID_FILENAME_MISMATCH'), 'error'); + + return false; + } + elseif ($data['extension_id'] != $model->getState('extension.id')) + { + $app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_SOURCE_ID_FILENAME_MISMATCH'), 'error'); + + return false; + } + elseif ($data['filename'] != end($explodeArray)) + { + $app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_SOURCE_ID_FILENAME_MISMATCH'), 'error'); + + return false; + } + + // Validate the posted data. + $form = $model->getForm(); + + if (!$form) + { + $app->enqueueMessage($model->getError(), 'error'); + + return false; + } + + $data = $model->validate($form, $data); + + // Check for validation errors. + if ($data === false) + { + // Get the validation messages. + $errors = $model->getErrors(); + + // Push up to three validation messages out to the user. + for ($i = 0, $n = count($errors); $i < $n && $i < 3; $i++) + { + if ($errors[$i] instanceof Exception) + { + $app->enqueueMessage($errors[$i]->getMessage(), 'warning'); + } + else + { + $app->enqueueMessage($errors[$i], 'warning'); + } + } + + // Redirect back to the edit screen. + $url = 'index.php?option=com_templates&view=template&id=' . $model->getState('extension.id') . '&file=' . $fileName; + $this->setRedirect(JRoute::_($url, false)); + + return false; + } + + // Attempt to save the data. + if (!$model->save($data)) + { + // Redirect back to the edit screen. + $this->setMessage(JText::sprintf('JERROR_SAVE_FAILED', $model->getError()), 'warning'); + $url = 'index.php?option=com_templates&view=template&id=' . $model->getState('extension.id') . '&file=' . $fileName; + $this->setRedirect(JRoute::_($url, false)); + + return false; + } + + $this->setMessage(JText::_('COM_TEMPLATES_FILE_SAVE_SUCCESS')); + + // Redirect the user based on the chosen task. + switch ($task) + { + case 'apply': + // Redirect back to the edit screen. + $url = 'index.php?option=com_templates&view=template&id=' . $model->getState('extension.id') . '&file=' . $fileName; + $this->setRedirect(JRoute::_($url, false)); + break; + + default: + // Redirect to the list screen. + $file = base64_encode('home'); + $id = (int) $app->input->get('id', 0, 'int'); + $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; + $this->setRedirect(JRoute::_($url, false)); + break; + } + } + + /** + * Method for creating override. + * + * @return void + * + * @since 3.2 + */ + public function overrides() + { + // Check for request forgeries. + $this->checkToken('get'); + + $app = JFactory::getApplication(); + $model = $this->getModel(); + $file = (string) $app->input->get('file', '', 'cmd'); + $override = (string) InputFilter::getInstance(array(), array(), 1, 1)->clean(base64_decode($app->input->get('folder', '', 'base64')), 'path'); + $id = (int) $app->input->get('id', 0, 'int'); + + // Access check. + if (!$this->allowEdit()) + { + $app->enqueueMessage(JText::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'error'); + + return false; + } + + + if ($model->createOverride($override)) + { + $this->setMessage(JText::_('COM_TEMPLATES_OVERRIDE_SUCCESS')); + } + + // Redirect back to the edit screen. + $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; + $this->setRedirect(JRoute::_($url, false)); + } + + /** + * Method for compiling LESS. + * + * @return void + * + * @since 3.2 + */ + public function less() + { + // Check for request forgeries + $this->checkToken(); + + $app = JFactory::getApplication(); + $model = $this->getModel(); + $id = (int) $app->input->get('id', 0, 'int'); + $file = (string) $app->input->get('file', '', 'cmd'); + + // Access check. + if (!$this->allowEdit()) + { + $app->enqueueMessage(JText::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'error'); + + return false; + } + + if ($model->compileLess($file)) + { + $this->setMessage(JText::_('COM_TEMPLATES_COMPILE_SUCCESS')); + } + else + { + $app->enqueueMessage(JText::_('COM_TEMPLATES_COMPILE_ERROR'), 'error'); + } + + $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; + $this->setRedirect(JRoute::_($url, false)); + } + + /** + * Method for deleting a file. + * + * @return void + * + * @since 3.2 + */ + public function delete() + { + // Check for request forgeries + $this->checkToken(); + + $app = JFactory::getApplication(); + $model = $this->getModel(); + $id = (int) $app->input->get('id', 0, 'int'); + $file = (string) $app->input->get('file', '', 'cmd'); + + // Access check. + if (!$this->allowEdit()) + { + $app->enqueueMessage(JText::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'error'); + + return false; + } + + if (base64_decode(urldecode($file)) == '/index.php') + { + $app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_INDEX_DELETE'), 'warning'); + $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; + $this->setRedirect(JRoute::_($url, false)); + } + + elseif ($model->deleteFile($file)) + { + $this->setMessage(JText::_('COM_TEMPLATES_FILE_DELETE_SUCCESS')); + $file = base64_encode('home'); + $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; + $this->setRedirect(JRoute::_($url, false)); + } + else + { + $app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_FILE_DELETE'), 'error'); + $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; + $this->setRedirect(JRoute::_($url, false)); + } + } + + /** + * Method for creating a new file. + * + * @return void + * + * @since 3.2 + */ + public function createFile() + { + // Check for request forgeries + $this->checkToken(); + + $app = JFactory::getApplication(); + $model = $this->getModel(); + $id = (int) $app->input->get('id', 0, 'int'); + $file = (string) $app->input->get('file', '', 'cmd'); + $name = (string) $app->input->get('name', '', 'cmd'); + $location = (string) InputFilter::getinstance(array(), array(), 1, 1)->clean(base64_decode($app->input->get('address', '', 'base64')), 'path'); + $type = (string) $app->input->get('type', '', 'cmd'); + + // Access check. + if (!$this->allowEdit()) + { + $app->enqueueMessage(JText::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'error'); + + return false; + } + + if ($type == 'null') + { + $app->enqueueMessage(JText::_('COM_TEMPLATES_INVALID_FILE_TYPE'), 'error'); + $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; + $this->setRedirect(JRoute::_($url, false)); + } + elseif (!preg_match('/^[a-zA-Z0-9-_]+$/', $name)) + { + $app->enqueueMessage(JText::_('COM_TEMPLATES_INVALID_FILE_NAME'), 'error'); + $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; + $this->setRedirect(JRoute::_($url, false)); + } + elseif ($model->createFile($name, $type, $location)) + { + $this->setMessage(JText::_('COM_TEMPLATES_FILE_CREATE_SUCCESS')); + $file = urlencode(base64_encode($location . '/' . $name . '.' . $type)); + $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; + $this->setRedirect(JRoute::_($url, false)); + } + else + { + $app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_FILE_CREATE'), 'error'); + $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; + $this->setRedirect(JRoute::_($url, false)); + } + } + + /** + * Method for uploading a file. + * + * @return void + * + * @since 3.2 + */ + public function uploadFile() + { + // Check for request forgeries + $this->checkToken(); + + $app = JFactory::getApplication(); + $model = $this->getModel(); + $id = (int) $app->input->get('id', 0, 'int'); + $file = (string) $app->input->get('file', '', 'cmd'); + $upload = $app->input->files->get('files'); + $location = (string) InputFilter::getinstance(array(), array(), 1, 1)->clean(base64_decode($app->input->get('address', '', 'base64')), 'path'); + + // Access check. + if (!$this->allowEdit()) + { + $app->enqueueMessage(JText::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'error'); + + return false; + } + + if ($return = $model->uploadFile($upload, $location)) + { + $app->enqueueMessage(JText::_('COM_TEMPLATES_FILE_UPLOAD_SUCCESS') . $upload['name']); + $redirect = base64_encode($return); + $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $redirect; + $this->setRedirect(JRoute::_($url, false)); + } + else + { + $app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_FILE_UPLOAD'), 'error'); + $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; + $this->setRedirect(JRoute::_($url, false)); + } + } + + /** + * Method for creating a new folder. + * + * @return void + * + * @since 3.2 + */ + public function createFolder() + { + // Check for request forgeries + $this->checkToken(); + + $app = JFactory::getApplication(); + $model = $this->getModel(); + $id = (int) $app->input->get('id', 0, 'int'); + $file = (string) $app->input->get('file', '', 'cmd'); + $name = $app->input->get('name'); + $location = (string) InputFilter::getinstance(array(), array(), 1, 1)->clean(base64_decode($app->input->get('address', '', 'base64')), 'path'); + + // Access check. + if (!$this->allowEdit()) + { + $app->enqueueMessage(JText::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'error'); + + return false; + } + + if (!preg_match('/^[a-zA-Z0-9-_.]+$/', $name)) + { + $app->enqueueMessage(JText::_('COM_TEMPLATES_INVALID_FOLDER_NAME'), 'error'); + $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; + $this->setRedirect(JRoute::_($url, false)); + } + elseif ($model->createFolder($name, $location)) + { + $this->setMessage(JText::_('COM_TEMPLATES_FOLDER_CREATE_SUCCESS')); + $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; + $this->setRedirect(JRoute::_($url, false)); + } + else + { + $app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_FOLDER_CREATE'), 'error'); + $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; + $this->setRedirect(JRoute::_($url, false)); + } + } + + /** + * Method for deleting a folder. + * + * @return void + * + * @since 3.2 + */ + public function deleteFolder() + { + // Check for request forgeries + $this->checkToken(); + + $app = JFactory::getApplication(); + $model = $this->getModel(); + $id = (int) $app->input->get('id', 0, 'int'); + $file = (string) $app->input->get('file', '', 'cmd'); + $location = (string) InputFilter::getinstance(array(), array(), 1, 1)->clean(base64_decode($app->input->get('address', '', 'base64')), 'path'); + + // Access check. + if (!$this->allowEdit()) + { + $app->enqueueMessage(JText::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'error'); + + return false; + } + + if (empty($location)) + { + $app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_ROOT_DELETE'), 'warning'); + $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; + $this->setRedirect(JRoute::_($url, false)); + } + elseif ($model->deleteFolder($location)) + { + $this->setMessage(JText::_('COM_TEMPLATES_FOLDER_DELETE_SUCCESS')); + + if (stristr(base64_decode($file), $location) != false) + { + $file = base64_encode('home'); + } + + $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; + $this->setRedirect(JRoute::_($url, false)); + } + else + { + $app->enqueueMessage(JText::_('COM_TEMPLATES_FOLDER_DELETE_ERROR'), 'error'); + $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; + $this->setRedirect(JRoute::_($url, false)); + } + } + + /** + * Method for renaming a file. + * + * @return void + * + * @since 3.2 + */ + public function renameFile() + { + // Check for request forgeries + $this->checkToken(); + + $app = JFactory::getApplication(); + $model = $this->getModel(); + $id = (int) $app->input->get('id', 0, 'int'); + $file = (string) $app->input->get('file', '', 'cmd'); + $newName = $app->input->get('new_name'); + + // Access check. + if (!$this->allowEdit()) + { + $app->enqueueMessage(JText::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'error'); + + return false; + } + + if (base64_decode(urldecode($file)) == '/index.php') + { + $app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_RENAME_INDEX'), 'warning'); + $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; + $this->setRedirect(JRoute::_($url, false)); + } + elseif (!preg_match('/^[a-zA-Z0-9-_]+$/', $newName)) + { + $app->enqueueMessage(JText::_('COM_TEMPLATES_INVALID_FILE_NAME'), 'error'); + $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; + $this->setRedirect(JRoute::_($url, false)); + } + elseif ($rename = $model->renameFile($file, $newName)) + { + $this->setMessage(JText::_('COM_TEMPLATES_FILE_RENAME_SUCCESS')); + $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $rename; + $this->setRedirect(JRoute::_($url, false)); + } + else + { + $app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_FILE_RENAME'), 'error'); + $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; + $this->setRedirect(JRoute::_($url, false)); + } + } + + /** + * Method for cropping an image. + * + * @return void + * + * @since 3.2 + */ + public function cropImage() + { + // Check for request forgeries + $this->checkToken(); + + $app = JFactory::getApplication(); + $id = (int) $app->input->get('id', 0, 'int'); + $file = (string) $app->input->get('file', '', 'cmd'); + $x = $app->input->get('x'); + $y = $app->input->get('y'); + $w = $app->input->get('w'); + $h = $app->input->get('h'); + $model = $this->getModel(); + + // Access check. + if (!$this->allowEdit()) + { + $app->enqueueMessage(JText::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'error'); + + return false; + } + + if (empty($w) && empty($h) && empty($x) && empty($y)) + { + $app->enqueueMessage(JText::_('COM_TEMPLATES_CROP_AREA_ERROR'), 'error'); + $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; + $this->setRedirect(JRoute::_($url, false)); + } + elseif ($model->cropImage($file, $w, $h, $x, $y)) + { + $app->enqueueMessage(JText::_('COM_TEMPLATES_FILE_CROP_SUCCESS')); + $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; + $this->setRedirect(JRoute::_($url, false)); + } + else + { + $app->enqueueMessage(JText::_('COM_TEMPLATES_FILE_CROP_ERROR'), 'error'); + $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; + $this->setRedirect(JRoute::_($url, false)); + } + } + + /** + * Method for resizing an image. + * + * @return void + * + * @since 3.2 + */ + public function resizeImage() + { + // Check for request forgeries + $this->checkToken(); + + $app = JFactory::getApplication(); + $id = (int) $app->input->get('id', 0, 'int'); + $file = (string) $app->input->get('file', '', 'cmd'); + $width = $app->input->get('width'); + $height = $app->input->get('height'); + $model = $this->getModel(); + + // Access check. + if (!$this->allowEdit()) + { + $app->enqueueMessage(JText::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'error'); + + return false; + } + + if ($model->resizeImage($file, $width, $height)) + { + $app->enqueueMessage(JText::_('COM_TEMPLATES_FILE_RESIZE_SUCCESS')); + $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; + $this->setRedirect(JRoute::_($url, false)); + } + else + { + $app->enqueueMessage(JText::_('COM_TEMPLATES_FILE_RESIZE_ERROR'), 'error'); + $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; + $this->setRedirect(JRoute::_($url, false)); + } + } + + /** + * Method for copying a file. + * + * @return void + * + * @since 3.2 + */ + public function copyFile() + { + // Check for request forgeries + $this->checkToken(); + + $app = JFactory::getApplication(); + $id = (int) $app->input->get('id', 0, 'int'); + $file = (string) $app->input->get('file', '', 'cmd'); + $newName = $app->input->get('new_name'); + $location = (string) InputFilter::getinstance(array(), array(), 1, 1)->clean(base64_decode($app->input->get('address', '', 'base64')), 'path'); + $model = $this->getModel(); + + // Access check. + if (!$this->allowEdit()) + { + $app->enqueueMessage(JText::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'error'); + + return false; + } + + if (!preg_match('/^[a-zA-Z0-9-_]+$/', $newName)) + { + $app->enqueueMessage(JText::_('COM_TEMPLATES_INVALID_FILE_NAME'), 'error'); + $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; + $this->setRedirect(JRoute::_($url, false)); + } + elseif ($model->copyFile($newName, $location, $file)) + { + $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; + $this->setRedirect(JRoute::_($url, false)); + } + else + { + $app->enqueueMessage(JText::_('COM_TEMPLATES_FILE_COPY_FAIL'), 'error'); + $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; + $this->setRedirect(JRoute::_($url, false)); + } + } + + /** + * Method for extracting an archive file. + * + * @return void + * + * @since 3.2 + */ + public function extractArchive() + { + // Check for request forgeries + $this->checkToken(); + + $app = JFactory::getApplication(); + $id = (int) $app->input->get('id', 0, 'int'); + $file = (string) $app->input->get('file', '', 'cmd'); + $model = $this->getModel(); + + // Access check. + if (!$this->allowEdit()) + { + $app->enqueueMessage(JText::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'error'); + + return false; + } + + if ($model->extractArchive($file)) + { + $app->enqueueMessage(JText::_('COM_TEMPLATES_FILE_ARCHIVE_EXTRACT_SUCCESS')); + $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; + $this->setRedirect(JRoute::_($url, false)); + } + else + { + $app->enqueueMessage(JText::_('COM_TEMPLATES_FILE_ARCHIVE_EXTRACT_FAIL'), 'error'); + $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; + $this->setRedirect(JRoute::_($url, false)); + } + } +} diff --git a/Sites/pages/administrator/components/com_templates/helpers/html/templates.php b/Sites/pages/administrator/components/com_templates/helpers/html/templates.php new file mode 100644 index 00000000..50a822eb --- /dev/null +++ b/Sites/pages/administrator/components/com_templates/helpers/html/templates.php @@ -0,0 +1,98 @@ +path . '/templates/' . $template; + $thumb = $basePath . '/template_thumbnail.png'; + $preview = $basePath . '/template_preview.png'; + $html = ''; + + if (file_exists($thumb)) + { + JHtml::_('bootstrap.tooltip'); + + $clientPath = ($clientId == 0) ? '' : 'administrator/'; + $thumb = $clientPath . 'templates/' . $template . '/template_thumbnail.png'; + $html = JHtml::_('image', $thumb, JText::_('COM_TEMPLATES_PREVIEW')); + + if (file_exists($preview)) + { + $html = ''; + } + } + + return $html; + } + + /** + * Renders the html for the modal linked to thumb. + * + * @param string $template The name of the template. + * @param integer $clientId The application client ID the template applies to + * + * @return string The html string + * + * @since 3.4 + */ + public static function thumbModal($template, $clientId = 0) + { + $client = JApplicationHelper::getClientInfo($clientId); + $basePath = $client->path . '/templates/' . $template; + $baseUrl = ($clientId == 0) ? JUri::root(true) : JUri::root(true) . '/administrator'; + $thumb = $basePath . '/template_thumbnail.png'; + $preview = $basePath . '/template_preview.png'; + $html = ''; + + if (file_exists($thumb)) + { + if (file_exists($preview)) + { + $preview = $baseUrl . '/templates/' . $template . '/template_preview.png'; + $footer = ''; + + $html .= JHtml::_( + 'bootstrap.renderModal', + $template . '-Modal', + array( + 'title' => JText::_('COM_TEMPLATES_BUTTON_PREVIEW'), + 'height' => '500px', + 'width' => '800px', + 'footer' => $footer, + ), + $body = '
    ' . $template . '
    ' + ); + } + } + + return $html; + } +} diff --git a/Sites/pages/administrator/components/com_templates/helpers/template.php b/Sites/pages/administrator/components/com_templates/helpers/template.php new file mode 100644 index 00000000..07cd5777 --- /dev/null +++ b/Sites/pages/administrator/components/com_templates/helpers/template.php @@ -0,0 +1,178 @@ +enqueueMessage(JText::_('COM_TEMPLATES_ERROR_UPLOAD_INPUT'), 'error'); + + return false; + } + + // Media file names should never have executable extensions buried in them. + $executable = array( + 'exe', 'phtml','java', 'perl', 'py', 'asp','dll', 'go', 'jar', + 'ade', 'adp', 'bat', 'chm', 'cmd', 'com', 'cpl', 'hta', 'ins', 'isp', + 'jse', 'lib', 'mde', 'msc', 'msp', 'mst', 'pif', 'scr', 'sct', 'shb', + 'sys', 'vb', 'vbe', 'vbs', 'vxd', 'wsc', 'wsf', 'wsh' + ); + $explodedFileName = explode('.', $file['name']); + + if (count($explodedFileName) > 2) + { + foreach ($executable as $extensionName) + { + if (in_array($extensionName, $explodedFileName)) + { + $app = JFactory::getApplication(); + $app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_EXECUTABLE'), 'error'); + + return false; + } + } + } + + jimport('joomla.filesystem.file'); + + if ($file['name'] !== JFile::makeSafe($file['name']) || preg_match('/\s/', JFile::makeSafe($file['name']))) + { + $app = JFactory::getApplication(); + $app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_WARNFILENAME'), 'error'); + + return false; + } + + $format = strtolower(JFile::getExt($file['name'])); + + $imageTypes = explode(',', $params->get('image_formats')); + $sourceTypes = explode(',', $params->get('source_formats')); + $fontTypes = explode(',', $params->get('font_formats')); + $archiveTypes = explode(',', $params->get('compressed_formats')); + + $allowable = array_merge($imageTypes, $sourceTypes, $fontTypes, $archiveTypes); + + if ($format == '' || $format == false || (!in_array($format, $allowable))) + { + $app = JFactory::getApplication(); + $app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_WARNFILETYPE'), 'error'); + + return false; + } + + if (in_array($format, $archiveTypes)) + { + $zip = new ZipArchive; + + if ($zip->open($file['tmp_name']) === true) + { + for ($i = 0; $i < $zip->numFiles; $i++) + { + $entry = $zip->getNameIndex($i); + $endString = substr($entry, -1); + + if ($endString != DIRECTORY_SEPARATOR) + { + $explodeArray = explode('.', $entry); + $ext = end($explodeArray); + + if (!in_array($ext, $allowable)) + { + $app = JFactory::getApplication(); + $app->enqueueMessage(JText::_('COM_TEMPLATES_FILE_UNSUPPORTED_ARCHIVE'), 'error'); + + return false; + } + } + } + } + else + { + $app = JFactory::getApplication(); + $app->enqueueMessage(JText::_('COM_TEMPLATES_FILE_ARCHIVE_OPEN_FAIL'), 'error'); + + return false; + } + } + + // Max upload size set to 2 MB for Template Manager + $maxSize = (int) ($params->get('upload_limit') * 1024 * 1024); + + if ($maxSize > 0 && (int) $file['size'] > $maxSize) + { + $app = JFactory::getApplication(); + $app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_WARNFILETOOLARGE'), 'error'); + + return false; + } + + $xss_check = file_get_contents($file['tmp_name'], false, null, -1, 256); + $html_tags = array( + 'abbr', 'acronym', 'address', 'applet', 'area', 'audioscope', 'base', 'basefont', 'bdo', 'bgsound', 'big', 'blackface', 'blink', 'blockquote', + 'body', 'bq', 'br', 'button', 'caption', 'center', 'cite', 'code', 'col', 'colgroup', 'comment', 'custom', 'dd', 'del', 'dfn', 'dir', 'div', + 'dl', 'dt', 'em', 'embed', 'fieldset', 'fn', 'font', 'form', 'frame', 'frameset', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'hr', 'html', + 'iframe', 'ilayer', 'img', 'input', 'ins', 'isindex', 'keygen', 'kbd', 'label', 'layer', 'legend', 'li', 'limittext', 'link', 'listing', + 'map', 'marquee', 'menu', 'meta', 'multicol', 'nobr', 'noembed', 'noframes', 'noscript', 'nosmartquotes', 'object', 'ol', 'optgroup', 'option', + 'param', 'plaintext', 'pre', 'rt', 'ruby', 's', 'samp', 'script', 'select', 'server', 'shadow', 'sidebar', 'small', 'spacer', 'span', 'strike', + 'strong', 'style', 'sub', 'sup', 'table', 'tbody', 'td', 'textarea', 'tfoot', 'th', 'thead', 'title', 'tr', 'tt', 'ul', 'var', 'wbr', 'xml', + 'xmp', '!DOCTYPE', '!--' + ); + + foreach ($html_tags as $tag) + { + // A tag is '' + if (stristr($xss_check, '<' . $tag . ' ') || stristr($xss_check, '<' . $tag . '>')) + { + $app = JFactory::getApplication(); + $app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_WARNIEXSS'), 'error'); + + return false; + } + } + + return true; + } +} diff --git a/Sites/pages/administrator/components/com_templates/helpers/templates.php b/Sites/pages/administrator/components/com_templates/helpers/templates.php new file mode 100644 index 00000000..9eccabcc --- /dev/null +++ b/Sites/pages/administrator/components/com_templates/helpers/templates.php @@ -0,0 +1,200 @@ +getQuery(true); + + $query->select($db->quoteName('element', 'value')) + ->select($db->quoteName('name', 'text')) + ->select($db->quoteName('extension_id', 'e_id')) + ->from($db->quoteName('#__extensions')) + ->where($db->quoteName('type') . ' = ' . $db->quote('template')) + ->where($db->quoteName('enabled') . ' = 1') + ->order($db->quoteName('client_id') . ' ASC') + ->order($db->quoteName('name') . ' ASC'); + + if ($clientId != '*') + { + $query->where($db->quoteName('client_id') . ' = ' . (int) $clientId); + } + + $db->setQuery($query); + $options = $db->loadObjectList(); + + return $options; + } + + /** + * TODO + * + * @param string $templateBaseDir TODO + * @param string $templateDir TODO + * + * @return boolean|JObject + */ + public static function parseXMLTemplateFile($templateBaseDir, $templateDir) + { + $data = new JObject; + + // Check of the xml file exists + $filePath = JPath::clean($templateBaseDir . '/templates/' . $templateDir . '/templateDetails.xml'); + + if (is_file($filePath)) + { + $xml = JInstaller::parseXMLInstallFile($filePath); + + if ($xml['type'] != 'template') + { + return false; + } + + foreach ($xml as $key => $value) + { + $data->set($key, $value); + } + } + + return $data; + } + + /** + * TODO + * + * @param integer $clientId TODO + * @param string $templateDir TODO + * + * @return boolean|array + * + * @since 3.0 + */ + public static function getPositions($clientId, $templateDir) + { + $positions = array(); + + $templateBaseDir = $clientId ? JPATH_ADMINISTRATOR : JPATH_SITE; + $filePath = JPath::clean($templateBaseDir . '/templates/' . $templateDir . '/templateDetails.xml'); + + if (is_file($filePath)) + { + // Read the file to see if it's a valid component XML file + $xml = simplexml_load_file($filePath); + + if (!$xml) + { + return false; + } + + // Check for a valid XML root tag. + + // Extensions use 'extension' as the root tag. Languages use 'metafile' instead + + if ($xml->getName() != 'extension' && $xml->getName() != 'metafile') + { + unset($xml); + + return false; + } + + $positions = (array) $xml->positions; + + if (isset($positions['position'])) + { + $positions = (array) $positions['position']; + } + else + { + $positions = array(); + } + } + + return $positions; + } +} diff --git a/Sites/pages/administrator/components/com_templates/models/fields/templatelocation.php b/Sites/pages/administrator/components/com_templates/models/fields/templatelocation.php new file mode 100644 index 00000000..bd65442d --- /dev/null +++ b/Sites/pages/administrator/components/com_templates/models/fields/templatelocation.php @@ -0,0 +1,44 @@ +getUserStateFromRequest('com_templates.styles.client_id', 'client_id', '0', 'string'); + + // Get the templates for the selected client_id. + $options = TemplatesHelper::getTemplateOptions($clientId); + + // Merge into the parent options. + return array_merge(parent::getOptions(), $options); + } +} diff --git a/Sites/pages/administrator/components/com_templates/models/forms/filter_styles.xml b/Sites/pages/administrator/components/com_templates/models/forms/filter_styles.xml new file mode 100644 index 00000000..c8d87294 --- /dev/null +++ b/Sites/pages/administrator/components/com_templates/models/forms/filter_styles.xml @@ -0,0 +1,72 @@ + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Sites/pages/administrator/components/com_templates/models/forms/filter_templates.xml b/Sites/pages/administrator/components/com_templates/models/forms/filter_templates.xml new file mode 100644 index 00000000..239f4e8a --- /dev/null +++ b/Sites/pages/administrator/components/com_templates/models/forms/filter_templates.xml @@ -0,0 +1,48 @@ + +
    +
    + + + + + + + + + + + + + + + + diff --git a/Sites/pages/administrator/components/com_templates/models/forms/source.xml b/Sites/pages/administrator/components/com_templates/models/forms/source.xml new file mode 100644 index 00000000..5aadea8d --- /dev/null +++ b/Sites/pages/administrator/components/com_templates/models/forms/source.xml @@ -0,0 +1,28 @@ + +
    +
    + + + + + +
    +
    diff --git a/Sites/pages/administrator/components/com_templates/models/forms/style.xml b/Sites/pages/administrator/components/com_templates/models/forms/style.xml new file mode 100644 index 00000000..897efc18 --- /dev/null +++ b/Sites/pages/administrator/components/com_templates/models/forms/style.xml @@ -0,0 +1,51 @@ + +
    +
    + + + + + + + + + + +
    +
    diff --git a/Sites/pages/administrator/components/com_templates/models/forms/style_administrator.xml b/Sites/pages/administrator/components/com_templates/models/forms/style_administrator.xml new file mode 100644 index 00000000..219d381b --- /dev/null +++ b/Sites/pages/administrator/components/com_templates/models/forms/style_administrator.xml @@ -0,0 +1,16 @@ + +
    +
    + + + + +
    +
    diff --git a/Sites/pages/administrator/components/com_templates/models/forms/style_site.xml b/Sites/pages/administrator/components/com_templates/models/forms/style_site.xml new file mode 100644 index 00000000..d30c7809 --- /dev/null +++ b/Sites/pages/administrator/components/com_templates/models/forms/style_site.xml @@ -0,0 +1,15 @@ + +
    +
    + + + + +
    +
    diff --git a/Sites/pages/administrator/components/com_templates/models/style.php b/Sites/pages/administrator/components/com_templates/models/style.php new file mode 100644 index 00000000..3c40af88 --- /dev/null +++ b/Sites/pages/administrator/components/com_templates/models/style.php @@ -0,0 +1,729 @@ + 'onExtensionBeforeDelete', + 'event_after_delete' => 'onExtensionAfterDelete', + 'event_before_save' => 'onExtensionBeforeSave', + 'event_after_save' => 'onExtensionAfterSave', + 'events_map' => array('delete' => 'extension', 'save' => 'extension') + ), $config + ); + + parent::__construct($config); + } + + /** + * Method to auto-populate the model state. + * + * @note Calling getState in this method will result in recursion. + * + * @return void + * + * @since 1.6 + */ + protected function populateState() + { + $app = JFactory::getApplication('administrator'); + + // Load the User state. + $pk = $app->input->getInt('id'); + $this->setState('style.id', $pk); + + // Load the parameters. + $params = JComponentHelper::getParams('com_templates'); + $this->setState('params', $params); + } + + /** + * Method to delete rows. + * + * @param array &$pks An array of item ids. + * + * @return boolean Returns true on success, false on failure. + * + * @since 1.6 + * @throws Exception + */ + public function delete(&$pks) + { + $pks = (array) $pks; + $user = JFactory::getUser(); + $table = $this->getTable(); + $dispatcher = JEventDispatcher::getInstance(); + $context = $this->option . '.' . $this->name; + + JPluginHelper::importPlugin($this->events_map['delete']); + + // Iterate the items to delete each one. + foreach ($pks as $pk) + { + if ($table->load($pk)) + { + // Access checks. + if (!$user->authorise('core.delete', 'com_templates')) + { + throw new Exception(JText::_('JERROR_CORE_DELETE_NOT_PERMITTED')); + } + + // You should not delete a default style + if ($table->home != '0') + { + JError::raiseWarning(500, JText::_('COM_TEMPLATES_STYLE_CANNOT_DELETE_DEFAULT_STYLE')); + + return false; + } + + // Trigger the before delete event. + $result = $dispatcher->trigger($this->event_before_delete, array($context, $table)); + + if (in_array(false, $result, true) || !$table->delete($pk)) + { + $this->setError($table->getError()); + + return false; + } + + // Trigger the after delete event. + $dispatcher->trigger($this->event_after_delete, array($context, $table)); + } + else + { + $this->setError($table->getError()); + + return false; + } + } + + // Clean cache + $this->cleanCache(); + + return true; + } + + /** + * Method to duplicate styles. + * + * @param array &$pks An array of primary key IDs. + * + * @return boolean True if successful. + * + * @throws Exception + */ + public function duplicate(&$pks) + { + $user = JFactory::getUser(); + + // Access checks. + if (!$user->authorise('core.create', 'com_templates')) + { + throw new Exception(JText::_('JERROR_CORE_CREATE_NOT_PERMITTED')); + } + + $dispatcher = JEventDispatcher::getInstance(); + $context = $this->option . '.' . $this->name; + + // Include the plugins for the save events. + JPluginHelper::importPlugin($this->events_map['save']); + + $table = $this->getTable(); + + foreach ($pks as $pk) + { + if ($table->load($pk, true)) + { + // Reset the id to create a new record. + $table->id = 0; + + // Reset the home (don't want dupes of that field). + $table->home = 0; + + // Alter the title. + $m = null; + $table->title = $this->generateNewTitle(null, null, $table->title); + + if (!$table->check()) + { + throw new Exception($table->getError()); + } + + // Trigger the before save event. + $result = $dispatcher->trigger($this->event_before_save, array($context, &$table, true)); + + if (in_array(false, $result, true) || !$table->store()) + { + throw new Exception($table->getError()); + } + + // Trigger the after save event. + $dispatcher->trigger($this->event_after_save, array($context, &$table, true)); + } + else + { + throw new Exception($table->getError()); + } + } + + // Clean cache + $this->cleanCache(); + + return true; + } + + /** + * Method to change the title. + * + * @param integer $categoryId The id of the category. + * @param string $alias The alias. + * @param string $title The title. + * + * @return string New title. + * + * @since 1.7.1 + */ + protected function generateNewTitle($categoryId, $alias, $title) + { + // Alter the title + $table = $this->getTable(); + + while ($table->load(array('title' => $title))) + { + $title = StringHelper::increment($title); + } + + return $title; + } + + /** + * Method to get the record form. + * + * @param array $data An optional array of data for the form to interrogate. + * @param boolean $loadData True if the form is to load its own data (default case), false if not. + * + * @return JForm A JForm object on success, false on failure + * + * @since 1.6 + */ + public function getForm($data = array(), $loadData = true) + { + // The folder and element vars are passed when saving the form. + if (empty($data)) + { + $item = $this->getItem(); + $clientId = $item->client_id; + $template = $item->template; + } + else + { + $clientId = ArrayHelper::getValue($data, 'client_id'); + $template = ArrayHelper::getValue($data, 'template'); + } + + // Add the default fields directory + $baseFolder = $clientId ? JPATH_ADMINISTRATOR : JPATH_SITE; + JForm::addFieldPath($baseFolder . '/templates/' . $template . '/field'); + + // These variables are used to add data from the plugin XML files. + $this->setState('item.client_id', $clientId); + $this->setState('item.template', $template); + + // Get the form. + $form = $this->loadForm('com_templates.style', 'style', array('control' => 'jform', 'load_data' => $loadData)); + + if (empty($form)) + { + return false; + } + + // Modify the form based on access controls. + if (!$this->canEditState((object) $data)) + { + // Disable fields for display. + $form->setFieldAttribute('home', 'disabled', 'true'); + + // Disable fields while saving. + // The controller has already verified this is a record you can edit. + $form->setFieldAttribute('home', 'filter', 'unset'); + } + + return $form; + } + + /** + * Method to get the data that should be injected in the form. + * + * @return mixed The data for the form. + * + * @since 1.6 + */ + protected function loadFormData() + { + // Check the session for previously entered form data. + $data = JFactory::getApplication()->getUserState('com_templates.edit.style.data', array()); + + if (empty($data)) + { + $data = $this->getItem(); + } + + $this->preprocessData('com_templates.style', $data); + + return $data; + } + + /** + * Method to get a single record. + * + * @param integer $pk The id of the primary key. + * + * @return mixed Object on success, false on failure. + */ + public function getItem($pk = null) + { + $pk = (!empty($pk)) ? $pk : (int) $this->getState('style.id'); + + if (!isset($this->_cache[$pk])) + { + // Get a row instance. + $table = $this->getTable(); + + // Attempt to load the row. + $return = $table->load($pk); + + // Check for a table object error. + if ($return === false && $table->getError()) + { + $this->setError($table->getError()); + + return false; + } + + // Convert to the JObject before adding other data. + $properties = $table->getProperties(1); + $this->_cache[$pk] = ArrayHelper::toObject($properties, 'JObject'); + + // Convert the params field to an array. + $registry = new Registry($table->params); + $this->_cache[$pk]->params = $registry->toArray(); + + // Get the template XML. + $client = JApplicationHelper::getClientInfo($table->client_id); + $path = JPath::clean($client->path . '/templates/' . $table->template . '/templateDetails.xml'); + + if (file_exists($path)) + { + $this->_cache[$pk]->xml = simplexml_load_file($path); + } + else + { + $this->_cache[$pk]->xml = null; + } + } + + return $this->_cache[$pk]; + } + + /** + * Returns a reference to the a Table object, always creating it. + * + * @param type $type The table type to instantiate + * @param string $prefix A prefix for the table class name. Optional. + * @param array $config Configuration array for model. Optional. + * + * @return JTable A database object + */ + public function getTable($type = 'Style', $prefix = 'TemplatesTable', $config = array()) + { + return JTable::getInstance($type, $prefix, $config); + } + + /** + * Method to allow derived classes to preprocess the form. + * + * @param JForm $form A JForm object. + * @param mixed $data The data expected for the form. + * @param string $group The name of the plugin group to import (defaults to "content"). + * + * @return void + * + * @since 1.6 + * @throws Exception if there is an error in the form event. + */ + protected function preprocessForm(JForm $form, $data, $group = 'content') + { + $clientId = $this->getState('item.client_id'); + $template = $this->getState('item.template'); + $lang = JFactory::getLanguage(); + $client = JApplicationHelper::getClientInfo($clientId); + + if (!$form->loadFile('style_' . $client->name, true)) + { + throw new Exception(JText::_('JERROR_LOADFILE_FAILED')); + } + + jimport('joomla.filesystem.path'); + + $formFile = JPath::clean($client->path . '/templates/' . $template . '/templateDetails.xml'); + + // Load the core and/or local language file(s). + $lang->load('tpl_' . $template, $client->path, null, false, true) + || $lang->load('tpl_' . $template, $client->path . '/templates/' . $template, null, false, true); + + if (file_exists($formFile)) + { + // Get the template form. + if (!$form->loadFile($formFile, false, '//config')) + { + throw new Exception(JText::_('JERROR_LOADFILE_FAILED')); + } + } + + // Disable home field if it is default style + + if ((is_array($data) && array_key_exists('home', $data) && $data['home'] == '1') + || (is_object($data) && isset($data->home) && $data->home == '1')) + { + $form->setFieldAttribute('home', 'readonly', 'true'); + } + + // Attempt to load the xml file. + if (!$xml = simplexml_load_file($formFile)) + { + throw new Exception(JText::_('JERROR_LOADFILE_FAILED')); + } + + // Get the help data from the XML file if present. + $help = $xml->xpath('/extension/help'); + + if (!empty($help)) + { + $helpKey = trim((string) $help[0]['key']); + $helpURL = trim((string) $help[0]['url']); + + $this->helpKey = $helpKey ?: $this->helpKey; + $this->helpURL = $helpURL ?: $this->helpURL; + } + + // Trigger the default form events. + parent::preprocessForm($form, $data, $group); + } + + /** + * Method to save the form data. + * + * @param array $data The form data. + * + * @return boolean True on success. + */ + public function save($data) + { + // Detect disabled extension + $extension = JTable::getInstance('Extension'); + + if ($extension->load(array('enabled' => 0, 'type' => 'template', 'element' => $data['template'], 'client_id' => $data['client_id']))) + { + $this->setError(JText::_('COM_TEMPLATES_ERROR_SAVE_DISABLED_TEMPLATE')); + + return false; + } + + $app = JFactory::getApplication(); + $dispatcher = JEventDispatcher::getInstance(); + $table = $this->getTable(); + $pk = (!empty($data['id'])) ? $data['id'] : (int) $this->getState('style.id'); + $isNew = true; + + // Include the extension plugins for the save events. + JPluginHelper::importPlugin($this->events_map['save']); + + // Load the row if saving an existing record. + if ($pk > 0) + { + $table->load($pk); + $isNew = false; + } + + if ($app->input->get('task') == 'save2copy') + { + $data['title'] = $this->generateNewTitle(null, null, $data['title']); + $data['home'] = 0; + $data['assigned'] = ''; + } + + // Bind the data. + if (!$table->bind($data)) + { + $this->setError($table->getError()); + + return false; + } + + // Prepare the row for saving + $this->prepareTable($table); + + // Check the data. + if (!$table->check()) + { + $this->setError($table->getError()); + + return false; + } + + // Trigger the before save event. + $result = $dispatcher->trigger($this->event_before_save, array('com_templates.style', &$table, $isNew)); + + // Store the data. + if (in_array(false, $result, true) || !$table->store()) + { + $this->setError($table->getError()); + + return false; + } + + $user = JFactory::getUser(); + + if ($user->authorise('core.edit', 'com_menus') && $table->client_id == 0) + { + $n = 0; + $db = $this->getDbo(); + $user = JFactory::getUser(); + + if (!empty($data['assigned']) && is_array($data['assigned'])) + { + $data['assigned'] = ArrayHelper::toInteger($data['assigned']); + + // Update the mapping for menu items that this style IS assigned to. + $query = $db->getQuery(true) + ->update('#__menu') + ->set('template_style_id = ' . (int) $table->id) + ->where('id IN (' . implode(',', $data['assigned']) . ')') + ->where('template_style_id != ' . (int) $table->id) + ->where('checked_out IN (0,' . (int) $user->id . ')'); + $db->setQuery($query); + $db->execute(); + $n += $db->getAffectedRows(); + } + + // Remove style mappings for menu items this style is NOT assigned to. + // If unassigned then all existing maps will be removed. + $query = $db->getQuery(true) + ->update('#__menu') + ->set('template_style_id = 0'); + + if (!empty($data['assigned'])) + { + $query->where('id NOT IN (' . implode(',', $data['assigned']) . ')'); + } + + $query->where('template_style_id = ' . (int) $table->id) + ->where('checked_out IN (0,' . (int) $user->id . ')'); + $db->setQuery($query); + $db->execute(); + + $n += $db->getAffectedRows(); + + if ($n > 0) + { + $app->enqueueMessage(JText::plural('COM_TEMPLATES_MENU_CHANGED', $n)); + } + } + + // Clean the cache. + $this->cleanCache(); + + // Trigger the after save event. + $dispatcher->trigger($this->event_after_save, array('com_templates.style', &$table, $isNew)); + + $this->setState('style.id', $table->id); + + return true; + } + + /** + * Method to set a template style as home. + * + * @param integer $id The primary key ID for the style. + * + * @return boolean True if successful. + * + * @throws Exception + */ + public function setHome($id = 0) + { + $user = JFactory::getUser(); + $db = $this->getDbo(); + + // Access checks. + if (!$user->authorise('core.edit.state', 'com_templates')) + { + throw new Exception(JText::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED')); + } + + $style = JTable::getInstance('Style', 'TemplatesTable'); + + if (!$style->load((int) $id)) + { + throw new Exception(JText::_('COM_TEMPLATES_ERROR_STYLE_NOT_FOUND')); + } + + // Detect disabled extension + $extension = JTable::getInstance('Extension'); + + if ($extension->load(array('enabled' => 0, 'type' => 'template', 'element' => $style->template, 'client_id' => $style->client_id))) + { + throw new Exception(JText::_('COM_TEMPLATES_ERROR_SAVE_DISABLED_TEMPLATE')); + } + + // Reset the home fields for the client_id. + $query = $db->getQuery(true) + ->update('#__template_styles') + ->set('home = ' . $db->q('0')) + ->where('client_id = ' . (int) $style->client_id) + ->where('home = ' . $db->q('1')); + $db->setQuery($query); + $db->execute(); + + // Set the new home style. + $query = $db->getQuery(true) + ->update('#__template_styles') + ->set('home = ' . $db->q('1')) + ->where('id = ' . (int) $id); + $db->setQuery($query); + $db->execute(); + + // Clean the cache. + $this->cleanCache(); + + return true; + } + + /** + * Method to unset a template style as default for a language. + * + * @param integer $id The primary key ID for the style. + * + * @return boolean True if successful. + * + * @throws Exception + */ + public function unsetHome($id = 0) + { + $user = JFactory::getUser(); + $db = $this->getDbo(); + + // Access checks. + if (!$user->authorise('core.edit.state', 'com_templates')) + { + throw new Exception(JText::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED')); + } + + // Lookup the client_id. + $query = $db->getQuery(true) + ->select('client_id, home') + ->from('#__template_styles') + ->where('id = ' . (int) $id); + $db->setQuery($query); + $style = $db->loadObject(); + + if (!is_numeric($style->client_id)) + { + throw new Exception(JText::_('COM_TEMPLATES_ERROR_STYLE_NOT_FOUND')); + } + elseif ($style->home == '1') + { + throw new Exception(JText::_('COM_TEMPLATES_ERROR_CANNOT_UNSET_DEFAULT_STYLE')); + } + + // Set the new home style. + $query = $db->getQuery(true) + ->update('#__template_styles') + ->set('home = ' . $db->q('0')) + ->where('id = ' . (int) $id); + $db->setQuery($query); + $db->execute(); + + // Clean the cache. + $this->cleanCache(); + + return true; + } + + /** + * Get the necessary data to load an item help screen. + * + * @return object An object with key, url, and local properties for loading the item help screen. + * + * @since 1.6 + */ + public function getHelp() + { + return (object) array('key' => $this->helpKey, 'url' => $this->helpURL); + } + + /** + * Custom clean cache method + * + * @param string $group The cache group + * @param integer $clientId The ID of the client + * + * @return void + * + * @since 1.6 + */ + protected function cleanCache($group = null, $clientId = 0) + { + parent::cleanCache('com_templates'); + parent::cleanCache('_system'); + } +} diff --git a/Sites/pages/administrator/components/com_templates/models/styles.php b/Sites/pages/administrator/components/com_templates/models/styles.php new file mode 100644 index 00000000..5af60c4f --- /dev/null +++ b/Sites/pages/administrator/components/com_templates/models/styles.php @@ -0,0 +1,201 @@ +setState('filter.search', $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search', '', 'string')); + $this->setState('filter.template', $this->getUserStateFromRequest($this->context . '.filter.template', 'filter_template', '', 'string')); + $this->setState('filter.menuitem', $this->getUserStateFromRequest($this->context . '.filter.menuitem', 'filter_menuitem', '', 'cmd')); + + // Special case for the client id. + $clientId = (int) $this->getUserStateFromRequest($this->context . '.client_id', 'client_id', 0, 'int'); + $clientId = (!in_array($clientId, array (0, 1))) ? 0 : $clientId; + $this->setState('client_id', $clientId); + + // Load the parameters. + $params = JComponentHelper::getParams('com_templates'); + $this->setState('params', $params); + + // List state information. + parent::populateState($ordering, $direction); + } + + /** + * Method to get a store id based on model configuration state. + * + * This is necessary because the model is used by the component and + * different modules that might need different sets of data or different + * ordering requirements. + * + * @param string $id A prefix for the store id. + * + * @return string A store id. + */ + protected function getStoreId($id = '') + { + // Compile the store id. + $id .= ':' . $this->getState('client_id'); + $id .= ':' . $this->getState('filter.search'); + $id .= ':' . $this->getState('filter.template'); + $id .= ':' . $this->getState('filter.menuitem'); + + return parent::getStoreId($id); + } + + /** + * Build an SQL query to load the list data. + * + * @return JDatabaseQuery + */ + protected function getListQuery() + { + $clientId = (int) $this->getState('client_id'); + + // Create a new query object. + $db = $this->getDbo(); + $query = $db->getQuery(true); + + // Select the required fields from the table. + $query->select( + $this->getState( + 'list.select', + 'a.id, a.template, a.title, a.home, a.client_id, l.title AS language_title, l.image as image, l.sef AS language_sef' + ) + ); + $query->from($db->quoteName('#__template_styles', 'a')) + ->where($db->quoteName('a.client_id') . ' = ' . $clientId); + + // Join on menus. + $query->select('COUNT(m.template_style_id) AS assigned') + ->join('LEFT', $db->quoteName('#__menu', 'm') . ' ON ' . $db->quoteName('m.template_style_id') . ' = ' . $db->quoteName('a.id')) + ->group('a.id, a.template, a.title, a.home, a.client_id, l.title, l.image, e.extension_id, l.sef'); + + // Join over the language. + $query->join('LEFT', $db->quoteName('#__languages', 'l') . ' ON ' . $db->quoteName('l.lang_code') . ' = ' . $db->quoteName('a.home')); + + // Filter by extension enabled. + $query->select($db->quoteName('extension_id', 'e_id')) + ->join('LEFT', $db->quoteName('#__extensions', 'e') . ' ON e.element = a.template AND e.client_id = a.client_id') + ->where($db->quoteName('e.enabled') . ' = 1') + ->where($db->quoteName('e.type') . ' = ' . $db->quote('template')); + + // Filter by template. + if ($template = $this->getState('filter.template')) + { + $query->where($db->quoteName('a.template') . ' = ' . $db->quote($template)); + } + + // Filter by menuitem. + $menuItemId = $this->getState('filter.menuitem'); + + if ($clientId === 0 && is_numeric($menuItemId)) + { + // If user selected the templates styles that are not assigned to any page. + if ((int) $menuItemId === -1) + { + // Only custom template styles overrides not assigned to any menu item. + $query->where($db->quoteName('a.home') . ' = ' . $db->quote(0)) + ->where($db->quoteName('m.id') . ' IS NULL'); + } + // If user selected the templates styles assigned to particular pages. + else + { + // Subquery to get the language of the selected menu item. + $menuItemLanguageSubQuery = $db->getQuery(true); + $menuItemLanguageSubQuery->select($db->quoteName('language')) + ->from($db->quoteName('#__menu')) + ->where($db->quoteName('id') . ' = ' . $menuItemId); + + // Subquery to get the language of the selected menu item. + $templateStylesMenuItemsSubQuery = $db->getQuery(true); + $templateStylesMenuItemsSubQuery->select($db->quoteName('id')) + ->from($db->quoteName('#__menu')) + ->where($db->quoteName('template_style_id') . ' = ' . $db->quoteName('a.id')); + + // Main query where clause. + $query->where('(' . + // Default template style (fallback template style to all menu items). + $db->quoteName('a.home') . ' = ' . $db->quote(1) . ' OR ' . + // Default template style for specific language (fallback template style to the selected menu item language). + $db->quoteName('a.home') . ' IN (' . $menuItemLanguageSubQuery . ') OR ' . + // Custom template styles override (only if assigned to the selected menu item). + '(' . $db->quoteName('a.home') . ' = ' . $db->quote(0) . ' AND ' . $menuItemId . ' IN (' . $templateStylesMenuItemsSubQuery . '))' . + ')' + ); + } + } + + // Filter by search in title. + if ($search = $this->getState('filter.search')) + { + if (stripos($search, 'id:') === 0) + { + $query->where($db->quoteName('a.id') . ' = ' . (int) substr($search, 3)); + } + else + { + $search = $db->quote('%' . StringHelper::strtolower($search) . '%'); + $query->where('(' . ' LOWER(a.template) LIKE ' . $search . ' OR LOWER(a.title) LIKE ' . $search . ')'); + } + } + + // Add the list ordering clause. + $query->order($db->escape($this->getState('list.ordering', 'a.template')) . ' ' . $db->escape($this->getState('list.direction', 'ASC'))); + + return $query; + } +} diff --git a/Sites/pages/administrator/components/com_templates/models/template.php b/Sites/pages/administrator/components/com_templates/models/template.php new file mode 100644 index 00000000..a5ae68e7 --- /dev/null +++ b/Sites/pages/administrator/components/com_templates/models/template.php @@ -0,0 +1,1501 @@ +getTemplate()) + { + $temp->name = $name; + $temp->id = urlencode(base64_encode($path . $name)); + + return $temp; + } + } + + /** + * Method to get a list of all the files to edit in a template. + * + * @return array A nested array of relevant files. + * + * @since 1.6 + */ + public function getFiles() + { + $result = array(); + + if ($template = $this->getTemplate()) + { + jimport('joomla.filesystem.folder'); + $app = JFactory::getApplication(); + $client = JApplicationHelper::getClientInfo($template->client_id); + $path = JPath::clean($client->path . '/templates/' . $template->element . '/'); + $lang = JFactory::getLanguage(); + + // Load the core and/or local language file(s). + $lang->load('tpl_' . $template->element, $client->path, null, false, true) || + $lang->load('tpl_' . $template->element, $client->path . '/templates/' . $template->element, null, false, true); + $this->element = $path; + + if (!is_writable($path)) + { + $app->enqueueMessage(JText::_('COM_TEMPLATES_DIRECTORY_NOT_WRITABLE'), 'error'); + } + + if (is_dir($path)) + { + $result = $this->getDirectoryTree($path); + } + else + { + $app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_TEMPLATE_FOLDER_NOT_FOUND'), 'error'); + + return false; + } + } + + return $result; + } + + /** + * Get the directory tree. + * + * @param string $dir The path of the directory to scan + * + * @return array + * + * @since 3.2 + */ + public function getDirectoryTree($dir) + { + $result = array(); + + $dirFiles = scandir($dir); + + foreach ($dirFiles as $key => $value) + { + if (!in_array($value, array('.', '..'))) + { + if (is_dir($dir . $value)) + { + $relativePath = str_replace($this->element, '', $dir . $value); + $result['/' . $relativePath] = $this->getDirectoryTree($dir . $value . '/'); + } + else + { + $ext = pathinfo($dir . $value, PATHINFO_EXTENSION); + $allowedFormat = $this->checkFormat($ext); + + if ($allowedFormat == true) + { + $relativePath = str_replace($this->element, '', $dir); + $info = $this->getFile('/' . $relativePath, $value); + $result[] = $info; + } + } + } + } + + return $result; + } + + /** + * Method to auto-populate the model state. + * + * Note. Calling getState in this method will result in recursion. + * + * @return void + * + * @since 1.6 + */ + protected function populateState() + { + jimport('joomla.filesystem.file'); + $app = JFactory::getApplication('administrator'); + + // Load the User state. + $pk = $app->input->getInt('id'); + $this->setState('extension.id', $pk); + + // Load the parameters. + $params = JComponentHelper::getParams('com_templates'); + $this->setState('params', $params); + } + + /** + * Method to get the template information. + * + * @return mixed Object if successful, false if not and internal error is set. + * + * @since 1.6 + */ + public function &getTemplate() + { + if (empty($this->template)) + { + $pk = $this->getState('extension.id'); + $db = $this->getDbo(); + $app = JFactory::getApplication(); + + // Get the template information. + $query = $db->getQuery(true) + ->select('extension_id, client_id, element, name, manifest_cache') + ->from('#__extensions') + ->where($db->quoteName('extension_id') . ' = ' . (int) $pk) + ->where($db->quoteName('type') . ' = ' . $db->quote('template')); + $db->setQuery($query); + + try + { + $result = $db->loadObject(); + } + catch (RuntimeException $e) + { + $app->enqueueMessage($e->getMessage(), 'warning'); + $this->template = false; + + return false; + } + + if (empty($result)) + { + $app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_EXTENSION_RECORD_NOT_FOUND'), 'error'); + $this->template = false; + } + else + { + $this->template = $result; + } + } + + return $this->template; + } + + /** + * Method to check if new template name already exists + * + * @return boolean true if name is not used, false otherwise + * + * @since 2.5 + */ + public function checkNewName() + { + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select('COUNT(*)') + ->from('#__extensions') + ->where('name = ' . $db->quote($this->getState('new_name'))); + $db->setQuery($query); + + return ($db->loadResult() == 0); + } + + /** + * Method to check if new template name already exists + * + * @return string name of current template + * + * @since 2.5 + */ + public function getFromName() + { + return $this->getTemplate()->element; + } + + /** + * Method to check if new template name already exists + * + * @return boolean true if name is not used, false otherwise + * + * @since 2.5 + */ + public function copy() + { + $app = JFactory::getApplication(); + + if ($template = $this->getTemplate()) + { + jimport('joomla.filesystem.folder'); + $client = JApplicationHelper::getClientInfo($template->client_id); + $fromPath = JPath::clean($client->path . '/templates/' . $template->element . '/'); + + // Delete new folder if it exists + $toPath = $this->getState('to_path'); + + if (JFolder::exists($toPath)) + { + if (!JFolder::delete($toPath)) + { + $app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_COULD_NOT_WRITE'), 'error'); + + return false; + } + } + + // Copy all files from $fromName template to $newName folder + if (!JFolder::copy($fromPath, $toPath) || !$this->fixTemplateName()) + { + return false; + } + + return true; + } + else + { + $app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_INVALID_FROM_NAME'), 'error'); + + return false; + } + } + + /** + * Method to delete tmp folder + * + * @return boolean true if delete successful, false otherwise + * + * @since 2.5 + */ + public function cleanup() + { + // Clear installation messages + $app = JFactory::getApplication(); + $app->setUserState('com_installer.message', ''); + $app->setUserState('com_installer.extension_message', ''); + + // Delete temporary directory + return JFolder::delete($this->getState('to_path')); + } + + /** + * Method to rename the template in the XML files and rename the language files + * + * @return boolean true if successful, false otherwise + * + * @since 2.5 + */ + protected function fixTemplateName() + { + // Rename Language files + // Get list of language files + $result = true; + $files = JFolder::files($this->getState('to_path'), '.ini', true, true); + $newName = strtolower($this->getState('new_name')); + $template = $this->getTemplate(); + $oldName = $template->element; + $manifest = json_decode($template->manifest_cache); + + jimport('joomla.filesystem.file'); + + foreach ($files as $file) + { + $newFile = '/' . str_replace($oldName, $newName, basename($file)); + $result = JFile::move($file, dirname($file) . $newFile) && $result; + } + + // Edit XML file + $xmlFile = $this->getState('to_path') . '/templateDetails.xml'; + + if (JFile::exists($xmlFile)) + { + $contents = file_get_contents($xmlFile); + $pattern[] = '#\s*' . $manifest->name . '\s*#i'; + $replace[] = '' . $newName . ''; + $pattern[] = '##'; + $replace[] = ''; + $contents = preg_replace($pattern, $replace, $contents); + $result = JFile::write($xmlFile, $contents) && $result; + } + + return $result; + } + + /** + * Method to get the record form. + * + * @param array $data Data for the form. + * @param boolean $loadData True if the form is to load its own data (default case), false if not. + * + * @return JForm A JForm object on success, false on failure + * + * @since 1.6 + */ + public function getForm($data = array(), $loadData = true) + { + $app = JFactory::getApplication(); + + // Codemirror or Editor None should be enabled + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select('COUNT(*)') + ->from('#__extensions as a') + ->where( + '(a.name =' . $db->quote('plg_editors_codemirror') . + ' AND a.enabled = 1) OR (a.name =' . + $db->quote('plg_editors_none') . + ' AND a.enabled = 1)' + ); + $db->setQuery($query); + $state = $db->loadResult(); + + if ((int) $state < 1) + { + $app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_EDITOR_DISABLED'), 'warning'); + } + + // Get the form. + $form = $this->loadForm('com_templates.source', 'source', array('control' => 'jform', 'load_data' => $loadData)); + + if (empty($form)) + { + return false; + } + + return $form; + } + + /** + * Method to get the data that should be injected in the form. + * + * @return mixed The data for the form. + * + * @since 1.6 + */ + protected function loadFormData() + { + $data = $this->getSource(); + + $this->preprocessData('com_templates.source', $data); + + return $data; + } + + /** + * Method to get a single record. + * + * @return mixed Object on success, false on failure. + * + * @since 1.6 + */ + public function &getSource() + { + $app = JFactory::getApplication(); + $item = new stdClass; + + if (!$this->template) + { + $this->getTemplate(); + } + + if ($this->template) + { + $input = JFactory::getApplication()->input; + $fileName = base64_decode($input->get('file')); + $client = JApplicationHelper::getClientInfo($this->template->client_id); + + try + { + $filePath = JPath::check($client->path . '/templates/' . $this->template->element . '/' . $fileName); + } + catch (Exception $e) + { + $app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_SOURCE_FILE_NOT_FOUND'), 'error'); + + return; + } + + if (file_exists($filePath)) + { + $item->extension_id = $this->getState('extension.id'); + $item->filename = $fileName; + $item->source = file_get_contents($filePath); + } + else + { + $app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_SOURCE_FILE_NOT_FOUND'), 'error'); + } + } + + return $item; + } + + /** + * Method to store the source file contents. + * + * @param array $data The source data to save. + * + * @return boolean True on success, false otherwise and internal error set. + * + * @since 1.6 + */ + public function save($data) + { + jimport('joomla.filesystem.file'); + + // Get the template. + $template = $this->getTemplate(); + + if (empty($template)) + { + return false; + } + + $app = JFactory::getApplication(); + $fileName = base64_decode($app->input->get('file')); + $client = JApplicationHelper::getClientInfo($template->client_id); + $filePath = JPath::clean($client->path . '/templates/' . $template->element . '/' . $fileName); + + // Include the extension plugins for the save events. + JPluginHelper::importPlugin('extension'); + + $user = get_current_user(); + chown($filePath, $user); + JPath::setPermissions($filePath, '0644'); + + // Try to make the template file writable. + if (!is_writable($filePath)) + { + $app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_SOURCE_FILE_NOT_WRITABLE'), 'warning'); + $app->enqueueMessage(JText::sprintf('COM_TEMPLATES_FILE_PERMISSIONS', JPath::getPermissions($filePath)), 'warning'); + + if (!JPath::isOwner($filePath)) + { + $app->enqueueMessage(JText::_('COM_TEMPLATES_CHECK_FILE_OWNERSHIP'), 'warning'); + } + + return false; + } + + // Make sure EOL is Unix + $data['source'] = str_replace(array("\r\n", "\r"), "\n", $data['source']); + + $return = JFile::write($filePath, $data['source']); + + if (!$return) + { + $app->enqueueMessage(JText::sprintf('COM_TEMPLATES_ERROR_FAILED_TO_SAVE_FILENAME', $fileName), 'error'); + + return false; + } + + // Get the extension of the changed file. + $explodeArray = explode('.', $fileName); + $ext = end($explodeArray); + + if ($ext == 'less') + { + $app->enqueueMessage(JText::sprintf('COM_TEMPLATES_COMPILE_LESS', $fileName)); + } + + return true; + } + + /** + * Get overrides folder. + * + * @param string $name The name of override. + * @param string $path Location of override. + * + * @return object containing override name and path. + * + * @since 3.2 + */ + public function getOverridesFolder($name,$path) + { + $folder = new stdClass; + $folder->name = $name; + $folder->path = base64_encode($path . $name); + + return $folder; + } + + /** + * Get a list of overrides. + * + * @return array containing overrides. + * + * @since 3.2 + */ + public function getOverridesList() + { + if ($template = $this->getTemplate()) + { + $client = JApplicationHelper::getClientInfo($template->client_id); + $componentPath = JPath::clean($client->path . '/components/'); + $modulePath = JPath::clean($client->path . '/modules/'); + $pluginPath = JPath::clean(JPATH_ROOT . '/plugins/'); + $layoutPath = JPath::clean(JPATH_ROOT . '/layouts/'); + $components = JFolder::folders($componentPath); + + foreach ($components as $component) + { + if (file_exists($componentPath . '/' . $component . '/views/')) + { + $viewPath = JPath::clean($componentPath . '/' . $component . '/views/'); + } + elseif (file_exists($componentPath . '/' . $component . '/view/')) + { + $viewPath = JPath::clean($componentPath . '/' . $component . '/view/'); + } + else + { + $viewPath = ''; + } + + if ($viewPath) + { + $views = JFolder::folders($viewPath); + + foreach ($views as $view) + { + // Only show the view has layout inside it + if (file_exists($viewPath . $view . '/tmpl')) + { + $result['components'][$component][] = $this->getOverridesFolder($view, $viewPath); + } + } + } + } + + foreach (JFolder::folders($pluginPath) as $pluginGroup) + { + foreach (JFolder::folders($pluginPath . '/' . $pluginGroup) as $plugin) + { + if (file_exists($pluginPath . '/' . $pluginGroup . '/' . $plugin . '/tmpl/')) + { + $pluginLayoutPath = JPath::clean($pluginPath . '/' . $pluginGroup . '/'); + $result['plugins'][$pluginGroup][] = $this->getOverridesFolder($plugin, $pluginLayoutPath); + } + } + } + + $modules = JFolder::folders($modulePath); + + foreach ($modules as $module) + { + $result['modules'][] = $this->getOverridesFolder($module, $modulePath); + } + + $layoutFolders = JFolder::folders($layoutPath); + + foreach ($layoutFolders as $layoutFolder) + { + $layoutFolderPath = JPath::clean($layoutPath . '/' . $layoutFolder . '/'); + $layouts = JFolder::folders($layoutFolderPath); + + foreach ($layouts as $layout) + { + $result['layouts'][$layoutFolder][] = $this->getOverridesFolder($layout, $layoutFolderPath); + } + } + + // Check for layouts in component folders + foreach ($components as $component) + { + if (file_exists($componentPath . '/' . $component . '/layouts/')) + { + $componentLayoutPath = JPath::clean($componentPath . '/' . $component . '/layouts/'); + + if ($componentLayoutPath) + { + $layouts = JFolder::folders($componentLayoutPath); + + foreach ($layouts as $layout) + { + $result['layouts'][$component][] = $this->getOverridesFolder($layout, $componentLayoutPath); + } + } + } + } + } + + if (!empty($result)) + { + return $result; + } + } + + /** + * Create overrides. + * + * @param string $override The override location. + * + * @return boolean true if override creation is successful, false otherwise + * + * @since 3.2 + */ + public function createOverride($override) + { + jimport('joomla.filesystem.folder'); + + if ($template = $this->getTemplate()) + { + $app = JFactory::getApplication(); + $explodeArray = explode(DIRECTORY_SEPARATOR, $override); + $name = end($explodeArray); + $client = JApplicationHelper::getClientInfo($template->client_id); + + if (stristr($name, 'mod_') != false) + { + $htmlPath = JPath::clean($client->path . '/templates/' . $template->element . '/html/' . $name); + } + elseif (stristr($override, 'com_') != false) + { + $size = count($explodeArray); + + $url = JPath::clean($explodeArray[$size - 3] . '/' . $explodeArray[$size - 1]); + + if ($explodeArray[$size - 2] == 'layouts') + { + $htmlPath = JPath::clean($client->path . '/templates/' . $template->element . '/html/layouts/' . $url); + } + else + { + $htmlPath = JPath::clean($client->path . '/templates/' . $template->element . '/html/' . $url); + } + } + elseif (stripos($override, JPath::clean(JPATH_ROOT . '/plugins/')) === 0) + { + $size = count($explodeArray); + $layoutPath = JPath::clean('plg_' . $explodeArray[$size - 2] . '_' . $explodeArray[$size - 1]); + $htmlPath = JPath::clean($client->path . '/templates/' . $template->element . '/html/' . $layoutPath); + } + else + { + $layoutPath = implode('/', array_slice($explodeArray, -2)); + $htmlPath = JPath::clean($client->path . '/templates/' . $template->element . '/html/layouts/' . $layoutPath); + } + + // Check Html folder, create if not exist + if (!JFolder::exists($htmlPath)) + { + if (!JFolder::create($htmlPath)) + { + $app->enqueueMessage(JText::_('COM_TEMPLATES_FOLDER_ERROR'), 'error'); + + return false; + } + } + + if (stristr($name, 'mod_') != false) + { + $return = $this->createTemplateOverride(JPath::clean($override . '/tmpl'), $htmlPath); + } + elseif (stristr($override, 'com_') != false && stristr($override, 'layouts') == false) + { + $return = $this->createTemplateOverride(JPath::clean($override . '/tmpl'), $htmlPath); + } + elseif (stripos($override, JPath::clean(JPATH_ROOT . '/plugins/')) === 0) + { + $return = $this->createTemplateOverride(JPath::clean($override . '/tmpl'), $htmlPath); + } + else + { + $return = $this->createTemplateOverride($override, $htmlPath); + } + + if ($return) + { + $app->enqueueMessage(JText::_('COM_TEMPLATES_OVERRIDE_CREATED') . str_replace(JPATH_ROOT, '', $htmlPath)); + + return true; + } + else + { + $app->enqueueMessage(JText::_('COM_TEMPLATES_OVERRIDE_FAILED'), 'error'); + + return false; + } + } + } + + /** + * Create override folder & file + * + * @param string $overridePath The override location + * @param string $htmlPath The html location + * + * @return boolean True on success. False otherwise. + */ + public function createTemplateOverride($overridePath, $htmlPath) + { + $return = false; + + if (empty($overridePath) || empty($htmlPath)) + { + return $return; + } + + // Get list of template folders + $folders = JFolder::folders($overridePath, null, true, true); + + if (!empty($folders)) + { + foreach ($folders as $folder) + { + $htmlFolder = $htmlPath . str_replace($overridePath, '', $folder); + + if (!JFolder::exists($htmlFolder)) + { + JFolder::create($htmlFolder); + } + } + } + + // Get list of template files (Only get *.php file for template file) + $files = JFolder::files($overridePath, '.php', true, true); + + if (empty($files)) + { + return true; + } + + foreach ($files as $file) + { + $overrideFilePath = str_replace($overridePath, '', $file); + $htmlFilePath = $htmlPath . $overrideFilePath; + + if (JFile::exists($htmlFilePath)) + { + // Generate new unique file name base on current time + $today = JFactory::getDate(); + $htmlFilePath = JFile::stripExt($htmlFilePath) . '-' . $today->format('Ymd-His') . '.' . JFile::getExt($htmlFilePath); + } + + $return = JFile::copy($file, $htmlFilePath, '', true); + } + + return $return; + } + + /** + * Compile less using the less compiler under /build. + * + * @param string $input The relative location of the less file. + * + * @return boolean true if compilation is successful, false otherwise + * + * @since 3.2 + */ + public function compileLess($input) + { + if ($template = $this->getTemplate()) + { + $app = JFactory::getApplication(); + $client = JApplicationHelper::getClientInfo($template->client_id); + $path = JPath::clean($client->path . '/templates/' . $template->element . '/'); + $inFile = urldecode(base64_decode($input)); + $explodeArray = explode('/', $inFile); + $fileName = end($explodeArray); + $outFile = current(explode('.', $fileName)); + + $less = new JLess; + $less->setFormatter(new JLessFormatterJoomla); + + try + { + $less->compileFile($path . $inFile, $path . 'css/' . $outFile . '.css'); + + return true; + } + catch (Exception $e) + { + $app->enqueueMessage($e->getMessage(), 'error'); + } + } + } + + /** + * Delete a particular file. + * + * @param string $file The relative location of the file. + * + * @return boolean True if file deletion is successful, false otherwise + * + * @since 3.2 + */ + public function deleteFile($file) + { + if ($template = $this->getTemplate()) + { + $app = JFactory::getApplication(); + $client = JApplicationHelper::getClientInfo($template->client_id); + $path = JPath::clean($client->path . '/templates/' . $template->element . '/'); + $filePath = $path . urldecode(base64_decode($file)); + + $return = JFile::delete($filePath); + + if (!$return) + { + $app->enqueueMessage(JText::_('COM_TEMPLATES_FILE_DELETE_FAIL'), 'error'); + + return false; + } + + return true; + } + } + + /** + * Create new file. + * + * @param string $name The name of file. + * @param string $type The extension of the file. + * @param string $location Location for the new file. + * + * @return boolean true if file created successfully, false otherwise + * + * @since 3.2 + */ + public function createFile($name, $type, $location) + { + if ($template = $this->getTemplate()) + { + $app = JFactory::getApplication(); + $client = JApplicationHelper::getClientInfo($template->client_id); + $path = JPath::clean($client->path . '/templates/' . $template->element . '/'); + + if (file_exists(JPath::clean($path . '/' . $location . '/' . $name . '.' . $type))) + { + $app->enqueueMessage(JText::_('COM_TEMPLATES_FILE_EXISTS'), 'error'); + + return false; + } + + if (!fopen(JPath::clean($path . '/' . $location . '/' . $name . '.' . $type), 'x')) + { + $app->enqueueMessage(JText::_('COM_TEMPLATES_FILE_CREATE_ERROR'), 'error'); + + return false; + } + + // Check if the format is allowed and will be showed in the backend + $check = $this->checkFormat($type); + + // Add a message if we are not allowed to show this file in the backend. + if (!$check) + { + $app->enqueueMessage(JText::sprintf('COM_TEMPLATES_WARNING_FORMAT_WILL_NOT_BE_VISIBLE', $type), 'warning'); + } + + return true; + } + } + + /** + * Upload new file. + * + * @param string $file The name of the file. + * @param string $location Location for the new file. + * + * @return boolean True if file uploaded successfully, false otherwise + * + * @since 3.2 + */ + public function uploadFile($file, $location) + { + jimport('joomla.filesystem.folder'); + + if ($template = $this->getTemplate()) + { + $app = JFactory::getApplication(); + $client = JApplicationHelper::getClientInfo($template->client_id); + $path = JPath::clean($client->path . '/templates/' . $template->element . '/'); + $fileName = JFile::makeSafe($file['name']); + + $err = null; + JLoader::register('TemplateHelper', JPATH_ADMINISTRATOR . '/components/com_templates/helpers/template.php'); + + if (!TemplateHelper::canUpload($file, $err)) + { + // Can't upload the file + return false; + } + + if (file_exists(JPath::clean($path . '/' . $location . '/' . $file['name']))) + { + $app->enqueueMessage(JText::_('COM_TEMPLATES_FILE_EXISTS'), 'error'); + + return false; + } + + if (!JFile::upload($file['tmp_name'], JPath::clean($path . '/' . $location . '/' . $fileName))) + { + $app->enqueueMessage(JText::_('COM_TEMPLATES_FILE_UPLOAD_ERROR'), 'error'); + + return false; + } + + $url = JPath::clean($location . '/' . $fileName); + + return $url; + } + } + + /** + * Create new folder. + * + * @param string $name The name of the new folder. + * @param string $location Location for the new folder. + * + * @return boolean True if override folder is created successfully, false otherwise + * + * @since 3.2 + */ + public function createFolder($name, $location) + { + jimport('joomla.filesystem.folder'); + + if ($template = $this->getTemplate()) + { + $app = JFactory::getApplication(); + $client = JApplicationHelper::getClientInfo($template->client_id); + $path = JPath::clean($client->path . '/templates/' . $template->element . '/'); + + if (file_exists(JPath::clean($path . '/' . $location . '/' . $name . '/'))) + { + $app->enqueueMessage(JText::_('COM_TEMPLATES_FOLDER_EXISTS'), 'error'); + + return false; + } + + if (!JFolder::create(JPath::clean($path . '/' . $location . '/' . $name))) + { + $app->enqueueMessage(JText::_('COM_TEMPLATES_FOLDER_CREATE_ERROR'), 'error'); + + return false; + } + + return true; + } + } + + /** + * Delete a folder. + * + * @param string $location The name and location of the folder. + * + * @return boolean True if override folder is deleted successfully, false otherwise + * + * @since 3.2 + */ + public function deleteFolder($location) + { + jimport('joomla.filesystem.folder'); + + if ($template = $this->getTemplate()) + { + $app = JFactory::getApplication(); + $client = JApplicationHelper::getClientInfo($template->client_id); + $path = JPath::clean($client->path . '/templates/' . $template->element . '/' . $location); + + if (!file_exists($path)) + { + $app->enqueueMessage(JText::_('COM_TEMPLATES_FOLDER_NOT_EXISTS'), 'error'); + + return false; + } + + $return = JFolder::delete($path); + + if (!$return) + { + $app->enqueueMessage(JText::_('COM_TEMPLATES_FILE_DELETE_ERROR'), 'error'); + + return false; + } + + return true; + } + } + + /** + * Rename a file. + * + * @param string $file The name and location of the old file + * @param string $name The new name of the file. + * + * @return string Encoded string containing the new file location. + * + * @since 3.2 + */ + public function renameFile($file, $name) + { + if ($template = $this->getTemplate()) + { + $app = JFactory::getApplication(); + $client = JApplicationHelper::getClientInfo($template->client_id); + $path = JPath::clean($client->path . '/templates/' . $template->element . '/'); + $fileName = base64_decode($file); + $explodeArray = explode('.', $fileName); + $type = end($explodeArray); + $explodeArray = explode('/', $fileName); + $newName = str_replace(end($explodeArray), $name . '.' . $type, $fileName); + + if (file_exists($path . $newName)) + { + $app->enqueueMessage(JText::_('COM_TEMPLATES_FILE_EXISTS'), 'error'); + + return false; + } + + if (!rename($path . $fileName, $path . $newName)) + { + $app->enqueueMessage(JText::_('COM_TEMPLATES_FILE_RENAME_ERROR'), 'error'); + + return false; + } + + return base64_encode($newName); + } + } + + /** + * Get an image address, height and width. + * + * @return array an associative array containing image address, height and width. + * + * @since 3.2 + */ + public function getImage() + { + if ($template = $this->getTemplate()) + { + $app = JFactory::getApplication(); + $client = JApplicationHelper::getClientInfo($template->client_id); + $fileName = base64_decode($app->input->get('file')); + $path = JPath::clean($client->path . '/templates/' . $template->element . '/'); + + if (stristr($client->path, 'administrator') == false) + { + $folder = '/templates/'; + } + else + { + $folder = '/administrator/templates/'; + } + + $uri = JUri::root(true) . $folder . $template->element; + + if (file_exists(JPath::clean($path . $fileName))) + { + $JImage = new JImage(JPath::clean($path . $fileName)); + $image['address'] = $uri . $fileName; + $image['path'] = $fileName; + $image['height'] = $JImage->getHeight(); + $image['width'] = $JImage->getWidth(); + } + + else + { + $app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_IMAGE_FILE_NOT_FOUND'), 'error'); + + return false; + } + + return $image; + } + } + + /** + * Crop an image. + * + * @param string $file The name and location of the file + * @param string $w width. + * @param string $h height. + * @param string $x x-coordinate. + * @param string $y y-coordinate. + * + * @return boolean true if image cropped successfully, false otherwise. + * + * @since 3.2 + */ + public function cropImage($file, $w, $h, $x, $y) + { + if ($template = $this->getTemplate()) + { + $app = JFactory::getApplication(); + $client = JApplicationHelper::getClientInfo($template->client_id); + $relPath = base64_decode($file); + $path = JPath::clean($client->path . '/templates/' . $template->element . '/' . $relPath); + + try + { + $image = new \JImage($path); + $properties = $image->getImageFileProperties($path); + + switch ($properties->mime) + { + case 'image/png': + $imageType = \IMAGETYPE_PNG; + break; + case 'image/gif': + $imageType = \IMAGETYPE_GIF; + break; + default: + $imageType = \IMAGETYPE_JPEG; + } + + $image->crop($w, $h, $x, $y, false); + $image->toFile($path, $imageType); + + return true; + } + catch (Exception $e) + { + $app->enqueueMessage($e->getMessage(), 'error'); + } + } + } + + /** + * Resize an image. + * + * @param string $file The name and location of the file + * @param string $width The new width of the image. + * @param string $height The new height of the image. + * + * @return boolean true if image resize successful, false otherwise. + * + * @since 3.2 + */ + public function resizeImage($file, $width, $height) + { + if ($template = $this->getTemplate()) + { + $app = JFactory::getApplication(); + $client = JApplicationHelper::getClientInfo($template->client_id); + $relPath = base64_decode($file); + $path = JPath::clean($client->path . '/templates/' . $template->element . '/' . $relPath); + + try + { + $image = new \JImage($path); + $properties = $image->getImageFileProperties($path); + + switch ($properties->mime) + { + case 'image/png': + $imageType = \IMAGETYPE_PNG; + break; + case 'image/gif': + $imageType = \IMAGETYPE_GIF; + break; + default: + $imageType = \IMAGETYPE_JPEG; + } + + $image->resize($width, $height, false, \JImage::SCALE_FILL); + $image->toFile($path, $imageType); + + return true; + } + catch (Exception $e) + { + $app->enqueueMessage($e->getMessage(), 'error'); + } + } + } + + /** + * Template preview. + * + * @return object object containing the id of the template. + * + * @since 3.2 + */ + public function getPreview() + { + $app = JFactory::getApplication(); + $db = $this->getDbo(); + $query = $db->getQuery(true); + + $query->select('id, client_id'); + $query->from('#__template_styles'); + $query->where($db->quoteName('template') . ' = ' . $db->quote($this->template->element)); + + $db->setQuery($query); + + try + { + $result = $db->loadObject(); + } + catch (RuntimeException $e) + { + $app->enqueueMessage($e->getMessage(), 'warning'); + } + + if (empty($result)) + { + $app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_EXTENSION_RECORD_NOT_FOUND'), 'warning'); + } + else + { + return $result; + } + } + + /** + * Rename a file. + * + * @return mixed array on success, false on failure + * + * @since 3.2 + */ + public function getFont() + { + if ($template = $this->getTemplate()) + { + $app = JFactory::getApplication(); + $client = JApplicationHelper::getClientInfo($template->client_id); + $relPath = base64_decode($app->input->get('file')); + $explodeArray = explode('/', $relPath); + $fileName = end($explodeArray); + $path = JPath::clean($client->path . '/templates/' . $template->element . '/' . $relPath); + + if (stristr($client->path, 'administrator') == false) + { + $folder = '/templates/'; + } + else + { + $folder = '/administrator/templates/'; + } + + $uri = JUri::root(true) . $folder . $template->element; + + if (file_exists(JPath::clean($path))) + { + $font['address'] = $uri . $relPath; + + $font['rel_path'] = $relPath; + + $font['name'] = $fileName; + } + + else + { + $app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_FONT_FILE_NOT_FOUND'), 'error'); + + return false; + } + + return $font; + } + } + + /** + * Copy a file. + * + * @param string $newName The name of the copied file + * @param string $location The final location where the file is to be copied + * @param string $file The name and location of the file + * + * @return boolean true if image resize successful, false otherwise. + * + * @since 3.2 + */ + public function copyFile($newName, $location, $file) + { + if ($template = $this->getTemplate()) + { + $app = JFactory::getApplication(); + $client = JApplicationHelper::getClientInfo($template->client_id); + $relPath = base64_decode($file); + $explodeArray = explode('.', $relPath); + $ext = end($explodeArray); + $path = JPath::clean($client->path . '/templates/' . $template->element . '/'); + $newPath = JPath::clean($path . '/' . $location . '/' . $newName . '.' . $ext); + + if (file_exists($newPath)) + { + $app->enqueueMessage(JText::_('COM_TEMPLATES_FILE_EXISTS'), 'error'); + + return false; + } + + if (JFile::copy($path . $relPath, $newPath)) + { + $app->enqueueMessage(JText::sprintf('COM_TEMPLATES_FILE_COPY_SUCCESS', $newName . '.' . $ext)); + + return true; + } + else + { + return false; + } + } + } + + /** + * Get the compressed files. + * + * @return array if file exists, false otherwise + * + * @since 3.2 + */ + public function getArchive() + { + if ($template = $this->getTemplate()) + { + $app = JFactory::getApplication(); + $client = JApplicationHelper::getClientInfo($template->client_id); + $relPath = base64_decode($app->input->get('file')); + $path = JPath::clean($client->path . '/templates/' . $template->element . '/' . $relPath); + + if (file_exists(JPath::clean($path))) + { + $files = array(); + $zip = new ZipArchive; + + if ($zip->open($path) === true) + { + for ($i = 0; $i < $zip->numFiles; $i++) + { + $entry = $zip->getNameIndex($i); + $files[] = $entry; + } + } + else + { + $app->enqueueMessage(JText::_('COM_TEMPLATES_FILE_ARCHIVE_OPEN_FAIL'), 'error'); + + return false; + } + } + else + { + $app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_FONT_FILE_NOT_FOUND'), 'error'); + + return false; + } + + return $files; + } + } + + /** + * Extract contents of an archive file. + * + * @param string $file The name and location of the file + * + * @return boolean true if image extraction is successful, false otherwise. + * + * @since 3.2 + */ + public function extractArchive($file) + { + if ($template = $this->getTemplate()) + { + $app = JFactory::getApplication(); + $client = JApplicationHelper::getClientInfo($template->client_id); + $relPath = base64_decode($file); + $explodeArray = explode('/', $relPath); + $fileName = end($explodeArray); + $folderPath = stristr($relPath, $fileName, true); + $path = JPath::clean($client->path . '/templates/' . $template->element . '/' . $folderPath . '/'); + + if (file_exists(JPath::clean($path . '/' . $fileName))) + { + $zip = new ZipArchive; + + if ($zip->open(JPath::clean($path . '/' . $fileName)) === true) + { + for ($i = 0; $i < $zip->numFiles; $i++) + { + $entry = $zip->getNameIndex($i); + + if (file_exists(JPath::clean($path . '/' . $entry))) + { + $app->enqueueMessage(JText::_('COM_TEMPLATES_FILE_ARCHIVE_EXISTS'), 'error'); + + return false; + } + } + + $zip->extractTo($path); + + return true; + } + else + { + $app->enqueueMessage(JText::_('COM_TEMPLATES_FILE_ARCHIVE_OPEN_FAIL'), 'error'); + + return false; + } + } + else + { + $app->enqueueMessage(JText::_('COM_TEMPLATES_FILE_ARCHIVE_NOT_FOUND'), 'error'); + + return false; + } + } + } + + /** + * Check if the extension is allowed and will be shown in the template manager + * + * @param string $ext The extension to check if it is allowed + * + * @return boolean true if the extension is allowed false otherwise + * + * @since 3.6.0 + */ + protected function checkFormat($ext) + { + if (!isset($this->allowedFormats)) + { + $params = JComponentHelper::getParams('com_templates'); + $imageTypes = explode(',', $params->get('image_formats')); + $sourceTypes = explode(',', $params->get('source_formats')); + $fontTypes = explode(',', $params->get('font_formats')); + $archiveTypes = explode(',', $params->get('compressed_formats')); + + $this->allowedFormats = array_merge($imageTypes, $sourceTypes, $fontTypes, $archiveTypes); + } + + return in_array($ext, $this->allowedFormats); + } +} diff --git a/Sites/pages/administrator/components/com_templates/models/templates.php b/Sites/pages/administrator/components/com_templates/models/templates.php new file mode 100644 index 00000000..a222309a --- /dev/null +++ b/Sites/pages/administrator/components/com_templates/models/templates.php @@ -0,0 +1,165 @@ +client_id); + $item->xmldata = TemplatesHelper::parseXMLTemplateFile($client->path, $item->element); + } + + return $items; + } + + /** + * Build an SQL query to load the list data. + * + * @return JDatabaseQuery + * + * @since 1.6 + */ + protected function getListQuery() + { + // Create a new query object. + $db = $this->getDbo(); + $query = $db->getQuery(true); + + // Select the required fields from the table. + $query->select( + $this->getState( + 'list.select', + 'a.extension_id, a.name, a.element, a.client_id' + ) + ); + $query->from($db->quoteName('#__extensions', 'a')) + ->where($db->quoteName('a.client_id') . ' = ' . (int) $this->getState('client_id')) + ->where($db->quoteName('a.enabled') . ' = 1') + ->where($db->quoteName('a.type') . ' = ' . $db->quote('template')); + + // Filter by search in title. + if ($search = $this->getState('filter.search')) + { + if (stripos($search, 'id:') === 0) + { + $query->where($db->quoteName('a.id') . ' = ' . (int) substr($search, 3)); + } + else + { + $search = $db->quote('%' . StringHelper::strtolower($search) . '%'); + $query->where('(' . ' LOWER(a.element) LIKE ' . $search . ' OR LOWER(a.name) LIKE ' . $search . ')'); + } + } + + // Add the list ordering clause. + $query->order($db->escape($this->getState('list.ordering', 'a.element')) . ' ' . $db->escape($this->getState('list.direction', 'ASC'))); + + return $query; + } + + /** + * Method to get a store id based on model configuration state. + * + * This is necessary because the model is used by the component and + * different modules that might need different sets of data or different + * ordering requirements. + * + * @param string $id A prefix for the store id. + * + * @return string A store id. + * + * @since 1.6 + */ + protected function getStoreId($id = '') + { + // Compile the store id. + $id .= ':' . $this->getState('client_id'); + $id .= ':' . $this->getState('filter.search'); + + return parent::getStoreId($id); + } + + /** + * Method to auto-populate the model state. + * + * Note. Calling getState in this method will result in recursion. + * + * @param string $ordering An optional ordering field. + * @param string $direction An optional direction (asc|desc). + * + * @return void + * + * @since 1.6 + */ + protected function populateState($ordering = 'a.element', $direction = 'asc') + { + // Load the filter state. + $this->setState('filter.search', $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search', '', 'string')); + + // Special case for the client id. + $clientId = (int) $this->getUserStateFromRequest($this->context . '.client_id', 'client_id', 0, 'int'); + $clientId = (!in_array($clientId, array (0, 1))) ? 0 : $clientId; + $this->setState('client_id', $clientId); + + // Load the parameters. + $params = JComponentHelper::getParams('com_templates'); + $this->setState('params', $params); + + // List state information. + parent::populateState($ordering, $direction); + } +} diff --git a/Sites/pages/administrator/components/com_templates/tables/style.php b/Sites/pages/administrator/components/com_templates/tables/style.php new file mode 100644 index 00000000..d0160b5f --- /dev/null +++ b/Sites/pages/administrator/components/com_templates/tables/style.php @@ -0,0 +1,140 @@ +home == '1') + { + $this->setError(JText::_('COM_TEMPLATES_ERROR_CANNOT_UNSET_DEFAULT_STYLE')); + + return false; + } + + return parent::bind($array, $ignore); + } + + /** + * Overloaded check method to ensure data integrity. + * + * @return boolean True on success. + * + * @since 1.6 + */ + public function check() + { + if (empty($this->title)) + { + $this->setError(JText::_('COM_TEMPLATES_ERROR_STYLE_REQUIRES_TITLE')); + + return false; + } + + return true; + } + + /** + * Overloaded store method to ensure unicity of default style. + * + * @param boolean $updateNulls True to update fields even if they are null. + * + * @return boolean True on success. + * + * @since 1.6 + */ + public function store($updateNulls = false) + { + if ($this->home != '0') + { + $query = $this->_db->getQuery(true) + ->update('#__template_styles') + ->set('home=\'0\'') + ->where('client_id=' . (int) $this->client_id) + ->where('home=' . $this->_db->quote($this->home)); + $this->_db->setQuery($query); + $this->_db->execute(); + } + + return parent::store($updateNulls); + } + + /** + * Overloaded store method to unsure existence of a default style for a template. + * + * @param mixed $pk An optional primary key value to delete. If not set the instance property value is used. + * + * @return boolean True on success. + * + * @since 1.6 + */ + public function delete($pk = null) + { + $k = $this->_tbl_key; + $pk = is_null($pk) ? $this->$k : $pk; + + if (!is_null($pk)) + { + $query = $this->_db->getQuery(true) + ->from('#__template_styles') + ->select('id') + ->where('client_id=' . (int) $this->client_id) + ->where('template=' . $this->_db->quote($this->template)); + $this->_db->setQuery($query); + $results = $this->_db->loadColumn(); + + if (count($results) == 1 && $results[0] == $pk) + { + $this->setError(JText::_('COM_TEMPLATES_ERROR_CANNOT_DELETE_LAST_STYLE')); + + return false; + } + } + + return parent::delete($pk); + } +} diff --git a/Sites/pages/administrator/components/com_templates/templates.php b/Sites/pages/administrator/components/com_templates/templates.php new file mode 100644 index 00000000..63265de2 --- /dev/null +++ b/Sites/pages/administrator/components/com_templates/templates.php @@ -0,0 +1,22 @@ +authorise('core.manage', 'com_templates')) +{ + throw new JAccessExceptionNotallowed(JText::_('JERROR_ALERTNOAUTHOR'), 403); +} + +JLoader::register('TemplatesHelper', __DIR__ . '/helpers/templates.php'); + +$controller = JControllerLegacy::getInstance('Templates'); +$controller->execute(JFactory::getApplication()->input->get('task')); +$controller->redirect(); diff --git a/Sites/pages/administrator/components/com_templates/templates.xml b/Sites/pages/administrator/components/com_templates/templates.xml new file mode 100644 index 00000000..59c894e7 --- /dev/null +++ b/Sites/pages/administrator/components/com_templates/templates.xml @@ -0,0 +1,29 @@ + + + com_templates + Joomla! Project + April 2006 + (C) 2005 - 2020 Open Source Matters. All rights reserved. + GNU General Public License version 2 or later; see LICENSE.txt + admin@joomla.org + www.joomla.org + 3.0.0 + COM_TEMPLATES_XML_DESCRIPTION + + + config.xml + controller.php + templates.php + controllers + helpers + models + tables + views + + + language/en-GB.com_templates.ini + language/en-GB.com_templates.sys.ini + + + + diff --git a/Sites/pages/administrator/components/com_templates/views/style/tmpl/edit.php b/Sites/pages/administrator/components/com_templates/views/style/tmpl/edit.php new file mode 100644 index 00000000..e69004fd --- /dev/null +++ b/Sites/pages/administrator/components/com_templates/views/style/tmpl/edit.php @@ -0,0 +1,105 @@ +addScriptDeclaration(" + Joomla.submitbutton = function(task) + { + if (task == 'style.cancel' || document.formvalidator.isValid(document.getElementById('style-form'))) { + Joomla.submitform(task, document.getElementById('style-form')); + } + }; +"); +?> + +
    + + + +
    + 'details')); ?> + + + +
    +
    +

    + item->template); ?> +

    +
    + + item->client_id == 0 ? JText::_('JSITE') : JText::_('JADMINISTRATOR'); ?> + +
    +
    +

    item->xml->description); ?>

    + fieldset = 'description'; + $description = JLayoutHelper::render('joomla.edit.fieldset', $this); + ?> + +

    + + + +

    + +
    + fieldset = 'basic'; + $html = JLayoutHelper::render('joomla.edit.fieldset', $this); + echo $html ? '
    ' . $html : ''; + ?> +
    +
    + fields = array( + 'home', + 'client_id', + 'template' + ); + ?> + +
    +
    + + + + + + + + + fieldsets = array(); + $this->ignore_fieldsets = array('basic', 'description'); + echo JLayoutHelper::render('joomla.edit.params', $this); + ?> + + authorise('core.edit', 'com_menus') && $this->item->client_id == 0 && $this->canDo->get('core.edit.state')) : ?> + + loadTemplate('assignment'); ?> + + + + + + + +
    +
    diff --git a/Sites/pages/administrator/components/com_templates/views/style/tmpl/edit_assignment.php b/Sites/pages/administrator/components/com_templates/views/style/tmpl/edit_assignment.php new file mode 100644 index 00000000..9dfbe268 --- /dev/null +++ b/Sites/pages/administrator/components/com_templates/views/style/tmpl/edit_assignment.php @@ -0,0 +1,46 @@ + + +
    + +
    + diff --git a/Sites/pages/administrator/components/com_templates/views/style/tmpl/edit_options.php b/Sites/pages/administrator/components/com_templates/views/style/tmpl/edit_options.php new file mode 100644 index 00000000..588c5b8c --- /dev/null +++ b/Sites/pages/administrator/components/com_templates/views/style/tmpl/edit_options.php @@ -0,0 +1,40 @@ + + 'collapse0')); + $fieldSets = $this->form->getFieldsets('params'); + $i = 0; + + foreach ($fieldSets as $name => $fieldSet) : + $label = !empty($fieldSet->label) ? $fieldSet->label : 'COM_TEMPLATES_' . $name . '_FIELDSET_LABEL'; + echo JHtml::_('bootstrap.addSlide', 'templatestyleOptions', JText::_($label), 'collapse' . ($i++)); + if (isset($fieldSet->description) && trim($fieldSet->description)) : + echo '

    ' . $this->escape(JText::_($fieldSet->description)) . '

    '; + endif; + ?> + form->getFieldset($name) as $field) : ?> +
    +
    + label; ?> +
    +
    + input; ?> +
    +
    + item = $this->get('Item'); + $this->state = $this->get('State'); + $this->form = $this->get('Form'); + $this->canDo = JHelperContent::getActions('com_templates'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + $this->addToolbar(); + + return parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + JFactory::getApplication()->input->set('hidemainmenu', true); + + $isNew = ($this->item->id == 0); + $canDo = $this->canDo; + + JToolbarHelper::title( + $isNew ? JText::_('COM_TEMPLATES_MANAGER_ADD_STYLE') + : JText::_('COM_TEMPLATES_MANAGER_EDIT_STYLE'), 'eye thememanager' + ); + + // If not checked out, can save the item. + if ($canDo->get('core.edit')) + { + JToolbarHelper::apply('style.apply'); + JToolbarHelper::save('style.save'); + } + + // If an existing item, can save to a copy. + if (!$isNew && $canDo->get('core.create')) + { + JToolbarHelper::save2copy('style.save2copy'); + } + + if (empty($this->item->id)) + { + JToolbarHelper::cancel('style.cancel'); + } + else + { + JToolbarHelper::cancel('style.cancel', 'JTOOLBAR_CLOSE'); + } + + JToolbarHelper::divider(); + + // Get the help information for the template item. + $lang = JFactory::getLanguage(); + $help = $this->get('Help'); + + if ($lang->hasKey($help->url)) + { + $debug = $lang->setDebug(false); + $url = JText::_($help->url); + $lang->setDebug($debug); + } + else + { + $url = null; + } + + JToolbarHelper::help($help->key, false, $url); + } +} diff --git a/Sites/pages/administrator/components/com_templates/views/style/view.json.php b/Sites/pages/administrator/components/com_templates/views/style/view.json.php new file mode 100644 index 00000000..0b08bf1b --- /dev/null +++ b/Sites/pages/administrator/components/com_templates/views/style/view.json.php @@ -0,0 +1,72 @@ +item = $this->get('Item'); + } + catch (Exception $e) + { + $app = JFactory::getApplication(); + $app->enqueueMessage($e->getMessage(), 'error'); + + return false; + } + + $paramsList = $this->item->getProperties(); + + unset($paramsList['xml']); + + $paramsList = json_encode($paramsList); + + return $paramsList; + + } +} diff --git a/Sites/pages/administrator/components/com_templates/views/styles/tmpl/default.php b/Sites/pages/administrator/components/com_templates/views/styles/tmpl/default.php new file mode 100644 index 00000000..d1ea2b0b --- /dev/null +++ b/Sites/pages/administrator/components/com_templates/views/styles/tmpl/default.php @@ -0,0 +1,150 @@ +state->get('client_id', 0); +$listOrder = $this->escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$colSpan = $clientId === 1 ? 5 : 6; +?> +
    +sidebar)) : ?> +
    + sidebar; ?> +
    +
    + +
    + + $this, 'options' => array('selectorFieldName' => 'client_id'))); ?> + total > 0) : ?> + + + + + + + + + + + + + + + + + + + + items as $i => $item) : + $canCreate = $user->authorise('core.create', 'com_templates'); + $canEdit = $user->authorise('core.edit', 'com_templates'); + $canChange = $user->authorise('core.edit.state', 'com_templates'); + ?> + + + + + + + + + + + + +
    +   + + + + + + + + + + +
    + pagination->getListFooter(); ?> +
    + id); ?> + + preview && $item->client_id == '0') : ?> + + + + + client_id == '1') : ?> + + + + + + + + + escape($item->title); ?> + + escape($item->title); ?> + + + home == '0' || $item->home == '1') : ?> + home != '0', $i, 'styles.', $canChange && $item->home != '1'); ?> + + + image) : ?> + image . '.gif', $item->language_title, array('title' => JText::sprintf('COM_TEMPLATES_GRID_UNSET_LANGUAGE', $item->language_title)), true); ?> + + language_sef; ?> + + + + image) : ?> + image . '.gif', $item->language_title, array('title' => $item->language_title), true); ?> + + language_sef; ?> + + + + home == '1') : ?> + + home != '0' && $item->home != '1') : ?> + escape($item->language_title)); ?> + assigned > 0) : ?> + escape($item->assigned)); ?> + + + + + + + id; ?> +
    + + + + + +
    + diff --git a/Sites/pages/administrator/components/com_templates/views/styles/tmpl/default.xml b/Sites/pages/administrator/components/com_templates/views/styles/tmpl/default.xml new file mode 100755 index 00000000..95ef7adb --- /dev/null +++ b/Sites/pages/administrator/components/com_templates/views/styles/tmpl/default.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/Sites/pages/administrator/components/com_templates/views/styles/view.html.php b/Sites/pages/administrator/components/com_templates/views/styles/view.html.php new file mode 100644 index 00000000..7c82d445 --- /dev/null +++ b/Sites/pages/administrator/components/com_templates/views/styles/view.html.php @@ -0,0 +1,111 @@ +items = $this->get('Items'); + $this->pagination = $this->get('Pagination'); + $this->state = $this->get('State'); + $this->total = $this->get('Total'); + $this->filterForm = $this->get('FilterForm'); + $this->activeFilters = $this->get('ActiveFilters'); + $this->preview = JComponentHelper::getParams('com_templates')->get('template_positions_display'); + + TemplatesHelper::addSubmenu('styles'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + $this->addToolbar(); + $this->sidebar = JHtmlSidebar::render(); + + return parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + $canDo = JHelperContent::getActions('com_templates'); + + // Set the title. + if ((int) $this->get('State')->get('client_id') === 1) + { + JToolbarHelper::title(JText::_('COM_TEMPLATES_MANAGER_STYLES_ADMIN'), 'eye thememanager'); + } + else + { + JToolbarHelper::title(JText::_('COM_TEMPLATES_MANAGER_STYLES_SITE'), 'eye thememanager'); + } + + if ($canDo->get('core.edit.state')) + { + JToolbarHelper::makeDefault('styles.setDefault', 'COM_TEMPLATES_TOOLBAR_SET_HOME'); + JToolbarHelper::divider(); + } + + if ($canDo->get('core.edit')) + { + JToolbarHelper::editList('style.edit'); + } + + if ($canDo->get('core.create')) + { + JToolbarHelper::custom('styles.duplicate', 'copy.png', 'copy_f2.png', 'JTOOLBAR_DUPLICATE', true); + JToolbarHelper::divider(); + } + + if ($canDo->get('core.delete')) + { + JToolbarHelper::deleteList('JGLOBAL_CONFIRM_DELETE', 'styles.delete', 'JTOOLBAR_DELETE'); + JToolbarHelper::divider(); + } + + if ($canDo->get('core.admin') || $canDo->get('core.options')) + { + JToolbarHelper::preferences('com_templates'); + JToolbarHelper::divider(); + } + + JToolbarHelper::help('JHELP_EXTENSIONS_TEMPLATE_MANAGER_STYLES'); + + JHtmlSidebar::setAction('index.php?option=com_templates&view=styles'); + + } +} diff --git a/Sites/pages/administrator/components/com_templates/views/template/tmpl/default.php b/Sites/pages/administrator/components/com_templates/views/template/tmpl/default.php new file mode 100644 index 00000000..5385f6a0 --- /dev/null +++ b/Sites/pages/administrator/components/com_templates/views/template/tmpl/default.php @@ -0,0 +1,529 @@ +input; + +// No access if not global SuperUser +if (!JFactory::getUser()->authorise('core.admin')) +{ + JFactory::getApplication()->enqueueMessage(JText::_('JERROR_ALERTNOAUTHOR'), 'error'); +} + +if ($this->type == 'image') +{ + JHtml::_('script', 'system/jquery.Jcrop.min.js', array('version' => 'auto', 'relative' => true)); + JHtml::_('stylesheet', 'system/jquery.Jcrop.min.css', array('version' => 'auto', 'relative' => true)); +} + +JFactory::getDocument()->addScriptDeclaration(" +jQuery(document).ready(function($){ + + // Hide all the folder when the page loads + $('.folder ul, .component-folder ul, .plugin-folder ul, .layout-folder ul').hide(); + + // Display the tree after loading + $('.directory-tree').removeClass('directory-tree'); + + // Show all the lists in the path of an open file + $('.show > ul').show(); + + // Stop the default action of anchor tag on a click event + $('.folder-url, .component-folder-url, .plugin-folder-url, .layout-folder-url').click(function(event){ + event.preventDefault(); + }); + + // Prevent the click event from proliferating + $('.file, .component-file-url, .plugin-file-url').bind('click',function(e){ + e.stopPropagation(); + }); + + // Toggle the child indented list on a click event + $('.folder, .component-folder, .plugin-folder, .layout-folder').bind('click',function(e){ + $(this).children('ul').toggle(); + e.stopPropagation(); + }); + + // New file tree + $('#fileModal .folder-url').bind('click',function(e){ + $('.folder-url').removeClass('selected'); + e.stopPropagation(); + $('#fileModal input.address').val($(this).attr('data-id')); + $(this).addClass('selected'); + }); + + // Folder manager tree + $('#folderModal .folder-url').bind('click',function(e){ + $('.folder-url').removeClass('selected'); + e.stopPropagation(); + $('#folderModal input.address').val($(this).attr('data-id')); + $(this).addClass('selected'); + }); + + var containerDiv = document.querySelector('.span3.tree-holder'), + treeContainer = containerDiv.querySelector('.nav.nav-list'), + liEls = treeContainer.querySelectorAll('.folder.show'), + filePathEl = document.querySelector('p.lead.hidden.path'); + + if(filePathEl) + var filePathTmp = document.querySelector('p.lead.hidden.path').innerText; + + if(filePathTmp && filePathTmp.charAt( 0 ) === '/' ) { + filePathTmp = filePathTmp.slice( 1 ); + filePathTmp = filePathTmp.split('/'); + filePathTmp = filePathTmp[filePathTmp.length - 1]; + + for (var i = 0, l = liEls.length; i < l; i++) { + liEls[i].querySelector('a').classList.add('active'); + if (i === liEls.length - 1) { + var parentUl = liEls[i].querySelector('ul'), + allLi = parentUl.querySelectorAll('li'); + + for (var i = 0, l = allLi.length; i < l; i++) { + aEl = allLi[i].querySelector('a'), + spanEl = aEl.querySelector('span'); + + if (spanEl && filePathTmp === $.trim(spanEl.innerText)) { + aEl.classList.add('active'); + } + } + } + } + } +});"); + +if ($this->type == 'image') +{ + JFactory::getDocument()->addScriptDeclaration(" + jQuery(document).ready(function($) { + var jcrop_api; + + // Configuration for image cropping + $('#image-crop').Jcrop({ + onChange: showCoords, + onSelect: showCoords, + onRelease: clearCoords, + trueSize: [" . $this->image['width'] . ',' . $this->image['height'] . "] + },function(){ + jcrop_api = this; + }); + + // Function for calculating the crop coordinates + function showCoords(c) + { + $('#x').val(c.x); + $('#y').val(c.y); + $('#w').val(c.w); + $('#h').val(c.h); + }; + + // Function for clearing the coordinates + function clearCoords() + { + $('#adminForm input').val(''); + }; + });"); +} + +JFactory::getDocument()->addStyleDeclaration(' + /* Styles for modals */ + .selected{ + background: #08c; + color: #fff; + } + .selected:hover{ + background: #08c !important; + color: #fff; + } + .modal-body .column-left { + float: left; max-height: 70vh; overflow-y: auto; + } + .modal-body .column-right { + float: right; + } + @media (max-width: 767px) { + .modal-body .column-right { + float: left; + } + } + #deleteFolder{ + margin: 0; + } + + #image-crop{ + max-width: 100% !important; + width: auto; + height: auto; + } + + .directory-tree{ + display: none; + } + + .tree-holder{ + overflow-x: auto; + } +'); + +if ($this->type == 'font') +{ + JFactory::getDocument()->addStyleDeclaration( + "/* Styles for font preview */ + @font-face + { + font-family: previewFont; + src: url('" . $this->font['address'] . "') + } + + .font-preview{ + font-family: previewFont !important; + }" + ); +} +?> + 'editor')); ?> + +
    +
    + type == 'file') : ?> +

    source->filename, $this->template->element); ?>

    + + + type == 'image') : ?> +

    image['path'], $this->template->element); ?>

    + + + + type == 'font') : ?> +

    font['rel_path'], $this->template->element); ?>

    + + + +
    +
    +
    +
    + loadTemplate('tree'); ?> +
    +
    + type == 'home') : ?> +
    + + +
    +

    +

    +

    + + + +

    +
    +
    + + type == 'file') : ?> +
    + +
    + form->getInput('source'); ?> +
    + + + form->getInput('extension_id'); ?> + form->getInput('filename'); ?> + +
    + + type == 'archive') : ?> + +
    + + + + +
    + + type == 'image') : ?> + +
    +
    + + + + + + +
    +
    + + type == 'font') : ?> +
    +
    +
    +

    H1

    Quickly gaze at Joomla! views from HTML, CSS, JavaScript and XML

    +

    H2

    Quickly gaze at Joomla! views from HTML, CSS, JavaScript and XML

    +

    H3

    Quickly gaze at Joomla! views from HTML, CSS, JavaScript and XML

    +

    H4

    Quickly gaze at Joomla! views from HTML, CSS, JavaScript and XML

    +

    H5

    Quickly gaze at Joomla! views from HTML, CSS, JavaScript and XML
    +

    H6

    Quickly gaze at Joomla! views from HTML, CSS, JavaScript and XML
    +

    Bold

    Quickly gaze at Joomla! views from HTML, CSS, JavaScript and XML +

    Italics

    Quickly gaze at Joomla! views from HTML, CSS, JavaScript and XML +

    Unordered List

    +
      +
    • Item
    • +
    • Item
    • +
    • Item
      +
        +
      • Item
      • +
      • Item
      • +
      • Item
        +
          +
        • Item
        • +
        • Item
        • +
        • Item
        • +
        +
      • +
      +
    • +
    +

    Ordered List

    +
      +
    1. Item
    2. +
    3. Item
    4. +
    5. Item
      +
        +
      • Item
      • +
      • Item
      • +
      • Item
        +
          +
        • Item
        • +
        • Item
        • +
        • Item
        • +
        +
      • +
      +
    6. +
    + + +
    +
    +
    + +
    +
    + + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + + +loadTemplate('description'); ?> + + + + 'copyModal', + 'params' => array( + 'title' => JText::_('COM_TEMPLATES_TEMPLATE_COPY'), + 'footer' => $this->loadTemplate('modal_copy_footer'), + ), + 'body' => $this->loadTemplate('modal_copy_body'), +); +?> +
    + + +
    +type != 'home') : ?> + 'renameModal', + 'params' => array( + 'title' => JText::sprintf('COM_TEMPLATES_RENAME_FILE', $this->fileName), + 'footer' => $this->loadTemplate('modal_rename_footer'), + ), + 'body' => $this->loadTemplate('modal_rename_body'), + ); + ?> +
    + + +
    + +type != 'home') : ?> + 'deleteModal', + 'params' => array( + 'title' => JText::_('COM_TEMPLATES_ARE_YOU_SURE'), + 'footer' => $this->loadTemplate('modal_delete_footer'), + ), + 'body' => $this->loadTemplate('modal_delete_body'), + ); + ?> + + + 'fileModal', + 'params' => array( + 'title' => JText::_('COM_TEMPLATES_NEW_FILE_HEADER'), + 'footer' => $this->loadTemplate('modal_file_footer'), + ), + 'body' => $this->loadTemplate('modal_file_body'), +); +?> + + 'folderModal', + 'params' => array( + 'title' => JText::_('COM_TEMPLATES_MANAGE_FOLDERS'), + 'footer' => $this->loadTemplate('modal_folder_footer'), + ), + 'body' => $this->loadTemplate('modal_folder_body'), +); +?> + +type == 'image') : ?> + 'resizeModal', + 'params' => array( + 'title' => JText::_('COM_TEMPLATES_RESIZE_IMAGE'), + 'footer' => $this->loadTemplate('modal_resize_footer'), + ), + 'body' => $this->loadTemplate('modal_resize_body'), + ); + ?> +
    + + +
    + \ No newline at end of file diff --git a/Sites/pages/administrator/components/com_templates/views/template/tmpl/default_description.php b/Sites/pages/administrator/components/com_templates/views/template/tmpl/default_description.php new file mode 100644 index 00000000..bca0e59d --- /dev/null +++ b/Sites/pages/administrator/components/com_templates/views/template/tmpl/default_description.php @@ -0,0 +1,20 @@ + + +
    + template->element, $this->template->client_id); ?> + template->element, $this->template->client_id); ?> +
    +

    template->element); ?>

    +template->client_id); ?> +

    template->xmldata = TemplatesHelper::parseXMLTemplateFile($client->path, $this->template->element); ?>

    +

    template->xmldata->description); ?>

    \ No newline at end of file diff --git a/Sites/pages/administrator/components/com_templates/views/template/tmpl/default_folders.php b/Sites/pages/administrator/components/com_templates/views/template/tmpl/default_folders.php new file mode 100644 index 00000000..e85c152d --- /dev/null +++ b/Sites/pages/administrator/components/com_templates/views/template/tmpl/default_folders.php @@ -0,0 +1,25 @@ +files, SORT_STRING); +?> + + diff --git a/Sites/pages/administrator/components/com_templates/views/template/tmpl/default_modal_copy_body.php b/Sites/pages/administrator/components/com_templates/views/template/tmpl/default_modal_copy_body.php new file mode 100644 index 00000000..713b1dda --- /dev/null +++ b/Sites/pages/administrator/components/com_templates/views/template/tmpl/default_modal_copy_body.php @@ -0,0 +1,27 @@ + +
    +
    +
    +
    +
    + +
    +
    + +
    +
    +
    +
    +
    diff --git a/Sites/pages/administrator/components/com_templates/views/template/tmpl/default_modal_copy_footer.php b/Sites/pages/administrator/components/com_templates/views/template/tmpl/default_modal_copy_footer.php new file mode 100644 index 00000000..17f4eb22 --- /dev/null +++ b/Sites/pages/administrator/components/com_templates/views/template/tmpl/default_modal_copy_footer.php @@ -0,0 +1,13 @@ + + + diff --git a/Sites/pages/administrator/components/com_templates/views/template/tmpl/default_modal_delete_body.php b/Sites/pages/administrator/components/com_templates/views/template/tmpl/default_modal_delete_body.php new file mode 100644 index 00000000..aea0e51a --- /dev/null +++ b/Sites/pages/administrator/components/com_templates/views/template/tmpl/default_modal_delete_body.php @@ -0,0 +1,16 @@ + +
    +
    +

    fileName); ?>

    +
    +
    \ No newline at end of file diff --git a/Sites/pages/administrator/components/com_templates/views/template/tmpl/default_modal_delete_footer.php b/Sites/pages/administrator/components/com_templates/views/template/tmpl/default_modal_delete_footer.php new file mode 100644 index 00000000..5d7a6e4b --- /dev/null +++ b/Sites/pages/administrator/components/com_templates/views/template/tmpl/default_modal_delete_footer.php @@ -0,0 +1,22 @@ +input; +?> +
    + + + + + + + +
    diff --git a/Sites/pages/administrator/components/com_templates/views/template/tmpl/default_modal_file_body.php b/Sites/pages/administrator/components/com_templates/views/template/tmpl/default_modal_file_body.php new file mode 100644 index 00000000..6bf54eb4 --- /dev/null +++ b/Sites/pages/administrator/components/com_templates/views/template/tmpl/default_modal_file_body.php @@ -0,0 +1,70 @@ +input; +?> +
    +
    +
    +
    +
    +
    + + + + + + +
    +
    +
    +
    + + + +
    + state->get('params')->get('upload_limit'); ?> + + +
    +
    + type != 'home') : ?> +
    +
    + + + + + +
    +
    + +
    +
    + loadTemplate('folders'); ?> +
    +
    +
    +
    +
    diff --git a/Sites/pages/administrator/components/com_templates/views/template/tmpl/default_modal_file_footer.php b/Sites/pages/administrator/components/com_templates/views/template/tmpl/default_modal_file_footer.php new file mode 100644 index 00000000..765e7989 --- /dev/null +++ b/Sites/pages/administrator/components/com_templates/views/template/tmpl/default_modal_file_footer.php @@ -0,0 +1,12 @@ + + diff --git a/Sites/pages/administrator/components/com_templates/views/template/tmpl/default_modal_folder_body.php b/Sites/pages/administrator/components/com_templates/views/template/tmpl/default_modal_folder_body.php new file mode 100644 index 00000000..4537772a --- /dev/null +++ b/Sites/pages/administrator/components/com_templates/views/template/tmpl/default_modal_folder_body.php @@ -0,0 +1,34 @@ +input; +?> +
    +
    +
    +
    +
    +
    + + + + + +
    +
    +
    +
    + loadTemplate('folders'); ?> +
    +
    +
    +
    +
    diff --git a/Sites/pages/administrator/components/com_templates/views/template/tmpl/default_modal_folder_footer.php b/Sites/pages/administrator/components/com_templates/views/template/tmpl/default_modal_folder_footer.php new file mode 100644 index 00000000..ee5e5657 --- /dev/null +++ b/Sites/pages/administrator/components/com_templates/views/template/tmpl/default_modal_folder_footer.php @@ -0,0 +1,21 @@ +input; +?> +
    +
    + + + + +
    +
    diff --git a/Sites/pages/administrator/components/com_templates/views/template/tmpl/default_modal_rename_body.php b/Sites/pages/administrator/components/com_templates/views/template/tmpl/default_modal_rename_body.php new file mode 100644 index 00000000..b73e2a97 --- /dev/null +++ b/Sites/pages/administrator/components/com_templates/views/template/tmpl/default_modal_rename_body.php @@ -0,0 +1,31 @@ + +
    +
    +
    +
    +
    + +
    +
    +
    + + .fileName); ?> +
    +
    +
    +
    +
    +
    diff --git a/Sites/pages/administrator/components/com_templates/views/template/tmpl/default_modal_rename_footer.php b/Sites/pages/administrator/components/com_templates/views/template/tmpl/default_modal_rename_footer.php new file mode 100644 index 00000000..76d06dc6 --- /dev/null +++ b/Sites/pages/administrator/components/com_templates/views/template/tmpl/default_modal_rename_footer.php @@ -0,0 +1,13 @@ + + + diff --git a/Sites/pages/administrator/components/com_templates/views/template/tmpl/default_modal_resize_body.php b/Sites/pages/administrator/components/com_templates/views/template/tmpl/default_modal_resize_body.php new file mode 100644 index 00000000..96451351 --- /dev/null +++ b/Sites/pages/administrator/components/com_templates/views/template/tmpl/default_modal_resize_body.php @@ -0,0 +1,35 @@ + +
    +
    +
    +
    + +
    +
    + +
    +
    +
    +
    + +
    +
    + +
    +
    +
    +
    diff --git a/Sites/pages/administrator/components/com_templates/views/template/tmpl/default_modal_resize_footer.php b/Sites/pages/administrator/components/com_templates/views/template/tmpl/default_modal_resize_footer.php new file mode 100644 index 00000000..91f81d04 --- /dev/null +++ b/Sites/pages/administrator/components/com_templates/views/template/tmpl/default_modal_resize_footer.php @@ -0,0 +1,13 @@ + + + diff --git a/Sites/pages/administrator/components/com_templates/views/template/tmpl/default_tree.php b/Sites/pages/administrator/components/com_templates/views/template/tmpl/default_tree.php new file mode 100644 index 00000000..73129b18 --- /dev/null +++ b/Sites/pages/administrator/components/com_templates/views/template/tmpl/default_tree.php @@ -0,0 +1,66 @@ +files, 'strnatcmp'); + +?> + diff --git a/Sites/pages/administrator/components/com_templates/views/template/tmpl/readonly.php b/Sites/pages/administrator/components/com_templates/views/template/tmpl/readonly.php new file mode 100644 index 00000000..96905f3c --- /dev/null +++ b/Sites/pages/administrator/components/com_templates/views/template/tmpl/readonly.php @@ -0,0 +1,27 @@ +input; +?> +
    + 'description')); ?> + + loadTemplate('description'); ?> + + + + +
    diff --git a/Sites/pages/administrator/components/com_templates/views/template/view.html.php b/Sites/pages/administrator/components/com_templates/views/template/view.html.php new file mode 100644 index 00000000..515bb465 --- /dev/null +++ b/Sites/pages/administrator/components/com_templates/views/template/view.html.php @@ -0,0 +1,299 @@ +file = $app->input->get('file'); + $this->fileName = JFilterInput::getInstance()->clean(base64_decode($this->file), 'string'); + $explodeArray = explode('.', $this->fileName); + $ext = end($explodeArray); + $this->files = $this->get('Files'); + $this->state = $this->get('State'); + $this->template = $this->get('Template'); + $this->preview = $this->get('Preview'); + + $params = JComponentHelper::getParams('com_templates'); + $imageTypes = explode(',', $params->get('image_formats')); + $sourceTypes = explode(',', $params->get('source_formats')); + $fontTypes = explode(',', $params->get('font_formats')); + $archiveTypes = explode(',', $params->get('compressed_formats')); + + if (in_array($ext, $sourceTypes)) + { + $this->form = $this->get('Form'); + $this->form->setFieldAttribute('source', 'syntax', $ext); + $this->source = $this->get('Source'); + $this->type = 'file'; + } + elseif (in_array($ext, $imageTypes)) + { + $this->image = $this->get('Image'); + $this->type = 'image'; + } + elseif (in_array($ext, $fontTypes)) + { + $this->font = $this->get('Font'); + $this->type = 'font'; + } + elseif (in_array($ext, $archiveTypes)) + { + $this->archive = $this->get('Archive'); + $this->type = 'archive'; + } + else + { + $this->type = 'home'; + } + + $this->overridesList = $this->get('OverridesList'); + $this->id = $this->state->get('extension.id'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + $app->enqueueMessage(implode("\n", $errors)); + + return false; + } + + $this->addToolbar(); + + if (!JFactory::getUser()->authorise('core.admin')) + { + $this->setLayout('readonly'); + } + + return parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @since 1.6 + * + * @return void + */ + protected function addToolbar() + { + $app = JFactory::getApplication(); + $user = JFactory::getUser(); + $app->input->set('hidemainmenu', true); + + // User is global SuperUser + $isSuperUser = $user->authorise('core.admin'); + + // Get the toolbar object instance + $bar = JToolbar::getInstance('toolbar'); + $explodeArray = explode('.', $this->fileName); + $ext = end($explodeArray); + + JToolbarHelper::title(JText::sprintf('COM_TEMPLATES_MANAGER_VIEW_TEMPLATE', ucfirst($this->template->name)), 'eye thememanager'); + + // Only show file edit buttons for global SuperUser + if ($isSuperUser) + { + // Add an Apply and save button + if ($this->type == 'file') + { + JToolbarHelper::apply('template.apply'); + JToolbarHelper::save('template.save'); + } + // Add a Crop and Resize button + elseif ($this->type == 'image') + { + JToolbarHelper::custom('template.cropImage', 'move', 'move', 'COM_TEMPLATES_BUTTON_CROP', false); + JToolbarHelper::modal('resizeModal', 'icon-refresh', 'COM_TEMPLATES_BUTTON_RESIZE'); + } + // Add an extract button + elseif ($this->type == 'archive') + { + JToolbarHelper::custom('template.extractArchive', 'arrow-down', 'arrow-down', 'COM_TEMPLATES_BUTTON_EXTRACT_ARCHIVE', false); + } + + // Add a copy template button (Hathor override doesn't need the button) + if ($app->getTemplate() != 'hathor') + { + JToolbarHelper::modal('copyModal', 'icon-copy', 'COM_TEMPLATES_BUTTON_COPY_TEMPLATE'); + } + } + + // Add a Template preview button + if ($this->preview->client_id == 0) + { + $bar->appendButton('Popup', 'picture', 'COM_TEMPLATES_BUTTON_PREVIEW', JUri::root() . 'index.php?tp=1&templateStyle=' . $this->preview->id, 800, 520); + } + + // Only show file manage buttons for global SuperUser + if ($isSuperUser) + { + // Add Manage folders button + JToolbarHelper::modal('folderModal', 'icon-folder icon white', 'COM_TEMPLATES_BUTTON_FOLDERS'); + + // Add a new file button + JToolbarHelper::modal('fileModal', 'icon-file', 'COM_TEMPLATES_BUTTON_FILE'); + + // Add a Rename file Button (Hathor override doesn't need the button) + if ($app->getTemplate() != 'hathor' && $this->type != 'home') + { + JToolbarHelper::modal('renameModal', 'icon-refresh', 'COM_TEMPLATES_BUTTON_RENAME_FILE'); + } + + // Add a Delete file Button + if ($this->type != 'home') + { + JToolbarHelper::modal('deleteModal', 'icon-remove', 'COM_TEMPLATES_BUTTON_DELETE_FILE'); + } + + // Add a Compile Button + if ($ext == 'less') + { + JToolbarHelper::custom('template.less', 'play', 'play', 'COM_TEMPLATES_BUTTON_LESS', false); + } + } + + if ($this->type == 'home') + { + JToolbarHelper::cancel('template.cancel', 'JTOOLBAR_CLOSE'); + } + else + { + JToolbarHelper::cancel('template.close', 'COM_TEMPLATES_BUTTON_CLOSE_FILE'); + } + + JToolbarHelper::divider(); + JToolbarHelper::help('JHELP_EXTENSIONS_TEMPLATE_MANAGER_TEMPLATES_EDIT'); + } + + /** + * Method for creating the collapsible tree. + * + * @param array $array The value of the present node for recursion + * + * @return string + * + * @note Uses recursion + * @since 3.2 + */ + protected function directoryTree($array) + { + $temp = $this->files; + $this->files = $array; + $txt = $this->loadTemplate('tree'); + $this->files = $temp; + + return $txt; + } + + /** + * Method for listing the folder tree in modals. + * + * @param array $array The value of the present node for recursion + * + * @return string + * + * @note Uses recursion + * @since 3.2 + */ + protected function folderTree($array) + { + $temp = $this->files; + $this->files = $array; + $txt = $this->loadTemplate('folders'); + $this->files = $temp; + + return $txt; + } +} diff --git a/Sites/pages/administrator/components/com_templates/views/templates/tmpl/default.php b/Sites/pages/administrator/components/com_templates/views/templates/tmpl/default.php new file mode 100644 index 00000000..ab1673dd --- /dev/null +++ b/Sites/pages/administrator/components/com_templates/views/templates/tmpl/default.php @@ -0,0 +1,113 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +?> + +
    +sidebar)) : ?> +
    + sidebar; ?> +
    +
    + +
    + + $this, 'options' => array('selectorFieldName' => 'client_id'))); ?> + total > 0) : ?> + + + + + + + + + + + + + + + + + items as $i => $item) : ?> + + + + + + + + + +
    + + + + + + + + + +
    + pagination->getListFooter(); ?> +
    + element, $item->client_id); ?> + element, $item->client_id); ?> + + + name)); ?> +
    + preview && $item->client_id == '0') : ?> + + + + client_id == '1') : ?> + + + + +
    +
    + escape($item->xmldata->get('version')); ?> + + escape($item->xmldata->get('creationDate')); ?> + + xmldata->get('author')) : ?> +
    escape($author); ?>
    + + — + + xmldata->get('authorEmail')) : ?> +
    escape($email); ?>
    + + xmldata->get('authorUrl')) : ?> + + +
    + + + + + +
    + diff --git a/Sites/pages/administrator/components/com_templates/views/templates/tmpl/default.xml b/Sites/pages/administrator/components/com_templates/views/templates/tmpl/default.xml new file mode 100755 index 00000000..b867cf71 --- /dev/null +++ b/Sites/pages/administrator/components/com_templates/views/templates/tmpl/default.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/Sites/pages/administrator/components/com_templates/views/templates/view.html.php b/Sites/pages/administrator/components/com_templates/views/templates/view.html.php new file mode 100644 index 00000000..7911e449 --- /dev/null +++ b/Sites/pages/administrator/components/com_templates/views/templates/view.html.php @@ -0,0 +1,109 @@ +items = $this->get('Items'); + $this->pagination = $this->get('Pagination'); + $this->state = $this->get('State'); + $this->total = $this->get('Total'); + $this->filterForm = $this->get('FilterForm'); + $this->activeFilters = $this->get('ActiveFilters'); + $this->preview = JComponentHelper::getParams('com_templates')->get('template_positions_display'); + $this->file = base64_encode('home'); + + TemplatesHelper::addSubmenu('templates'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + $this->addToolbar(); + + return parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + $canDo = JHelperContent::getActions('com_templates'); + + // Set the title. + if ((int) $this->get('State')->get('client_id') === 1) + { + JToolbarHelper::title(JText::_('COM_TEMPLATES_MANAGER_TEMPLATES_ADMIN'), 'eye thememanager'); + } + else + { + JToolbarHelper::title(JText::_('COM_TEMPLATES_MANAGER_TEMPLATES_SITE'), 'eye thememanager'); + } + + if ($canDo->get('core.admin') || $canDo->get('core.options')) + { + JToolbarHelper::preferences('com_templates'); + JToolbarHelper::divider(); + } + + JToolbarHelper::help('JHELP_EXTENSIONS_TEMPLATE_MANAGER_TEMPLATES'); + + JHtmlSidebar::setAction('index.php?option=com_templates&view=templates'); + + $this->sidebar = JHtmlSidebar::render(); + } +} diff --git a/Sites/pages/administrator/components/com_users/access.xml b/Sites/pages/administrator/components/com_users/access.xml new file mode 100644 index 00000000..01051d5e --- /dev/null +++ b/Sites/pages/administrator/components/com_users/access.xml @@ -0,0 +1,34 @@ + + +
    + + + + + + + + +
    +
    + + + + + +
    +
    + + + + + + +
    +
    + + + + +
    +
    diff --git a/Sites/pages/administrator/components/com_users/config.xml b/Sites/pages/administrator/components/com_users/config.xml new file mode 100644 index 00000000..39bb03f6 --- /dev/null +++ b/Sites/pages/administrator/components/com_users/config.xml @@ -0,0 +1,364 @@ + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + +
    + +
    + + + + + + + + + + + + + + +
    + +
    + + + + + + + + +
    + +
    + + + + + +
    + +
    + + + + + + + + + + + +
    + +
    + + + + + + + + + + + + + + + +
    + +
    + + + +
    +
    diff --git a/Sites/pages/administrator/components/com_users/controller.php b/Sites/pages/administrator/components/com_users/controller.php new file mode 100644 index 00000000..b9efac5d --- /dev/null +++ b/Sites/pages/administrator/components/com_users/controller.php @@ -0,0 +1,109 @@ +get('core.admin'); + break; + + // Default permissions. + default: + return true; + } + } + + /** + * Method to display a view. + * + * @param boolean $cachable If true, the view output will be cached + * @param array $urlparams An array of safe URL parameters and their variable types, for valid values see {@link JFilterInput::clean()}. + * + * @return JController This object to support chaining. + * + * @since 1.5 + */ + public function display($cachable = false, $urlparams = false) + { + $view = $this->input->get('view', 'users'); + $layout = $this->input->get('layout', 'default'); + $id = $this->input->getInt('id'); + + if (!$this->canView($view)) + { + throw new JAccessExceptionNotallowed(JText::_('JERROR_ALERTNOAUTHOR'), 403); + } + + // Check for edit form. + if ($view == 'user' && $layout == 'edit' && !$this->checkEditId('com_users.edit.user', $id)) + { + // Somehow the person just went to the form - we don't allow that. + $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id)); + $this->setMessage($this->getError(), 'error'); + $this->setRedirect(JRoute::_('index.php?option=com_users&view=users', false)); + + return false; + } + elseif ($view == 'group' && $layout == 'edit' && !$this->checkEditId('com_users.edit.group', $id)) + { + // Somehow the person just went to the form - we don't allow that. + $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id)); + $this->setMessage($this->getError(), 'error'); + $this->setRedirect(JRoute::_('index.php?option=com_users&view=groups', false)); + + return false; + } + elseif ($view == 'level' && $layout == 'edit' && !$this->checkEditId('com_users.edit.level', $id)) + { + // Somehow the person just went to the form - we don't allow that. + $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id)); + $this->setMessage($this->getError(), 'error'); + $this->setRedirect(JRoute::_('index.php?option=com_users&view=levels', false)); + + return false; + } + elseif ($view == 'note' && $layout == 'edit' && !$this->checkEditId('com_users.edit.note', $id)) + { + // Somehow the person just went to the form - we don't allow that. + $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id)); + $this->setMessage($this->getError(), 'error'); + $this->setRedirect(JRoute::_('index.php?option=com_users&view=notes', false)); + + return false; + } + + return parent::display(); + } +} diff --git a/Sites/pages/administrator/components/com_users/controllers/group.php b/Sites/pages/administrator/components/com_users/controllers/group.php new file mode 100644 index 00000000..920bfe93 --- /dev/null +++ b/Sites/pages/administrator/components/com_users/controllers/group.php @@ -0,0 +1,68 @@ +authorise('core.admin', $this->option) && parent::allowSave($data, $key)); + } + + /** + * Overrides JControllerForm::allowEdit + * + * Checks that non-Super Admins are not editing Super Admins. + * + * @param array $data An array of input data. + * @param string $key The name of the key for the primary key. + * + * @return boolean + * + * @since 1.6 + */ + protected function allowEdit($data = array(), $key = 'id') + { + // Check if this group is a Super Admin + if (JAccess::checkGroup($data[$key], 'core.admin')) + { + // If I'm not a Super Admin, then disallow the edit. + if (!JFactory::getUser()->authorise('core.admin')) + { + return false; + } + } + + return parent::allowEdit($data, $key); + } +} diff --git a/Sites/pages/administrator/components/com_users/controllers/groups.php b/Sites/pages/administrator/components/com_users/controllers/groups.php new file mode 100644 index 00000000..027a48f3 --- /dev/null +++ b/Sites/pages/administrator/components/com_users/controllers/groups.php @@ -0,0 +1,140 @@ + true)); + } + + /** + * Removes an item. + * + * Overrides JControllerAdmin::delete to check the core.admin permission. + * + * @return boolean Returns true on success, false on failure. + * + * @since 1.6 + */ + public function delete() + { + if (!JFactory::getUser()->authorise('core.admin', $this->option)) + { + JError::raiseError(500, JText::_('JERROR_ALERTNOAUTHOR')); + jexit(); + } + + return parent::delete(); + } + + /** + * Method to publish a list of records. + * + * Overrides JControllerAdmin::publish to check the core.admin permission. + * + * @return void + * + * @since 1.6 + */ + public function publish() + { + if (!JFactory::getUser()->authorise('core.admin', $this->option)) + { + JError::raiseError(500, JText::_('JERROR_ALERTNOAUTHOR')); + jexit(); + } + + return parent::publish(); + } + + /** + * Changes the order of one or more records. + * + * Overrides JControllerAdmin::reorder to check the core.admin permission. + * + * @return boolean True on success + * + * @since 1.6 + */ + public function reorder() + { + if (!JFactory::getUser()->authorise('core.admin', $this->option)) + { + JError::raiseError(500, JText::_('JERROR_ALERTNOAUTHOR')); + jexit(); + } + + return parent::reorder(); + } + + /** + * Method to save the submitted ordering values for records. + * + * Overrides JControllerAdmin::saveorder to check the core.admin permission. + * + * @return boolean True on success + * + * @since 1.6 + */ + public function saveorder() + { + if (!JFactory::getUser()->authorise('core.admin', $this->option)) + { + JError::raiseError(500, JText::_('JERROR_ALERTNOAUTHOR')); + jexit(); + } + + return parent::saveorder(); + } + + /** + * Check in of one or more records. + * + * Overrides JControllerAdmin::checkin to check the core.admin permission. + * + * @return boolean True on success + * + * @since 1.6 + */ + public function checkin() + { + if (!JFactory::getUser()->authorise('core.admin', $this->option)) + { + JError::raiseError(500, JText::_('JERROR_ALERTNOAUTHOR')); + jexit(); + } + + return parent::checkin(); + } +} diff --git a/Sites/pages/administrator/components/com_users/controllers/level.php b/Sites/pages/administrator/components/com_users/controllers/level.php new file mode 100644 index 00000000..5adf2065 --- /dev/null +++ b/Sites/pages/administrator/components/com_users/controllers/level.php @@ -0,0 +1,130 @@ +authorise('core.admin', $this->option) && parent::allowSave($data, $key)); + } + + /** + * Overrides JControllerForm::allowEdit + * + * Checks that non-Super Admins are not editing Super Admins. + * + * @param array $data An array of input data. + * @param string $key The name of the key for the primary key. + * + * @return boolean + * + * @since 3.8.8 + */ + protected function allowEdit($data = array(), $key = 'id') + { + // Get user instance + $user = JFactory::getUser(); + + // Check for if Super Admin can edit + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->select('*') + ->from($db->quoteName('#__viewlevels')) + ->where($db->quoteName('id') . ' = ' . (int) $data['id']); + $db->setQuery($query); + + $viewlevel = $db->loadAssoc(); + + // Decode level groups + $groups = json_decode($viewlevel['rules']); + + // If this group is super admin and this user is not super admin, canEdit is false + if (!$user->authorise('core.admin') && JAccess::checkGroup($groups[0], 'core.admin')) + { + $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_EDIT_NOT_PERMITTED')); + + return false; + } + + return parent::allowEdit($data, $key); + } + + /** + * Removes an item. + * + * Overrides JControllerAdmin::delete to check the core.admin permission. + * + * @return boolean Returns true on success, false on failure. + * + * @since 1.6 + */ + public function delete() + { + // Check for request forgeries. + $this->checkToken(); + + $ids = $this->input->get('cid', array(), 'array'); + + if (!JFactory::getUser()->authorise('core.admin', $this->option)) + { + JError::raiseError(500, JText::_('JERROR_ALERTNOAUTHOR')); + jexit(); + } + elseif (empty($ids)) + { + JError::raiseWarning(500, JText::_('COM_USERS_NO_LEVELS_SELECTED')); + } + else + { + // Get the model. + $model = $this->getModel(); + + $ids = ArrayHelper::toInteger($ids); + + // Remove the items. + if (!$model->delete($ids)) + { + JError::raiseWarning(500, $model->getError()); + } + else + { + $this->setMessage(JText::plural('COM_USERS_N_LEVELS_DELETED', count($ids))); + } + } + + $this->setRedirect('index.php?option=com_users&view=levels'); + } +} diff --git a/Sites/pages/administrator/components/com_users/controllers/levels.php b/Sites/pages/administrator/components/com_users/controllers/levels.php new file mode 100644 index 00000000..6b0de010 --- /dev/null +++ b/Sites/pages/administrator/components/com_users/controllers/levels.php @@ -0,0 +1,40 @@ + true)); + } +} diff --git a/Sites/pages/administrator/components/com_users/controllers/mail.php b/Sites/pages/administrator/components/com_users/controllers/mail.php new file mode 100644 index 00000000..dee1dcad --- /dev/null +++ b/Sites/pages/administrator/components/com_users/controllers/mail.php @@ -0,0 +1,69 @@ +get('massmailoff', 0) == 1) + { + JFactory::getApplication()->redirect(JRoute::_('index.php', false)); + } + + // Check for request forgeries. + $this->checkToken('request'); + + $model = $this->getModel('Mail'); + + if ($model->send()) + { + $type = 'message'; + } + else + { + $type = 'error'; + } + + $msg = $model->getError(); + $this->setRedirect('index.php?option=com_users&view=mail', $msg, $type); + } + + /** + * Cancel the mail + * + * @return void + * + * @since 1.6 + */ + public function cancel() + { + // Check for request forgeries. + $this->checkToken('request'); + + // Clear data from session. + \JFactory::getApplication()->setUserState('com_users.display.mail.data', null); + + $this->setRedirect('index.php'); + } +} diff --git a/Sites/pages/administrator/components/com_users/controllers/note.php b/Sites/pages/administrator/components/com_users/controllers/note.php new file mode 100644 index 00000000..24ec2d42 --- /dev/null +++ b/Sites/pages/administrator/components/com_users/controllers/note.php @@ -0,0 +1,50 @@ +input->get('u_id', 0, 'int'); + + if ($userId) + { + $append .= '&u_id=' . $userId; + } + + return $append; + } +} diff --git a/Sites/pages/administrator/components/com_users/controllers/notes.php b/Sites/pages/administrator/components/com_users/controllers/notes.php new file mode 100644 index 00000000..293b1f4a --- /dev/null +++ b/Sites/pages/administrator/components/com_users/controllers/notes.php @@ -0,0 +1,42 @@ + true)) + { + return parent::getModel($name, $prefix, $config); + } +} diff --git a/Sites/pages/administrator/components/com_users/controllers/user.php b/Sites/pages/administrator/components/com_users/controllers/user.php new file mode 100644 index 00000000..e8083a62 --- /dev/null +++ b/Sites/pages/administrator/components/com_users/controllers/user.php @@ -0,0 +1,88 @@ +authorise('core.admin')) + { + return false; + } + } + + return parent::allowEdit($data, $key); + } + + /** + * Method to run batch operations. + * + * @param object $model The model. + * + * @return boolean True on success, false on failure + * + * @since 2.5 + */ + public function batch($model = null) + { + $this->checkToken(); + + // Set the model + $model = $this->getModel('User', '', array()); + + // Preset the redirect + $this->setRedirect(JRoute::_('index.php?option=com_users&view=users' . $this->getRedirectToListAppend(), false)); + + return parent::batch($model); + } + + /** + * Function that allows child controller access to model data after the data has been saved. + * + * @param JModelLegacy $model The data model object. + * @param array $validData The validated data. + * + * @return void + * + * @since 3.1 + */ + protected function postSaveHook(JModelLegacy $model, $validData = array()) + { + return; + } +} diff --git a/Sites/pages/administrator/components/com_users/controllers/users.php b/Sites/pages/administrator/components/com_users/controllers/users.php new file mode 100644 index 00000000..4769e286 --- /dev/null +++ b/Sites/pages/administrator/components/com_users/controllers/users.php @@ -0,0 +1,142 @@ +registerTask('block', 'changeBlock'); + $this->registerTask('unblock', 'changeBlock'); + } + + /** + * Proxy for getModel. + * + * @param string $name The model name. Optional. + * @param string $prefix The class prefix. Optional. + * @param array $config Configuration array for model. Optional. + * + * @return object The model. + * + * @since 1.6 + */ + public function getModel($name = 'User', $prefix = 'UsersModel', $config = array('ignore_request' => true)) + { + return parent::getModel($name, $prefix, $config); + } + + /** + * Method to change the block status on a record. + * + * @return void + * + * @since 1.6 + */ + public function changeBlock() + { + // Check for request forgeries. + $this->checkToken(); + + $ids = $this->input->get('cid', array(), 'array'); + $values = array('block' => 1, 'unblock' => 0); + $task = $this->getTask(); + $value = ArrayHelper::getValue($values, $task, 0, 'int'); + + if (empty($ids)) + { + JError::raiseWarning(500, JText::_('COM_USERS_USERS_NO_ITEM_SELECTED')); + } + else + { + // Get the model. + $model = $this->getModel(); + + // Change the state of the records. + if (!$model->block($ids, $value)) + { + JError::raiseWarning(500, $model->getError()); + } + else + { + if ($value == 1) + { + $this->setMessage(JText::plural('COM_USERS_N_USERS_BLOCKED', count($ids))); + } + elseif ($value == 0) + { + $this->setMessage(JText::plural('COM_USERS_N_USERS_UNBLOCKED', count($ids))); + } + } + } + + $this->setRedirect('index.php?option=com_users&view=users'); + } + + /** + * Method to activate a record. + * + * @return void + * + * @since 1.6 + */ + public function activate() + { + // Check for request forgeries. + $this->checkToken(); + + $ids = $this->input->get('cid', array(), 'array'); + + if (empty($ids)) + { + JError::raiseWarning(500, JText::_('COM_USERS_USERS_NO_ITEM_SELECTED')); + } + else + { + // Get the model. + $model = $this->getModel(); + + // Change the state of the records. + if (!$model->activate($ids)) + { + JError::raiseWarning(500, $model->getError()); + } + else + { + $this->setMessage(JText::plural('COM_USERS_N_USERS_ACTIVATED', count($ids))); + } + } + + $this->setRedirect('index.php?option=com_users&view=users'); + } +} diff --git a/Sites/pages/administrator/components/com_users/helpers/debug.php b/Sites/pages/administrator/components/com_users/helpers/debug.php new file mode 100644 index 00000000..4c7795cc --- /dev/null +++ b/Sites/pages/administrator/components/com_users/helpers/debug.php @@ -0,0 +1,154 @@ +getQuery(true) + ->select('name AS text, element AS value') + ->from('#__extensions') + ->where('enabled >= 1') + ->where('type =' . $db->quote('component')); + + $items = $db->setQuery($query)->loadObjectList(); + + if (count($items)) + { + $lang = JFactory::getLanguage(); + + foreach ($items as &$item) + { + // Load language + $extension = $item->value; + $source = JPATH_ADMINISTRATOR . '/components/' . $extension; + $lang->load("$extension.sys", JPATH_ADMINISTRATOR, null, false, true) + || $lang->load("$extension.sys", $source, null, false, true); + + // Translate component name + $item->text = JText::_($item->text); + } + + // Sort by component name + $items = ArrayHelper::sortObjects($items, 'text', 1, true, true); + } + + return $items; + } + + /** + * Get a list of the actions for the component or code actions. + * + * @param string $component The name of the component. + * + * @return array + * + * @since 1.6 + */ + public static function getDebugActions($component = null) + { + $actions = array(); + + // Try to get actions for the component + if (!empty($component)) + { + $component_actions = JAccess::getActions($component); + + if (!empty($component_actions)) + { + foreach ($component_actions as &$action) + { + $actions[$action->title] = array($action->name, $action->description); + } + } + } + + // Use default actions from configuration if no component selected or component doesn't have actions + if (empty($actions)) + { + $filename = JPATH_ADMINISTRATOR . '/components/com_config/model/form/application.xml'; + + if (is_file($filename)) + { + $xml = simplexml_load_file($filename); + + foreach ($xml->children()->fieldset as $fieldset) + { + if ('permissions' == (string) $fieldset['name']) + { + foreach ($fieldset->children() as $field) + { + if ('rules' == (string) $field['name']) + { + foreach ($field->children() as $action) + { + $actions[(string) $action['title']] = array( + (string) $action['name'], + (string) $action['description'] + ); + } + + break; + } + } + } + } + + // Load language + $lang = JFactory::getLanguage(); + $extension = 'com_config'; + $source = JPATH_ADMINISTRATOR . '/components/' . $extension; + + $lang->load($extension, JPATH_ADMINISTRATOR, null, false, false) + || $lang->load($extension, $source, null, false, false) + || $lang->load($extension, JPATH_ADMINISTRATOR, $lang->getDefault(), false, false) + || $lang->load($extension, $source, $lang->getDefault(), false, false); + } + } + + return $actions; + } + + /** + * Get a list of filter options for the levels. + * + * @return array An array of JHtmlOption elements. + */ + public static function getLevelsOptions() + { + // Build the filter options. + $options = array(); + $options[] = JHtml::_('select.option', '1', JText::sprintf('COM_USERS_OPTION_LEVEL_COMPONENT', 1)); + $options[] = JHtml::_('select.option', '2', JText::sprintf('COM_USERS_OPTION_LEVEL_CATEGORY', 2)); + $options[] = JHtml::_('select.option', '3', JText::sprintf('COM_USERS_OPTION_LEVEL_DEEPER', 3)); + $options[] = JHtml::_('select.option', '4', '4'); + $options[] = JHtml::_('select.option', '5', '5'); + $options[] = JHtml::_('select.option', '6', '6'); + + return $options; + } +} diff --git a/Sites/pages/administrator/components/com_users/helpers/html/users.php b/Sites/pages/administrator/components/com_users/helpers/html/users.php new file mode 100644 index 00000000..0320cc47 --- /dev/null +++ b/Sites/pages/administrator/components/com_users/helpers/html/users.php @@ -0,0 +1,241 @@ + element if the specified file exists, otherwise, a null string + * + * @since 2.5 + */ + public static function image($src) + { + $src = preg_replace('#[^A-Z0-9\-_\./]#i', '', $src); + $file = JPATH_SITE . '/' . $src; + + jimport('joomla.filesystem.path'); + JPath::check($file); + + if (!file_exists($file)) + { + return ''; + } + + return ''; + } + + /** + * Displays an icon to add a note for this user. + * + * @param integer $userId The user ID + * + * @return string A link to add a note + * + * @since 2.5 + */ + public static function addNote($userId) + { + $title = JText::_('COM_USERS_ADD_NOTE'); + + return '' . $title . ''; + } + + /** + * Displays an icon to filter the notes list on this user. + * + * @param integer $count The number of notes for the user + * @param integer $userId The user ID + * + * @return string A link to apply a filter + * + * @since 2.5 + */ + public static function filterNotes($count, $userId) + { + if (empty($count)) + { + return ''; + } + + $title = JText::_('COM_USERS_FILTER_NOTES'); + + return ''; + } + + /** + * Displays a note icon. + * + * @param integer $count The number of notes for the user + * @param integer $userId The user ID + * + * @return string A link to a modal window with the user notes + * + * @since 2.5 + */ + public static function notes($count, $userId) + { + if (empty($count)) + { + return ''; + } + + $title = JText::plural('COM_USERS_N_USER_NOTES', $count); + + return ''; + } + + /** + * Renders the modal html. + * + * @param integer $count The number of notes for the user + * @param integer $userId The user ID + * + * @return string The html for the rendered modal + * + * @since 3.4.1 + */ + public static function notesModal($count, $userId) + { + if (empty($count)) + { + return ''; + } + + $title = JText::plural('COM_USERS_N_USER_NOTES', $count); + $footer = ''; + + return JHtml::_( + 'bootstrap.renderModal', + 'userModal_' . (int) $userId, + array( + 'title' => $title, + 'backdrop' => 'static', + 'keyboard' => true, + 'closeButton' => true, + 'footer' => $footer, + 'url' => JRoute::_('index.php?option=com_users&view=notes&tmpl=component&layout=modal&filter[user_id]=' . (int) $userId), + 'height' => '300px', + 'width' => '800px', + ) + ); + + } + + /** + * Build an array of block/unblock user states to be used by jgrid.state, + * State options will be different for any user + * and for currently logged in user + * + * @param boolean $self True if state array is for currently logged in user + * + * @return array a list of possible states to display + * + * @since 3.0 + */ + public static function blockStates( $self = false) + { + if ($self) + { + $states = array( + 1 => array( + 'task' => 'unblock', + 'text' => '', + 'active_title' => 'COM_USERS_USER_FIELD_BLOCK_DESC', + 'inactive_title' => '', + 'tip' => true, + 'active_class' => 'unpublish', + 'inactive_class' => 'unpublish', + ), + 0 => array( + 'task' => 'block', + 'text' => '', + 'active_title' => '', + 'inactive_title' => 'COM_USERS_USERS_ERROR_CANNOT_BLOCK_SELF', + 'tip' => true, + 'active_class' => 'publish', + 'inactive_class' => 'publish', + ) + ); + } + else + { + $states = array( + 1 => array( + 'task' => 'unblock', + 'text' => '', + 'active_title' => 'COM_USERS_TOOLBAR_UNBLOCK', + 'inactive_title' => '', + 'tip' => true, + 'active_class' => 'unpublish', + 'inactive_class' => 'unpublish', + ), + 0 => array( + 'task' => 'block', + 'text' => '', + 'active_title' => 'COM_USERS_USER_FIELD_BLOCK_DESC', + 'inactive_title' => '', + 'tip' => true, + 'active_class' => 'publish', + 'inactive_class' => 'publish', + ) + ); + } + + return $states; + } + + /** + * Build an array of activate states to be used by jgrid.state, + * + * @return array a list of possible states to display + * + * @since 3.0 + */ + public static function activateStates() + { + $states = array( + 1 => array( + 'task' => 'activate', + 'text' => '', + 'active_title' => 'COM_USERS_TOOLBAR_ACTIVATE', + 'inactive_title' => '', + 'tip' => true, + 'active_class' => 'unpublish', + 'inactive_class' => 'unpublish', + ), + 0 => array( + 'task' => '', + 'text' => '', + 'active_title' => '', + 'inactive_title' => 'COM_USERS_ACTIVATED', + 'tip' => true, + 'active_class' => 'publish', + 'inactive_class' => 'publish', + ) + ); + + return $states; + } +} diff --git a/Sites/pages/administrator/components/com_users/helpers/users.php b/Sites/pages/administrator/components/com_users/helpers/users.php new file mode 100644 index 00000000..b283325f --- /dev/null +++ b/Sites/pages/administrator/components/com_users/helpers/users.php @@ -0,0 +1,304 @@ +get('core.admin')) + { + JHtmlSidebar::addEntry( + JText::_('COM_USERS_SUBMENU_GROUPS'), + 'index.php?option=com_users&view=groups', + $vName == 'groups' + ); + JHtmlSidebar::addEntry( + JText::_('COM_USERS_SUBMENU_LEVELS'), + 'index.php?option=com_users&view=levels', + $vName == 'levels' + ); + } + + if (JComponentHelper::isEnabled('com_fields') && JComponentHelper::getParams('com_users')->get('custom_fields_enable', '1')) + { + JHtmlSidebar::addEntry( + JText::_('JGLOBAL_FIELDS'), + 'index.php?option=com_fields&context=com_users.user', + $vName == 'fields.fields' + ); + JHtmlSidebar::addEntry( + JText::_('JGLOBAL_FIELD_GROUPS'), + 'index.php?option=com_fields&view=groups&context=com_users.user', + $vName == 'fields.groups' + ); + } + + JHtmlSidebar::addEntry( + JText::_('COM_USERS_SUBMENU_NOTES'), + 'index.php?option=com_users&view=notes', + $vName == 'notes' + ); + + JHtmlSidebar::addEntry( + JText::_('COM_USERS_SUBMENU_NOTE_CATEGORIES'), + 'index.php?option=com_categories&extension=com_users', + $vName == 'categories' + ); + } + + /** + * Gets a list of the actions that can be performed. + * + * @return JObject + * + * @deprecated 3.2 Use JHelperContent::getActions() instead + */ + public static function getActions() + { + // Log usage of deprecated function + try + { + JLog::add( + sprintf('%s() is deprecated. Use JHelperContent::getActions() with new arguments order instead.', __METHOD__), + JLog::WARNING, + 'deprecated' + ); + } + catch (RuntimeException $exception) + { + // Informational log only + } + + // Get list of actions + return JHelperContent::getActions('com_users'); + } + + /** + * Get a list of filter options for the blocked state of a user. + * + * @return array An array of JHtmlOption elements. + * + * @since 1.6 + */ + public static function getStateOptions() + { + // Build the filter options. + $options = array(); + $options[] = JHtml::_('select.option', '0', JText::_('JENABLED')); + $options[] = JHtml::_('select.option', '1', JText::_('JDISABLED')); + + return $options; + } + + /** + * Get a list of filter options for the activated state of a user. + * + * @return array An array of JHtmlOption elements. + * + * @since 1.6 + */ + public static function getActiveOptions() + { + // Build the filter options. + $options = array(); + $options[] = JHtml::_('select.option', '0', JText::_('COM_USERS_ACTIVATED')); + $options[] = JHtml::_('select.option', '1', JText::_('COM_USERS_UNACTIVATED')); + + return $options; + } + + /** + * Get a list of the user groups for filtering. + * + * @return array An array of JHtmlOption elements. + * + * @since 1.6 + */ + public static function getGroups() + { + $options = JHelperUsergroups::getInstance()->getAll(); + + foreach ($options as &$option) + { + $option->value = $option->id; + $option->text = str_repeat('- ', $option->level) . $option->title; + } + + return $options; + } + + /** + * Creates a list of range options used in filter select list + * used in com_users on users view + * + * @return array + * + * @since 2.5 + */ + public static function getRangeOptions() + { + $options = array( + JHtml::_('select.option', 'today', JText::_('COM_USERS_OPTION_RANGE_TODAY')), + JHtml::_('select.option', 'past_week', JText::_('COM_USERS_OPTION_RANGE_PAST_WEEK')), + JHtml::_('select.option', 'past_1month', JText::_('COM_USERS_OPTION_RANGE_PAST_1MONTH')), + JHtml::_('select.option', 'past_3month', JText::_('COM_USERS_OPTION_RANGE_PAST_3MONTH')), + JHtml::_('select.option', 'past_6month', JText::_('COM_USERS_OPTION_RANGE_PAST_6MONTH')), + JHtml::_('select.option', 'past_year', JText::_('COM_USERS_OPTION_RANGE_PAST_YEAR')), + JHtml::_('select.option', 'post_year', JText::_('COM_USERS_OPTION_RANGE_POST_YEAR')), + ); + + return $options; + } + + /** + * Creates a list of two factor authentication methods used in com_users + * on user view + * + * @return array + * + * @since 3.2.0 + */ + public static function getTwoFactorMethods() + { + FOFPlatform::getInstance()->importPlugin('twofactorauth'); + $identities = FOFPlatform::getInstance()->runPlugins('onUserTwofactorIdentify', array()); + + $options = array( + JHtml::_('select.option', 'none', JText::_('JGLOBAL_OTPMETHOD_NONE'), 'value', 'text'), + ); + + if (!empty($identities)) + { + foreach ($identities as $identity) + { + if (!is_object($identity)) + { + continue; + } + + $options[] = JHtml::_('select.option', $identity->method, $identity->title, 'value', 'text'); + } + } + + return $options; + } + + /** + * Get a list of the User Groups for Viewing Access Levels + * + * @param string $rules User Groups in JSON format + * + * @return string $groups Comma separated list of User Groups + * + * @since 3.6 + */ + public static function getVisibleByGroups($rules) + { + $rules = json_decode($rules); + + if (!$rules) + { + return false; + } + + $rules = implode(',', $rules); + + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->select('a.title AS text') + ->from('#__usergroups as a') + ->where('a.id IN (' . $rules . ')'); + $db->setQuery($query); + + $groups = $db->loadColumn(); + $groups = implode(', ', $groups); + + return $groups; + } + + /** + * Returns a valid section for users. If it is not valid then null + * is returned. + * + * @param string $section The section to get the mapping for + * + * @return string|null The new section + * + * @since 3.7.0 + */ + public static function validateSection($section) + { + if (JFactory::getApplication()->isClient('site')) + { + switch ($section) + { + case 'registration': + case 'profile': + $section = 'user'; + } + } + + if ($section != 'user') + { + // We don't know other sections + return null; + } + + return $section; + } + + /** + * Returns valid contexts + * + * @return array + * + * @since 3.7.0 + */ + public static function getContexts() + { + JFactory::getLanguage()->load('com_users', JPATH_ADMINISTRATOR); + + $contexts = array( + 'com_users.user' => JText::_('COM_USERS'), + ); + + return $contexts; + } +} diff --git a/Sites/pages/administrator/components/com_users/models/debuggroup.php b/Sites/pages/administrator/components/com_users/models/debuggroup.php new file mode 100644 index 00000000..e7c4670c --- /dev/null +++ b/Sites/pages/administrator/components/com_users/models/debuggroup.php @@ -0,0 +1,264 @@ +getState('filter.component'); + + return UsersHelperDebug::getDebugActions($component); + } + + /** + * Override getItems method. + * + * @return array + * + * @since 1.6 + */ + public function getItems() + { + $groupId = $this->getState('group_id'); + + if (($assets = parent::getItems()) && $groupId) + { + $actions = $this->getDebugActions(); + + foreach ($assets as &$asset) + { + $asset->checks = array(); + + foreach ($actions as $action) + { + $name = $action[0]; + + $asset->checks[$name] = JAccess::checkGroup($groupId, $name, $asset->name); + } + } + } + + return $assets; + } + + /** + * Method to auto-populate the model state. + * + * Note. Calling getState in this method will result in recursion. + * + * @param string $ordering An optional ordering field. + * @param string $direction An optional direction (asc|desc). + * + * @return void + * + * @since 1.6 + */ + protected function populateState($ordering = 'a.lft', $direction = 'asc') + { + $app = JFactory::getApplication('administrator'); + + // Adjust the context to support modal layouts. + $layout = $app->input->get('layout', 'default'); + + if ($layout) + { + $this->context .= '.' . $layout; + } + + // Load the filter state. + $this->setState('filter.search', $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search', '', 'string')); + $this->setState('group_id', $this->getUserStateFromRequest($this->context . '.group_id', 'group_id', 0, 'int', false)); + + $levelStart = $this->getUserStateFromRequest($this->context . '.filter.level_start', 'filter_level_start', '', 'cmd'); + $this->setState('filter.level_start', $levelStart); + + $value = $this->getUserStateFromRequest($this->context . '.filter.level_end', 'filter_level_end', '', 'cmd'); + + if ($value > 0 && $value < $levelStart) + { + $value = $levelStart; + } + + $this->setState('filter.level_end', $value); + + $this->setState('filter.component', $this->getUserStateFromRequest($this->context . '.filter.component', 'filter_component', '', 'string')); + + // Load the parameters. + $params = JComponentHelper::getParams('com_users'); + $this->setState('params', $params); + + // List state information. + parent::populateState($ordering, $direction); + } + + /** + * Method to get a store id based on model configuration state. + * + * This is necessary because the model is used by the component and + * different modules that might need different sets of data or different + * ordering requirements. + * + * @param string $id A prefix for the store id. + * + * @return string A store id. + */ + protected function getStoreId($id = '') + { + // Compile the store id. + $id .= ':' . $this->getState('group_id'); + $id .= ':' . $this->getState('filter.search'); + $id .= ':' . $this->getState('filter.level_start'); + $id .= ':' . $this->getState('filter.level_end'); + $id .= ':' . $this->getState('filter.component'); + + return parent::getStoreId($id); + } + + /** + * Get the group being debugged. + * + * @return JObject + * + * @since 1.6 + */ + public function getGroup() + { + $groupId = (int) $this->getState('group_id'); + + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select('id, title') + ->from('#__usergroups') + ->where('id = ' . $groupId); + + $db->setQuery($query); + + try + { + $group = $db->loadObject(); + } + catch (RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + + return $group; + } + + /** + * Build an SQL query to load the list data. + * + * @return JDatabaseQuery + * + * @since 1.6 + */ + protected function getListQuery() + { + // Create a new query object. + $db = $this->getDbo(); + $query = $db->getQuery(true); + + // Select the required fields from the table. + $query->select( + $this->getState( + 'list.select', + 'a.id, a.name, a.title, a.level, a.lft, a.rgt' + ) + ); + $query->from($db->quoteName('#__assets', 'a')); + + // Filter the items over the search string if set. + if ($this->getState('filter.search')) + { + // Escape the search token. + $search = $db->quote('%' . str_replace(' ', '%', $db->escape(trim($this->getState('filter.search')), true) . '%')); + + // Compile the different search clauses. + $searches = array(); + $searches[] = 'a.name LIKE ' . $search; + $searches[] = 'a.title LIKE ' . $search; + + // Add the clauses to the query. + $query->where('(' . implode(' OR ', $searches) . ')'); + } + + // Filter on the start and end levels. + $levelStart = (int) $this->getState('filter.level_start'); + $levelEnd = (int) $this->getState('filter.level_end'); + + if ($levelEnd > 0 && $levelEnd < $levelStart) + { + $levelEnd = $levelStart; + } + + if ($levelStart > 0) + { + $query->where('a.level >= ' . $levelStart); + } + + if ($levelEnd > 0) + { + $query->where('a.level <= ' . $levelEnd); + } + + // Filter the items over the component if set. + if ($this->getState('filter.component')) + { + $component = $this->getState('filter.component'); + $query->where('(a.name = ' . $db->quote($component) . ' OR a.name LIKE ' . $db->quote($component . '.%') . ')'); + } + + // Add the list ordering clause. + $query->order($db->escape($this->getState('list.ordering', 'a.lft')) . ' ' . $db->escape($this->getState('list.direction', 'ASC'))); + + return $query; + } +} diff --git a/Sites/pages/administrator/components/com_users/models/debuguser.php b/Sites/pages/administrator/components/com_users/models/debuguser.php new file mode 100644 index 00000000..7dc14fb5 --- /dev/null +++ b/Sites/pages/administrator/components/com_users/models/debuguser.php @@ -0,0 +1,246 @@ +getState('filter.component'); + + return UsersHelperDebug::getDebugActions($component); + } + + /** + * Override getItems method. + * + * @return array + * + * @since 1.6 + */ + public function getItems() + { + $userId = $this->getState('user_id'); + $user = JFactory::getUser($userId); + + if (($assets = parent::getItems()) && $userId) + { + $actions = $this->getDebugActions(); + + foreach ($assets as &$asset) + { + $asset->checks = array(); + + foreach ($actions as $action) + { + $name = $action[0]; + + $asset->checks[$name] = $user->authorise($name, $asset->name); + } + } + } + + return $assets; + } + + /** + * Method to auto-populate the model state. + * + * Note. Calling getState in this method will result in recursion. + * + * @param string $ordering An optional ordering field. + * @param string $direction An optional direction (asc|desc). + * + * @return void + * + * @since 1.6 + */ + protected function populateState($ordering = 'a.lft', $direction = 'asc') + { + $app = JFactory::getApplication('administrator'); + + // Adjust the context to support modal layouts. + $layout = $app->input->get('layout', 'default'); + + if ($layout) + { + $this->context .= '.' . $layout; + } + + // Load the filter state. + $this->setState('filter.search', $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search', '', 'string')); + $this->setState('user_id', $this->getUserStateFromRequest($this->context . '.user_id', 'user_id', 0, 'int', false)); + + $levelStart = $this->getUserStateFromRequest($this->context . '.filter.level_start', 'filter_level_start', '', 'cmd'); + $this->setState('filter.level_start', $levelStart); + + $value = $this->getUserStateFromRequest($this->context . '.filter.level_end', 'filter_level_end', '', 'cmd'); + + if ($value > 0 && $value < $levelStart) + { + $value = $levelStart; + } + + $this->setState('filter.level_end', $value); + + $this->setState('filter.component', $this->getUserStateFromRequest($this->context . '.filter.component', 'filter_component', '', 'string')); + + // Load the parameters. + $params = JComponentHelper::getParams('com_users'); + $this->setState('params', $params); + + // List state information. + parent::populateState($ordering, $direction); + } + + /** + * Method to get a store id based on model configuration state. + * + * This is necessary because the model is used by the component and + * different modules that might need different sets of data or different + * ordering requirements. + * + * @param string $id A prefix for the store id. + * + * @return string A store id. + */ + protected function getStoreId($id = '') + { + // Compile the store id. + $id .= ':' . $this->getState('user_id'); + $id .= ':' . $this->getState('filter.search'); + $id .= ':' . $this->getState('filter.level_start'); + $id .= ':' . $this->getState('filter.level_end'); + $id .= ':' . $this->getState('filter.component'); + + return parent::getStoreId($id); + } + + /** + * Get the user being debugged. + * + * @return JUser + * + * @since 1.6 + */ + public function getUser() + { + $userId = $this->getState('user_id'); + + return JFactory::getUser($userId); + } + + /** + * Build an SQL query to load the list data. + * + * @return JDatabaseQuery + * + * @since 1.6 + */ + protected function getListQuery() + { + // Create a new query object. + $db = $this->getDbo(); + $query = $db->getQuery(true); + + // Select the required fields from the table. + $query->select( + $this->getState( + 'list.select', + 'a.id, a.name, a.title, a.level, a.lft, a.rgt' + ) + ); + $query->from($db->quoteName('#__assets', 'a')); + + // Filter the items over the search string if set. + if ($this->getState('filter.search')) + { + // Escape the search token. + $search = $db->quote('%' . str_replace(' ', '%', $db->escape(trim($this->getState('filter.search')), true) . '%')); + + // Compile the different search clauses. + $searches = array(); + $searches[] = 'a.name LIKE ' . $search; + $searches[] = 'a.title LIKE ' . $search; + + // Add the clauses to the query. + $query->where('(' . implode(' OR ', $searches) . ')'); + } + + // Filter on the start and end levels. + $levelStart = (int) $this->getState('filter.level_start'); + $levelEnd = (int) $this->getState('filter.level_end'); + + if ($levelEnd > 0 && $levelEnd < $levelStart) + { + $levelEnd = $levelStart; + } + + if ($levelStart > 0) + { + $query->where('a.level >= ' . $levelStart); + } + + if ($levelEnd > 0) + { + $query->where('a.level <= ' . $levelEnd); + } + + // Filter the items over the component if set. + if ($this->getState('filter.component')) + { + $component = $this->getState('filter.component'); + $query->where('(a.name = ' . $db->quote($component) . ' OR a.name LIKE ' . $db->quote($component . '.%') . ')'); + } + + // Add the list ordering clause. + $query->order($db->escape($this->getState('list.ordering', 'a.lft')) . ' ' . $db->escape($this->getState('list.direction', 'ASC'))); + + return $query; + } +} diff --git a/Sites/pages/administrator/components/com_users/models/fields/groupparent.php b/Sites/pages/administrator/components/com_users/models/fields/groupparent.php new file mode 100644 index 00000000..8b095ff2 --- /dev/null +++ b/Sites/pages/administrator/components/com_users/models/fields/groupparent.php @@ -0,0 +1,105 @@ + $userGroupsOptionsData) + { + if ((int) $userGroupsOptionsData->parent_id === (int) $fatherId) + { + unset($userGroupsOptions[$userGroupsOptionsId]); + + $userGroupsOptions = $this->cleanOptionsChildrenByFather($userGroupsOptions, $userGroupsOptionsId); + } + } + + return $userGroupsOptions; + } + + /** + * Method to get the field options. + * + * @return array The field option objects + * + * @since 1.6 + */ + protected function getOptions() + { + $options = UserGroupsHelper::getInstance()->getAll(); + $currentGroupId = $this->form->getValue('id'); + + // Prevent to set yourself as parent + if ($currentGroupId) + { + unset($options[$currentGroupId]); + } + + // We should not remove any groups when we are creating a new group + if (!is_null($currentGroupId)) + { + // Prevent parenting direct children and children of children of this item. + $options = $this->cleanOptionsChildrenByFather($options, $currentGroupId); + } + + $options = array_values($options); + $isSuperAdmin = Factory::getUser()->authorise('core.admin'); + + // Pad the option text with spaces using depth level as a multiplier. + for ($i = 0, $n = count($options); $i < $n; $i++) + { + // Show groups only if user is super admin or group is not super admin + if ($isSuperAdmin || !Access::checkGroup($options[$i]->id, 'core.admin')) + { + $options[$i]->value = $options[$i]->id; + $options[$i]->text = str_repeat('- ', $options[$i]->level) . $options[$i]->title; + } + else + { + unset($options[$i]); + } + } + + // Merge any additional options in the XML definition. + return array_merge(parent::getOptions(), $options); + } +} diff --git a/Sites/pages/administrator/components/com_users/models/fields/levels.php b/Sites/pages/administrator/components/com_users/models/fields/levels.php new file mode 100644 index 00000000..ab8b1e43 --- /dev/null +++ b/Sites/pages/administrator/components/com_users/models/fields/levels.php @@ -0,0 +1,41 @@ + +
    +
    + + + + + + +
    +
    diff --git a/Sites/pages/administrator/components/com_users/models/forms/fields/user.xml b/Sites/pages/administrator/components/com_users/models/forms/fields/user.xml new file mode 100644 index 00000000..2c830864 --- /dev/null +++ b/Sites/pages/administrator/components/com_users/models/forms/fields/user.xml @@ -0,0 +1,12 @@ + +
    + +
    + +
    +
    +
    diff --git a/Sites/pages/administrator/components/com_users/models/forms/filter_debuggroup.xml b/Sites/pages/administrator/components/com_users/models/forms/filter_debuggroup.xml new file mode 100644 index 00000000..dd351c6b --- /dev/null +++ b/Sites/pages/administrator/components/com_users/models/forms/filter_debuggroup.xml @@ -0,0 +1,71 @@ + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    diff --git a/Sites/pages/administrator/components/com_users/models/forms/filter_debuguser.xml b/Sites/pages/administrator/components/com_users/models/forms/filter_debuguser.xml new file mode 100644 index 00000000..99da868c --- /dev/null +++ b/Sites/pages/administrator/components/com_users/models/forms/filter_debuguser.xml @@ -0,0 +1,66 @@ + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    diff --git a/Sites/pages/administrator/components/com_users/models/forms/filter_groups.xml b/Sites/pages/administrator/components/com_users/models/forms/filter_groups.xml new file mode 100644 index 00000000..486bc01a --- /dev/null +++ b/Sites/pages/administrator/components/com_users/models/forms/filter_groups.xml @@ -0,0 +1,41 @@ + +
    + + + + + + + + + + + + + + + +
    diff --git a/Sites/pages/administrator/components/com_users/models/forms/filter_levels.xml b/Sites/pages/administrator/components/com_users/models/forms/filter_levels.xml new file mode 100644 index 00000000..663e8770 --- /dev/null +++ b/Sites/pages/administrator/components/com_users/models/forms/filter_levels.xml @@ -0,0 +1,41 @@ + +
    + + + + + + + + + + + + + + + +
    diff --git a/Sites/pages/administrator/components/com_users/models/forms/filter_notes.xml b/Sites/pages/administrator/components/com_users/models/forms/filter_notes.xml new file mode 100644 index 00000000..a26bc0ce --- /dev/null +++ b/Sites/pages/administrator/components/com_users/models/forms/filter_notes.xml @@ -0,0 +1,77 @@ + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    diff --git a/Sites/pages/administrator/components/com_users/models/forms/filter_users.xml b/Sites/pages/administrator/components/com_users/models/forms/filter_users.xml new file mode 100644 index 00000000..1928ce69 --- /dev/null +++ b/Sites/pages/administrator/components/com_users/models/forms/filter_users.xml @@ -0,0 +1,96 @@ + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    diff --git a/Sites/pages/administrator/components/com_users/models/forms/group.xml b/Sites/pages/administrator/components/com_users/models/forms/group.xml new file mode 100644 index 00000000..f050ae5f --- /dev/null +++ b/Sites/pages/administrator/components/com_users/models/forms/group.xml @@ -0,0 +1,46 @@ + +
    +
    + + + + + + + + + + + +
    +
    diff --git a/Sites/pages/administrator/components/com_users/models/forms/level.xml b/Sites/pages/administrator/components/com_users/models/forms/level.xml new file mode 100644 index 00000000..0651cacb --- /dev/null +++ b/Sites/pages/administrator/components/com_users/models/forms/level.xml @@ -0,0 +1,35 @@ + +
    +
    + + + + + + + +
    +
    diff --git a/Sites/pages/administrator/components/com_users/models/forms/mail.xml b/Sites/pages/administrator/components/com_users/models/forms/mail.xml new file mode 100644 index 00000000..c1e8d5b6 --- /dev/null +++ b/Sites/pages/administrator/components/com_users/models/forms/mail.xml @@ -0,0 +1,70 @@ + +
    +
    + + + + + + + + + + + + + + + + +
    +
    diff --git a/Sites/pages/administrator/components/com_users/models/forms/note.xml b/Sites/pages/administrator/components/com_users/models/forms/note.xml new file mode 100644 index 00000000..2da5740d --- /dev/null +++ b/Sites/pages/administrator/components/com_users/models/forms/note.xml @@ -0,0 +1,153 @@ + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    diff --git a/Sites/pages/administrator/components/com_users/models/forms/user.xml b/Sites/pages/administrator/components/com_users/models/forms/user.xml new file mode 100644 index 00000000..2b1ec1a7 --- /dev/null +++ b/Sites/pages/administrator/components/com_users/models/forms/user.xml @@ -0,0 +1,216 @@ + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + +
    + +
    + diff --git a/Sites/pages/administrator/components/com_users/models/group.php b/Sites/pages/administrator/components/com_users/models/group.php new file mode 100644 index 00000000..ee4f19c2 --- /dev/null +++ b/Sites/pages/administrator/components/com_users/models/group.php @@ -0,0 +1,330 @@ + 'onUserAfterDeleteGroup', + 'event_after_save' => 'onUserAfterSaveGroup', + 'event_before_delete' => 'onUserBeforeDeleteGroup', + 'event_before_save' => 'onUserBeforeSaveGroup', + 'events_map' => array('delete' => 'user', 'save' => 'user') + ), $config + ); + + parent::__construct($config); + } + + /** + * Returns a reference to the a Table object, always creating it. + * + * @param string $type The table type to instantiate + * @param string $prefix A prefix for the table class name. Optional. + * @param array $config Configuration array for model. Optional. + * + * @return JTable A database object + * + * @since 1.6 + */ + public function getTable($type = 'Usergroup', $prefix = 'JTable', $config = array()) + { + $return = JTable::getInstance($type, $prefix, $config); + + return $return; + } + + /** + * Method to get the record form. + * + * @param array $data An optional array of data for the form to interrogate. + * @param boolean $loadData True if the form is to load its own data (default case), false if not. + * + * @return JForm A JForm object on success, false on failure + * + * @since 1.6 + */ + public function getForm($data = array(), $loadData = true) + { + // Get the form. + $form = $this->loadForm('com_users.group', 'group', array('control' => 'jform', 'load_data' => $loadData)); + + if (empty($form)) + { + return false; + } + + return $form; + } + + /** + * Method to get the data that should be injected in the form. + * + * @return mixed The data for the form. + * + * @since 1.6 + */ + protected function loadFormData() + { + // Check the session for previously entered form data. + $data = JFactory::getApplication()->getUserState('com_users.edit.group.data', array()); + + if (empty($data)) + { + $data = $this->getItem(); + } + + $this->preprocessData('com_users.group', $data); + + return $data; + } + + /** + * Override preprocessForm to load the user plugin group instead of content. + * + * @param JForm $form A form object. + * @param mixed $data The data expected for the form. + * @param string $group The name of the plugin group to import (defaults to "content"). + * + * @return void + * + * @since 1.6 + * @throws Exception if there is an error loading the form. + */ + protected function preprocessForm(JForm $form, $data, $group = '') + { + $obj = is_array($data) ? ArrayHelper::toObject($data, 'JObject') : $data; + + if (isset($obj->parent_id) && $obj->parent_id == 0 && $obj->id > 0) + { + $form->setFieldAttribute('parent_id', 'type', 'hidden'); + $form->setFieldAttribute('parent_id', 'hidden', 'true'); + } + + parent::preprocessForm($form, $data, 'user'); + } + + /** + * Method to save the form data. + * + * @param array $data The form data. + * + * @return boolean True on success. + * + * @since 1.6 + */ + public function save($data) + { + // Include the user plugins for events. + JPluginHelper::importPlugin($this->events_map['save']); + + /** + * Check the super admin permissions for group + * We get the parent group permissions and then check the group permissions manually + * We have to calculate the group permissions manually because we haven't saved the group yet + */ + $parentSuperAdmin = JAccess::checkGroup($data['parent_id'], 'core.admin'); + + // Get core.admin rules from the root asset + $rules = JAccess::getAssetRules('root.1')->getData('core.admin'); + + // Get the value for the current group (will be true (allowed), false (denied), or null (inherit) + $groupSuperAdmin = $rules['core.admin']->allow($data['id']); + + // We only need to change the $groupSuperAdmin if the parent is true or false. Otherwise, the value set in the rule takes effect. + if ($parentSuperAdmin === false) + { + // If parent is false (Denied), effective value will always be false + $groupSuperAdmin = false; + } + elseif ($parentSuperAdmin === true) + { + // If parent is true (allowed), group is true unless explicitly set to false + $groupSuperAdmin = ($groupSuperAdmin === false) ? false : true; + } + + // Check for non-super admin trying to save with super admin group + $iAmSuperAdmin = JFactory::getUser()->authorise('core.admin'); + + if (!$iAmSuperAdmin && $groupSuperAdmin) + { + $this->setError(JText::_('JLIB_USER_ERROR_NOT_SUPERADMIN')); + + return false; + } + + /** + * Check for super-admin changing self to be non-super-admin + * First, are we a super admin + */ + if ($iAmSuperAdmin) + { + // Next, are we a member of the current group? + $myGroups = JAccess::getGroupsByUser(JFactory::getUser()->get('id'), false); + + if (in_array($data['id'], $myGroups)) + { + // Now, would we have super admin permissions without the current group? + $otherGroups = array_diff($myGroups, array($data['id'])); + $otherSuperAdmin = false; + + foreach ($otherGroups as $otherGroup) + { + $otherSuperAdmin = $otherSuperAdmin ?: JAccess::checkGroup($otherGroup, 'core.admin'); + } + + /** + * If we would not otherwise have super admin permissions + * and the current group does not have super admin permissions, throw an exception + */ + if ((!$otherSuperAdmin) && (!$groupSuperAdmin)) + { + $this->setError(JText::_('JLIB_USER_ERROR_CANNOT_DEMOTE_SELF')); + + return false; + } + } + } + + if (JFactory::getApplication()->input->get('task') == 'save2copy') + { + $data['title'] = $this->generateGroupTitle($data['parent_id'], $data['title']); + } + + // Proceed with the save + return parent::save($data); + } + + /** + * Method to delete rows. + * + * @param array &$pks An array of item ids. + * + * @return boolean Returns true on success, false on failure. + * + * @since 1.6 + * @throws Exception + */ + public function delete(&$pks) + { + // Typecast variable. + $pks = (array) $pks; + $user = JFactory::getUser(); + $groups = JAccess::getGroupsByUser($user->get('id')); + + // Get a row instance. + $table = $this->getTable(); + + // Load plugins. + JPluginHelper::importPlugin($this->events_map['delete']); + $dispatcher = JEventDispatcher::getInstance(); + + // Check if I am a Super Admin + $iAmSuperAdmin = $user->authorise('core.admin'); + + // Do not allow to delete groups to which the current user belongs + foreach ($pks as $pk) + { + if (in_array($pk, $groups)) + { + JError::raiseWarning(403, JText::_('COM_USERS_DELETE_ERROR_INVALID_GROUP')); + + return false; + } + } + + // Iterate the items to delete each one. + foreach ($pks as $i => $pk) + { + if ($table->load($pk)) + { + // Access checks. + $allow = $user->authorise('core.edit.state', 'com_users'); + + // Don't allow non-super-admin to delete a super admin + $allow = (!$iAmSuperAdmin && JAccess::checkGroup($pk, 'core.admin')) ? false : $allow; + + if ($allow) + { + // Fire the before delete event. + $dispatcher->trigger($this->event_before_delete, array($table->getProperties())); + + if (!$table->delete($pk)) + { + $this->setError($table->getError()); + + return false; + } + else + { + // Trigger the after delete event. + $dispatcher->trigger($this->event_after_delete, array($table->getProperties(), true, $this->getError())); + } + } + else + { + // Prune items that you can't change. + unset($pks[$i]); + JError::raiseWarning(403, JText::_('JERROR_CORE_DELETE_NOT_PERMITTED')); + } + } + else + { + $this->setError($table->getError()); + + return false; + } + } + + return true; + } + + /** + * Method to generate the title of group on Save as Copy action + * + * @param integer $parentId The id of the parent. + * @param string $title The title of group + * + * @return string Contains the modified title. + * + * @since 3.3.7 + */ + protected function generateGroupTitle($parentId, $title) + { + // Alter the title & alias + $table = $this->getTable(); + + while ($table->load(array('title' => $title, 'parent_id' => $parentId))) + { + if ($title == $table->title) + { + $title = StringHelper::increment($title); + } + } + + return $title; + } +} diff --git a/Sites/pages/administrator/components/com_users/models/groups.php b/Sites/pages/administrator/components/com_users/models/groups.php new file mode 100644 index 00000000..fde23dea --- /dev/null +++ b/Sites/pages/administrator/components/com_users/models/groups.php @@ -0,0 +1,247 @@ +setState('filter.search', $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search', '', 'string')); + + // Load the parameters. + $params = JComponentHelper::getParams('com_users'); + $this->setState('params', $params); + + // List state information. + parent::populateState($ordering, $direction); + } + + /** + * Method to get a store id based on model configuration state. + * + * This is necessary because the model is used by the component and + * different modules that might need different sets of data or different + * ordering requirements. + * + * @param string $id A prefix for the store id. + * + * @return string A store id. + */ + protected function getStoreId($id = '') + { + // Compile the store id. + $id .= ':' . $this->getState('filter.search'); + + return parent::getStoreId($id); + } + + /** + * Gets the list of groups and adds expensive joins to the result set. + * + * @return mixed An array of data items on success, false on failure. + * + * @since 1.6 + */ + public function getItems() + { + // Get a storage key. + $store = $this->getStoreId(); + + // Try to load the data from internal storage. + if (empty($this->cache[$store])) + { + $items = parent::getItems(); + + // Bail out on an error or empty list. + if (empty($items)) + { + $this->cache[$store] = $items; + + return $items; + } + + try + { + $items = $this->populateExtraData($items); + } + catch (RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + + // Add the items to the internal cache. + $this->cache[$store] = $items; + } + + return $this->cache[$store]; + } + + /** + * Build an SQL query to load the list data. + * + * @return JDatabaseQuery + */ + protected function getListQuery() + { + // Create a new query object. + $db = $this->getDbo(); + $query = $db->getQuery(true); + + // Select the required fields from the table. + $query->select( + $this->getState( + 'list.select', + 'a.*' + ) + ); + $query->from($db->quoteName('#__usergroups') . ' AS a'); + + // Filter the comments over the search string if set. + $search = $this->getState('filter.search'); + + if (!empty($search)) + { + if (stripos($search, 'id:') === 0) + { + $query->where('a.id = ' . (int) substr($search, 3)); + } + else + { + $search = $db->quote('%' . str_replace(' ', '%', $db->escape(trim($search), true) . '%')); + $query->where('a.title LIKE ' . $search); + } + } + + // Add the list ordering clause. + $query->order($db->escape($this->getState('list.ordering', 'a.lft')) . ' ' . $db->escape($this->getState('list.direction', 'ASC'))); + + return $query; + } + + /** + * Populate level & path for items. + * + * @param array $items Array of stdClass objects + * + * @return array + * + * @since 3.6.3 + */ + private function populateExtraData(array $items) + { + // First pass: get list of the group id's and reset the counts. + $groupsByKey = array(); + + foreach ($items as $item) + { + $groupsByKey[(int) $item->id] = $item; + } + + $groupIds = array_keys($groupsByKey); + + $db = $this->getDbo(); + + // Get total enabled users in group. + $query = $db->getQuery(true); + + // Count the objects in the user group. + $query->select('map.group_id, COUNT(DISTINCT map.user_id) AS user_count') + ->from($db->quoteName('#__user_usergroup_map', 'map')) + ->join('LEFT', $db->quoteName('#__users', 'u') . ' ON ' . $db->quoteName('u.id') . ' = ' . $db->quoteName('map.user_id')) + ->where($db->quoteName('map.group_id') . ' IN (' . implode(',', $groupIds) . ')') + ->where($db->quoteName('u.block') . ' = 0') + ->group($db->quoteName('map.group_id')); + $db->setQuery($query); + + try + { + $countEnabled = $db->loadAssocList('group_id', 'count_enabled'); + } + catch (RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + + // Get total disabled users in group. + $query->clear('where') + ->where('map.group_id IN (' . implode(',', $groupIds) . ')') + ->where('u.block = 1'); + $db->setQuery($query); + + try + { + $countDisabled = $db->loadAssocList('group_id', 'count_disabled'); + } + catch (RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + + // Inject the values back into the array. + foreach ($groupsByKey as &$item) + { + $item->count_enabled = isset($countEnabled[$item->id]) ? (int) $countEnabled[$item->id]['user_count'] : 0; + $item->count_disabled = isset($countDisabled[$item->id]) ? (int) $countDisabled[$item->id]['user_count'] : 0; + $item->user_count = $item->count_enabled + $item->count_disabled; + } + + $groups = new JHelperUsergroups($groupsByKey); + + return array_values($groups->getAll()); + } +} diff --git a/Sites/pages/administrator/components/com_users/models/level.php b/Sites/pages/administrator/components/com_users/models/level.php new file mode 100644 index 00000000..ec4a8154 --- /dev/null +++ b/Sites/pages/administrator/components/com_users/models/level.php @@ -0,0 +1,309 @@ +rules); + + if ($groups === null) + { + throw new RuntimeException('Invalid rules schema'); + } + + $isAdmin = JFactory::getUser()->authorise('core.admin'); + + // Check permissions + foreach ($groups as $group) + { + if (!$isAdmin && JAccess::checkGroup($group, 'core.admin')) + { + $this->setError(JText::_('JERROR_ALERTNOAUTHOR')); + + return false; + } + } + + // Check if the access level is being used by any content. + if ($this->levelsInUse === null) + { + // Populate the list once. + $this->levelsInUse = array(); + + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select('DISTINCT access'); + + // Get all the tables and the prefix + $tables = $db->getTableList(); + $prefix = $db->getPrefix(); + + foreach ($tables as $table) + { + // Get all of the columns in the table + $fields = $db->getTableColumns($table); + + /** + * We are looking for the access field. If custom tables are using something other + * than the 'access' field they are on their own unfortunately. + * Also make sure the table prefix matches the live db prefix (eg, it is not a "bak_" table) + */ + if (strpos($table, $prefix) === 0 && isset($fields['access'])) + { + // Lookup the distinct values of the field. + $query->clear('from') + ->from($db->quoteName($table)); + $db->setQuery($query); + + try + { + $values = $db->loadColumn(); + } + catch (RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + + $this->levelsInUse = array_merge($this->levelsInUse, $values); + + // TODO Could assemble an array of the tables used by each view level list those, + // giving the user a clue in the error where to look. + } + } + + // Get uniques. + $this->levelsInUse = array_unique($this->levelsInUse); + + // Ok, after all that we are ready to check the record :) + } + + if (in_array($record->id, $this->levelsInUse)) + { + $this->setError(JText::sprintf('COM_USERS_ERROR_VIEW_LEVEL_IN_USE', $record->id, $record->title)); + + return false; + } + + return parent::canDelete($record); + } + + /** + * Returns a reference to the a Table object, always creating it. + * + * @param string $type The table type to instantiate + * @param string $prefix A prefix for the table class name. Optional. + * @param array $config Configuration array for model. Optional. + * + * @return JTable A database object + * + * @since 1.6 + */ + public function getTable($type = 'Viewlevel', $prefix = 'JTable', $config = array()) + { + $return = JTable::getInstance($type, $prefix, $config); + + return $return; + } + + /** + * Method to get a single record. + * + * @param integer $pk The id of the primary key. + * + * @return mixed Object on success, false on failure. + * + * @since 1.6 + */ + public function getItem($pk = null) + { + $result = parent::getItem($pk); + + // Convert the params field to an array. + $result->rules = json_decode($result->rules); + + return $result; + } + + /** + * Method to get the record form. + * + * @param array $data An optional array of data for the form to interrogate. + * @param boolean $loadData True if the form is to load its own data (default case), false if not. + * + * @return JForm A JForm object on success, false on failure + * + * @since 1.6 + */ + public function getForm($data = array(), $loadData = true) + { + // Get the form. + $form = $this->loadForm('com_users.level', 'level', array('control' => 'jform', 'load_data' => $loadData)); + + if (empty($form)) + { + return false; + } + + return $form; + } + + /** + * Method to get the data that should be injected in the form. + * + * @return mixed The data for the form. + * + * @since 1.6 + */ + protected function loadFormData() + { + // Check the session for previously entered form data. + $data = JFactory::getApplication()->getUserState('com_users.edit.level.data', array()); + + if (empty($data)) + { + $data = $this->getItem(); + } + + $this->preprocessData('com_users.level', $data); + + return $data; + } + + /** + * Method to preprocess the form + * + * @param JForm $form A form object. + * @param mixed $data The data expected for the form. + * @param string $group The name of the plugin group to import (defaults to "content"). + * + * @return void + * + * @since 1.6 + * @throws Exception if there is an error loading the form. + */ + protected function preprocessForm(JForm $form, $data, $group = '') + { + parent::preprocessForm($form, $data, 'user'); + } + + /** + * Method to save the form data. + * + * @param array $data The form data. + * + * @return boolean True on success. + * + * @since 1.6 + */ + public function save($data) + { + if (!isset($data['rules'])) + { + $data['rules'] = array(); + } + + $data['title'] = JFilterInput::getInstance()->clean($data['title'], 'TRIM'); + + return parent::save($data); + } + + /** + * Method to validate the form data. + * + * @param \JForm $form The form to validate against. + * @param array $data The data to validate. + * @param string $group The name of the field group to validate. + * + * @return array|boolean Array of filtered data if valid, false otherwise. + * + * @see \JFormRule + * @see \JFilterInput + * @since 3.8.8 + */ + public function validate($form, $data, $group = null) + { + $isSuperAdmin = Factory::getUser()->authorise('core.admin'); + + // Non Super user should not be able to change the access levels of super user groups + if (!$isSuperAdmin) + { + if (!isset($data['rules']) || !is_array($data['rules'])) + { + $data['rules'] = array(); + } + + $groups = array_values(UserGroupsHelper::getInstance()->getAll()); + + $rules = array(); + + if (!empty($data['id'])) + { + $table = $this->getTable(); + + $table->load($data['id']); + + $rules = json_decode($table->rules); + } + + $rules = ArrayHelper::toInteger($rules); + + for ($i = 0, $n = count($groups); $i < $n; ++$i) + { + if (Access::checkGroup((int) $groups[$i]->id, 'core.admin')) + { + if (in_array((int) $groups[$i]->id, $rules) && !in_array((int) $groups[$i]->id, $data['rules'])) + { + $data['rules'][] = (int) $groups[$i]->id; + } + elseif (!in_array((int) $groups[$i]->id, $rules) && in_array((int) $groups[$i]->id, $data['rules'])) + { + $this->setError(Text::_('JLIB_USER_ERROR_NOT_SUPERADMIN')); + + return false; + } + } + } + } + + return parent::validate($form, $data, $group); + } +} diff --git a/Sites/pages/administrator/components/com_users/models/levels.php b/Sites/pages/administrator/components/com_users/models/levels.php new file mode 100644 index 00000000..5a6a6bf4 --- /dev/null +++ b/Sites/pages/administrator/components/com_users/models/levels.php @@ -0,0 +1,229 @@ +setState('filter.search', $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search')); + + // Load the parameters. + $params = JComponentHelper::getParams('com_users'); + $this->setState('params', $params); + + // List state information. + parent::populateState($ordering, $direction); + } + + /** + * Method to get a store id based on model configuration state. + * + * This is necessary because the model is used by the component and + * different modules that might need different sets of data or different + * ordering requirements. + * + * @param string $id A prefix for the store id. + * + * @return string A store id. + */ + protected function getStoreId($id = '') + { + // Compile the store id. + $id .= ':' . $this->getState('filter.search'); + + return parent::getStoreId($id); + } + + /** + * Build an SQL query to load the list data. + * + * @return JDatabaseQuery + */ + protected function getListQuery() + { + // Create a new query object. + $db = $this->getDbo(); + $query = $db->getQuery(true); + + // Select the required fields from the table. + $query->select( + $this->getState( + 'list.select', + 'a.*' + ) + ); + $query->from($db->quoteName('#__viewlevels') . ' AS a'); + + // Add the level in the tree. + $query->group('a.id, a.title, a.ordering, a.rules'); + + // Filter the items over the search string if set. + $search = $this->getState('filter.search'); + + if (!empty($search)) + { + if (stripos($search, 'id:') === 0) + { + $query->where('a.id = ' . (int) substr($search, 3)); + } + else + { + $search = $db->quote('%' . str_replace(' ', '%', $db->escape(trim($search), true) . '%')); + $query->where('a.title LIKE ' . $search); + } + } + + $query->group('a.id'); + + // Add the list ordering clause. + $query->order($db->escape($this->getState('list.ordering', 'a.ordering')) . ' ' . $db->escape($this->getState('list.direction', 'ASC'))); + + return $query; + } + + /** + * Method to adjust the ordering of a row. + * + * @param integer $pk The ID of the primary key to move. + * @param integer $direction Increment, usually +1 or -1 + * + * @return boolean False on failure or error, true otherwise. + */ + public function reorder($pk, $direction = 0) + { + // Sanitize the id and adjustment. + $pk = (!empty($pk)) ? $pk : (int) $this->getState('level.id'); + $user = JFactory::getUser(); + + // Get an instance of the record's table. + $table = JTable::getInstance('viewlevel'); + + // Load the row. + if (!$table->load($pk)) + { + $this->setError($table->getError()); + + return false; + } + + // Access checks. + $allow = $user->authorise('core.edit.state', 'com_users'); + + if (!$allow) + { + $this->setError(JText::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED')); + + return false; + } + + // Move the row. + // TODO: Where clause to restrict category. + $table->move($pk); + + return true; + } + + /** + * Saves the manually set order of records. + * + * @param array $pks An array of primary key ids. + * @param integer $order Order position + * + * @return boolean|JException Boolean true on success, boolean false or JException instance on error + */ + public function saveorder($pks, $order) + { + $table = JTable::getInstance('viewlevel'); + $user = JFactory::getUser(); + $conditions = array(); + + if (empty($pks)) + { + return JError::raiseWarning(500, JText::_('COM_USERS_ERROR_LEVELS_NOLEVELS_SELECTED')); + } + + // Update ordering values + foreach ($pks as $i => $pk) + { + $table->load((int) $pk); + + // Access checks. + $allow = $user->authorise('core.edit.state', 'com_users'); + + if (!$allow) + { + // Prune items that you can't change. + unset($pks[$i]); + JError::raiseWarning(403, JText::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED')); + } + elseif ($table->ordering != $order[$i]) + { + $table->ordering = $order[$i]; + + if (!$table->store()) + { + $this->setError($table->getError()); + + return false; + } + } + } + + // Execute reorder for each category. + foreach ($conditions as $cond) + { + $table->load($cond[0]); + $table->reorder($cond[1]); + } + + return true; + } +} diff --git a/Sites/pages/administrator/components/com_users/models/mail.php b/Sites/pages/administrator/components/com_users/models/mail.php new file mode 100644 index 00000000..d241d5f2 --- /dev/null +++ b/Sites/pages/administrator/components/com_users/models/mail.php @@ -0,0 +1,217 @@ +loadForm('com_users.mail', 'mail', array('control' => 'jform', 'load_data' => $loadData)); + + if (empty($form)) + { + return false; + } + + return $form; + } + + /** + * Method to get the data that should be injected in the form. + * + * @return mixed The data for the form. + * + * @since 1.6 + */ + protected function loadFormData() + { + // Check the session for previously entered form data. + $data = JFactory::getApplication()->getUserState('com_users.display.mail.data', array()); + + $this->preprocessData('com_users.mail', $data); + + return $data; + } + + /** + * Method to preprocess the form + * + * @param JForm $form A form object. + * @param mixed $data The data expected for the form. + * @param string $group The name of the plugin group to import (defaults to "content"). + * + * @return void + * + * @since 1.6 + * @throws Exception if there is an error loading the form. + */ + protected function preprocessForm(JForm $form, $data, $group = 'user') + { + parent::preprocessForm($form, $data, $group); + } + + /** + * Send the email + * + * @return boolean + */ + public function send() + { + $app = JFactory::getApplication(); + $data = $app->input->post->get('jform', array(), 'array'); + $user = JFactory::getUser(); + $access = new JAccess; + $db = $this->getDbo(); + + $mode = array_key_exists('mode', $data) ? (int) $data['mode'] : 0; + $subject = array_key_exists('subject', $data) ? $data['subject'] : ''; + $grp = array_key_exists('group', $data) ? (int) $data['group'] : 0; + $recurse = array_key_exists('recurse', $data) ? (int) $data['recurse'] : 0; + $bcc = array_key_exists('bcc', $data) ? (int) $data['bcc'] : 0; + $disabled = array_key_exists('disabled', $data) ? (int) $data['disabled'] : 0; + $message_body = array_key_exists('message', $data) ? $data['message'] : ''; + + // Automatically removes html formatting + if (!$mode) + { + $message_body = JFilterInput::getInstance()->clean($message_body, 'string'); + } + + // Check for a message body and subject + if (!$message_body || !$subject) + { + $app->setUserState('com_users.display.mail.data', $data); + $this->setError(JText::_('COM_USERS_MAIL_PLEASE_FILL_IN_THE_FORM_CORRECTLY')); + + return false; + } + + // Get users in the group out of the ACL, if group is provided. + $to = $grp !== 0 ? $access->getUsersByGroup($grp, $recurse) : array(); + + // When group is provided but no users are found in the group. + if ($grp !== 0 && !$to) + { + $rows = array(); + } + else + { + // Get all users email and group except for senders + $query = $db->getQuery(true) + ->select($db->quoteName('email')) + ->from($db->quoteName('#__users')) + ->where($db->quoteName('id') . ' != ' . (int) $user->id); + + if ($grp !== 0) + { + $query->where($db->quoteName('id') . ' IN (' . implode(',', $to) . ')'); + } + + if ($disabled === 0) + { + $query->where($db->quoteName('block') . ' = 0'); + } + + $db->setQuery($query); + $rows = $db->loadColumn(); + } + + // Check to see if there are any users in this group before we continue + if (!$rows) + { + $app->setUserState('com_users.display.mail.data', $data); + + if (in_array($user->id, $to)) + { + $this->setError(JText::_('COM_USERS_MAIL_ONLY_YOU_COULD_BE_FOUND_IN_THIS_GROUP')); + } + else + { + $this->setError(JText::_('COM_USERS_MAIL_NO_USERS_COULD_BE_FOUND_IN_THIS_GROUP')); + } + + return false; + } + + // Get the Mailer + $mailer = JFactory::getMailer(); + $params = JComponentHelper::getParams('com_users'); + + // Build email message format. + $mailer->setSender(array($app->get('mailfrom'), $app->get('fromname'))); + $mailer->setSubject($params->get('mailSubjectPrefix') . stripslashes($subject)); + $mailer->setBody($message_body . $params->get('mailBodySuffix')); + $mailer->IsHtml($mode); + + // Add recipients + if ($bcc) + { + $mailer->addBcc($rows); + $mailer->addRecipient($app->get('mailfrom')); + } + else + { + $mailer->addRecipient($rows); + } + + // Send the Mail + $rs = $mailer->Send(); + + // Check for an error + if ($rs instanceof Exception) + { + $app->setUserState('com_users.display.mail.data', $data); + $this->setError($rs->getError()); + + return false; + } + elseif (empty($rs)) + { + $app->setUserState('com_users.display.mail.data', $data); + $this->setError(JText::_('COM_USERS_MAIL_THE_MAIL_COULD_NOT_BE_SENT')); + + return false; + } + else + { + /** + * Fill the data (specially for the 'mode', 'group' and 'bcc': they could not exist in the array + * when the box is not checked and in this case, the default value would be used instead of the '0' + * one) + */ + $data['mode'] = $mode; + $data['subject'] = $subject; + $data['group'] = $grp; + $data['recurse'] = $recurse; + $data['bcc'] = $bcc; + $data['message'] = $message_body; + $app->setUserState('com_users.display.mail.data', array()); + $app->enqueueMessage(JText::plural('COM_USERS_MAIL_EMAIL_SENT_TO_N_USERS', count($rows)), 'message'); + + return true; + } + } +} diff --git a/Sites/pages/administrator/components/com_users/models/note.php b/Sites/pages/administrator/components/com_users/models/note.php new file mode 100644 index 00000000..28d10ae1 --- /dev/null +++ b/Sites/pages/administrator/components/com_users/models/note.php @@ -0,0 +1,146 @@ +loadForm('com_users.note', 'note', array('control' => 'jform', 'load_data' => $loadData)); + + if (empty($form)) + { + return false; + } + + return $form; + } + + /** + * Method to get a single record. + * + * @param integer $pk The id of the primary key. + * + * @return mixed Object on success, false on failure. + * + * @since 2.5 + */ + public function getItem($pk = null) + { + $result = parent::getItem($pk); + + // Get the dispatcher and load the content plugins. + $dispatcher = JEventDispatcher::getInstance(); + JPluginHelper::importPlugin('content'); + + // Load the user plugins for backward compatibility (v3.3.3 and earlier). + JPluginHelper::importPlugin('user'); + + // Trigger the data preparation event. + $dispatcher->trigger('onContentPrepareData', array('com_users.note', $result)); + + return $result; + } + + /** + * Method to get a table object, load it if necessary. + * + * @param string $name The table name. Optional. + * @param string $prefix The class prefix. Optional. + * @param array $options Configuration array for model. Optional. + * + * @return JTable The table object + * + * @since 2.5 + */ + public function getTable($name = 'Note', $prefix = 'UsersTable', $options = array()) + { + return JTable::getInstance($name, $prefix, $options); + } + + /** + * Method to get the data that should be injected in the form. + * + * @return mixed The data for the form. + * + * @since 1.6 + */ + protected function loadFormData() + { + // Get the application + $app = JFactory::getApplication(); + + // Check the session for previously entered form data. + $data = $app->getUserState('com_users.edit.note.data', array()); + + if (empty($data)) + { + $data = $this->getItem(); + + // Prime some default values. + if ($this->getState('note.id') == 0) + { + $data->set('catid', $app->input->get('catid', $app->getUserState('com_users.notes.filter.category_id'), 'int')); + } + + $userId = $app->input->get('u_id', 0, 'int'); + + if ($userId != 0) + { + $data->user_id = $userId; + } + } + + $this->preprocessData('com_users.note', $data); + + return $data; + } + + /** + * Method to auto-populate the model state. + * + * Note. Calling getState in this method will result in recursion. + * + * @return void + * + * @since 2.5 + */ + protected function populateState() + { + parent::populateState(); + + $userId = JFactory::getApplication()->input->get('u_id', 0, 'int'); + $this->setState('note.user_id', $userId); + } +} diff --git a/Sites/pages/administrator/components/com_users/models/notes.php b/Sites/pages/administrator/components/com_users/models/notes.php new file mode 100644 index 00000000..173d250e --- /dev/null +++ b/Sites/pages/administrator/components/com_users/models/notes.php @@ -0,0 +1,220 @@ +getDbo(); + $query = $db->getQuery(true); + + // Select the required fields from the table. + $query->select( + $this->getState('list.select', + 'a.id, a.subject, a.checked_out, a.checked_out_time,' . + 'a.catid, a.created_time, a.review_time,' . + 'a.state, a.publish_up, a.publish_down' + ) + ); + $query->from('#__user_notes AS a'); + + // Join over the category + $query->select('c.title AS category_title, c.params AS category_params') + ->join('LEFT', '#__categories AS c ON c.id = a.catid'); + + // Join over the users for the note user. + $query->select('u.name AS user_name') + ->join('LEFT', '#__users AS u ON u.id = a.user_id'); + + // Join over the users for the checked out user. + $query->select('uc.name AS editor') + ->join('LEFT', '#__users AS uc ON uc.id = a.checked_out'); + + // Filter by search in title + $search = $this->getState('filter.search'); + + if (!empty($search)) + { + if (stripos($search, 'id:') === 0) + { + $query->where('a.id = ' . (int) substr($search, 3)); + } + elseif (stripos($search, 'uid:') === 0) + { + $query->where('a.user_id = ' . (int) substr($search, 4)); + } + else + { + $search = $db->quote('%' . str_replace(' ', '%', $db->escape(trim($search), true) . '%')); + $query->where('((a.subject LIKE ' . $search . ') OR (u.name LIKE ' . $search . ') OR (u.username LIKE ' . $search . '))'); + } + } + + // Filter by published state + $published = $this->getState('filter.published'); + + if (is_numeric($published)) + { + $query->where('a.state = ' . (int) $published); + } + elseif ($published === '') + { + $query->where('(a.state IN (0, 1))'); + } + + // Filter by a single category. + $categoryId = (int) $this->getState('filter.category_id'); + + if ($categoryId) + { + $query->where('a.catid = ' . $categoryId); + } + + // Filter by a single user. + $userId = (int) $this->getState('filter.user_id'); + + if ($userId) + { + // Add the body and where filter. + $query->select('a.body') + ->where('a.user_id = ' . $userId); + } + + // Filter on the level. + if ($level = $this->getState('filter.level')) + { + $query->where($db->quoteName('c.level') . ' <= ' . (int) $level); + } + + // Add the list ordering clause. + $query->order($db->escape($this->getState('list.ordering', 'a.review_time')) . ' ' . $db->escape($this->getState('list.direction', 'DESC'))); + + return $query; + } + + /** + * Method to get a store id based on model configuration state. + * + * This is necessary because the model is used by the component and + * different modules that might need different sets of data or different + * ordering requirements. + * + * @param string $id A prefix for the store id. + * + * @return string A store id. + * + * @since 2.5 + */ + protected function getStoreId($id = '') + { + // Compile the store id. + $id .= ':' . $this->getState('filter.search'); + $id .= ':' . $this->getState('filter.published'); + $id .= ':' . $this->getState('filter.category_id'); + $id .= ':' . $this->getState('filter.user_id'); + $id .= ':' . $this->getState('filter.level'); + + return parent::getStoreId($id); + } + + /** + * Gets a user object if the user filter is set. + * + * @return JUser The JUser object + * + * @since 2.5 + */ + public function getUser() + { + $user = new JUser; + + // Filter by search in title + $search = (int) $this->getState('filter.user_id'); + + if ($search != 0) + { + $user->load((int) $search); + } + + return $user; + } + + /** + * Method to auto-populate the model state. + * + * Note. Calling getState in this method will result in recursion. + * + * @param string $ordering An optional ordering field. + * @param string $direction An optional direction (asc|desc). + * + * @return void + * + * @since 1.6 + */ + protected function populateState($ordering = 'a.review_time', $direction = 'desc') + { + // Adjust the context to support modal layouts. + if ($layout = JFactory::getApplication()->input->get('layout')) + { + $this->context .= '.' . $layout; + } + + $this->setState('filter.search', $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search')); + $this->setState('filter.published', $this->getUserStateFromRequest($this->context . '.filter.published', 'filter_published', '', 'string')); + $this->setState('filter.category_id', $this->getUserStateFromRequest($this->context . '.filter.category_id', 'filter_category_id')); + $this->setState('filter.user_id', $this->getUserStateFromRequest($this->context . '.filter.user_id', 'filter_user_id')); + $this->setState('filter.level', $this->getUserStateFromRequest($this->context . '.filter.level', 'filter_level', '', 'cmd')); + + parent::populateState($ordering, $direction); + } +} diff --git a/Sites/pages/administrator/components/com_users/models/user.php b/Sites/pages/administrator/components/com_users/models/user.php new file mode 100644 index 00000000..671cd02d --- /dev/null +++ b/Sites/pages/administrator/components/com_users/models/user.php @@ -0,0 +1,1373 @@ + 'onUserAfterDelete', + 'event_after_save' => 'onUserAfterSave', + 'event_before_delete' => 'onUserBeforeDelete', + 'event_before_save' => 'onUserBeforeSave', + 'events_map' => array('save' => 'user', 'delete' => 'user', 'validate' => 'user') + ), $config + ); + + parent::__construct($config); + } + + /** + * Returns a reference to the a Table object, always creating it. + * + * @param string $type The table type to instantiate + * @param string $prefix A prefix for the table class name. Optional. + * @param array $config Configuration array for model. Optional. + * + * @return JTable A database object + * + * @since 1.6 + */ + public function getTable($type = 'User', $prefix = 'JTable', $config = array()) + { + $table = JTable::getInstance($type, $prefix, $config); + + return $table; + } + + /** + * Method to get a single record. + * + * @param integer $pk The id of the primary key. + * + * @return mixed Object on success, false on failure. + * + * @since 1.6 + */ + public function getItem($pk = null) + { + $pk = (!empty($pk)) ? $pk : (int) $this->getState('user.id'); + + if ($this->_item === null) + { + $this->_item = array(); + } + + if (!isset($this->_item[$pk])) + { + $this->_item[$pk] = parent::getItem($pk); + } + + return $this->_item[$pk]; + } + + /** + * Method to get the record form. + * + * @param array $data An optional array of data for the form to interrogate. + * @param boolean $loadData True if the form is to load its own data (default case), false if not. + * + * @return mixed A JForm object on success, false on failure + * + * @since 1.6 + */ + public function getForm($data = array(), $loadData = true) + { + // Get the form. + $form = $this->loadForm('com_users.user', 'user', array('control' => 'jform', 'load_data' => $loadData)); + + if (empty($form)) + { + return false; + } + + // If the user needs to change their password, mark the password fields as required + if (JFactory::getUser()->requireReset) + { + $form->setFieldAttribute('password', 'required', 'true'); + $form->setFieldAttribute('password2', 'required', 'true'); + } + + // When multilanguage is set, a user's default site language should also be a Content Language + if (JLanguageMultilang::isEnabled()) + { + $form->setFieldAttribute('language', 'type', 'frontend_language', 'params'); + } + + $userId = $form->getValue('id'); + + // The user should not be able to set the requireReset value on their own account + if ((int) $userId === (int) JFactory::getUser()->id) + { + $form->removeField('requireReset'); + } + + return $form; + } + + /** + * Method to get the data that should be injected in the form. + * + * @return mixed The data for the form. + * + * @since 1.6 + */ + protected function loadFormData() + { + // Check the session for previously entered form data. + $data = JFactory::getApplication()->getUserState('com_users.edit.user.data', array()); + + if (empty($data)) + { + $data = $this->getItem(); + } + + $this->preprocessData('com_users.profile', $data, 'user'); + + return $data; + } + + /** + * Override JModelAdmin::preprocessForm to ensure the correct plugin group is loaded. + * + * @param JForm $form A JForm object. + * @param mixed $data The data expected for the form. + * @param string $group The name of the plugin group to import (defaults to "content"). + * + * @return void + * + * @since 1.6 + * @throws Exception if there is an error in the form event. + */ + protected function preprocessForm(JForm $form, $data, $group = 'user') + { + parent::preprocessForm($form, $data, $group); + } + + /** + * Method to save the form data. + * + * @param array $data The form data. + * + * @return boolean True on success. + * + * @since 1.6 + */ + public function save($data) + { + $pk = (!empty($data['id'])) ? $data['id'] : (int) $this->getState('user.id'); + $user = JUser::getInstance($pk); + + $my = JFactory::getUser(); + $iAmSuperAdmin = $my->authorise('core.admin'); + + // User cannot modify own user groups + if ((int) $user->id == (int) $my->id && !$iAmSuperAdmin && isset($data['groups'])) + { + // Form was probably tampered with + JFactory::getApplication()->enqueueMessage(JText::_('COM_USERS_USERS_ERROR_CANNOT_EDIT_OWN_GROUP'), 'warning'); + + $data['groups'] = null; + } + + if ($data['block'] && $pk == $my->id && !$my->block) + { + $this->setError(JText::_('COM_USERS_USERS_ERROR_CANNOT_BLOCK_SELF')); + + return false; + } + + // Make sure user groups is selected when add/edit an account + if (empty($data['groups']) && ((int) $user->id != (int) $my->id || $iAmSuperAdmin)) + { + $this->setError(JText::_('COM_USERS_USERS_ERROR_CANNOT_SAVE_ACCOUNT_WITHOUT_GROUPS')); + + return false; + } + + // Make sure that we are not removing ourself from Super Admin group + if ($iAmSuperAdmin && $my->get('id') == $pk) + { + // Check that at least one of our new groups is Super Admin + $stillSuperAdmin = false; + $myNewGroups = $data['groups']; + + foreach ($myNewGroups as $group) + { + $stillSuperAdmin = $stillSuperAdmin ?: JAccess::checkGroup($group, 'core.admin'); + } + + if (!$stillSuperAdmin) + { + $this->setError(JText::_('COM_USERS_USERS_ERROR_CANNOT_DEMOTE_SELF')); + + return false; + } + } + + // Handle the two factor authentication setup + if (array_key_exists('twofactor', $data)) + { + $twoFactorMethod = $data['twofactor']['method']; + + // Get the current One Time Password (two factor auth) configuration + $otpConfig = $this->getOtpConfig($pk); + + if ($twoFactorMethod != 'none') + { + // Run the plugins + FOFPlatform::getInstance()->importPlugin('twofactorauth'); + $otpConfigReplies = FOFPlatform::getInstance()->runPlugins('onUserTwofactorApplyConfiguration', array($twoFactorMethod)); + + // Look for a valid reply + foreach ($otpConfigReplies as $reply) + { + if (!is_object($reply) || empty($reply->method) || ($reply->method != $twoFactorMethod)) + { + continue; + } + + $otpConfig->method = $reply->method; + $otpConfig->config = $reply->config; + + break; + } + + // Save OTP configuration. + $this->setOtpConfig($pk, $otpConfig); + + // Generate one time emergency passwords if required (depleted or not set) + if (empty($otpConfig->otep)) + { + $oteps = $this->generateOteps($pk); + } + } + else + { + $otpConfig->method = 'none'; + $otpConfig->config = array(); + $this->setOtpConfig($pk, $otpConfig); + } + + // Unset the raw data + unset($data['twofactor']); + + // Reload the user record with the updated OTP configuration + $user->load($pk); + } + + // Bind the data. + if (!$user->bind($data)) + { + $this->setError($user->getError()); + + return false; + } + + // Store the data. + if (!$user->save()) + { + $this->setError($user->getError()); + + return false; + } + + $this->setState('user.id', $user->id); + + return true; + } + + /** + * Method to delete rows. + * + * @param array &$pks An array of item ids. + * + * @return boolean Returns true on success, false on failure. + * + * @since 1.6 + */ + public function delete(&$pks) + { + $user = JFactory::getUser(); + $table = $this->getTable(); + $pks = (array) $pks; + + // Check if I am a Super Admin + $iAmSuperAdmin = $user->authorise('core.admin'); + + JPluginHelper::importPlugin($this->events_map['delete']); + $dispatcher = JEventDispatcher::getInstance(); + + if (in_array($user->id, $pks)) + { + $this->setError(JText::_('COM_USERS_USERS_ERROR_CANNOT_DELETE_SELF')); + + return false; + } + + // Iterate the items to delete each one. + foreach ($pks as $i => $pk) + { + if ($table->load($pk)) + { + // Access checks. + $allow = $user->authorise('core.delete', 'com_users'); + + // Don't allow non-super-admin to delete a super admin + $allow = (!$iAmSuperAdmin && JAccess::check($pk, 'core.admin')) ? false : $allow; + + if ($allow) + { + // Get users data for the users to delete. + $user_to_delete = JFactory::getUser($pk); + + // Fire the before delete event. + $dispatcher->trigger($this->event_before_delete, array($table->getProperties())); + + if (!$table->delete($pk)) + { + $this->setError($table->getError()); + + return false; + } + else + { + // Trigger the after delete event. + $dispatcher->trigger($this->event_after_delete, array($user_to_delete->getProperties(), true, $this->getError())); + } + } + else + { + // Prune items that you can't change. + unset($pks[$i]); + JError::raiseWarning(403, JText::_('JERROR_CORE_DELETE_NOT_PERMITTED')); + } + } + else + { + $this->setError($table->getError()); + + return false; + } + } + + return true; + } + + /** + * Method to block user records. + * + * @param array &$pks The ids of the items to publish. + * @param integer $value The value of the published state + * + * @return boolean True on success. + * + * @since 1.6 + */ + public function block(&$pks, $value = 1) + { + $app = JFactory::getApplication(); + $dispatcher = JEventDispatcher::getInstance(); + $user = JFactory::getUser(); + + // Check if I am a Super Admin + $iAmSuperAdmin = $user->authorise('core.admin'); + $table = $this->getTable(); + $pks = (array) $pks; + + JPluginHelper::importPlugin($this->events_map['save']); + + // Prepare the logout options. + $options = array( + 'clientid' => $app->get('shared_session', '0') ? null : 0, + ); + + // Access checks. + foreach ($pks as $i => $pk) + { + if ($value == 1 && $pk == $user->get('id')) + { + // Cannot block yourself. + unset($pks[$i]); + JError::raiseWarning(403, JText::_('COM_USERS_USERS_ERROR_CANNOT_BLOCK_SELF')); + } + elseif ($table->load($pk)) + { + $old = $table->getProperties(); + $allow = $user->authorise('core.edit.state', 'com_users'); + + // Don't allow non-super-admin to delete a super admin + $allow = (!$iAmSuperAdmin && JAccess::check($pk, 'core.admin')) ? false : $allow; + + if ($allow) + { + // Skip changing of same state + if ($table->block == $value) + { + unset($pks[$i]); + continue; + } + + $table->block = (int) $value; + + // If unblocking, also change password reset count to zero to unblock reset + if ($table->block === 0) + { + $table->resetCount = 0; + } + + // Allow an exception to be thrown. + try + { + if (!$table->check()) + { + $this->setError($table->getError()); + + return false; + } + + // Trigger the before save event. + $result = $dispatcher->trigger($this->event_before_save, array($old, false, $table->getProperties())); + + if (in_array(false, $result, true)) + { + // Plugin will have to raise its own error or throw an exception. + return false; + } + + // Store the table. + if (!$table->store()) + { + $this->setError($table->getError()); + + return false; + } + + // Trigger the after save event + $dispatcher->trigger($this->event_after_save, array($table->getProperties(), false, true, null)); + } + catch (Exception $e) + { + $this->setError($e->getMessage()); + + return false; + } + + // Log the user out. + if ($value) + { + $app->logout($table->id, $options); + } + } + else + { + // Prune items that you can't change. + unset($pks[$i]); + JError::raiseWarning(403, JText::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED')); + } + } + } + + return true; + } + + /** + * Method to activate user records. + * + * @param array &$pks The ids of the items to activate. + * + * @return boolean True on success. + * + * @since 1.6 + */ + public function activate(&$pks) + { + $dispatcher = JEventDispatcher::getInstance(); + $user = JFactory::getUser(); + + // Check if I am a Super Admin + $iAmSuperAdmin = $user->authorise('core.admin'); + $table = $this->getTable(); + $pks = (array) $pks; + + JPluginHelper::importPlugin($this->events_map['save']); + + // Access checks. + foreach ($pks as $i => $pk) + { + if ($table->load($pk)) + { + $old = $table->getProperties(); + $allow = $user->authorise('core.edit.state', 'com_users'); + + // Don't allow non-super-admin to delete a super admin + $allow = (!$iAmSuperAdmin && JAccess::check($pk, 'core.admin')) ? false : $allow; + + if (empty($table->activation)) + { + // Ignore activated accounts. + unset($pks[$i]); + } + elseif ($allow) + { + $table->block = 0; + $table->activation = ''; + + // Allow an exception to be thrown. + try + { + if (!$table->check()) + { + $this->setError($table->getError()); + + return false; + } + + // Trigger the before save event. + $result = $dispatcher->trigger($this->event_before_save, array($old, false, $table->getProperties())); + + if (in_array(false, $result, true)) + { + // Plugin will have to raise it's own error or throw an exception. + return false; + } + + // Store the table. + if (!$table->store()) + { + $this->setError($table->getError()); + + return false; + } + + // Fire the after save event + $dispatcher->trigger($this->event_after_save, array($table->getProperties(), false, true, null)); + } + catch (Exception $e) + { + $this->setError($e->getMessage()); + + return false; + } + } + else + { + // Prune items that you can't change. + unset($pks[$i]); + JError::raiseWarning(403, JText::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED')); + } + } + } + + return true; + } + + /** + * Method to perform batch operations on an item or a set of items. + * + * @param array $commands An array of commands to perform. + * @param array $pks An array of item ids. + * @param array $contexts An array of item contexts. + * + * @return boolean Returns true on success, false on failure. + * + * @since 2.5 + */ + public function batch($commands, $pks, $contexts) + { + // Sanitize user ids. + $pks = array_unique($pks); + $pks = ArrayHelper::toInteger($pks); + + // Remove any values of zero. + if (array_search(0, $pks, true)) + { + unset($pks[array_search(0, $pks, true)]); + } + + if (empty($pks)) + { + $this->setError(JText::_('COM_USERS_USERS_NO_ITEM_SELECTED')); + + return false; + } + + $done = false; + + if (!empty($commands['group_id'])) + { + $cmd = ArrayHelper::getValue($commands, 'group_action', 'add'); + + if (!$this->batchUser((int) $commands['group_id'], $pks, $cmd)) + { + return false; + } + + $done = true; + } + + if (!empty($commands['reset_id'])) + { + if (!$this->batchReset($pks, $commands['reset_id'])) + { + return false; + } + + $done = true; + } + + if (!$done) + { + $this->setError(JText::_('JLIB_APPLICATION_ERROR_INSUFFICIENT_BATCH_INFORMATION')); + + return false; + } + + // Clear the cache + $this->cleanCache(); + + return true; + } + + /** + * Batch flag users as being required to reset their passwords + * + * @param array $userIds An array of user IDs on which to operate + * @param string $action The action to perform + * + * @return boolean True on success, false on failure + * + * @since 3.2 + */ + public function batchReset($userIds, $action) + { + $userIds = ArrayHelper::toInteger($userIds); + + // Check if I am a Super Admin + $iAmSuperAdmin = JFactory::getUser()->authorise('core.admin'); + + // Non-super super user cannot work with super-admin user. + if (!$iAmSuperAdmin && JUserHelper::checkSuperUserInUsers($userIds)) + { + $this->setError(JText::_('COM_USERS_ERROR_CANNOT_BATCH_SUPERUSER')); + + return false; + } + + // Set the action to perform + if ($action === 'yes') + { + $value = 1; + } + else + { + $value = 0; + } + + // Prune out the current user if they are in the supplied user ID array + $userIds = array_diff($userIds, array(JFactory::getUser()->id)); + + if (empty($userIds)) + { + $this->setError(JText::_('COM_USERS_USERS_ERROR_CANNOT_REQUIRERESET_SELF')); + + return false; + } + + // Get the DB object + $db = $this->getDbo(); + + $userIds = ArrayHelper::toInteger($userIds); + + $query = $db->getQuery(true); + + // Update the reset flag + $query->update($db->quoteName('#__users')) + ->set($db->quoteName('requireReset') . ' = ' . $value) + ->where($db->quoteName('id') . ' IN (' . implode(',', $userIds) . ')'); + + $db->setQuery($query); + + try + { + $db->execute(); + } + catch (RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + + return true; + } + + /** + * Perform batch operations + * + * @param integer $groupId The group ID which assignments are being edited + * @param array $userIds An array of user IDs on which to operate + * @param string $action The action to perform + * + * @return boolean True on success, false on failure + * + * @since 1.6 + */ + public function batchUser($groupId, $userIds, $action) + { + $userIds = ArrayHelper::toInteger($userIds); + + // Check if I am a Super Admin + $iAmSuperAdmin = JFactory::getUser()->authorise('core.admin'); + + // Non-super super user cannot work with super-admin user. + if (!$iAmSuperAdmin && JUserHelper::checkSuperUserInUsers($userIds)) + { + $this->setError(JText::_('COM_USERS_ERROR_CANNOT_BATCH_SUPERUSER')); + + return false; + } + + // Non-super admin cannot work with super-admin group. + if ((!$iAmSuperAdmin && JAccess::checkGroup($groupId, 'core.admin')) || $groupId < 1) + { + $this->setError(JText::_('COM_USERS_ERROR_INVALID_GROUP')); + + return false; + } + + // Get the DB object + $db = $this->getDbo(); + + switch ($action) + { + // Sets users to a selected group + case 'set': + $doDelete = 'all'; + $doAssign = true; + break; + + // Remove users from a selected group + case 'del': + $doDelete = 'group'; + break; + + // Add users to a selected group + case 'add': + default: + $doAssign = true; + break; + } + + // Remove the users from the group if requested. + if (isset($doDelete)) + { + $query = $db->getQuery(true); + + // Remove users from the group + $query->delete($db->quoteName('#__user_usergroup_map')) + ->where($db->quoteName('user_id') . ' IN (' . implode(',', $userIds) . ')'); + + // Only remove users from selected group + if ($doDelete == 'group') + { + $query->where($db->quoteName('group_id') . ' = ' . (int) $groupId); + } + + $db->setQuery($query); + + try + { + $db->execute(); + } + catch (RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + } + + // Assign the users to the group if requested. + if (isset($doAssign)) + { + $query = $db->getQuery(true); + + // First, we need to check if the user is already assigned to a group + $query->select($db->quoteName('user_id')) + ->from($db->quoteName('#__user_usergroup_map')) + ->where($db->quoteName('group_id') . ' = ' . (int) $groupId); + $db->setQuery($query); + $users = $db->loadColumn(); + + // Build the values clause for the assignment query. + $query->clear(); + $groups = false; + + foreach ($userIds as $id) + { + if (!in_array($id, $users)) + { + $query->values($id . ',' . $groupId); + $groups = true; + } + } + + // If we have no users to process, throw an error to notify the user + if (!$groups) + { + $this->setError(JText::_('COM_USERS_ERROR_NO_ADDITIONS')); + + return false; + } + + $query->insert($db->quoteName('#__user_usergroup_map')) + ->columns(array($db->quoteName('user_id'), $db->quoteName('group_id'))); + $db->setQuery($query); + + try + { + $db->execute(); + } + catch (RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + } + + return true; + } + + /** + * Gets the available groups. + * + * @return array An array of groups + * + * @since 1.6 + */ + public function getGroups() + { + $user = JFactory::getUser(); + + if ($user->authorise('core.edit', 'com_users') && $user->authorise('core.manage', 'com_users')) + { + $model = JModelLegacy::getInstance('Groups', 'UsersModel', array('ignore_request' => true)); + + return $model->getItems(); + } + else + { + return null; + } + } + + /** + * Gets the groups this object is assigned to + * + * @param integer $userId The user ID to retrieve the groups for + * + * @return array An array of assigned groups + * + * @since 1.6 + */ + public function getAssignedGroups($userId = null) + { + $userId = (!empty($userId)) ? $userId : (int) $this->getState('user.id'); + + if (empty($userId)) + { + $result = array(); + $form = $this->getForm(); + + if ($form) + { + $groupsIDs = $form->getValue('groups'); + } + + if (!empty($groupsIDs)) + { + $result = $groupsIDs; + } + else + { + $params = JComponentHelper::getParams('com_users'); + + if ($groupId = $params->get('new_usertype', $params->get('guest_usergroup', 1))) + { + $result[] = $groupId; + } + } + } + else + { + $result = JUserHelper::getUserGroups($userId); + } + + return $result; + } + + /** + * Returns the one time password (OTP) – a.k.a. two factor authentication – + * configuration for a particular user. + * + * @param integer $userId The numeric ID of the user + * + * @return stdClass An object holding the OTP configuration for this user + * + * @since 3.2 + */ + public function getOtpConfig($userId = null) + { + $userId = (!empty($userId)) ? $userId : (int) $this->getState('user.id'); + + // Initialise + $otpConfig = (object) array( + 'method' => 'none', + 'config' => array(), + 'otep' => array() + ); + + /** + * Get the raw data, without going through JUser (required in order to + * be able to modify the user record before logging in the user). + */ + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select('*') + ->from($db->qn('#__users')) + ->where($db->qn('id') . ' = ' . (int) $userId); + $db->setQuery($query); + $item = $db->loadObject(); + + // Make sure this user does have OTP enabled + if (empty($item->otpKey)) + { + return $otpConfig; + } + + // Get the encrypted data + list($method, $config) = explode(':', $item->otpKey, 2); + $encryptedOtep = $item->otep; + + // Get the secret key, yes the thing that is saved in the configuration file + $key = $this->getOtpConfigEncryptionKey(); + + if (strpos($config, '{') === false) + { + $openssl = new FOFEncryptAes($key, 256); + $mcrypt = new FOFEncryptAes($key, 256, 'cbc', null, 'mcrypt'); + + $decryptedConfig = $mcrypt->decryptString($config); + + if (strpos($decryptedConfig, '{') !== false) + { + // Data encrypted with mcrypt + $decryptedOtep = $mcrypt->decryptString($encryptedOtep); + $encryptedOtep = $openssl->encryptString($decryptedOtep); + } + else + { + // Config data seems to be save encrypted, this can happen with 3.6.3 and openssl, lets get the data + $decryptedConfig = $openssl->decryptString($config); + } + + $otpKey = $method . ':' . $decryptedConfig; + + $query = $db->getQuery(true) + ->update($db->qn('#__users')) + ->set($db->qn('otep') . '=' . $db->q($encryptedOtep)) + ->set($db->qn('otpKey') . '=' . $db->q($otpKey)) + ->where($db->qn('id') . ' = ' . $db->q($userId)); + $db->setQuery($query); + $db->execute(); + } + else + { + $decryptedConfig = $config; + } + + // Create an encryptor class + $aes = new FOFEncryptAes($key, 256); + + // Decrypt the data + $decryptedOtep = $aes->decryptString($encryptedOtep); + + // Remove the null padding added during encryption + $decryptedConfig = rtrim($decryptedConfig, "\0"); + $decryptedOtep = rtrim($decryptedOtep, "\0"); + + // Update the configuration object + $otpConfig->method = $method; + $otpConfig->config = @json_decode($decryptedConfig); + $otpConfig->otep = @json_decode($decryptedOtep); + + /* + * If the decryption failed for any reason we essentially disable the + * two-factor authentication. This prevents impossible to log in sites + * if the site admin changes the site secret for any reason. + */ + if (is_null($otpConfig->config)) + { + $otpConfig->config = array(); + } + + if (is_object($otpConfig->config)) + { + $otpConfig->config = (array) $otpConfig->config; + } + + if (is_null($otpConfig->otep)) + { + $otpConfig->otep = array(); + } + + if (is_object($otpConfig->otep)) + { + $otpConfig->otep = (array) $otpConfig->otep; + } + + // Return the configuration object + return $otpConfig; + } + + /** + * Sets the one time password (OTP) – a.k.a. two factor authentication – + * configuration for a particular user. The $otpConfig object is the same as + * the one returned by the getOtpConfig method. + * + * @param integer $userId The numeric ID of the user + * @param stdClass $otpConfig The OTP configuration object + * + * @return boolean True on success + * + * @since 3.2 + */ + public function setOtpConfig($userId, $otpConfig) + { + $userId = (!empty($userId)) ? $userId : (int) $this->getState('user.id'); + + $updates = (object) array( + 'id' => $userId, + 'otpKey' => '', + 'otep' => '' + ); + + // Create an encryptor class + $key = $this->getOtpConfigEncryptionKey(); + $aes = new FOFEncryptAes($key, 256); + + // Create the encrypted option strings + if (!empty($otpConfig->method) && ($otpConfig->method != 'none')) + { + $decryptedConfig = json_encode($otpConfig->config); + $decryptedOtep = json_encode($otpConfig->otep); + $updates->otpKey = $otpConfig->method . ':' . $decryptedConfig; + $updates->otep = $aes->encryptString($decryptedOtep); + } + + $db = $this->getDbo(); + $result = $db->updateObject('#__users', $updates, 'id'); + + return $result; + } + + /** + * Gets the symmetric encryption key for the OTP configuration data. It + * currently returns the site's secret. + * + * @return string The encryption key + * + * @since 3.2 + */ + public function getOtpConfigEncryptionKey() + { + return JFactory::getConfig()->get('secret'); + } + + /** + * Gets the configuration forms for all two-factor authentication methods + * in an array. + * + * @param integer $userId The user ID to load the forms for (optional) + * + * @return array + * + * @since 3.2 + */ + public function getTwofactorform($userId = null) + { + $userId = (!empty($userId)) ? $userId : (int) $this->getState('user.id'); + + $otpConfig = $this->getOtpConfig($userId); + + FOFPlatform::getInstance()->importPlugin('twofactorauth'); + + return FOFPlatform::getInstance()->runPlugins('onUserTwofactorShowConfiguration', array($otpConfig, $userId)); + } + + /** + * Generates a new set of One Time Emergency Passwords (OTEPs) for a given user. + * + * @param integer $userId The user ID + * @param integer $count How many OTEPs to generate? Default: 10 + * + * @return array The generated OTEPs + * + * @since 3.2 + */ + public function generateOteps($userId, $count = 10) + { + $userId = (!empty($userId)) ? $userId : (int) $this->getState('user.id'); + + // Initialise + $oteps = array(); + + // Get the OTP configuration for the user + $otpConfig = $this->getOtpConfig($userId); + + // If two factor authentication is not enabled, abort + if (empty($otpConfig->method) || ($otpConfig->method == 'none')) + { + return $oteps; + } + + $salt = '0123456789'; + $base = strlen($salt); + $length = 16; + + for ($i = 0; $i < $count; $i++) + { + $makepass = ''; + $random = JCrypt::genRandomBytes($length + 1); + $shift = ord($random[0]); + + for ($j = 1; $j <= $length; ++$j) + { + $makepass .= $salt[($shift + ord($random[$j])) % $base]; + $shift += ord($random[$j]); + } + + $oteps[] = $makepass; + } + + $otpConfig->otep = $oteps; + + // Save the now modified OTP configuration + $this->setOtpConfig($userId, $otpConfig); + + return $oteps; + } + + /** + * Checks if the provided secret key is a valid two factor authentication + * secret key. If not, it will check it against the list of one time + * emergency passwords (OTEPs). If it's a valid OTEP it will also remove it + * from the user's list of OTEPs. + * + * This method will return true in the following conditions: + * - The two factor authentication is not enabled + * - You have provided a valid secret key for + * - You have provided a valid OTEP + * + * You can define the following options in the $options array: + * otp_config The OTP (one time password, a.k.a. two factor auth) + * configuration object. If not set we'll load it automatically. + * warn_if_not_req Issue a warning if you are checking a secret key against + * a user account which doesn't have any two factor + * authentication method enabled. + * warn_irq_msg The string to use for the warn_if_not_req warning + * + * @param integer $userId The user's numeric ID + * @param string $secretKey The secret key you want to check + * @param array $options Options; see above + * + * @return boolean True if it's a valid secret key for this user. + * + * @since 3.2 + */ + public function isValidSecretKey($userId, $secretKey, $options = array()) + { + // Load the user's OTP (one time password, a.k.a. two factor auth) configuration + if (!array_key_exists('otp_config', $options)) + { + $otpConfig = $this->getOtpConfig($userId); + $options['otp_config'] = $otpConfig; + } + else + { + $otpConfig = $options['otp_config']; + } + + // Check if the user has enabled two factor authentication + if (empty($otpConfig->method) || ($otpConfig->method == 'none')) + { + // Load language + $lang = JFactory::getLanguage(); + $extension = 'com_users'; + $source = JPATH_ADMINISTRATOR . '/components/' . $extension; + + $lang->load($extension, JPATH_ADMINISTRATOR, null, false, true) + || $lang->load($extension, $source, null, false, true); + + $warn = true; + $warnMessage = JText::_('COM_USERS_ERROR_SECRET_CODE_WITHOUT_TFA'); + + if (array_key_exists('warn_if_not_req', $options)) + { + $warn = $options['warn_if_not_req']; + } + + if (array_key_exists('warn_irq_msg', $options)) + { + $warnMessage = $options['warn_irq_msg']; + } + + // Warn the user if they are using a secret code but they have not + // enabled two factor auth in their account. + if (!empty($secretKey) && $warn) + { + try + { + $app = JFactory::getApplication(); + $app->enqueueMessage($warnMessage, 'warning'); + } + catch (Exception $exc) + { + // This happens when we are in CLI mode. In this case + // no warning is issued + return true; + } + } + + return true; + } + + $credentials = array( + 'secretkey' => $secretKey, + ); + + // Try to validate the OTP + FOFPlatform::getInstance()->importPlugin('twofactorauth'); + + $otpAuthReplies = FOFPlatform::getInstance()->runPlugins('onUserTwofactorAuthenticate', array($credentials, $options)); + + $check = false; + + /* + * This looks like noob code but DO NOT TOUCH IT and do not convert + * to in_array(). During testing in_array() inexplicably returned + * null when the OTEP begins with a zero! o_O + */ + if (!empty($otpAuthReplies)) + { + foreach ($otpAuthReplies as $authReply) + { + $check = $check || $authReply; + } + } + + // Fall back to one time emergency passwords + if (!$check) + { + $check = $this->isValidOtep($userId, $secretKey, $otpConfig); + } + + return $check; + } + + /** + * Checks if the supplied string is a valid one time emergency password + * (OTEP) for this user. If it is it will be automatically removed from the + * user's list of OTEPs. + * + * @param integer $userId The user ID against which you are checking + * @param string $otep The string you want to test for validity + * @param object $otpConfig Optional; the two factor authentication configuration (automatically fetched if not set) + * + * @return boolean True if it's a valid OTEP or if two factor auth is not + * enabled in this user's account. + * + * @since 3.2 + */ + public function isValidOtep($userId, $otep, $otpConfig = null) + { + if (is_null($otpConfig)) + { + $otpConfig = $this->getOtpConfig($userId); + } + + // Did the user use an OTEP instead? + if (empty($otpConfig->otep)) + { + if (empty($otpConfig->method) || ($otpConfig->method == 'none')) + { + // Two factor authentication is not enabled on this account. + // Any string is assumed to be a valid OTEP. + return true; + } + else + { + /** + * Two factor authentication enabled and no OTEPs defined. The + * user has used them all up. Therefore anything they enter is + * an invalid OTEP. + */ + return false; + } + } + + // Clean up the OTEP (remove dashes, spaces and other funny stuff + // our beloved users may have unwittingly stuffed in it) + $otep = filter_var($otep, FILTER_SANITIZE_NUMBER_INT); + $otep = str_replace('-', '', $otep); + + $check = false; + + // Did we find a valid OTEP? + if (in_array($otep, $otpConfig->otep)) + { + // Remove the OTEP from the array + $otpConfig->otep = array_diff($otpConfig->otep, array($otep)); + + $this->setOtpConfig($userId, $otpConfig); + + // Return true; the OTEP was a valid one + $check = true; + } + + return $check; + } +} diff --git a/Sites/pages/administrator/components/com_users/models/users.php b/Sites/pages/administrator/components/com_users/models/users.php new file mode 100644 index 00000000..f9eff641 --- /dev/null +++ b/Sites/pages/administrator/components/com_users/models/users.php @@ -0,0 +1,530 @@ +input->get('layout', 'default', 'cmd')) + { + $this->context .= '.' . $layout; + } + + // Load the filter state. + $this->setState('filter.search', $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search', '', 'string')); + $this->setState('filter.active', $this->getUserStateFromRequest($this->context . '.filter.active', 'filter_active', '', 'cmd')); + $this->setState('filter.state', $this->getUserStateFromRequest($this->context . '.filter.state', 'filter_state', '', 'cmd')); + $this->setState('filter.group_id', $this->getUserStateFromRequest($this->context . '.filter.group_id', 'filter_group_id', null, 'int')); + $this->setState('filter.range', $this->getUserStateFromRequest($this->context . '.filter.range', 'filter_range', '', 'cmd')); + $this->setState( + 'filter.lastvisitrange', $this->getUserStateFromRequest($this->context . '.filter.lastvisitrange', 'filter_lastvisitrange', '', 'cmd') + ); + + $groups = json_decode(base64_decode($app->input->get('groups', '', 'BASE64'))); + + if (isset($groups)) + { + $groups = ArrayHelper::toInteger($groups); + } + + $this->setState('filter.groups', $groups); + + $excluded = json_decode(base64_decode($app->input->get('excluded', '', 'BASE64'))); + + if (isset($excluded)) + { + $excluded = ArrayHelper::toInteger($excluded); + } + + $this->setState('filter.excluded', $excluded); + + // Load the parameters. + $params = JComponentHelper::getParams('com_users'); + $this->setState('params', $params); + + // List state information. + parent::populateState($ordering, $direction); + } + + /** + * Method to get a store id based on model configuration state. + * + * This is necessary because the model is used by the component and + * different modules that might need different sets of data or different + * ordering requirements. + * + * @param string $id A prefix for the store id. + * + * @return string A store id. + * + * @since 1.6 + */ + protected function getStoreId($id = '') + { + // Compile the store id. + $id .= ':' . $this->getState('filter.search'); + $id .= ':' . $this->getState('filter.active'); + $id .= ':' . $this->getState('filter.state'); + $id .= ':' . $this->getState('filter.group_id'); + $id .= ':' . $this->getState('filter.range'); + + return parent::getStoreId($id); + } + + /** + * Gets the list of users and adds expensive joins to the result set. + * + * @return mixed An array of data items on success, false on failure. + * + * @since 1.6 + */ + public function getItems() + { + // Get a storage key. + $store = $this->getStoreId(); + + // Try to load the data from internal storage. + if (empty($this->cache[$store])) + { + $groups = $this->getState('filter.groups'); + $groupId = $this->getState('filter.group_id'); + + if (isset($groups) && (empty($groups) || $groupId && !in_array($groupId, $groups))) + { + $items = array(); + } + else + { + $items = parent::getItems(); + } + + // Bail out on an error or empty list. + if (empty($items)) + { + $this->cache[$store] = $items; + + return $items; + } + + // Joining the groups with the main query is a performance hog. + // Find the information only on the result set. + + // First pass: get list of the user id's and reset the counts. + $userIds = array(); + + foreach ($items as $item) + { + $userIds[] = (int) $item->id; + $item->group_count = 0; + $item->group_names = ''; + $item->note_count = 0; + } + + // Get the counts from the database only for the users in the list. + $db = $this->getDbo(); + $query = $db->getQuery(true); + + // Join over the group mapping table. + $query->select('map.user_id, COUNT(map.group_id) AS group_count') + ->from('#__user_usergroup_map AS map') + ->where('map.user_id IN (' . implode(',', $userIds) . ')') + ->group('map.user_id') + // Join over the user groups table. + ->join('LEFT', '#__usergroups AS g2 ON g2.id = map.group_id'); + + $db->setQuery($query); + + // Load the counts into an array indexed on the user id field. + try + { + $userGroups = $db->loadObjectList('user_id'); + } + catch (RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + + $query->clear() + ->select('n.user_id, COUNT(n.id) As note_count') + ->from('#__user_notes AS n') + ->where('n.user_id IN (' . implode(',', $userIds) . ')') + ->where('n.state >= 0') + ->group('n.user_id'); + + $db->setQuery($query); + + // Load the counts into an array indexed on the aro.value field (the user id). + try + { + $userNotes = $db->loadObjectList('user_id'); + } + catch (RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + + // Second pass: collect the group counts into the master items array. + foreach ($items as &$item) + { + if (isset($userGroups[$item->id])) + { + $item->group_count = $userGroups[$item->id]->group_count; + + // Group_concat in other databases is not supported + $item->group_names = $this->_getUserDisplayedGroups($item->id); + } + + if (isset($userNotes[$item->id])) + { + $item->note_count = $userNotes[$item->id]->note_count; + } + } + + // Add the items to the internal cache. + $this->cache[$store] = $items; + } + + return $this->cache[$store]; + } + + /** + * Build an SQL query to load the list data. + * + * @return JDatabaseQuery + * + * @since 1.6 + */ + protected function getListQuery() + { + // Create a new query object. + $db = $this->getDbo(); + $query = $db->getQuery(true); + + // Select the required fields from the table. + $query->select( + $this->getState( + 'list.select', + 'a.*' + ) + ); + + $query->from($db->quoteName('#__users') . ' AS a'); + + // If the model is set to check item state, add to the query. + $state = $this->getState('filter.state'); + + if (is_numeric($state)) + { + $query->where('a.block = ' . (int) $state); + } + + // If the model is set to check the activated state, add to the query. + $active = $this->getState('filter.active'); + + if (is_numeric($active)) + { + if ($active == '0') + { + $query->where('a.activation IN (' . $db->quote('') . ', ' . $db->quote('0') . ')'); + } + elseif ($active == '1') + { + $query->where($query->length('a.activation') . ' > 1'); + } + } + + // Filter the items over the group id if set. + $groupId = $this->getState('filter.group_id'); + $groups = $this->getState('filter.groups'); + + if ($groupId || isset($groups)) + { + $query->join('LEFT', '#__user_usergroup_map AS map2 ON map2.user_id = a.id') + ->group( + $db->quoteName( + array( + 'a.id', + 'a.name', + 'a.username', + 'a.password', + 'a.block', + 'a.sendEmail', + 'a.registerDate', + 'a.lastvisitDate', + 'a.activation', + 'a.params', + 'a.email' + ) + ) + ); + + if ($groupId) + { + $query->where('map2.group_id = ' . (int) $groupId); + } + + if (isset($groups)) + { + $query->where('map2.group_id IN (' . implode(',', $groups) . ')'); + } + } + + // Filter the items over the search string if set. + $search = $this->getState('filter.search'); + + if (!empty($search)) + { + if (stripos($search, 'id:') === 0) + { + $query->where('a.id = ' . (int) substr($search, 3)); + } + elseif (stripos($search, 'username:') === 0) + { + $search = $db->quote('%' . $db->escape(substr($search, 9), true) . '%'); + $query->where('a.username LIKE ' . $search); + } + else + { + // Escape the search token. + $search = $db->quote('%' . str_replace(' ', '%', $db->escape(trim($search), true) . '%')); + + // Compile the different search clauses. + $searches = array(); + $searches[] = 'a.name LIKE ' . $search; + $searches[] = 'a.username LIKE ' . $search; + $searches[] = 'a.email LIKE ' . $search; + + // Add the clauses to the query. + $query->where('(' . implode(' OR ', $searches) . ')'); + } + } + + // Add filter for registration ranges select list + $range = $this->getState('filter.range'); + + // Apply the range filter. + if ($range) + { + $dates = $this->buildDateRange($range); + + if ($dates['dNow'] === false) + { + $query->where( + $db->qn('a.registerDate') . ' < ' . $db->quote($dates['dStart']->format('Y-m-d H:i:s')) + ); + } + else + { + $query->where( + $db->qn('a.registerDate') . ' >= ' . $db->quote($dates['dStart']->format('Y-m-d H:i:s')) . + ' AND ' . $db->qn('a.registerDate') . ' <= ' . $db->quote($dates['dNow']->format('Y-m-d H:i:s')) + ); + } + } + + // Add filter for registration ranges select list + $lastvisitrange = $this->getState('filter.lastvisitrange'); + + // Apply the range filter. + if ($lastvisitrange) + { + $dates = $this->buildDateRange($lastvisitrange); + + if (is_string($dates['dStart'])) + { + $query->where( + $db->qn('a.lastvisitDate') . ' = ' . $db->quote($dates['dStart']) + ); + } + elseif ($dates['dNow'] === false) + { + $query->where( + $db->qn('a.lastvisitDate') . ' < ' . $db->quote($dates['dStart']->format('Y-m-d H:i:s')) + ); + } + else + { + $query->where( + $db->qn('a.lastvisitDate') . ' >= ' . $db->quote($dates['dStart']->format('Y-m-d H:i:s')) . + ' AND ' . $db->qn('a.lastvisitDate') . ' <= ' . $db->quote($dates['dNow']->format('Y-m-d H:i:s')) + ); + } + } + + // Filter by excluded users + $excluded = $this->getState('filter.excluded'); + + if (!empty($excluded)) + { + $query->where('id NOT IN (' . implode(',', $excluded) . ')'); + } + + // Add the list ordering clause. + $query->order($db->qn($db->escape($this->getState('list.ordering', 'a.name'))) . ' ' . $db->escape($this->getState('list.direction', 'ASC'))); + + return $query; + } + + /** + * Construct the date range to filter on. + * + * @param string $range The textual range to construct the filter for. + * + * @return string The date range to filter on. + * + * @since 3.6.0 + */ + private function buildDateRange($range) + { + // Get UTC for now. + $dNow = new JDate; + $dStart = clone $dNow; + + switch ($range) + { + case 'past_week': + $dStart->modify('-7 day'); + break; + + case 'past_1month': + $dStart->modify('-1 month'); + break; + + case 'past_3month': + $dStart->modify('-3 month'); + break; + + case 'past_6month': + $dStart->modify('-6 month'); + break; + + case 'post_year': + $dNow = false; + case 'past_year': + $dStart->modify('-1 year'); + break; + + case 'today': + // Ranges that need to align with local 'days' need special treatment. + $app = JFactory::getApplication(); + $offset = $app->get('offset'); + + // Reset the start time to be the beginning of today, local time. + $dStart = new JDate('now', $offset); + $dStart->setTime(0, 0, 0); + + // Now change the timezone back to UTC. + $tz = new DateTimeZone('GMT'); + $dStart->setTimezone($tz); + break; + case 'never': + $dNow = false; + $dStart = $this->_db->getNullDate(); + break; + } + + return array('dNow' => $dNow, 'dStart' => $dStart); + } + + /** + * SQL server change + * + * @param integer $userId User identifier + * + * @return string Groups titles imploded :$ + */ + protected function _getUserDisplayedGroups($userId) + { + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select($db->qn('title')) + ->from($db->qn('#__usergroups', 'ug')) + ->join('LEFT', $db->qn('#__user_usergroup_map', 'map') . ' ON (ug.id = map.group_id)') + ->where($db->qn('map.user_id') . ' = ' . (int) $userId); + + try + { + $result = $db->setQuery($query)->loadColumn(); + } + catch (RunTimeException $e) + { + $result = array(); + } + + return implode("\n", $result); + } +} diff --git a/Sites/pages/administrator/components/com_users/tables/note.php b/Sites/pages/administrator/components/com_users/tables/note.php new file mode 100644 index 00000000..51c7d985 --- /dev/null +++ b/Sites/pages/administrator/components/com_users/tables/note.php @@ -0,0 +1,161 @@ +setColumnAlias('published', 'state'); + + JTableObserverContenthistory::createObserver($this, array('typeAlias' => 'com_users.note')); + } + + /** + * Overloaded store method for the notes table. + * + * @param boolean $updateNulls Toggle whether null values should be updated. + * + * @return boolean True on success, false on failure. + * + * @since 2.5 + */ + public function store($updateNulls = false) + { + $date = JFactory::getDate()->toSql(); + $userId = JFactory::getUser()->get('id'); + + $this->modified_time = $date; + $this->modified_user_id = $userId; + + if (!((int) $this->review_time)) + { + // Null date. + $this->review_time = $this->_db->getNullDate(); + } + + if (empty($this->id)) + { + // New record. + $this->created_time = $date; + $this->created_user_id = $userId; + } + + // Attempt to store the data. + return parent::store($updateNulls); + } + + /** + * Method to set the publishing state for a row or list of rows in the database + * table. The method respects checked out rows by other users and will attempt + * to check-in rows that it can after adjustments are made. + * + * @param mixed $pks An optional array of primary key values to update. If not set the instance property value is used. + * @param integer $state The publishing state. eg. [0 = unpublished, 1 = published] + * @param integer $userId The user id of the user performing the operation. + * + * @return boolean True on success. + * + * @since 2.5 + */ + public function publish($pks = null, $state = 1, $userId = 0) + { + $k = $this->_tbl_key; + + // Sanitize input. + $pks = ArrayHelper::toInteger($pks); + $userId = (int) $userId; + $state = (int) $state; + + // If there are no primary keys set check to see if the instance key is set. + if (empty($pks)) + { + if ($this->$k) + { + $pks = array($this->$k); + } + // Nothing to set publishing state on, return false. + else + { + $this->setError(JText::_('JLIB_DATABASE_ERROR_NO_ROWS_SELECTED')); + + return false; + } + } + + $query = $this->_db->getQuery(true) + ->update($this->_db->quoteName($this->_tbl)) + ->set($this->_db->quoteName('state') . ' = ' . (int) $state); + + // Build the WHERE clause for the primary keys. + $query->where($k . '=' . implode(' OR ' . $k . '=', $pks)); + + // Determine if there is checkin support for the table. + if (!property_exists($this, 'checked_out') || !property_exists($this, 'checked_out_time')) + { + $checkin = false; + } + else + { + $query->where('(checked_out = 0 OR checked_out = ' . (int) $userId . ')'); + $checkin = true; + } + + // Update the publishing state for rows with the given primary keys. + $this->_db->setQuery($query); + + try + { + $this->_db->execute(); + } + catch (RuntimeException $e) + { + $this->setError($this->_db->getMessage()); + + return false; + } + + // If checkin is supported and all rows were adjusted, check them in. + if ($checkin && (count($pks) == $this->_db->getAffectedRows())) + { + // Checkin the rows. + foreach ($pks as $pk) + { + $this->checkin($pk); + } + } + + // If the JTable instance value is in the list of primary keys that were set, set the instance. + if (in_array($this->$k, $pks)) + { + $this->state = $state; + } + + $this->setError(''); + + return true; + } +} diff --git a/Sites/pages/administrator/components/com_users/users.php b/Sites/pages/administrator/components/com_users/users.php new file mode 100644 index 00000000..fc3f6c7a --- /dev/null +++ b/Sites/pages/administrator/components/com_users/users.php @@ -0,0 +1,22 @@ +authorise('core.manage', 'com_users')) +{ + throw new JAccessExceptionNotallowed(JText::_('JERROR_ALERTNOAUTHOR'), 403); +} + +JLoader::register('UsersHelper', __DIR__ . '/helpers/users.php'); + +$controller = JControllerLegacy::getInstance('Users'); +$controller->execute(JFactory::getApplication()->input->get('task')); +$controller->redirect(); diff --git a/Sites/pages/administrator/components/com_users/users.xml b/Sites/pages/administrator/components/com_users/users.xml new file mode 100644 index 00000000..44652c66 --- /dev/null +++ b/Sites/pages/administrator/components/com_users/users.xml @@ -0,0 +1,40 @@ + + + com_users + Joomla! Project + April 2006 + (C) 2005 - 2020 Open Source Matters. All rights reserved. + GNU General Public License version 2 or later; see LICENSE.txt + admin@joomla.org + www.joomla.org + 3.0.0 + COM_USERS_XML_DESCRIPTION + + + controller.php + router.php + users.php + controllers + helpers + models + views + + + language/en-GB.com_users.ini + + + + config.xml + controller.php + users.php + controllers + helpers + models + views + + + language/en-GB.com_users.ini + language/en-GB.com_users.sys.ini + + + diff --git a/Sites/pages/administrator/components/com_users/views/debuggroup/tmpl/default.php b/Sites/pages/administrator/components/com_users/views/debuggroup/tmpl/default.php new file mode 100644 index 00000000..78119da2 --- /dev/null +++ b/Sites/pages/administrator/components/com_users/views/debuggroup/tmpl/default.php @@ -0,0 +1,115 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$colSpan = 4 + count($this->actions); +?> +
    +sidebar)) : ?> +
    + sidebar; ?> +
    +
    + +
    + + $this)); ?> +
    + + + + + + actions as $key => $action) : ?> + + + + + + + + + + + + + items as $i => $item) : ?> + + + + actions as $action) : ?> + checks[$name]; + if ($check === true) : + $class = 'icon-ok'; + $button = 'btn-success'; + elseif ($check === false) : + $class = 'icon-remove'; + $button = 'btn-danger'; + elseif ($check === null) : + $class = 'icon-ban-circle'; + $button = 'btn-warning'; + else : + $class = ''; + $button = ''; + endif; + ?> + + + + + + + +
    + + + + + + + + + +
    + pagination->getListFooter(); ?> +
    + escape($item->title); ?> + + $item->level + 1)) . $this->escape($item->name); ?> + + + + lft; ?> + - rgt; ?> + + id; ?> +
    + + + +
    + +   +   + +

    +
    +
    + diff --git a/Sites/pages/administrator/components/com_users/views/debuggroup/view.html.php b/Sites/pages/administrator/components/com_users/views/debuggroup/view.html.php new file mode 100644 index 00000000..3f587ac7 --- /dev/null +++ b/Sites/pages/administrator/components/com_users/views/debuggroup/view.html.php @@ -0,0 +1,106 @@ +authorise('core.manage', 'com_users')) + { + throw new JAccessExceptionNotallowed(JText::_('JERROR_ALERTNOAUTHOR'), 403); + } + + $this->actions = $this->get('DebugActions'); + $this->items = $this->get('Items'); + $this->pagination = $this->get('Pagination'); + $this->state = $this->get('State'); + $this->group = $this->get('Group'); + $this->filterForm = $this->get('FilterForm'); + $this->activeFilters = $this->get('ActiveFilters'); + + // Vars only used in hathor. + // @deprecated 4.0 To be removed with Hathor + $this->levels = UsersHelperDebug::getLevelsOptions(); + $this->components = UsersHelperDebug::getComponents(); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + $this->addToolbar(); + + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + $canDo = JHelperContent::getActions('com_users'); + + JToolbarHelper::title(JText::sprintf('COM_USERS_VIEW_DEBUG_GROUP_TITLE', $this->group->id, $this->escape($this->group->title)), 'users groups'); + JToolbarHelper::cancel('group.cancel', 'JTOOLBAR_CLOSE'); + + if ($canDo->get('core.admin') || $canDo->get('core.options')) + { + JToolbarHelper::preferences('com_users'); + JToolbarHelper::divider(); + } + + JToolbarHelper::help('JHELP_USERS_DEBUG_GROUPS'); + } +} diff --git a/Sites/pages/administrator/components/com_users/views/debuguser/tmpl/default.php b/Sites/pages/administrator/components/com_users/views/debuguser/tmpl/default.php new file mode 100644 index 00000000..657c9749 --- /dev/null +++ b/Sites/pages/administrator/components/com_users/views/debuguser/tmpl/default.php @@ -0,0 +1,115 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$colSpan = 4 + count($this->actions); +?> +
    +sidebar)) : ?> +
    + sidebar; ?> +
    +
    + +
    + + $this)); ?> +
    + + + + + + actions as $key => $action) : ?> + + + + + + + + + + + + + items as $i => $item) : ?> + + + + actions as $action) : ?> + checks[$name]; + if ($check === true) : + $class = 'icon-ok'; + $button = 'btn-success'; + elseif ($check === false) : + $class = 'icon-remove'; + $button = 'btn-danger'; + elseif ($check === null) : + $class = 'icon-ban-circle'; + $button = 'btn-warning'; + else : + $class = ''; + $button = ''; + endif; + ?> + + + + + + + +
    + + + + + + + + + +
    + pagination->getListFooter(); ?> +
    + escape($item->title); ?> + + $item->level + 1)) . $this->escape($item->name); ?> + + + + lft; ?> + - rgt; ?> + + id; ?> +
    + + + +
    + +   +   + +

    +
    +
    + diff --git a/Sites/pages/administrator/components/com_users/views/debuguser/view.html.php b/Sites/pages/administrator/components/com_users/views/debuguser/view.html.php new file mode 100644 index 00000000..61e7d680 --- /dev/null +++ b/Sites/pages/administrator/components/com_users/views/debuguser/view.html.php @@ -0,0 +1,106 @@ +authorise('core.manage', 'com_users')) + { + throw new JAccessExceptionNotallowed(JText::_('JERROR_ALERTNOAUTHOR'), 403); + } + + $this->actions = $this->get('DebugActions'); + $this->items = $this->get('Items'); + $this->pagination = $this->get('Pagination'); + $this->state = $this->get('State'); + $this->user = $this->get('User'); + $this->filterForm = $this->get('FilterForm'); + $this->activeFilters = $this->get('ActiveFilters'); + + // Vars only used in hathor. + // @deprecated 4.0 To be removed with Hathor + $this->levels = UsersHelperDebug::getLevelsOptions(); + $this->components = UsersHelperDebug::getComponents(); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + $this->addToolbar(); + + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + $canDo = JHelperContent::getActions('com_users'); + + JToolbarHelper::title(JText::sprintf('COM_USERS_VIEW_DEBUG_USER_TITLE', $this->user->id, $this->escape($this->user->name)), 'users user'); + JToolbarHelper::cancel('user.cancel', 'JTOOLBAR_CLOSE'); + + if ($canDo->get('core.admin') || $canDo->get('core.options')) + { + JToolbarHelper::preferences('com_users'); + JToolbarHelper::divider(); + } + + JToolbarHelper::help('JHELP_USERS_DEBUG_USERS'); + } +} diff --git a/Sites/pages/administrator/components/com_users/views/group/tmpl/edit.php b/Sites/pages/administrator/components/com_users/views/group/tmpl/edit.php new file mode 100644 index 00000000..c9d8b575 --- /dev/null +++ b/Sites/pages/administrator/components/com_users/views/group/tmpl/edit.php @@ -0,0 +1,43 @@ +addScriptDeclaration(" + Joomla.submitbutton = function(task) + { + if (task == 'group.cancel' || document.formvalidator.isValid(document.getElementById('group-form'))) + { + Joomla.submitform(task, document.getElementById('group-form')); + } + }; +"); +?> + +
    +
    + 'details')); ?> + + form->renderField('title'); ?> + form->renderField('parent_id'); ?> + + ignore_fieldsets = array('group_details'); ?> + + +
    + + + +
    diff --git a/Sites/pages/administrator/components/com_users/views/group/tmpl/edit.xml b/Sites/pages/administrator/components/com_users/views/group/tmpl/edit.xml new file mode 100755 index 00000000..bcc58adf --- /dev/null +++ b/Sites/pages/administrator/components/com_users/views/group/tmpl/edit.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/Sites/pages/administrator/components/com_users/views/group/view.html.php b/Sites/pages/administrator/components/com_users/views/group/view.html.php new file mode 100644 index 00000000..bcccc194 --- /dev/null +++ b/Sites/pages/administrator/components/com_users/views/group/view.html.php @@ -0,0 +1,105 @@ +state = $this->get('State'); + $this->item = $this->get('Item'); + $this->form = $this->get('Form'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + $this->addToolbar(); + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + JFactory::getApplication()->input->set('hidemainmenu', true); + + $isNew = ($this->item->id == 0); + $canDo = JHelperContent::getActions('com_users'); + + JToolbarHelper::title(JText::_($isNew ? 'COM_USERS_VIEW_NEW_GROUP_TITLE' : 'COM_USERS_VIEW_EDIT_GROUP_TITLE'), 'users groups-add'); + + if ($canDo->get('core.edit') || $canDo->get('core.create')) + { + JToolbarHelper::apply('group.apply'); + JToolbarHelper::save('group.save'); + } + + if ($canDo->get('core.create')) + { + JToolbarHelper::save2new('group.save2new'); + } + + // If an existing item, can save to a copy. + if (!$isNew && $canDo->get('core.create')) + { + JToolbarHelper::save2copy('group.save2copy'); + } + + if (empty($this->item->id)) + { + JToolbarHelper::cancel('group.cancel'); + } + else + { + JToolbarHelper::cancel('group.cancel', 'JTOOLBAR_CLOSE'); + } + + JToolbarHelper::divider(); + JToolbarHelper::help('JHELP_USERS_GROUPS_EDIT'); + } +} diff --git a/Sites/pages/administrator/components/com_users/views/groups/tmpl/default.php b/Sites/pages/administrator/components/com_users/views/groups/tmpl/default.php new file mode 100644 index 00000000..631e8bef --- /dev/null +++ b/Sites/pages/administrator/components/com_users/views/groups/tmpl/default.php @@ -0,0 +1,144 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$debugGroups = $this->state->get('params')->get('debugGroups', 1); + +JText::script('COM_USERS_GROUPS_CONFIRM_DELETE'); + +JFactory::getDocument()->addScriptDeclaration(' + Joomla.submitbutton = function(task) { + if (task == "groups.delete") { + var i, cids = document.getElementsByName("cid[]"); + for (i = 0; i < cids.length; i++) { + if (cids[i].checked && cids[i].parentNode.getAttribute("data-usercount") != 0) { + if (confirm(Joomla.JText._("COM_USERS_GROUPS_CONFIRM_DELETE"))) { + Joomla.submitform(task); + } + return false; + } + } + } + + Joomla.submitform(task); + return false; + }; +'); +?> +
    +sidebar)) : ?> +
    + sidebar; ?> +
    +
    + +
    + + $this, 'options' => array('filterButton' => false))); ?> +
    + items)) : ?> +
    + +
    + + + + + + + + + + + + + + + + + + items as $i => $item) : + $canCreate = $user->authorise('core.create', 'com_users'); + $canEdit = $user->authorise('core.edit', 'com_users'); + + // If this group is super admin and this user is not super admin, $canEdit is false + if (!$user->authorise('core.admin') && JAccess::checkGroup($item->id, 'core.admin')) + { + $canEdit = false; + } + $canChange = $user->authorise('core.edit.state', 'com_users'); + ?> + + + + + + + + + +
    + + + + + + + + + +
    + pagination->getListFooter(); ?> +
    + + id); ?> + + + $item->level + 1)); ?> + + + escape($item->title); ?> + + escape($item->title); ?> + + + + + + + count_enabled; ?> + + + count_disabled; ?> + + id; ?> +
    + + + + + +
    + diff --git a/Sites/pages/administrator/components/com_users/views/groups/tmpl/default.xml b/Sites/pages/administrator/components/com_users/views/groups/tmpl/default.xml new file mode 100755 index 00000000..b5cccb81 --- /dev/null +++ b/Sites/pages/administrator/components/com_users/views/groups/tmpl/default.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/Sites/pages/administrator/components/com_users/views/groups/view.html.php b/Sites/pages/administrator/components/com_users/views/groups/view.html.php new file mode 100644 index 00000000..5e970a19 --- /dev/null +++ b/Sites/pages/administrator/components/com_users/views/groups/view.html.php @@ -0,0 +1,124 @@ +items = $this->get('Items'); + $this->pagination = $this->get('Pagination'); + $this->state = $this->get('State'); + $this->filterForm = $this->get('FilterForm'); + $this->activeFilters = $this->get('ActiveFilters'); + + UsersHelper::addSubmenu('groups'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + $this->addToolbar(); + $this->sidebar = JHtmlSidebar::render(); + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + $canDo = JHelperContent::getActions('com_users'); + + JToolbarHelper::title(JText::_('COM_USERS_VIEW_GROUPS_TITLE'), 'users groups'); + + if ($canDo->get('core.create')) + { + JToolbarHelper::addNew('group.add'); + } + + if ($canDo->get('core.edit')) + { + JToolbarHelper::editList('group.edit'); + JToolbarHelper::divider(); + } + + if ($canDo->get('core.delete')) + { + JToolbarHelper::deleteList('JGLOBAL_CONFIRM_DELETE', 'groups.delete', 'JTOOLBAR_DELETE'); + JToolbarHelper::divider(); + } + + if ($canDo->get('core.admin') || $canDo->get('core.options')) + { + JToolbarHelper::preferences('com_users'); + JToolbarHelper::divider(); + } + + JToolbarHelper::help('JHELP_USERS_GROUPS'); + } + + /** + * Returns an array of fields the table can be sorted by + * + * @return array Array containing the field name to sort by as the key and display text as value + * + * @since 3.0 + */ + protected function getSortFields() + { + return array( + 'a.title' => JText::_('COM_USERS_HEADING_GROUP_TITLE'), + 'a.id' => JText::_('JGRID_HEADING_ID'), + ); + } +} diff --git a/Sites/pages/administrator/components/com_users/views/level/tmpl/edit.php b/Sites/pages/administrator/components/com_users/views/level/tmpl/edit.php new file mode 100644 index 00000000..defc1152 --- /dev/null +++ b/Sites/pages/administrator/components/com_users/views/level/tmpl/edit.php @@ -0,0 +1,47 @@ +addScriptDeclaration(" + Joomla.submitbutton = function(task) + { + if (task == 'level.cancel' || document.formvalidator.isValid(document.getElementById('level-form'))) + { + Joomla.submitform(task, document.getElementById('level-form')); + } + }; +"); +?> + +
    +
    + +
    +
    + form->getLabel('title'); ?> +
    +
    + form->getInput('title'); ?> +
    +
    +
    + +
    + + item->rules, true); ?> +
    + + +
    diff --git a/Sites/pages/administrator/components/com_users/views/level/tmpl/edit.xml b/Sites/pages/administrator/components/com_users/views/level/tmpl/edit.xml new file mode 100755 index 00000000..fc078486 --- /dev/null +++ b/Sites/pages/administrator/components/com_users/views/level/tmpl/edit.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/Sites/pages/administrator/components/com_users/views/level/view.html.php b/Sites/pages/administrator/components/com_users/views/level/view.html.php new file mode 100644 index 00000000..b21a1662 --- /dev/null +++ b/Sites/pages/administrator/components/com_users/views/level/view.html.php @@ -0,0 +1,105 @@ +form = $this->get('Form'); + $this->item = $this->get('Item'); + $this->state = $this->get('State'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + $this->addToolbar(); + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + JFactory::getApplication()->input->set('hidemainmenu', true); + + $isNew = ($this->item->id == 0); + $canDo = JHelperContent::getActions('com_users'); + + JToolbarHelper::title(JText::_($isNew ? 'COM_USERS_VIEW_NEW_LEVEL_TITLE' : 'COM_USERS_VIEW_EDIT_LEVEL_TITLE'), 'users levels-add'); + + if ($canDo->get('core.edit') || $canDo->get('core.create')) + { + JToolbarHelper::apply('level.apply'); + JToolbarHelper::save('level.save'); + } + + if ($canDo->get('core.create')) + { + JToolbarHelper::save2new('level.save2new'); + } + + // If an existing item, can save to a copy. + if (!$isNew && $canDo->get('core.create')) + { + JToolbarHelper::save2copy('level.save2copy'); + } + + if (empty($this->item->id)) + { + JToolbarHelper::cancel('level.cancel'); + } + else + { + JToolbarHelper::cancel('level.cancel', 'JTOOLBAR_CLOSE'); + } + + JToolbarHelper::divider(); + JToolbarHelper::help('JHELP_USERS_ACCESS_LEVELS_EDIT'); + } +} diff --git a/Sites/pages/administrator/components/com_users/views/levels/tmpl/default.php b/Sites/pages/administrator/components/com_users/views/levels/tmpl/default.php new file mode 100644 index 00000000..8886a374 --- /dev/null +++ b/Sites/pages/administrator/components/com_users/views/levels/tmpl/default.php @@ -0,0 +1,140 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$saveOrder = $listOrder == 'a.ordering'; + +if ($saveOrder) +{ + $saveOrderingUrl = 'index.php?option=com_users&task=levels.saveOrderAjax&tmpl=component'; + JHtml::_('sortablelist.sortable', 'levelList', 'adminForm', strtolower($listDirn), $saveOrderingUrl); +} + +?> +
    +sidebar)) : ?> +
    + sidebar; ?> +
    +
    + +
    + + $this, 'options' => array('filterButton' => false))); ?> +
    + items)) : ?> +
    + +
    + + + + + + + + + + + + + + + + + + items); ?> + items as $i => $item) : + $ordering = ($listOrder == 'a.ordering'); + $canCreate = $user->authorise('core.create', 'com_users'); + $canEdit = $user->authorise('core.edit', 'com_users'); + $canChange = $user->authorise('core.edit.state', 'com_users'); + + // Decode level groups + $groups = json_decode($item->rules); + + // If this group is super admin and this user is not super admin, $canEdit is false + if (!JFactory::getUser()->authorise('core.admin') && JAccess::checkGroup($groups[0], 'core.admin')) + { + $canEdit = false; + $canChange = false; + } + ?> + + + + + + + + + +
    + + + + + + + + + +
    + pagination->getListFooter(); ?> +
    + + + + + + + + + + id); ?> + + + + + escape($item->title); ?> + + escape($item->title); ?> + + + rules); ?> + + id; ?> +
    + + + + +
    + diff --git a/Sites/pages/administrator/components/com_users/views/levels/tmpl/default.xml b/Sites/pages/administrator/components/com_users/views/levels/tmpl/default.xml new file mode 100755 index 00000000..77c94281 --- /dev/null +++ b/Sites/pages/administrator/components/com_users/views/levels/tmpl/default.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/Sites/pages/administrator/components/com_users/views/levels/view.html.php b/Sites/pages/administrator/components/com_users/views/levels/view.html.php new file mode 100644 index 00000000..3db72b2d --- /dev/null +++ b/Sites/pages/administrator/components/com_users/views/levels/view.html.php @@ -0,0 +1,125 @@ +items = $this->get('Items'); + $this->pagination = $this->get('Pagination'); + $this->state = $this->get('State'); + $this->filterForm = $this->get('FilterForm'); + $this->activeFilters = $this->get('ActiveFilters'); + + UsersHelper::addSubmenu('levels'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + $this->addToolbar(); + $this->sidebar = JHtmlSidebar::render(); + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + $canDo = JHelperContent::getActions('com_users'); + + JToolbarHelper::title(JText::_('COM_USERS_VIEW_LEVELS_TITLE'), 'users levels'); + + if ($canDo->get('core.create')) + { + JToolbarHelper::addNew('level.add'); + } + + if ($canDo->get('core.edit')) + { + JToolbarHelper::editList('level.edit'); + JToolbarHelper::divider(); + } + + if ($canDo->get('core.delete')) + { + JToolbarHelper::deleteList('JGLOBAL_CONFIRM_DELETE', 'level.delete', 'JTOOLBAR_DELETE'); + JToolbarHelper::divider(); + } + + if ($canDo->get('core.admin') || $canDo->get('core.options')) + { + JToolbarHelper::preferences('com_users'); + JToolbarHelper::divider(); + } + + JToolbarHelper::help('JHELP_USERS_ACCESS_LEVELS'); + } + + /** + * Returns an array of fields the table can be sorted by + * + * @return array Array containing the field name to sort by as the key and display text as value + * + * @since 3.0 + */ + protected function getSortFields() + { + return array( + 'a.ordering' => JText::_('JGRID_HEADING_ORDERING'), + 'a.title' => JText::_('COM_USERS_HEADING_LEVEL_NAME'), + 'a.id' => JText::_('JGRID_HEADING_ID'), + ); + } +} diff --git a/Sites/pages/administrator/components/com_users/views/mail/tmpl/default.php b/Sites/pages/administrator/components/com_users/views/mail/tmpl/default.php new file mode 100644 index 00000000..d0c318bd --- /dev/null +++ b/Sites/pages/administrator/components/com_users/views/mail/tmpl/default.php @@ -0,0 +1,75 @@ +addScriptDeclaration($script); +?> + +
    +
    +
    +
    +
    +
    form->getLabel('subject'); ?>
    +
    get('mailSubjectPrefix'); ?> + form->getInput('subject'); ?>
    +
    +
    +
    form->getLabel('message'); ?>
    +
    form->getInput('message'); ?>
    + get('mailBodySuffix'); ?>
    +
    +
    + + +
    +
    +
    +
    +
    form->getInput('recurse'); ?> form->getLabel('recurse'); ?>
    +
    +
    +
    form->getInput('mode'); ?> form->getLabel('mode'); ?>
    +
    +
    +
    form->getInput('disabled'); ?> form->getLabel('disabled'); ?>
    +
    +
    +
    form->getInput('bcc'); ?> form->getLabel('bcc'); ?>
    +
    +
    +
    form->getLabel('group'); ?>
    +
    form->getInput('group'); ?>
    +
    +
    +
    +
    +
    diff --git a/Sites/pages/administrator/components/com_users/views/mail/tmpl/default.xml b/Sites/pages/administrator/components/com_users/views/mail/tmpl/default.xml new file mode 100755 index 00000000..075e0da0 --- /dev/null +++ b/Sites/pages/administrator/components/com_users/views/mail/tmpl/default.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/Sites/pages/administrator/components/com_users/views/mail/view.html.php b/Sites/pages/administrator/components/com_users/views/mail/view.html.php new file mode 100644 index 00000000..3c7d99ee --- /dev/null +++ b/Sites/pages/administrator/components/com_users/views/mail/view.html.php @@ -0,0 +1,65 @@ +get('massmailoff', 0) == 1) + { + JFactory::getApplication()->redirect(JRoute::_('index.php', false)); + } + + // Get data from the model + $this->form = $this->get('Form'); + + $this->addToolbar(); + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + JFactory::getApplication()->input->set('hidemainmenu', true); + + JToolbarHelper::title(JText::_('COM_USERS_MASS_MAIL'), 'users massmail'); + JToolbarHelper::custom('mail.send', 'envelope.png', 'send_f2.png', 'COM_USERS_TOOLBAR_MAIL_SEND_MAIL', false); + JToolbarHelper::cancel('mail.cancel'); + JToolbarHelper::divider(); + JToolbarHelper::preferences('com_users'); + JToolbarHelper::divider(); + JToolbarHelper::help('JHELP_USERS_MASS_MAIL_USERS'); + } +} diff --git a/Sites/pages/administrator/components/com_users/views/note/tmpl/edit.php b/Sites/pages/administrator/components/com_users/views/note/tmpl/edit.php new file mode 100644 index 00000000..eb7e8ae0 --- /dev/null +++ b/Sites/pages/administrator/components/com_users/views/note/tmpl/edit.php @@ -0,0 +1,90 @@ +addScriptDeclaration(' +jQuery(document).ready(function() { + Joomla.submitbutton = function(task) + { + if (task == "note.cancel" || document.formvalidator.isValid(document.getElementById("note-form"))) + { + ' . $this->form->getField('body')->save() . ' + Joomla.submitform(task, document.getElementById("note-form")); + } + } +});'); +?> +
    +
    +
    +
    + form->getLabel('subject'); ?> +
    +
    + form->getInput('subject'); ?> +
    +
    +
    +
    + form->getLabel('user_id'); ?> +
    +
    + form->getInput('user_id'); ?> +
    +
    +
    +
    + form->getLabel('catid'); ?> +
    +
    + form->getInput('catid'); ?> +
    +
    +
    +
    + form->getLabel('state'); ?> +
    +
    + form->getInput('state'); ?> +
    +
    +
    +
    + form->getLabel('review_time'); ?> +
    +
    + form->getInput('review_time'); ?> +
    +
    +
    +
    + form->getLabel('version_note'); ?> +
    +
    + form->getInput('version_note'); ?> +
    +
    + +
    +
    + form->getLabel('body'); ?> +
    +
    + form->getInput('body'); ?> +
    +
    + + + +
    +
    diff --git a/Sites/pages/administrator/components/com_users/views/note/tmpl/edit.xml b/Sites/pages/administrator/components/com_users/views/note/tmpl/edit.xml new file mode 100755 index 00000000..7a6a20b6 --- /dev/null +++ b/Sites/pages/administrator/components/com_users/views/note/tmpl/edit.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/Sites/pages/administrator/components/com_users/views/note/view.html.php b/Sites/pages/administrator/components/com_users/views/note/view.html.php new file mode 100644 index 00000000..bdec73fd --- /dev/null +++ b/Sites/pages/administrator/components/com_users/views/note/view.html.php @@ -0,0 +1,128 @@ +state = $this->get('State'); + $this->item = $this->get('Item'); + $this->form = $this->get('Form'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + // Get the component HTML helpers + JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html'); + + parent::display($tpl); + $this->addToolbar(); + } + + /** + * Display the toolbar. + * + * @return void + * + * @since 2.5 + */ + protected function addToolbar() + { + $input = JFactory::getApplication()->input; + $input->set('hidemainmenu', 1); + + $user = JFactory::getUser(); + $isNew = ($this->item->id == 0); + $checkedOut = !($this->item->checked_out == 0 || $this->item->checked_out == $user->get('id')); + + // Since we don't track these assets at the item level, use the category id. + $canDo = JHelperContent::getActions('com_users', 'category', $this->item->catid); + + JToolbarHelper::title(JText::_('COM_USERS_NOTES'), 'users user'); + + // If not checked out, can save the item. + if (!$checkedOut && ($canDo->get('core.edit') || count($user->getAuthorisedCategories('com_users', 'core.create')))) + { + JToolbarHelper::apply('note.apply'); + JToolbarHelper::save('note.save'); + } + + if (!$checkedOut && count($user->getAuthorisedCategories('com_users', 'core.create'))) + { + JToolbarHelper::save2new('note.save2new'); + } + + // If an existing item, can save to a copy. + if (!$isNew && (count($user->getAuthorisedCategories('com_users', 'core.create')) > 0)) + { + JToolbarHelper::save2copy('note.save2copy'); + } + + if (empty($this->item->id)) + { + JToolbarHelper::cancel('note.cancel'); + } + else + { + if (JComponentHelper::isEnabled('com_contenthistory') && $this->state->params->get('save_history', 0) && $canDo->get('core.edit')) + { + JToolbarHelper::versions('com_users.note', $this->item->id); + } + + JToolbarHelper::cancel('note.cancel', 'JTOOLBAR_CLOSE'); + } + + JToolbarHelper::divider(); + JToolbarHelper::help('JHELP_USERS_USER_NOTES_EDIT'); + } +} diff --git a/Sites/pages/administrator/components/com_users/views/notes/tmpl/default.php b/Sites/pages/administrator/components/com_users/views/notes/tmpl/default.php new file mode 100644 index 00000000..fbbe0e06 --- /dev/null +++ b/Sites/pages/administrator/components/com_users/views/notes/tmpl/default.php @@ -0,0 +1,129 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +?> +
    +sidebar)) : ?> +
    + sidebar; ?> +
    +
    + +
    + + $this)); ?> + + items)) : ?> +
    + +
    + + + + + + + + + + + + + + + + + + + items as $i => $item) : + $canEdit = $user->authorise('core.edit', 'com_users.category.' . $item->catid); + $canCheckin = $user->authorise('core.admin', 'com_checkin') || $item->checked_out == $user->get('id') || $item->checked_out == 0; + $canChange = $user->authorise('core.edit.state', 'com_users.category.' . $item->catid) && $canCheckin; + $subject = $item->subject ?: JText::_('COM_USERS_EMPTY_SUBJECT'); + ?> + + + + + + + + + + +
    + + + + + + + + + + + +
    + pagination->getListFooter(); ?> +
    + id); ?> + +
    + state, $i, 'notes.', $canChange, 'cb', $item->publish_up, $item->publish_down); ?> + state === 2 ? 'un' : '') . 'archive', 'cb' . $i, 'notes'); + JHtml::_('actionsdropdown.' . ((int) $item->state === -2 ? 'un' : '') . 'trash', 'cb' . $i, 'notes'); + echo JHtml::_('actionsdropdown.render', $this->escape($subject)); + } + ?> +
    +
    + checked_out) : ?> + editor, $item->checked_out_time, 'notes.', $canCheckin); ?> + + subject ?: JText::_('COM_USERS_EMPTY_SUBJECT'); ?> + + escape($subject); ?> + + escape($subject); ?> + +
    + escape($item->category_title); ?> +
    +
    + escape($item->user_name); ?> + + review_time !== JFactory::getDbo()->getNullDate()) : ?> + review_time, JText::_('DATE_FORMAT_LC4')); ?> + + + + + id; ?> +
    + + +
    + + + +
    +
    + diff --git a/Sites/pages/administrator/components/com_users/views/notes/tmpl/default.xml b/Sites/pages/administrator/components/com_users/views/notes/tmpl/default.xml new file mode 100755 index 00000000..a1a88fbd --- /dev/null +++ b/Sites/pages/administrator/components/com_users/views/notes/tmpl/default.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/Sites/pages/administrator/components/com_users/views/notes/tmpl/modal.php b/Sites/pages/administrator/components/com_users/views/notes/tmpl/modal.php new file mode 100644 index 00000000..78fc977f --- /dev/null +++ b/Sites/pages/administrator/components/com_users/views/notes/tmpl/modal.php @@ -0,0 +1,54 @@ + +
    +

    user->name, $this->user->id); ?>

    +items)) : ?> + + +
      + items as $item) : ?> +
    • +
      + subject) : ?> +

      id, $this->escape($item->subject)); ?>

      + +

      id, JText::_('COM_USERS_EMPTY_SUBJECT')); ?>

      + +
      + +
      + created_time, JText::_('DATE_FORMAT_LC2')); ?> +
      + + cparams->get('image'); ?> + + catid && isset($category_image)) : ?> +
      + +
      + +
      + escape($item->category_title); ?> +
      + + +
      +
      + body) ? JHtml::_('content.prepare', $item->body) : ''); ?> +
      +
    • + +
    + +
    diff --git a/Sites/pages/administrator/components/com_users/views/notes/view.html.php b/Sites/pages/administrator/components/com_users/views/notes/view.html.php new file mode 100644 index 00000000..b9666004 --- /dev/null +++ b/Sites/pages/administrator/components/com_users/views/notes/view.html.php @@ -0,0 +1,168 @@ +items = $this->get('Items'); + $this->pagination = $this->get('Pagination'); + $this->state = $this->get('State'); + $this->user = $this->get('User'); + $this->filterForm = $this->get('FilterForm'); + $this->activeFilters = $this->get('ActiveFilters'); + + UsersHelper::addSubmenu('notes'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + // Get the component HTML helpers + JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html'); + + // Turn parameters into registry objects + foreach ($this->items as $item) + { + $item->cparams = new Registry($item->category_params); + } + + $this->addToolbar(); + $this->sidebar = JHtmlSidebar::render(); + parent::display($tpl); + } + + /** + * Display the toolbar. + * + * @return void + * + * @since 2.5 + */ + protected function addToolbar() + { + $canDo = JHelperContent::getActions('com_users', 'category', $this->state->get('filter.category_id')); + + JToolbarHelper::title(JText::_('COM_USERS_VIEW_NOTES_TITLE'), 'users user'); + + if ($canDo->get('core.create')) + { + JToolbarHelper::addNew('note.add'); + } + + if ($canDo->get('core.edit')) + { + JToolbarHelper::editList('note.edit'); + } + + if ($canDo->get('core.edit.state')) + { + JToolbarHelper::divider(); + JToolbarHelper::publish('notes.publish', 'JTOOLBAR_PUBLISH', true); + JToolbarHelper::unpublish('notes.unpublish', 'JTOOLBAR_UNPUBLISH', true); + + JToolbarHelper::divider(); + JToolbarHelper::archiveList('notes.archive'); + JToolbarHelper::checkin('notes.checkin'); + } + + if ($this->state->get('filter.published') == -2 && $canDo->get('core.delete')) + { + JToolbarHelper::deleteList('JGLOBAL_CONFIRM_DELETE', 'notes.delete', 'JTOOLBAR_EMPTY_TRASH'); + JToolbarHelper::divider(); + } + elseif ($canDo->get('core.edit.state')) + { + JToolbarHelper::trash('notes.trash'); + JToolbarHelper::divider(); + } + + if ($canDo->get('core.admin') || $canDo->get('core.options')) + { + JToolbarHelper::preferences('com_users'); + JToolbarHelper::divider(); + } + + JToolbarHelper::help('JHELP_USERS_USER_NOTES'); + + JHtmlSidebar::setAction('index.php?option=com_users&view=notes'); + } + + /** + * Returns an array of fields the table can be sorted by + * + * @return array Array containing the field name to sort by as the key and display text as value + * + * @since 3.0 + */ + protected function getSortFields() + { + return array( + 'u.name' => JText::_('COM_USERS_USER_HEADING'), + 'a.subject' => JText::_('COM_USERS_SUBJECT_HEADING'), + 'c.title' => JText::_('COM_USERS_CATEGORY_HEADING'), + 'a.state' => JText::_('JSTATUS'), + 'a.review_time' => JText::_('COM_USERS_REVIEW_HEADING'), + 'a.id' => JText::_('JGRID_HEADING_ID') + ); + } +} diff --git a/Sites/pages/administrator/components/com_users/views/user/tmpl/edit.php b/Sites/pages/administrator/components/com_users/views/user/tmpl/edit.php new file mode 100644 index 00000000..fa9b4973 --- /dev/null +++ b/Sites/pages/administrator/components/com_users/views/user/tmpl/edit.php @@ -0,0 +1,133 @@ +addScriptDeclaration(" + Joomla.submitbutton = function(task) + { + if (task == 'user.cancel' || document.formvalidator.isValid(document.getElementById('user-form'))) + { + Joomla.submitform(task, document.getElementById('user-form')); + } + }; + + Joomla.twoFactorMethodChange = function(e) + { + var selectedPane = 'com_users_twofactor_' + jQuery('#jform_twofactor_method').val(); + + jQuery.each(jQuery('#com_users_twofactor_forms_container>div'), function(i, el) { + if (el.id != selectedPane) + { + jQuery('#' + el.id).hide(0); + } + else + { + jQuery('#' + el.id).show(0); + } + }); + }; +"); + +// Get the form fieldsets. +$fieldsets = $this->form->getFieldsets(); +?> + +
    + + + +
    + 'details')); ?> + + + form->getFieldset('user_details') as $field) : ?> +
    +
    + label; ?> +
    +
    + fieldname == 'password') : ?> + + + input; ?> +
    +
    + + + + grouplist) : ?> + + loadTemplate('groups'); ?> + + + + ignore_fieldsets = array('user_details'); + echo JLayoutHelper::render('joomla.edit.params', $this); + ?> + + tfaform) && $this->item->id) : ?> + +
    +
    + +
    +
    + 'Joomla.twoFactorMethodChange()'), 'value', 'text', $this->otpConfig->method, 'jform_twofactor_method', false); ?> +
    +
    +
    + tfaform as $form) : ?> + otpConfig->method ? 'display: block' : 'display: none'; ?> +
    + +
    + +
    + +
    + + + +
    + +
    + otpConfig->otep)) : ?> +
    + +
    + + otpConfig->otep as $otep) : ?> + + --- + + +
    + +
    + + + + + +
    + + + +
    diff --git a/Sites/pages/administrator/components/com_users/views/user/tmpl/edit.xml b/Sites/pages/administrator/components/com_users/views/user/tmpl/edit.xml new file mode 100755 index 00000000..045a8e9a --- /dev/null +++ b/Sites/pages/administrator/components/com_users/views/user/tmpl/edit.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/Sites/pages/administrator/components/com_users/views/user/tmpl/edit_groups.php b/Sites/pages/administrator/components/com_users/views/user/tmpl/edit_groups.php new file mode 100644 index 00000000..3356b8f6 --- /dev/null +++ b/Sites/pages/administrator/components/com_users/views/user/tmpl/edit_groups.php @@ -0,0 +1,15 @@ + +groups, true); ?> diff --git a/Sites/pages/administrator/components/com_users/views/user/view.html.php b/Sites/pages/administrator/components/com_users/views/user/view.html.php new file mode 100644 index 00000000..07fa556c --- /dev/null +++ b/Sites/pages/administrator/components/com_users/views/user/view.html.php @@ -0,0 +1,114 @@ +form = $this->get('Form'); + $this->item = $this->get('Item'); + $this->state = $this->get('State'); + $this->tfaform = $this->get('Twofactorform'); + $this->otpConfig = $this->get('otpConfig'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + // Prevent user from modifying own group(s) + $user = JFactory::getUser(); + + if ((int) $user->id != (int) $this->item->id || $user->authorise('core.admin')) + { + $this->grouplist = $this->get('Groups'); + $this->groups = $this->get('AssignedGroups'); + } + + $this->form->setValue('password', null); + $this->form->setValue('password2', null); + + parent::display($tpl); + $this->addToolbar(); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + JFactory::getApplication()->input->set('hidemainmenu', true); + + $user = JFactory::getUser(); + $canDo = JHelperContent::getActions('com_users'); + $isNew = ($this->item->id == 0); + $isProfile = $this->item->id == $user->id; + + JToolbarHelper::title( + JText::_( + $isNew ? 'COM_USERS_VIEW_NEW_USER_TITLE' : ($isProfile ? 'COM_USERS_VIEW_EDIT_PROFILE_TITLE' : 'COM_USERS_VIEW_EDIT_USER_TITLE') + ), + 'user ' . ($isNew ? 'user-add' : ($isProfile ? 'user-profile' : 'user-edit')) + ); + + if ($canDo->get('core.edit') || $canDo->get('core.create')) + { + JToolbarHelper::apply('user.apply'); + JToolbarHelper::save('user.save'); + } + + if ($canDo->get('core.create') && $canDo->get('core.manage')) + { + JToolbarHelper::save2new('user.save2new'); + } + + if (empty($this->item->id)) + { + JToolbarHelper::cancel('user.cancel'); + } + else + { + JToolbarHelper::cancel('user.cancel', 'JTOOLBAR_CLOSE'); + } + + JToolbarHelper::divider(); + JToolbarHelper::help('JHELP_USERS_USER_MANAGER_EDIT'); + } +} diff --git a/Sites/pages/administrator/components/com_users/views/users/tmpl/default.php b/Sites/pages/administrator/components/com_users/views/users/tmpl/default.php new file mode 100644 index 00000000..76f1d5dc --- /dev/null +++ b/Sites/pages/administrator/components/com_users/views/users/tmpl/default.php @@ -0,0 +1,188 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$loggeduser = JFactory::getUser(); +$debugUsers = $this->state->get('params')->get('debugUsers', 1); +?> +
    + sidebar)) : ?> +
    + sidebar; ?> +
    +
    + +
    + + $this)); + ?> + items)) : ?> +
    + +
    + + + + + + + + + + + + + + + + + + + + + + + items as $i => $item) : + $canEdit = $this->canDo->get('core.edit'); + $canChange = $loggeduser->authorise('core.edit.state', 'com_users'); + + // If this group is super admin and this user is not super admin, $canEdit is false + if ((!$loggeduser->authorise('core.admin')) && JAccess::check($item->id, 'core.admin')) + { + $canEdit = false; + $canChange = false; + } + ?> + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    + pagination->getListFooter(); ?> +
    + + id); ?> + + +
    + + + escape($item->name); ?> + + escape($item->name); ?> + +
    +
    + note_count, $item->id); ?> + note_count, $item->id); ?> + id); ?> +
    + note_count, $item->id); ?> + requireReset == '1') : ?> + + + + + +
    + escape($item->username); ?> + + id == $item->id; + + if ($canChange) : + echo JHtml::_('jgrid.state', JHtml::_('users.blockStates', $self), $item->block, $i, 'users.', !$self); + else : + echo JHtml::_('jgrid.state', JHtml::_('users.blockStates', $self), $item->block, $i, 'users.', false); + endif; ?> + + activation) ? 0 : 1; + echo JHtml::_('jgrid.state', JHtml::_('users.activateStates'), $activated, $i, 'users.', (boolean) $activated); + ?> + + group_names, "\n") > 1) : ?> + + + group_names); ?> + + + escape($item->email)); ?> + + lastvisitDate != $this->db->getNullDate()) : ?> + lastvisitDate, JText::_('DATE_FORMAT_LC6')); ?> + + + + + registerDate, JText::_('DATE_FORMAT_LC6')); ?> + + id; ?> +
    + + authorise('core.create', 'com_users') + && $loggeduser->authorise('core.edit', 'com_users') + && $loggeduser->authorise('core.edit.state', 'com_users')) : ?> + JText::_('COM_USERS_BATCH_OPTIONS'), + 'footer' => $this->loadTemplate('batch_footer'), + ), + $this->loadTemplate('batch_body') + ); ?> + + + + + + +
    + diff --git a/Sites/pages/administrator/components/com_users/views/users/tmpl/default.xml b/Sites/pages/administrator/components/com_users/views/users/tmpl/default.xml new file mode 100755 index 00000000..28b9faff --- /dev/null +++ b/Sites/pages/administrator/components/com_users/views/users/tmpl/default.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/Sites/pages/administrator/components/com_users/views/users/tmpl/default_batch_body.php b/Sites/pages/administrator/components/com_users/views/users/tmpl/default_batch_body.php new file mode 100644 index 00000000..f6b746a8 --- /dev/null +++ b/Sites/pages/administrator/components/com_users/views/users/tmpl/default_batch_body.php @@ -0,0 +1,50 @@ + + +
    +
    +
    + +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    + +
    +
    diff --git a/Sites/pages/administrator/components/com_users/views/users/tmpl/default_batch_footer.php b/Sites/pages/administrator/components/com_users/views/users/tmpl/default_batch_footer.php new file mode 100644 index 00000000..516f35d4 --- /dev/null +++ b/Sites/pages/administrator/components/com_users/views/users/tmpl/default_batch_footer.php @@ -0,0 +1,17 @@ + + + diff --git a/Sites/pages/administrator/components/com_users/views/users/tmpl/modal.php b/Sites/pages/administrator/components/com_users/views/users/tmpl/modal.php new file mode 100644 index 00000000..fe65eb74 --- /dev/null +++ b/Sites/pages/administrator/components/com_users/views/users/tmpl/modal.php @@ -0,0 +1,128 @@ + 'bottom')); +JHtml::_('bootstrap.popover', '.hasPopover', array('placement' => 'bottom')); +JHtml::_('formbehavior.chosen', 'select'); +JHtml::_('behavior.multiselect'); + +// Special case for the search field tooltip. +$searchFilterDesc = $this->filterForm->getFieldAttribute('search', 'description', null, 'filter'); +JHtml::_('bootstrap.tooltip', '#filter_search', array('title' => JText::_($searchFilterDesc), 'placement' => 'bottom')); + +$input = JFactory::getApplication()->input; +$field = $input->getCmd('field'); +$listOrder = $this->escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$enabledStates = array(0 => 'icon-publish', 1 => 'icon-unpublish'); +$activatedStates = array(0 => 'icon-publish', 1 => 'icon-unpublish'); +$userRequired = (int) $input->get('required', 0, 'int'); + +/** + * Mootools compatibility + * + * There is an extra option passed in the URL for the iframe &ismoo=0 for the bootstraped field. + * By default the value will be 1 or defaults to mootools behaviour using function jSelectUser() + * + * This should be removed when mootools won't be shipped by Joomla. + */ +$isMoo = $input->getInt('ismoo', 1); + +if ($isMoo) +{ + $onClick = "window.parent.jSelectUser(this);window.parent.jQuery('.modal.in').modal('hide');"; +} + +?> +
    +
    + +
    +   +
    + + $this)); ?> + items)) : ?> +
    + +
    + + + + + + + + + + + + + + + + + + + + items as $item) : ?> + + + + + + + + + + +
    + + + + + + + + + + + +
    + pagination->getListFooter(); ?> +
    + onclick=""> + escape($item->name); ?> + + + escape($item->username); ?> + + + + + + group_names); ?> + + id; ?> +
    + + + + + + + +
    +
    diff --git a/Sites/pages/administrator/components/com_users/views/users/view.html.php b/Sites/pages/administrator/components/com_users/views/users/view.html.php new file mode 100644 index 00000000..f6aa5377 --- /dev/null +++ b/Sites/pages/administrator/components/com_users/views/users/view.html.php @@ -0,0 +1,194 @@ +items = $this->get('Items'); + $this->pagination = $this->get('Pagination'); + $this->state = $this->get('State'); + $this->filterForm = $this->get('FilterForm'); + $this->activeFilters = $this->get('ActiveFilters'); + $this->canDo = JHelperContent::getActions('com_users'); + $this->db = JFactory::getDbo(); + + UsersHelper::addSubmenu('users'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + // Include the component HTML helpers. + JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html'); + + $this->addToolbar(); + $this->sidebar = JHtmlSidebar::render(); + + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + $canDo = $this->canDo; + $user = JFactory::getUser(); + + // Get the toolbar object instance + $bar = JToolbar::getInstance('toolbar'); + + JToolbarHelper::title(JText::_('COM_USERS_VIEW_USERS_TITLE'), 'users user'); + + if ($canDo->get('core.create')) + { + JToolbarHelper::addNew('user.add'); + } + + if ($canDo->get('core.edit')) + { + JToolbarHelper::editList('user.edit'); + } + + if ($canDo->get('core.edit.state')) + { + JToolbarHelper::divider(); + JToolbarHelper::publish('users.activate', 'COM_USERS_TOOLBAR_ACTIVATE', true); + JToolbarHelper::unpublish('users.block', 'COM_USERS_TOOLBAR_BLOCK', true); + JToolbarHelper::custom('users.unblock', 'unblock.png', 'unblock_f2.png', 'COM_USERS_TOOLBAR_UNBLOCK', true); + JToolbarHelper::divider(); + } + + if ($canDo->get('core.delete')) + { + JToolbarHelper::deleteList('JGLOBAL_CONFIRM_DELETE', 'users.delete', 'JTOOLBAR_DELETE'); + JToolbarHelper::divider(); + } + + // Add a batch button + if ($user->authorise('core.create', 'com_users') + && $user->authorise('core.edit', 'com_users') + && $user->authorise('core.edit.state', 'com_users')) + { + $title = JText::_('JTOOLBAR_BATCH'); + + // Instantiate a new JLayoutFile instance and render the batch button + $layout = new JLayoutFile('joomla.toolbar.batch'); + + $dhtml = $layout->render(array('title' => $title)); + $bar->appendButton('Custom', $dhtml, 'batch'); + } + + if ($canDo->get('core.admin') || $canDo->get('core.options')) + { + JToolbarHelper::preferences('com_users'); + JToolbarHelper::divider(); + } + + JToolbarHelper::help('JHELP_USERS_USER_MANAGER'); + } + + /** + * Returns an array of fields the table can be sorted by + * + * @return array Array containing the field name to sort by as the key and display text as value + * + * @since 3.0 + */ + protected function getSortFields() + { + return array( + 'a.name' => JText::_('COM_USERS_HEADING_NAME'), + 'a.username' => JText::_('JGLOBAL_USERNAME'), + 'a.block' => JText::_('COM_USERS_HEADING_ENABLED'), + 'a.activation' => JText::_('COM_USERS_HEADING_ACTIVATED'), + 'a.email' => JText::_('JGLOBAL_EMAIL'), + 'a.lastvisitDate' => JText::_('COM_USERS_HEADING_LAST_VISIT_DATE'), + 'a.registerDate' => JText::_('COM_USERS_HEADING_REGISTRATION_DATE'), + 'a.id' => JText::_('JGRID_HEADING_ID'), + ); + } +} diff --git a/Sites/pages/administrator/help/en-GB/toc.json b/Sites/pages/administrator/help/en-GB/toc.json new file mode 100644 index 00000000..e48d7359 --- /dev/null +++ b/Sites/pages/administrator/help/en-GB/toc.json @@ -0,0 +1 @@ +{"COMPONENTS_ASSOCIATIONS":"COMPONENTS_ASSOCIATIONS","COMPONENTS_ASSOCIATIONS_EDIT":"COMPONENTS_ASSOCIATIONS_EDIT","COMPONENTS_BANNERS_BANNERS":"COMPONENTS_BANNERS_BANNERS","COMPONENTS_BANNERS_BANNERS_EDIT":"COMPONENTS_BANNERS_BANNERS_EDIT","COMPONENTS_BANNERS_CATEGORIES":"COMPONENTS_BANNERS_CATEGORIES","COMPONENTS_BANNERS_CATEGORY_EDIT":"COMPONENTS_BANNERS_CATEGORIES_EDIT","COMPONENTS_BANNERS_CLIENTS":"COMPONENTS_BANNERS_CLIENTS","COMPONENTS_BANNERS_CLIENTS_EDIT":"COMPONENTS_BANNERS_CLIENTS_EDIT","COMPONENTS_BANNERS_TRACKS":"COMPONENTS_BANNERS_TRACKS","COMPONENTS_CONTACTS_CONTACTS":"COMPONENTS_CONTACTS_CONTACTS","COMPONENTS_CONTACTS_CONTACTS_EDIT":"COMPONENTS_CONTACTS_CONTACTS_EDIT","COMPONENTS_CONTACT_CATEGORIES":"COMPONENTS_CONTACT_CATEGORIES","COMPONENTS_CONTACT_CATEGORY_EDIT":"COMPONENTS_CONTACT_CATEGORIES_EDIT","COMPONENTS_CONTENT_CATEGORIES":"COMPONENTS_CONTENT_CATEGORIES","COMPONENTS_CONTENT_CATEGORY_EDIT":"COMPONENTS_CONTENT_CATEGORIES_EDIT","COMPONENTS_FIELDS_FIELDS":"COMPONENTS_FIELDS_FIELDS","COMPONENTS_FIELDS_FIELDS_EDIT":"COMPONENTS_FIELDS_FIELDS_EDIT","COMPONENTS_FIELDS_FIELD_GROUPS":"COMPONENTS_FIELDS_FIELD_GROUPS","COMPONENTS_FIELDS_FIELD_GROUPS_EDIT":"COMPONENTS_FIELDS_FIELD_GROUPS_EDIT","COMPONENTS_FINDER_MANAGE_CONTENT_MAPS":"COMPONENTS_FINDER_MANAGE_CONTENT_MAPS","COMPONENTS_FINDER_MANAGE_INDEXED_CONTENT":"COMPONENTS_FINDER_MANAGE_INDEXED_CONTENT","COMPONENTS_FINDER_MANAGE_SEARCH_FILTERS":"COMPONENTS_FINDER_MANAGE_SEARCH_FILTERS","COMPONENTS_FINDER_MANAGE_SEARCH_FILTERS_EDIT":"COMPONENTS_FINDER_MANAGE_SEARCH_FILTERS_EDIT","COMPONENTS_JOOMLA_UPDATE":"COMPONENTS_JOOMLA_UPDATE","COMPONENTS_MESSAGING_INBOX":"COMPONENTS_MESSAGING_INBOX","COMPONENTS_MESSAGING_READ":"COMPONENTS_MESSAGING_READ","COMPONENTS_MESSAGING_WRITE":"COMPONENTS_MESSAGING_WRITE","COMPONENTS_NEWSFEEDS_CATEGORIES":"COMPONENTS_NEWSFEEDS_CATEGORIES","COMPONENTS_NEWSFEEDS_CATEGORY_EDIT":"COMPONENTS_NEWSFEEDS_CATEGORIES_EDIT","COMPONENTS_NEWSFEEDS_FEEDS":"COMPONENTS_NEWSFEEDS_FEEDS","COMPONENTS_NEWSFEEDS_FEEDS_EDIT":"COMPONENTS_NEWSFEEDS_FEEDS_EDIT","COMPONENTS_REDIRECT_MANAGER":"COMPONENTS_REDIRECT_MANAGER","COMPONENTS_REDIRECT_MANAGER_EDIT":"COMPONENTS_REDIRECT_MANAGER_EDIT","COMPONENTS_SEARCH":"COMPONENTS_SEARCH","COMPONENTS_TAGS_MANAGER":"COMPONENTS_TAGS_MANAGER","COMPONENTS_TAGS_MANAGER_EDIT":"COMPONENTS_TAGS_MANAGER_EDIT","COMPONENTS_WEBLINKS_CATEGORIES":"COMPONENTS_WEBLINKS_CATEGORIES","COMPONENTS_WEBLINKS_CATEGORY_EDIT":"COMPONENTS_WEBLINKS_CATEGORIES_EDIT","COMPONENTS_WEBLINKS_LINKS":"COMPONENTS_WEBLINKS_LINKS","COMPONENTS_WEBLINKS_LINKS_EDIT":"COMPONENTS_WEBLINKS_LINKS_EDIT","CONTENT_ARTICLE_MANAGER":"CONTENT_ARTICLE_MANAGER","CONTENT_ARTICLE_MANAGER_EDIT":"CONTENT_ARTICLE_MANAGER_EDIT","CONTENT_FEATURED_ARTICLES":"CONTENT_FEATURED_ARTICLES","CONTENT_MEDIA_MANAGER":"CONTENT_MEDIA_MANAGER","EXTENSIONS_EXTENSION_MANAGER_DATABASE":"EXTENSIONS_EXTENSION_MANAGER_DATABASE","EXTENSIONS_EXTENSION_MANAGER_DISCOVER":"EXTENSIONS_EXTENSION_MANAGER_DISCOVER","EXTENSIONS_EXTENSION_MANAGER_INSTALL":"EXTENSIONS_EXTENSION_MANAGER_INSTALL","EXTENSIONS_EXTENSION_MANAGER_LANGUAGES":"EXTENSIONS_EXTENSION_MANAGER_LANGUAGES","EXTENSIONS_EXTENSION_MANAGER_MANAGE":"EXTENSIONS_EXTENSION_MANAGER_MANAGE","EXTENSIONS_EXTENSION_MANAGER_UPDATE":"EXTENSIONS_EXTENSION_MANAGER_UPDATE","EXTENSIONS_EXTENSION_MANAGER_WARNINGS":"EXTENSIONS_EXTENSION_MANAGER_WARNINGS","EXTENSIONS_LANGUAGE_MANAGER_CONTENT":"EXTENSIONS_LANGUAGE_MANAGER_CONTENT","EXTENSIONS_LANGUAGE_MANAGER_EDIT":"EXTENSIONS_LANGUAGE_MANAGER_EDIT","EXTENSIONS_LANGUAGE_MANAGER_INSTALLED":"EXTENSIONS_LANGUAGE_MANAGER_INSTALLED","EXTENSIONS_LANGUAGE_MANAGER_OVERRIDES":"EXTENSIONS_LANGUAGE_MANAGER_OVERRIDES","EXTENSIONS_LANGUAGE_MANAGER_OVERRIDES_EDIT":"EXTENSIONS_LANGUAGE_MANAGER_OVERRIDES_EDIT","EXTENSIONS_MODULE_MANAGER":"EXTENSIONS_MODULE_MANAGER","EXTENSIONS_MODULE_MANAGER_EDIT":"EXTENSIONS_MODULE_MANAGER_EDIT","EXTENSIONS_PLUGIN_MANAGER":"EXTENSIONS_PLUGIN_MANAGER","EXTENSIONS_PLUGIN_MANAGER_EDIT":"EXTENSIONS_PLUGIN_MANAGER_EDIT","EXTENSIONS_TEMPLATE_MANAGER_STYLES":"EXTENSIONS_TEMPLATE_MANAGER_STYLES","EXTENSIONS_TEMPLATE_MANAGER_STYLES_EDIT":"EXTENSIONS_TEMPLATE_MANAGER_STYLES_EDIT","EXTENSIONS_TEMPLATE_MANAGER_TEMPLATES":"EXTENSIONS_TEMPLATE_MANAGER_TEMPLATES","EXTENSIONS_TEMPLATE_MANAGER_TEMPLATES_EDIT":"EXTENSIONS_TEMPLATE_MANAGER_TEMPLATES_EDIT","EXTENSIONS_TEMPLATE_MANAGER_TEMPLATES_EDIT_SOURCE":"EXTENSIONS_TEMPLATE_MANAGER_TEMPLATES_EDIT_SOURCE","MENUS_MENU_ITEM_MANAGER":"MENUS_MENU_ITEM_MANAGER","MENUS_MENU_ITEM_MANAGER_EDIT":"MENUS_MENU_ITEM_MANAGER_EDIT","MENUS_MENU_MANAGER":"MENUS_MENU_MANAGER","MENUS_MENU_MANAGER_EDIT":"MENUS_MENU_MANAGER_EDIT","SITE_GLOBAL_CONFIGURATION":"SITE_GLOBAL_CONFIGURATION","SITE_MAINTENANCE_CLEAR_CACHE":"SITE_MAINTENANCE_CLEAR_CACHE","SITE_MAINTENANCE_GLOBAL_CHECK-IN":"SITE_MAINTENANCE_GLOBAL_CHECK-IN","SITE_MAINTENANCE_PURGE_EXPIRED_CACHE":"SITE_MAINTENANCE_PURGE_EXPIRED_CACHE","SITE_SYSTEM_INFORMATION":"SITE_SYSTEM_INFORMATION","START_HERE":"START_HERE","USERS_ACCESS_LEVELS":"USERS_ACCESS_LEVELS","USERS_ACCESS_LEVELS_EDIT":"USERS_ACCESS_LEVELS_EDIT","USERS_DEBUG_USERS":"USERS_DEBUG_USER","USERS_GROUPS_EDIT":"USERS_GROUPS_EDIT","USERS_MASS_MAIL_USERS":"USERS_MASS_MAIL_USERS","USERS_USER_MANAGER_EDIT":"USERS_USER_MANAGER_EDIT","USERS_USER_NOTES":"USERS_USER_NOTES","USERS_USER_NOTES_EDIT":"USERS_USER_NOTES_EDIT"} \ No newline at end of file diff --git a/Sites/pages/administrator/help/helpsites.xml b/Sites/pages/administrator/help/helpsites.xml new file mode 100644 index 00000000..a907d603 --- /dev/null +++ b/Sites/pages/administrator/help/helpsites.xml @@ -0,0 +1,6 @@ + + + + English (GB) - Joomla help wiki + + diff --git a/Sites/pages/administrator/includes/defines.php b/Sites/pages/administrator/includes/defines.php new file mode 100644 index 00000000..aab3aa3e --- /dev/null +++ b/Sites/pages/administrator/includes/defines.php @@ -0,0 +1,25 @@ +isInDevelopmentState()))) +{ + if (file_exists(JPATH_INSTALLATION . '/index.php')) + { + header('Location: ../installation/index.php'); + + exit(); + } + else + { + echo 'No configuration file found and no installation code available. Exiting...'; + + exit; + } +} + +// Pre-Load configuration. Don't remove the Output Buffering due to BOM issues, see JCode 26026 +ob_start(); +require_once JPATH_CONFIGURATION . '/configuration.php'; +ob_end_clean(); + +// System configuration. +$config = new JConfig; + +// Set the error_reporting +switch ($config->error_reporting) +{ + case 'default': + case '-1': + break; + + case 'none': + case '0': + error_reporting(0); + + break; + + case 'simple': + error_reporting(E_ERROR | E_WARNING | E_PARSE); + ini_set('display_errors', 1); + + break; + + case 'maximum': + error_reporting(E_ALL); + ini_set('display_errors', 1); + + break; + + case 'development': + error_reporting(-1); + ini_set('display_errors', 1); + + break; + + default: + error_reporting($config->error_reporting); + ini_set('display_errors', 1); + + break; +} + +define('JDEBUG', $config->debug); + +unset($config); + +// System profiler +if (JDEBUG) +{ + // @deprecated 4.0 - The $_PROFILER global will be removed + $_PROFILER = JProfiler::getInstance('Application'); +} diff --git a/Sites/pages/administrator/includes/helper.php b/Sites/pages/administrator/includes/helper.php new file mode 100644 index 00000000..2b030534 --- /dev/null +++ b/Sites/pages/administrator/includes/helper.php @@ -0,0 +1,50 @@ +input->get('option')); + + $app->loadIdentity(); + $user = $app->getIdentity(); + + if ($user->get('guest') || !$user->authorise('core.login.admin')) + { + $option = 'com_login'; + } + + if (empty($option)) + { + $option = 'com_cpanel'; + } + + $app->input->set('option', $option); + + return $option; + } +} diff --git a/Sites/pages/administrator/includes/subtoolbar.php b/Sites/pages/administrator/includes/subtoolbar.php new file mode 100644 index 00000000..3b315bf6 --- /dev/null +++ b/Sites/pages/administrator/includes/subtoolbar.php @@ -0,0 +1,213 @@ + $label, 'name' => $name, 'options' => $options, 'noDefault' => $noDefault); + } + + /** + * Returns an array of all filters + * + * @return array + * + * @since 3.0 + * @deprecated 4.0 Use JHtmlSidebar::getFilters() instead. + */ + public static function getFilters() + { + try + { + JLog::add( + sprintf('%s() is deprecated. Use JHtmlSidebar::getFilters() instead.', __METHOD__), + JLog::WARNING, + 'deprecated' + ); + } + catch (RuntimeException $exception) + { + // Informational log only + } + + return self::$filters; + } + + /** + * Set value for the action attribute of the filter form + * + * @param string $action Value for the action attribute of the form + * + * @return void + * + * @since 3.0 + * @deprecated 4.0 Use JHtmlSidebar::setAction() instead. + */ + public static function setAction($action) + { + try + { + JLog::add( + sprintf('%s() is deprecated. Use JHtmlSidebar::setAction() instead.', __METHOD__), + JLog::WARNING, + 'deprecated' + ); + } + catch (RuntimeException $exception) + { + // Informational log only + } + + self::$action = $action; + } + + /** + * Get value for the action attribute of the filter form + * + * @return string Value for the action attribute of the form + * + * @since 3.0 + * @deprecated 4.0 Use JHtmlSidebar::getAction() instead. + */ + public static function getAction() + { + try + { + JLog::add( + sprintf('%s() is deprecated. Use JHtmlSidebar::getAction() instead.', __METHOD__), + JLog::WARNING, + 'deprecated' + ); + } + catch (RuntimeException $exception) + { + // Informational log only + } + + return self::$action; + } +} diff --git a/Sites/pages/administrator/index.php b/Sites/pages/administrator/index.php new file mode 100644 index 00000000..fd80a8fb --- /dev/null +++ b/Sites/pages/administrator/index.php @@ -0,0 +1,51 @@ +setStart($startTime, $startMem)->mark('afterLoad') : null; + +// Instantiate the application. +$app = JFactory::getApplication('administrator'); + +// Execute the application. +$app->execute(); diff --git a/Sites/pages/administrator/language/en-GB/en-GB.com_actionlogs.ini b/Sites/pages/administrator/language/en-GB/en-GB.com_actionlogs.ini new file mode 100644 index 00000000..b3020ba6 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.com_actionlogs.ini @@ -0,0 +1,63 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +COM_ACTIONLOGS="User Actions Log" +COM_ACTIONLOGS_ACTION="Action" +COM_ACTIONLOGS_ACTION_ASC="Action ascending" +COM_ACTIONLOGS_ACTION_DESC="Action descending" +COM_ACTIONLOGS_ACTION_VIEWLOGS="View logs" +COM_ACTIONLOGS_ACTION_VIEWLOGS_DESC="Allows users in the group to view the logs." +COM_ACTIONLOGS_COMMA="Comma" +COM_ACTIONLOGS_CONFIGURATION="User Actions Log: Options" +COM_ACTIONLOGS_CSV_DELIMITER_DESC="Set the separator for values in the CSV export." +COM_ACTIONLOGS_CSV_DELIMITER_LABEL="CSV Delimiter" +COM_ACTIONLOGS_DATE="Date" +COM_ACTIONLOGS_DISABLED="Disabled" +COM_ACTIONLOGS_EMAIL_DESC="This is the latest action performed by a user on your website." +COM_ACTIONLOGS_EMAIL_SUBJECT="Latest User Actions" +COM_ACTIONLOGS_EXPORT_ALL_CSV="Export All as CSV" +COM_ACTIONLOGS_EXPORT_CSV="Export Selected as CSV" +COM_ACTIONLOGS_EXTENSION="Extension" +COM_ACTIONLOGS_EXTENSION_ASC="Extension ascending" +COM_ACTIONLOGS_EXTENSION_DESC="Extension descending" +COM_ACTIONLOGS_EXTENSION_FILTER_DESC="Search in the User Action logs by extension" +COM_ACTIONLOGS_ERROR_COULD_NOT_EXPORT_DATA="Could not export data." +COM_ACTIONLOGS_FILTER_SEARCH_DESC="Search in username. Prefix with ID: to search for an actionlog ID. Prefix with ITEM_ID: to search for an actionlog item ID." +COM_ACTIONLOGS_IP_ADDRESS="IP Address" +COM_ACTIONLOGS_IP_ADDRESS_ASC="IP Address ascending" +COM_ACTIONLOGS_IP_ADDRESS_DESC="IP Address descending" +COM_ACTIONLOGS_IP_INVALID="Invalid IP" +COM_ACTIONLOGS_IP_LOGGING_DESC="Enable logging the IP address of users." +COM_ACTIONLOGS_IP_LOGGING_LABEL="IP Logging" +COM_ACTIONLOGS_LOG_EXTENSIONS_DESC="Select events to be logged." +COM_ACTIONLOGS_LOG_EXTENSIONS_LABEL="Events To Log" +COM_ACTIONLOGS_MANAGER_USERLOGS="User Actions Log" +COM_ACTIONLOGS_N_ITEMS_DELETED="%s logs deleted." +COM_ACTIONLOGS_N_ITEMS_DELETED_1="%s log deleted." +COM_ACTIONLOGS_NAME="Name" +COM_ACTIONLOGS_NAME_ASC="Name ascending" +COM_ACTIONLOGS_NAME_DESC="Name descending" +COM_ACTIONLOGS_NO_ITEM_SELECTED="Please first make a selection from the list." +COM_ACTIONLOGS_NO_LOGS_TO_EXPORT="There are no User Action logs to export." +COM_ACTIONLOGS_OPTION_FILTER_DATE="- Select Date -" +COM_ACTIONLOGS_OPTION_RANGE_NEVER="Never" +COM_ACTIONLOGS_OPTION_RANGE_PAST_1MONTH="In the last month" +COM_ACTIONLOGS_OPTION_RANGE_PAST_3MONTH="In the last 3 months" +COM_ACTIONLOGS_OPTION_RANGE_PAST_6MONTH="In the last 6 months" +COM_ACTIONLOGS_OPTION_RANGE_PAST_WEEK="In the last week" +COM_ACTIONLOGS_OPTION_RANGE_PAST_YEAR="In the last year" +COM_ACTIONLOGS_OPTION_RANGE_POST_YEAR="More than a year ago" +COM_ACTIONLOGS_OPTION_RANGE_TODAY="Today" +COM_ACTIONLOGS_OPTIONS="Options" +COM_ACTIONLOGS_POSTINSTALL_BODY="

    With the release of Joomla 3.9.0 you can now log all administrative actions performed by your users in supported extensions. It is now easy to see who did what and when they did it.

    The logs can be reviewed in Joomla or exported for external use.

    For further information on this new feature read the User Action Logs documentation.

    " +COM_ACTIONLOGS_POSTINSTALL_TITLE="User Actions Can Now Be Logged" +COM_ACTIONLOGS_PURGE_CONFIRM="Are you sure want to delete all User Action logs?" +COM_ACTIONLOGS_PURGE_FAIL="Failed to delete all User Action logs." +COM_ACTIONLOGS_PURGE_SUCCESS="All User Action logs have been deleted." +COM_ACTIONLOGS_SELECT_EXTENSION="- Select Extension -" +COM_ACTIONLOGS_SELECT_USER="- Select User -" +COM_ACTIONLOGS_SEMICOLON="Semicolon" +COM_ACTIONLOGS_TOOLBAR_PURGE="Purge" +COM_ACTIONLOGS_XML_DESCRIPTION="Displays a log of actions performed by users on your website." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.com_actionlogs.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.com_actionlogs.sys.ini new file mode 100644 index 00000000..a6afe546 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.com_actionlogs.sys.ini @@ -0,0 +1,9 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +COM_ACTIONLOGS="User Actions Log" +COM_ACTIONLOGS_VIEW_DEFAULT_DESC="Shows a list of user actions." +COM_ACTIONLOGS_VIEW_DEFAULT_TITLE="User Action Log" +COM_ACTIONLOGS_XML_DESCRIPTION="Displays a log of actions performed by users on your website." \ No newline at end of file diff --git a/Sites/pages/administrator/language/en-GB/en-GB.com_admin.ini b/Sites/pages/administrator/language/en-GB/en-GB.com_admin.ini new file mode 100644 index 00000000..57a89b00 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.com_admin.ini @@ -0,0 +1,208 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +COM_ADMIN="System Information" +COM_ADMIN_ALPHABETICAL_INDEX="Alphabetical Index" +COM_ADMIN_CACHE_DIRECTORY="(Cache Folder)" +COM_ADMIN_CLEAR_RESULTS="Clear results" +COM_ADMIN_CONFIGURATION_FILE="Configuration File" +COM_ADMIN_DATABASE_COLLATION="Database Collation" +COM_ADMIN_DATABASE_CONNECTION_COLLATION="Database Connection Collation" +COM_ADMIN_DATABASE_TYPE="Database Type" +COM_ADMIN_DATABASE_VERSION="Database Version" +COM_ADMIN_DIRECTORY="Folder" +COM_ADMIN_DIRECTORY_PERMISSIONS="Folder Permissions" +COM_ADMIN_DISABLED_FUNCTIONS="Disabled Functions" +COM_ADMIN_DISPLAY_ERRORS="Display Errors" +COM_ADMIN_DOWNLOAD_SYSTEM_INFORMATION_TEXT="Download as text" +COM_ADMIN_DOWNLOAD_SYSTEM_INFORMATION_JSON="Download as JSON" +COM_ADMIN_EXTENSIONS="Extensions" +COM_ADMIN_FILE_UPLOADS="File Uploads" +COM_ADMIN_GLOSSARY="Glossary" +COM_ADMIN_GO="Go" +COM_ADMIN_HELP="Joomla! Help" +COM_ADMIN_HELP_COMPONENTS_ACTIONLOGS="Action Logs" +COM_ADMIN_HELP_COMPONENTS_ASSOCIATIONS="Multilingual Associations" +COM_ADMIN_HELP_COMPONENTS_ASSOCIATIONS_EDIT="Multilingual Associations: Select" +COM_ADMIN_HELP_COMPONENTS_BANNERS_BANNERS="Banners" +COM_ADMIN_HELP_COMPONENTS_BANNERS_BANNERS_EDIT="Banners: New/Edit" +COM_ADMIN_HELP_COMPONENTS_BANNERS_CATEGORIES="Banners: Categories" +COM_ADMIN_HELP_COMPONENTS_BANNERS_CATEGORIES_EDIT="Banners: Categories - New/Edit" +COM_ADMIN_HELP_COMPONENTS_BANNERS_CLIENTS="Banners: Clients" +COM_ADMIN_HELP_COMPONENTS_BANNERS_CLIENTS_EDIT="Banners: Clients - New/Edit" +COM_ADMIN_HELP_COMPONENTS_BANNERS_TRACKS="Banners: Tracks" +COM_ADMIN_HELP_COMPONENTS_CONTACTS_CONTACTS="Contacts" +COM_ADMIN_HELP_COMPONENTS_CONTACTS_CONTACTS_EDIT="Contacts: New/Edit" +COM_ADMIN_HELP_COMPONENTS_CONTACT_CATEGORIES="Contacts: Categories" +COM_ADMIN_HELP_COMPONENTS_CONTACT_CATEGORIES_EDIT="Contacts: Categories - New/Edit" +COM_ADMIN_HELP_COMPONENTS_CONTENT_CATEGORIES="Articles: Categories" +COM_ADMIN_HELP_COMPONENTS_CONTENT_CATEGORIES_EDIT="Articles: Categories - New/Edit" +COM_ADMIN_HELP_COMPONENTS_FIELDS_FIELDS="Fields" +COM_ADMIN_HELP_COMPONENTS_FIELDS_FIELDS_EDIT="Fields: New/Edit" +COM_ADMIN_HELP_COMPONENTS_FIELDS_FIELD_GROUPS="Field Groups" +COM_ADMIN_HELP_COMPONENTS_FIELDS_FIELD_GROUPS_EDIT="Field Groups: New/Edit" +COM_ADMIN_HELP_COMPONENTS_FINDER_MANAGE_CONTENT_MAPS="Smart Search: Content Maps" +COM_ADMIN_HELP_COMPONENTS_FINDER_MANAGE_INDEXED_CONTENT="Smart Search: Indexed Content" +COM_ADMIN_HELP_COMPONENTS_FINDER_MANAGE_SEARCH_FILTERS_EDIT="Smart Search: Filters - New/Edit" +COM_ADMIN_HELP_COMPONENTS_FINDER_MANAGE_SEARCH_FILTERS="Smart Search: Search Filters" +COM_ADMIN_HELP_COMPONENTS_JOOMLA_UPDATE="Joomla Update" +COM_ADMIN_HELP_COMPONENTS_MESSAGING_INBOX="Private Messages: Inbox" +COM_ADMIN_HELP_COMPONENTS_MESSAGING_READ="Private Messages: Read" +COM_ADMIN_HELP_COMPONENTS_MESSAGING_WRITE="Private Messages: Write" +COM_ADMIN_HELP_COMPONENTS_NEWSFEEDS_CATEGORIES="News Feeds: Categories" +COM_ADMIN_HELP_COMPONENTS_NEWSFEEDS_CATEGORIES_EDIT="News Feeds: Categories - New/Edit" +COM_ADMIN_HELP_COMPONENTS_NEWSFEEDS_FEEDS="News Feeds" +COM_ADMIN_HELP_COMPONENTS_NEWSFEEDS_FEEDS_EDIT="News Feeds: New/Edit" +COM_ADMIN_HELP_COMPONENTS_POST_INSTALLATION_MESSAGES="Post-Installation Messages" +COM_ADMIN_HELP_COMPONENTS_PRIVACY_CAPABILITIES="Privacy: Extension Capabilities" +COM_ADMIN_HELP_COMPONENTS_PRIVACY_CONSENTS="Privacy: Consents" +COM_ADMIN_HELP_COMPONENTS_PRIVACY_DASHBOARD="Privacy: Dashboard" +COM_ADMIN_HELP_COMPONENTS_PRIVACY_REQUEST="Privacy: Review Information Request" +COM_ADMIN_HELP_COMPONENTS_PRIVACY_REQUEST_EDIT="Privacy: New Information Request" +COM_ADMIN_HELP_COMPONENTS_PRIVACY_REQUESTS="Privacy: Information Requests" +COM_ADMIN_HELP_COMPONENTS_REDIRECT_MANAGER="Redirect: Links" +COM_ADMIN_HELP_COMPONENTS_REDIRECT_MANAGER_EDIT="Redirect: Links - New/Edit" +COM_ADMIN_HELP_COMPONENTS_SEARCH="Search" +COM_ADMIN_HELP_COMPONENTS_TAGS_MANAGER="Tags" +COM_ADMIN_HELP_COMPONENTS_TAGS_MANAGER_EDIT="Tags: New/Edit" +COM_ADMIN_HELP_COMPONENTS_WEBLINKS_CATEGORIES="Web Links: Categories" +COM_ADMIN_HELP_COMPONENTS_WEBLINKS_CATEGORIES_EDIT="Web Links: Categories - New/Edit" +COM_ADMIN_HELP_COMPONENTS_WEBLINKS_LINKS="Web Links" +COM_ADMIN_HELP_COMPONENTS_WEBLINKS_LINKS_EDIT="Web Links: New/Edit" +COM_ADMIN_HELP_CONTENT_ARTICLE_MANAGER="Articles" +COM_ADMIN_HELP_CONTENT_ARTICLE_MANAGER_EDIT="Articles: New/Edit" +COM_ADMIN_HELP_CONTENT_FEATURED_ARTICLES="Articles: Featured " +COM_ADMIN_HELP_CONTENT_MEDIA_MANAGER="Media" +COM_ADMIN_HELP_EXTENSIONS_EXTENSION_MANAGER_DATABASE="Extensions: Check Database" +COM_ADMIN_HELP_EXTENSIONS_EXTENSION_MANAGER_DISCOVER="Extensions: Discover" +COM_ADMIN_HELP_EXTENSIONS_EXTENSION_MANAGER_INSTALL="Extensions: Install" +COM_ADMIN_HELP_EXTENSIONS_EXTENSION_MANAGER_LANGUAGES="Extensions: Install Accredited Language Translations" +COM_ADMIN_HELP_EXTENSIONS_EXTENSION_MANAGER_MANAGE="Extensions: Manage" +COM_ADMIN_HELP_EXTENSIONS_EXTENSION_MANAGER_UPDATE="Extensions: Update" +COM_ADMIN_HELP_EXTENSIONS_EXTENSION_MANAGER_WARNINGS="Extensions: Warnings" +COM_ADMIN_HELP_EXTENSIONS_LANGUAGE_MANAGER_CONTENT="Languages: Content" +COM_ADMIN_HELP_EXTENSIONS_LANGUAGE_MANAGER_EDIT="Languages: New/Edit" +COM_ADMIN_HELP_EXTENSIONS_LANGUAGE_MANAGER_INSTALLED="Languages: Installed" +COM_ADMIN_HELP_EXTENSIONS_LANGUAGE_MANAGER_OVERRIDES="Languages: Overrides" +COM_ADMIN_HELP_EXTENSIONS_LANGUAGE_MANAGER_OVERRIDES_EDIT="Languages: Overrides - New/Edit" +COM_ADMIN_HELP_EXTENSIONS_MODULE_MANAGER="Modules" +COM_ADMIN_HELP_EXTENSIONS_MODULE_MANAGER_EDIT="Modules: Edit" +COM_ADMIN_HELP_EXTENSIONS_PLUGIN_MANAGER="Plugins" +COM_ADMIN_HELP_EXTENSIONS_PLUGIN_MANAGER_EDIT="Plugins: New/Edit" +COM_ADMIN_HELP_EXTENSIONS_TEMPLATE_MANAGER_STYLES="Templates: Styles" +COM_ADMIN_HELP_EXTENSIONS_TEMPLATE_MANAGER_STYLES_EDIT="Templates: Styles - Edit" +COM_ADMIN_HELP_EXTENSIONS_TEMPLATE_MANAGER_TEMPLATES="Templates" +COM_ADMIN_HELP_EXTENSIONS_TEMPLATE_MANAGER_TEMPLATES_EDIT="Templates: Edit" +COM_ADMIN_HELP_EXTENSIONS_TEMPLATE_MANAGER_TEMPLATES_EDIT_SOURCE="Templates: Source - Edit" +COM_ADMIN_HELP_GLOSSARY="Glossary" +COM_ADMIN_HELP_MENUS_MENU_ITEM_MANAGER="Menu: Items" +COM_ADMIN_HELP_MENUS_MENU_ITEM_MANAGER_EDIT="Menu: Items New/Edit" +COM_ADMIN_HELP_MENUS_MENU_MANAGER="Menus" +COM_ADMIN_HELP_MENUS_MENU_MANAGER_EDIT="Menus: New/Edit" +COM_ADMIN_HELP_SITE_GLOBAL_CONFIGURATION="Global Configuration" +COM_ADMIN_HELP_SITE_MAINTENANCE_CLEAR_CACHE="Cache: Clear Cache" +COM_ADMIN_HELP_SITE_MAINTENANCE_GLOBAL_CHECK-IN="Global Check-in" +COM_ADMIN_HELP_SITE_MAINTENANCE_PURGE_EXPIRED_CACHE="Cache: Clear Expired Cache" +COM_ADMIN_HELP_SITE_SYSTEM_INFORMATION="System Information" +COM_ADMIN_HELP_START_HERE="Start Here" +COM_ADMIN_HELP_USERS_ACCESS_LEVELS="Users: Access Levels" +COM_ADMIN_HELP_USERS_ACCESS_LEVELS_EDIT="Users: Access Levels - New/Edit" +COM_ADMIN_HELP_USERS_DEBUG_USER="Users: Debug Users Permissions" +COM_ADMIN_HELP_USERS_GROUPS="Users: Groups" +COM_ADMIN_HELP_USERS_GROUPS_EDIT="Users: Groups - New/Edit" +COM_ADMIN_HELP_USERS_MASS_MAIL_USERS="Mass Mail Users" +COM_ADMIN_HELP_USERS_USER_NOTES="Users: User Notes" +COM_ADMIN_HELP_USERS_USER_NOTES_EDIT="Users: User Notes - New/Edit" +COM_ADMIN_HELP_USERS_USER_MANAGER="Users" +COM_ADMIN_HELP_USERS_USER_MANAGER_EDIT="Users: New/Edit" +COM_ADMIN_ICONV_AVAILABLE="Iconv Available" +COM_ADMIN_INFORMATION="System Information" +COM_ADMIN_JOOMLA_VERSION="Joomla! Version" +COM_ADMIN_LATEST_VERSION_CHECK="Latest Version Check" +COM_ADMIN_LICENSE="License" +COM_ADMIN_LOG_DIRECTORY="(Log folder)" +COM_ADMIN_MAGIC_QUOTES="Magic Quotes" +COM_ADMIN_MAX_INPUT_VARS="Maximum Input Variables" +COM_ADMIN_MBSTRING_ENABLED="Multibyte String (mbstring) Enabled" +COM_ADMIN_MCRYPT_ENABLED="Mcrypt Enabled" +COM_ADMIN_NA="n/a" +COM_ADMIN_OPEN_BASEDIR="Open basedir" +COM_ADMIN_OUTPUT_BUFFERING="Output Buffering" +COM_ADMIN_PHP_BUILT_ON="PHP Built On" +COM_ADMIN_PHP_INFORMATION="PHP Information" +COM_ADMIN_PHP_SETTINGS="PHP Settings" +COM_ADMIN_PHP_VERSION="PHP Version" +COM_ADMIN_PHPINFO_DISABLED="The built in phpinfo() function has been disabled by your host." +COM_ADMIN_PLATFORM_VERSION="Joomla! Platform Version" +COM_ADMIN_POSTINSTALL_MSG_HTACCESS_AUTOINDEX_DESCRIPTION="

    Before 3.9.22 the default htaccess.txt file contained erroneous code meant for disabling directory listings. The security team recommends to manually apply the necessary changes to any existing .htaccess file, as this file can not be updated automatically.

    The old code:

    <IfModule autoindex>\n  IndexIgnore *\n</IfModule>

    The new code:

    <IfModule mod_autoindex.c>\n  IndexIgnore *\n</IfModule>
    " +COM_ADMIN_POSTINSTALL_MSG_HTACCESS_AUTOINDEX_TITLE=".htaccess Update Concerning Directory Listings" +COM_ADMIN_REGISTER_GLOBALS="Register Globals" +COM_ADMIN_RELEVANT_PHP_SETTINGS="Relevant PHP Settings" +COM_ADMIN_SAFE_MODE="Safe Mode" +COM_ADMIN_SAVE_SUCCESS="Profile saved." +COM_ADMIN_SEARCH="Search" +COM_ADMIN_SESSION_AUTO_START="Session Auto Start" +COM_ADMIN_SESSION_SAVE_PATH="Session Save Path" +COM_ADMIN_SETTING="Setting" +COM_ADMIN_SHORT_OPEN_TAGS="Short Open Tags" +COM_ADMIN_START_HERE="Start here" +COM_ADMIN_STATUS="Status" +COM_ADMIN_SYSTEM_INFO="System Info" +COM_ADMIN_SYSTEM_INFORMATION="System Information" +COM_ADMIN_TEMP_DIRECTORY="(Temp folder)" +COM_ADMIN_UNWRITABLE="Unwritable" +COM_ADMIN_USER_ACCOUNT_DETAILS="My Profile Details" +COM_ADMIN_USER_AGENT="User Agent" +COM_ADMIN_USER_FIELD_BACKEND_LANGUAGE_DESC="Select the Language for the Administrator Backend interface. This will only affect this User." +COM_ADMIN_USER_FIELD_BACKEND_LANGUAGE_LABEL="Backend Language" +COM_ADMIN_USER_FIELD_BACKEND_TEMPLATE_DESC="Select the template style for the Administrator Backend interface. This will only affect this User." +COM_ADMIN_USER_FIELD_BACKEND_TEMPLATE_LABEL="Backend Template Style" +COM_ADMIN_USER_FIELD_EDITOR_DESC="Editor for this user." +COM_ADMIN_USER_FIELD_EDITOR_LABEL="Editor" +COM_ADMIN_USER_FIELD_EMAIL_DESC="Enter an email address for the user." +COM_ADMIN_USER_FIELD_FRONTEND_LANGUAGE_DESC="Select the Language for the Frontend interface. This will only affect this User." +COM_ADMIN_USER_FIELD_FRONTEND_LANGUAGE_LABEL="Frontend Language" +; The following two strings are deprecated and will be removed with 4.0. +COM_ADMIN_USER_FIELD_HELPSITE_DESC="Help site for this user." +COM_ADMIN_USER_FIELD_HELPSITE_LABEL="Help Site" +COM_ADMIN_USER_FIELD_LASTVISIT_DESC="Last visit date." +COM_ADMIN_USER_FIELD_LASTVISIT_LABEL="Last Visit Date" +COM_ADMIN_USER_FIELD_NAME_DESC="Enter the name of the user." +COM_ADMIN_USER_FIELD_NOCHANGE_USERNAME_DESC="If you want to change your Username, please contact a site administrator." +COM_ADMIN_USER_FIELD_PASSWORD1_MESSAGE="The passwords you entered do not match. Please enter your desired password in the password field and confirm your entry by entering it in the confirm password field." +COM_ADMIN_USER_FIELD_PASSWORD2_DESC="Confirm the user's password." +COM_ADMIN_USER_FIELD_PASSWORD2_LABEL="Confirm Password" +COM_ADMIN_USER_FIELD_PASSWORD_DESC="Enter the password for the user." +COM_ADMIN_USER_FIELD_REGISTERDATE_DESC="Registration date." +COM_ADMIN_USER_FIELD_REGISTERDATE_LABEL="Registration Date" +COM_ADMIN_USER_FIELD_TIMEZONE_DESC="Time zone for this user." +COM_ADMIN_USER_FIELD_TIMEZONE_LABEL="Time Zone" +COM_ADMIN_USER_FIELD_USERNAME_DESC="Enter the login name (Username) for the user." +COM_ADMIN_USER_FIELD_USERNAME_LABEL="Login Name" +COM_ADMIN_USER_HEADING_NAME="Name" +COM_ADMIN_USER_SETTINGS_FIELDSET_LABEL="Basic Settings" +COM_ADMIN_VALUE="Value" +COM_ADMIN_VIEW="View" +COM_ADMIN_VIEW_PROFILE_TITLE="My Profile" +COM_ADMIN_WEBSERVER_TO_PHP_INTERFACE="WebServer to PHP Interface" +COM_ADMIN_WEB_SERVER="Web Server" +COM_ADMIN_WRITABLE="Writable" +COM_ADMIN_XML_DESCRIPTION="Administration system information component." +COM_ADMIN_XML_ENABLED="XML Enabled" +COM_ADMIN_ZIP_ENABLED="Native ZIP Enabled" +COM_ADMIN_ZLIB_ENABLED="Zlib Enabled" + +; Messages +COM_USERS_MSG_NOT_ENOUGH_INTEGERS_N="Password does not have enough digits. At least %s digits are required." +COM_USERS_MSG_NOT_ENOUGH_INTEGERS_N_1="Password does not have enough digits. At least 1 digit is required." +COM_USERS_MSG_NOT_ENOUGH_LOWERCASE_LETTERS_N="Password does not have enough lower case characters. At least %s lower case characters are required." +COM_USERS_MSG_NOT_ENOUGH_LOWERCASE_LETTERS_N_1="Password does not have enough lower case characters. At least 1 lower case character is required." +COM_USERS_MSG_NOT_ENOUGH_SYMBOLS_N="Password does not have enough symbols (such as !@#$). At least %s symbols are required." +COM_USERS_MSG_NOT_ENOUGH_SYMBOLS_N_1="Password does not have enough symbols (such as !@#$). At least 1 symbol is required." +COM_USERS_MSG_NOT_ENOUGH_UPPERCASE_LETTERS_N="Password does not have enough upper case characters. At least %s upper case characters are required." +COM_USERS_MSG_NOT_ENOUGH_UPPERCASE_LETTERS_N_1="Password does not have enough upper case characters. At least 1 upper case character is required." +COM_USERS_MSG_PASSWORD_TOO_LONG="Password is too long. Passwords must be less than 100 characters." +COM_USERS_MSG_PASSWORD_TOO_SHORT_N="Password is too short. Passwords must have at least %s characters." +COM_USERS_MSG_SPACES_IN_PASSWORD="Password must not have spaces at the beginning or end." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.com_admin.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.com_admin.sys.ini new file mode 100644 index 00000000..0f71f3c1 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.com_admin.sys.ini @@ -0,0 +1,12 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +COM_ADMIN="System Information" +COM_ADMIN_XML_DESCRIPTION="Administration system information component." + +COM_ADMIN_HELP_VIEW_DEFAULT_DESC="Get help on various pages in your Joomla administrator interface." +COM_ADMIN_HELP_VIEW_DEFAULT_TITLE="Joomla! Help" +COM_ADMIN_SYSINFO_VIEW_DEFAULT_DESC="View detailed information about your Joomla site and server configuration settings." +COM_ADMIN_SYSINFO_VIEW_DEFAULT_TITLE="System Information" diff --git a/Sites/pages/administrator/language/en-GB/en-GB.com_ajax.ini b/Sites/pages/administrator/language/en-GB/en-GB.com_ajax.ini new file mode 100644 index 00000000..e6d91576 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.com_ajax.ini @@ -0,0 +1,13 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + + +COM_AJAX="Ajax Interface" +COM_AJAX_XML_DESCRIPTION="An extendable Ajax interface for Joomla." +COM_AJAX_SPECIFY_FORMAT="Please specify a valid response format, other than that of HTML, such as json, raw, debug, etc." +COM_AJAX_METHOD_NOT_EXISTS="Method %s does not exist." +COM_AJAX_FILE_NOT_EXISTS="The file at %s does not exist." +COM_AJAX_MODULE_NOT_ACCESSIBLE="Module %s is not published, you do not have access to it, or it's not assigned to the current menu item." +COM_AJAX_TEMPLATE_NOT_ACCESSIBLE="Template %s is not assigned to the current menu item." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.com_ajax.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.com_ajax.sys.ini new file mode 100644 index 00000000..04a9725a --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.com_ajax.sys.ini @@ -0,0 +1,8 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + + +COM_AJAX="Ajax Interface" +COM_AJAX_XML_DESCRIPTION="An extendable Ajax interface for Joomla." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.com_associations.ini b/Sites/pages/administrator/language/en-GB/en-GB.com_associations.ini new file mode 100644 index 00000000..d392dd7d --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.com_associations.ini @@ -0,0 +1,53 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +COM_ASSOCIATIONS="Multilingual Associations" +COM_ASSOCIATIONS_ADD_NEW_ASSOCIATION="Add new association" +COM_ASSOCIATIONS_ASSOCIATED_ITEM="Target" +COM_ASSOCIATIONS_CHANGE_TARGET="Change Target" +COM_ASSOCIATIONS_COMPONENT_NOT_SUPPORTED="The extension %s does not support multilingual associations." +COM_ASSOCIATIONS_COMPONENT_SELECTOR_DESC="Select a component from this list" +COM_ASSOCIATIONS_COMPONENT_SELECTOR_LABEL="Select component" +COM_ASSOCIATIONS_CONFIGURATION="Multilingual Associations: Options" +COM_ASSOCIATIONS_COPY_REFERENCE="Copy Reference to Target" +COM_ASSOCIATIONS_DELETE_ORPHANS="Delete Orphans" +COM_ASSOCIATIONS_DELETE_ORPHANS_FAILED="Failed to delete orphans." +COM_ASSOCIATIONS_DELETE_ORPHANS_NONE="There were no orphans to delete." +COM_ASSOCIATIONS_DELETE_ORPHANS_SUCCESS="All orphans have been deleted." +COM_ASSOCIATIONS_EDIT_ASSOCIATION="Edit association" +COM_ASSOCIATIONS_EDIT_HIDE_REFERENCE="Hide Reference" +COM_ASSOCIATIONS_EDIT_SHOW_REFERENCE="Show Reference" +COM_ASSOCIATIONS_ERROR_NO_ASSOC="The Multilingual Associations component can't be used if the site is not set as multilingual and/or Associations is not enabled in the Language Filter plugin." +COM_ASSOCIATIONS_ERROR_NO_TYPE="The item type selected does not exist for this component." +COM_ASSOCIATIONS_FILTER_MENUTYPE_DESC="Select a Menu" +COM_ASSOCIATIONS_FILTER_MENUTYPE_LABEL="Menu" +COM_ASSOCIATIONS_FILTER_SEARCH_DESC="Search an item by its title" +COM_ASSOCIATIONS_FILTER_SEARCH_LABEL="Search item" +COM_ASSOCIATIONS_FILTER_SELECT_ITEM_TYPE="- Select Item Type -" +COM_ASSOCIATIONS_HEADING_ASSOCIATION="Associations" +COM_ASSOCIATIONS_HEADING_MENUTYPE="Menu" +COM_ASSOCIATIONS_HEADING_MENUTYPE_ASC="Menu ascending" +COM_ASSOCIATIONS_HEADING_MENUTYPE_DESC="Menu descending" +COM_ASSOCIATIONS_HEADING_NO_ASSOCIATION="Not Associated" +COM_ASSOCIATIONS_ITEMS="Items" +COM_ASSOCIATIONS_NO_ASSOCIATION="There is no association for this language" +COM_ASSOCIATIONS_NOTICE_NO_SELECTORS="Please select an Item Type and a reference language to view the associations." +COM_ASSOCIATIONS_PURGE="Delete All Associations" +COM_ASSOCIATIONS_PURGE_CONFIRM_PROMPT="Are you sure you want to delete all associations? Confirming will permanently delete them!" +COM_ASSOCIATIONS_PURGE_FAILED="Failed to delete all associations." +COM_ASSOCIATIONS_PURGE_NONE="There were no associations to delete." +COM_ASSOCIATIONS_PURGE_SUCCESS="All associations have been deleted." +COM_ASSOCIATIONS_REFERENCE_ITEM="Reference" +COM_ASSOCIATIONS_SAVE_REFERENCE="Save Reference" +COM_ASSOCIATIONS_SAVE_TARGET="Save Target" +COM_ASSOCIATIONS_SELECT_MENU="- Select Menu -" +COM_ASSOCIATIONS_SELECT_TARGET="Select Target" +COM_ASSOCIATIONS_SELECT_TARGET_LANGUAGE="- Select Target Language -" +COM_ASSOCIATIONS_TITLE="Associations" +COM_ASSOCIATIONS_TITLE_EDIT="Multilingual Associations: Edit Associations (%1$s > %2$s)" +COM_ASSOCIATIONS_TITLE_LIST="Multilingual Associations (%1$s > %2$s)" +COM_ASSOCIATIONS_TITLE_LIST_SELECT="Multilingual Associations: Select Item Type and Language" +COM_ASSOCIATIONS_XML_DESCRIPTION="Improved multilingual content management component" +COM_ASSOCIATIONS_YOU_ARE_NOT_ALLOWED_TO_CHECKIN_THIS_ITEM="You can't check in this item" diff --git a/Sites/pages/administrator/language/en-GB/en-GB.com_associations.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.com_associations.sys.ini new file mode 100644 index 00000000..27627817 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.com_associations.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +COM_ASSOCIATIONS="Multilingual Associations" +COM_ASSOCIATIONS_XML_DESCRIPTION="Improved multilingual content management component" \ No newline at end of file diff --git a/Sites/pages/administrator/language/en-GB/en-GB.com_banners.ini b/Sites/pages/administrator/language/en-GB/en-GB.com_banners.ini new file mode 100644 index 00000000..d57e9008 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.com_banners.ini @@ -0,0 +1,248 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +COM_BANNERS="Banners" +COM_BANNERS_BANNER_DETAILS="Details" +COM_BANNERS_BANNER_SAVE_SUCCESS="Banner saved." +COM_BANNERS_BANNERS_FILTER_SEARCH_DESC="Search in banner name and alias. Prefix with ID: to search for a banner ID." +COM_BANNERS_BANNERS_FILTER_SEARCH_LABEL="Search Banners" +COM_BANNERS_BANNERS_HTML_PIN_BANNER="Pinned banner" +COM_BANNERS_BANNERS_HTML_UNPIN_BANNER="Unpinned banner" +COM_BANNERS_BANNERS_N_ITEMS_ARCHIVED="%d banners archived." +COM_BANNERS_BANNERS_N_ITEMS_ARCHIVED_1="%d banner archived." +COM_BANNERS_BANNERS_N_ITEMS_CHECKED_IN_0="No banner checked in." +COM_BANNERS_BANNERS_N_ITEMS_CHECKED_IN_1="%d banner checked in." +COM_BANNERS_BANNERS_N_ITEMS_CHECKED_IN_MORE="%d banners checked in." +COM_BANNERS_BANNERS_N_ITEMS_DELETED="%d banners deleted." +COM_BANNERS_BANNERS_N_ITEMS_DELETED_1="%d banner deleted." +COM_BANNERS_BANNERS_N_ITEMS_PUBLISHED="%d banners published." +COM_BANNERS_BANNERS_N_ITEMS_PUBLISHED_1="%d banner published." +COM_BANNERS_BANNERS_N_ITEMS_TRASHED="%d banners trashed." +COM_BANNERS_BANNERS_N_ITEMS_TRASHED_1="%d banner trashed." +COM_BANNERS_BANNERS_N_ITEMS_UNPUBLISHED="%d banners unpublished." +COM_BANNERS_BANNERS_N_ITEMS_UNPUBLISHED_1="%d banner unpublished." +COM_BANNERS_BANNERS_NO_ITEM_SELECTED="No Banners selected." +COM_BANNERS_BANNERS_PINNED="Pinned Banner" +COM_BANNERS_BANNERS_UNPINNED="Unpinned Banner" +COM_BANNERS_BATCH_CLIENT_LABEL="Set Client" +COM_BANNERS_BATCH_CLIENT_LABEL_DESC="Not making a selection will keep the original client when processing." +COM_BANNERS_BATCH_CLIENT_NOCHANGE="- Keep original Client -" +COM_BANNERS_BATCH_OPTIONS="Batch process the selected banners" +COM_BANNERS_BATCH_TIP="If a category is selected for move/copy, any actions selected will be applied to the copied or moved banners. Otherwise, all actions are applied to the selected banners." +COM_BANNERS_BEGIN_DESC="Banner begin date" +COM_BANNERS_BEGIN_HINT="Begin date (yyyy-mm-dd)" +COM_BANNERS_BEGIN_LABEL="Begin Date" +COM_BANNERS_CANCEL="Cancel" +COM_BANNERS_CLICK="Click" +COM_BANNERS_CLIENT_SAVE_SUCCESS="Client saved." +COM_BANNERS_CLIENTS_FILTER_SEARCH_DESC="Search in client name. Prefix with ID: to search for a client ID." +COM_BANNERS_CLIENTS_FILTER_SEARCH_LABEL="Search Clients" +COM_BANNERS_CLIENTS_N_ITEMS_ARCHIVED="%d clients archived." +COM_BANNERS_CLIENTS_N_ITEMS_ARCHIVED_1="%d client archived." +COM_BANNERS_CLIENTS_N_ITEMS_CHECKED_IN_0="No client checked in." +COM_BANNERS_CLIENTS_N_ITEMS_CHECKED_IN_1="%d client checked in." +COM_BANNERS_CLIENTS_N_ITEMS_CHECKED_IN_MORE="%d clients checked in." +COM_BANNERS_CLIENTS_N_ITEMS_DELETED="%d clients deleted." +COM_BANNERS_CLIENTS_N_ITEMS_DELETED_1="%d client deleted." +COM_BANNERS_CLIENTS_N_ITEMS_PUBLISHED="%d clients published." +COM_BANNERS_CLIENTS_N_ITEMS_PUBLISHED_1="%d client published." +COM_BANNERS_CLIENTS_N_ITEMS_TRASHED="%d clients trashed." +COM_BANNERS_CLIENTS_N_ITEMS_TRASHED_1="%d client trashed." +COM_BANNERS_CLIENTS_N_ITEMS_UNPUBLISHED="%d clients unpublished." +COM_BANNERS_CLIENTS_N_ITEMS_UNPUBLISHED_1="%d client unpublished." +COM_BANNERS_CLIENTS_NO_ITEM_SELECTED="No clients selected." +COM_BANNERS_CONFIGURATION="Banners: Options" +COM_BANNERS_COUNT_ARCHIVED_ITEMS="Archived banners" +COM_BANNERS_COUNT_PUBLISHED_ITEMS="Published banners" +COM_BANNERS_COUNT_TRASHED_ITEMS="Trashed banners" +COM_BANNERS_COUNT_UNPUBLISHED_ITEMS="Unpublished banners" +COM_BANNERS_DEFAULT="Default (%s)" +COM_BANNERS_DELETE_MSG="Are you sure you want to delete all these tracks?" +COM_BANNERS_EDIT_BANNER="Edit Banner" +COM_BANNERS_EDIT_CLIENT="Details" +COM_BANNERS_END_DESC="Banner end date" +COM_BANNERS_END_HINT="End date (yyyy-mm-dd)" +COM_BANNERS_END_LABEL="End Date" +COM_BANNERS_ERR_ZIP_ADAPTER_FAILURE="Zip adapter failure" +COM_BANNERS_ERR_ZIP_CREATE_FAILURE="Zip create failure" +COM_BANNERS_ERR_ZIP_DELETE_FAILURE="Zip delete failure" +COM_BANNERS_ERROR_UNIQUE_ALIAS="Another Banner from this category has the same alias (remember it may be a trashed item)." +COM_BANNERS_EXTRA="Additional Information" +COM_BANNERS_FIELD_ALIAS_DESC="The alias is for internal use only. Leave this blank and Joomla will fill in a default value from the title. It has to be unique for each banner in the same category." +COM_BANNERS_FIELD_ALT_DESC="Alternative text used for visitors without access to images." +COM_BANNERS_FIELD_ALT_LABEL="Alt Text" +COM_BANNERS_FIELD_BANNEROWNPREFIX_DESC="Use own prefix or the client prefix." +COM_BANNERS_FIELD_BANNEROWNPREFIX_LABEL="Use Own Prefix" +COM_BANNERS_FIELD_BASENAME_DESC="File name pattern which can have
    __SITE__ for the site name
    __CATID__ for the category ID
    __CATNAME__ for the category name
    __CLIENTID__ for the client ID
    __CLIENTNAME__ for the client name
    __TYPE__ for the type
    __TYPENAME__ for the type name
    __BEGIN__ for the begin date
    __END__ for the end date." +COM_BANNERS_FIELD_BASENAME_LABEL="File Name" +COM_BANNERS_FIELD_CATEGORY_DESC="Choose a category for this banner." +COM_BANNERS_FIELD_CLICKS_DESC="Displays the number of clicks on the banner. Select reset if desired." +COM_BANNERS_FIELD_CLICKS_LABEL="Total Clicks" +COM_BANNERS_FIELD_CLICKURL_DESC="The URL used when the banner is clicked on." +COM_BANNERS_FIELD_CLICKURL_LABEL="Click URL" +COM_BANNERS_FIELD_CLIENT_DESC="Choose a client for this banner." +COM_BANNERS_FIELD_CLIENT_LABEL="Client" +COM_BANNERS_FIELD_CLIENT_METAKEYWORDPREFIX_DESC="When matching Meta keywords, only search for Meta keywords with this prefix (improves performance)." +COM_BANNERS_FIELD_CLIENT_METAKEYWORDPREFIX_LABEL="Meta Keyword Prefix" +COM_BANNERS_FIELD_CLIENT_METAKEYWORDS_DESC="Enter the meta keywords for the clients' banners." +COM_BANNERS_FIELD_CLIENT_NAME_DESC="Enter a name for the client." +COM_BANNERS_FIELD_CLIENT_NAME_LABEL="Client Name" +COM_BANNERS_FIELD_CLIENT_STATE_DESC="Defines the status of the client." +COM_BANNERS_FIELD_CLIENTOWNPREFIX_DESC="Use own prefix or the component prefix." +COM_BANNERS_FIELD_CLIENTOWNPREFIX_LABEL="Use Own Prefix" +COM_BANNERS_FIELD_COMPRESSED_DESC="Option to compress file for export." +COM_BANNERS_FIELD_COMPRESSED_LABEL="Compressed" +COM_BANNERS_FIELD_CONTACT_DESC="Enter the name of a user as contact." +COM_BANNERS_FIELD_CONTACT_LABEL="Contact Name" +COM_BANNERS_FIELD_CREATED_BY_ALIAS_DESC="Enter an alias to be displayed instead of the name of the user who created the banner." +COM_BANNERS_FIELD_CREATED_BY_ALIAS_LABEL="Created by Alias" +COM_BANNERS_FIELD_CREATED_BY_DESC="Select the name of the user who created the banner." +COM_BANNERS_FIELD_CREATED_BY_LABEL="Created By" +COM_BANNERS_FIELD_CREATED_DESC="Banner created date." +COM_BANNERS_FIELD_CREATED_LABEL="Created Date" +COM_BANNERS_FIELD_CUSTOMCODE_DESC="Enter your custom code for the banner." +COM_BANNERS_FIELD_CUSTOMCODE_LABEL="Custom Code" +COM_BANNERS_FIELD_DESCRIPTION_DESC="Enter a description for the banner." +COM_BANNERS_FIELD_EMAIL_DESC="Enter a valid Contact email." +COM_BANNERS_FIELD_EMAIL_LABEL="Contact Email" +COM_BANNERS_FIELD_EXTRAINFO_DESC="Enter extra information for this client." +COM_BANNERS_FIELD_EXTRAINFO_LABEL="Additional Information" +COM_BANNERS_FIELD_HEIGHT_DESC="The height of the banner." +COM_BANNERS_FIELD_HEIGHT_LABEL="Height" +COM_BANNERS_FIELD_IMAGE_DESC="Select or upload an image for this banner." +COM_BANNERS_FIELD_IMAGE_LABEL="Image" +COM_BANNERS_FIELD_IMPMADE_DESC="Displays the number of impressions made for the banner." +COM_BANNERS_FIELD_IMPMADE_LABEL="Total Impressions" +COM_BANNERS_FIELD_IMPTOTAL_DESC="Total limit of impressions defined for the banner." +COM_BANNERS_FIELD_IMPTOTAL_LABEL="Max. Impressions" +COM_BANNERS_FIELD_LANGUAGE_DESC="Assign a language to this banner." +COM_BANNERS_FIELD_METAKEYWORDPREFIX_DESC="When matching Meta keywords, only search for Meta keywords with this prefix (improves performance)." +COM_BANNERS_FIELD_METAKEYWORDPREFIX_LABEL="Meta Keyword Prefix" +COM_BANNERS_FIELD_METAKEYWORDS_DESC="Enter the meta keywords for the banner." +COM_BANNERS_FIELD_MODIFIED_BY_DESC="Name of the user who modified this banner." +COM_BANNERS_FIELD_NAME_DESC="Enter a name for the banner." +COM_BANNERS_FIELD_NAME_LABEL="Name" +COM_BANNERS_FIELD_PUBLISH_DOWN_DESC="An optional date to Finish Publishing the banner." +COM_BANNERS_FIELD_PUBLISH_DOWN_LABEL="Finish Publishing" +COM_BANNERS_FIELD_PUBLISH_UP_DESC="An optional date to Start Publishing the banner." +COM_BANNERS_FIELD_PUBLISH_UP_LABEL="Start Publishing" +COM_BANNERS_FIELD_PURCHASETYPE_DESC="Select the type of purchase in the list." +COM_BANNERS_FIELD_PURCHASETYPE_LABEL="Purchase Type" +COM_BANNERS_FIELD_STATE_DESC="Defines the status of the banner." +COM_BANNERS_FIELD_STICKY_DESC="Whether or not the Banner is 'pinned'. If one or more Banners in a Category are pinned, they will take priority over Banners that are not pinned. For example, if two Banners in a Category are pinned and a third Banner is not pinned, the third Banner will not display if the module setting is 'Pinned, Randomise'. Only the two pinned Banners will display." +COM_BANNERS_FIELD_STICKY_LABEL="Pinned" +COM_BANNERS_FIELD_TRACKCLICK_DESC="Record the number of clicks on the banners on a daily basis." +COM_BANNERS_FIELD_TRACKCLICK_LABEL="Track Clicks" +COM_BANNERS_FIELD_TRACKIMPRESSION_DESC="Record the impressions (views) of the banners on a daily basis." +COM_BANNERS_FIELD_TRACKIMPRESSION_LABEL="Track Impressions" +COM_BANNERS_FIELD_TRACKROBOTSIMPRESSION_DESC="Include search engines in the count of impressions." +COM_BANNERS_FIELD_TRACKROBOTSIMPRESSION_LABEL="Impressions by Search Engines" +COM_BANNERS_FIELD_TYPE_DESC="Choose the type of banner. Select Image to display an image. Select Custom to enter your custom code." +COM_BANNERS_FIELD_TYPE_LABEL="Type" +; The following five strings are deprecated and will be removed with 4.0. They generate wrong plural detection in Crowdin. +COM_BANNERS_FIELD_VALUE_1="Unlimited" +COM_BANNERS_FIELD_VALUE_2="Yearly" +COM_BANNERS_FIELD_VALUE_3="Monthly" +COM_BANNERS_FIELD_VALUE_4="Weekly" +COM_BANNERS_FIELD_VALUE_5="Daily" +COM_BANNERS_FIELD_VALUE_UNLIMITED="Unlimited" +COM_BANNERS_FIELD_VALUE_YEARLY="Yearly" +COM_BANNERS_FIELD_VALUE_MONTHLY="Monthly" +COM_BANNERS_FIELD_VALUE_WEEKLY="Weekly" +COM_BANNERS_FIELD_VALUE_DAILY="Daily" +COM_BANNERS_FIELD_VALUE_CUSTOM="Custom" +COM_BANNERS_FIELD_VALUE_IMAGE="Image" +COM_BANNERS_FIELD_VALUE_USECLIENTDEFAULT="-- Use Client Default --" +COM_BANNERS_FIELD_VALUE_USECOMPONENTDEFAULT="-- Use Component Default --" +COM_BANNERS_FIELD_VERSION_LABEL="Revision" +COM_BANNERS_FIELD_VERSION_DESC="A count of the number of times this banner has been revised." +COM_BANNERS_FIELD_WIDTH_LABEL="Width" +COM_BANNERS_FIELD_WIDTH_DESC="The width of the banner." +COM_BANNERS_FIELDSET_CONFIG_BANNER_OPTIONS_DESC="These settings apply to version history for Banners, Banner Categories and Banner Clients." +COM_BANNERS_FIELDSET_CONFIG_BANNER_OPTIONS_LABEL="History" +COM_BANNERS_FIELDSET_CONFIG_CLIENT_OPTIONS_LABEL="Client" +COM_BANNERS_FIELDSET_CONFIG_CLIENT_OPTIONS_DESC="These settings apply for all clients unless they are changed for a specific client." +COM_BANNERS_FILENAME="%1$s-banners-tracks-%2$s" +COM_BANNERS_GROUP_LABEL_PUBLISHING_DETAILS="Publishing Options" +COM_BANNERS_GROUP_LABEL_BANNER_DETAILS="Banner Details" +COM_BANNERS_HEADING_ACTIVE="Active" +COM_BANNERS_HEADING_ACTIVE_ASC="Active ascending" +COM_BANNERS_HEADING_ACTIVE_DESC="Active descending" +COM_BANNERS_HEADING_BANNERS="Banners" +COM_BANNERS_HEADING_BANNERS_ASC="Banners ascending" +COM_BANNERS_HEADING_BANNERS_DESC="Banners descending" +COM_BANNERS_HEADING_CLICKS="Clicks" +COM_BANNERS_HEADING_CLICKS_ASC="Clicks ascending" +COM_BANNERS_HEADING_CLICKS_DESC="Clicks descending" +COM_BANNERS_HEADING_CLIENT="Client" +COM_BANNERS_HEADING_CLIENT_ASC="Client ascending" +COM_BANNERS_HEADING_CLIENT_DESC="Client descending" +COM_BANNERS_HEADING_CONTACT="Contact" +COM_BANNERS_HEADING_CONTACT_ASC="Contact ascending" +COM_BANNERS_HEADING_CONTACT_DESC="Contact descending" +COM_BANNERS_HEADING_COUNT="Count" +COM_BANNERS_HEADING_COUNT_ASC="Count ascending" +COM_BANNERS_HEADING_COUNT_DESC="Count descending" +COM_BANNERS_HEADING_IMPRESSIONS="Impressions" +COM_BANNERS_HEADING_IMPRESSIONS_ASC="Impressions ascending" +COM_BANNERS_HEADING_IMPRESSIONS_DESC="Impressions descending" +COM_BANNERS_HEADING_METAKEYWORDS="Meta Keywords" +COM_BANNERS_HEADING_NAME="Name" +COM_BANNERS_HEADING_NAME_ASC="Name ascending" +COM_BANNERS_HEADING_NAME_DESC="Name descending" +COM_BANNERS_HEADING_PURCHASETYPE="Purchase Type" +COM_BANNERS_HEADING_PURCHASETYPE_ASC="Purchase Type ascending" +COM_BANNERS_HEADING_PURCHASETYPE_DESC="Purchase Type descending" +COM_BANNERS_HEADING_STICKY="Pinned" +COM_BANNERS_HEADING_STICKY_ASC="Pinned ascending" +COM_BANNERS_HEADING_STICKY_DESC="Pinned descending" +COM_BANNERS_HEADING_TYPE="Type" +COM_BANNERS_HEADING_TYPE_ASC="Type ascending" +COM_BANNERS_HEADING_TYPE_DESC="Type descending" +COM_BANNERS_IMPRESSION="Impression" +COM_BANNERS_IMPRESSIONS="%1$s of %2$s" +COM_BANNERS_MANAGER="Banners" +COM_BANNERS_MANAGER_BANNER_EDIT="Banners: Edit" +COM_BANNERS_MANAGER_BANNER_NEW="Banners: New" +COM_BANNERS_MANAGER_BANNERS="Banners" +COM_BANNERS_MANAGER_CLIENT_EDIT="Banners: Edit Client" +COM_BANNERS_MANAGER_CLIENT_NEW="Banners: New Client" +COM_BANNERS_MANAGER_CLIENTS="Banners: Clients" +COM_BANNERS_MANAGER_TRACKS="Banners: Tracks" +COM_BANNERS_METADATA="Metadata" +COM_BANNERS_FIELD_MODIFIED_DESC="The date and time that the banner was last modified." +COM_BANNERS_N_BANNERS_STUCK="%d banners pinned." +COM_BANNERS_N_BANNERS_STUCK_1="%d banner pinned." +COM_BANNERS_N_BANNERS_UNSTUCK="%d banners unpinned." +COM_BANNERS_N_BANNERS_UNSTUCK_1="%d banner unpinned." +COM_BANNERS_NEW_BANNER="New Banner" +COM_BANNERS_NEW_CLIENT="New Client" +COM_BANNERS_NO_BANNERS_SELECTED="No banners selected." +COM_BANNERS_NO_CLIENT="- No client -" +COM_BANNERS_NO_CLIENTS_SELECTED="No clients selected." +COM_BANNERS_NOCATEGORYNAME="No category" +COM_BANNERS_NOCLIENTNAME="No client" +COM_BANNERS_RESET_CLICKS="Reset clicks" +COM_BANNERS_RESET_IMPMADE="Reset impressions" +COM_BANNERS_SEARCH_IN_TITLE="Search in title" +COM_BANNERS_SELECT_CLIENT="- Select Client -" +COM_BANNERS_SELECT_TYPE="- Select Type -" +COM_BANNERS_SUBMENU_BANNERS="Banners" +COM_BANNERS_SUBMENU_CATEGORIES="Categories" +COM_BANNERS_SUBMENU_CLIENTS="Clients" +COM_BANNERS_SUBMENU_TRACKS="Tracks" +COM_BANNERS_TRACKS_DELETE="Delete Tracks" +COM_BANNERS_TRACKS_DOWNLOAD="Download tracks" +COM_BANNERS_TRACKS_EXPORT="Export" +COM_BANNERS_TRACKS_FILTER_SEARCH_DESC="Search in track name and track client name." +COM_BANNERS_TRACKS_FILTER_SEARCH_LABEL="Search Tracks" +COM_BANNERS_TRACKS_NO_ITEMS_DELETED="No Tracks to Delete." +COM_BANNERS_TRACKS_N_ITEMS_DELETED="%d tracks deleted." +COM_BANNERS_TRACKS_N_ITEMS_DELETED_1="%d track deleted." +COM_BANNERS_TYPE1="Impressions" +COM_BANNERS_TYPE2="Clicks" +COM_BANNERS_UNLIMITED="Unlimited" +COM_BANNERS_XML_DESCRIPTION="This component manages banners and banner clients." +JLIB_RULES_SETTING_NOTES="Changes apply to this component only.
    Inherited - a Global Configuration setting or higher level setting is applied.
    Denied always wins - whatever is set at the Global or higher level and applies to all child elements.
    Allowed will enable the action for this component unless overruled by a Global Configuration setting." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.com_banners.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.com_banners.sys.ini new file mode 100644 index 00000000..e18f729f --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.com_banners.sys.ini @@ -0,0 +1,17 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +COM_BANNERS="Banners" +COM_BANNERS_BANNERS="Banners" +COM_BANNERS_CATEGORY_ADD_TITLE="Banners: Add Category" +COM_BANNERS_CATEGORY_EDIT_TITLE="Banners: Edit Category" +COM_BANNERS_CATEGORIES="Categories" +COM_BANNERS_CONTENT_TYPE_BANNER="Banner" +COM_BANNERS_CONTENT_TYPE_CLIENT="Banner Client" +COM_BANNERS_CONTENT_TYPE_CATEGORY="Banner Category" +COM_BANNERS_CLIENTS="Clients" +COM_BANNERS_TAGS_CATEGORY="Banner Category" +COM_BANNERS_TRACKS="Tracks" +COM_BANNERS_XML_DESCRIPTION="This component manages banners and banner clients." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.com_cache.ini b/Sites/pages/administrator/language/en-GB/en-GB.com_cache.ini new file mode 100644 index 00000000..a009ea2f --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.com_cache.ini @@ -0,0 +1,41 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +COM_CACHE="Cache" +COM_CACHE_BACK_CACHE_MANAGER="Return to Cache" +COM_CACHE_CLEAR_CACHE_ADMIN="Clear Cache Administrator" +COM_CACHE_CLEAR_CACHE="Maintenance: Clear Cache" +COM_CACHE_CLEAR_CACHE_ADMIN_TITLE="Maintenance: Clear Cache (Administrator)" +COM_CACHE_CLEAR_CACHE_SITE_TITLE="Maintenance: Clear Cache (Site)" +COM_CACHE_PURGE_EXPIRED_CACHE="Maintenance: Clear Expired Cache" +COM_CACHE_CONFIGURATION="Cache: Options" +COM_CACHE_ERROR_CACHE_CONNECTION_FAILED="Could not connect to the cache store to fetch the cache data." +COM_CACHE_ERROR_CACHE_DRIVER_UNSUPPORTED="Could not read the cache data, the configured cache handler is not supported by this environment." +COM_CACHE_EXPIRED_ITEMS_HAVE_BEEN_DELETED="The selected cache group(s) have been cleared." +COM_CACHE_EXPIRED_ITEMS_HAVE_BEEN_PURGED="Expired cached items have been cleared." +COM_CACHE_EXPIRED_ITEMS_DELETE_ERROR="Error clearing cache group(s): %s." +COM_CACHE_EXPIRED_ITEMS_PURGING_ERROR="Error clearing expired cached items." +COM_CACHE_FILTER_SEARCH_DESC="Search in cache group." +COM_CACHE_FILTER_SEARCH_LABEL="Search Cache" +COM_CACHE_GROUP="Cache Group" +COM_CACHE_HEADING_GROUP_ASC="Cache Group ascending" +COM_CACHE_HEADING_GROUP_DESC="Cache Group descending" +COM_CACHE_HEADING_COUNT_ASC="Number of Files ascending" +COM_CACHE_HEADING_COUNT_DESC="Number of Files descending" +COM_CACHE_HEADING_SIZE_ASC="Size ascending" +COM_CACHE_HEADING_SIZE_DESC="Size descending" +COM_CACHE_MANAGER="Cache" +COM_CACHE_MSG_ALL_CACHE_GROUPS_CLEARED="All cache group(s) have been cleared." +COM_CACHE_MSG_SOME_CACHE_GROUPS_CLEARED="Only some cache group(s) have been cleared." +COM_CACHE_NUMBER_OF_FILES="Number of Files" +COM_CACHE_PURGE_CACHE_ADMIN="Clear Cache Administrator" +COM_CACHE_PURGE_EXPIRED="Clear Expired Cache" +COM_CACHE_PURGE_EXPIRED_ITEMS="Clear expired items" +COM_CACHE_PURGE_INSTRUCTIONS="Select the Clear Expired Cache icon in the toolbar to delete all expired cache files. Note: Cache files that are still current will not be deleted." +COM_CACHE_RESOURCE_INTENSIVE_WARNING="This can be resource intensive on sites with a large number of items!" +COM_CACHE_SIZE="Size" +COM_CACHE_SELECT_CLIENT="- Select Location -" +COM_CACHE_XML_DESCRIPTION="Component for cache management." +JLIB_RULES_SETTING_NOTES="Changes apply to this component only.
    Inherited - a Global Configuration setting or higher level setting is applied.
    Denied always wins - whatever is set at the Global or higher level and applies to all child elements.
    Allowed will enable the action for this component unless overruled by a Global Configuration setting." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.com_cache.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.com_cache.sys.ini new file mode 100644 index 00000000..96ccfd42 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.com_cache.sys.ini @@ -0,0 +1,11 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +COM_CACHE="Cache" +COM_CACHE_CACHE_VIEW_DEFAULT_DESC="Maintenance: Clear Cache" +COM_CACHE_CACHE_VIEW_DEFAULT_TITLE="Clear Cache" +COM_CACHE_PURGE_VIEW_DEFAULT_DESC="Maintenance: Clear Expired Cache" +COM_CACHE_PURGE_VIEW_DEFAULT_TITLE="Clear Expired Cache" +COM_CACHE_XML_DESCRIPTION="Component for cache management." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.com_categories.ini b/Sites/pages/administrator/language/en-GB/en-GB.com_categories.ini new file mode 100644 index 00000000..41f60e03 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.com_categories.ini @@ -0,0 +1,87 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +CATEGORIES_FIELDSET_OPTIONS="Options" +COM_CATEGORIES="Categories" +COM_CATEGORIES_ACCESS_CREATE_DESC="New setting for create actions in this category and the calculated setting based on the parent category and group permissions." +COM_CATEGORIES_ACCESS_DELETE_DESC="New setting for delete actions on this category and the calculated setting based on the parent category and group permissions." +COM_CATEGORIES_ACCESS_EDIT_DESC="New setting for edit actions on this category and the calculated setting based on the parent category and group permissions." +COM_CATEGORIES_ACCESS_EDITOWN_DESC="New setting for edit own actions on this category and the calculated setting based on the parent category and group permissions." +COM_CATEGORIES_ACCESS_EDITSTATE_DESC="New setting for edit state actions on this category and the calculated setting based on the parent category and group permissions." +COM_CATEGORIES_BASIC_FIELDSET_LABEL="Options" +COM_CATEGORIES_BATCH_CANNOT_CREATE="You are not allowed to create new categories in this category." +COM_CATEGORIES_BATCH_CANNOT_EDIT="You are not allowed to edit one or more of these categories." +; COM_CATEGORIES_BATCH_CATEGORY_LABEL is deprecated, use JLIB_HTML_BATCH_MENU_LABEL instead. +COM_CATEGORIES_BATCH_CATEGORY_LABEL="To Move or Copy your selection please select a Category." +COM_CATEGORIES_BATCH_OPTIONS="Batch process the selected categories." +COM_CATEGORIES_BATCH_TIP="If a category is selected for move/copy, any actions selected will be applied to the copied or moved categories. Otherwise, all actions are applied to the selected categories." +COM_CATEGORIES_CATEGORIES_BASE_TITLE="Categories" +COM_CATEGORIES_CATEGORIES_TITLE="%s: Categories" +COM_CATEGORIES_CATEGORY_ADD_TITLE="%s: New Category" +COM_CATEGORIES_CATEGORY_BASE_ADD_TITLE="Categories: New Category" +COM_CATEGORIES_CATEGORY_BASE_EDIT_TITLE="Categories: Edit Category" +COM_CATEGORIES_CATEGORY_EDIT_TITLE="%s: Edit Category" +COM_CATEGORIES_CATEGORY_OPTIONS="Category" +COM_CATEGORIES_CHANGE_CATEGORY="Select or Change Category" +COM_CATEGORIES_DELETE_NOT_ALLOWED="Delete not allowed for category %s." +COM_CATEGORIES_DESCRIPTION_DESC="Enter an optional category description in the text area." +COM_CATEGORIES_EDIT_CATEGORY="Edit Category" +COM_CATEGORIES_ERROR_ALL_LANGUAGE_ASSOCIATED="A category item set to All languages can't be associated. Associations have not been set." +COM_CATEGORIES_FIELD_BASIC_LABEL="Options" +COM_CATEGORIES_FIELD_HITS_DESC="Number of hits for this category." +COM_CATEGORIES_FIELD_IMAGE_ALT_LABEL="Alt Text" +COM_CATEGORIES_FIELD_IMAGE_ALT_DESC="Alternative text used for visitors without access to images." +COM_CATEGORIES_FIELD_IMAGE_DESC="Select or upload an image for this category." +COM_CATEGORIES_FIELD_IMAGE_LABEL="Image" +COM_CATEGORIES_FIELD_LANGUAGE_DESC="Assign a language to this category." +COM_CATEGORIES_FIELD_NOTE_DESC="An optional note to display in the category list." +COM_CATEGORIES_FIELD_NOTE_LABEL="Note" +COM_CATEGORIES_FIELD_PARENT_DESC="Select a parent category." +COM_CATEGORIES_FIELD_PARENT_LABEL="Parent" +COM_CATEGORIES_FIELDSET_DETAILS="Category Details" +COM_CATEGORIES_FIELDSET_PUBLISHING="Publishing" +COM_CATEGORIES_FIELDSET_RULES="Permissions" +COM_CATEGORIES_FILTER_SEARCH_DESC="Search in title, alias and note. Prefix with ID: to search for a category ID." +COM_CATEGORIES_FILTER_SEARCH_LABEL="Search Categories" +COM_CATEGORIES_HAS_SUBCATEGORY_ITEMS="%d items are assigned to this category's subcategories." +COM_CATEGORIES_HAS_SUBCATEGORY_ITEMS_1="%d item is assigned to one of this category's subcategories." +; The following 2 strings are deprecated and will be removed with 4.0. +COM_CATEGORIES_ITEM_ASSOCIATIONS_FIELDSET_LABEL="Category Item Associations" +COM_CATEGORIES_ITEM_ASSOCIATIONS_FIELDSET_DESC="Multilingual only! This choice will only display if the Language Filter parameter 'Item Associations' is set to 'Yes'. Choose a category item for the target language. This association will let the Language Switcher module redirect to the associated category item in another language. If used, make sure to display the Language switcher module on the relevant pages. A category item set to language 'All' can't be associated." +COM_CATEGORIES_ITEMS_SEARCH_FILTER="Search" +COM_CATEGORIES_N_ITEMS_ARCHIVED="%d categories archived." +COM_CATEGORIES_N_ITEMS_ARCHIVED_1="%d category archived." +COM_CATEGORIES_N_ITEMS_ASSIGNED="%d items are assigned to this category." +COM_CATEGORIES_N_ITEMS_ASSIGNED_1="%d item is assigned to this category." +COM_CATEGORIES_N_ITEMS_CHECKED_IN_0="No category checked in." +COM_CATEGORIES_N_ITEMS_CHECKED_IN_1="%d category checked in." +COM_CATEGORIES_N_ITEMS_CHECKED_IN_MORE="%d categories checked in." +COM_CATEGORIES_N_ITEMS_DELETED="%d categories deleted." +COM_CATEGORIES_N_ITEMS_DELETED_1="%d category deleted." +COM_CATEGORIES_N_ITEMS_FAILED_PUBLISHING="Failed publishing %d categories as at least one of their parents is unpublished or one of their children is checked out." +COM_CATEGORIES_N_ITEMS_FAILED_PUBLISHING_1="Failed publishing %d category as at least one of its parents is unpublished or one of its children is checked out." +COM_CATEGORIES_N_ITEMS_PUBLISHED="%d categories published." +COM_CATEGORIES_N_ITEMS_PUBLISHED_1="%d category published." +COM_CATEGORIES_N_ITEMS_TRASHED="%d categories trashed." +COM_CATEGORIES_N_ITEMS_TRASHED_1="%d category trashed." +COM_CATEGORIES_N_ITEMS_UNPUBLISHED="%d categories unpublished." +COM_CATEGORIES_N_ITEMS_UNPUBLISHED_1="%d category unpublished." +COM_CATEGORIES_NEW_CATEGORY="New Category" +COM_CATEGORIES_NO_ITEM_SELECTED="Please first make a selection from the list." +COM_CATEGORIES_PATH_LABEL="Category Path" +COM_CATEGORIES_REBUILD_FAILURE="Failed rebuilding Categories tree data." +COM_CATEGORIES_REBUILD_SUCCESS="Categories tree data rebuilt." +COM_CATEGORIES_SAVE_SUCCESS="Category saved." +COM_CATEGORIES_SELECT_A_CATEGORY="Select a Category" +COM_CATEGORIES_TIP_ASSOCIATION="Associated categories" +COM_CATEGORIES_XML_DESCRIPTION="This component manages categories." +COM_CATEGORY_COUNT_ARCHIVED_ITEMS="Archived items" +COM_CATEGORY_COUNT_PUBLISHED_ITEMS="Published items" +COM_CATEGORY_COUNT_TRASHED_ITEMS="Trashed items" +COM_CATEGORY_COUNT_UNPUBLISHED_ITEMS="Unpublished items" +COM_CATEGORY_HEADING_ASSOCIATION="Association" +JGLOBAL_NO_ITEM_SELECTED="No categories selected." +JLIB_HTML_ACCESS_SUMMARY_DESC="Shown below is an overview of the permission settings for this category. Select the tabs above to customise these settings by action." +JLIB_RULES_SETTING_NOTES_ITEM="Changes apply to this category and all child categories.
    Inherited - a Global Configuration setting or higher level setting is applied.
    Denied always wins - whatever is set at the Global or higher level and applies to all child elements.
    Allowed will enable the action for this component unless overruled by a Global Configuration setting." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.com_categories.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.com_categories.sys.ini new file mode 100644 index 00000000..9723c08a --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.com_categories.sys.ini @@ -0,0 +1,13 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +COM_CATEGORIES="Categories" +COM_CATEGORIES_CATEGORIES_VIEW_DEFAULT_DESC="Shows a List of All categories in the selected component." +COM_CATEGORIES_CATEGORIES_VIEW_DEFAULT_TITLE="List All Categories" +COM_CATEGORIES_CATEGORY_VIEW_EDIT_DESC="Create a new Category in the selected component." +COM_CATEGORIES_CATEGORY_VIEW_EDIT_TITLE="Create New Category" +COM_CATEGORIES_CHOOSE_COMPONENT_DESC="Select a component to which this category should be linked.
    If a component using categories is not shown in the list, please create at least one category for it using the default regular menu." +COM_CATEGORIES_CHOOSE_COMPONENT_LABEL="Choose a Component" +COM_CATEGORIES_XML_DESCRIPTION="This component manages categories." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.com_checkin.ini b/Sites/pages/administrator/language/en-GB/en-GB.com_checkin.ini new file mode 100644 index 00000000..a8396d9c --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.com_checkin.ini @@ -0,0 +1,23 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +COM_CHECKIN="Check-in" +COM_CHECKIN_CONFIGURATION="Check-in: Options" +COM_CHECKIN_DATABASE_TABLE="Database Table" +COM_CHECKIN_DATABASE_TABLE_ASC="Database Table ascending" +COM_CHECKIN_DATABASE_TABLE_DESC="Database Table descending" +COM_CHECKIN_FILTER_SEARCH_DESC="Search database tables with items to check-in." +COM_CHECKIN_FILTER_SEARCH_LABEL="Search Database Tables" +COM_CHECKIN_GLOBAL_CHECK_IN="Maintenance: Global Check-in" +COM_CHECKIN_ITEMS_TO_CHECK_IN="Items to check-in" +COM_CHECKIN_ITEMS_TO_CHECK_IN_ASC="Items to check-in ascending" +COM_CHECKIN_ITEMS_TO_CHECK_IN_DESC="Items to check-in descending" +COM_CHECKIN_N_ITEMS_CHECKED_IN_0="No item checked in." +COM_CHECKIN_N_ITEMS_CHECKED_IN_1="1 item checked in." +COM_CHECKIN_N_ITEMS_CHECKED_IN_MORE="%s items checked in." +COM_CHECKIN_NO_ITEMS="There are no tables with checked out items or there are no tables with checked out items that match your search." +COM_CHECKIN_TABLE="%s table" +COM_CHECKIN_XML_DESCRIPTION="Check-in Component." +JLIB_RULES_SETTING_NOTES="Changes apply to this component only.
    Inherited - a Global Configuration setting or higher level setting is applied.
    Denied always wins - whatever is set at the Global or higher level and applies to all child elements.
    Allowed will enable the action for this component unless overruled by a Global Configuration setting." \ No newline at end of file diff --git a/Sites/pages/administrator/language/en-GB/en-GB.com_checkin.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.com_checkin.sys.ini new file mode 100644 index 00000000..313da314 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.com_checkin.sys.ini @@ -0,0 +1,10 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +COM_CHECKIN="Check-in" +COM_CHECKIN_XML_DESCRIPTION="Check-in Component" + +COM_CHECKIN_CHECKIN_VIEW_DEFAULT_DESC="Shows a list of checked out items from all components/tables." +COM_CHECKIN_CHECKIN_VIEW_DEFAULT_TITLE="Global Check-in" diff --git a/Sites/pages/administrator/language/en-GB/en-GB.com_config.ini b/Sites/pages/administrator/language/en-GB/en-GB.com_config.ini new file mode 100644 index 00000000..bc5a35a2 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.com_config.ini @@ -0,0 +1,275 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +COM_CONFIG="Configuration" +COM_CONFIG_ACTION_ADMIN_DESC="Allows users in the group to perform any action over the whole site regardless of any other permission settings." +COM_CONFIG_ACTION_CREATE_DESC="Allows users in the group to create any content in any extension." +COM_CONFIG_ACTION_DELETE_DESC="Allows users in the group to delete any content in any extension." +COM_CONFIG_ACTION_EDIT_DESC="Allows users in the group to edit any content in any extension." +COM_CONFIG_ACTION_EDITOWN_DESC="Allows users in the group to edit any content they own in any extension." +COM_CONFIG_ACTION_EDITVALUE_DESC="Allows users in the group to edit any value of custom fields submitted in any extension." +COM_CONFIG_ACTION_EDITSTATE_DESC="Allows users in the group to edit the state of any content in any extension." +COM_CONFIG_ACTION_LOGIN_ADMIN_DESC="Allows users in the group to login to the Backend Administrator site." +COM_CONFIG_ACTION_LOGIN_OFFLINE_DESC="Allows users in the group to access the Frontend site when site is offline." +COM_CONFIG_ACTION_LOGIN_SITE_DESC="Allows users in the group to login to the Frontend site." +COM_CONFIG_ACTION_MANAGE_DESC="Allows users in the group to access all of the administration interface except Global Configuration." +COM_CONFIG_ACTION_OPTIONS_DESC="Allows users in the group to edit the options except the permissions of any extension." +COM_CONFIG_CACHE_SETTINGS="Cache Settings" +COM_CONFIG_CACHE_WARNING="Failed to clear cache automatically, you may need to do so manually." +COM_CONFIG_COMPONENT_FIELDSET_LABEL="Component" +COM_CONFIG_COMPONENT_NO_CONFIG_FIELDS_MESSAGE="This component has no configuration options." +COM_CONFIG_COOKIE_SETTINGS="Cookie Settings" +COM_CONFIG_DATABASE_SETTINGS="Database Settings" +COM_CONFIG_DEBUG_SETTINGS="Debug Settings" +COM_CONFIG_ERROR_CACHE_PATH_NOTWRITABLE="The cache folder is not writable: %s" +COM_CONFIG_ERROR_CACHE_CONNECTION_FAILED="Could not connect to the cache handler to clean the cache." +COM_CONFIG_ERROR_CACHE_DRIVER_UNSUPPORTED="Could not clean the cache, the configured cache handler is not supported by this environment." +COM_CONFIG_ERROR_COMPONENT_ASSET_NOT_FOUND="The asset for the component could not be found. Permissions have not been saved." +COM_CONFIG_ERROR_CONFIG_EXTENSION_NOT_FOUND="The Global Configuration extension could not be found. Text filter settings have not been saved." +COM_CONFIG_ERROR_CONFIGURATION_PHP_NOTUNWRITABLE="Could not make configuration.php unwritable." +COM_CONFIG_ERROR_CONFIGURATION_PHP_NOTWRITABLE="Could not make configuration.php writable." +COM_CONFIG_ERROR_CUSTOM_CACHE_PATH_NOTWRITABLE_USING_DEFAULT="The folder at %1$s is not writable and cannot be used for the cache, using the default %2$s instead." +; The following 2 strings are deprecated and will be removed with 4.0. +COM_CONFIG_ERROR_HELPREFRESH_ERROR_STORE="The new Help Sites list could not be saved." +COM_CONFIG_ERROR_HELPREFRESH_FETCH="The current Help Sites list could not be fetched from the remote server." +COM_CONFIG_ERROR_ROOT_ASSET_NOT_FOUND="The asset for global configuration could not be found. Permissions have not been saved." +COM_CONFIG_ERROR_SSL_NOT_AVAILABLE="HTTPS has not been enabled as it is not available on this server. HTTPS connection test failed with the following error: %s" +COM_CONFIG_ERROR_SSL_NOT_AVAILABLE_HTTP_CODE="HTTPS version of the site returned an invalid HTTP status code." +COM_CONFIG_ERROR_REMOVING_SUPER_ADMIN="You can't remove your own Super User permissions." +COM_CONFIG_ERROR_UNKNOWN_BEFORE_SAVING="A plugin reported an unknown error before saving the configuration." +COM_CONFIG_ERROR_WRITE_FAILED="Could not write to the configuration file" +COM_CONFIG_FIELD_CACHE_HANDLER_DESC="Choose the cache handler. Native caching mechanism is file-based. Please make sure the cache folders are writable." +COM_CONFIG_FIELD_CACHE_HANDLER_LABEL="Cache Handler" +COM_CONFIG_FIELD_CACHE_PLATFORMPREFIX_LABEL="Platform Specific Caching" +COM_CONFIG_FIELD_CACHE_PLATFORMPREFIX_DESC="Enable or disable platform specific caching. Enable when HTML output on mobile differs from other devices. (Default disabled.)" +COM_CONFIG_FIELD_CACHE_LABEL="System Cache" +COM_CONFIG_FIELD_CACHE_DESC="Enable or disable caching and set caching level. Conservative level: smaller system cache, Progressive level (default): faster, bigger system cache, includes module renderers cache. Not appropriate for extremely large sites." +COM_CONFIG_FIELD_CACHE_PATH_DESC="Please specify a writable folder to store cache files if you do not wish to use the default folder." +COM_CONFIG_FIELD_CACHE_PATH_LABEL="Path to Cache Folder" +COM_CONFIG_FIELD_CACHE_TIME_DESC="The maximum length of time in minutes for a cache file to be stored before it is refreshed." +COM_CONFIG_FIELD_CACHE_TIME_LABEL="Cache Time" +COM_CONFIG_FIELD_COOKIE_DOMAIN_DESC="Domain to use when setting session cookies. Precede domain with '.' if cookie should be valid for all subdomains." +COM_CONFIG_FIELD_COOKIE_DOMAIN_LABEL="Cookie Domain" +COM_CONFIG_FIELD_COOKIE_PATH_DESC="Path the cookie should be valid for." +COM_CONFIG_FIELD_COOKIE_PATH_LABEL="Cookie Path" +COM_CONFIG_FIELD_DATABASE_HOST_DESC="The hostname for your database entered during the installation process. Do not edit this field unless absolutely necessary (eg the transfer of the database to a new hosting provider)." +COM_CONFIG_FIELD_DATABASE_HOST_LABEL="Host" +COM_CONFIG_FIELD_DATABASE_NAME_DESC="The name for your database entered during the installation process. Do not edit this field unless absolutely necessary (eg the transfer of the database to a new hosting provider)." +COM_CONFIG_FIELD_DATABASE_NAME_LABEL="Database Name" +COM_CONFIG_FIELD_DATABASE_PASSWORD_DESC="The password for access to your database. Do not edit this field unless absolutely necessary (eg after the transfer of the database to a new hosting provider)." +COM_CONFIG_FIELD_DATABASE_PASSWORD_LABEL="Database Password" +COM_CONFIG_FIELD_DATABASE_PREFIX_DESC="The prefix used for your database tables, created during the installation process. Do not edit this field unless absolutely necessary (eg the transfer of the database to a new hosting provider)." +COM_CONFIG_FIELD_DATABASE_PREFIX_LABEL="Database Tables Prefix" +COM_CONFIG_FIELD_DATABASE_TYPE_DESC="The type of database in use, selected during the installation process. Do not edit this field unless you are migrating to a different type of database, perhaps due to changing your hosting provider." +COM_CONFIG_FIELD_DATABASE_TYPE_LABEL="Database Type" +COM_CONFIG_FIELD_DATABASE_USERNAME_DESC="The username for access to your database entered during the installation process. Do not edit this field unless absolutely necessary (eg the transfer of the database to a new hosting provider)." +COM_CONFIG_FIELD_DATABASE_USERNAME_LABEL="Database Username" +COM_CONFIG_FIELD_DEBUG_CONST="Constant" +COM_CONFIG_FIELD_DEBUG_CONST_LANG_DESC="Select if you should display the language constant or the language value when debugging the language strings." +COM_CONFIG_FIELD_DEBUG_CONST_LANG_LABEL="Language Display" +COM_CONFIG_FIELD_DEBUG_LANG_DESC="Select if the debugging indicators (** ... **) or (?? ... ??) for the Joomla Language files will be displayed. Debug Language will work without Debug System being activated, but you will not get the additional detailed references that will help you correct any errors." +COM_CONFIG_FIELD_DEBUG_LANG_LABEL="Debug Language" +COM_CONFIG_FIELD_DEBUG_SYSTEM_DESC="If enabled, diagnostic information, language translation and SQL errors (if present) will be displayed. The information will be displayed at the foot of every page you view within the Joomla Backend and Frontend. It is not advisable to leave the debug mode activated when running a live website." +COM_CONFIG_FIELD_DEBUG_SYSTEM_LABEL="Debug System" +COM_CONFIG_FIELD_DEBUG_VALUE="Value" +COM_CONFIG_FIELD_DEFAULT_ACCESS_LEVEL_DESC="Select the default access level for new content, menu items and other items created on your site." +COM_CONFIG_FIELD_DEFAULT_ACCESS_LEVEL_LABEL="Default Access Level" +COM_CONFIG_FIELD_DEFAULT_EDITOR_DESC="Select the default text editor for your site. Registered Users will be able to change their preference in their personal details if you allow that option." +COM_CONFIG_FIELD_DEFAULT_EDITOR_LABEL="Default Editor" +COM_CONFIG_FIELD_DEFAULT_CAPTCHA_DESC="Select the default captcha for your site. You may need to enter required information for your captcha plugin in the Plugin Manager." +COM_CONFIG_FIELD_DEFAULT_CAPTCHA_LABEL="Default Captcha" +COM_CONFIG_FIELD_DEFAULT_FEED_LIMIT_DESC="Select the number of content items to show in the feed(s)." +COM_CONFIG_FIELD_DEFAULT_FEED_LIMIT_LABEL="Default Feed Limit" +COM_CONFIG_FIELD_DEFAULT_LIST_LIMIT_DESC="Sets the default length of lists in the Control Panel for all users." +COM_CONFIG_FIELD_DEFAULT_LIST_LIMIT_LABEL="Default List Limit" +COM_CONFIG_FIELD_ERROR_REPORTING_DESC="Select the level of reporting. See the Help Screen for full details." +COM_CONFIG_FIELD_ERROR_REPORTING_LABEL="Error Reporting" +COM_CONFIG_FIELD_FEED_EMAIL_DESC="The RSS and Atom news feeds include the author's email address. Select Author Email Address to use each author's email address (from the User Manager) in the news feed. Select Site Email Address to include the site 'Mail from' email address for each article." +COM_CONFIG_FIELD_FEED_EMAIL_LABEL="Feed Email Address" +COM_CONFIG_FIELD_FILTERS_DEFAULT_BLACK_LIST="Default Blacklist" +COM_CONFIG_FIELD_FILTERS_CUSTOM_BLACK_LIST="Custom Blacklist" +COM_CONFIG_FIELD_FILTERS_NO_HTML="No HTML" +COM_CONFIG_FIELD_FILTERS_NO_FILTER="No Filtering" +COM_CONFIG_FIELD_FILTERS_WHITE_LIST="Whitelist" +COM_CONFIG_FRONTEDITING_DESC="Select if you want inline editing for modules and menu items (support may depend on your template)." +COM_CONFIG_FRONTEDITING_LABEL="Inline Editing" +COM_CONFIG_FRONTEDITING_MENUSANDMODULES="Modules & Menus" +COM_CONFIG_FRONTEDITING_MENUSANDMODULES_ADMIN_TOO="Modules & Menus (administrator too)" +COM_CONFIG_FRONTEDITING_MODULES="Modules" +COM_CONFIG_FIELD_FORCE_SSL_DESC="Force site access in the selected areas to occur only with HTTPS (encrypted HTTP connections with the https:// protocol prefix) and also force the use of secure cookies. Note, you must have HTTPS enabled on your server to utilise this option." +COM_CONFIG_FIELD_FORCE_SSL_LABEL="Force HTTPS" +COM_CONFIG_FIELD_FTP_ENABLE_DESC="Enable the built in FTP (File Transfer Protocol) functionality which is needed, in some server environments, instead of the normal upload functionality of Joomla." +COM_CONFIG_FIELD_FTP_ENABLE_LABEL="Enable FTP" +COM_CONFIG_FIELD_FTP_HOST_DESC="Enter the name of the host of your FTP server." +COM_CONFIG_FIELD_FTP_HOST_LABEL="FTP Host" +COM_CONFIG_FIELD_FTP_PASSWORD_DESC="Enter your FTP password." +COM_CONFIG_FIELD_FTP_PASSWORD_LABEL="FTP Password" +COM_CONFIG_FIELD_FTP_PORT_DESC="Enter the port that FTP should be accessed by. The default is port 21." +COM_CONFIG_FIELD_FTP_PORT_LABEL="FTP Port" +COM_CONFIG_FIELD_FTP_ROOT_DESC="The path to the root folder of the FTP server. The root folder is the base folder to which the FTP server is allowed access." +COM_CONFIG_FIELD_FTP_ROOT_LABEL="FTP Root" +COM_CONFIG_FIELD_FTP_USERNAME_DESC="The username used to access the FTP server." +COM_CONFIG_FIELD_FTP_USERNAME_LABEL="FTP Username" +COM_CONFIG_FIELD_GZIP_COMPRESSION_DESC="Compress buffered output if supported." +COM_CONFIG_FIELD_GZIP_COMPRESSION_LABEL="Gzip Page Compression" +; The following two strings are deprecated and will be removed with 4.0. +COM_CONFIG_FIELD_HELP_SERVER_DESC="Select the name of the help server from which your system will collect the help screen displays." +COM_CONFIG_FIELD_HELP_SERVER_LABEL="Help Server" +COM_CONFIG_FIELD_LOG_PATH_DESC="Please specify a folder to store log files." +COM_CONFIG_FIELD_LOG_PATH_LABEL="Path to Log Folder" +COM_CONFIG_FIELD_MAIL_FROM_EMAIL_DESC="The email address that will be used to send site email." +COM_CONFIG_FIELD_MAIL_FROM_EMAIL_LABEL="From Email" +COM_CONFIG_FIELD_MAIL_FROM_NAME_DESC="Text displayed in the header "From:" field when sending a site email. Usually the site name." +COM_CONFIG_FIELD_MAIL_FROM_NAME_LABEL="From Name" +COM_CONFIG_FIELD_MAIL_REPLY_TO_EMAIL_LABEL="Reply To Email" +COM_CONFIG_FIELD_MAIL_REPLY_TO_EMAIL_DESC="The email address that will be used to receive end user(s) reply" +COM_CONFIG_FIELD_MAIL_REPLY_TO_NAME_LABEL="Reply To Name" +COM_CONFIG_FIELD_MAIL_REPLY_TO_NAME_DESC="Text displayed in the header "To:" field when end user(s) replying to received email" +COM_CONFIG_FIELD_MAIL_MAILONLINE_DESC="Select Yes to turn on mail sending, select No to turn off mail sending. Warning: It is recommended to put the site offline when disabling the mail function!" +COM_CONFIG_FIELD_MAIL_MAILONLINE_LABEL="Send Mail" +COM_CONFIG_FIELD_MAIL_MASSMAILOFF_DESC="Select Yes to disable the Mass Mail Users function, select No to make it active." +COM_CONFIG_FIELD_MAIL_MASSMAILOFF_LABEL="Disable Mass Mail" +COM_CONFIG_FIELD_MAIL_MAILER_DESC="Select which mailer for the delivery of site email." +COM_CONFIG_FIELD_MAIL_MAILER_LABEL="Mailer" +COM_CONFIG_FIELD_MAIL_SENDMAIL_PATH_DESC="Enter the path to the sendmail program folder on the host server." +COM_CONFIG_FIELD_MAIL_SENDMAIL_PATH_LABEL="Sendmail Path" +COM_CONFIG_FIELD_MAIL_SMTP_AUTH_DESC="Select Yes if your SMTP Host requires SMTP Authentication." +COM_CONFIG_FIELD_MAIL_SMTP_AUTH_LABEL="SMTP Authentication" +COM_CONFIG_FIELD_MAIL_SMTP_HOST_DESC="Enter the name of the SMTP host." +COM_CONFIG_FIELD_MAIL_SMTP_HOST_LABEL="SMTP Host" +COM_CONFIG_FIELD_MAIL_SMTP_PASSWORD_DESC="Enter the password for the SMTP host." +COM_CONFIG_FIELD_MAIL_SMTP_PASSWORD_LABEL="SMTP Password" +COM_CONFIG_FIELD_MAIL_SMTP_PORT_DESC="Enter the port number of the SMTP server Joomla will use to send emails. Usually:
    - 25 when using an unsecure mail server
    - 465 when using a secure server with SMTPS
    - 25 or 587 when using a secure server with SMTP with STARTTLS extension." +COM_CONFIG_FIELD_MAIL_SMTP_PORT_LABEL="SMTP Port" +COM_CONFIG_FIELD_MAIL_SMTP_SECURE_DESC="Select the security model of the SMTP server Joomla will use to send emails.
    - None for no encryption
    - SSL/TLS for SMTPS (usually on port 465)
    - STARTTLS for SMTP with STARTTLS extension (usually on port 25 or port 587)" +COM_CONFIG_FIELD_MAIL_SMTP_SECURE_LABEL="SMTP Security" +COM_CONFIG_FIELD_MAIL_SMTP_USERNAME_DESC="Enter the username for access to the SMTP host." +COM_CONFIG_FIELD_MAIL_SMTP_USERNAME_LABEL="SMTP Username" +COM_CONFIG_FIELD_MEMCACHE_COMPRESSION_DESC="Memcache(d) compression." +COM_CONFIG_FIELD_MEMCACHE_COMPRESSION_LABEL="Memcache(d) Compression" +COM_CONFIG_FIELD_MEMCACHE_HOST_DESC="Memcache(d) server host." +COM_CONFIG_FIELD_MEMCACHE_HOST_LABEL="Memcache(d) Server Host" +COM_CONFIG_FIELD_MEMCACHE_PERSISTENT_DESC="Persistent Memcache(d)." +COM_CONFIG_FIELD_MEMCACHE_PERSISTENT_LABEL="Persistent Memcache(d)" +COM_CONFIG_FIELD_MEMCACHE_PORT_DESC="Memcache(d) server port." +COM_CONFIG_FIELD_MEMCACHE_PORT_LABEL="Memcache(d) Server Port" +COM_CONFIG_FIELD_REDIS_AUTH_DESC="Redis server authentication." +COM_CONFIG_FIELD_REDIS_AUTH_LABEL="Redis Server Authentication" +COM_CONFIG_FIELD_REDIS_DB_DESC="Redis database." +COM_CONFIG_FIELD_REDIS_DB_LABEL="Redis Database" +COM_CONFIG_FIELD_REDIS_HOST_DESC="Redis server host." +COM_CONFIG_FIELD_REDIS_HOST_LABEL="Redis Server Host" +COM_CONFIG_FIELD_REDIS_PERSISTENT_DESC="Persistent Redis." +COM_CONFIG_FIELD_REDIS_PERSISTENT_LABEL="Persistent Redis" +COM_CONFIG_FIELD_REDIS_PORT_DESC="Redis server port." +COM_CONFIG_FIELD_REDIS_PORT_LABEL="Redis Server Port" +COM_CONFIG_FIELD_METAAUTHOR_DESC="Show the author meta tag when viewing articles." +COM_CONFIG_FIELD_METAAUTHOR_LABEL="Show Author Meta Tag" +COM_CONFIG_FIELD_METADESC_DESC="Enter a description of the overall website that may be used by search engines. Generally, a maximum of 20 words is best." +COM_CONFIG_FIELD_METADESC_LABEL="Site Meta Description" +COM_CONFIG_FIELD_METAKEYS_DESC="Enter the keywords and phrases that best describe your website. Separate keywords and phrases with a comma." +COM_CONFIG_FIELD_METAKEYS_LABEL="Site Meta Keywords" +COM_CONFIG_FIELD_METALANGUAGE_DESC="Places the selected language in the metadata for the site." +COM_CONFIG_FIELD_METALANGUAGE_LABEL="Site Meta Language" +COM_CONFIG_FIELD_METAVERSION_LABEL="Show Joomla Version" +COM_CONFIG_FIELD_METAVERSION_DESC="Show the Joomla version number in the generator meta tag." +COM_CONFIG_FIELD_OFFLINE_IMAGE_DESC="Select or upload an optional image to be displayed on the default offline page. Make sure the image is less than 400px wide." +COM_CONFIG_FIELD_OFFLINE_IMAGE_LABEL="Offline Image" +COM_CONFIG_FIELD_OFFLINE_MESSAGE_DESC="The custom offline message will be used if the 'Offline Message' field is set to 'Use Custom Message'." +COM_CONFIG_FIELD_OFFLINE_MESSAGE_LABEL="Custom Message" +COM_CONFIG_FIELD_PROXY_ENABLE_DESC="Enable Joomla to use a proxy which is needed in some server environments to fetch URLs like in the Joomla Update component." +COM_CONFIG_FIELD_PROXY_ENABLE_LABEL="Enable Proxy" +COM_CONFIG_FIELD_PROXY_HOST_DESC="Enter the name of the host of your Proxy server." +COM_CONFIG_FIELD_PROXY_HOST_LABEL="Proxy Host" +COM_CONFIG_FIELD_PROXY_PASSWORD_DESC="Enter your Proxy password." +COM_CONFIG_FIELD_PROXY_PASSWORD_LABEL="Proxy Password" +COM_CONFIG_FIELD_PROXY_PORT_DESC="Enter the port that Proxy should be accessed by." +COM_CONFIG_FIELD_PROXY_PORT_LABEL="Proxy Port" +COM_CONFIG_FIELD_PROXY_USERNAME_DESC="The username used to access the Proxy server." +COM_CONFIG_FIELD_PROXY_USERNAME_LABEL="Proxy Username" +COM_CONFIG_FIELD_SECRET_DESC="This is an auto-generated, unique alphanumeric code for every Joomla installation. It is used for security functions." +COM_CONFIG_FIELD_SECRET_LABEL="Secret" +COM_CONFIG_FIELD_SEF_REWRITE_DESC="Select to use a server's rewrite engine to catch URLs that meet specific conditions and rewrite them as directed. Available for IIS 7 and Apache.
    Apache users only!
    Rename htaccess.txt to .htaccess before activating.
    IIS 7 users only!
    Rename web.config.txt to web.config and install IIS URL Rewrite Module before activating.
    " +COM_CONFIG_FIELD_SEF_REWRITE_LABEL="Use URL Rewriting" +COM_CONFIG_FIELD_SEF_SUFFIX_DESC="If yes, the system will add a suffix to the URL based on the document type." +COM_CONFIG_FIELD_SEF_SUFFIX_LABEL="Add Suffix to URL" +COM_CONFIG_FIELD_SEF_URL_DESC="Select if the URLs are optimised for Search Engines." +COM_CONFIG_FIELD_SEF_URL_LABEL="Search Engine Friendly URLs" +COM_CONFIG_FIELD_SERVER_TIMEZONE_DESC="Choose a city in the list to configure the date and time for display." +COM_CONFIG_FIELD_SERVER_TIMEZONE_LABEL="Website Time Zone" +COM_CONFIG_FIELD_SESSION_HANDLER_DESC="The mechanism by which Joomla identifies a User once they are connected to the website using non-persistent cookies.
    If 'PHP' is selected, the session.save_handler value from the PHP configuration will be used." +COM_CONFIG_FIELD_SESSION_HANDLER_LABEL="Session Handler" +COM_CONFIG_FIELD_SESSION_TIME_DESC="Auto log out a User after they have been inactive for the entered number of minutes. Do not set too high." +COM_CONFIG_FIELD_SESSION_TIME_LABEL="Session Lifetime" +COM_CONFIG_FIELD_SHARED_SESSION_DESC="When enabled, a user's session is shared between the frontend and administrator sections of the site. Note that changing this value will invalidate all existing sessions on the site. This is not available when the \"Force HTTPS\" option is set to \"Administrator Only\"." +COM_CONFIG_FIELD_SHARED_SESSION_LABEL="Shared Sessions" +COM_CONFIG_FIELD_SITE_DISPLAY_MESSAGE_DESC="Display or not a Frontend message when the site is offline. The custom offline message uses the value defined in the 'Custom message' field. The language offline message uses the value defined in the site language ini file." +COM_CONFIG_FIELD_SITE_DISPLAY_MESSAGE_LABEL="Offline Message" +COM_CONFIG_FIELD_SITE_NAME_DESC="Enter the name of your website. This will be used in various locations (eg the Backend browser title bar and Site Offline pages)." +COM_CONFIG_FIELD_SITE_NAME_LABEL="Site Name" +COM_CONFIG_FIELD_SITE_OFFLINE_DESC="Select if access to the Site Frontend is available. If Yes, the Frontend will display or not a message depending on the settings below." +COM_CONFIG_FIELD_SITE_OFFLINE_LABEL="Site Offline" +COM_CONFIG_FIELD_SITENAME_PAGETITLES_DESC="Begin or end all Page Titles with the site name (for example, My Site Name - My Article Name)." +COM_CONFIG_FIELD_SITENAME_PAGETITLES_LABEL="Site Name in Page Titles" +COM_CONFIG_FIELD_TEMP_PATH_DESC="Please specify a writable folder to store temporary files." +COM_CONFIG_FIELD_TEMP_PATH_LABEL="Path to Temp Folder" +COM_CONFIG_FIELD_UNICODESLUGS_DESC="Choose between transliteration and unicode aliases. Transliteration is the default." +COM_CONFIG_FIELD_UNICODESLUGS_LABEL="Unicode Aliases" +COM_CONFIG_FIELD_VALUE_ADMINISTRATOR_ONLY="Administrator Only" +COM_CONFIG_FIELD_VALUE_AFTER="After" +COM_CONFIG_FIELD_VALUE_AUTHOR_EMAIL="Author Email" +COM_CONFIG_FIELD_VALUE_BEFORE="Before" +COM_CONFIG_FIELD_VALUE_CACHE_OFF="OFF - Caching disabled" +COM_CONFIG_FIELD_VALUE_CACHE_CONSERVATIVE="ON - Conservative caching" +COM_CONFIG_FIELD_VALUE_CACHE_PROGRESSIVE="ON - Progressive caching" +COM_CONFIG_FIELD_VALUE_DEVELOPMENT="Development" +COM_CONFIG_FIELD_VALUE_DISPLAY_OFFLINE_MESSAGE_CUSTOM="Use Custom Message" +COM_CONFIG_FIELD_VALUE_DISPLAY_OFFLINE_MESSAGE_LANGUAGE="Use Site Language Default Message" +COM_CONFIG_FIELD_VALUE_ENTIRE_SITE="Entire Site" +COM_CONFIG_FIELD_VALUE_MAXIMUM="Maximum" +COM_CONFIG_FIELD_VALUE_NO_EMAIL="No Email" +COM_CONFIG_FIELD_VALUE_NONE="None" +COM_CONFIG_FIELD_VALUE_PHP_MAIL="PHP Mail" +COM_CONFIG_FIELD_VALUE_SENDMAIL="Sendmail" +COM_CONFIG_FIELD_VALUE_SIMPLE="Simple" +COM_CONFIG_FIELD_VALUE_SITE_EMAIL="Site Email" +COM_CONFIG_FIELD_VALUE_SMTP="SMTP" +COM_CONFIG_FIELD_VALUE_SSL="SSL/TLS" +COM_CONFIG_FIELD_VALUE_SYSTEM_DEFAULT="System Default" +COM_CONFIG_FIELD_VALUE_TLS="STARTTLS" +COM_CONFIG_FTP_DETAILS="FTP Login Details" +COM_CONFIG_FTP_DETAILS_TIP="For updating your configuration.php file, Joomla will most likely need your FTP account details. Please enter them in the form fields below." +COM_CONFIG_FTP_SETTINGS="FTP Settings" +COM_CONFIG_GLOBAL_CONFIGURATION="Global Configuration" +COM_CONFIG_HELPREFRESH_SUCCESS="The Help Sites list has been refreshed." +COM_CONFIG_LOCATION_SETTINGS="Location Settings" +COM_CONFIG_MAIL_SETTINGS="Mail Settings" +COM_CONFIG_METADATA_SETTINGS="Metadata Settings" +COM_CONFIG_PERMISSION_SETTINGS="Permission Settings" +COM_CONFIG_PERMISSIONS="Permissions" +COM_CONFIG_PROXY_SETTINGS="Proxy Settings" +COM_CONFIG_SAVE_SUCCESS="Configuration saved." +COM_CONFIG_SENDMAIL_ACTION_BUTTON="Send Test Mail" +COM_CONFIG_SENDMAIL_BODY="This is a test mail sent using "_QQ_"%s"_QQ_". Your email settings are correct!" +COM_CONFIG_SENDMAIL_ERROR="Test mail could not be sent." +COM_CONFIG_SENDMAIL_METHOD_MAIL="PHP Mail" +COM_CONFIG_SENDMAIL_METHOD_SENDMAIL="Sendmail" +COM_CONFIG_SENDMAIL_METHOD_SMTP="SMTP" +COM_CONFIG_SENDMAIL_SUBJECT="Test mail from %s" +COM_CONFIG_SENDMAIL_SUCCESS="The email was sent to %s using %s. You should check that you've received the test email." +COM_CONFIG_SENDMAIL_SUCCESS_FALLBACK="The email was sent to %s but using %s as fallback. You should check that you've received the test email." +COM_CONFIG_SEO_SETTINGS="SEO Settings" +COM_CONFIG_SERVER="Server" +COM_CONFIG_SERVER_SETTINGS="Server Settings" +COM_CONFIG_SESSION_SETTINGS="Session Settings" +COM_CONFIG_SITE_SETTINGS="Site Settings" +COM_CONFIG_SYSTEM="System" +COM_CONFIG_SYSTEM_SETTINGS="System Settings" +COM_CONFIG_TEXT_FILTER_SETTINGS="Text Filter Settings" +COM_CONFIG_TEXT_FILTERS="Text Filters" +COM_CONFIG_TEXT_FILTERS_DESC="These text filter settings will be applied to all text editor fields in the selected groups.
    These filtering options give more control over the HTML your content providers submit. You can be as strict or as liberal as you require to suit your site's needs. The filtering is opt-in and the default settings provide good protection against markup commonly associated with website attacks." +COM_CONFIG_TEXT_FILTERS_NOTE="WARNING: You have configured a parent group with the setting 'No Filtering' - this setting can't be overridden in child groups and any other configured filter will not be applied." +COM_CONFIG_XML_DESCRIPTION="Configuration Manager" +JLIB_RULES_SETTING_NOTES="If you change the setting, it will apply to this and all child groups, components and content. Note that:
    Inherited means that the permissions from the parent group will be used.
    Denied means that no matter what the parent group's setting is, the group being edited can't take this action.
    Allowed means that the group being edited will be able to take this action (but if this is in conflict with the parent group it will have no impact; a conflict will be indicated by Not Allowed (Locked) under Calculated Settings).
    Not Set is used only for the Public group in global configuration. The Public group is the parent of all other groups. If a permission is not set, it is treated as deny but can be changed for child groups, components, categories and items." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.com_config.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.com_config.sys.ini new file mode 100644 index 00000000..c6bf028c --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.com_config.sys.ini @@ -0,0 +1,14 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +COM_CONFIG="Configuration" +COM_CONFIG_XML_DESCRIPTION="Configuration Manager" + +COM_CONFIG_COMPONENT_VIEW_DEFAULT_DESC="Display the configuration options for the selected component." +COM_CONFIG_COMPONENT_VIEW_DEFAULT_TITLE="Component Configuration Options" +COM_CONFIG_CONFIG_VIEW_DEFAULT_DESC="Displays global site configuration options." +COM_CONFIG_CONFIG_VIEW_DEFAULT_TITLE="Site Configuration Options" +COM_CONFIG_TEMPLATES_VIEW_DEFAULT_DESC="Displays template parameter options if the template allows this." +COM_CONFIG_TEMPLATES_VIEW_DEFAULT_TITLE="Display Template Options" diff --git a/Sites/pages/administrator/language/en-GB/en-GB.com_contact.ini b/Sites/pages/administrator/language/en-GB/en-GB.com_contact.ini new file mode 100644 index 00000000..40cec0fb --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.com_contact.ini @@ -0,0 +1,316 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +COM_CONTACT="Contacts" +COM_CONTACT_BASIC_OPTIONS_FIELDSET_LABEL="Contact Display Options" +; COM_CONTACT_BATCH_MENU_LABEL is deprecated, use JLIB_HTML_BATCH_MENU_LABEL instead. +COM_CONTACT_BATCH_MENU_LABEL="To Move or Copy your selection please select a Category." +COM_CONTACT_BATCH_OPTIONS="Batch process the selected contacts" +COM_CONTACT_BATCH_TIP="If a category is selected for move/copy, any actions selected will be applied to the copied or moved contacts. Otherwise, all actions are applied to the selected contacts." +COM_CONTACT_CATEGORIES_VIEW_DEFAULT_DESC="Shows a list of contact categories within a category." +COM_CONTACT_CATEGORY_VIEW_DEFAULT_DESC="This view lists the contacts in a category." +COM_CONTACT_CHANGE_CONTACT="Select or Change Contact" +; COM_CONTACT_CHANGE_CONTACT_BUTTON deprecated, use COM_CONTACT_CHANGE_CONTACT instead. +COM_CONTACT_CHANGE_CONTACT_BUTTON="Change Contact" +COM_CONTACT_CONFIG_INTEGRATION_SETTINGS_DESC="These settings determine how the Contact Component will integrate with other extensions." +COM_CONTACT_CONFIGURATION="Contacts: Options" +COM_CONTACT_CONTACT_DETAILS="Details" +COM_CONTACT_CONTACT_DISPLAY_DETAILS="Display options for the individual contact page." +COM_CONTACT_CONTACT_SETTINGS_LABEL="Contact Options" +COM_CONTACT_CONTACT_VIEW_DEFAULT_DESC="This links to the contact information for one contact." +COM_CONTACT_CONTACTS="Contacts" +COM_CONTACT_DETAILS="Contact Information" +COM_CONTACT_EDIT_CONTACT="Edit Contact" +COM_CONTACT_EDIT_DETAILS="Edit contact information displayed on an individual page." +COM_CONTACT_ERROR_UNIQUE_ALIAS="Another Contact from this category has the same alias (remember it may be a trashed item)." +COM_CONTACT_ERROR_ALL_LANGUAGE_ASSOCIATED="A contact item set to All languages can't be associated. Associations have not been set." +COM_CONTACT_FIELD_ARTICLES_DISPLAY_NUM_DESC="Number of articles to list." +COM_CONTACT_FIELD_ARTICLES_DISPLAY_NUM_LABEL="# Articles to List" +COM_CONTACT_FIELD_ARTICLES_SHOW_DESC="If this contact is mapped to a user, and if this is set to Show, then a list of articles created by this user will show." +COM_CONTACT_FIELD_ARTICLES_SHOW_LABEL="Show User Articles" +COM_CONTACT_FIELD_BREADCRUMBS_DESC="Show or hide category breadcrumbs." +COM_CONTACT_FIELD_BREADCRUMBS_LABEL="Show Category Breadcrumbs" +COM_CONTACT_FIELD_CAPTCHA_DESC="Select the captcha plugin that will be used in the contact form. You may need to enter required information for your captcha plugin in the Plugin Manager.
    If 'Use Global' is selected, make sure a captcha plugin is selected in Global Configuration." +COM_CONTACT_FIELD_CAPTCHA_LABEL="Allow Captcha on Contact" +COM_CONTACT_FIELD_CATEGORIES_DESC="Displays a list of contact categories within a category." +COM_CONTACT_FIELD_CATEGORIES_LABEL="Choose a Parent Category" +COM_CONTACT_FIELD_CATEGORY_DESC="Select a contact category to display." +COM_CONTACT_FIELD_CATEGORY_LABEL="Select a Category" +COM_CONTACT_FIELD_CONFIG_ALLOW_VCARD_DESC="Allow vCard to be displayed." +COM_CONTACT_FIELD_CONFIG_ALLOW_VCARD_LABEL="Allow vCard" +COM_CONTACT_FIELD_CONFIG_BANNED_EMAIL_DESC="Email addresses not allowed to submit contact form. Separate multiple email addresses with a semicolon." +COM_CONTACT_FIELD_CONFIG_BANNED_EMAIL_LABEL="Banned Email" +COM_CONTACT_FIELD_CONFIG_BANNED_SUBJECT_DESC="Subjects not allowed in contact form. Separate multiple subjects with a semicolon." +COM_CONTACT_FIELD_CONFIG_BANNED_SUBJECT_LABEL="Banned Subject" +COM_CONTACT_FIELD_CONFIG_BANNED_TEXT_DESC="Text not allowed in contact form body. Separate multiple words with a semicolon." +COM_CONTACT_FIELD_CONFIG_BANNED_TEXT_LABEL="Banned Text" +COM_CONTACT_FIELD_CONFIG_CATEGORIES_DESC="These settings apply for Contact Categories Options unless they are changed for a specific menu item." +COM_CONTACT_FIELD_CONFIG_CATEGORY_DESC="These settings apply for Contact Category Options unless they are changed for a specific menu item." +COM_CONTACT_FIELD_CONFIG_CONTACT_FORM="Form" +COM_CONTACT_FIELD_CONFIG_COUNTRY_DESC="Show or hide a Country column in the list of Contacts." +COM_CONTACT_FIELD_CONFIG_COUNTRY_LABEL="Country" +COM_CONTACT_FIELD_CONFIG_CUSTOM_REPLY_DESC="Turns off the automated reply, allowing for Plugins to handle integration with other systems." +COM_CONTACT_FIELD_CONFIG_CUSTOM_REPLY_LABEL="Custom Reply" +COM_CONTACT_FIELD_CONFIG_EMAIL_DESC="Show or hide an Email column in the list of Contacts." +COM_CONTACT_FIELD_CONFIG_FAX_DESC="Show or hide a Fax column in the list of Contacts." +COM_CONTACT_FIELD_CONFIG_FAX_LABEL="Fax" +COM_CONTACT_FIELD_CONFIG_INDIVIDUAL_CONTACT_DESC="These settings apply for single Contact unless they are changed for a specific menu item or Contact." +COM_CONTACT_FIELD_CONFIG_INDIVIDUAL_CONTACT_DISPLAY="Contact" +COM_CONTACT_FIELD_CONFIG_SHOW_IMAGE_LABEL="Image" +COM_CONTACT_FIELD_CONFIG_SHOW_IMAGE_DESC="Show or hide an Image column in the list of Contacts." +COM_CONTACT_FIELD_CONFIG_MOBILE_DESC="Show or hide show a Mobile column in the list of Contacts." +COM_CONTACT_FIELD_CONFIG_MOBILE_LABEL="Mobile" +COM_CONTACT_FIELD_CONFIG_PHONE_DESC="Show or hide a Phone column in the list of Contacts." +COM_CONTACT_FIELD_CONFIG_PHONE_LABEL="Phone" +COM_CONTACT_FIELD_CONFIG_POSITION_DESC="Show or hide a Position column in the list of Contacts." +COM_CONTACT_FIELD_CONFIG_POSITION_LABEL="Position" +COM_CONTACT_FIELD_CONFIG_REDIRECT_DESC="Enter an alternative URL where the user will be redirected to after mail is sent." +COM_CONTACT_FIELD_CONFIG_REDIRECT_LABEL="Contact Redirect" +COM_CONTACT_FIELD_CONFIG_SESSION_CHECK_DESC="Check for the existence of session cookie. This means that users without cookies enabled will not be able to send emails." +COM_CONTACT_FIELD_CONFIG_SESSION_CHECK_LABEL="Session Check" +COM_CONTACT_FIELD_CONFIG_STATE_LABEL="State or County" +COM_CONTACT_FIELD_CONFIG_STATE_DESC="Show or hide a State or County column in the list of Contacts." +COM_CONTACT_FIELD_CONFIG_SUBURB_DESC="Show or hide a City or Suburb column in the list of Contacts." +COM_CONTACT_FIELD_CONFIG_SUBURB_LABEL="City or Suburb" +COM_CONTACT_FIELD_CONFIG_TABLE_OF_CONTACTS_DESC="These settings apply for Contact List Options unless they are changed for a specific menu item." +COM_CONTACT_FIELD_CONFIG_VCARD_DESC="Show or hide a vCard column in the list of Contacts." +COM_CONTACT_FIELD_CONFIG_VCARD_LABEL="vCard" +COM_CONTACT_FIELD_CONTACT_SHOW_CATEGORY_DESC="If "Hide", the Contact Category will not show. If "Show Without Link", Category will show as text. If "Show With Link", Category will show as a link to a Single Category Menu Item." +COM_CONTACT_FIELD_CONTACT_SHOW_CATEGORY_LABEL="Contact Category" +COM_CONTACT_FIELD_CONTACT_SHOW_LIST_DESC="If Show, the user will be able to change which contact is shown by selecting a contact from a dropdown list of all contacts in the current contact category." +COM_CONTACT_FIELD_CONTACT_SHOW_LIST_LABEL="Show Contact List" +COM_CONTACT_FIELD_CREATED_BY_ALIAS_DESC="Enter an alias to be displayed instead of the name of the user who created the contact." +COM_CONTACT_FIELD_CREATED_BY_ALIAS_LABEL="Created By Alias" +COM_CONTACT_FIELD_CREATED_BY_DESC="Select the name of the user who created the contact." +COM_CONTACT_FIELD_CREATED_DESC="Date when the contact was created." +COM_CONTACT_FIELD_CREATED_LABEL="Created Date" +; The following six strings are deprecated and will be removed in 4.0 +COM_CONTACT_FIELD_EMAIL_BANNED_EMAIL_DESC="Email addresses not allowed to submit contact form. Separate multiple email addresses with a semicolon." +COM_CONTACT_FIELD_EMAIL_BANNED_EMAIL_LABEL="Banned Email" +COM_CONTACT_FIELD_EMAIL_BANNED_SUBJECT_DESC="Subjects not allowed in contact form. Separate multiple subjects with a semicolon." +COM_CONTACT_FIELD_EMAIL_BANNED_SUBJECT_LABEL="Banned Subject" +COM_CONTACT_FIELD_EMAIL_BANNED_TEXT_DESC="Text not allowed in contact form body. Separate multiple words with a semicolon." +COM_CONTACT_FIELD_EMAIL_BANNED_TEXT_LABEL="Banned Text" +COM_CONTACT_FIELD_EMAIL_EMAIL_COPY_DESC="Hide or Show checkbox to allow copy of email to be sent to submitter." +COM_CONTACT_FIELD_EMAIL_EMAIL_COPY_LABEL="Send Copy to Submitter" +COM_CONTACT_FIELD_EMAIL_SHOW_FORM_DESC="Show or hide the contact form." +COM_CONTACT_FIELD_EMAIL_SHOW_FORM_LABEL="Contact Form" +COM_CONTACT_FIELD_FEATURED_DESC="If marked yes, will be displayed in featured view." +COM_CONTACT_FIELD_FEEDLINK_DESC="Show or hide a feed link for this contact category." +COM_CONTACT_FIELD_FEEDLINK_LABEL="Feed Link" +COM_CONTACT_FIELD_ICONS_ADDRESS_DESC="Select or upload an image for the Address icon. If none selected, the default icon will be displayed." +COM_CONTACT_FIELD_ICONS_ADDRESS_LABEL="Address Icon" +COM_CONTACT_FIELD_ICONS_EMAIL_DESC="Select or upload an image for the Email icon. If none selected, the default icon will be displayed." +COM_CONTACT_FIELD_ICONS_EMAIL_LABEL="Email Icon" +COM_CONTACT_FIELD_ICONS_FAX_DESC="Select or upload an image for the Fax icon. If none selected, the default icon will be displayed." +COM_CONTACT_FIELD_ICONS_FAX_LABEL="Fax Icon" +COM_CONTACT_FIELD_ICONS_MISC_DESC="Select or upload an image for the Misc icon. If none selected, the default icon will be displayed." +COM_CONTACT_FIELD_ICONS_MISC_LABEL="Misc Icon" +COM_CONTACT_FIELD_ICONS_MOBILE_DESC="Select or upload an image for the Mobile icon. If none selected, the default icon will be displayed." +COM_CONTACT_FIELD_ICONS_MOBILE_LABEL="Mobile Icon" +COM_CONTACT_FIELD_ICONS_SETTINGS_DESC="Show icons, text or nothing next to the information." +COM_CONTACT_FIELD_ICONS_SETTINGS_LABEL="Settings" +COM_CONTACT_FIELD_ICONS_TELEPHONE_DESC="Select or upload an image for the Telephone icon. If none selected, the default icon will be displayed." +COM_CONTACT_FIELD_ICONS_TELEPHONE_LABEL="Telephone Icon" +COM_CONTACT_FIELD_IMAGE_ALIGN_DESC="Alignment of the image." +COM_CONTACT_FIELD_IMAGE_ALIGN_LABEL="Image Alignment" +COM_CONTACT_FIELD_INFORMATION_ADDRESS_DESC="Contact's address." +COM_CONTACT_FIELD_INFORMATION_ADDRESS_LABEL="Address" +COM_CONTACT_FIELD_INFORMATION_COUNTRY_DESC="Contact's country." +COM_CONTACT_FIELD_INFORMATION_COUNTRY_LABEL="Country" +COM_CONTACT_FIELD_INFORMATION_EMAIL_DESC="Contact's email." +COM_CONTACT_FIELD_INFORMATION_FAX_DESC="Contact's fax." +COM_CONTACT_FIELD_INFORMATION_FAX_LABEL="Fax" +COM_CONTACT_FIELD_INFORMATION_MISC_DESC="Contact's miscellaneous information." +COM_CONTACT_FIELD_INFORMATION_MISC_LABEL="Miscellaneous Information" +COM_CONTACT_FIELD_INFORMATION_MOBILE_DESC="Contact's mobile phone." +COM_CONTACT_FIELD_INFORMATION_MOBILE_LABEL="Mobile" +COM_CONTACT_FIELD_INFORMATION_POSITION_DESC="Contact's position." +COM_CONTACT_FIELD_INFORMATION_POSITION_LABEL="Position" +COM_CONTACT_FIELD_INFORMATION_POSTCODE_DESC="Contact's Postal/ZIP code." +COM_CONTACT_FIELD_INFORMATION_POSTCODE_LABEL="Postal/ZIP Code" +COM_CONTACT_FIELD_INFORMATION_STATE_DESC="Contact's state or county." +COM_CONTACT_FIELD_INFORMATION_STATE_LABEL="State or County" +COM_CONTACT_FIELD_INFORMATION_SUBURB_DESC="Contact's city or suburb." +COM_CONTACT_FIELD_INFORMATION_SUBURB_LABEL="City or Suburb" +COM_CONTACT_FIELD_INFORMATION_TELEPHONE_DESC="Contact's telephone." +COM_CONTACT_FIELD_INFORMATION_TELEPHONE_LABEL="Telephone" +COM_CONTACT_FIELD_INFORMATION_WEBPAGE_DESC="Contact's Website. IDN (International) Links are converted to punycode when they are saved." +COM_CONTACT_FIELD_INFORMATION_WEBPAGE_LABEL="Website" +COM_CONTACT_FIELD_INITIAL_SORT_DESC="Choose the field or fields by which contacts will be sorted." +COM_CONTACT_FIELD_INITIAL_SORT_LABEL="Sort By" +COM_CONTACT_FIELD_LANGUAGE_DESC="Assign a language for this contact." +COM_CONTACT_FIELD_LIMIT_BOX_DESC="Show or hide limit box." +COM_CONTACT_FIELD_LIMIT_BOX_LABEL="Limit box" +COM_CONTACT_FIELD_LINK_NAME_DESC="An additional link for this contact." +COM_CONTACT_FIELD_LINKA_DESC="Enter a URL for Link A." +COM_CONTACT_FIELD_LINKA_LABEL="Link A URL" +COM_CONTACT_FIELD_LINKA_NAME_LABEL="Link A Label" +COM_CONTACT_FIELD_LINKB_DESC="Enter a URL for Link B." +COM_CONTACT_FIELD_LINKB_LABEL="Link B URL" +COM_CONTACT_FIELD_LINKB_NAME_LABEL="Link B Label" +COM_CONTACT_FIELD_LINKC_DESC="Enter a URL for Link C." +COM_CONTACT_FIELD_LINKC_LABEL="Link C URL" +COM_CONTACT_FIELD_LINKC_NAME_LABEL="Link C Label" +COM_CONTACT_FIELD_LINKD_DESC="Enter a URL for Link D." +COM_CONTACT_FIELD_LINKD_LABEL="Link D URL" +COM_CONTACT_FIELD_LINKD_NAME_LABEL="Link D Label" +COM_CONTACT_FIELD_LINKE_DESC="Enter a URL for Link E." +COM_CONTACT_FIELD_LINKE_LABEL="Link E URL" +COM_CONTACT_FIELD_LINKE_NAME_LABEL="Link E Label" +COM_CONTACT_FIELD_LINKED_USER_DESC="Linked Joomla User." +COM_CONTACT_FIELD_LINKED_USER_LABEL="Linked User" +COM_CONTACT_FIELD_LINKED_USER_LABEL_ASC="Linked User ascending" +COM_CONTACT_FIELD_LINKED_USER_LABEL_DESC="Linked User descending" +COM_CONTACT_FIELD_MODIFIED_BY_DESC="Name of the user who modified this contact." +COM_CONTACT_FIELD_MODIFIED_DESC="The date and time that the contact was last modified." +COM_CONTACT_FIELD_NAME_DESC="Contact name." +COM_CONTACT_FIELD_NAME_LABEL="Name" +COM_CONTACT_FIELD_NUM_CONTACTS_DESC="Number of Contacts to display as list." +COM_CONTACT_FIELD_NUM_CONTACTS_LABEL="Number of Contacts" +COM_CONTACT_FIELD_PARAMS_ADD_MAILTO_LINK_DESC="Adds a mailto: link to the displayed email address." +COM_CONTACT_FIELD_PARAMS_ADD_MAILTO_LINK_LABEL="Add Mailto: Link" +COM_CONTACT_FIELD_PARAMS_CONTACT_E_MAIL_DESC="Show or hide contact email." +COM_CONTACT_FIELD_PARAMS_CONTACT_POSITION_DESC="Show or hide position." +COM_CONTACT_FIELD_PARAMS_CONTACT_POSITION_LABEL="Contact's Position" +COM_CONTACT_FIELD_PARAMS_COUNTRY_DESC="Show or hide country." +COM_CONTACT_FIELD_PARAMS_COUNTRY_LABEL="Country" +COM_CONTACT_FIELD_PARAMS_FAX_DESC="Show or hide fax number." +COM_CONTACT_FIELD_PARAMS_FAX_LABEL="Fax" +COM_CONTACT_FIELD_PARAMS_IMAGE_DESC="Select or upload the contact image." +COM_CONTACT_FIELD_PARAMS_IMAGE_LABEL="Image" +COM_CONTACT_FIELD_PARAMS_MISC_INFO_DESC="Show or hide miscellaneous information." +COM_CONTACT_FIELD_PARAMS_MISC_INFO_LABEL="Miscellaneous Information" +COM_CONTACT_FIELD_PARAMS_MOBILE_DESC="Show or hide mobile number." +COM_CONTACT_FIELD_PARAMS_MOBILE_LABEL="Mobile Phone" +COM_CONTACT_FIELD_PARAMS_NAME_DESC="Show or hide name of the contact." +COM_CONTACT_FIELD_PARAMS_NAME_LABEL="Name" +COM_CONTACT_FIELD_PARAMS_POST-ZIP_CODE_DESC="Show or hide the Postal/ZIP code." +COM_CONTACT_FIELD_PARAMS_POST-ZIP_CODE_LABEL="Postal/ZIP Code" +COM_CONTACT_FIELD_PARAMS_SHOW_IMAGE_DESC="Show or hide image." +COM_CONTACT_FIELD_PARAMS_SHOW_IMAGE_LABEL="Image" +COM_CONTACT_FIELD_PARAMS_STATE-COUNTY_DESC="Show or hide state or county." +COM_CONTACT_FIELD_PARAMS_STATE-COUNTY_LABEL="State or County" +COM_CONTACT_FIELD_PARAMS_STREET_ADDRESS_DESC="Show or hide street address." +COM_CONTACT_FIELD_PARAMS_STREET_ADDRESS_LABEL="Street Address" +COM_CONTACT_FIELD_PARAMS_TELEPHONE_DESC="Show or hide telephone number." +COM_CONTACT_FIELD_PARAMS_TELEPHONE_LABEL="Telephone" +COM_CONTACT_FIELD_PARAMS_TOWN-SUBURB_DESC="Show or hide city or suburb." +COM_CONTACT_FIELD_PARAMS_TOWN-SUBURB_LABEL="City or Suburb" +COM_CONTACT_FIELD_PARAMS_VCARD_DESC="Show or hide a link to allow export to vCard format." +COM_CONTACT_FIELD_PARAMS_VCARD_LABEL="vCard" +COM_CONTACT_FIELD_PARAMS_WEBPAGE_DESC="Show or hide webpage." +COM_CONTACT_FIELD_PARAMS_WEBPAGE_LABEL="Webpage" +COM_CONTACT_FIELD_PRESENTATION_DESC="Determines the style used to display sections of the contact form." +COM_CONTACT_FIELD_PRESENTATION_LABEL="Display Format" +COM_CONTACT_FIELD_PROFILE_SHOW_DESC="If the contact is mapped to a user and this option is set to Show, then the profile of the user will be shown in the contact details." +COM_CONTACT_FIELD_PROFILE_SHOW_LABEL="User Profile" +COM_CONTACT_FIELD_PUBLISH_DOWN_DESC="An optional date to Finish Publishing the contact." +COM_CONTACT_FIELD_PUBLISH_DOWN_LABEL="Finish Publishing" +COM_CONTACT_FIELD_PUBLISH_UP_DESC="An optional date to Start Publishing the contact." +COM_CONTACT_FIELD_PUBLISH_UP_LABEL="Start Publishing" +COM_CONTACT_FIELD_SHOW_CAT_ITEMS_DESC="Show or hide the number of contacts in category." +COM_CONTACT_FIELD_SHOW_CAT_ITEMS_LABEL="# Contacts in Category" +COM_CONTACT_FIELD_SHOW_CATEGORY_DESC="Displays the category." +COM_CONTACT_FIELD_SHOW_LINKS_DESC="Show or hide the contact links." +COM_CONTACT_FIELD_SHOW_LINKS_LABEL="Contact Links" +COM_CONTACT_FIELD_SHOW_CAT_TAGS_DESC="Show or hide the tags for a contact category." +COM_CONTACT_FIELD_SHOW_CAT_TAGS_LABEL="Category Tags" +COM_CONTACT_FIELD_SHOW_TAGS_DESC="Show or hide the tags for a contact." +COM_CONTACT_FIELD_SHOW_TAGS_LABEL="Tags" +COM_CONTACT_FIELD_SHOW_INFO_LABEL="Contact Information" +COM_CONTACT_FIELD_SHOW_INFO_DESC="Show or hide the contact information." +COM_CONTACT_FIELD_SORTNAME1_DESC="The part of the name to use as the first sort field." +COM_CONTACT_FIELD_SORTNAME1_LABEL="First Sort Field" +COM_CONTACT_FIELD_SORTNAME2_DESC="The part of the name to use as the second sort field." +COM_CONTACT_FIELD_SORTNAME2_LABEL="Second Sort Field" +COM_CONTACT_FIELD_SORTNAME3_DESC="The part of the name to use as the third sort field." +COM_CONTACT_FIELD_SORTNAME3_LABEL="Third Sort Field" +COM_CONTACT_FIELD_USER_CUSTOM_FIELDS_SHOW_LABEL="Show User Custom Fields" +COM_CONTACT_FIELD_USER_CUSTOM_FIELDS_SHOW_DESC="Show user custom fields which belong to all or only selected field groups." +COM_CONTACT_FIELD_VALUE_ICONS="Icons" +COM_CONTACT_FIELD_VALUE_NAME="Name" +COM_CONTACT_FIELD_VALUE_NO_LINK="Show Without Link" +COM_CONTACT_FIELD_VALUE_NONE="None" +COM_CONTACT_FIELD_VALUE_ORDERING="Ordering" +COM_CONTACT_FIELD_VALUE_PLAIN="Plain" +COM_CONTACT_FIELD_VALUE_SLIDERS="Sliders" +COM_CONTACT_FIELD_VALUE_SORT_NAME="Sort Name" +COM_CONTACT_FIELD_VALUE_TABS="Tabs" +COM_CONTACT_FIELD_VALUE_TEXT="Text" +COM_CONTACT_FIELD_VALUE_USE_CONTACT_SETTINGS="Use Contact Settings" +COM_CONTACT_FIELD_VALUE_WITH_LINK="Show With Link" +COM_CONTACT_FIELD_VERSION_LABEL="Revision" +COM_CONTACT_FIELD_VERSION_DESC="A count of the number of times this contact has been revised." +COM_CONTACT_FIELDS_CONTACT_FIELDS_TITLE="Contacts: Fields" +COM_CONTACT_FIELDS_CONTACT_FIELD_ADD_TITLE="Contacts: New Field" +COM_CONTACT_FIELDS_CONTACT_FIELD_EDIT_TITLE="Contacts: Edit Field" +COM_CONTACT_FIELDS_CONTEXT_CONTACT="Contact" +COM_CONTACT_FIELDS_CONTEXT_MAIL="Mail" +COM_CONTACT_FIELDSET_CONTACT_FORM="Contact form" +COM_CONTACT_FIELDSET_CONTACT_LABEL="Form" +COM_CONTACT_FIELDSET_CONTACTFORM_LABEL="Mail Options" +COM_CONTACT_FIELDSET_OPTIONS="Display Options" +COM_CONTACT_FILTER_DESC="Choose the type of filter to display per default." +COM_CONTACT_FILTER_LABEL="Filter field" +COM_CONTACT_FILTER_SEARCH_DESC="Search in contact name and alias. Prefix with ID: to search for a contact ID." +COM_CONTACT_FILTER_SEARCH_LABEL="Search Contacts" +COM_CONTACT_ICONS_SETTINGS="Icons" +COM_CONTACT_HEADING_ASSOCIATION="Association" +COM_CONTACT_HITS_DESC="Number of hits for this contact." +COM_CONTACT_ID_LABEL="ID" +; The following 2 strings are deprecated and will be removed with 4.0. +COM_CONTACT_ITEM_ASSOCIATIONS_FIELDSET_LABEL="Contact Item Associations" +COM_CONTACT_ITEM_ASSOCIATIONS_FIELDSET_DESC="Multilingual only! This choice will only display if the Language Filter parameter 'Item Associations' is set to 'Yes'. Choose a contact item for the target language. This association will let the Language Switcher module redirect to the associated contact item in another language. If used, make sure to display the Language switcher module on the relevant pages. A contact item set to language 'All' can't be associated." +COM_CONTACT_MAIL_FIELDSET_LABEL="Mail Options" +COM_CONTACT_MANAGER_CONTACT="Contacts: New/Edit" +COM_CONTACT_MANAGER_CONTACT_EDIT="Contacts: Edit" +COM_CONTACT_MANAGER_CONTACT_NEW="Contacts: New" +COM_CONTACT_MANAGER_CONTACTS="Contacts" +COM_CONTACT_N_ITEMS_ARCHIVED="%d contacts archived." +COM_CONTACT_N_ITEMS_ARCHIVED_1="%d contact archived." +COM_CONTACT_N_ITEMS_CHECKED_IN_0="No contact checked in." +COM_CONTACT_N_ITEMS_CHECKED_IN_1="%d contact checked in." +COM_CONTACT_N_ITEMS_CHECKED_IN_MORE="%d contacts checked in." +COM_CONTACT_N_ITEMS_DELETED="%d contacts deleted." +COM_CONTACT_N_ITEMS_DELETED_1="%d contact deleted." +COM_CONTACT_N_ITEMS_FEATURED="%d contacts featured." +COM_CONTACT_N_ITEMS_FEATURED_1="%d contact featured." +COM_CONTACT_N_ITEMS_PUBLISHED="%d contacts published." +COM_CONTACT_N_ITEMS_PUBLISHED_1="%d contact published." +COM_CONTACT_N_ITEMS_TRASHED="%d contacts trashed." +COM_CONTACT_N_ITEMS_TRASHED_1="%d contact trashed." +COM_CONTACT_N_ITEMS_UNFEATURED="%d contacts unfeatured." +COM_CONTACT_N_ITEMS_UNFEATURED_1="%d contact unfeatured." +COM_CONTACT_N_ITEMS_UNPUBLISHED="%d contacts unpublished." +COM_CONTACT_N_ITEMS_UNPUBLISHED_1="%d contact unpublished." +COM_CONTACT_NAME_DESC="Contact name." +COM_CONTACT_NEW_CONTACT="New Contact" +COM_CONTACT_NO_ITEM_SELECTED="No contacts selected." +COM_CONTACT_OPTIONS="Options" +COM_CONTACT_SAVE_SUCCESS="Contact saved." +COM_CONTACT_SEARCH_IN_NAME="Search contacts by name" +COM_CONTACT_SELECT_A_CONTACT="Select a Contact" +COM_CONTACT_SELECT_CONTACT_DESC="Select or create a contact to be displayed." +COM_CONTACT_SELECT_CONTACT_LABEL="Select Contact" +COM_CONTACT_SELECT_USER="Select User" +COM_CONTACT_SHOW_EMAIL_ADDRESS_DESC="Show email address." +COM_CONTACT_SHOW_EMAIL_ADDRESS_LABEL="Email Address" +COM_CONTACT_SHOW_EMPTY_CATEGORIES_DESC="If Show, empty categories will display. A category is only empty if it has no Contacts or subcategories." +COM_CONTACT_SUBMENU_CATEGORIES="Categories" +COM_CONTACT_SUBMENU_CONTACTS="Contacts" +COM_CONTACT_TIP_ASSOCIATION="Associated contacts" +COM_CONTACT_TOGGLE_TO_FEATURE="Toggle to change contact state to 'Featured'." +COM_CONTACT_TOGGLE_TO_UNFEATURE="Toggle to change contact state to 'Unfeatured'." +COM_CONTACT_UNFEATURED="Unfeatured contact" +COM_CONTACT_WARNING_CATEGORY="This category is invalid." +COM_CONTACT_WARNING_PROVIDE_VALID_NAME="Please provide a valid name." +COM_CONTACT_WARNING_PROVIDE_VALID_URL="Please provide a valid URL." +COM_CONTACT_WARNING_SELECT_CONTACT_TOPUBLISH="Please select a contact to publish." +COM_CONTACT_XML_DESCRIPTION="This component shows a listing of contact information." +JGLOBAL_FIELDSET_MISCELLANEOUS="Miscellaneous Information" +JGLOBAL_NEWITEMSLAST_DESC="New Contacts default to the last position. Ordering can be changed after this Contact is saved." +JLIB_HTML_BATCH_USER_LABEL="Set Linked User" +JLIB_RULES_SETTING_NOTES="Changes apply to this component only.
    Inherited - a Global Configuration setting or higher level setting is applied.
    Denied always wins - whatever is set at the Global or higher level and applies to all child elements.
    Allowed will enable the action for this component unless overruled by a Global Configuration setting." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.com_contact.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.com_contact.sys.ini new file mode 100644 index 00000000..201449c9 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.com_contact.sys.ini @@ -0,0 +1,27 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +COM_CONTACT="Contacts" +COM_CONTACT_CATEGORIES="Categories" +COM_CONTACT_CATEGORIES_VIEW_DEFAULT_DESC="Shows a list of contact categories within a category." +COM_CONTACT_CATEGORIES_VIEW_DEFAULT_OPTION="Default" +COM_CONTACT_CATEGORIES_VIEW_DEFAULT_TITLE="List All Contact Categories" +COM_CONTACT_CATEGORY_ADD_TITLE="Contacts: New Category" +COM_CONTACT_CATEGORY_EDIT_TITLE="Contacts: Edit Category" +COM_CONTACT_CATEGORY_VIEW_DEFAULT_DESC="This view lists the contacts in a category." +COM_CONTACT_CATEGORY_VIEW_DEFAULT_OPTION="Default" +COM_CONTACT_CATEGORY_VIEW_DEFAULT_TITLE="List Contacts in a Category" +COM_CONTACT_CONTACT_VIEW_DEFAULT_DESC="This links to the contact information for one contact." +COM_CONTACT_CONTACT_VIEW_DEFAULT_OPTION="Default" +COM_CONTACT_CONTACT_VIEW_DEFAULT_TITLE="Single Contact" +COM_CONTACT_CONTENT_TYPE_CONTACT="Contact" +COM_CONTACT_CONTENT_TYPE_CATEGORY="Contact Category" +COM_CONTACT_FEATURED_VIEW_DEFAULT_DESC="This view lists the featured contacts." +COM_CONTACT_FEATURED_VIEW_DEFAULT_OPTION="Default" +COM_CONTACT_FEATURED_VIEW_DEFAULT_TITLE="Featured Contacts" +COM_CONTACT_CONTACTS="Contacts" +COM_CONTACT_TAGS_CONTACT="Contact" +COM_CONTACT_TAGS_CATEGORY="Contact Category" +COM_CONTACT_XML_DESCRIPTION="This component shows a listing of Contact Information." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.com_content.ini b/Sites/pages/administrator/language/en-GB/en-GB.com_content.ini new file mode 100644 index 00000000..7e91741e --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.com_content.ini @@ -0,0 +1,213 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +COM_CONTENT="Articles" +COM_CONTENT_ACCESS_DELETE_DESC="New setting for delete actions on this article and the calculated setting based on the parent category and group permissions." +COM_CONTENT_ACCESS_EDIT_DESC="New setting for edit actions on this article and the calculated setting based on the parent category and group permissions." +COM_CONTENT_ACCESS_EDITSTATE_DESC="New setting for edit state actions on this article and the calculated setting based on the parent category and group permissions." +COM_CONTENT_ARTICLE_CONTENT="Content" +COM_CONTENT_ARTICLE_DETAILS="Article Details" +COM_CONTENT_ARTICLES_TITLE="Articles" +COM_CONTENT_ATTRIBS_ARTICLE_SETTINGS_LABEL="Options" +COM_CONTENT_ATTRIBS_FIELDSET_LABEL="Options" +; COM_CONTENT_BATCH_MENU_LABEL is deprecated, use JLIB_HTML_BATCH_MENU_LABEL instead. +COM_CONTENT_BATCH_MENU_LABEL="To Move or Copy your selection please select a Category." +COM_CONTENT_BATCH_OPTIONS="Batch process the selected articles" +COM_CONTENT_BATCH_TIP="If a category is selected for move/copy, any actions selected will be applied to the copied or moved articles. Otherwise, all actions are applied to the selected articles." +COM_CONTENT_CHANGE_ARTICLE="Select or Change article" +COM_CONTENT_CHANGE_ARTICLE_BUTTON="Select/Change" +COM_CONTENT_CHOOSE_CATEGORY_DESC="Select a parent category." +COM_CONTENT_CONFIG_ARTICLE_SETTINGS_DESC="These settings apply for article layouts unless they are changed for a specific menu item or article." +COM_CONTENT_CONFIG_BLOG_SETTINGS_DESC="These settings apply for blog or featured layouts unless they are changed for a specific menu item." +COM_CONTENT_CONFIG_BLOG_SETTINGS_LABEL="Blog/Featured Layouts" +COM_CONTENT_CONFIG_CATEGORIES_SETTINGS_DESC="These settings apply for Articles Categories Options, unless they are changed by the individual category or menu settings." +COM_CONTENT_CONFIG_CATEGORY_SETTINGS_DESC="These settings apply for Articles Category Options unless they are changed by the individual category or menu settings." +COM_CONTENT_CONFIG_EDITOR_LAYOUT="These options control the layout of the article editing page." +COM_CONTENT_CONFIG_INTEGRATION_SETTINGS_DESC="These settings determine how the Article Component will integrate with other extensions." +COM_CONTENT_CONFIG_LIST_SETTINGS_DESC="These settings apply for List Layouts Options unless they are changed for a specific menu item or category." +COM_CONTENT_CONFIGURATION="Articles: Options" +COM_CONTENT_CREATE_ARTICLE_CANCEL_REDIRECT_MENU_DESC="Select the page the user will be redirected to after Canceling article submission. The default is to redirect to the same article submission page (cleaning form)." +COM_CONTENT_CREATE_ARTICLE_CANCEL_REDIRECT_MENU_LABEL="Cancel Redirect" +COM_CONTENT_CREATE_ARTICLE_CATEGORY_DESC="If set to 'Yes', this page will only let you create articles in the category selected below." +COM_CONTENT_CREATE_ARTICLE_CATEGORY_LABEL="Specific Category" +COM_CONTENT_CREATE_ARTICLE_CUSTOM_CANCEL_REDIRECT_DESC="If set to 'Yes', you can set a redirection page, distinct from above 'Submission/Cancel Redirect', to redirect to when user Cancels article submission.
    If set to 'No', when user Cancels article submission, the user is redirected to the above 'Submission/Cancel Redirect' page." +COM_CONTENT_CREATE_ARTICLE_CUSTOM_CANCEL_REDIRECT_LABEL="Custom Redirect on Cancel" +COM_CONTENT_CREATE_ARTICLE_ERROR="When default category is enabled, a category should be selected." +COM_CONTENT_CREATE_ARTICLE_REDIRECTMENU_DESC="Select the page the user will be redirected to after a successful article submission and after cancel (if not set differently below). The default is to redirect to the home page." +COM_CONTENT_CREATE_ARTICLE_REDIRECTMENU_LABEL="Submission/Cancel Redirect" +COM_CONTENT_DRILL_CATEGORIES_LABEL="List or Blog: after choosing the display,
    make sure you define the Options in the desired layout." +COM_CONTENT_DRILL_DOWN_LAYOUT_DESC="When drilling down to a category, show articles in a list or blog layout." +COM_CONTENT_DRILL_DOWN_LAYOUT_LABEL="List or Blog Layout" +COM_CONTENT_EDIT_ARTICLE="Edit Article" +COM_CONTENT_EDIT_CATEGORY="Edit Category" +COM_CONTENT_EDITORCONFIG_FIELDSET_LABEL="Configure Edit Screen" +COM_CONTENT_EDITING_LAYOUT="Editing Layout" +COM_CONTENT_ERROR_ALL_LANGUAGE_ASSOCIATED="A content item set to All languages can't be associated. Associations have not been set." +COM_CONTENT_FEATURED="Featured Article" +COM_CONTENT_FEATURED_ARTICLES="Featured Articles" +COM_CONTENT_FEATURED_CATEGORIES_DESC="Optional list of categories. If selected, only featured articles from the selected categories will show." +COM_CONTENT_FEATURED_CATEGORIES_LABEL="Select Categories" +COM_CONTENT_FEATURED_ORDER="Featured Articles Order" +COM_CONTENT_FEATURED_TITLE="Articles: Featured" +COM_CONTENT_FIELD_BROWSER_PAGE_TITLE_DESC="Optional text for the "Browser page title" element to be used when the article is viewed with a non-article menu item. If blank, the article's title is used instead." +COM_CONTENT_FIELD_BROWSER_PAGE_TITLE_LABEL="Browser Page Title" +COM_CONTENT_FIELD_ARTICLETEXT_DESC="Enter the article content in the text area." +COM_CONTENT_FIELD_ARTICLETEXT_LABEL="Article Text" +COM_CONTENT_FIELD_CAPTCHA_DESC="Select the captcha plugin that will be used in the article submit form. You may need to enter required information for your captcha plugin in the Plugin Manager.
    If 'Use Global' is selected, make sure a captcha plugin is selected in Global Configuration." +COM_CONTENT_FIELD_CAPTCHA_LABEL="Allow Captcha on submit" +COM_CONTENT_FIELD_CREATED_BY_ALIAS_DESC="Enter an alias to be displayed instead of the name of the user who created the article." +COM_CONTENT_FIELD_CREATED_BY_ALIAS_LABEL="Created by Alias" +COM_CONTENT_FIELD_CREATED_BY_DESC="Select the name of the user who created the article." +COM_CONTENT_FIELD_CREATED_BY_LABEL="Created By" +COM_CONTENT_FIELD_CREATED_DESC="Created date." +COM_CONTENT_FIELD_CREATED_LABEL="Created Date" +COM_CONTENT_FIELD_FEATURED_DESC="Assign the article to the featured blog layout." +COM_CONTENT_FIELD_FULL_DESC="Select or upload an image for the single article display." +COM_CONTENT_FIELD_FULL_LABEL="Full Article Image" +COM_CONTENT_FIELD_FULLTEXT="Full text" +COM_CONTENT_FIELD_HITS_DESC="Number of hits for this article." +COM_CONTENT_FIELD_IMAGE_DESC="The image to be displayed." +COM_CONTENT_FIELD_IMAGE_ALT_DESC="Alternative text used for visitors without access to images." +COM_CONTENT_FIELD_IMAGE_ALT_LABEL="Alt Text" +COM_CONTENT_FIELD_IMAGE_CAPTION_DESC="Caption attached to the image." +COM_CONTENT_FIELD_IMAGE_CAPTION_LABEL="Caption" +COM_CONTENT_FIELD_IMAGE_OPTIONS="Image Options" +COM_CONTENT_FIELD_INFOBLOCK_POSITION_DESC="Puts the article information block above or below the text or splits it into two separate blocks, one above and the other below." +COM_CONTENT_FIELD_INFOBLOCK_POSITION_LABEL="Position of Article Info" +COM_CONTENT_FIELD_INFOBLOCK_TITLE_DESC="Displays the 'Article Info' title on top of the article information block." +COM_CONTENT_FIELD_INFOBLOCK_TITLE_LABEL="Article Info Title" +COM_CONTENT_FIELD_INTRO_DESC="Image for the intro text layouts such as blogs and featured." +COM_CONTENT_FIELD_INTRO_LABEL="Intro Image" +COM_CONTENT_FIELD_INTROTEXT="Intro Text" +COM_CONTENT_FIELD_LANGUAGE_DESC="The language that the article is assigned to." +COM_CONTENT_FIELD_MODIFIED_DESC="The date and time that the article was last modified." +COM_CONTENT_FIELD_NOTE_DESC="An optional note to display in the article list." +COM_CONTENT_FIELD_NOTE_LABEL="Note" +COM_CONTENT_FIELD_OPTION_ABOVE="Above" +COM_CONTENT_FIELD_OPTION_BELOW="Below" +COM_CONTENT_FIELD_OPTION_SPLIT="Split" +COM_CONTENT_FIELD_PUBLISH_DOWN_DESC="An optional date to Finish Publishing the article." +COM_CONTENT_FIELD_PUBLISH_DOWN_LABEL="Finish Publishing" +COM_CONTENT_FIELD_PUBLISH_UP_DESC="An optional date to Start Publishing the article." +COM_CONTENT_FIELD_PUBLISH_UP_LABEL="Start Publishing" +COM_CONTENT_FIELD_SELECT_ARTICLE_DESC="Select or create an article to be displayed." +COM_CONTENT_FIELD_SELECT_ARTICLE_LABEL="Select Article" +COM_CONTENT_FIELD_SHOW_CAT_TAGS_DESC="Show the tags for the category." +COM_CONTENT_FIELD_SHOW_CAT_TAGS_LABEL="Show Tags" +COM_CONTENT_FIELD_SHOW_TAGS_DESC="Show the tags for each article." +COM_CONTENT_FIELD_SHOW_TAGS_LABEL="Show Tags" +COM_CONTENT_FIELD_URL_DESC="The actual link to which users will be redirected." +COM_CONTENT_FIELD_URL_LINK_TEXT_DESC="Text to display for the link." +COM_CONTENT_FIELD_URL_LINK_TEXT_LABEL="Link Text" +COM_CONTENT_FIELD_URLA_LABEL="Link A" +COM_CONTENT_FIELD_URLA_LINK_TEXT_LABEL="Link A Text" +COM_CONTENT_FIELD_URLB_LABEL="Link B" +COM_CONTENT_FIELD_URLB_LINK_TEXT_LABEL="Link B Text" +COM_CONTENT_FIELD_URLC_LABEL="Link C" +COM_CONTENT_FIELD_URLC_LINK_TEXT_LABEL="Link C Text" +COM_CONTENT_FIELD_URLS_OPTIONS="URL Options" +COM_CONTENT_FIELD_URLSPOSITION_LABEL="Positioning of the Links" +COM_CONTENT_FIELD_URLSPOSITION_DESC="Display the links above or below the content." +COM_CONTENT_FIELD_VALUE_USE_ARTICLE_SETTINGS="Use Article Settings" +COM_CONTENT_FIELD_VERSION_DESC="A count of the number of times this article has been revised." +COM_CONTENT_FIELD_VERSION_LABEL="Revision" +COM_CONTENT_FIELD_XREFERENCE_DESC="An optional reference used to link to external data sources." +COM_CONTENT_FIELD_XREFERENCE_LABEL="External Reference" +COM_CONTENT_FIELDS_ARTICLE_FIELDS_TITLE="Articles: Fields" +COM_CONTENT_FIELDS_ARTICLE_FIELD_ADD_TITLE="Articles: New Field" +COM_CONTENT_FIELDS_ARTICLE_FIELD_EDIT_TITLE="Articles: Edit Field" +COM_CONTENT_FIELDS_TYPE_MODAL_ARTICLE="Article" +COM_CONTENT_FIELDSET_PUBLISHING="Publishing" +COM_CONTENT_FIELDSET_RULES="Permissions" +COM_CONTENT_FIELDSET_URLS_AND_IMAGES="Images and Links" +COM_CONTENT_FILTER_SEARCH_DESC="Search in title, alias and note. Prefix with ID: or AUTHOR: or CONTENT: to search for an article ID, article author or search in article content." +COM_CONTENT_FILTER_SEARCH_LABEL="Search Articles" +COM_CONTENT_FLOAT_DESC="Controls placement of the image." +COM_CONTENT_FLOAT_FULLTEXT_LABEL="Full Text Image Float" +COM_CONTENT_FLOAT_LABEL="Image Float" +COM_CONTENT_FLOAT_INTRO_LABEL="Intro Image Float" +COM_CONTENT_HEADING_ASSOCIATION="Association" +COM_CONTENT_HEADING_DATE_CREATED="Date Created" +COM_CONTENT_HEADING_DATE_MODIFIED="Date Modified" +COM_CONTENT_HEADING_DATE_PUBLISH_UP="Start Publishing" +COM_CONTENT_HEADING_DATE_PUBLISH_DOWN="Finish Publishing" +COM_CONTENT_ID_LABEL="ID" +; The following 2 strings are deprecated and will be removed with 4.0. +COM_CONTENT_ITEM_ASSOCIATIONS_FIELDSET_LABEL="Content Item Associations" +COM_CONTENT_ITEM_ASSOCIATIONS_FIELDSET_DESC="Multilingual only! This choice will only display if the Language Filter parameter 'Item Associations' is set to 'Yes'. Choose a content item for the target language. This association will let the Language Switcher module redirect to the associated content item in another language. If used, make sure to display the Language switcher module on the relevant pages. A content item set to language 'All' can't be associated." +COM_CONTENT_LEFT="Left" +COM_CONTENT_MODIFIED_ASC="Date Modified ascending" +COM_CONTENT_MODIFIED_DESC="Date Modified descending" +COM_CONTENT_MONTH="Month" +COM_CONTENT_N_ITEMS_ARCHIVED="%s articles archived." +COM_CONTENT_N_ITEMS_ARCHIVED_1="%s article archived." +COM_CONTENT_N_ITEMS_CHECKED_IN_0="No article checked in." +COM_CONTENT_N_ITEMS_CHECKED_IN_1="%d article checked in." +COM_CONTENT_N_ITEMS_CHECKED_IN_MORE="%d articles checked in." +COM_CONTENT_N_ITEMS_DELETED="%s articles deleted." +COM_CONTENT_N_ITEMS_DELETED_1="%s article deleted." +COM_CONTENT_N_ITEMS_FEATURED="%s articles featured." +COM_CONTENT_N_ITEMS_FEATURED_1="%s article featured." +COM_CONTENT_N_ITEMS_PUBLISHED="%s articles published." +COM_CONTENT_N_ITEMS_PUBLISHED_1="%s article published." +COM_CONTENT_N_ITEMS_TRASHED="%s articles trashed." +COM_CONTENT_N_ITEMS_TRASHED_1="%s article trashed." +COM_CONTENT_N_ITEMS_UNFEATURED="%s articles unfeatured." +COM_CONTENT_N_ITEMS_UNFEATURED_1="%s article unfeatured." +COM_CONTENT_N_ITEMS_UNPUBLISHED="%s articles unpublished." +COM_CONTENT_N_ITEMS_UNPUBLISHED_1="%s article unpublished." +COM_CONTENT_NEW_ARTICLE="New Article" +COM_CONTENT_NO_ARTICLES_DESC="If Show, the message 'There are no articles in this category' will display when there are no articles in the category or when 'Empty Categories' is set to show." +COM_CONTENT_NO_ARTICLES_LABEL="No Articles Message" +COM_CONTENT_NO_ITEM_SELECTED="Please first make a selection from the list." +COM_CONTENT_NONE="None" +COM_CONTENT_NUMBER_CATEGORY_ITEMS_DESC="If Show, the number of articles in the category will show." +COM_CONTENT_NUMBER_CATEGORY_ITEMS_LABEL="# Articles in Category" +COM_CONTENT_PAGE_ADD_ARTICLE="Articles: New" +COM_CONTENT_PAGE_EDIT_ARTICLE="Articles: Edit" +COM_CONTENT_PAGE_VIEW_ARTICLE="Articles: View" +COM_CONTENT_PAGEBREAK_DOC_TITLE="Page Break" +COM_CONTENT_PAGEBREAK_INSERT_BUTTON="Insert Page Break" +COM_CONTENT_PAGEBREAK_TITLE="Page Title:" +COM_CONTENT_PAGEBREAK_TOC="Table of Contents Alias:" +COM_CONTENT_PUBLISH_DOWN_ASC="Finish Publishing ascending" +COM_CONTENT_PUBLISH_DOWN_DESC="Finish Publishing descending" +COM_CONTENT_PUBLISH_UP_ASC="Start Publishing ascending" +COM_CONTENT_PUBLISH_UP_DESC="Start Publishing descending" +COM_CONTENT_RIGHT="Right" +COM_CONTENT_SAVE_SUCCESS="Article saved." +COM_CONTENT_SAVE_WARNING="Alias already existed so a number was added at the end. You can re-edit the article to customise the alias." +COM_CONTENT_SELECT_AN_ARTICLE="Select an Article" +COM_CONTENT_SHARED_DESC="These settings apply for Shared Options in List, Blog and Featured unless they are changed by the menu settings." +COM_CONTENT_SHARED_LABEL="Shared" +COM_CONTENT_SHOW_ARTICLE_OPTIONS_DESC="Show or hide the article options tab in the Backend article edit view. These options allow overriding of the global options." +COM_CONTENT_SHOW_ARTICLE_OPTIONS_LABEL="Show Article Options" +COM_CONTENT_SHOW_EMPTY_CATEGORIES_DESC="If Show, empty categories will display. A category is only empty if it has no articles or subcategories." +COM_CONTENT_SHOW_IMAGES_URLS_BACK_DESC="Show or hide fields to insert images and links in the Administrator." +COM_CONTENT_SHOW_IMAGES_URLS_BACK_LABEL="Administrator Images and Links" +COM_CONTENT_SHOW_IMAGES_URLS_FRONT_DESC="Show or hide fields to insert images and links when Frontend editing." +COM_CONTENT_SHOW_IMAGES_URLS_FRONT_LABEL="Frontend Images and Links" +COM_CONTENT_SHOW_PUBLISHING_OPTIONS_DESC="Show or hide the publishing options tab in the article edit view. These options allow changes in dates and author identities." +COM_CONTENT_SHOW_PUBLISHING_OPTIONS_LABEL="Show Publishing Options" +COM_CONTENT_SLIDER_EDITOR_CONFIG="Configure Edit Screen" +COM_CONTENT_SUBMENU_CATEGORIES="Categories" +COM_CONTENT_SUBMENU_FEATURED="Featured Articles" +COM_CONTENT_TIP_ASSOCIATION="Associated articles" +COM_CONTENT_TOGGLE_TO_FEATURE="Toggle to change article state to 'Featured'" +COM_CONTENT_TOGGLE_TO_UNFEATURE="Toggle to change article state to 'Unfeatured'" +COM_CONTENT_UNFEATURED="Unfeatured Article" +COM_CONTENT_URL_FIELD_BROWSERNAV_LABEL="URL Target Window" +COM_CONTENT_URL_FIELD_BROWSERNAV_DESC="Target browser window when the link is selected." +COM_CONTENT_URL_FIELD_A_BROWSERNAV_LABEL="URL A Target Window" +COM_CONTENT_URL_FIELD_B_BROWSERNAV_LABEL="URL B Target Window" +COM_CONTENT_URL_FIELD_C_BROWSERNAV_LABEL="URL C Target Window" +COM_CONTENT_WARNING_PROVIDE_VALID_NAME="Please provide a valid, non-blank title." +COM_CONTENT_XML_DESCRIPTION="Article management component." + +JGLOBAL_NO_ITEM_SELECTED="No articles selected" +JLIB_APPLICATION_ERROR_BATCH_CANNOT_CREATE="You are not allowed to create new articles in this category." +JLIB_APPLICATION_ERROR_BATCH_CANNOT_EDIT="You are not allowed to edit one or more of these articles." +JLIB_RULES_SETTING_NOTES="Changes apply to this component only.
    Inherited - a Global Configuration setting or higher level setting is applied.
    Denied always wins - whatever is set at the Global or higher level and applies to all child elements.
    Allowed will enable the action for this component unless overruled by a Global Configuration setting." +JLIB_RULES_SETTING_NOTES_ITEM="Changes apply to this article only.
    Inherited - a Global Configuration setting or higher level setting is applied.
    Denied always wins - whatever is set at the Global or higher level and applies to all child elements.
    Allowed will enable the action for this component unless overruled by a Global Configuration setting." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.com_content.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.com_content.sys.ini new file mode 100644 index 00000000..5b59de23 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.com_content.sys.ini @@ -0,0 +1,45 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +COM_CONTENT="Articles" +COM_CONTENT_ARCHIVE_VIEW_DEFAULT_DESC="Display all archived articles." +COM_CONTENT_ARCHIVE_VIEW_DEFAULT_OPTION="Default" +COM_CONTENT_ARCHIVE_VIEW_DEFAULT_TITLE="Archived Articles" +COM_CONTENT_ARTICLE_MANAGER="Articles" +COM_CONTENT_ARTICLE_VIEW_DEFAULT_DESC="Display a single article." +COM_CONTENT_ARTICLE_VIEW_DEFAULT_OPTION="Default" +COM_CONTENT_ARTICLE_VIEW_DEFAULT_TITLE="Single Article" +COM_CONTENT_ARTICLE_VIEW_EDIT_DESC="Shows a form to create a New Article." +COM_CONTENT_ARTICLE_VIEW_EDIT_TITLE="Create an Article" +COM_CONTENT_ARTICLES="Articles" +COM_CONTENT_ARTICLES_VIEW_DEFAULT_DESC="Shows a list of all the articles." +COM_CONTENT_ARTICLES_VIEW_DEFAULT_TITLE="List All Articles" +COM_CONTENT_CATEGORIES="Categories" +COM_CONTENT_CATEGORIES_VIEW_DEFAULT_DESC="Shows a list of all the article categories within a category." +COM_CONTENT_CATEGORIES_VIEW_DEFAULT_OPTION="Default" +COM_CONTENT_CATEGORIES_VIEW_DEFAULT_TITLE="List All Categories" +COM_CONTENT_CATEGORY_ADD_TITLE="Articles: New Category" +COM_CONTENT_CATEGORY_EDIT_TITLE="Articles: Edit Category" +COM_CONTENT_CATEGORY_VIEW_BLOG_DESC="Displays article introductions in a single or multi-column layout." +COM_CONTENT_CATEGORY_VIEW_BLOG_OPTION="Blog" +COM_CONTENT_CATEGORY_VIEW_BLOG_TITLE="Category Blog" +COM_CONTENT_CATEGORY_VIEW_DEFAULT_DESC="Displays a list of articles in a category." +COM_CONTENT_CATEGORY_VIEW_DEFAULT_OPTION="List" +COM_CONTENT_CATEGORY_VIEW_DEFAULT_TITLE="Category List" +COM_CONTENT_CATEGORY_VIEW_FEATURED_DESC="Show all featured articles from one or multiple categories in a single or multi-column layout." +COM_CONTENT_CATEGORY_VIEW_FEATURED_OPTION="Default" +COM_CONTENT_CATEGORY_VIEW_FEATURED_TITLE="Featured Articles Single Category" +COM_CONTENT_CONTENT_TYPE_ARTICLE="Article" +COM_CONTENT_CONTENT_TYPE_CATEGORY="Article Category" +COM_CONTENT_FEATURED="Featured" +COM_CONTENT_FEATURED_VIEW_DEFAULT_DESC="Displays article introductions in a single or multi-column layout for featured articles from all categories." +COM_CONTENT_FEATURED_VIEW_DEFAULT_OPTION="Default" +COM_CONTENT_FEATURED_VIEW_DEFAULT_TITLE="Featured Articles" +COM_CONTENT_FORM_VIEW_DEFAULT_DESC="Create a new article." +COM_CONTENT_FORM_VIEW_DEFAULT_OPTION="Create" +COM_CONTENT_FORM_VIEW_DEFAULT_TITLE="Create Article" +COM_CONTENT_TAGS_ARTICLE="Article" +COM_CONTENT_TAGS_CATEGORY="Article Category" +COM_CONTENT_XML_DESCRIPTION="Article management component." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.com_contenthistory.ini b/Sites/pages/administrator/language/en-GB/en-GB.com_contenthistory.ini new file mode 100644 index 00000000..fca25475 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.com_contenthistory.ini @@ -0,0 +1,49 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +COM_CONTENTHISTORY_BUTTON_COMPARE_ALL_ROWS_DESC="Select to see all values for the item, including ones that haven't changed." +COM_CONTENTHISTORY_BUTTON_COMPARE_ALL_ROWS="All Values" +COM_CONTENTHISTORY_BUTTON_COMPARE_CHANGED_ROWS_DESC="Select to see only those values that have changed." +COM_CONTENTHISTORY_BUTTON_COMPARE_CHANGED_ROWS="Changed Values" +COM_CONTENTHISTORY_BUTTON_COMPARE_DESC="Choose two versions and select to compare them." +COM_CONTENTHISTORY_BUTTON_COMPARE_HTML_DESC="Select to see the HTML source code for the changes." +COM_CONTENTHISTORY_BUTTON_COMPARE_HTML="Show HTML Code" +COM_CONTENTHISTORY_BUTTON_COMPARE_TEXT_DESC="Select to see the item changes as text." +COM_CONTENTHISTORY_BUTTON_COMPARE_TEXT="Show Text" +COM_CONTENTHISTORY_BUTTON_COMPARE="Compare" +COM_CONTENTHISTORY_BUTTON_DELETE_DESC="Choose one or more versions and select to permanently delete them." +COM_CONTENTHISTORY_BUTTON_DELETE="Delete" +COM_CONTENTHISTORY_BUTTON_KEEP_DESC="Choose one or more versions and select to toggle the keep forever on or off." +COM_CONTENTHISTORY_BUTTON_KEEP_TOGGLE_OFF="Select to allow this version to be deleted automatically according to the delete schedule." +COM_CONTENTHISTORY_BUTTON_KEEP_TOGGLE_ON="Select to prevent this version being deleted automatically." +COM_CONTENTHISTORY_BUTTON_KEEP="Keep On/Off" +COM_CONTENTHISTORY_BUTTON_LOAD_DESC="This button loads the selected version into the edit form." +COM_CONTENTHISTORY_BUTTON_LOAD="Restore" +COM_CONTENTHISTORY_BUTTON_PREVIEW_DESC="This button allows you to see a preview of the selected version." +COM_CONTENTHISTORY_BUTTON_PREVIEW="Preview" +COM_CONTENTHISTORY_BUTTON_SELECT_ONE="Please select one version." +COM_CONTENTHISTORY_BUTTON_SELECT_TWO="Please select two versions." +COM_CONTENTHISTORY_CHARACTER_COUNT="Character Count" +COM_CONTENTHISTORY_COMPARE_DIFF="Changes" +COM_CONTENTHISTORY_COMPARE_TITLE="Compare View" +COM_CONTENTHISTORY_COMPARE_VALUE1="Saved on %s %s" +COM_CONTENTHISTORY_COMPARE_VALUE2="Saved on %s %s" +COM_CONTENTHISTORY_ERROR_FAILED_LOADING_CONTENT_TYPE="Failed loading content type." +COM_CONTENTHISTORY_ERROR_INVALID_ID="Invalid ID selected." +COM_CONTENTHISTORY_ERROR_KEEP_NOT_PERMITTED="You are not permitted to change the keep forever status." +COM_CONTENTHISTORY_ERROR_VERSION_NOT_FOUND="Version not found." +COM_CONTENTHISTORY_KEEP_VERSION="Keep Forever" +COM_CONTENTHISTORY_MODAL_TITLE="Item Version History" +COM_CONTENTHISTORY_N_ITEMS_DELETED_1="%s history version deleted." +COM_CONTENTHISTORY_N_ITEMS_DELETED="%s history versions deleted." +COM_CONTENTHISTORY_N_ITEMS_KEEP_TOGGLE_1="Successfully changed the keep forever value for %s history version." +COM_CONTENTHISTORY_N_ITEMS_KEEP_TOGGLE="Successfully changed the keep forever value for %s history versions." +COM_CONTENTHISTORY_NO_ITEM_SELECTED="No history version selected." +COM_CONTENTHISTORY_PREVIEW_FIELD="Field" +COM_CONTENTHISTORY_PREVIEW_SUBTITLE_DATE="Preview of version from %s" +COM_CONTENTHISTORY_PREVIEW_SUBTITLE="Version note: %s" +COM_CONTENTHISTORY_PREVIEW_TITLE="Preview of Selected Item" +COM_CONTENTHISTORY_PREVIEW_VALUE="Value" +COM_CONTENTHISTORY_VERSION_NOTE="Version Note" diff --git a/Sites/pages/administrator/language/en-GB/en-GB.com_contenthistory.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.com_contenthistory.sys.ini new file mode 100644 index 00000000..9b738138 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.com_contenthistory.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +COM_CONTENTHISTORY="Content History" +COM_CONTENTHISTORY_XML_DESCRIPTION="Content History Component." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.com_cpanel.ini b/Sites/pages/administrator/language/en-GB/en-GB.com_cpanel.ini new file mode 100644 index 00000000..708a33de --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.com_cpanel.ini @@ -0,0 +1,46 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +COM_CPANEL="Control Panel" +COM_CPANEL_HEADER_SUBMENU="Submenu" +COM_CPANEL_HEADER_SYSTEM="System" +COM_CPANEL_LINK_CHECKIN="Global Check-in" +COM_CPANEL_LINK_CLEAR_CACHE="Clear Cache" +COM_CPANEL_LINK_DASHBOARD="Dashboard" +COM_CPANEL_LINK_EXTENSIONS="Install Extensions" +COM_CPANEL_LINK_GLOBAL_CONFIG="Global Configuration" +COM_CPANEL_LINK_SYSINFO="System Information" +COM_CPANEL_MESSAGES_BODY_NOCLOSE="There are important post-installation messages that require your attention." +COM_CPANEL_MESSAGES_BODYMORE_NOCLOSE="This information area won't appear when you have hidden all the messages." +COM_CPANEL_MESSAGES_REVIEW="Read Messages" +COM_CPANEL_MESSAGES_TITLE="You have post-installation messages" +; Translators: Don't touch the code part in the following message, Starting with ## Mod rewrite ... +COM_CPANEL_MSG_ADDNOSNIFF_BODY="

    Joomla is now shipped with additional security hardenings in the default htaccess.txt and web.config.txt files. These hardenings disable the so called MIME-type sniffing feature in web browsers. The sniffing leads to specific attack vectors, where scripts in normally harmless file formats (eg images) will be executed, leading to Cross-Site-Scripting vulnerabilities.

    The security team recommends to manually apply the necessary changes to existing .htaccess or web.config files, as those files can not be updated automatically.

    Changes for .htaccess
    Add the following lines before \"## Mod_rewrite in use.\":

    <IfModule mod_headers.c>\nHeader always set X-Content-Type-Options \"nosniff\"\n</IfModule>

    Changes for web.config
    Add the following lines right after \"</rewrite>\":

    <httpProtocol>\n  <customHeaders>\n    <add name=\"X-Content-Type-Options\" value=\"nosniff\" />\n  </customHeaders>\n</httpProtocol>
    " +COM_CPANEL_MSG_ADDNOSNIFF_TITLE=".htaccess & web.config Security Update" +COM_CPANEL_MSG_EACCELERATOR_BODY="eAccelerator is not compatible with Joomla! By selecting the Change to File Caching button below we will change the cache handler to file. If you want to use a different cache handler, please change it in the Global Configuration page." +COM_CPANEL_MSG_EACCELERATOR_BUTTON="Change to File." +COM_CPANEL_MSG_EACCELERATOR_TITLE="eAccelerator is not compatible with Joomla!" +COM_CPANEL_MSG_HTACCESS_BODY="A change to the default .htaccess and web.config files was made in Joomla! 3.4 to disallow folder listings by default. Users are recommended to implement this change in their files. Please see this page for more information." +COM_CPANEL_MSG_HTACCESS_TITLE=".htaccess & web.config Update" +COM_CPANEL_MSG_HTACCESSSVG_TITLE="Additional XSS protection for the usage of SVG files" +COM_CPANEL_MSG_HTACCESSSVG_BODY="

    Since 3.9.21 Joomla is shipped with an additional security rule in the default htaccess.txt. This rule will protect users of svg files from potential Cross-Site-Scripting (XSS) vulnerabilities.
    The security team recommends to manually apply the necessary changes to any existing .htaccess file, as this file can not be updated automatically.

    Changes for .htaccess

    <FilesMatch \"\.svg$\">\n  <IfModule mod_headers.c>\n    Header always set Content-Security-Policy \"script-src 'none'\"\n  </IfModule>\n</FilesMatch>

    Currently we are not aware of a method to conditionally configure this on IIS web servers, please contact your hosting provider for further assistance.

    " +COM_CPANEL_MSG_JOOMLA40_PRE_CHECKS_TITLE="Prepare for the next Major Release of Joomla" +COM_CPANEL_MSG_JOOMLA40_PRE_CHECKS_BODY="

    Beginning with Joomla! 4.0 we are raising the minimum server requirements. If you are seeing this message then your current configuration does not meet these new minimum requirements.

    The minimum requirements are the following:

    • PHP 7.2.5
    • MySQL 5.6
    • MariaDB 10.1
    • PostgreSQL 11.0
    • MS SQL will not be supported
    • MySQL using the legacy `ext/mysql` PHP extension will not be supported, either the MySQLi or \"MySQL (PDO)\" driver must be used instead
    • PostgreSQL using the `ext/pgsql` PHP extension will not be supported, the \"PostgreSQL (PDO)\" driver must be used instead

    Please contact your hosting provider to ask how you can meet these raised server requirements - it is usually a very simple change. When you meet these new requirements then this message will no longer be displayed.

    " +COM_CPANEL_MSG_LANGUAGEACCESS340_TITLE="You have possible issues with your multilingual settings" +COM_CPANEL_MSG_LANGUAGEACCESS340_BODY="Since Joomla! 3.4.0 you may have issues with the System - Language Filter plugin on your website. To fix them please open the Language Manager and save each content language manually to make sure an Access level is saved." +; The following two strings are deprecated and will be removed with 4.0 +COM_CPANEL_MSG_PHPVERSION_BODY="Beginning with Joomla! 3.3, the version of PHP this site is using will no longer be supported. Joomla! 3.3 will require at least PHP version 5.3.10 to provide enhanced security features to its users." +COM_CPANEL_MSG_PHPVERSION_TITLE="Your PHP Version Will Be Unsupported in Joomla! 3.3" +COM_CPANEL_MSG_ROBOTS_TITLE="robots.txt Update" +COM_CPANEL_MSG_ROBOTS_BODY="A change to the default robots.txt files was made in Joomla! 3.3 to allow Google to access templates and media files by default to improve SEO. This change is not applied automatically on upgrades and users are recommended to review the changes in the robots.txt.dist file and implement these changes in their own robots.txt file." +COM_CPANEL_MSG_STATS_COLLECTION_BODY="

    Since Joomla! 3.5 a statistics plugin will submit anonymous data to the Joomla Project. This will only submit the Joomla version, PHP version, database engine and version, and server operating system.

    This data is collected to ensure that future versions of Joomla can take advantage of the latest database and PHP features without affecting significant numbers of users. The need for this became clear when a minimum of PHP 5.3.10 was required when Joomla! 3.3 implemented the more secure Bcrypt passwords.

    In the interest of full transparency and to help developers this data is publicly available. An API and graphs will show the Joomla version, PHP versions and database engines in use.

    If you do not wish to provide the Joomla Project with this information you can disable the plugin called System - Joomla Statistics.

    " +COM_CPANEL_MSG_STATS_COLLECTION_TITLE="Stats Collection in Joomla" +COM_CPANEL_MSG_TEXTFILTER3919_BODY="

    As part of our security team's review, we have made some changes to the default settings for the global text filters in a new Joomla installation. The default setting for the 'Public', 'Guest' and 'Registered' groups is now 'No HTML'. As these changes are only applied to new installations, we strongly recommend that you review these changes and update your site from: System -> Global Configuration -> Text Filters

    " +COM_CPANEL_MSG_TEXTFILTER3919_TITLE="Updated Text Filter Recommendations" +COM_CPANEL_MSG_UPDATEDEFAULTSETTINGS_BODY="

    As part of our security team's review, we have made some changes to the default settings in a new Joomla installation. As these changes are only applied to new installations, we strongly recommend that you review these changes and update your site.

    The changed settings are:

    • Global Configuration > Text Filters: The default \"Administrator\" user group has changed from \"No Filtering\" to \"Default Blacklist\"
    • Users > Send Password: The option to send a user their password in plain text when an account is created is now disabled by default
    • Media Manager: Flash files (\"swf\" file extension and \"application/x-shockwave-flash\" MIME Type) are not allowed to be uploaded
    • Articles > Show Email: The option to show an email icon with articles is disabled by default

    We have created a dedicated documentation page explaining these changes.

    " +COM_CPANEL_MSG_UPDATEDEFAULTSETTINGS_TITLE="Updated site security recommendations" +COM_CPANEL_WELCOME_BEGINNERS_MESSAGE="

    Community resources are available for new users.

    " +COM_CPANEL_WELCOME_BEGINNERS_TITLE="Welcome to Joomla!" +COM_CPANEL_XML_DESCRIPTION="Control Panel component" diff --git a/Sites/pages/administrator/language/en-GB/en-GB.com_cpanel.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.com_cpanel.sys.ini new file mode 100644 index 00000000..13c00242 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.com_cpanel.sys.ini @@ -0,0 +1,10 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +COM_CPANEL="Control Panel" +COM_CPANEL_XML_DESCRIPTION="Control Panel component." + +COM_CPANEL_CPANEL_VIEW_DEFAULT_TITLE="Control Panel" +COM_CPANEL_CPANEL_VIEW_DEFAULT_TITLE_DESC="Shows the Joomla! Administration Dashboard page." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.com_fields.ini b/Sites/pages/administrator/language/en-GB/en-GB.com_fields.ini new file mode 100644 index 00000000..faa7b6ee --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.com_fields.ini @@ -0,0 +1,115 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +COM_FIELDS="Fields" +COM_FIELDS_BATCH_GROUP_LABEL="To Move or Copy your selection please select a group." +COM_FIELDS_BATCH_GROUP_OPTION_NONE="- No Group -" +COM_FIELDS_ERROR_UNIQUE_NAME="Another Field has the same name (remember it may be a trashed item or it may be already present as a custom field in another extension)." +COM_FIELDS_FIELDS_FILTER_SEARCH_DESC="Search in field name, title or note. Prefix with ID: to search for a field ID. Prefix with AUTHOR: to search for a field author." +COM_FIELDS_FIELD_CLASS_DESC="The class attributes of the field in the edit form. If multiple classes are needed, list them with spaces." +COM_FIELDS_FIELD_CLASS_LABEL="Field Class" +COM_FIELDS_FIELD_DEFAULT_VALUE_DESC="The default value of the field." +COM_FIELDS_FIELD_DEFAULT_VALUE_LABEL="Default Value" +COM_FIELDS_FIELD_DESCRIPTION_DESC="A description of the field that will be displayed in the label tooltip." +COM_FIELDS_FIELD_DISPLAY_AFTER_DISPLAY="After Display" +COM_FIELDS_FIELD_DISPLAY_AFTER_TITLE="After Title" +COM_FIELDS_FIELD_DISPLAY_BEFORE_DISPLAY="Before Display" +COM_FIELDS_FIELD_DISPLAY_DESC="Joomla offers some content events which are triggered during the content creation process. This is the place to define how the custom fields should be integrated into content." +COM_FIELDS_FIELD_DISPLAY_LABEL="Automatic Display" +COM_FIELDS_FIELD_DISPLAY_NO_DISPLAY="Do not automatically display" +COM_FIELDS_FIELD_EDITABLE_IN_ADMIN="Administrator" +COM_FIELDS_FIELD_EDITABLE_IN_BOTH="Both" +COM_FIELDS_FIELD_EDITABLE_IN_DESC="On which part of the site should the field be editable?" +COM_FIELDS_FIELD_EDITABLE_IN_LABEL="Editable In" +COM_FIELDS_FIELD_EDITABLE_IN_SITE="Site" +COM_FIELDS_FIELD_FORMOPTIONS_HEADING="Form Options" +COM_FIELDS_FIELD_GROUP_DESC="The group this field belongs to." +COM_FIELDS_FIELD_GROUP_LABEL="Field Group" +COM_FIELDS_FIELD_IMAGE_ALT_DESC="Alternative text used for visitors without access to images." +COM_FIELDS_FIELD_IMAGE_ALT_LABEL="Alt Text" +COM_FIELDS_FIELD_IMAGE_DESC="Image label." +COM_FIELDS_FIELD_IMAGE_LABEL="Image" +COM_FIELDS_FIELD_INVALID_DEFAULT_VALUE="The default value is invalid." +COM_FIELDS_FIELD_LABEL_DESC="The label of the field to display." +COM_FIELDS_FIELD_LABEL_FORM_CLASS_DESC="The class of the label in the form." +COM_FIELDS_FIELD_LABEL_FORM_CLASS_LABEL="Label Class" +COM_FIELDS_FIELD_LABEL_LABEL="Label" +COM_FIELDS_FIELD_LABEL_RENDER_CLASS_DESC="The class of the label in the output." +COM_FIELDS_FIELD_LABEL_RENDER_CLASS_LABEL="Label Class" +COM_FIELDS_FIELD_LANGUAGE_DESC="Assign a language to this field." +COM_FIELDS_FIELD_LAYOUT_DESC="Choose an alternate layout." +COM_FIELDS_FIELD_LAYOUT_LABEL="Layout" +COM_FIELDS_FIELD_NOTE_DESC="An optional note for the field." +COM_FIELDS_FIELD_NOTE_LABEL="Note" +COM_FIELDS_FIELD_N_ITEMS_ARCHIVED="%d fields archived" +COM_FIELDS_FIELD_N_ITEMS_ARCHIVED_1="%d field archived" +COM_FIELDS_FIELD_N_ITEMS_CHECKED_IN="%d fields checked in" +COM_FIELDS_FIELD_N_ITEMS_CHECKED_IN_0="No field checked in" +COM_FIELDS_FIELD_N_ITEMS_CHECKED_IN_1="%d field checked in" +COM_FIELDS_FIELD_N_ITEMS_DELETED="%d fields deleted" +COM_FIELDS_FIELD_N_ITEMS_DELETED_1="%d field deleted" +COM_FIELDS_FIELD_N_ITEMS_PUBLISHED="%d fields published" +COM_FIELDS_FIELD_N_ITEMS_PUBLISHED_1="%d field published" +COM_FIELDS_FIELD_N_ITEMS_TRASHED="%d fields trashed" +COM_FIELDS_FIELD_N_ITEMS_TRASHED_1="%d field trashed" +COM_FIELDS_FIELD_N_ITEMS_UNPUBLISHED="%d fields unpublished" +COM_FIELDS_FIELD_N_ITEMS_UNPUBLISHED_1="%d field unpublished" +COM_FIELDS_FIELD_PERMISSION_DELETE_DESC="New setting for delete actions on this field and the calculated setting based on the parent extension and group permissions." +COM_FIELDS_FIELD_PERMISSION_EDITSTATE_DESC="New setting for edit state actions on this field and the calculated setting based on the parent extension and group permissions." +COM_FIELDS_FIELD_PERMISSION_EDITVALUE_DESC="Who can edit the custom field value in the form editor?" +COM_FIELDS_FIELD_PERMISSION_EDIT_DESC="New setting for edit actions on this field and the calculated setting based on the parent extension and group permissions." +COM_FIELDS_FIELD_PLACEHOLDER_DESC="Placeholder text which will appear inside the field as a hint to the user for the required input." +COM_FIELDS_FIELD_PLACEHOLDER_LABEL="Placeholder" +COM_FIELDS_FIELD_RENDEROPTIONS_HEADING="Render Options" +COM_FIELDS_FIELD_RENDER_CLASS_DESC="The class attributes of the field when the field is rendered. If multiple classes are needed, list them with spaces." +COM_FIELDS_FIELD_RENDER_CLASS_LABEL="Render Class" +COM_FIELDS_FIELD_REQUIRED_DESC="Is this a mandatory field?" +COM_FIELDS_FIELD_REQUIRED_LABEL="Required" +COM_FIELDS_FIELD_SAVE_SUCCESS="Field saved" +COM_FIELDS_FIELD_SHOWLABEL_DESC="Show or Hide the label when the field renders." +COM_FIELDS_FIELD_SHOWLABEL_LABEL="Show Label" +COM_FIELDS_FIELD_TYPE_DESC="The type of the field." +COM_FIELDS_FIELD_TYPE_LABEL="Type" +COM_FIELDS_FIELD_USE_GLOBAL="Use settings from Plugin" +COM_FIELDS_GROUPS_FILTER_SEARCH_DESC="Search in field group title. Prefix with ID: to search for a field group ID." +COM_FIELDS_GROUP_N_ITEMS_ARCHIVED="%d field groups archived" +COM_FIELDS_GROUP_N_ITEMS_ARCHIVED_1="%d field group archived" +COM_FIELDS_GROUP_N_ITEMS_CHECKED_IN="%d field groups checked in" +COM_FIELDS_GROUP_N_ITEMS_CHECKED_IN_0="No field group checked in" +COM_FIELDS_GROUP_N_ITEMS_CHECKED_IN_1="%d field group checked in" +COM_FIELDS_GROUP_N_ITEMS_DELETED="%d field groups deleted" +COM_FIELDS_GROUP_N_ITEMS_DELETED_1="%d field group deleted" +COM_FIELDS_GROUP_N_ITEMS_PUBLISHED="%d field groups published" +COM_FIELDS_GROUP_N_ITEMS_PUBLISHED_1="%d field group published" +COM_FIELDS_GROUP_N_ITEMS_TRASHED="%d field groups trashed" +COM_FIELDS_GROUP_N_ITEMS_TRASHED_1="%d field group trashed" +COM_FIELDS_GROUP_N_ITEMS_UNPUBLISHED="%d field groups unpublished" +COM_FIELDS_GROUP_N_ITEMS_UNPUBLISHED_1="%d field group unpublished" +COM_FIELDS_GROUP_PERMISSION_CREATE_DESC="New setting for create actions in this field group and the calculated setting based on the parent extension permissions." +COM_FIELDS_GROUP_PERMISSION_DELETE_DESC="New setting for delete actions on this field group and the calculated setting based on the parent extension permissions." +COM_FIELDS_GROUP_PERMISSION_EDITOWN_DESC="New setting for edit own actions on this field group and the calculated setting based on the parent extension permissions." +COM_FIELDS_GROUP_PERMISSION_EDITSTATE_DESC="New setting for edit state actions on this field group and the calculated setting based on the parent extension permissions." +COM_FIELDS_GROUP_PERMISSION_EDITVALUE_DESC="Who can edit the field value in the form editor." +COM_FIELDS_GROUP_PERMISSION_EDIT_DESC="New setting for edit actions on this field group and the calculated setting based on the parent extension permissions." +COM_FIELDS_GROUP_SAVE_SUCCESS="Field Group saved" +COM_FIELDS_MUSTCONTAIN_A_TITLE_FIELD="Field must have a title." +COM_FIELDS_MUSTCONTAIN_A_TITLE_GROUP="Field Group must have a title." +COM_FIELDS_SYSTEM_PLUGIN_NOT_ENABLED="The System - Fields plugin is disabled. Custom fields will not display until you enable this plugin." +COM_FIELDS_VIEW_FIELDS_BATCH_OPTIONS="Batch process the selected fields." +COM_FIELDS_VIEW_FIELDS_SELECT_CATEGORY="- Select Assigned Category -" +COM_FIELDS_VIEW_FIELDS_SELECT_GROUP="- Select Field Group -" +COM_FIELDS_VIEW_FIELDS_SORT_GROUP_ASC="Field Group ascending" +COM_FIELDS_VIEW_FIELDS_SORT_GROUP_DESC="Field Group descending" +COM_FIELDS_VIEW_FIELDS_SORT_TYPE_ASC="Type ascending" +COM_FIELDS_VIEW_FIELDS_SORT_TYPE_DESC="Type descending" +COM_FIELDS_VIEW_FIELDS_TITLE="%s: Fields" +COM_FIELDS_VIEW_FIELD_ADD_TITLE="%s: New Field" +COM_FIELDS_VIEW_FIELD_EDIT_TITLE="%s: Edit Field" +COM_FIELDS_VIEW_FIELD_FIELDSET_GENERAL="General" +COM_FIELDS_VIEW_GROUPS_BATCH_OPTIONS="Batch process the selected field groups." +COM_FIELDS_VIEW_GROUPS_TITLE="%s: Field Groups" +COM_FIELDS_VIEW_GROUP_ADD_TITLE="%s: New Field Group" +COM_FIELDS_VIEW_GROUP_EDIT_TITLE="%s: Edit Field Group" +COM_FIELDS_XML_DESCRIPTION="Component to manage custom fields." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.com_fields.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.com_fields.sys.ini new file mode 100644 index 00000000..c8d0cdfb --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.com_fields.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +COM_FIELDS="Fields" +COM_FIELDS_XML_DESCRIPTION="Component to manage custom fields." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.com_finder.ini b/Sites/pages/administrator/language/en-GB/en-GB.com_finder.ini new file mode 100644 index 00000000..677a2181 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.com_finder.ini @@ -0,0 +1,242 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +COM_FINDER="Smart Search" +COM_FINDER_ALLOW_EMPTY_QUERY_DESC="Only if a filter is selected, allow an empty search string to initiate a search within the filter constraints." +COM_FINDER_ALLOW_EMPTY_QUERY_LABEL="Allow Empty Search" +COM_FINDER_AN_ERROR_HAS_OCCURRED="An Error Has Occurred" +COM_FINDER_CONFIG_ALLOW_EMPTY_QUERY_DESCRIPTION="Only if a filter is selected, allow an empty search string to initiate a search within the filter restraints." +COM_FINDER_CONFIG_ALLOW_EMPTY_QUERY_LABEL="Allow Empty Search" +COM_FINDER_CONFIG_BATCH_SIZE_DESCRIPTION="The batch size controls how many items are processed per batch. Large batch sizes require lots of memory whereas small batch sizes require less memory but execute more requests which tends to take longer." +COM_FINDER_CONFIG_BATCH_SIZE_LABEL="Indexer Batch Size" +COM_FINDER_CONFIG_DESCRIPTION_LENGTH_DESC="Description text for search results will be truncated to the specified character length." +COM_FINDER_CONFIG_DESCRIPTION_LENGTH_DESCRIPTION="Description text for search results will be truncated to the specified character length." +COM_FINDER_CONFIG_DESCRIPTION_LENGTH_LABEL="Description Length" +COM_FINDER_CONFIG_ENABLE_LOGGING_DESCRIPTION="Enable this option to create a log file in your site's logs folder during the index process. This file is useful for troubleshooting issues with the index process. It is recommended that logging be disabled unless necessary." +COM_FINDER_CONFIG_ENABLE_LOGGING_LABEL="Enable Logging" +COM_FINDER_CONFIG_EXPAND_ADVANCED_DESC="Toggle if the advanced search options should be expanded by default." +COM_FINDER_CONFIG_EXPAND_ADVANCED_DESCRIPTION="Toggle if the advanced search options should be expanded by default." +COM_FINDER_CONFIG_EXPAND_ADVANCED_LABEL="Expand Advanced Search" +COM_FINDER_CONFIG_FIELD_OPENSEARCH_DESCRIPTON_DESCRIPTION="Description displayed for this site as a search provider." +COM_FINDER_CONFIG_FIELD_OPENSEARCH_DESCRIPTON_LABEL="OpenSearch Description" +COM_FINDER_CONFIG_FIELD_OPENSEARCH_NAME_DESCRIPTION="Name displayed for this site as a search provider." +COM_FINDER_CONFIG_FIELD_OPENSEARCH_NAME_LABEL="OpenSearch Name" +COM_FINDER_CONFIG_GATHER_SEARCH_STATISTICS_DESCRIPTION="Record the search phrases submitted by visitors." +COM_FINDER_CONFIG_GATHER_SEARCH_STATISTICS_LABEL="Gather Search Statistics" +COM_FINDER_CONFIG_HILIGHT_CONTENT_SEARCH_TERMS_DESCRIPTION="Toggle if search terms should be highlighted in search results." +COM_FINDER_CONFIG_HILIGHT_CONTENT_SEARCH_TERMS_LABEL="Highlight Search Terms" +COM_FINDER_CONFIG_IMPORT_EXPORT="Import/Export" +COM_FINDER_CONFIG_IMPORT_EXPORT_HELP="Help" +COM_FINDER_CONFIG_IMPORT_EXPORT_INSTRUCTIONS="To export your configuration options, select the Export button in the toolbar above.

    To import an existing configuration, select the browse button to choose a file from your hard drive or copy/paste the data into the text field below and then select the Import button in the toolbar above." +COM_FINDER_CONFIG_IMPORT_FROM_FILE="Import From File:" +COM_FINDER_CONFIG_IMPORT_FROM_STRING="Import From Text:" +COM_FINDER_CONFIG_IMPORT_TOOLBAR_TITLE="Smart Search: Import/Export Configuration" +COM_FINDER_CONFIG_MEMORY_TABLE_LIMIT_DESCRIPTION="The memory table limit should not be changed unless you are getting errors indicating that the finder_tokens or finder_tokens_aggregate tables are full. The default is 30,000." +COM_FINDER_CONFIG_MEMORY_TABLE_LIMIT_LABEL="Memory Table Limit" +COM_FINDER_CONFIG_META_MULTIPLIER_DESCRIPTION="The multiplier is used to control how much influence matching text has on the overall relevance score of a search result. A multiplier is considered in relationship to the other multipliers. The metadata comes from a number of sources including the meta keywords and meta description, author names, etc." +COM_FINDER_CONFIG_META_MULTIPLIER_LABEL="Metadata Weight Multiplier" +COM_FINDER_CONFIG_MISC_MULTIPLIER_DESCRIPTION="The multiplier is used to control how much influence matching text has on the overall relevance score of a search result. A multiplier is considered in relationship to the other multipliers. The miscellaneous text comes from a number of sources including comments and other associated data." +COM_FINDER_CONFIG_MISC_MULTIPLIER_LABEL="Misc. Text Weight Multiplier" +COM_FINDER_CONFIG_PATH_MULTIPLIER_DESCRIPTION="The multiplier is used to control how much influence matching text has on the overall relevance score of a search result. A multiplier is considered in relationship to the other multipliers. The path text comes from the SEF URL of the content." +COM_FINDER_CONFIG_PATH_MULTIPLIER_LABEL="Path Text Weight Multiplier" +COM_FINDER_CONFIG_SHOW_ADVANCED_DESC="Toggle if users should be able to see advanced search options." +COM_FINDER_CONFIG_SHOW_ADVANCED_DESCRIPTION="Toggle if users should be able to see advanced search options." +COM_FINDER_CONFIG_SHOW_ADVANCED_LABEL="Advanced Search" +COM_FINDER_CONFIG_SHOW_ADVANCED_TIPS_DESCRIPTION="Toggle if users should be able to see advanced search tips." +COM_FINDER_CONFIG_SHOW_ADVANCED_TIPS_LABEL="Advanced Tips" +COM_FINDER_CONFIG_SHOW_AUTOSUGGEST_DESCRIPTION="Toggle if automatic search suggestions should be displayed." +COM_FINDER_CONFIG_SHOW_AUTOSUGGEST_LABEL="Search Suggestions" +COM_FINDER_CONFIG_SHOW_DATE_FILTERS_DESC="Show the start and end date filters in the advanced search." +COM_FINDER_CONFIG_SHOW_DATE_FILTERS_DESCRIPTION="Show the start and end date filters in the advanced search." +COM_FINDER_CONFIG_SHOW_DATE_FILTERS_LABEL="Date Filters" +COM_FINDER_CONFIG_SHOW_DESCRIPTION_DESC="Toggle if the description should be displayed with search results." +COM_FINDER_CONFIG_SHOW_DESCRIPTION_DESCRIPTION="Toggle if the description should be displayed with search results." +COM_FINDER_CONFIG_SHOW_DESCRIPTION_LABEL="Result Description" +COM_FINDER_CONFIG_SHOW_EXPLAINED_QUERY_DESC="Show or hide a detailed explanation of the search requested." +COM_FINDER_CONFIG_SHOW_EXPLAINED_QUERY_LABEL="Query Explanation" +; The following 4 strings are deprecated and will be removed with 4.0. +COM_FINDER_CONFIG_SHOW_FEED_DESC="Show the syndication feed link." +COM_FINDER_CONFIG_SHOW_FEED_LABEL="Show Feed" +COM_FINDER_CONFIG_SHOW_FEED_TEXT_DESC="Show the associated text with the feed, otherwise the title is shown in the feed." +COM_FINDER_CONFIG_SHOW_FEED_TEXT_LABEL="Show Feed Text" +COM_FINDER_CONFIG_SHOW_SUGGESTED_QUERY_DESC="Whether to suggest alternative search terms when a search produces no results." +COM_FINDER_CONFIG_SHOW_SUGGESTED_QUERY_LABEL="Did You Mean" +COM_FINDER_CONFIG_SHOW_URL_DESC="Show the associated URL that for the item." +COM_FINDER_CONFIG_SHOW_URL_DESCRIPTION="Show the associated URL for the item." +COM_FINDER_CONFIG_SHOW_URL_LABEL="Result URL" +COM_FINDER_CONFIG_SORT_DIRECTION_DESC="The direction in which to sort the search results." +COM_FINDER_CONFIG_SORT_DIRECTION_LABEL="Sort Direction" +COM_FINDER_CONFIG_SORT_OPTION_ASCENDING="Ascending" +COM_FINDER_CONFIG_SORT_OPTION_DESCENDING="Descending" +COM_FINDER_CONFIG_SORT_OPTION_LIST_PRICE="List price" +COM_FINDER_CONFIG_SORT_OPTION_RELEVANCE="Relevance" +COM_FINDER_CONFIG_SORT_OPTION_START_DATE="Date" +COM_FINDER_CONFIG_SORT_ORDER_DESC="The field on which to sort the search results." +COM_FINDER_CONFIG_SORT_ORDER_LABEL="Sort Field" +COM_FINDER_CONFIG_STEMMER_DESCRIPTION="The language stemmer to use. Choose snowball if a stemmer for your language is not available or you have multilingual content." +COM_FINDER_CONFIG_STEMMER_ENABLE_DESCRIPTION="Enable language stemming if available." +COM_FINDER_CONFIG_STEMMER_ENABLE_LABEL="Enable Stemmer" +COM_FINDER_CONFIG_STEMMER_FR="French Only" +COM_FINDER_CONFIG_STEMMER_LABEL="Stemmer" +COM_FINDER_CONFIG_STEMMER_PORTER_EN="English Only" +COM_FINDER_CONFIG_STEMMER_SNOWBALL="Snowball" +COM_FINDER_CONFIG_TEXT_MULTIPLIER_DESCRIPTION="The multiplier is used to control how much influence matching text has on the overall relevance score of a search result. A multiplier is considered in relationship to the other multipliers. The body text comes from the summary and/or body of the content." +COM_FINDER_CONFIG_TEXT_MULTIPLIER_LABEL="Body Text Weight Multiplier" +COM_FINDER_CONFIG_TITLE_MULTIPLIER_DESCRIPTION="The multiplier is used to control how much influence matching text has on the overall relevance score of a search result. A multiplier is considered in relationship to the other multipliers. The title text comes from the title of the content." +COM_FINDER_CONFIG_TITLE_MULTIPLIER_LABEL="Title Text Weight Multiplier" +COM_FINDER_CONFIGURATION="Smart Search: Options" +COM_FINDER_CREATE_FILTER="Create a filter." +COM_FINDER_EDIT_FILTER="Edit Filter" +COM_FINDER_EXPORT="Export" +COM_FINDER_FIELD_CREATED_BY_ALIAS_DESC="Displayed name of the filter creator." +COM_FINDER_FIELD_CREATED_BY_ALIAS_LABEL="Alias" +COM_FINDER_FIELD_CREATED_BY_DESC="Creator of the filter." +COM_FINDER_FIELD_CREATED_BY_LABEL="Created By" +COM_FINDER_FIELD_MODIFIED_DESCRIPTION="The date and time that the filter was last modified." +COM_FINDER_FIELDSET_INDEX_OPTIONS_DESCRIPTION="Indexing options" +COM_FINDER_FIELDSET_INDEX_OPTIONS_LABEL="Index" +COM_FINDER_FIELDSET_SEARCH_OPTIONS_DESCRIPTION="Smart Search options" +COM_FINDER_FIELDSET_SEARCH_OPTIONS_LABEL="Smart Search" +COM_FINDER_FILTER_BRANCH_LABEL="Search by %s" +COM_FINDER_FILTER_BY="Show %s:" +COM_FINDER_FILTER_CONTENT_MAP_DESC="Filter the indexed content by content map." +COM_FINDER_FILTER_CONTENT_MAP_LABEL="Select the Content Map" +COM_FINDER_FILTER_EDIT_TOOLBAR_TITLE="Smart Search: Edit Filter" +COM_FINDER_FILTER_END_DATE_DESCRIPTION="Format YYYY-MM-DD" +COM_FINDER_FILTER_END_DATE_LABEL="End Date" +COM_FINDER_FILTER_FIELDSET_DETAILS="Filter Details" +COM_FINDER_FILTER_FIELDSET_PARAMS="Filter Timeline" +COM_FINDER_FILTER_HIDE_ALL="Collapse all" +COM_FINDER_FILTER_MAP_COUNT="Map Count" +COM_FINDER_FILTER_MAP_COUNT_DESCRIPTION="The number of maps included in the filter." +COM_FINDER_FILTER_NEW_TOOLBAR_TITLE="Smart Search: New Filter" +COM_FINDER_FILTER_SEARCH_DESCRIPTION="Filter the list by a title." +COM_FINDER_FILTER_SELECT_CONTENT_MAP="- Select Content Map -" +COM_FINDER_FILTER_SELECT_ALL_LABEL="Search All" +COM_FINDER_FILTER_START_DATE_DESCRIPTION="Format YYYY-MM-DD" +COM_FINDER_FILTER_START_DATE_LABEL="Start Date" +COM_FINDER_FILTER_TIMESTAMP="Created On" +COM_FINDER_FILTER_SHOW_ALL="Expand all" +COM_FINDER_FILTER_TITLE_DESCRIPTION="The title of the filter." +COM_FINDER_FILTER_WHEN_AFTER="After" +COM_FINDER_FILTER_WHEN_BEFORE="Before" +COM_FINDER_FILTER_WHEN_END_DATE_DESCRIPTION="When to search relative to the end date (before, after or exactly)" +COM_FINDER_FILTER_WHEN_END_DATE_LABEL="When (End Date)" +COM_FINDER_FILTER_WHEN_EXACTLY="Exactly" +COM_FINDER_FILTER_WHEN_START_DATE_DESCRIPTION="When to search relative to the start date (before, after or exactly)" +COM_FINDER_FILTER_WHEN_START_DATE_LABEL="When (Start Date)" +COM_FINDER_FILTERS="Filters" +COM_FINDER_FILTERS_DELETE_CONFIRMATION="Are you sure you want to delete the selected filters(s)?" +COM_FINDER_FILTERS_TOOLBAR_TITLE="Smart Search: Search Filters" +COM_FINDER_GO="Go" +COM_FINDER_HEADING_CHILDREN="Maps" +COM_FINDER_HEADING_CREATED_BY="Created By" +COM_FINDER_HEADING_CREATED_BY_ASC="Created By ascending" +COM_FINDER_HEADING_CREATED_BY_DESC="Created By descending" +COM_FINDER_HEADING_CREATED_ON="Created On" +COM_FINDER_HEADING_CREATED_ON_ASC="Created On ascending" +COM_FINDER_HEADING_CREATED_ON_DESC="Created On descending" +COM_FINDER_HEADING_INDEXER="Smart Search Indexer" +COM_FINDER_HEADING_MAP_COUNT="Map Count" +COM_FINDER_HEADING_MAP_COUNT_ASC="Map Count ascending" +COM_FINDER_HEADING_MAP_COUNT_DESC="Map Count descending" +COM_FINDER_HEADING_NODES="Items" +COM_FINDER_IMPORT="Import" +COM_FINDER_INDEX="Index" +COM_FINDER_INDEX_CONFIRM_DELETE_PROMPT="Are you sure you want to delete the selected item(s)?" +COM_FINDER_INDEX_CONFIRM_PURGE_PROMPT="Are you sure you want to delete ALL items from the index? This can take a long time on large sites." +COM_FINDER_INDEX_DATE_INFO="Published Start: %s
    Published End: %s
    Content Start: %s
    Content End: %s" +COM_FINDER_INDEX_DATE_INFO_TITLE="Link Date Information" +COM_FINDER_INDEX_FILTER_BY_STATE="Any Published State" +COM_FINDER_INDEX_HEADING_DETAILS="Details" +COM_FINDER_INDEX_HEADING_INDEX_DATE="Last Updated" +COM_FINDER_INDEX_HEADING_INDEX_DATE_ASC="Last Updated ascending" +COM_FINDER_INDEX_HEADING_INDEX_DATE_DESC="Last Updated descending" +COM_FINDER_INDEX_HEADING_INDEX_TYPE="Type" +COM_FINDER_INDEX_HEADING_INDEX_TYPE_ASC="Type ascending" +COM_FINDER_INDEX_HEADING_INDEX_TYPE_DESC="Type descending" +COM_FINDER_INDEX_HEADING_LINK_URL="Raw URL" +COM_FINDER_INDEX_HEADING_LINK_URL_ASC="Raw URL ascending" +COM_FINDER_INDEX_HEADING_LINK_URL_DESC="Raw URL descending" +COM_FINDER_INDEX_NO_CONTENT="No content matches your search criteria." +COM_FINDER_INDEX_NO_DATA="No content has been indexed." +COM_FINDER_INDEX_PLUGIN_CONTENT_NOT_ENABLED="The Smart Search Content Plugin is disabled. Changes to content will not update the Smart Search index if you do not enable this plugin." +COM_FINDER_INDEX_PURGE_FAILED="Failed to delete selected items." +COM_FINDER_INDEX_PURGE_SUCCESS="All items have been deleted." +COM_FINDER_INDEX_SEARCH_DESC="Search in title, URL and last updated date." +COM_FINDER_INDEX_SEARCH_LABEL="Search Indexed Content" +COM_FINDER_INDEX_TIP="Start the indexer by pressing the Index button in the toolbar." +COM_FINDER_INDEX_TOOLBAR_PURGE="Clear Index" +COM_FINDER_INDEX_TOOLBAR_TITLE="Smart Search: Indexed Content" +COM_FINDER_INDEX_TYPE_FILTER="Any Type of Content" +COM_FINDER_INDEXER_HEADER_COMPLETE="Indexing Complete" +COM_FINDER_INDEXER_HEADER_ERROR="An Error Has Occurred" +COM_FINDER_INDEXER_HEADER_INIT="Starting Indexer" +COM_FINDER_INDEXER_HEADER_OPTIMIZE="Optimising Index" +COM_FINDER_INDEXER_HEADER_RUNNING="Indexer Running" +COM_FINDER_INDEXER_INVALID_DRIVER="The indexer does not support processing on the %s database driver." +COM_FINDER_INDEXER_INVALID_PARSER="Invalid parser type %s" +COM_FINDER_INDEXER_INVALID_STEMMER="Invalid stemmer type %s" +COM_FINDER_INDEXER_MESSAGE_COMPLETE="The indexing process is complete. It is now safe to close this window." +COM_FINDER_INDEXER_MESSAGE_INIT="The indexer is starting. Do not close this window." +COM_FINDER_INDEXER_MESSAGE_OPTIMIZE="The index tables are being optimised for the best possible performance. Do not close this window." +COM_FINDER_INDEXER_MESSAGE_RUNNING="Your content is being indexed. Do not close this window." +COM_FINDER_ITEM_X_ONLY="%s Only" +COM_FINDER_ITEMS="Content" +COM_FINDER_MAP_PUBLISH_FAILED="The selected map(s) could not be published. The returned error message is: %s." +COM_FINDER_MAP_PUBLISH_SUCCESS="The selected map(s) were published." +COM_FINDER_MAP_UNPUBLISH_FAILED="The selected map(s) could not be unpublished. The returned error message is: %s." +COM_FINDER_MAP_UNPUBLISH_SUCCESS="The selected map(s) were unpublished." +COM_FINDER_MAPS="Maps" +COM_FINDER_MAPS_BRANCH_LINK="Select to show the children in this branch." +COM_FINDER_MAPS_BRANCHES="Branches Only" +COM_FINDER_MAPS_CONFIRM_DELETE_PROMPT="Are you sure you want to delete the selected map(s)?" +COM_FINDER_MAPS_COUNT_PUBLISHED_ITEMS="Published Indexed Content" +COM_FINDER_MAPS_COUNT_UNPUBLISHED_ITEMS="Unpublished Indexed Content" +COM_FINDER_MAPS_MULTILANG="Note: Language filter system plugin has been enabled, so this branch will not be used." +COM_FINDER_MAPS_NO_CONTENT="No results to display. Either no content has been indexed or no content meets your filter criteria." +COM_FINDER_MAPS_RETURN_TO_BRANCHES="Return to Map Groups" +COM_FINDER_MAPS_SELECT_BRANCH="- Select Map Group -" +COM_FINDER_MAPS_SELECT_TYPE="- Select Type of Content -" +COM_FINDER_MAPS_TOOLBAR_TITLE="Smart Search: Content Maps" +COM_FINDER_MESSAGE_RETURNED="The following message was returned by the server:" +COM_FINDER_N_ITEMS_CHECKED_IN_0="No item checked in." +COM_FINDER_N_ITEMS_CHECKED_IN_1="%d item checked in." +COM_FINDER_N_ITEMS_CHECKED_IN_MORE="%d items checked in." +COM_FINDER_N_ITEMS_DELETED="%d items deleted." +COM_FINDER_N_ITEMS_DELETED_1="%d item deleted." +COM_FINDER_N_ITEMS_PUBLISHED="%d items published." +COM_FINDER_N_ITEMS_PUBLISHED_1="%d item published." +COM_FINDER_N_ITEMS_TRASHED="%d items trashed." +COM_FINDER_N_ITEMS_TRASHED_1="%d item trashed." +COM_FINDER_N_ITEMS_UNPUBLISHED="%d items unpublished." +COM_FINDER_N_ITEMS_UNPUBLISHED_1="%d item unpublished." +COM_FINDER_NO_ERROR_RETURNED="No error was returned. Make sure error reporting is enabled." +COM_FINDER_NO_FILTERS="No filters have been created yet." +COM_FINDER_NO_RESULTS="No results match your search criteria." +COM_FINDER_NO_RESULTS_OR_FILTERS="No results match your search criteria or no filters have been created yet." +COM_FINDER_QUERY_FILTER_TODAY="Today" +COM_FINDER_QUERY_OPERATOR_AND="And" +COM_FINDER_QUERY_OPERATOR_NOT="Not" +COM_FINDER_QUERY_OPERATOR_OR="Or" +COM_FINDER_SEARCH_FILTER_SEARCH_DESC="Search in filter title." +COM_FINDER_SEARCH_FILTER_SEARCH_LABEL="Search Filters" +COM_FINDER_SEARCH_LABEL="Search %s:" +COM_FINDER_SEARCH_SEARCH_QUERY_DESC="Search in content map title." +COM_FINDER_SEARCH_SEARCH_QUERY_LABEL="Search Content Maps" +COM_FINDER_SELECT_SEARCH_FILTER="Select filter" +COM_FINDER_STATISTICS="Statistics" +COM_FINDER_STATISTICS_LINK_TYPE_COUNT="Count" +COM_FINDER_STATISTICS_LINK_TYPE_HEADING="Link Type" +COM_FINDER_STATISTICS_LINK_TYPE_TOTAL="Total" +COM_FINDER_STATISTICS_STATS_DESCRIPTION="The indexed content on this site includes %s terms across %s links with %s attributes in %s branches." +COM_FINDER_STATISTICS_TITLE="Smart Search Statistics" +COM_FINDER_SUBMENU_FILTERS="Search Filters" +COM_FINDER_SUBMENU_INDEX="Indexed Content" +COM_FINDER_SUBMENU_MAPS="Content Maps" +COM_FINDER_UPDATER_MESSAGE_COMPLETE="Smart Search is up to date." +COM_FINDER_UPDATER_MESSAGE_OPTIMIZE="Smart Search is optimising." +COM_FINDER_UPDATER_MESSAGE_PROCESS="Smart Search is updating." +COM_FINDER_XML_DESCRIPTION="Smart Search." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.com_finder.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.com_finder.sys.ini new file mode 100644 index 00000000..44db1886 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.com_finder.sys.ini @@ -0,0 +1,9 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +COM_FINDER="Smart Search" +COM_FINDER_MENU_SEARCH_VIEW_DEFAULT_TEXT="The default search layout." +COM_FINDER_MENU_SEARCH_VIEW_DEFAULT_TITLE="Search" +COM_FINDER_XML_DESCRIPTION="Smart Search" diff --git a/Sites/pages/administrator/language/en-GB/en-GB.com_installer.ini b/Sites/pages/administrator/language/en-GB/en-GB.com_installer.ini new file mode 100644 index 00000000..43d0df51 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.com_installer.ini @@ -0,0 +1,281 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +COM_INSTALLER="Installer" +COM_INSTALLER_AUTHOR_INFORMATION="Author Information" +COM_INSTALLER_CACHETIMEOUT_DESC="For how many hours should Joomla cache update information. This is also the cache time for the Update Notification Plugin, if enabled" +COM_INSTALLER_CACHETIMEOUT_LABEL="Updates Caching (in hours)" +COM_INSTALLER_CONFIGURATION="Installer: Options" +COM_INSTALLER_CONFIRM_UNINSTALL="Are you sure you want to uninstall? Confirming will permanently delete the selected item(s)!" +COM_INSTALLER_CURRENT_VERSION="Installed" +COM_INSTALLER_DISCOVER_FILTER_SEARCH_DESC="Search in discovered extension name. Prefix with ID: to search for an extension ID." +COM_INSTALLER_DISCOVER_FILTER_SEARCH_LABEL="Search Discovered Extensions" +COM_INSTALLER_ENABLED_UPDATES_1=", 1 disabled site was enabled." +COM_INSTALLER_ENABLED_UPDATES_MORE=", %s disabled sites were enabled." +COM_INSTALLER_ERROR_DISABLE_DEFAULT_TEMPLATE_NOT_PERMITTED="Disable default template is not permitted." +COM_INSTALLER_ERROR_METHOD="Method Not Implemented" +COM_INSTALLER_ERROR_NO_EXTENSIONS_SELECTED="No extensions selected." +COM_INSTALLER_ERROR_NO_UPDATESITES_SELECTED="No update sites selected." +COM_INSTALLER_EXTENSION_DISABLE="Disable extension" +COM_INSTALLER_EXTENSION_DISABLED="Disabled extension" +COM_INSTALLER_EXTENSION_ENABLE="Enable extension" +COM_INSTALLER_EXTENSION_ENABLED="Enabled extension" +COM_INSTALLER_EXTENSION_PACKAGE_FILE="Extension package file" +COM_INSTALLER_EXTENSION_PROTECTED="Protected extension" +COM_INSTALLER_EXTENSION_PUBLISHED="Extension enabled." +COM_INSTALLER_EXTENSION_UNPUBLISHED="Extension disabled." +COM_INSTALLER_FAILED_TO_ENABLE_UPDATES=", failed to enable updates" +COM_INSTALLER_FILTER_LABEL="Search by Extension Name" +COM_INSTALLER_HEADER_DATABASE="Extensions: Database" +COM_INSTALLER_HEADER_DISCOVER="Extensions: Discover" +COM_INSTALLER_HEADER_INSTALL="Extensions: Install" +COM_INSTALLER_HEADER_LANGUAGES="Extensions: Install Languages" +COM_INSTALLER_HEADER_MANAGE="Extensions: Manage" +COM_INSTALLER_HEADER_UPDATE="Extensions: Update" +COM_INSTALLER_HEADER_UPDATESITES="Extensions: Update Sites" +COM_INSTALLER_HEADER_WARNINGS="Extensions: Warnings" +COM_INSTALLER_HEADING_CLIENT="Client" +COM_INSTALLER_HEADING_DETAILS_URL="Details URL" +COM_INSTALLER_HEADING_DETAILSURL="URL Details" +COM_INSTALLER_HEADING_FOLDER="Folder" +COM_INSTALLER_HEADING_FOLDER_ASC="Folder ascending" +COM_INSTALLER_HEADING_FOLDER_DESC="Folder descending" +COM_INSTALLER_HEADING_ID="ID" +COM_INSTALLER_HEADING_INSTALLTYPE="Install Type" +COM_INSTALLER_HEADING_LANGUAGE_TAG="Language Tag" +COM_INSTALLER_HEADING_LANGUAGE_TAG_ASC="Language Tag ascending" +COM_INSTALLER_HEADING_LANGUAGE_TAG_DESC="Language Tag descending" +COM_INSTALLER_HEADING_LOCATION="Location" +COM_INSTALLER_HEADING_LOCATION_ASC="Location ascending" +COM_INSTALLER_HEADING_LOCATION_DESC="Location descending" +COM_INSTALLER_HEADING_NAME="Name" +COM_INSTALLER_HEADING_NAME_ASC="Name ascending" +COM_INSTALLER_HEADING_NAME_DESC="Name descending" +COM_INSTALLER_HEADING_PACKAGE_ID="Package ID" +COM_INSTALLER_HEADING_PACKAGE_ID_ASC="Package ID ascending" +COM_INSTALLER_HEADING_PACKAGE_ID_DESC="Package ID descending" +COM_INSTALLER_HEADING_TYPE="Type" +COM_INSTALLER_HEADING_TYPE_ASC="Type ascending" +COM_INSTALLER_HEADING_TYPE_DESC="Type descending" +COM_INSTALLER_HEADING_UPDATESITE_NAME="Update Site" +COM_INSTALLER_HEADING_UPDATESITE_NAME_ASC="Update Site ascending" +COM_INSTALLER_HEADING_UPDATESITE_NAME_DESC="Update Site descending" +COM_INSTALLER_HEADING_UPDATESITEID="ID" +COM_INSTALLER_INSTALL_BUTTON="Install" +COM_INSTALLER_INSTALL_CHECKSUM_WRONG="The checksum verification failed. Please make sure you are using the correct update server!" +COM_INSTALLER_INSTALL_DIRECTORY="Install Folder" +COM_INSTALLER_INSTALL_ERROR="Error installing %s" +COM_INSTALLER_INSTALL_FROM_DIRECTORY="Install from Folder" +COM_INSTALLER_INSTALL_FROM_URL="Install from URL" +COM_INSTALLER_INSTALL_FROM_WEB="Install from Web" +COM_INSTALLER_INSTALL_FROM_WEB_ADD_TAB="Add "Install from Web" tab" +COM_INSTALLER_INSTALL_FROM_WEB_INFO="Joomla! Extensions Directory™ (JED) now available with Install from Web on this page." +COM_INSTALLER_INSTALL_FROM_WEB_TOS="By selecting "_QQ_"Add Install from Web tab"_QQ_" below, you agree to the JED Terms of Service and all applicable third party license terms." +COM_INSTALLER_INSTALL_LANGUAGE_SUCCESS="Installation of the %s language was successful." +COM_INSTALLER_INSTALL_SUCCESS="Installation of the %s was successful." +COM_INSTALLER_INSTALL_URL="Install URL" +COM_INSTALLER_INVALID_EXTENSION_UPDATE="Invalid extension update" +COM_INSTALLER_LABEL_HIDEPROTECTED_DESC="Hide protected extensions. Protected extensions can't be uninstalled." +COM_INSTALLER_LABEL_HIDEPROTECTED_LABEL="Hide Protected Extensions" +COM_INSTALLER_LANGUAGES_AVAILABLE_LANGUAGES="Available Languages" +COM_INSTALLER_LANGUAGES_FILTER_SEARCH_DESC="Search in language name and language tag." +COM_INSTALLER_LANGUAGES_FILTER_SEARCH_LABEL="Search Languages" +COM_INSTALLER_MANAGE_FILTER_SEARCH_DESC="Search in extension name. Prefix with ID: to search for an extension ID." +COM_INSTALLER_MANAGE_FILTER_SEARCH_LABEL="Search Extensions" +COM_INSTALLER_MINIMUM_STABILITY_ALPHA="Alpha" +COM_INSTALLER_MINIMUM_STABILITY_BETA="Beta" +COM_INSTALLER_MINIMUM_STABILITY_DESC="The minimum stability of the extension updates you would like to see. Development is the least stable, Stable is production quality. If an extension doesn't specify a level it is assumed to be Stable." +COM_INSTALLER_MINIMUM_STABILITY_DEV="Development" +COM_INSTALLER_MINIMUM_STABILITY_LABEL="Minimum Stability" +COM_INSTALLER_MINIMUM_STABILITY_STABLE="Stable" +COM_INSTALLER_MINIMUM_STABILITY_RC="Release Candidate" +COM_INSTALLER_MSG_DATABASE="This screen allows to you check that your database table structure is up to date with changes from the previous versions." +COM_INSTALLER_MSG_DATABASE_ADD_COLUMN="Table %2$s does not have column %3$s. (From file %1$s.)" +COM_INSTALLER_MSG_DATABASE_ADD_INDEX="Table %2$s does not have index %3$s. (From file %1$s.)" +COM_INSTALLER_MSG_DATABASE_CHANGE_COLUMN_TYPE="Table %2$s has the wrong type or attributes for column %3$s with type %4$s. (From file %1$s.)" +COM_INSTALLER_MSG_DATABASE_CHECKED_OK="%s database changes were checked." +COM_INSTALLER_MSG_DATABASE_CREATE_TABLE="Table %2$s does not exist. (From file %1$s.)" +COM_INSTALLER_MSG_DATABASE_DRIVER="Database driver: %s." +COM_INSTALLER_MSG_DATABASE_DROP_COLUMN="Table %2$s should not have column %3$s. (From file %1$s.)" +COM_INSTALLER_MSG_DATABASE_DROP_INDEX="Table %2$s should not have index %3$s. (From file %1$s.)" +COM_INSTALLER_MSG_DATABASE_ERRORS="Warning: Database is not up to date!" +COM_INSTALLER_MSG_DATABASE_FILTER_ERROR="No default text filters found." +COM_INSTALLER_MSG_DATABASE_INFO="Other Information" +COM_INSTALLER_MSG_DATABASE_OK="Database table structure is up to date." +COM_INSTALLER_MSG_DATABASE_SCHEMA_ERROR="Database schema version (%s) does not match CMS version (%s)." +COM_INSTALLER_MSG_DATABASE_SCHEMA_VERSION="Database schema version (in #__schemas): %s." +COM_INSTALLER_MSG_DATABASE_SKIPPED="%s database changes did not alter table structure and were skipped." +COM_INSTALLER_MSG_DATABASE_UPDATE_VERSION="Update version (in #__extensions): %s." +COM_INSTALLER_MSG_DATABASE_UPDATEVERSION_ERROR="Database update version (%s) does not match CMS version (%s)." +COM_INSTALLER_MSG_DATABASE_UTF8_CONVERSION_UTF8="The Joomla! Core database tables have not been converted yet to UTF-8." +COM_INSTALLER_MSG_DATABASE_UTF8_CONVERSION_UTF8MB4="The Joomla! Core database tables have not been converted yet to UTF-8 Multibyte (utf8mb4)." +COM_INSTALLER_MSG_DESCFTP="For installing or uninstalling Extensions, Joomla will most likely need your FTP account details. Please enter them in the form fields below." +COM_INSTALLER_MSG_DESCFTPTITLE="FTP Login Details" +COM_INSTALLER_MSG_DISCOVER_DESCRIPTION="Discover extensions that have not gone through the normal installation process." +COM_INSTALLER_MSG_DISCOVER_FAILEDTOPURGEEXTENSIONS="Failed to clear discovered extensions" +COM_INSTALLER_MSG_DISCOVER_INSTALLFAILED="Discover install failed." +COM_INSTALLER_MSG_DISCOVER_INSTALLSUCCESSFUL="Discover install successful." +COM_INSTALLER_MSG_DISCOVER_NOEXTENSION="No extensions have been discovered. Select Discover to find new extensions that might be available for install." +COM_INSTALLER_MSG_DISCOVER_NOEXTENSIONSELECTED="No extension selected." +COM_INSTALLER_MSG_DISCOVER_PURGEDDISCOVEREDEXTENSIONS="Cleared discovered extensions." +COM_INSTALLER_MSG_ERROR_CANT_CONNECT_TO_UPDATESERVER="Can't connect to %s" +COM_INSTALLER_MSG_INSTALL_ENTER_A_URL="Please enter a URL" +COM_INSTALLER_MSG_INSTALL_INVALID_URL="Invalid URL" +COM_INSTALLER_MSG_INSTALL_INVALID_URL_SCHEME="Please enter a valid URL starting with http or https." +COM_INSTALLER_MSG_INSTALL_NO_FILE_SELECTED="No file selected." +COM_INSTALLER_MSG_INSTALL_PATH_DOES_NOT_HAVE_A_VALID_PACKAGE="Path does not have a valid package." +COM_INSTALLER_MSG_INSTALL_PLEASE_ENTER_A_PACKAGE_DIRECTORY="Please enter a package folder." +COM_INSTALLER_MSG_INSTALL_PLEASE_SELECT_A_DIRECTORY="Please select a folder." +COM_INSTALLER_MSG_INSTALL_PLEASE_SELECT_A_PACKAGE="Please select a package location." +COM_INSTALLER_MSG_INSTALL_WARNINSTALLFILE="The installer can't continue until file uploads are enabled for the server." +COM_INSTALLER_MSG_INSTALL_WARNINSTALLUPLOADERROR="There was an error uploading this file to the server." +COM_INSTALLER_MSG_INSTALL_WARNINSTALLZLIB="The installer can't continue until Zlib is installed." +COM_INSTALLER_MSG_LANGUAGES_CANT_FIND_REMOTE_MANIFEST="The installer can't get the URL to the XML manifest file of the %s language." +COM_INSTALLER_MSG_LANGUAGES_CANT_FIND_REMOTE_PACKAGE="The installer can't get the URL to the remote %s language." +COM_INSTALLER_MSG_LANGUAGES_NOLANGUAGES="There are no available languages to install at the moment. Please select the "Find languages" button to check for updates on the Joomla! Languages server. You will need an internet connection for this to work." +COM_INSTALLER_MSG_LANGUAGES_TRY_LATER="Try again later or contact the language team coordinator." +COM_INSTALLER_MSG_MANAGE_NOEXTENSION="There are no extensions installed matching your query." +COM_INSTALLER_MSG_MANAGE_NOUPDATESITE="There are no update sites matching your query." +COM_INSTALLER_MSG_N_DATABASE_ERROR_PANEL="%d Database Problems Found." +COM_INSTALLER_MSG_N_DATABASE_ERROR_PANEL_1="1 Database Problem Found." +COM_INSTALLER_MSG_UPDATE_ERROR="Error updating %s." +COM_INSTALLER_MSG_UPDATE_NODESC="No description available for this item." +COM_INSTALLER_MSG_UPDATE_NOUPDATES="There are no updates available at the moment. Please check again later." +COM_INSTALLER_MSG_UPDATE_SITES_COUNT_CHECK="Some update sites are disabled. You may want to check the Update Sites Manager." +COM_INSTALLER_MSG_UPDATE_SUCCESS="Updating %s was successful." +COM_INSTALLER_MSG_UPDATE_UPDATE="Update" +COM_INSTALLER_MSG_UPDATESITES_DELETE_ERROR="An error has occurred while trying to delete "_QQ_"%s"_QQ_" update site: %s." +COM_INSTALLER_MSG_UPDATESITES_DELETE_CANNOT_DELETE="%s update site cannot be deleted." +COM_INSTALLER_MSG_UPDATESITES_N_DELETE_UPDATESITES_DELETED="%s update sites have been deleted." +COM_INSTALLER_MSG_UPDATESITES_N_DELETE_UPDATESITES_DELETED_1="1 update site has been deleted." +COM_INSTALLER_MSG_UPDATESITES_REBUILD_EXTENSION_PLUGIN_NOT_ENABLED="The Joomla Extension Plugin is disabled. This plugin must be enabled to rebuild the update sites." +COM_INSTALLER_MSG_UPDATESITES_REBUILD_MESSAGE="Update sites have been rebuilt. No extension with an update site has been discovered." +COM_INSTALLER_MSG_UPDATESITES_REBUILD_NOT_PERMITTED="Rebuilding update sites is not permitted." +COM_INSTALLER_MSG_UPDATESITES_REBUILD_WARNING="Update sites have been rebuilt. No extension with updates sites discovered." +COM_INSTALLER_MSG_UPDATESITES_REBUILD_SUCCESS="Update sites have been rebuilt from manifest files." +COM_INSTALLER_MSG_WARNING_NO_LANGUAGES_UPDATESERVER="The update table is not up to date. Please rebuild your update server table" +COM_INSTALLER_MSG_WARNINGFURTHERINFO="Further information on warnings" +COM_INSTALLER_MSG_WARNINGFURTHERINFODESC="For more information on warnings, see the Joomla! Documentation Site." +COM_INSTALLER_MSG_WARNINGS_FILEUPLOADISDISABLEDDESC="File uploads are required to upload extensions into the installer." +COM_INSTALLER_MSG_WARNINGS_FILEUPLOADSDISABLED="File uploads disabled." +COM_INSTALLER_MSG_WARNINGS_JOOMLATMPNOTSET="The Joomla temporary folder is not set." +COM_INSTALLER_MSG_WARNINGS_JOOMLATMPNOTSETDESC="The Joomla temporary folder is where Joomla copies an extension, extracts the extension and the files are copied into the correct directories. If this configuration is not set in configuration.php ($tmp_path) then you won't be able to upload extensions. Create a folder to enable Joomla to write to the folder to fix the issue." +COM_INSTALLER_MSG_WARNINGS_JOOMLATMPNOTWRITEABLE="The Joomla temporary folder is not writable or does not exist." +COM_INSTALLER_MSG_WARNINGS_JOOMLATMPNOTWRITEABLEDESC="The Joomla temporary folder is not writeable by the Joomla instance, or may not exist, which may cause issues when trying to upload extensions to Joomla. If you are having issues uploading extensions, make sure the folder defined in your configuration.php exists or check the '%s' and set it to be writeable and see if this fixes the issue." +COM_INSTALLER_MSG_WARNINGS_LOWMEMORYDESC="Low PHP memory limit." +COM_INSTALLER_MSG_WARNINGS_LOWMEMORYWARN="Your PHP memory limit is set below 8MB which may cause some issues when installing large extensions. Please set your memory limit to at least 16MB." +COM_INSTALLER_MSG_WARNINGS_MEDMEMORYDESC="Potentially low PHP memory limit." +COM_INSTALLER_MSG_WARNINGS_MEDMEMORYWARN="Your PHP memory limit is set below 16MB which may cause some issues when installing large extensions. Please set your memory limit to at least 16MB." +COM_INSTALLER_MSG_WARNINGS_NONE="No warnings detected." +COM_INSTALLER_MSG_WARNINGS_NOTCOMPLETE="

    Warning: Update Not Complete!

    The update is only partially complete. Please do the second update to complete the process.

    " +COM_INSTALLER_MSG_WARNINGS_NOTICE="There are some warnings detected." +COM_INSTALLER_MSG_WARNINGS_PHPUPLOADNOTSET="The PHP temporary folder is not set." +COM_INSTALLER_MSG_WARNINGS_PHPUPLOADNOTSETDESC="The PHP temporary folder is the folder that PHP uses to store an uploaded file before Joomla can access this file. Whilst the folder not being set isn't always a problem, if you are having issues with manifest files not being detected or uploaded files not being detected, setting this in your php.ini file might fix the issue." +COM_INSTALLER_MSG_WARNINGS_PHPUPLOADNOTWRITEABLE="The PHP temporary folder is not writeable." +COM_INSTALLER_MSG_WARNINGS_PHPUPLOADNOTWRITEABLEDESC="The PHP temporary folder is not writeable by the Joomla! instance, which may cause issues when trying to upload extensions to Joomla. If you are having issues uploading extensions, check the '%s' and set it to be writeable and see if this fixes the issue." +COM_INSTALLER_MSG_WARNINGS_SMALLPOSTSIZE="Small PHP maximum POST size." +COM_INSTALLER_MSG_WARNINGS_SMALLPOSTSIZEDESC="The maximum POST size sets the most amount of data that can be sent via POST to the server. This includes form submissions for articles, media (images, videos) and packages. This value is less than 8MB which may impact on uploading large packages. This is set in the php.ini under post_max_size." +COM_INSTALLER_MSG_WARNINGS_SMALLUPLOADSIZE="Maximum PHP file upload size is too small: This is set in php.ini in both upload_max_filesize and post_max_size settings of your PHP settings (located in php.ini and/or .htaccess file)." +COM_INSTALLER_MSG_WARNINGS_SMALLUPLOADSIZEDESC="The maximum file size for uploads is set to less than 8MB which may impact on uploading large packages." +COM_INSTALLER_MSG_WARNINGS_UPDATE_NOTICE="Before updating ensure that the update is compatible with your Joomla! installation.
    You are strongly advised to make a backup of your installation before you start updating." +COM_INSTALLER_MSG_WARNINGS_UPLOADBIGGERTHANPOST="PHP Upload Size bigger than POST size." +COM_INSTALLER_MSG_WARNINGS_UPLOADBIGGERTHANPOSTDESC="The value of the upload_max_filesize in the php.ini file is greater than the post_max_size variable. The post_max_size variable will take precedence and block requests larger than it. This is generally a server misconfiguration when trying to increase upload sizes. Please increase the upload_max_filesize to at least match the post_max_size variable or vice versa." +COM_INSTALLER_MSG_WARNINGS_UPLOADFILETOOBIG="The selected file cannot be uploaded as it is bigger than the maximum upload size." +COM_INSTALLER_N_EXTENSIONS_PUBLISHED="%d extensions enabled." +COM_INSTALLER_N_EXTENSIONS_PUBLISHED_1="%d extension enabled." +COM_INSTALLER_N_EXTENSIONS_UNPUBLISHED="%d extensions disabled." +COM_INSTALLER_N_EXTENSIONS_UNPUBLISHED_1="%d extension disabled." +COM_INSTALLER_N_UPDATESITES_PUBLISHED="%d update sites enabled." +COM_INSTALLER_N_UPDATESITES_PUBLISHED_1="%d update site enabled." +COM_INSTALLER_N_UPDATESITES_UNPUBLISHED="%d update sites disabled." +COM_INSTALLER_N_UPDATESITES_UNPUBLISHED_1="%d update site disabled." +COM_INSTALLER_NEW_INSTALL="New Install" +COM_INSTALLER_NEW_VERSION="Available" +COM_INSTALLER_NO_INSTALL_TYPE_FOUND="No Install Type Found" +COM_INSTALLER_NO_INSTALLATION_PLUGINS_FOUND="No installation plugin has been enabled. At least one must be enabled to be able to use the installer. Go to the Plugin Manager to enable the plugins." +COM_INSTALLER_PACKAGE_DOWNLOAD_FAILED="Failed to download package. Download it and install manually from %1$s." +COM_INSTALLER_PACKAGE_FILE="Package File" +COM_INSTALLER_PREFERENCES_DESCRIPTION="Fine tune how extensions installation and updates work." +COM_INSTALLER_PREFERENCES_LABEL="Preferences" +COM_INSTALLER_REINSTALL_BUTTON="Reinstall" +COM_INSTALLER_SHOW_JED_INFORMATION_DESC="Show or hide the information at the top of the installer page about the Joomla! Extensions Directory™." +COM_INSTALLER_SHOW_JED_INFORMATION_HIDE_MESSAGE="Hide message" +COM_INSTALLER_SHOW_JED_INFORMATION_LABEL="Joomla! Extensions Directory" +COM_INSTALLER_SHOW_JED_INFORMATION_SHOW_MESSAGE="Show message" +COM_INSTALLER_SHOW_JED_INFORMATION_TOOLTIP="Opens Installer Options for setting to hide this Joomla! Extensions Directory™ message." +COM_INSTALLER_SUBMENU_DATABASE="Database" +COM_INSTALLER_SUBMENU_DISCOVER="Discover" +COM_INSTALLER_SUBMENU_INSTALL="Install" +COM_INSTALLER_SUBMENU_LANGUAGES="Install Languages" +COM_INSTALLER_SUBMENU_MANAGE="Manage" +COM_INSTALLER_SUBMENU_UPDATE="Update" +COM_INSTALLER_SUBMENU_UPDATESITES="Update Sites" +COM_INSTALLER_SUBMENU_WARNINGS="Warnings" +COM_INSTALLER_TITLE_DATABASE="Extensions: Database" +COM_INSTALLER_TITLE_DISCOVER="Extensions: Discover" +COM_INSTALLER_TITLE_INSTALL="Extensions: Install" +COM_INSTALLER_TITLE_LANGUAGES="Extensions: Install Languages" +COM_INSTALLER_TITLE_MANAGE="Extension: Manage" +COM_INSTALLER_TITLE_UPDATE="Extension: Update" +COM_INSTALLER_TITLE_UPDATESITES="Extensions: Update Sites" +COM_INSTALLER_TITLE_WARNINGS="Extensions: Warnings" +COM_INSTALLER_TOOLBAR_DATABASE_FIX="Fix" +COM_INSTALLER_TOOLBAR_DISCOVER="Discover" +COM_INSTALLER_TOOLBAR_FIND_LANGUAGES="Find languages" +COM_INSTALLER_TOOLBAR_FIND_UPDATES="Find Updates" +COM_INSTALLER_TOOLBAR_INSTALL="Install" +COM_INSTALLER_TOOLBAR_PURGE="Clear Cache" +COM_INSTALLER_TOOLBAR_UPDATE="Update" +COM_INSTALLER_TYPE_CLIENT="Location" +COM_INSTALLER_TYPE_COMPONENT="Component" +COM_INSTALLER_TYPE_FILE="File" +COM_INSTALLER_TYPE_LANGUAGE="Language" +COM_INSTALLER_TYPE_LIBRARY="Library" +COM_INSTALLER_TYPE_MODULE="Module" +COM_INSTALLER_TYPE_NONAPPLICABLE="N/A" +COM_INSTALLER_TYPE_PACKAGE="Package" +COM_INSTALLER_TYPE_PLUGIN="Plugin" +COM_INSTALLER_TYPE_TEMPLATE="Template" +COM_INSTALLER_TYPE_TYPE_COMPONENT="component" +COM_INSTALLER_TYPE_TYPE_FILE="file" +COM_INSTALLER_TYPE_TYPE_LANGUAGE="language" +COM_INSTALLER_TYPE_TYPE_LIBRARY="library" +COM_INSTALLER_TYPE_TYPE_MODULE="module" +COM_INSTALLER_TYPE_TYPE_PACKAGE="package" +COM_INSTALLER_TYPE_TYPE_PLUGIN="plugin" +COM_INSTALLER_TYPE_TYPE_TEMPLATE="template" +COM_INSTALLER_UNABLE_TO_FIND_INSTALL_PACKAGE="Unable to find install package" +COM_INSTALLER_UNABLE_TO_INSTALL_JOOMLA_PACKAGE="The Joomla package cannot be installed through the Extension Manager. Please use the Joomla! Update component to update Joomla." +COM_INSTALLER_UNINSTALL_ERROR="Error uninstalling %s." +; This string is deprecated and will be removed with 4.0. +COM_INSTALLER_UNINSTALL_LANGUAGE="A language should always have been installed as a package.
    To uninstall a language, filter type by package and uninstall the package." +COM_INSTALLER_UNINSTALL_SUCCESS="Uninstalling the %s was successful." +COM_INSTALLER_UNPACK_ERROR="Failed to extract file: %s" +COM_INSTALLER_UPDATE_FILTER_SEARCH_DESC="Search in extension name. Prefix with ID:, UID: or EID: to search for an update ID, update site ID or extension ID." +COM_INSTALLER_UPDATE_FILTER_SEARCH_LABEL="Search Extensions with Updates" +COM_INSTALLER_UPDATESITE_DISABLE="Disable update site" +COM_INSTALLER_UPDATESITE_DISABLED="Disabled update site" +COM_INSTALLER_UPDATESITE_ENABLE="Enable update site" +COM_INSTALLER_UPDATESITE_ENABLED="Enabled update site" +COM_INSTALLER_UPDATESITES_FILTER_SEARCH_DESC="Search in extension name. Prefix with ID: to search for an update site ID." +COM_INSTALLER_UPDATESITES_FILTER_SEARCH_LABEL="Search Update Sites" +COM_INSTALLER_UPLOAD_AND_INSTALL="Upload & Install" +COM_INSTALLER_UPLOAD_INSTALL_JOOMLA_EXTENSION="Upload & Install Joomla Extension" +COM_INSTALLER_UPLOAD_PACKAGE_FILE="Upload Package File" +COM_INSTALLER_VALUE_CLIENT_SELECT="- Select Location -" +COM_INSTALLER_VALUE_FOLDER_NONAPPLICABLE="N/A" +COM_INSTALLER_VALUE_FOLDER_SELECT="- Select Folder -" +COM_INSTALLER_VALUE_STATE_SELECT="- Select Status -" +COM_INSTALLER_VALUE_TYPE_SELECT="- Select Type -" +COM_INSTALLER_WEBINSTALLER_INSTALL_OBSOLETE="The Install from Web plugin needs to be updated." +COM_INSTALLER_WEBINSTALLER_INSTALL_UPDATE_AVAILABLE="There is a new update available for the Install from Web plugin. It is advisable that you update as soon as possible." +COM_INSTALLER_WEBINSTALLER_INSTALL_WEB_CONFIRM="Please confirm the installation by selecting the Install button" +COM_INSTALLER_WEBINSTALLER_INSTALL_WEB_CONFIRM_NAME="Extension Name" +COM_INSTALLER_WEBINSTALLER_INSTALL_WEB_CONFIRM_URL="Install from" +COM_INSTALLER_WEBINSTALLER_INSTALL_WEB_LOADING="Loading ..." +COM_INSTALLER_WEBINSTALLER_INSTALL_WEB_LOADING_ERROR="Can't connect to the Joomla! server. Please try again later." +COM_INSTALLER_WEBINSTALLER_LOAD_APPS="Select to load extensions browser" +COM_INSTALLER_XML_DESCRIPTION="Installer component for adding, removing and upgrading extensions" +JLIB_RULES_SETTING_NOTES="Changes apply to this component only.
    Inherited - a Global Configuration setting or higher level setting is applied.
    Denied always wins - whatever is set at the Global or higher level and applies to all child elements.
    Allowed will enable the action for this component unless overruled by a Global Configuration setting." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.com_installer.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.com_installer.sys.ini new file mode 100644 index 00000000..da77ddbb --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.com_installer.sys.ini @@ -0,0 +1,23 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +COM_INSTALLER="Installer" +COM_INSTALLER_DATABASE_VIEW_DEFAULT_DESC="Check and fix any database issues with your website." +COM_INSTALLER_DATABASE_VIEW_DEFAULT_TITLE="Check Database" +COM_INSTALLER_DISCOVER_VIEW_DEFAULT_DESC="Discover extensions that have not gone through the normal installation process." +COM_INSTALLER_DISCOVER_VIEW_DEFAULT_TITLE="Discover Extensions" +COM_INSTALLER_INSTALL_VIEW_DEFAULT_DESC="Install extensions into your Joomla! installation." +COM_INSTALLER_INSTALL_VIEW_DEFAULT_TITLE="Install Extensions" +COM_INSTALLER_LANGUAGES_VIEW_DEFAULT_DESC="Install Language packs into your Joomla! website." +COM_INSTALLER_LANGUAGES_VIEW_DEFAULT_TITLE="Install Languages" +COM_INSTALLER_MANAGE_VIEW_DEFAULT_DESC="Manage extensions that are already installed on your Joomla! website." +COM_INSTALLER_MANAGE_VIEW_DEFAULT_TITLE="Manage Extensions" +COM_INSTALLER_UPDATESITES_VIEW_DEFAULT_DESC="Manage "_QQ_"Update Sites"_QQ_" for various installed extensions." +COM_INSTALLER_UPDATESITES_VIEW_DEFAULT_TITLE="Update Sites" +COM_INSTALLER_UPDATE_VIEW_DEFAULT_DESC="Find and Install updates for the installed extensions." +COM_INSTALLER_UPDATE_VIEW_DEFAULT_TITLE="Update Extensions" +COM_INSTALLER_WARNINGS_VIEW_DEFAULT_DESC="Displays warnings related to your installed extensions." +COM_INSTALLER_WARNINGS_VIEW_DEFAULT_TITLE="Warnings" +COM_INSTALLER_XML_DESCRIPTION="Installer component for adding, removing and upgrading extensions." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.com_joomlaupdate.ini b/Sites/pages/administrator/language/en-GB/en-GB.com_joomlaupdate.ini new file mode 100644 index 00000000..80f613b8 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.com_joomlaupdate.ini @@ -0,0 +1,89 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +COM_JOOMLAUPDATE_CHECKED_UPDATES="Checked for updates." +COM_JOOMLAUPDATE_CONFIGURATION="Joomla Update: Options" +COM_JOOMLAUPDATE_CONFIG_CUSTOMURL_DESC="This is a custom XML update source URL, used only when the "Update Source" option is set to "Custom URL"." +COM_JOOMLAUPDATE_CONFIG_CUSTOMURL_LABEL="Custom URL" +COM_JOOMLAUPDATE_CONFIG_SOURCES_DESC="Configure where Joomla gets its update information from." +COM_JOOMLAUPDATE_CONFIG_SOURCES_LABEL="Update Source" +COM_JOOMLAUPDATE_CONFIG_UPDATESOURCE_CUSTOM="Custom URL" +COM_JOOMLAUPDATE_CONFIG_UPDATESOURCE_CUSTOM_ERROR="The custom URL field is empty." +COM_JOOMLAUPDATE_CONFIG_UPDATESOURCE_DEFAULT="Default" +COM_JOOMLAUPDATE_CONFIG_UPDATESOURCE_DESC="The update channel Joomla will use to find out if there is an update available." +COM_JOOMLAUPDATE_CONFIG_UPDATESOURCE_LABEL="Update Channel" +COM_JOOMLAUPDATE_CONFIG_UPDATESOURCE_NEXT="Joomla Next" +COM_JOOMLAUPDATE_CONFIG_UPDATESOURCE_TESTING="Testing" +COM_JOOMLAUPDATE_FAILED_TO_CHECK_UPDATES="Failed to check for updates." +COM_JOOMLAUPDATE_MINIMUM_STABILITY_ALPHA="Alpha" +COM_JOOMLAUPDATE_MINIMUM_STABILITY_BETA="Beta" +COM_JOOMLAUPDATE_MINIMUM_STABILITY_DESC="The minimum stability of the extension updates you would like to see. Development is the least stable, Stable is production quality. If an extension doesn't specify a level it is assumed to be Stable." +COM_JOOMLAUPDATE_MINIMUM_STABILITY_DEV="Development" +COM_JOOMLAUPDATE_MINIMUM_STABILITY_LABEL="Minimum Stability" +COM_JOOMLAUPDATE_MINIMUM_STABILITY_RC="Release Candidate" +COM_JOOMLAUPDATE_MINIMUM_STABILITY_STABLE="Stable" +COM_JOOMLAUPDATE_OVERVIEW="Joomla Update" +COM_JOOMLAUPDATE_TOOLBAR_CHECK="Check for Updates" +COM_JOOMLAUPDATE_UPDATE_LOG_CLEANUP="Cleaning up after installation." +COM_JOOMLAUPDATE_UPDATE_LOG_COMPLETE="Update to version %s is complete." +; The following two strings are deprecated and will be removed with 4.0 +COM_JOOMLAUPDATE_UPDATE_LOG_CONFIRM_FINALISE="The confirm for the finalise step has passed." +COM_JOOMLAUPDATE_UPDATE_LOG_CONFIRM_FINALISE_FAIL="The confirm of the finalise step has failed" +COM_JOOMLAUPDATE_UPDATE_LOG_DELETE_FILES="Deleting removed files and folders." +COM_JOOMLAUPDATE_UPDATE_LOG_FILE="File %s downloaded." +COM_JOOMLAUPDATE_UPDATE_LOG_FINALISE="Finalising installation." +COM_JOOMLAUPDATE_UPDATE_LOG_INSTALL="Starting installation of new version." +COM_JOOMLAUPDATE_UPDATE_LOG_START="Update started by user %2$s (%1$s). Old version is %3$s." +COM_JOOMLAUPDATE_UPDATE_LOG_URL="Downloading update file from %s." +COM_JOOMLAUPDATE_VIEW_COMPLETE_HEADING="Joomla Version Update Status" +COM_JOOMLAUPDATE_VIEW_COMPLETE_MESSAGE="Your site has been updated. Your Joomla version is now %s." +COM_JOOMLAUPDATE_VIEW_DEFAULT_DOWNLOAD_IN_PROGRESS="Downloading update file. Please wait ..." +COM_JOOMLAUPDATE_VIEW_DEFAULT_FTP_DIRECTORY="FTP Root" +COM_JOOMLAUPDATE_VIEW_DEFAULT_FTP_HOSTNAME="FTP Host" +COM_JOOMLAUPDATE_VIEW_DEFAULT_FTP_PASSWORD="FTP Password" +COM_JOOMLAUPDATE_VIEW_DEFAULT_FTP_PORT="FTP Port" +COM_JOOMLAUPDATE_VIEW_DEFAULT_FTP_USERNAME="FTP Username" +COM_JOOMLAUPDATE_VIEW_DEFAULT_INFOURL="Additional Information" +COM_JOOMLAUPDATE_VIEW_DEFAULT_INSTALLAGAIN="Reinstall Joomla core files" +COM_JOOMLAUPDATE_VIEW_DEFAULT_INSTALLED="Installed Joomla version" +COM_JOOMLAUPDATE_VIEW_DEFAULT_INSTALLUPDATE="Install the Update" +COM_JOOMLAUPDATE_VIEW_DEFAULT_INSTALL_SELF_UPDATE_FIRST="You must update to the latest version of the Joomla Update Component before you can update Joomla!" +COM_JOOMLAUPDATE_VIEW_DEFAULT_LATEST="Latest Joomla version" +COM_JOOMLAUPDATE_VIEW_DEFAULT_METHOD="Installation method" +COM_JOOMLAUPDATE_VIEW_DEFAULT_METHOD_DIRECT="Write files directly" +COM_JOOMLAUPDATE_VIEW_DEFAULT_METHOD_FTP="Write files using FTP" +COM_JOOMLAUPDATE_VIEW_DEFAULT_METHOD_HYBRID="Hybrid (use FTP only if needed)" +COM_JOOMLAUPDATE_VIEW_DEFAULT_NOUPDATES="No updates available." +COM_JOOMLAUPDATE_VIEW_DEFAULT_NOUPDATESNOTICE="You already have the latest Joomla version, %s." +COM_JOOMLAUPDATE_VIEW_DEFAULT_NO_DOWNLOAD_URL="We can't find a download URL" +COM_JOOMLAUPDATE_VIEW_DEFAULT_NO_DOWNLOAD_URL_DESC="An update to Joomla %1$s was found, but it wasn't possible to download that update. There are three possibilities why this happens:
    - Your host doesn't support the minimum requirements for Joomla %1$s and there is no alternative download for your configuration available.
    - The update to Joomla %1$s is not available for your stability level.
    - There is a problem with the Joomla Update Server.

    Please try to download the update package from the official Joomla download page and use the Upload and Update tab." +COM_JOOMLAUPDATE_VIEW_DEFAULT_NO_LIVE_UPDATE="Live Update is not available" +COM_JOOMLAUPDATE_VIEW_DEFAULT_NO_LIVE_UPDATE_DESC="There is a new version of the Joomla Update Component that needs to be installed first. Click here to update the component." +COM_JOOMLAUPDATE_VIEW_DEFAULT_PACKAGE="Update package URL" +COM_JOOMLAUPDATE_VIEW_DEFAULT_PACKAGE_REINSTALL="Reinstall package URL" +COM_JOOMLAUPDATE_VIEW_DEFAULT_TAB_ONLINE="Live Update" +COM_JOOMLAUPDATE_VIEW_DEFAULT_TAB_UPLOAD="Upload & Update" +COM_JOOMLAUPDATE_VIEW_DEFAULT_UPDATEFOUND="A Joomla update was found." +COM_JOOMLAUPDATE_VIEW_DEFAULT_UPDATES_INFO_CUSTOM="You are on the "%s" update channel. This is not an official Joomla update channel." +COM_JOOMLAUPDATE_VIEW_DEFAULT_UPDATES_INFO_DEFAULT="You are on the "%s" update channel. Through this channel you'll receive notifications for all updates of the current Joomla release (3.x)" +COM_JOOMLAUPDATE_VIEW_DEFAULT_UPDATES_INFO_NEXT="You are on the "%s" update channel. Through this channel you'll receive notifications for all updates of the current Joomla release (3.x) and you will also be notified when the future major release (4.x) will be available. Before upgrading to 4.x you'll need to assess its compatibility with your environment." +COM_JOOMLAUPDATE_VIEW_DEFAULT_UPDATES_INFO_TESTING="You are on the "%s" update channel. This channel is designed for testing new releases and fixes in Joomla.
    It is only intended for JBS (Joomla Bug Squad™) members and others within the Joomla community who are testing. Do not use this setting on a production site." +COM_JOOMLAUPDATE_VIEW_DEFAULT_UPDATE_NOTICE="Before you update Joomla, ensure that the installed extensions are available for the new Joomla version.
    You are strongly advised to make a backup of your installation before you start updating." +COM_JOOMLAUPDATE_VIEW_DEFAULT_UPLOAD_INTRO="You can use this feature to update Joomla if your server is behind a firewall or otherwise unable to contact the update servers. First download the Joomla Upgrade Package in ZIP format from the official Joomla download page. Then use the fields below to upload and install it." +COM_JOOMLAUPDATE_VIEW_PROGRESS="Update progress" +COM_JOOMLAUPDATE_VIEW_UPDATE_BYTESEXTRACTED="Bytes extracted" +COM_JOOMLAUPDATE_VIEW_UPDATE_BYTESREAD="Bytes read" +COM_JOOMLAUPDATE_VIEW_UPDATE_CHECKSUM_WRONG="File Checksum Failed" +COM_JOOMLAUPDATE_VIEW_UPDATE_DOWNLOADFAILED="Download of update package failed." +COM_JOOMLAUPDATE_VIEW_UPDATE_FILESEXTRACTED="Files extracted" +COM_JOOMLAUPDATE_VIEW_UPDATE_FINALISE_CONFIRM_AND_CONTINUE="Confirm & Continue" +COM_JOOMLAUPDATE_VIEW_UPDATE_FINALISE_HEAD="Joomla Update is finishing and cleaning up" +COM_JOOMLAUPDATE_VIEW_UPDATE_FINALISE_HEAD_DESC="To complete the update Process please confirm your identity by re-entering the login information for your site "%s" below." +COM_JOOMLAUPDATE_VIEW_UPDATE_INPROGRESS="Updating your Joomla files. Please wait ..." +COM_JOOMLAUPDATE_VIEW_UPDATE_PERCENT="Percent complete" +COM_JOOMLAUPDATE_VIEW_UPLOAD_CAPTIVE_INTRO_BODY="Make sure that the update file you have uploaded comes from the official Joomla download page. Afterwards, please confirm that you want to install it by re-entering the login information for your site "%s" below." +COM_JOOMLAUPDATE_VIEW_UPLOAD_CAPTIVE_INTRO_HEAD="Are you sure you want to install the file you uploaded?" +COM_JOOMLAUPDATE_VIEW_UPLOAD_PACKAGE_FILE="Joomla package file" +COM_JOOMLAUPDATE_XML_DESCRIPTION="Updates Joomla to the latest version with one click." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.com_joomlaupdate.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.com_joomlaupdate.sys.ini new file mode 100644 index 00000000..db90fb3e --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.com_joomlaupdate.sys.ini @@ -0,0 +1,10 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +COM_JOOMLAUPDATE="Joomla! Update" +COM_JOOMLAUPDATE_XML_DESCRIPTION="One-click update to the latest Joomla release." + +COM_JOOMLAUPDATE_DEFAULT_VIEW_DEFAULT_DESC="Check for Joomla! updates and update your website with the latest available release." +COM_JOOMLAUPDATE_DEFAULT_VIEW_DEFAULT_TITLE="View Joomla! Updates" diff --git a/Sites/pages/administrator/language/en-GB/en-GB.com_languages.ini b/Sites/pages/administrator/language/en-GB/en-GB.com_languages.ini new file mode 100644 index 00000000..93e0f4fd --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.com_languages.ini @@ -0,0 +1,158 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +COM_LANGUAGES="Languages" +COM_LANGUAGES_CONFIGURATION="Languages: Options" +COM_LANGUAGES_ERR_DELETE="Select a language to delete" +COM_LANGUAGES_ERR_NO_LANGUAGE_SELECTED="No language selected." +COM_LANGUAGES_ERR_PUBLISH="Select a language to publish." +COM_LANGUAGES_ERROR_LANG_TAG="
    The Language Tag should have 2 or 3 lowercase letters corresponding to the ISO language, a dash and 2 uppercase letters corresponding to the ISO country code.
    This should be the exact prefix used for the language installed or to be installed. Example: en-GB, srp-ME." +COM_LANGUAGES_ERROR_LANGUAGE_METAFILE_MISSING="Could not load %s language meta XML file from %s." +COM_LANGUAGES_ERROR_SEF="
    The \"URL Language Code\" should have only alphanumeric characters and dashes (-).
    To use UTF-8 characters, \"Unicode Aliases\" should be set to \"Yes\" in Global Configuration." +COM_LANGUAGES_FIELD_DESCRIPTION_DESC="Enter a description for the language." +COM_LANGUAGES_FIELD_IMAGE_DESC="Name of the image file for this language when using the "Use image flags" Language Switcher basic option. Example: if 'en' is chosen, then the image will be en.gif. Images and CSS for this module are in media/mod_languages/." +COM_LANGUAGES_FIELD_IMAGE_LABEL="Image" +COM_LANGUAGES_FIELD_LANG_TAG_DESC="Enter the language tag – example: en-GB for English (en-GB). This should be the exact prefix used for the language installed or to be installed." +COM_LANGUAGES_FIELD_LANG_TAG_LABEL="Language Tag" +COM_LANGUAGES_INSTALL="Install Languages" +COM_LANGUAGES_INSTALLED_FILTER_SEARCH_DESC="Search in title and language tag." +COM_LANGUAGES_INSTALLED_FILTER_SEARCH_LABEL="Search Installed Languages" +COM_LANGUAGES_OVERRIDE_ERROR_RESERVED_WORDS="YES, NO, NULL, FALSE, ON, OFF, NONE, TRUE are reserved words and can't be used as language constants." +COM_LANGUAGES_OVERRIDE_FIELD_BOTH_LABEL="For Both Locations" +COM_LANGUAGES_OVERRIDE_FIELD_BOTH_DESC="If this box is checked the override will be stored for both administrator (Backend) and site (Frontend). This is essential for creating language overrides for some plugins because their language files, while stored in backend, are also used in frontend (example: plg_content_vote).
    Please note that the two overrides will be completely independent from each other after storing them." +COM_LANGUAGES_OVERRIDE_FIELD_CLIENT_LABEL="Location" +COM_LANGUAGES_OVERRIDE_FIELD_CLIENT_DESC="Indicates if the override is created for the site (Frontend) or Administrator (Backend) client." +COM_LANGUAGES_OVERRIDE_FIELD_FILE_LABEL="File" +COM_LANGUAGES_OVERRIDE_FIELD_FILE_DESC="Language overrides are stored in a specific INI file (as it's the case for the original texts, too). Here you can see in which file the current override is stored." +COM_LANGUAGES_OVERRIDE_FIELD_LANGUAGE_LABEL="Language" +COM_LANGUAGES_OVERRIDE_FIELD_LANGUAGE_DESC="Language for which the constant is overridden." +COM_LANGUAGES_OVERRIDE_FIELD_KEY_LABEL="Language Constant" +COM_LANGUAGES_OVERRIDE_FIELD_KEY_DESC="The language constant of the string you want to override." +COM_LANGUAGES_OVERRIDE_FIELD_OVERRIDE_LABEL="Text" +COM_LANGUAGES_OVERRIDE_FIELD_OVERRIDE_DESC="Enter the text that you want to be displayed instead of the original one.
    Please note that there may be placeholders (eg %s, %d or %1$s) in the text which could be important (they will be replaced by other texts before displaying), so you should leave them in there." +COM_LANGUAGES_OVERRIDE_FIELD_SEARCHSTRING_LABEL="Search Text" +COM_LANGUAGES_OVERRIDE_FIELD_SEARCHSTRING_DESC="Please enter the text to search for here. It may be in any of the language files." +COM_LANGUAGES_OVERRIDE_FIELD_SEARCHTYPE_LABEL="Search For" +COM_LANGUAGES_OVERRIDE_FIELD_SEARCHTYPE_DESC="Select if you want to search for constant names or the values (the actual text)." +COM_LANGUAGES_OVERRIDE_FIELD_SEARCHTYPE_CONSTANT="Constant" +COM_LANGUAGES_OVERRIDE_FIELD_SEARCHTYPE_TEXT="Value" +COM_LANGUAGES_OVERRIDE_FIRST_SELECT_MESSAGE="To create a new override, please first select a language and client." +COM_LANGUAGES_OVERRIDE_SELECT_LANGUAGE="- Select Language & Client -" +COM_LANGUAGES_FIELD_PUBLISHED_DESC="Whether this content language is published or not. If published, it will display as a choice in the Language Switcher module in Frontend." +COM_LANGUAGES_FIELD_LANG_CODE_DESC="This Language Code will be appended to the site URL. When SEF is enabled, you will get https://example.com/en/. If SEF is disabled the suffix &lang=en will be appended at the end of the URL. Note the Language Code must be unique among all the languages." +COM_LANGUAGES_FIELD_LANG_CODE_LABEL="URL Language Code" +COM_LANGUAGES_FIELD_SITE_NAME_DESC="Enter a custom site name for this content language. If the site name is set to display, this custom site name will be used instead of the Global Configuration setting." +COM_LANGUAGES_FIELD_SITE_NAME_LABEL="Custom Site Name" +COM_LANGUAGES_FIELDSET_SITE_NAME_LABEL="Site Name" +COM_LANGUAGES_FIELD_TITLE_DESC="The name of the language as it will appear in the lists." +COM_LANGUAGES_FIELD_TITLE_NATIVE_DESC="Title in native language." +COM_LANGUAGES_FIELD_TITLE_NATIVE_LABEL="Title Native" +COM_LANGUAGES_FILTER_CLIENT_LABEL="Filter Location:" +COM_LANGUAGES_FTP_DESC="For setting Languages as default, Joomla will most likely need your FTP account details. Please enter them in the form fields below." +COM_LANGUAGES_FTP_TITLE="FTP Login Details" +COM_LANGUAGES_HEADING_AUTHOR="Author" +COM_LANGUAGES_HEADING_AUTHOR_ASC="Author ascending" +COM_LANGUAGES_HEADING_AUTHOR_DESC="Author descending" +COM_LANGUAGES_HEADING_AUTHOR_EMAIL="Author Email" +COM_LANGUAGES_HEADING_AUTHOR_EMAIL_ASC="Author Email ascending" +COM_LANGUAGES_HEADING_AUTHOR_EMAIL_DESC="Author Email descending" +COM_LANGUAGES_HEADING_DATE="Date" +COM_LANGUAGES_HEADING_DATE_ASC="Date ascending" +COM_LANGUAGES_HEADING_DATE_DESC="Date descending" +COM_LANGUAGES_HEADING_DEFAULT="Default" +COM_LANGUAGES_HEADING_DEFAULT_ASC="Default ascending" +COM_LANGUAGES_HEADING_DEFAULT_DESC="Default descending" +COM_LANGUAGES_HEADING_HOMEPAGE="Home" +COM_LANGUAGES_HEADING_HOMEPAGE_ASC="Home ascending" +COM_LANGUAGES_HEADING_HOMEPAGE_DESC="Home descending" +COM_LANGUAGES_HEADING_LANGUAGE="Language" +COM_LANGUAGES_HEADING_LANGUAGE_ASC="Language ascending" +COM_LANGUAGES_HEADING_LANGUAGE_DESC="Language descending" +COM_LANGUAGES_HEADING_LANG_CODE="URL Language Code" +COM_LANGUAGES_HEADING_LANG_CODE_ASC="URL Language Code ascending" +COM_LANGUAGES_HEADING_LANG_CODE_DESC="URL Language Code descending" +COM_LANGUAGES_HEADING_LANG_IMAGE="Image" +COM_LANGUAGES_HEADING_LANG_IMAGE_ASC="Image ascending" +COM_LANGUAGES_HEADING_LANG_IMAGE_DESC="Image descending" +COM_LANGUAGES_HEADING_LANG_TAG="Language Tag" +COM_LANGUAGES_HEADING_LANG_TAG_ASC="Language Tag ascending" +COM_LANGUAGES_HEADING_LANG_TAG_DESC="Language Tag descending" +COM_LANGUAGES_HEADING_VERSION="Version" +COM_LANGUAGES_HEADING_VERSION_ASC="Version ascending" +COM_LANGUAGES_HEADING_VERSION_DESC="Version descending" +COM_LANGUAGES_HEADING_TITLE_NATIVE="Native Title" +COM_LANGUAGES_HEADING_TITLE_NATIVE_ASC="Native Title ascending" +COM_LANGUAGES_HEADING_TITLE_NATIVE_DESC="Native Title descending" +COM_LANGUAGES_HOMEPAGE="Home" +COM_LANGUAGES_MSG_DEFAULT_LANGUAGE_SAVED="Default Language Saved. This does not affect users that have chosen a specific language on their profile or on the login page.
    Warning! When using the multilingual functionality (ie when the plugin System - Language Filter is enabled) the Site Default Language also has to be a published Content language." +COM_LANGUAGES_MSG_SWITCH_ADMIN_LANGUAGE_SUCCESS="The Administrator Language has been switched to "%s"." +COM_LANGUAGES_MULTILANGSTATUS_CONTACTS_ERROR="Some of the contacts linked to the user %s are incorrect." +COM_LANGUAGES_MULTILANGSTATUS_CONTACTS_ERROR_TIP="Warning! A user/author should have only one contact to which is assigned language 'All' OR one contact for each published Content Language." +COM_LANGUAGES_MULTILANGSTATUS_CONTENT_LANGUAGE_PUBLISHED="Published Content Languages" +COM_LANGUAGES_MULTILANGSTATUS_DEFAULT_HOME_MODULE_PUBLISHED="This site is set as a multilingual site. The menu module displaying the Home menu item set to language "All" should not be published." +COM_LANGUAGES_MULTILANGSTATUS_ERROR_CONTENT_LANGUAGE="A Default Home page is assigned to the %s Content Language although a Site Language for this Content Language is not installed or published AND/OR the Content Language is not published." +COM_LANGUAGES_MULTILANGSTATUS_ERROR_CONTENT_LANGUAGE_TRASHED="The Content Language %s is trashed." +COM_LANGUAGES_MULTILANGSTATUS_ERROR_LANGUAGE_TAG="The Content Language tag %s does not match the Site Language tag. Check that the Site Language is installed and published and the correct language tag is used for the Content Language. Example: for English (en-GB) both tags should be 'en-GB'." +COM_LANGUAGES_MULTILANGSTATUS_HOMES_MISSING="This site is set as a multilingual site. One or more of the Default Home pages for the published Content languages are missing although the Language Filter plugin is enabled AND/OR one or more Language Switcher modules are published." +COM_LANGUAGES_MULTILANGSTATUS_HOMES_PUBLISHED="Published Default Home pages" +COM_LANGUAGES_MULTILANGSTATUS_HOMES_PUBLISHED_ALL="1 assigned to language 'All'." +COM_LANGUAGES_MULTILANGSTATUS_HOMES_PUBLISHED_INCLUDING_ALL="Published Default Home pages (including 1 assigned to language "All")." +COM_LANGUAGES_MULTILANGSTATUS_LANGSWITCHER_PUBLISHED="Published Language Switcher Modules." +COM_LANGUAGES_MULTILANGSTATUS_LANGSWITCHER_UNPUBLISHED="This site is set as a multilingual site, at least one Language Switcher module set to language "All" has to be published. Disregard this message if you do not use a language switcher module but direct links." +COM_LANGUAGES_MULTILANGSTATUS_LANGUAGEFILTER="Language Filter Plugin" +COM_LANGUAGES_MULTILANGSTATUS_LANGUAGEFILTER_DISABLED="This site is set as a multilingual site. The Language Filter plugin is not enabled although one or more Language Switcher modules AND/OR one or more specific Content language Default Home pages are published." +COM_LANGUAGES_MULTILANGSTATUS_NONE="This site is not set as a multilingual site." +COM_LANGUAGES_MULTILANGSTATUS_SITE_LANG_PUBLISHED="Published Site Languages" +COM_LANGUAGES_MULTILANGSTATUS_USELESS_HOMES="This site is not set as a multilingual site.
    Note: at least one Default Home page is assigned to a Content Language. This will not break a monolingual site but is useless." +COM_LANGUAGES_N_ITEMS_DELETED="%d Content Languages deleted." +COM_LANGUAGES_N_ITEMS_DELETED_1="%d Content Language deleted." +COM_LANGUAGES_N_ITEMS_PUBLISHED="%d Content Languages published." +COM_LANGUAGES_N_ITEMS_PUBLISHED_1="%d Content Language published." +COM_LANGUAGES_N_ITEMS_TRASHED="%d Content Languages trashed." +COM_LANGUAGES_N_ITEMS_TRASHED_1="%d Content Language trashed." +COM_LANGUAGES_N_ITEMS_UNPUBLISHED="%d Content Languages unpublished.
    Warning! When using the multilingual functionality (ie when the plugin System - Language Filter is enabled) the Site Default Language also has to be a published Content language." +COM_LANGUAGES_N_ITEMS_UNPUBLISHED_1="%d Content Language unpublished.
    Warning! When using the multilingual functionality (ie when the plugin System - Language Filter is enabled) the Site Default Language also has to be a published Content language." +COM_LANGUAGES_NO_ITEM_SELECTED="No languages selected." +COM_LANGUAGES_SAVE_SUCCESS="Content Language saved." +COM_LANGUAGES_SEARCH_IN_TITLE="Search in title." +COM_LANGUAGES_SUBMENU_CONTENT="Content Languages" +COM_LANGUAGES_SUBMENU_INSTALLED="Installed" +COM_LANGUAGES_SUBMENU_INSTALLED_ADMINISTRATOR="Installed - Administrator" +COM_LANGUAGES_SUBMENU_INSTALLED_SITE="Installed - Site" +COM_LANGUAGES_SUBMENU_OVERRIDES="Overrides" +COM_LANGUAGES_SWITCH_ADMIN="Switch Language" +COM_LANGUAGES_VIEW_INSTALLED_ADMIN_TITLE="Languages: Installed (Administrator)" +COM_LANGUAGES_VIEW_INSTALLED_SITE_TITLE="Languages: Installed (Site)" +COM_LANGUAGES_VIEW_INSTALLED_TITLE="Languages: Installed" +COM_LANGUAGES_VIEW_LANGUAGE_EDIT_EDIT_TITLE="Languages: Edit Content Language" +COM_LANGUAGES_VIEW_LANGUAGE_EDIT_NEW_TITLE="Languages: New Content Language" +COM_LANGUAGES_VIEW_LANGUAGES_TITLE="Languages: Content" +COM_LANGUAGES_VIEW_OVERRIDE_CLIENT_SITE="Site" +COM_LANGUAGES_VIEW_OVERRIDE_CLIENT_ADMINISTRATOR="Administrator" +COM_LANGUAGES_VIEW_OVERRIDE_EDIT_TITLE="Languages: Edit Override" +COM_LANGUAGES_VIEW_OVERRIDE_EDIT_NEW_OVERRIDE_LEGEND="Create a New Override" +COM_LANGUAGES_VIEW_OVERRIDE_EDIT_EDIT_OVERRIDE_LEGEND="Edit this Override" +COM_LANGUAGES_VIEW_OVERRIDE_LANGUAGE="%1$s [%2$s]" +COM_LANGUAGES_VIEW_OVERRIDE_MORE_RESULTS="More Results" +COM_LANGUAGES_VIEW_OVERRIDE_NO_RESULTS="No matching texts found." +COM_LANGUAGES_VIEW_OVERRIDE_REFRESHING="Please wait while the cache is recreated." +COM_LANGUAGES_VIEW_OVERRIDE_REQUEST_ERROR="Error while performing an Ajax request." +COM_LANGUAGES_VIEW_OVERRIDE_RESULTS_LEGEND="Search Results" +COM_LANGUAGES_VIEW_OVERRIDE_SAVE_SUCCESS="Language Override was saved." +COM_LANGUAGES_VIEW_OVERRIDE_SEARCH_BUTTON="Search" +COM_LANGUAGES_VIEW_OVERRIDE_SEARCH_LEGEND="Search text you want to change." +COM_LANGUAGES_VIEW_OVERRIDE_SEARCH_TIP="A language string is composed of two parts: a specific language constant and its value.
    For example, in the string: COM_CONTENT_READ_MORE="Read more: "
    'COM_CONTENT_READ_MORE' is the constant and 'Read more: ' is the value.
    You have to use the specific language constant to create an override of the value.
    Therefore, you can search for the constant or the value you want to change with the search field below.
    By selecting the desired result the correct constant will automatically be inserted into the form." +COM_LANGUAGES_VIEW_OVERRIDES_FILTER_SEARCH_DESC="Search constant or text." +COM_LANGUAGES_VIEW_OVERRIDES_KEY="Constant" +COM_LANGUAGES_VIEW_OVERRIDES_LANGUAGES_BOX_ITEM="%1$s - %2$s" +COM_LANGUAGES_VIEW_OVERRIDES_N_ITEMS_DELETED="%d language overrides were deleted." +COM_LANGUAGES_VIEW_OVERRIDES_N_ITEMS_DELETED_1="%d language override was deleted." +COM_LANGUAGES_VIEW_OVERRIDES_NO_ITEM_SELECTED="You haven't selected any overrides." +COM_LANGUAGES_VIEW_OVERRIDES_PURGE="Clear Cache" +COM_LANGUAGES_VIEW_OVERRIDES_PURGE_SUCCESS="Overrider cache table cleared." +COM_LANGUAGES_VIEW_OVERRIDES_TEXT="Text" +COM_LANGUAGES_VIEW_OVERRIDES_TITLE="Languages: Overrides" +COM_LANGUAGES_XML_DESCRIPTION="Component for language management" +JLIB_RULES_SETTING_NOTES="Changes apply to this component only.
    Inherited - a Global Configuration setting or higher level setting is applied.
    Denied always wins - whatever is set at the Global or higher level and applies to all child elements.
    Allowed will enable the action for this component unless overruled by a Global Configuration setting." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.com_languages.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.com_languages.sys.ini new file mode 100644 index 00000000..21d2db3e --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.com_languages.sys.ini @@ -0,0 +1,13 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +COM_LANGUAGES="Languages" +COM_LANGUAGES_INSTALLED_VIEW_DEFAULT_DESC="Displays language packs installed into your Joomla! website." +COM_LANGUAGES_INSTALLED_VIEW_DEFAULT_TITLE="Installed Languages" +COM_LANGUAGES_LANGUAGES_VIEW_DEFAULT_DESC="Create or manage content languages for your Joomla! website." +COM_LANGUAGES_LANGUAGES_VIEW_DEFAULT_TITLE="Content Languages" +COM_LANGUAGES_OVERRIDE_VIEW_DEFAULT_DESC="Here you assign custom text for a language key that you want to use instead of language pack default text." +COM_LANGUAGES_OVERRIDE_VIEW_DEFAULT_TITLE="Language Overrides" +COM_LANGUAGES_XML_DESCRIPTION="Component for language management." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.com_login.ini b/Sites/pages/administrator/language/en-GB/en-GB.com_login.ini new file mode 100644 index 00000000..0d9816e8 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.com_login.ini @@ -0,0 +1,10 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +COM_LOGIN="Login" +COM_LOGIN_JOOMLA_ADMINISTRATION_LOGIN="Joomla! Administration Login" +COM_LOGIN_RETURN_TO_SITE_HOME_PAGE="Go to site home page" +COM_LOGIN_VALID="Use a valid username and password to gain access to the Administrator Backend." +COM_LOGIN_XML_DESCRIPTION="This component lets users login to the site." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.com_login.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.com_login.sys.ini new file mode 100644 index 00000000..c75d7b10 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.com_login.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +COM_LOGIN="Login" +COM_LOGIN_XML_DESCRIPTION="This component lets users login to the site." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.com_mailto.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.com_mailto.sys.ini new file mode 100644 index 00000000..9dcf67e0 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.com_mailto.sys.ini @@ -0,0 +1,8 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +COM_MAILTO="Mail to" +COM_MAILTO_XML_DESCRIPTION="A generic mail to friend component." + diff --git a/Sites/pages/administrator/language/en-GB/en-GB.com_media.ini b/Sites/pages/administrator/language/en-GB/en-GB.com_media.ini new file mode 100644 index 00000000..ade2a8de --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.com_media.ini @@ -0,0 +1,105 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +COM_MEDIA="Media" +COM_MEDIA_ALIGN="Image Float" +COM_MEDIA_ALIGN_DESC="This will apply the classes 'pull-left', 'pull-center' or 'pull-right' to the '
    ' or '' element." +COM_MEDIA_BROWSE_FILES="Browse files" +COM_MEDIA_CAPTION="Caption" +COM_MEDIA_CAPTION_CLASS_LABEL="Caption Class" +COM_MEDIA_CAPTION_CLASS_DESC="This will apply the entered class to the '
    ' element. For example: 'text-left', 'text-right', 'text-center'." +COM_MEDIA_CLEAR_LIST="Clear List" +COM_MEDIA_CONFIGURATION="Media: Options" +COM_MEDIA_CREATE_COMPLETE="Create Complete: %s" +COM_MEDIA_CREATE_FOLDER="Create Folder" +COM_MEDIA_CREATE_NEW_FOLDER="Create New Folder" +COM_MEDIA_CURRENT_PROGRESS="Current progress" +COM_MEDIA_DELETE_COMPLETE="Delete Complete: %s" +COM_MEDIA_DESCFTPTITLE="FTP Login Details" +COM_MEDIA_DESCFTP="To upload, change and delete media files, Joomla will most likely need your FTP account details. Please enter them in the form fields below." +COM_MEDIA_DETAIL_VIEW="Detail View" +COM_MEDIA_DIRECTORY="Folder" +COM_MEDIA_DIRECTORY_UP="Folder Up" +COM_MEDIA_ERROR_BAD_REQUEST="Bad Request" +COM_MEDIA_ERROR_BEFORE_DELETE_0="No error occurred before deleting the media." +COM_MEDIA_ERROR_BEFORE_DELETE_1="An error occurred before deleting the media: %2$s" +COM_MEDIA_ERROR_BEFORE_DELETE_MORE="Some errors occurred before deleting the media: %2$s" +COM_MEDIA_ERROR_BEFORE_SAVE_0="No error occurred before saving the media." +COM_MEDIA_ERROR_BEFORE_SAVE_1="An error occurred before saving the media: %2$s" +COM_MEDIA_ERROR_BEFORE_SAVE_MORE="Some errors occurred before saving the media: %2$s" +COM_MEDIA_ERROR_CREATE_NOT_PERMITTED="Create not permitted." +COM_MEDIA_ERROR_FILE_EXISTS="File already exists." +COM_MEDIA_ERROR_UNABLE_TO_CREATE_FOLDER_WARNDIRNAME="Unable to create folder. Folder name must only have alphanumeric characters and no spaces." +COM_MEDIA_ERROR_UNABLE_TO_BROWSE_FOLDER_WARNDIRNAME="Unable to browse: %s. Folder name must only have alphanumeric characters and no spaces." +COM_MEDIA_ERROR_UNABLE_TO_DELETE_FILE_WARNFILENAME="Unable to delete: %s. File name must only have alphanumeric characters and no spaces." +COM_MEDIA_ERROR_UNABLE_TO_DELETE_FOLDER_NOT_EMPTY="Unable to delete: %s. Folder is not empty!" +COM_MEDIA_ERROR_UNABLE_TO_DELETE_FOLDER_WARNDIRNAME="Unable to delete: %s." +COM_MEDIA_ERROR_UNABLE_TO_DELETE="Unable to delete: " +COM_MEDIA_ERROR_UNABLE_TO_UPLOAD_FILE="Unable to upload file." +COM_MEDIA_ERROR_UPLOAD_INPUT="Please input a file to upload." +COM_MEDIA_ERROR_WARNFILENAME="File name must only have alphanumeric characters and no spaces." +COM_MEDIA_ERROR_WARNFILENOTSAFE="You have tried to upload file(s) that are not safe." +COM_MEDIA_ERROR_WARNFILETOOLARGE="This file is too large to upload." +COM_MEDIA_ERROR_WARNFILETYPE="This file type is not supported." +COM_MEDIA_ERROR_WARNIEXSS="Possible IE XSS Attack found." +COM_MEDIA_ERROR_WARNINVALID_IMG="Not a valid image." +COM_MEDIA_ERROR_WARNINVALID_FOLDER="Invalid folder provided." +COM_MEDIA_ERROR_WARNINVALID_MIME="Illegal or invalid mime type detected." +COM_MEDIA_ERROR_WARNNOTADMIN="Uploaded file is not an image file and you are not a manager or higher." +COM_MEDIA_ERROR_WARNNOTEMPTY="Not empty!" +COM_MEDIA_ERROR_WARNUPLOADTOOLARGE="Total size of upload exceeds the limit." +COM_MEDIA_FIELD_CHECK_MIME_DESC="Use MIME Magic or Fileinfo to try to verify files. Try disabling this if you get invalid mime type errors." +COM_MEDIA_FIELD_CHECK_MIME_LABEL="Check MIME Types" +COM_MEDIA_FIELD_IGNORED_EXTENSIONS_DESC="Ignored file extensions for MIME type checking and restricted uploads." +COM_MEDIA_FIELD_IGNORED_EXTENSIONS_LABEL="Ignored Extensions" +COM_MEDIA_FIELD_ILLEGAL_MIME_TYPES_DESC="A comma separated list of illegal MIME types to upload (blacklist)." +COM_MEDIA_FIELD_ILLEGAL_MIME_TYPES_LABEL="Illegal MIME Types" +COM_MEDIA_FIELD_LEGAL_EXTENSIONS_DESC="Extensions (file types) you are allowed to upload (comma separated)." +COM_MEDIA_FIELD_LEGAL_EXTENSIONS_LABEL="Legal Extensions (File Types)" +COM_MEDIA_FIELD_LEGAL_IMAGE_EXTENSIONS_DESC="Image extensions (file types) you are allowed to upload (comma separated). These are used to check for valid image headers." +COM_MEDIA_FIELD_LEGAL_IMAGE_EXTENSIONS_LABEL="Legal Image Extensions (File Types)" +COM_MEDIA_FIELD_LEGAL_MIME_TYPES_DESC="A comma separated list of legal MIME types to upload." +COM_MEDIA_FIELD_LEGAL_MIME_TYPES_LABEL="Legal MIME Types" +COM_MEDIA_FIELD_MAXIMUM_SIZE_DESC="The maximum size for an upload (in megabytes). Use zero for no limit. Note: your server has a maximum limit." +COM_MEDIA_FIELD_MAXIMUM_SIZE_LABEL="Maximum Size (in MB)" +COM_MEDIA_FIELD_PATH_FILE_FOLDER_DESC="Enter the path to the files folder relative to the root of your webspace. Warning! Changing to another path than the default 'images' may break your links. Note: Do not start the path with a slash!" +COM_MEDIA_FIELD_PATH_FILE_FOLDER_LABEL="Path to Files Folder" +COM_MEDIA_FIELD_PATH_IMAGE_FOLDER_DESC="Enter the path to the images folder relative to the root of your webspace. This path has to be the same as path to files (default) or to a subfolder of the path to file folder.. Note: Do not start the path with a slash!" +COM_MEDIA_FIELD_PATH_IMAGE_FOLDER_LABEL="Path to Images Folder" +COM_MEDIA_FIELD_RESTRICT_UPLOADS_DESC="Restrict uploads for lower than manager users to images if Fileinfo or MIME Magic isn't installed." +COM_MEDIA_FIELD_RESTRICT_UPLOADS_LABEL="Restrict Uploads" +COM_MEDIA_FIELDSET_OPTIONS_LABEL="Media" +COM_MEDIA_FILES="Files" +COM_MEDIA_FILESIZE="File size" +COM_MEDIA_FOLDER="Folder" +COM_MEDIA_FOLDERS="Media Folders" +COM_MEDIA_FOLDERS_PATH_LABEL="Warning! Path Folder
    Changing the 'Path to files folder' from the default of 'images' may break your links.
    The 'Path to images' folder has to be the same or a subfolder of 'Path to files'." +COM_MEDIA_IMAGE_DESCRIPTION="Image Description" +COM_MEDIA_IMAGE_DIMENSIONS="%1$s x %2$s" +COM_MEDIA_IMAGE_TITLE="%1$s - %2$s" +COM_MEDIA_IMAGE_URL="Image URL" +COM_MEDIA_INSERT_IMAGE="Insert Image" +COM_MEDIA_INSERT="Insert" +COM_MEDIA_INVALID_REQUEST="Invalid Request" +COM_MEDIA_MEDIA="Media" +COM_MEDIA_NAME="Image Name" +COM_MEDIA_NO_IMAGES_FOUND="No Images Found" +COM_MEDIA_NOT_SET="Not Set" +COM_MEDIA_OVERALL_PROGRESS="Overall Progress" +COM_MEDIA_PIXEL_DIMENSIONS="Dimensions (px)" +COM_MEDIA_PREVIEW="Preview" +COM_MEDIA_START_UPLOAD="Start Upload" +COM_MEDIA_THUMBNAIL_VIEW="Thumbnail View" +COM_MEDIA_TITLE="Image Title" +COM_MEDIA_UPLOAD_COMPLETE="Upload Complete: %s" +COM_MEDIA_UPLOAD_FILE="Upload file" +; The following two strings are deprecated with 3.7.0 and will be removed in 4.0 +COM_MEDIA_UPLOAD_FILES="Upload files (Maximum Size: %s MB)" +COM_MEDIA_UPLOAD_FILES_NOLIMIT="Upload files (No maximum size)" +COM_MEDIA_UPLOAD_SUCCESSFUL="Upload Successful" +COM_MEDIA_UPLOAD="Upload" +COM_MEDIA_UP="Up" +COM_MEDIA_XML_DESCRIPTION="Component for managing site media" +JLIB_RULES_SETTING_NOTES="Changes apply to this component only.
    Inherited - a Global Configuration setting or higher level setting is applied.
    Denied always wins - whatever is set at the Global or higher level and applies to all child elements.
    Allowed will enable the action for this component unless overruled by a Global Configuration setting." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.com_media.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.com_media.sys.ini new file mode 100644 index 00000000..e8b6c7c0 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.com_media.sys.ini @@ -0,0 +1,9 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +COM_MEDIA="Media" +COM_MEDIA_MEDIA_VIEW_DEFAULT_DESC="Upload or manage images and other media files on you Joomla! website." +COM_MEDIA_MEDIA_VIEW_DEFAULT_TITLE="Media Manager" +COM_MEDIA_XML_DESCRIPTION="Component for managing site media." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.com_menus.ini b/Sites/pages/administrator/language/en-GB/en-GB.com_menus.ini new file mode 100644 index 00000000..91c1bd7c --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.com_menus.ini @@ -0,0 +1,257 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +COM_MENUS="Menus" +COM_MENUS_ACTION_COLLAPSE="Collapse" +COM_MENUS_ACTION_DESELECT="Deselect" +COM_MENUS_ACTION_EXPAND="Expand" +COM_MENUS_ACTION_SELECT="Select" +COM_MENUS_ADD_MENU_MODULE="Add a module for this menu" +COM_MENUS_ADMIN_ACCESS_DESC="Filter by viewing access level." +COM_MENUS_ADMIN_ACCESS_LABEL="Access" +COM_MENUS_ADMIN_AUTHOR_DESC="Filter by author." +COM_MENUS_ADMIN_AUTHOR_LABEL="Author" +COM_MENUS_ADMIN_CATEGORY_DESC="Filter by category." +COM_MENUS_ADMIN_CATEGORY_LABEL="Category" +COM_MENUS_ADMIN_FILTER_DESC="Apply filters to the menu item." +COM_MENUS_ADMIN_FILTER_LABEL="Filter" +COM_MENUS_ADMIN_LANGUAGE_DESC="Filter by language." +COM_MENUS_ADMIN_LANGUAGE_LABEL="Language" +COM_MENUS_ADMIN_LEVEL_DESC="The number of subcategory levels to display." +COM_MENUS_ADMIN_LEVEL_LABEL="Subcategory Levels" +COM_MENUS_ADMIN_TAGS_DESC="Filter by tags." +COM_MENUS_ADMIN_TAGS_LABEL="Tags" +COM_MENUS_ADVANCED_FIELDSET_LABEL="Advanced" +COM_MENUS_BASIC_FIELDSET_LABEL="Options" +COM_MENUS_BATCH_MENU_ITEM_CANNOT_CREATE="You are not allowed to create new menu items." +COM_MENUS_BATCH_MENU_ITEM_CANNOT_EDIT="You are not allowed to edit menu items." +COM_MENUS_BATCH_MENU_LABEL="To Move or Copy your selection please select a Menu or parent item." +COM_MENUS_BATCH_OPTIONS="Batch process the selected menu items" +COM_MENUS_BATCH_TIP="If a menu or parent is selected for move/copy, any actions selected will be applied to the copied or moved menu items. Otherwise, all actions are applied to the selected menu items." +COM_MENUS_CHANGE_MENUITEM="Select or Change Menu Item" +COM_MENUS_CONFIGURATION="Menus: Options" +COM_MENUS_EDIT_MENUITEM="Edit Menu Item" +COM_MENUS_EDIT_MODULE_SETTINGS="Edit module settings" +COM_MENUS_ERROR_ALL_LANGUAGE_ASSOCIATED="A menu item set to All languages can't be associated. Associations have not been set." +COM_MENUS_ERROR_ALREADY_HOME="Menu item already set to home." +COM_MENUS_ERROR_MENUTYPE="Please change the Menu type. The term 'main' is reserved for internal usage." +COM_MENUS_ERROR_MENUTYPE_HOME="The term 'main' is reserved for internal usage." +COM_MENUS_ERROR_MENUTYPE_NOT_FOUND="The Menu type doesn't exist." +COM_MENUS_ERROR_ONE_HOME="Only one menu item can be a home link for each language." +COM_MENUS_EXTENSION_PUBLISHED_DISABLED="Component disabled and menu item published." +COM_MENUS_EXTENSION_PUBLISHED_ENABLED="Component enabled and menu item published." +COM_MENUS_EXTENSION_UNPUBLISHED_DISABLED="Component disabled and menu item unpublished." +COM_MENUS_EXTENSION_UNPUBLISHED_ENABLED="Component enabled and menu item unpublished." +COM_MENUS_FIELD_FEEDLINK_DESC="Display a feed link for this menu item." +COM_MENUS_FIELD_FEEDLINK_LABEL="Feed link" +COM_MENUS_FIELD_PRESET_LABEL="Import a preset" +COM_MENUS_FIELD_PRESET_DESC="Select a preset if you want to populate this menu with the menu items in that preset. Otherwise leave this empty." +COM_MENUS_FIELD_VALUE_IGNORE="Ignore" +COM_MENUS_FIELD_VALUE_NEW_WITH_NAV="New Window With Navigation" +COM_MENUS_FIELD_VALUE_NEW_WITHOUT_NAV="New Without Navigation" +COM_MENUS_FIELD_VALUE_PARENT="Parent" +COM_MENUS_FIELDSET_RULES="Permissions" +COM_MENUS_FILTER_PARENT_MENU_ITEM_DESC="Filters the menu items list where the parent is this selected menu item." +COM_MENUS_FILTER_PARENT_MENU_ITEM_LABEL="Parent Menu Item" +COM_MENUS_FILTER_SELECT_PARENT_MENU_ITEM="- Select Parent Menu Item -" +COM_MENUS_GRID_UNSET_LANGUAGE="Unset %s Default" +COM_MENUS_HEADING_ASSIGN_MODULE="Module" +COM_MENUS_HEADING_ASSOCIATION="Association" +COM_MENUS_HEADING_DISPLAY="Display" +COM_MENUS_HEADING_HOME="Home" +COM_MENUS_HEADING_HOME_ASC="Home ascending" +COM_MENUS_HEADING_HOME_DESC="Home descending" +COM_MENUS_HEADING_LEVELS="View Level" +COM_MENUS_HEADING_LINKED_MODULES="Linked Modules" +COM_MENUS_HEADING_MENU="Menu" +COM_MENUS_HEADING_MENU_ASC="Menu ascending" +COM_MENUS_HEADING_MENU_DESC="Menu descending" +COM_MENUS_HEADING_NUMBER_MENU_ITEMS="Number of Menu Items" +COM_MENUS_HEADING_POSITION="Position" +COM_MENUS_HEADING_PUBLISHED_ITEMS="Published" +COM_MENUS_HEADING_TRASHED_ITEMS="Trashed" +COM_MENUS_HEADING_UNPUBLISHED_ITEMS="Unpublished" +COM_MENUS_HTML_PUBLISH="Publish menu item" +COM_MENUS_HTML_PUBLISH_ALIAS="Publish the menu item alias" +COM_MENUS_HTML_PUBLISH_DISABLED="Publish menu item::Component disabled" +COM_MENUS_HTML_PUBLISH_ENABLED="Publish menu item::Component enabled" +COM_MENUS_HTML_PUBLISH_HEADING="Publish the heading menu item" +COM_MENUS_HTML_PUBLISH_SEPARATOR="Publish the separator menu item" +COM_MENUS_HTML_PUBLISH_URL="Publish the URL menu item" +COM_MENUS_HTML_UNPUBLISH_ALIAS="Unpublish the menu item alias" +COM_MENUS_HTML_UNPUBLISH_DISABLED="Unpublish menu item::Component disabled" +COM_MENUS_HTML_UNPUBLISH_ENABLED="Unpublish menu item::Component enabled" +COM_MENUS_HTML_UNPUBLISH_HEADING="Unpublish the heading menu item" +COM_MENUS_HTML_UNPUBLISH_SEPARATOR="Unpublish the separator menu item" +COM_MENUS_HTML_UNPUBLISH_URL="Unpublish the URL menu item" +COM_MENUS_INTEGRATION_FIELDSET_LABEL="Integration" +; The following 2 strings are deprecated and will be removed with 4.0. +COM_MENUS_ITEM_ASSOCIATIONS_FIELDSET_LABEL="Menu Item Associations" +COM_MENUS_ITEM_ASSOCIATIONS_FIELDSET_DESC="Multilingual only! This choice will only display if the Language Filter parameter 'Item Associations' is set to 'Yes'. Choose a menu item for the target language. This association will let the Language Switcher module redirect to the associated menu item in another language. If used, make sure to display the Language switcher module on the relevant pages. A menu item set to language 'All' can't be associated." +COM_MENUS_ITEM_DETAILS="Details" +COM_MENUS_ITEM_FIELD_ALIAS_DESC="The alias is used in the URL when SEF is on." +COM_MENUS_ITEM_FIELD_ALIAS_MENU_DESC="Menu Item to link to." +COM_MENUS_ITEM_FIELD_ALIAS_MENU_LABEL="Menu Item" +COM_MENUS_ITEM_FIELD_ALIAS_REDIRECT_DESC="If set to Yes then visitors will be redirected to the linked menu item." +COM_MENUS_ITEM_FIELD_ALIAS_REDIRECT_LABEL="Use Redirection" +COM_MENUS_ITEM_FIELD_ANCHOR_CSS_DESC="An optional class to apply to the menu hyperlink." +COM_MENUS_ITEM_FIELD_ANCHOR_CSS_LABEL="Link Class" +COM_MENUS_ITEM_FIELD_ANCHOR_TITLE_DESC="An optional, custom description for the title attribute of the menu hyperlink." +COM_MENUS_ITEM_FIELD_ANCHOR_TITLE_LABEL="Link Title Attribute" +COM_MENUS_ITEM_FIELD_ANCHOR_REL_DESC="An optional, custom rel attribute to get more information about the menu hyperlink (search engines purpose)." +COM_MENUS_ITEM_FIELD_ANCHOR_REL_LABEL="Link Rel Attribute" +COM_MENUS_ITEM_FIELD_ASSIGNED_DESC="Shows which menu the link will appear in." +COM_MENUS_ITEM_FIELD_ASSIGNED_LABEL="Menu" +COM_MENUS_ITEM_FIELD_ASSOCIATION_NO_VALUE="- No association -" +COM_MENUS_ITEM_FIELD_BROWSERNAV_DESC="Target browser window when the menu item is selected." +COM_MENUS_ITEM_FIELD_BROWSERNAV_LABEL="Target Window" +COM_MENUS_ITEM_FIELD_COMPONENTS_CONTAINER_HIDE_ITEMS_DESC="Select the menu items that should or should not be shown under this container. If there are no items to show, then this container will also be hidden.
    Please note that when you install a new component it will be displayed by default until you come back here and hide it too." +COM_MENUS_ITEM_FIELD_COMPONENTS_CONTAINER_HIDE_ITEMS_LABEL="Show or Hide Menu Items" +COM_MENUS_ITEM_FIELD_HIDE_UNASSIGNED="Hide Unassigned Modules" +COM_MENUS_ITEM_FIELD_HIDE_UNASSIGNED_DESC="Show or hide modules unassigned to this menu item." +COM_MENUS_ITEM_FIELD_HIDE_UNASSIGNED_LABEL="Unassigned Modules" +COM_MENUS_ITEM_FIELD_HIDE_UNPUBLISHED="Hide Unpublished Modules" +COM_MENUS_ITEM_FIELD_HIDE_UNPUBLISHED_DESC="Show or hide modules that are unpublished." +COM_MENUS_ITEM_FIELD_HIDE_UNPUBLISHED_LABEL="Unpublished Modules" +COM_MENUS_ITEM_FIELD_HOME_DESC="Sets this menu item as the default or home page of the site. You must have a default page set at all times." +COM_MENUS_ITEM_FIELD_HOME_LABEL="Default Page" +COM_MENUS_ITEM_FIELD_LANGUAGE_DESC="Assign a language to this menu item." +COM_MENUS_ITEM_FIELD_LINK_DESC="Link for this menu." +COM_MENUS_ITEM_FIELD_LINK_LABEL="Link" +COM_MENUS_ITEM_FIELD_MENU_IMAGE_DESC="Select or upload an optional image to be used with the menu hyperlink." +COM_MENUS_ITEM_FIELD_MENU_IMAGE_LABEL="Link Image" +COM_MENUS_ITEM_FIELD_MENU_IMAGE_CSS_DESC="An optional class to apply to the image." +COM_MENUS_ITEM_FIELD_MENU_IMAGE_CSS_LABEL="Image Class" +COM_MENUS_ITEM_FIELD_MENU_SHOW_DESC="Select 'No' if you want to hide this menu item. Note any submenu items will also be hidden." +COM_MENUS_ITEM_FIELD_MENU_SHOW_LABEL="Display in Menu" +COM_MENUS_ITEM_FIELD_MENU_TEXT_DESC="If the optional image is added, adds the menu title next to the image. Default is 'Yes'." +COM_MENUS_ITEM_FIELD_MENU_TEXT_LABEL="Add Menu Title" +COM_MENUS_ITEM_FIELD_NOTE_DESC="An optional note to display in the Menu Manager." +COM_MENUS_ITEM_FIELD_ORDERING_DESC="The menu item will be placed in the menu after the selected menu item." +COM_MENUS_ITEM_FIELD_ORDERING_LABEL="Ordering" +COM_MENUS_ITEM_FIELD_ORDERING_TEXT="Ordering will be available after saving." +COM_MENUS_ITEM_FIELD_ORDERING_VALUE_FIRST="- First -" +COM_MENUS_ITEM_FIELD_ORDERING_VALUE_LAST="- Last -" +COM_MENUS_ITEM_FIELD_PAGE_CLASS_DESC="Optional CSS class to add to elements in this page. This allows CSS styling specific to this page." +COM_MENUS_ITEM_FIELD_PAGE_CLASS_LABEL="Page Class" +COM_MENUS_ITEM_FIELD_PAGE_HEADING_DESC="Optional alternative text for the Page heading." +COM_MENUS_ITEM_FIELD_PAGE_HEADING_LABEL="Page Heading" +COM_MENUS_ITEM_FIELD_PAGE_TITLE_DESC="Optional text for the "Browser page title" element. If blank, a default value is used based on the Menu Item Title." +COM_MENUS_ITEM_FIELD_PAGE_TITLE_LABEL="Browser Page Title" +COM_MENUS_ITEM_FIELD_PARENT_DESC="Select a parent item." +COM_MENUS_ITEM_FIELD_PARENT_LABEL="Parent Item" +COM_MENUS_ITEM_FIELD_SECURE_DESC="Selects if this link should use HTTPS (encrypted HTTP connections with the https:// protocol prefix). Note, you must have HTTPS enabled on your server to utilise this option." +COM_MENUS_ITEM_FIELD_SECURE_LABEL="Secure" +COM_MENUS_ITEM_FIELD_SHOW_PAGE_HEADING_DESC="Show or hide the Browser Page Title in the heading of the page ( If no optional text entered - will default to value based on the Menu Item Title ). The Page heading is usually displayed inside the "H1" tag." +COM_MENUS_ITEM_FIELD_SHOW_PAGE_HEADING_LABEL="Show Page Heading" +COM_MENUS_ITEM_FIELD_TEMPLATE_DESC="Select a specific template style for this menu item or use the default template." +COM_MENUS_ITEM_FIELD_TEMPLATE_LABEL="Template Style" +COM_MENUS_ITEM_FIELD_TEXT_SEPARATOR_DESC="Choose whether this separator will be displayed as a label. If the title has only dashes (-) and spaces, it will not be displayed as a label." +COM_MENUS_ITEM_FIELD_TEXT_SEPARATOR_LABEL="Display as a label" +COM_MENUS_ITEM_FIELD_TITLE_DESC="The title of the menu item that will display in the menu." +COM_MENUS_ITEM_FIELD_TITLE_LABEL="Menu Title" +COM_MENUS_ITEM_FIELD_TYPE_DESC="The type of link: Component, URL, Alias, Separator or Heading." +COM_MENUS_ITEM_FIELD_TYPE_LABEL="Menu Item Type" +COM_MENUS_ITEM_IS_DEFAULT="Is default" +COM_MENUS_ITEM_MODULE_ASSIGNMENT="Module Assignment" +COM_MENUS_ITEM_REQUIRED="Required" +COM_MENUS_ITEM_ROOT="Menu Item Root" +COM_MENUS_ITEMS_REBUILD_FAILED="Failed rebuilding Menu Items list." +COM_MENUS_ITEMS_REBUILD_SUCCESS="Menu items list rebuilt." +COM_MENUS_ITEMS_SEARCH_FILTER="Search in title, alias and notes. Prefix with ID: to search for a menu item ID." +COM_MENUS_ITEMS_SEARCH_FILTER_LABEL="Search Menu Items" +COM_MENUS_ITEMS_SET_HOME_0="No menu item set to home." +COM_MENUS_ITEMS_SET_HOME_1="1 menu item set to home." +COM_MENUS_ITEMS_SET_HOME_MORE="%d menu items set to home." +COM_MENUS_ITEMS_UNSET_HOME="1 menu item unset to home." +COM_MENUS_LABEL_HIDDEN="Hidden" +COM_MENUS_LAYOUT_FEATURED_OPTIONS="Layout" +COM_MENUS_LAYOUT_MENUTYPE_OPTIONS_LABEL="Menu Type" +COM_MENUS_LINKTYPE_OPTIONS_LABEL="Link Type" +COM_MENUS_MENU_CLIENT_ID_LABEL="Client" +COM_MENUS_MENU_CLIENT_ID_DESC="Select if this Menu is to be used in the Site or the Administrator." +COM_MENUS_MENU_CONFIRM_DELETE="Are you sure you want to delete these menus? Confirming will delete the selected menu types, all their menu items and the associated menu modules." +COM_MENUS_MENU_DESCRIPTION_DESC="A description about the purpose of the menu." +COM_MENUS_MENU_DETAILS="Menu Details" +COM_MENUS_MENU_EXPORT_BUTTON="Download as Preset" +COM_MENUS_MENU_ITEM_SAVE_SUCCESS="Menu item saved." +COM_MENUS_MENU_MENUTYPE_DESC="The system name of the menu." +COM_MENUS_MENU_MENUTYPE_LABEL="Menu Type" +COM_MENUS_MENU_SAVE_SUCCESS="Menu saved" +COM_MENUS_MENU_SEARCH_FILTER="Search in Title or Menu type" +COM_MENUS_MENU_SPRINTF="Menu: %s" +COM_MENUS_MENUS="Menu items" +COM_MENUS_MENU_TYPE_PROTECTED_MAIN_LABEL="Main (Protected)" +COM_MENUS_MENU_TITLE_DESC="The title of the menu to display in the Administrator Menubar and lists." +COM_MENUS_MENUS_FILTER_SEARCH_DESC="Search in title and menu type." +COM_MENUS_MENUS_FILTER_SEARCH_LABEL="Search Menus" +; in the following string +; %1$s is for module title, %2$s is for access-title, %3$s is for position +COM_MENUS_MODULE_ACCESS_POSITION="%1$s (%2$s in %3$s)" +COM_MENUS_MODULE_SHOW_VARIES="Varies" +COM_MENUS_MODULES="Modules" +COM_MENUS_N_ITEMS_CHECKED_IN_0="No menu item checked in." +COM_MENUS_N_ITEMS_CHECKED_IN_1="%d menu item checked in." +COM_MENUS_N_ITEMS_CHECKED_IN_MORE="%d menu items checked in." +COM_MENUS_N_ITEMS_DELETED="%d menu items deleted." +COM_MENUS_N_ITEMS_DELETED_1="%d menu item deleted." +COM_MENUS_N_ITEMS_FAILED_PUBLISHING="Failed publishing %d menu items as at least one of their parents is unpublished or one of their children is checked out." +COM_MENUS_N_ITEMS_FAILED_PUBLISHING_1="Failed publishing %d menu item as at least one of its parents is unpublished or one of its children is checked out." +COM_MENUS_N_ITEMS_PUBLISHED="%d menu items published." +COM_MENUS_N_ITEMS_PUBLISHED_1="%d menu item published." +COM_MENUS_N_ITEMS_TRASHED="%d menu items trashed." +COM_MENUS_N_ITEMS_TRASHED_1="%d menu item trashed." +COM_MENUS_N_ITEMS_UNPUBLISHED="%d menu items unpublished." +COM_MENUS_N_ITEMS_UNPUBLISHED_1="%d menu item unpublished." +COM_MENUS_N_MENUS_DELETED="%d menu types deleted." +COM_MENUS_N_MENUS_DELETED_1="Menu type deleted." +COM_MENUS_NEW_MENUITEM="New Menu Item" +COM_MENUS_NO_ITEM_SELECTED="No menu items selected." +COM_MENUS_NO_MENUS_SELECTED="No menu selected." +COM_MENUS_OPTION_SELECT_COMPONENT="- Select Component -" +COM_MENUS_OPTION_SELECT_LEVEL="- Select Max Levels -" +COM_MENUS_PAGE_OPTIONS_LABEL="Page Display" +COM_MENUS_PRESET_IMPORT_SUCCESS="Menu was saved and the menu items were imported from the selected preset." +COM_MENUS_PRESET_IMPORT_FAILED="Menu was saved but failed to import the preset: %s" +COM_MENUS_PRESET_LOAD_FAILED="Failed to load the specified preset." +COM_MENUS_REQUEST_FIELDSET_LABEL="Required Settings" +COM_MENUS_SAVE_SUCCESS="Menu item saved." +COM_MENUS_SELECT_A_MENUITEM="Select a Menu Item" +COM_MENUS_SELECT_MENU="- Select Menu -" +COM_MENUS_SELECT_MENU_FILTER_NOT_TRASHED="Filter the list by a state other than trashed or clear the filter." +COM_MENUS_SELECT_MENU_FIRST="To use batch processing, please first select a Menu in the manager." +COM_MENUS_SELECT_MENU_FIRST_EXPORT="To use export, please first select a valid Menu in the manager." +COM_MENUS_SUBMENU_ITEMS="Menu Items" +COM_MENUS_SUBMENU_MENUS="Menus" +COM_MENUS_SUCCESS_REORDERED="Menu item reordered." +COM_MENUS_TIP_ALIAS_LABEL="Warning!
    Leave the alias field empty if the menu item alias and the menu item linked to by the alias have the same parent." +COM_MENUS_TIP_ASSOCIATION="Associated menu items" +COM_MENUS_TITLE_EDIT_ITEM="Menu Manager: Title Edit Item" +COM_MENUS_TITLE_TRANSLATION="Title (%s)" +COM_MENUS_TOOLBAR_SET_HOME="Home" +COM_MENUS_TYPE_ALIAS="Menu Item Alias" +COM_MENUS_TYPE_ALIAS_DESC="Create an alias to another menu item." +COM_MENUS_TYPE_CHOOSE="Select a Menu Item Type:" +COM_MENUS_TYPE_CONTAINER="Components Menu Container" +COM_MENUS_TYPE_CONTAINER_DESC="This will create a container menu which will show the items in the protected menu type 'main'. You can also selectively hide or show menu items." +COM_MENUS_TYPE_EXTERNAL_URL="URL" +COM_MENUS_TYPE_EXTERNAL_URL_DESC="An external or internal URL." +COM_MENUS_TYPE_HEADING="Menu Heading" +COM_MENUS_TYPE_HEADING_DESC="A heading for the parent of submenu items." +COM_MENUS_TYPE_SEPARATOR="Separator" +COM_MENUS_TYPE_SEPARATOR_DESC="A separator with or without a text label, useful to separate items within a menu." +COM_MENUS_TYPE_SYSTEM="System Links" +COM_MENUS_TYPE_UNEXISTING="Component '%s' does not exist." +COM_MENUS_TYPE_UNKNOWN="Unknown" +COM_MENUS_VIEW_EDIT_ITEM_TITLE="Menus: Edit Item" +COM_MENUS_VIEW_EDIT_MENU_TITLE="Menus: Edit" +COM_MENUS_VIEW_ITEMS_ALL_TITLE="Menus: All Menu Items" +COM_MENUS_VIEW_ITEMS_MENU_TITLE="Menus: Items (%s)" +COM_MENUS_VIEW_ITEMS_TITLE="Menus: Items" +COM_MENUS_VIEW_MENUS_TITLE="Menus" +COM_MENUS_VIEW_NEW_ITEM_TITLE="Menus: New Item" +COM_MENUS_VIEW_NEW_MENU_TITLE="Menus: Add" +COM_MENUS_XML_DESCRIPTION="Component for creating menus." +JLIB_RULES_SETTING_NOTES="Changes apply to this component only.
    Inherited - a Global Configuration setting or higher level setting is applied.
    Denied always wins - whatever is set at the Global or higher level and applies to all child elements.
    Allowed will enable the action for this component unless overruled by a Global Configuration setting." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.com_menus.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.com_menus.sys.ini new file mode 100644 index 00000000..2aa996ac --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.com_menus.sys.ini @@ -0,0 +1,17 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +COM_MENUS="Menus" +COM_MENUS_ITEMS_CHOOSE_MENU_DESC="Choose a Menutype for the target page.

    Not to be confused with the Menu under which this menu item will be assigned." +COM_MENUS_ITEMS_CHOOSE_MENU_LABEL="Choose a Menutype" +COM_MENUS_ITEMS_VIEW_DEFAULT_DESC="Shows a list of menu items" +COM_MENUS_ITEMS_VIEW_DEFAULT_TITLE="Menu Items" +COM_MENUS_ITEM_VIEW_EDIT_DESC="Shows a form to create a new menu item" +COM_MENUS_ITEM_VIEW_EDIT_TITLE="New Menu Item" +COM_MENUS_MENUS_VIEW_DEFAULT_DESC="Shows a list of Menu Types" +COM_MENUS_MENUS_VIEW_DEFAULT_TITLE="Menus" +COM_MENUS_MENU_VIEW_EDIT_DESC="Shows a form to create a new menu" +COM_MENUS_MENU_VIEW_EDIT_TITLE="New Menu" +COM_MENUS_XML_DESCRIPTION="Component for creating menus." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.com_messages.ini b/Sites/pages/administrator/language/en-GB/en-GB.com_messages.ini new file mode 100644 index 00000000..954c6c7f --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.com_messages.ini @@ -0,0 +1,83 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +COM_MESSAGES="Messaging" +COM_MESSAGES_ADD="New Private Message" +COM_MESSAGES_CONFIG_SAVED="Configuration saved." +COM_MESSAGES_CONFIGURATION="Messages: Options" +COM_MESSAGES_ERR_INVALID_USER="Invalid user" +COM_MESSAGES_ERR_SEND_FAILED="The user has locked their mailbox. Message failed." +COM_MESSAGES_ERROR_COULD_NOT_SEND_INVALID_RECIPIENT="The email message cannot be sent due to an invalid recipient address." +COM_MESSAGES_ERROR_COULD_NOT_SEND_INVALID_REPLYTO="The email message cannot be sent due to an invalid reply-to address." +COM_MESSAGES_ERROR_INVALID_FROM_USER="Invalid sender" +COM_MESSAGES_ERROR_INVALID_MESSAGE="Invalid message content" +COM_MESSAGES_ERROR_INVALID_SUBJECT="Invalid subject" +COM_MESSAGES_ERROR_INVALID_TO_USER="Invalid recipient" +COM_MESSAGES_ERROR_MISSING_ROOT_ASSET_GROUPS="Missing root asset groups to send notification." +COM_MESSAGES_ERROR_NO_GROUPS_SET_AS_SUPER_USER="There are no groups set with super user permissions." +COM_MESSAGES_ERROR_NO_USERS_SET_AS_SUPER_USER="There are no users set with super user permissions." +COM_MESSAGES_ERROR_RECIPIENT_NOT_AUTHORISED="Recipient is not authorised to receive messages." +COM_MESSAGES_FIELD_AUTO_PURGE_DESC="Automatically delete private messages after the given number of days." +COM_MESSAGES_FIELD_AUTO_PURGE_LABEL="Auto-delete Messages (days)" +COM_MESSAGES_FIELD_DATE_TIME_LABEL="Posted" +COM_MESSAGES_FIELD_LOCK_DESC="Lock your private message inbox." +COM_MESSAGES_FIELD_LOCK_LABEL="Lock Inbox" +COM_MESSAGES_FIELD_MAIL_ON_NEW_DESC="Email me when a new private message arrives." +COM_MESSAGES_FIELD_MAIL_ON_NEW_LABEL="Email New Messages" +COM_MESSAGES_FIELD_MESSAGE_DESC="You must enter a message." +COM_MESSAGES_FIELD_MESSAGE_LABEL="Message" +COM_MESSAGES_FIELD_SUBJECT_DESC="You must enter a subject." +COM_MESSAGES_FIELD_SUBJECT_LABEL="Subject" +COM_MESSAGES_FIELD_USER_ID_FROM_LABEL="From" +COM_MESSAGES_FIELD_USER_ID_TO_DESC="You must select a recipient." +COM_MESSAGES_FIELD_USER_ID_TO_LABEL="Recipient" +COM_MESSAGES_FILTER_SEARCH_LABEL="Search Messages" +COM_MESSAGES_FILTER_STATES_DESC="Filter by message state." +COM_MESSAGES_FILTER_STATES_LABEL="State" +COM_MESSAGES_HEADING_FROM="From" +COM_MESSAGES_HEADING_FROM_ASC="From ascending" +COM_MESSAGES_HEADING_FROM_DESC="From descending" +COM_MESSAGES_HEADING_READ="Read" +COM_MESSAGES_HEADING_READ_ASC="Read ascending" +COM_MESSAGES_HEADING_READ_DESC="Read descending" +COM_MESSAGES_HEADING_SUBJECT="Subject" +COM_MESSAGES_HEADING_SUBJECT_ASC="Subject ascending" +COM_MESSAGES_HEADING_SUBJECT_DESC="Subject descending" +COM_MESSAGES_INVALID_REPLY_ID="Invalid recipient" +COM_MESSAGES_MANAGER_MESSAGES="Private Messages" +COM_MESSAGES_MARK_AS_READ="Mark as Read" +COM_MESSAGES_MARK_AS_UNREAD="Mark as Unread" +COM_MESSAGES_MY_SETTINGS="My Settings" +COM_MESSAGES_N_ITEMS_DELETED="%d messages deleted." +COM_MESSAGES_N_ITEMS_DELETED_1="Message deleted." +COM_MESSAGES_N_ITEMS_PUBLISHED="%d messages marked as read." +COM_MESSAGES_N_ITEMS_PUBLISHED_1="Message marked as read." +COM_MESSAGES_N_ITEMS_TRASHED="%d messages trashed." +COM_MESSAGES_N_ITEMS_TRASHED_1="Message trashed." +COM_MESSAGES_N_ITEMS_UNPUBLISHED="%d messages marked as unread." +COM_MESSAGES_N_ITEMS_UNPUBLISHED_1="Message marked as unread." +COM_MESSAGES_NEW_MESSAGE="New Message from %1$s at %2$s" +; The following string is deprecated and will be removed in Joomla 4.0 +COM_MESSAGES_NEW_MESSAGE_ARRIVED="A new private message has arrived from %s" +COM_MESSAGES_NO_ITEM_SELECTED="No messages selected." +COM_MESSAGES_OPTION_READ="Read" +COM_MESSAGES_OPTION_UNREAD="Unread" +COM_MESSAGES_PLEASE_LOGIN="Please log in to %s to read your message." +COM_MESSAGES_RE="Re:" +COM_MESSAGES_READ="Messages" +COM_MESSAGES_READ_PRIVATE_MESSAGE="Read Private Message" +COM_MESSAGES_SAVE_SUCCESS="Message sent." +COM_MESSAGES_SEARCH_IN_SUBJECT="Search in message subject and description." +COM_MESSAGES_TOOLBAR_MARK_AS_READ="Mark as Read" +COM_MESSAGES_TOOLBAR_MARK_AS_UNREAD="Mark as Unread" +COM_MESSAGES_TOOLBAR_MY_SETTINGS="My Settings" +COM_MESSAGES_TOOLBAR_REPLY="Reply" +COM_MESSAGES_TOOLBAR_SEND="Send" +COM_MESSAGES_VIEW_PRIVATE_MESSAGE="Private Messages: View" +COM_MESSAGES_WRITE_PRIVATE_MESSAGE="Private Messages: Write" +COM_MESSAGES_XML_DESCRIPTION="Component for private messaging support in Backend." +; The following string is deprecated and will be removed with 4.0. +JLIB_APPLICATION_SAVE_SUCCESS="Message sent." +JLIB_RULES_SETTING_NOTES="Changes apply to this component only.
    Inherited - a Global Configuration setting or higher level setting is applied.
    Denied always wins - whatever is set at the Global or higher level and applies to all child elements.
    Allowed will enable the action for this component unless overruled by a Global Configuration setting." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.com_messages.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.com_messages.sys.ini new file mode 100644 index 00000000..bd61f264 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.com_messages.sys.ini @@ -0,0 +1,9 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +COM_MESSAGES="Messaging" +COM_MESSAGES_ADD="New Private Message" +COM_MESSAGES_READ="Read Private Messages" +COM_MESSAGES_XML_DESCRIPTION="Component for private messaging support in the Backend." \ No newline at end of file diff --git a/Sites/pages/administrator/language/en-GB/en-GB.com_modules.ini b/Sites/pages/administrator/language/en-GB/en-GB.com_modules.ini new file mode 100644 index 00000000..9a9247b8 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.com_modules.ini @@ -0,0 +1,205 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +COM_MODULES="Modules" +COM_MODULES_ACTION_EDITFRONTEND="Frontend Editing" +COM_MODULES_ACTION_EDITFRONTEND_COMPONENT_DESC="Allows users in the group to edit in Frontend." +COM_MODULES_ADMIN_LANG_FILTER_FIELDSET_LABEL="Administrator Modules" +COM_MODULES_ADMIN_LANG_FILTER_DESC="Allows filtering administrator modules per administrator language." +COM_MODULES_ADMIN_LANG_FILTER_LABEL="Language Filtering" +COM_MODULES_ADVANCED_FIELDSET_LABEL="Advanced" +COM_MODULES_ASSIGNED_VARIES_EXCEPT="All except selected" +COM_MODULES_ASSIGNED_VARIES_ONLY="Selected" +COM_MODULES_BASIC_FIELDSET_LABEL="Options" +COM_MODULES_BATCH_POSITION_LABEL="Set Position" +COM_MODULES_BATCH_POSITION_NOCHANGE="Keep original Position" +COM_MODULES_BATCH_POSITION_NOPOSITION="No Module Position" +COM_MODULES_BATCH_OPTIONS="Batch process the selected modules" +COM_MODULES_BATCH_TIP="If choosing to copy a module, any other actions selected will be applied to the copied module. Otherwise, all actions are applied to the selected module. When copying and not changing position, it is nevertheless necessary to select 'Keep Original Position' in the dropdown." +COM_MODULES_CHANGE_POSITION_BUTTON="Select" +COM_MODULES_CHANGE_POSITION_TITLE="Change" +COM_MODULES_CONFIGURATION="Module: Options" +COM_MODULES_CUSTOM_OUTPUT="Custom Output" +COM_MODULES_ERR_XML="Module XML data not available" +COM_MODULES_ERROR_CANNOT_FIND_MODULE="Can't find module" +COM_MODULES_ERROR_CANNOT_GET_MODULE="Can't get module" +COM_MODULES_ERROR_INVALID_EXTENSION="Invalid module" +COM_MODULES_ERROR_NO_MODULES_SELECTED="No module selected." +COM_MODULES_EXTENSION_PUBLISHED_DISABLED="Module disabled and published." +COM_MODULES_EXTENSION_PUBLISHED_ENABLED="Module enabled and published." +COM_MODULES_EXTENSION_UNPUBLISHED_DISABLED="Module disabled and unpublished." +COM_MODULES_EXTENSION_UNPUBLISHED_ENABLED="Module enabled and unpublished." +COM_MODULES_EXTRA_STYLE_DESC="Specify the style for the module or the modules in the position selected." +COM_MODULES_EXTRA_STYLE_TITLE="Module(s) style" +COM_MODULES_FIELD_AUTOMATIC_TITLE_LABEL="Automatic Title" +COM_MODULES_FIELD_AUTOMATIC_TITLE_DESC="Set yes if you want an automatic translated title. Its use depends on the Administrator template." +COM_MODULES_FIELD_CACHE_TIME_DESC="The time in seconds before the module is recached." +COM_MODULES_FIELD_CACHE_TIME_LABEL="Cache Time" +COM_MODULES_FIELD_CACHING_DESC="Use the global cache setting to cache the content of this module or disable caching for this module." +COM_MODULES_FIELD_CACHING_LABEL="Caching" +COM_MODULES_FIELD_CLIENT_ID_DESC="The location of the module, Frontend or Backend. You can't change this value." +COM_MODULES_FIELD_CLIENT_ID_LABEL="Module Location" +COM_MODULES_FIELD_CONTENT_DESC="Text" +COM_MODULES_FIELD_CONTENT_LABEL="Text" +COM_MODULES_FIELD_CONTENT_TOO_LARGE="The content exceeds allowed limits" +COM_MODULES_FIELD_MODULE_DESC="Module type." +COM_MODULES_FIELD_MODULE_LABEL="Module Type" +COM_MODULES_FIELD_MODULECLASS_SFX_DESC="A suffix to be applied to the CSS class of the module. This allows for individual module styling." +COM_MODULES_FIELD_MODULECLASS_SFX_LABEL="Module Class Suffix" +COM_MODULES_FIELD_NOTE_DESC="An optional note to display in the Module Manager." +COM_MODULES_FIELD_NOTE_LABEL="Note" +COM_MODULES_FIELD_POSITION_DESC="You may select a module position from the list of pre-defined positions or enter your own module position by typing the name in the field and pressing enter." +COM_MODULES_FIELD_POSITION_LABEL="Position" +COM_MODULES_FIELD_PUBLISH_DOWN_DESC="An optional date to Finish Publishing the module." +COM_MODULES_FIELD_PUBLISH_DOWN_LABEL="Finish Publishing" +COM_MODULES_FIELD_PUBLISH_UP_DESC="An optional date to Start Publishing the module." +COM_MODULES_FIELD_PUBLISH_UP_LABEL="Start Publishing" +COM_MODULES_FIELD_PUBLISHED_DESC="If published, this module will display on your site Frontend or Backend depending on the module." +COM_MODULES_FIELD_SHOWTITLE_DESC="Show or hide module title on display. Effect will depend on the chrome style in the template." +COM_MODULES_FIELD_SHOWTITLE_LABEL="Show Title" +COM_MODULES_FIELD_TITLE_DESC="Module must have a title." +COM_MODULES_FIELD_VALUE_NOCACHING="No caching" +COM_MODULES_FIELD_MODULE_TAG_LABEL="Module Tag" +COM_MODULES_FIELD_MODULE_TAG_DESC="The HTML tag for module." +COM_MODULES_FIELD_BOOTSTRAP_SIZE_LABEL="Bootstrap Size" +COM_MODULES_FIELD_BOOTSTRAP_SIZE_DESC="An option to specify how many columns the module will use." +COM_MODULES_FIELD_HEADER_TAG_LABEL="Header Tag" +COM_MODULES_FIELD_HEADER_TAG_DESC="The HTML tag for module header/title." +COM_MODULES_FIELD_HEADER_CLASS_LABEL="Header Class" +COM_MODULES_FIELD_HEADER_CLASS_DESC="The CSS class for module header/title." +COM_MODULES_FIELD_MODULE_STYLE_LABEL="Module Style" +COM_MODULES_FIELD_MODULE_STYLE_DESC="Use this option to override the template style for its position." +COM_MODULES_FIELDSET_RULES="Permissions" +COM_MODULES_FILTER_SEARCH_DESC="Filter by position name." +COM_MODULES_GENERAL_FIELDSET_DESC="Configure module edit interface settings." +COM_MODULES_HEADING_MODULE="Type" +COM_MODULES_HEADING_MODULE_ASC="Type ascending" +COM_MODULES_HEADING_MODULE_DESC="Type descending" +COM_MODULES_HEADING_PAGES="Pages" +COM_MODULES_HEADING_PAGES_ASC="Pages ascending" +COM_MODULES_HEADING_PAGES_DESC="Pages descending" +COM_MODULES_HEADING_POSITION="Position" +COM_MODULES_HEADING_POSITION_ASC="Position ascending" +COM_MODULES_HEADING_POSITION_DESC="Position descending" +COM_MODULES_HEADING_TEMPLATES="Templates" +COM_MODULES_HTML_PUBLISH_DISABLED="Publish module::Extension disabled" +COM_MODULES_HTML_PUBLISH_ENABLED="Publish module::Extension enabled" +COM_MODULES_HTML_UNPUBLISH_DISABLED="Unpublish module::Extension disabled" +COM_MODULES_HTML_UNPUBLISH_ENABLED="Unpublish module::Extension enabled" +COM_MODULES_MANAGER_MODULE="Modules: %s" +COM_MODULES_MANAGER_MODULE_ADD="Modules: Add New Module" +COM_MODULES_MANAGER_MODULE_EDIT="Modules: Edit Module" +COM_MODULES_MANAGER_MODULES="Modules" +COM_MODULES_MANAGER_MODULES_ADMIN="Modules (Administrator)" +COM_MODULES_MANAGER_MODULES_SITE="Modules (Site)" +COM_MODULES_MENU_ASSIGNMENT="Menu Assignment" +COM_MODULES_MENU_ITEM_SEPARATOR="Separator" +COM_MODULES_MENU_ITEM_HEADING="Heading" +COM_MODULES_MENU_ITEM_ALIAS="Alias" +COM_MODULES_MENU_ITEM_URL="URL" +COM_MODULES_MODULE_ASSIGN="Module Assignment" +COM_MODULES_MODULE="Module" +COM_MODULES_MODULE_DESCRIPTION="Module Description" +COM_MODULES_MODULE_TEMPLATE_POSITION="%1$s (%2$s)" +COM_MODULES_MODULES="Modules" +COM_MODULES_MODULES_FILTER_SEARCH_DESC="Search in module title and note. Prefix with ID: to search for a module ID." +COM_MODULES_MODULES_FILTER_SEARCH_LABEL="Search Modules" +COM_MODULES_MSG_MANAGE_NO_MODULES="There are no modules matching your query" +COM_MODULES_MSG_MANAGE_EXTENSION_DISABLED="This module is disabled. Use Extensions => Manage to enable it." +COM_MODULES_N_ITEMS_ARCHIVED="%d modules archived." +COM_MODULES_N_ITEMS_ARCHIVED_1="%d module archived." +COM_MODULES_N_ITEMS_CHECKED_IN_0="No module checked in." +COM_MODULES_N_ITEMS_CHECKED_IN_1="%d module checked in." +COM_MODULES_N_ITEMS_CHECKED_IN_MORE="%d modules checked in." +COM_MODULES_N_ITEMS_DELETED="%d modules deleted." +COM_MODULES_N_ITEMS_DELETED_1="%d module deleted." +COM_MODULES_N_ITEMS_PUBLISHED="%d modules published." +COM_MODULES_N_ITEMS_PUBLISHED_1="%d module published." +COM_MODULES_N_ITEMS_TRASHED="%d modules trashed." +COM_MODULES_N_ITEMS_TRASHED_1="%d module trashed." +COM_MODULES_N_ITEMS_UNPUBLISHED="%d modules unpublished." +COM_MODULES_N_ITEMS_UNPUBLISHED_1="%d module unpublished." +COM_MODULES_N_MODULES_DUPLICATED="%d modules duplicated." +COM_MODULES_N_MODULES_DUPLICATED_1="%d module duplicated." +COM_MODULES_NO_ITEM_SELECTED="No modules selected." +COM_MODULES_NODESCRIPTION="No description available." +COM_MODULES_NONE=":: None ::" +COM_MODULES_OPTION_MENU_ALL="On all pages" +COM_MODULES_OPTION_MENU_EXCLUDE="On all pages except those selected" +COM_MODULES_OPTION_MENU_INCLUDE="Only on the pages selected" +COM_MODULES_OPTION_MENU_NONE="No pages" +COM_MODULES_OPTION_ORDER_POSITION="%d. %s" +COM_MODULES_OPTION_POSITION_TEMPLATE_DEFINED="Template" +COM_MODULES_OPTION_POSITION_USER_DEFINED="User" +COM_MODULES_OPTION_SELECT_CLIENT="- Select Type -" +COM_MODULES_OPTION_SELECT_MENU_ITEM="- Select Menu Item -" +COM_MODULES_OPTION_SELECT_MODULE="- Select Type -" +; Deprecated 4.0 +COM_MODULES_OPTION_SELECT_PAGE="- Select Page -" +COM_MODULES_OPTION_SELECT_POSITION="- Select Position -" +COM_MODULES_OPTION_SELECT_TYPE="- Select type -" +COM_MODULES_POSITION_ANALYTICS="Analytics" +COM_MODULES_POSITION_BANNER="Banner" +COM_MODULES_POSITION_BOTTOM="Bottom" +COM_MODULES_POSITION_BREADCRUMB="Breadcrumb" +COM_MODULES_POSITION_BREADCRUMBS="Breadcrumbs" +COM_MODULES_POSITION_DEBUG="Debug" +COM_MODULES_POSITION_FOOTER="Footer" +COM_MODULES_POSITION_HEADER="Header" +COM_MODULES_POSITION_LEFT2="Left 2" +COM_MODULES_POSITION_LEFT="Left" +COM_MODULES_POSITION_MAINNAV="Main Navigation" +COM_MODULES_POSITION_NAV="Navigation" +COM_MODULES_POSITION_OFFLINE="Offline" +COM_MODULES_POSITION_POSITION-0="Position 0" +COM_MODULES_POSITION_POSITION-10="Position 10" +COM_MODULES_POSITION_POSITION-11="Position 11" +COM_MODULES_POSITION_POSITION-12="Position 12" +COM_MODULES_POSITION_POSITION-13="Position 13" +COM_MODULES_POSITION_POSITION-14="Position 14" +COM_MODULES_POSITION_POSITION-15="Position 15" +COM_MODULES_POSITION_POSITION-1="Position 1" +COM_MODULES_POSITION_POSITION-2="Position 2" +COM_MODULES_POSITION_POSITION-3="Position 3" +COM_MODULES_POSITION_POSITION-4="Position 4" +COM_MODULES_POSITION_POSITION-5="Position 5" +COM_MODULES_POSITION_POSITION-6="Position 6" +COM_MODULES_POSITION_POSITION-7="Position 7" +COM_MODULES_POSITION_POSITION-8="Position 8" +COM_MODULES_POSITION_POSITION-9="Position 9" +COM_MODULES_POSITION_RIGHT2="Right 2" +COM_MODULES_POSITION_RIGHT="Right" +COM_MODULES_POSITION_SUB1="Sub 1" +COM_MODULES_POSITION_SUB2="Sub 2" +COM_MODULES_POSITION_SUB3="Sub 3" +COM_MODULES_POSITION_SUB4="Sub 4" +COM_MODULES_POSITION_SUB5="Sub 5" +COM_MODULES_POSITION_SUB6="Sub 6" +COM_MODULES_POSITION_SUB="Sub" +COM_MODULES_POSITION_SUBNAV="Sub Navigation" +COM_MODULES_POSITION_SYNDICATE="Syndicate" +COM_MODULES_POSITION_TOP2="Top 2" +COM_MODULES_POSITION_TOP3="Top 3" +COM_MODULES_POSITION_TOP4="Top 4" +COM_MODULES_POSITION_TOP="Top" +COM_MODULES_POSITION_USER1="User 1" +COM_MODULES_POSITION_USER2="User 2" +COM_MODULES_POSITION_USER3="User 3" +COM_MODULES_POSITION_USER4="User 4" +COM_MODULES_POSITION_USER5="User 5" +COM_MODULES_POSITION_USER6="User 6" +COM_MODULES_POSITION_USER7="User 7" +COM_MODULES_POSITION_USER8="User 8" +COM_MODULES_SAVE_SUCCESS="Module saved" +COM_MODULES_TYPE_CHOOSE="Select a Module Type:" +COM_MODULES_XML_DESCRIPTION="Component for module management in Backend" +COM_MODULES_ADD_CUSTOM_POSITION="Add custom position" +COM_MODULES_CUSTOM_POSITION="Active Positions" +COM_MODULES_TYPE_OR_SELECT_POSITION="Type or Select a Position" +COM_MODULES_DESELECT="Deselect" +COM_MODULES_EXPAND="Expand" +COM_MODULES_COLLAPSE="Collapse" +COM_MODULES_SUBITEMS="Sub-items:" +JLIB_RULES_SETTING_NOTES="Changes apply to this component only.
    Inherited - a Global Configuration setting or higher level setting is applied.
    Denied always wins - whatever is set at the Global or higher level and applies to all child elements.
    Allowed will enable the action for this component unless overruled by a Global Configuration setting." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.com_modules.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.com_modules.sys.ini new file mode 100644 index 00000000..3a83047b --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.com_modules.sys.ini @@ -0,0 +1,14 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +COM_MODULES="Modules" +COM_MODULES_ACTION_EDITFRONTEND="Frontend Editing" +COM_MODULES_ACTION_EDITFRONTEND_COMPONENT_DESC="Allows users in the group to edit in Frontend." +COM_MODULES_GENERAL="General" +COM_MODULES_MODULES_VIEW_DEFAULT_DESC="Shows a list of modules to manage" +COM_MODULES_MODULES_VIEW_DEFAULT_TITLE="Module Manager" +COM_MODULES_REDIRECT_EDIT_DESC="Select if module editing should be opened in the site or administration interface." +COM_MODULES_REDIRECT_EDIT_LABEL="Edit Module" +COM_MODULES_XML_DESCRIPTION="Component for module management on the Backend." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.com_newsfeeds.ini b/Sites/pages/administrator/language/en-GB/en-GB.com_newsfeeds.ini new file mode 100644 index 00000000..ecf35cc6 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.com_newsfeeds.ini @@ -0,0 +1,140 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +COM_NEWSFEEDS="News Feeds" +; COM_NEWSFEEDS_BATCH_MENU_LABEL is deprecated, use JLIB_HTML_BATCH_MENU_LABEL instead. +COM_NEWSFEEDS_BATCH_MENU_LABEL="To Move or Copy your selection please select a Category." +COM_NEWSFEEDS_BATCH_OPTIONS="Batch process the selected news feeds" +COM_NEWSFEEDS_BATCH_TIP="If a category is selected for move/copy, any actions selected will be applied to the copied or moved news feeds. Otherwise, all actions are applied to the selected news feeds." +COM_NEWSFEEDS_CACHE_TIME_HEADING="Cache Time" +COM_NEWSFEEDS_CACHE_TIME_HEADING_ASC="Cache Time ascending" +COM_NEWSFEEDS_CACHE_TIME_HEADING_DESC="Cache Time descending" +COM_NEWSFEEDS_CATEGORIES_DESC="These settings apply for News Feeds Categories Options unless they are changed for a specific menu item." +COM_NEWSFEEDS_CHANGE_FEED="Select or Change News Feed" +; COM_NEWSFEEDS_CHANGE_FEED_BUTTON is deprecated, use COM_NEWSFEEDS_CHANGE_FEED instead; +COM_NEWSFEEDS_CHANGE_FEED_BUTTON="Select Feed" +COM_NEWSFEEDS_CONFIG_INTEGRATION_SETTINGS_DESC="These settings determine how the Newsfeeds Component will integrate with other extensions." +COM_NEWSFEEDS_CONFIGURATION="News Feed: Options" +COM_NEWSFEEDS_EDIT_NEWSFEED="Edit News Feed" +COM_NEWSFEEDS_ERROR_UNIQUE_ALIAS="Another News feed from this category has the same alias (remember it may be a trashed item)." +COM_NEWSFEEDS_ERROR_ALL_LANGUAGE_ASSOCIATED="A news feed item set to All languages can't be associated. Associations have not been set." +COM_NEWSFEEDS_FEED_CATEGORY_OPTIONS_LABEL="Feeds Category Display Options" +COM_NEWSFEEDS_FIELD_CACHETIME_DESC="The number of minutes before the news feed cache is refreshed." +COM_NEWSFEEDS_FIELD_CACHETIME_LABEL="Cache Time" +COM_NEWSFEEDS_FIELD_CATEGORIES_OPTIONS_LABEL="Feeds Categories Display Options" +COM_NEWSFEEDS_FIELD_CATEGORY_DESC="The category that this feed is assigned to." +COM_NEWSFEEDS_FIELD_CHARACTER_COUNT_DESC="Number of characters to display per feed. 0 will show all the text." +COM_NEWSFEEDS_FIELD_CHARACTER_COUNT_LABEL="Characters Count" +COM_NEWSFEEDS_FIELD_CHARACTERS_COUNT_DESC="Number of characters to include in the feed. 0 will show all the text." +COM_NEWSFEEDS_FIELD_CHARACTERS_COUNT_LABEL="Characters Count" +COM_NEWSFEEDS_FIELD_CONFIG_CATEGORY_SETTINGS_DESC="These settings apply for News Feeds Category Options unless they are changed for a specific menu item." +COM_NEWSFEEDS_FIELD_CONFIG_LIST_SETTINGS_DESC="These settings apply for List Layout Options unless they are changed for a specific menu item." +COM_NEWSFEEDS_FIELD_CONFIG_NEWSFEED_SETTINGS_DESC="These settings apply for single news feeds unless they are changed for a specific menu item or news feed." +COM_NEWSFEEDS_FIELD_CONFIG_NEWSFEED_SETTINGS_LABEL="News Feed" +COM_NEWSFEEDS_FIELD_DESCRIPTION_DESC="Enter a description for the feed." +COM_NEWSFEEDS_FIELD_FEED_DISPLAY_ORDER_DESC="The order used to display the feed." +COM_NEWSFEEDS_FIELD_FEED_DISPLAY_ORDER_LABEL="Feed Display Order" +COM_NEWSFEEDS_FIELD_FEED_OPTIONS_DESC="Feeds display options." +COM_NEWSFEEDS_FIELD_FEED_OPTIONS_LABEL="Feeds Display Options" +COM_NEWSFEEDS_FIELD_FIRST_DESC="Select or upload the image to be displayed." +COM_NEWSFEEDS_FIELD_FIRST_LABEL="First Image" +COM_NEWSFEEDS_FIELD_IMAGE_ALT_DESC="Alternative text used for visitors without access to images. Replaced with caption text if it is present." +COM_NEWSFEEDS_FIELD_IMAGE_ALT_LABEL="Alt Text" +COM_NEWSFEEDS_FIELD_IMAGE_CAPTION_DESC="Caption attached to the image." +COM_NEWSFEEDS_FIELD_IMAGE_CAPTION_LABEL="Caption" +COM_NEWSFEEDS_FIELD_LANGUAGE_DESC="Assign a language to this news feed." +COM_NEWSFEEDS_FIELD_LINK_DESC="Link to the news feed. IDN (International) Links are converted to punycode when they are saved." +COM_NEWSFEEDS_FIELD_LINK_LABEL="Link" +COM_NEWSFEEDS_FIELD_MODIFIED_BY_DESC="Name of the user who modified this news feed." +COM_NEWSFEEDS_FIELD_MODIFIED_DESC="The date and time the news feed was last modified." +COM_NEWSFEEDS_FIELD_NUM_ARTICLES_COLUMN_DESC="Show or hide the Number of Articles in each Feed (You can set this value in each News feed)." +COM_NEWSFEEDS_FIELD_NUM_ARTICLES_COLUMN_LABEL="# Articles" +COM_NEWSFEEDS_FIELD_NUM_ARTICLES_DESC="Number of articles from the feed to display." +COM_NEWSFEEDS_FIELD_NUM_ARTICLES_LABEL="Number of Articles" +COM_NEWSFEEDS_FIELD_NUMBER_ITEMS_LIST_DESC="Default number of feeds to list on a page." +COM_NEWSFEEDS_FIELD_NUMBER_ITEMS_LIST_LABEL="# Feeds to List" +COM_NEWSFEEDS_FIELD_NUMFEEDS_DESC="Number of feeds to display." +COM_NEWSFEEDS_FIELD_NUMFEEDS_LABEL="Number of Feeds" +COM_NEWSFEEDS_FIELD_OPTIONS="Feed" +COM_NEWSFEEDS_FIELD_RTL_DESC="Select the language direction of the feed." +COM_NEWSFEEDS_FIELD_RTL_LABEL="Language Direction" +COM_NEWSFEEDS_FIELD_SECOND_DESC="Select or upload the second image to be displayed." +COM_NEWSFEEDS_FIELD_SECOND_LABEL="Second Image" +COM_NEWSFEEDS_FIELD_SELECT_CATEGORY_DESC="Choose a feed category to display." +COM_NEWSFEEDS_FIELD_SELECT_FEED_DESC="Select a feed to display." +COM_NEWSFEEDS_FIELD_SELECT_FEED_LABEL="Feed" +COM_NEWSFEEDS_FIELD_SHOW_CAT_ITEMS_DESC="Show or hide the number of news feeds in category." +COM_NEWSFEEDS_FIELD_SHOW_CAT_ITEMS_LABEL="# Feeds in Category" +COM_NEWSFEEDS_FIELD_SHOW_CAT_TAGS_DESC="Show the tags for a category." +COM_NEWSFEEDS_FIELD_SHOW_CAT_TAGS_LABEL="Show Tags" +COM_NEWSFEEDS_FIELD_SHOW_FEED_DESCRIPTION_DESC="Show or hide feed description." +COM_NEWSFEEDS_FIELD_SHOW_FEED_DESCRIPTION_LABEL="Feed Description" +COM_NEWSFEEDS_FIELD_SHOW_FEED_IMAGE_DESC="Show or hide feed images." +COM_NEWSFEEDS_FIELD_SHOW_FEED_IMAGE_LABEL="Feed Image" +COM_NEWSFEEDS_FIELD_SHOW_ITEM_DESCRIPTION_DESC="Show or hide feed content." +COM_NEWSFEEDS_FIELD_SHOW_ITEM_DESCRIPTION_LABEL="Feed Content" +COM_NEWSFEEDS_FIELD_SHOW_LINKS_DESC="Show or hide feed links URL." +COM_NEWSFEEDS_FIELD_SHOW_LINKS_LABEL="Feed Links" +COM_NEWSFEEDS_FIELD_SHOW_TAGS_DESC="Show the tags for a news feed." +COM_NEWSFEEDS_FIELD_SHOW_TAGS_LABEL="Show Tags" +COM_NEWSFEEDS_FIELD_VALUE_LTR="Left to Right Direction" +COM_NEWSFEEDS_FIELD_VALUE_NONE="None" +COM_NEWSFEEDS_FIELD_VALUE_RTL="Right to Left Direction" +COM_NEWSFEEDS_FIELD_VALUE_SITE="Site Language Direction" +COM_NEWSFEEDS_FIELD_VERSION_LABEL="Revision" +COM_NEWSFEEDS_FIELD_VERSION_DESC="A count of the number of times this news feed has been revised." +COM_NEWSFEEDS_FIELDSET_IMAGES="Images" +COM_NEWSFEEDS_FIELDSET_MORE_OPTIONS_LABEL="Feed Display Options" +COM_NEWSFEEDS_FILTER_SEARCH_DESC="Search in news feed title and alias. Prefix with ID: to search for a news feed ID." +COM_NEWSFEEDS_FILTER_SEARCH_LABEL="Search News Feeds" +COM_NEWSFEEDS_FLOAT_DESC="Controls placement of the image." +COM_NEWSFEEDS_FLOAT_FIRST_LABEL="First Image Float" +COM_NEWSFEEDS_FLOAT_LABEL="Image Float" +COM_NEWSFEEDS_FLOAT_SECOND_LABEL="Second Image Float" +COM_NEWSFEEDS_HEADING_ASSOCIATION="Association" +COM_NEWSFEEDS_HITS_DESC="Number of hits for this news feed." +; The following 2 strings are deprecated and will be removed with 4.0. +COM_NEWSFEEDS_ITEM_ASSOCIATIONS_FIELDSET_LABEL="News Feed Item Association" +COM_NEWSFEEDS_ITEM_ASSOCIATIONS_FIELDSET_DESC="Multilingual only! This choice will only display if the Language Filter parameter 'Item Associations' is set to 'Yes'. Choose a news feed item for the target language. This association will let the Language Switcher module redirect to the associated news feed item in another language. If used, make sure to display the Language switcher module on the relevant pages. A news feed item set to language 'All' can't be associated." +COM_NEWSFEEDS_LEFT="Left" +COM_NEWSFEEDS_MANAGER_NEWSFEED="News Feeds: New/Edit" +COM_NEWSFEEDS_MANAGER_NEWSFEED_NEW="News Feeds: New" +COM_NEWSFEEDS_MANAGER_NEWSFEED_EDIT="News Feeds: Edit" +COM_NEWSFEEDS_MANAGER_NEWSFEEDS="News Feeds" +COM_NEWSFEEDS_N_ITEMS_ARCHIVED="%d news feeds archived." +COM_NEWSFEEDS_N_ITEMS_ARCHIVED_1="News feed archived." +COM_NEWSFEEDS_N_ITEMS_CHECKED_IN_0="No news feed checked in." +COM_NEWSFEEDS_N_ITEMS_CHECKED_IN_1="News feed checked in." +COM_NEWSFEEDS_N_ITEMS_CHECKED_IN_MORE="%d news feeds checked in." +COM_NEWSFEEDS_N_ITEMS_DELETED="%d news feeds deleted." +COM_NEWSFEEDS_N_ITEMS_DELETED_1="News feed deleted." +COM_NEWSFEEDS_N_ITEMS_PUBLISHED="%d news feeds published." +COM_NEWSFEEDS_N_ITEMS_PUBLISHED_1="News feed published." +COM_NEWSFEEDS_N_ITEMS_TRASHED="%d news feeds trashed." +COM_NEWSFEEDS_N_ITEMS_TRASHED_1="News feed trashed." +COM_NEWSFEEDS_N_ITEMS_UNPUBLISHED="%d news feeds unpublished." +COM_NEWSFEEDS_N_ITEMS_UNPUBLISHED_1="News feed unpublished." +COM_NEWSFEEDS_NEW_NEWSFEED="New News Feed" +COM_NEWSFEEDS_NEWSFEEDS="Newsfeeds" +COM_NEWSFEEDS_NO_ITEM_SELECTED="No news feeds selected." +COM_NEWSFEEDS_NONE="None" +COM_NEWSFEEDS_NUM_ARTICLES_HEADING="# Articles" +COM_NEWSFEEDS_NUM_ARTICLES_HEADING_ASC="# Articles ascending" +COM_NEWSFEEDS_NUM_ARTICLES_HEADING_DESC="# Articles descending" +COM_NEWSFEEDS_PUBLISH_ITEM="Publish News Feed" +COM_NEWSFEEDS_RIGHT="Right" +COM_NEWSFEEDS_SAVE_SUCCESS="News feed saved." +COM_NEWSFEEDS_SEARCH_IN_TITLE="Search" +COM_NEWSFEEDS_SELECT_A_FEED="Select a News Feed" +COM_NEWSFEEDS_SELECT_FEED="Select feed" +COM_NEWSFEEDS_SHOW_EMPTY_CATEGORIES_DESC="If Show, empty categories will display. A category is only empty if it has no news feeds or subcategories." +COM_NEWSFEEDS_SUBMENU_CATEGORIES="Categories" +COM_NEWSFEEDS_SUBMENU_NEWSFEEDS="News Feeds" +COM_NEWSFEEDS_TIP_ASSOCIATION="Associated news feeds" +COM_NEWSFEEDS_UNPUBLISH_ITEM="Unpublish News Feed" +COM_NEWSFEEDS_WARNING_PROVIDE_VALID_NAME="Please provide a valid name." +COM_NEWSFEEDS_XML_DESCRIPTION="This component manages RSS and Atom news feeds." +JGLOBAL_NEWITEMSLAST_DESC="New news feeds default to the last position. The ordering can be changed after this news feed has been saved." +JLIB_RULES_SETTING_NOTES="Changes apply to this component only.
    Inherited - a Global Configuration setting or higher level setting is applied.
    Denied always wins - whatever is set at the Global or higher level and applies to all child elements.
    Allowed will enable the action for this component unless overruled by a Global Configuration setting." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.com_newsfeeds.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.com_newsfeeds.sys.ini new file mode 100644 index 00000000..5192b733 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.com_newsfeeds.sys.ini @@ -0,0 +1,24 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +COM_NEWSFEEDS="News Feeds" +COM_NEWSFEEDS_CATEGORIES="Categories" +COM_NEWSFEEDS_CATEGORIES_VIEW_DEFAULT_DESC="Show all the news feed categories within a category." +COM_NEWSFEEDS_CATEGORIES_VIEW_DEFAULT_OPTION="Default" +COM_NEWSFEEDS_CATEGORIES_VIEW_DEFAULT_TITLE="List All News Feed Categories" +COM_NEWSFEEDS_CATEGORY_ADD_TITLE="News Feed: Add Category" +COM_NEWSFEEDS_CATEGORY_EDIT_TITLE="News Feed: Edit Category" +COM_NEWSFEEDS_CATEGORY_VIEW_DEFAULT_DESC="Show all news feeds within a category." +COM_NEWSFEEDS_CATEGORY_VIEW_DEFAULT_OPTION="Default" +COM_NEWSFEEDS_CATEGORY_VIEW_DEFAULT_TITLE="List News Feeds in a Category" +COM_NEWSFEEDS_CONTENT_TYPE_NEWSFEED="News feed" +COM_NEWSFEEDS_CONTENT_TYPE_CATEGORY="News Feed Category" +COM_NEWSFEEDS_FEEDS="Feeds" +COM_NEWSFEEDS_NEWSFEED_VIEW_DEFAULT_DESC="Show a single news feed." +COM_NEWSFEEDS_NEWSFEED_VIEW_DEFAULT_OPTION="Default" +COM_NEWSFEEDS_NEWSFEED_VIEW_DEFAULT_TITLE="Single News Feed" +COM_NEWSFEEDS_TAGS_NEWSFEED="News Feed" +COM_NEWSFEEDS_TAGS_CATEGORY="News Feed Category" +COM_NEWSFEEDS_XML_DESCRIPTION="This component manages RSS and Atom news feeds." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.com_plugins.ini b/Sites/pages/administrator/language/en-GB/en-GB.com_plugins.ini new file mode 100644 index 00000000..2949f296 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.com_plugins.ini @@ -0,0 +1,47 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +COM_PLUGINS="Plugins" +COM_PLUGINS_ADVANCED_FIELDSET_LABEL="Advanced" +COM_PLUGINS_BASIC_FIELDSET_LABEL="Basic" +COM_PLUGINS_CONFIGURATION="Plugin: Options" +COM_PLUGINS_ELEMENT_HEADING="Element" +COM_PLUGINS_ERROR_FILE_NOT_FOUND="The file %s could not be found." +COM_PLUGINS_FIELD_ELEMENT_DESC="Plugin main file name." +COM_PLUGINS_FIELD_ELEMENT_LABEL="Plugin File" +COM_PLUGINS_FIELD_ENABLED_DESC="The enabled status of this plugin." +COM_PLUGINS_FIELD_FOLDER_DESC="Category/folder of plugins this plugin belongs to." +COM_PLUGINS_FIELD_FOLDER_LABEL="Plugin Type" +COM_PLUGINS_FIELD_NAME_DESC="The name of the plugin as defined in its xml." +COM_PLUGINS_FIELD_NAME_LABEL="Plugin Name" +COM_PLUGINS_FILTER_SEARCH_LABEL="Search Plugins" +COM_PLUGINS_FOLDER_HEADING="Type" +COM_PLUGINS_HEADING_ELEMENT_ASC="Element ascending" +COM_PLUGINS_HEADING_ELEMENT_DESC="Element descending" +COM_PLUGINS_HEADING_FOLDER_ASC="Type ascending" +COM_PLUGINS_HEADING_FOLDER_DESC="Type descending" +COM_PLUGINS_MANAGER_PLUGIN="Plugins: %s" +COM_PLUGINS_MANAGER_PLUGINS="Plugins" +COM_PLUGINS_MSG_MANAGE_NO_PLUGINS="There are no plugins installed matching your query." +COM_PLUGINS_N_ITEMS_CHECKED_IN_0="No plugin checked in." +COM_PLUGINS_N_ITEMS_CHECKED_IN_1="%d plugin checked in." +COM_PLUGINS_N_ITEMS_CHECKED_IN_MORE="%d plugins checked in." +COM_PLUGINS_N_ITEMS_PUBLISHED="%d plugins enabled." +COM_PLUGINS_N_ITEMS_PUBLISHED_1="Plugin enabled." +COM_PLUGINS_N_ITEMS_UNPUBLISHED="%d plugins disabled." +COM_PLUGINS_N_ITEMS_UNPUBLISHED_1="Plugin disabled." +COM_PLUGINS_NAME_HEADING="Plugin Name" +COM_PLUGINS_NO_ITEM_SELECTED="No plugins selected." +COM_PLUGINS_OPTION_ELEMENT="- Select Element -" +COM_PLUGINS_OPTION_FOLDER="- Select Type -" +COM_PLUGINS_PLUGIN="Plugin" +COM_PLUGINS_PLUGINS="Plugins" +COM_PLUGINS_SAVE_SUCCESS="Plugin saved." +COM_PLUGINS_SEARCH_IN_TITLE="Search in plugin name. Prefix with ID: to search for a plugin ID." +COM_PLUGINS_XML_DESCRIPTION="This component manages Joomla plugins." +COM_PLUGINS_XML_ERR="Plugins XML data not available." +JLIB_HTML_PUBLISH_ITEM="Enable plugin" +JLIB_HTML_UNPUBLISH_ITEM="Disable plugin" +JLIB_RULES_SETTING_NOTES="Changes apply to this component only.
    Inherited - a Global Configuration setting or higher level setting is applied.
    Denied always wins - whatever is set at the Global or higher level and applies to all child elements.
    Allowed will enable the action for this component unless overruled by a Global Configuration setting." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.com_plugins.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.com_plugins.sys.ini new file mode 100644 index 00000000..fb05333b --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.com_plugins.sys.ini @@ -0,0 +1,9 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +COM_PLUGINS="Plugins" +COM_PLUGINS_PLUGINS_VIEW_DEFAULT_DESC="Shows a list of plugins to manage" +COM_PLUGINS_PLUGINS_VIEW_DEFAULT_TITLE="Plugin Manager" +COM_PLUGINS_XML_DESCRIPTION="This component manages Joomla plugins." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.com_postinstall.ini b/Sites/pages/administrator/language/en-GB/en-GB.com_postinstall.ini new file mode 100644 index 00000000..7dfd62ed --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.com_postinstall.ini @@ -0,0 +1,18 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +COM_POSTINSTALL="Post-installation Messages" +COM_POSTINSTALL_BTN_HIDE="Hide this message" +COM_POSTINSTALL_BTN_RESET="Reset Messages" +COM_POSTINSTALL_CONFIGURATION="Post-installation Messages: Options" +COM_POSTINSTALL_HIDE_ALL_MESSAGES="Hide all messages" +COM_POSTINSTALL_LBL_MESSAGES="Post-installation and Upgrade Messages" +COM_POSTINSTALL_LBL_NOMESSAGES_DESC="You have read all the messages." +COM_POSTINSTALL_LBL_NOMESSAGES_TITLE="No Messages" +COM_POSTINSTALL_LBL_RELEASENEWS="Release news from the Joomla! Project" +COM_POSTINSTALL_LBL_SINCEVERSION="Since version %s" +COM_POSTINSTALL_MESSAGES_FOR="Showing messages for" +COM_POSTINSTALL_MESSAGES_TITLE="Post-installation Messages for %s" +COM_POSTINSTALL_XML_DESCRIPTION="Displays post-installation and post-upgrade messages for Joomla and its extensions." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.com_postinstall.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.com_postinstall.sys.ini new file mode 100644 index 00000000..cc6691ed --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.com_postinstall.sys.ini @@ -0,0 +1,9 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +COM_POSTINSTALL="Post-installation Messages" +COM_POSTINSTALL_MESSAGES_VIEW_DEFAULT_DESC="Displays post-installation and post-upgrade messages for Joomla! and its extensions." +COM_POSTINSTALL_MESSAGES_VIEW_DEFAULT_TITLE="Post-Installation Messages" +COM_POSTINSTALL_XML_DESCRIPTION="Displays post-installation and post-upgrade messages for Joomla! and its extensions." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.com_privacy.ini b/Sites/pages/administrator/language/en-GB/en-GB.com_privacy.ini new file mode 100644 index 00000000..5036c298 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.com_privacy.ini @@ -0,0 +1,164 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +COM_PRIVACY="Privacy" +COM_PRIVACY_ACTION_DELETE_DATA="Delete Data" +COM_PRIVACY_ACTION_EMAIL_EXPORT_DATA="Email Data Export" +COM_PRIVACY_ACTION_EXPORT_DATA="Export Data" +COM_PRIVACY_ACTION_LOG_ADMIN_COMPLETED_REQUEST="User {username} completed request #{id} for {subjectemail}" +COM_PRIVACY_ACTION_LOG_ADMIN_CREATED_REQUEST="User {username} created request #{id} for {subjectemail}" +COM_PRIVACY_ACTION_LOG_ADMIN_INVALIDATED_REQUEST="User {username} invalidated request #{id} for {subjectemail}" +COM_PRIVACY_ACTION_LOG_CONFIRMED_REQUEST="{subjectemail} has confirmed request #{id}" +COM_PRIVACY_ACTION_LOG_CREATED_REQUEST="{subjectemail} has submitted request #{id}" +COM_PRIVACY_ACTION_LOG_EXPORT="User {username} exported the data for request #{id}" +COM_PRIVACY_ACTION_LOG_EXPORT_EMAILED="User {username} emailed the data export for request #{id} to the recipient" +COM_PRIVACY_ACTION_LOG_REMOVE="User {username} removed the data for request #{id}" +COM_PRIVACY_ACTION_LOG_REMOVE_BLOCKED="User {username} attempted to remove the data for request #{id} however this action was blocked" +COM_PRIVACY_ACTION_VIEW="View Request" +COM_PRIVACY_BADGE_URGENT_REQUEST="Urgent" +COM_PRIVACY_CONFIGURATION="Privacy: Options" +COM_PRIVACY_CONSENTS_FILTER_STATE="State of Consents" +COM_PRIVACY_CONSENTS_FILTER_SUBJECT="Subject" +COM_PRIVACY_CONSENTS_INVALIDATED_ALL="All consents of this subject have been invalidated." +COM_PRIVACY_CONSENTS_STATE_INVALIDATED="Invalidated Consent" +COM_PRIVACY_CONSENTS_STATE_OBSOLETE="Obsolete Consent" +COM_PRIVACY_CONSENTS_STATE_VALID="Valid Consent" +COM_PRIVACY_CONSENTS_SUBJECT_DEFAULT="All Subjects" +COM_PRIVACY_CONSENTS_TOOLBAR_INVALIDATE_ALL="Invalidate all Consents" +COM_PRIVACY_CONSENTS_TOOLBAR_INVALIDATE_ALL_CONFIRM_MSG="Do you really want to invalidate all consents of the selected subject? This will force users to have to give their consent again." +COM_PRIVACY_CONSENTS_TOOLBAR_INVALIDATE="Invalidate Consent" +COM_PRIVACY_CONSENTS_TOOLBAR_INVALIDATE_CONFIRM_MSG="Do you really want to invalidate the selected consents? This will force users to have to give their consent again." +COM_PRIVACY_CORE_CAPABILITY_COMMUNICATION_WITH_JOOMLA_ORG="When a network connection is available, a Joomla installation will attempt to communicate with the joomla.org servers for various capabilities, to include:
    • Checking for updates for the Joomla application
    • Help screens for core Joomla extensions
    • The Install from Web service (opt-in)
    • The statistics collection server (opt-in)
    As with all HTTP requests, the IP address of your server will be transmitted as part of the request. For information on how Joomla processes data on its servers, please review our privacy policy." +; The placeholder for this key is the configured log path for the site. +COM_PRIVACY_CORE_CAPABILITY_LOGGING_IP_ADDRESS="Joomla's logging system records the IP address of the visitor which leads to a message being written to its log files. These log files are used to record various activity on a Joomla site, including information related to core updates, invalid login attempts, unhandled errors, and development information such as the use of deprecated APIs. The format of these log files may be customised by any extension which configures a logger, therefore you are encouraged to download and review the log files for your website which may be found at `%s`." +COM_PRIVACY_CORE_CAPABILITY_SESSION_IP_ADDRESS_AND_COOKIE="All requests to a Joomla website start a session which stores the IP address in the session data and creates a session cookie in the user's browser. The IP address is used as a security measure to help protect against potential session hijacking attacks and this information is deleted once the session has expired and its data purged. The session cookie's name is based on a randomly generated hash and therefore does not have a constant identifier. The session cookie is destroyed once the session has expired or the user has exited their browser." +COM_PRIVACY_DASHBOARD_BADGE_ACTIVE_REQUESTS_0="%d Active Requests" +COM_PRIVACY_DASHBOARD_BADGE_ACTIVE_REQUESTS_1="%d Active Request" +COM_PRIVACY_DASHBOARD_BADGE_ACTIVE_REQUESTS_MORE="%d Active Requests" +COM_PRIVACY_DASHBOARD_BADGE_TOTAL_REQUESTS_0="%d Total Requests" +COM_PRIVACY_DASHBOARD_BADGE_TOTAL_REQUESTS_1="%d Total Request" +COM_PRIVACY_DASHBOARD_BADGE_TOTAL_REQUESTS_MORE="%d Total Requests" +COM_PRIVACY_DASHBOARD_HEADING_CHECK="Check" +COM_PRIVACY_DASHBOARD_HEADING_REQUEST_COUNT="# of Requests" +COM_PRIVACY_DASHBOARD_HEADING_REQUEST_STATUS="Status" +COM_PRIVACY_DASHBOARD_HEADING_REQUEST_TYPE="Request Type" +COM_PRIVACY_DASHBOARD_HEADING_STATUS="Status" +COM_PRIVACY_DASHBOARD_HEADING_STATUS_CHECK="Status Check" +COM_PRIVACY_DASHBOARD_HEADING_TOTAL_REQUEST_COUNT="Total Request Count" +COM_PRIVACY_DASHBOARD_NO_REQUESTS="There are no requests." +COM_PRIVACY_DASHBOARD_VIEW_REQUESTS="View Requests" +COM_PRIVACY_DATA_REMOVED="Data removed" +COM_PRIVACY_EDIT_PRIVACY_CONSENT_PLUGIN="Edit Privacy Consents Plugin" +COM_PRIVACY_EDIT_PRIVACY_POLICY="Edit Privacy Policy" +COM_PRIVACY_EXTENSION_CAPABILITY_PERSONAL_INFO="In order to process information requests, information about the user must be collected and logged for the purposes of retaining an audit log. The request system is based on an individual's email address which will be used to link the request to an existing site user if able." +; You can use the following merge codes for all COM_PRIVACY_EMAIL strings: +; [SITENAME] Site name, as set in Global Configuration. +; [URL] URL of the site's frontend page. +; [TOKENURL] URL of the confirm page with the token prefilled. +; [FORMURL] URL of the confirm page where the user can paste their token. +; [TOKEN] The confirmation token. +; \n Newline character. Use it to start a new line in the email. +COM_PRIVACY_EMAIL_ADMIN_REQUEST_BODY_EXPORT_REQUEST="An administrator for [URL] has created a request to export personal information related to this email address. As a security measure, you must confirm that this is a valid request for your personal information from this website.\n\nIf this was a mistake, just ignore this email and nothing will happen.\n\nIn order to confirm this request, you can complete one of the following tasks:\n\n1. Visit the following URL: [TOKENURL]\n\n2. Copy your token from this email, visit the referenced URL, and paste your token into the form.\nURL: [FORMURL]\nToken: [TOKEN]\n\nPlease note that this token is only valid for 24 hours from the time this email was sent." +COM_PRIVACY_EMAIL_ADMIN_REQUEST_BODY_REMOVE_REQUEST="An administrator for [URL] has created a request to remove all personal information related to this email address. As a security measure, you must confirm that this is a valid request for your personal information to be removed from this website.\n\nIf this was a mistake, just ignore this email and nothing will happen.\n\nIn order to confirm this request, you can complete one of the following tasks:\n\n1. Visit the following URL: [TOKENURL]\n\n2. Copy your token from this email, visit the referenced URL, and paste your token into the form.\nURL: [FORMURL]\nToken: [TOKEN]\n\nPlease note that this token is only valid for 24 hours from the time this email was sent." +COM_PRIVACY_EMAIL_ADMIN_REQUEST_SUBJECT_EXPORT_REQUEST="Information Request Created at [SITENAME]" +COM_PRIVACY_EMAIL_ADMIN_REQUEST_SUBJECT_REMOVE_REQUEST="Information Deletion Request Created at [SITENAME]" +COM_PRIVACY_EMAIL_DATA_EXPORT_COMPLETED_BODY="An administrator for [URL] has completed the data export you requested and a copy of the information can be found in the file attached to this message." +COM_PRIVACY_EMAIL_DATA_EXPORT_COMPLETED_SUBJECT="Data Export for [SITENAME]" +COM_PRIVACY_ERROR_ACTIVE_REQUEST_FOR_EMAIL="There is already an active information request for this email address, the active request should be completed before starting a new one." +COM_PRIVACY_ERROR_CANNOT_CREATE_REQUEST_FOR_SELF="You can't create an information request for yourself." +COM_PRIVACY_ERROR_CANNOT_CREATE_REQUEST_WHEN_SENDMAIL_DISABLED="Information requests can't be created when sending mail is disabled." +COM_PRIVACY_ERROR_CANNOT_EXPORT_UNCONFIRMED_REQUEST="The data for an unconfirmed request can't be exported." +COM_PRIVACY_ERROR_CANNOT_REMOVE_DATA="The data for this request can't be removed." +COM_PRIVACY_ERROR_CANNOT_REMOVE_UNCONFIRMED_REQUEST="The data for an unconfirmed request can't be removed." +COM_PRIVACY_ERROR_COMPLETE_TRANSITION_NOT_PERMITTED="This record can't be updated to \"Completed\" status." +COM_PRIVACY_ERROR_EXPORT_EMAIL_FAILED="Export failed with the following error: %s" +COM_PRIVACY_ERROR_INVALID_TRANSITION_NOT_PERMITTED="This record can't be updated to \"Invalid\" status." +COM_PRIVACY_ERROR_REMOVE_DATA_FAILED="Removal failed with the following error: %s" +COM_PRIVACY_ERROR_REQUEST_ID_REQUIRED_FOR_EXPORT="A request ID is required to export data." +COM_PRIVACY_ERROR_REQUEST_ID_REQUIRED_FOR_REMOVE="A request ID is required to remove data." +COM_PRIVACY_ERROR_REQUEST_TYPE_NOT_EXPORT="Only export requests may be exported." +COM_PRIVACY_ERROR_REQUEST_TYPE_NOT_REMOVE="Only removal requests may have their data removed." +COM_PRIVACY_ERROR_UNKNOWN_REQUEST_TYPE="Unknown information request type." +COM_PRIVACY_EXPORT_EMAILED="The data export has been emailed." +COM_PRIVACY_FIELD_REQUESTED_AT_LABEL="Date Requested" +COM_PRIVACY_FIELD_REQUEST_TYPE_DESC="The type of information request." +COM_PRIVACY_FIELD_REQUEST_TYPE_LABEL="Request Type" +COM_PRIVACY_FIELD_STATUS_DESC="The status of the information request." +COM_PRIVACY_FILTER_SEARCH_LABEL="Search Requests" +COM_PRIVACY_HEADING_ACTION_LOG="Action Log" +COM_PRIVACY_HEADING_ACTIONS="Actions" +COM_PRIVACY_HEADING_CONSENTS_BODY="Body" +COM_PRIVACY_HEADING_CONSENTS_CREATED="Created" +COM_PRIVACY_HEADING_CONSENTS_SUBJECT="Subject" +COM_PRIVACY_HEADING_CORE_CAPABILITIES="Joomla Core Capabilities" +COM_PRIVACY_HEADING_CREATED_ASC="Created ascending" +COM_PRIVACY_HEADING_CREATED_DESC="Created descending" +COM_PRIVACY_HEADING_EMAIL_ASC="Email ascending" +COM_PRIVACY_HEADING_EMAIL_DESC="Email descending" +COM_PRIVACY_HEADING_REQUEST_INFORMATION="Request Information" +COM_PRIVACY_HEADING_REQUEST_TYPE="Request Type" +COM_PRIVACY_HEADING_REQUEST_TYPE_ASC="Request Type ascending" +COM_PRIVACY_HEADING_REQUEST_TYPE_DESC="Request Type descending" +COM_PRIVACY_HEADING_REQUEST_TYPE_TYPE_EXPORT="Export" +COM_PRIVACY_HEADING_REQUEST_TYPE_TYPE_REMOVE="Remove" +COM_PRIVACY_HEADING_REQUESTED_AT="Requested" +COM_PRIVACY_HEADING_REQUESTED_AT_ASC="Requested ascending" +COM_PRIVACY_HEADING_REQUESTED_AT_DESC="Requested descending" +COM_PRIVACY_HEADING_STATUS_ASC="Status ascending" +COM_PRIVACY_HEADING_STATUS_DESC="Status descending" +COM_PRIVACY_HEADING_SUBJECT_ASC="Subject ascending" +COM_PRIVACY_HEADING_SUBJECT_DESC="Subject descending" +COM_PRIVACY_HEADING_USERID="User ID" +COM_PRIVACY_HEADING_USERID_ASC="User ID ascending" +COM_PRIVACY_HEADING_USERID_DESC="User ID descending" +COM_PRIVACY_HEADING_USERNAME_ASC="Username ascending" +COM_PRIVACY_HEADING_USERNAME_DESC="Username descending" +COM_PRIVACY_MSG_CAPABILITIES_ABOUT_THIS_INFORMATION="About This Information" +COM_PRIVACY_MSG_CAPABILITIES_INTRODUCTION="The information on this screen is collected from extensions which report their privacy related capabilities to this system. It is intended to help site owners be aware of the capabilities of installed extensions and provide information to help owners create local site policies such as a privacy policy. As this screen requires extensions to support its reporting system, and only displays information from enabled extensions, this should not be considered a complete list and you are encouraged to consult each extension's documentation for more information." +COM_PRIVACY_MSG_CAPABILITIES_NO_CAPABILITIES="There are no reported extension capabilities." +COM_PRIVACY_MSG_CONFIRM_EMAIL_SENT_TO_USER="A confirmation email for this request has been sent to the user." +COM_PRIVACY_MSG_CONSENTS_NO_CONSENTS="There are no stored consents." +COM_PRIVACY_MSG_EXTENSION_NO_CAPABILITIES="This extension does not report any capabilities." +COM_PRIVACY_MSG_REQUESTS_NO_REQUESTS="There are no information requests matching your query." +COM_PRIVACY_N_CONSENTS_INVALIDATED="%s consents were invalidated." +COM_PRIVACY_N_CONSENTS_INVALIDATED_1="%s consent was invalidated." +COM_PRIVACY_NOTIFY_DESC="Show a notification when there are requests older than the specified number of days." +COM_PRIVACY_NOTIFY_LABEL="Days To Consider Request Urgent" +COM_PRIVACY_OPTION_LABEL="Options" +COM_PRIVACY_POSTINSTALL_TITLE="Increased Management Of Users Privacy" +COM_PRIVACY_POSTINSTALL_BODY="

    With the introduction of GDPR for EU citizens and similar regulations elsewhere in the world it may be necessary for you to request consent before storing any Personal Information of a user.

    Joomla 3.9 introduces new capabilities to assist you in creating site privacy policies and collecting user consent. In addition a workflow is available to help you manage user information requests such as requests for removing their personal data from your site.

    For further information on this new feature read the Privacy documentation.

    " +COM_PRIVACY_REQUEST_COMPLETED="The request has been completed." +COM_PRIVACY_REQUEST_INVALIDATED="The request has been invalidated." +COM_PRIVACY_SELECT_REQUEST_TYPE="- Select Request Type -" +COM_PRIVACY_SHOW_URGENT_REQUESTS="Show Urgent Requests" +COM_PRIVACY_STATUS_CHECK_NOT_AVAILABLE="Not Available" +COM_PRIVACY_STATUS_CHECK_OUTSTANDING_URGENT_REQUESTS="Outstanding Urgent Requests" +COM_PRIVACY_STATUS_CHECK_OUTSTANDING_URGENT_REQUESTS_DESCRIPTION="Requests which are older than %d days, as set in the component configuration." +COM_PRIVACY_STATUS_CHECK_PRIVACY_POLICY_PUBLISHED="Published Privacy Policy" +COM_PRIVACY_STATUS_CHECK_REQUEST_FORM_MENU_ITEM_PUBLISHED="Published Request Form Menu Item" +COM_PRIVACY_STATUS_CHECK_SENDMAIL_DISABLED="Mail Sending Disabled" +COM_PRIVACY_STATUS_CHECK_SENDMAIL_DISABLED_DESCRIPTION="Mail Sending must be enabled, it is a requirement to use the request system" +COM_PRIVACY_STATUS_CHECK_SENDMAIL_ENABLED="Mail Sending Enabled" +COM_PRIVACY_STATUS_COMPLETED="Completed" +COM_PRIVACY_STATUS_CONFIRMED="Confirmed" +COM_PRIVACY_STATUS_INVALID="Invalid" +COM_PRIVACY_STATUS_PENDING="Pending" +COM_PRIVACY_SEARCH_IN_EMAIL="Search in requestor email address. Prefix with ID: to search for a request ID." +COM_PRIVACY_SEARCH_IN_USERNAME="Search in username. Prefix with ID: to search for a consent ID. Prefix with UID: to search for a User ID." +COM_PRIVACY_SUBMENU_CAPABILITIES="Capabilities" +COM_PRIVACY_SUBMENU_CONSENTS="Consents" +COM_PRIVACY_SUBMENU_DASHBOARD="Dashboard" +COM_PRIVACY_SUBMENU_REQUESTS="Requests" +COM_PRIVACY_TOOLBAR_COMPLETE="Complete" +COM_PRIVACY_TOOLBAR_INVALIDATE="Invalidate" +COM_PRIVACY_USER_FIELD_EMAIL_DESC="The email address of the individual owning the information being requested." +COM_PRIVACY_VIEW_CAPABILITIES="Privacy: Extension Capabilities" +COM_PRIVACY_VIEW_CONSENTS="Privacy: Consents" +COM_PRIVACY_VIEW_DASHBOARD="Privacy: Dashboard" +COM_PRIVACY_VIEW_REQUEST_ADD_REQUEST="Privacy: New Information Request" +COM_PRIVACY_VIEW_REQUEST_SHOW_REQUEST="Privacy: Review Information Request" +COM_PRIVACY_VIEW_REQUESTS="Privacy: Information Requests" +COM_PRIVACY_WARNING_CANNOT_CREATE_REQUEST_WHEN_SENDMAIL_DISABLED="Information requests can't be created when sending mail is disabled." +COM_PRIVACY_XML_DESCRIPTION="Component for managing privacy related actions." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.com_privacy.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.com_privacy.sys.ini new file mode 100644 index 00000000..37b58176 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.com_privacy.sys.ini @@ -0,0 +1,21 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +COM_PRIVACY="Privacy" +COM_PRIVACY_CONFIRM_VIEW_DEFAULT_DESC="Displays a form to confirm an information request." +COM_PRIVACY_CONFIRM_VIEW_DEFAULT_OPTION="Default" +COM_PRIVACY_CONFIRM_VIEW_DEFAULT_TITLE="Confirm Request" +COM_PRIVACY_CONSENTS_VIEW_DEFAULT_DESC="Shows a list of user consents" +COM_PRIVACY_CONSENTS_VIEW_DEFAULT_TITLE="Privacy: Consents" +COM_PRIVACY_DASHBOARD_VIEW_DEFAULT_DESC="A dashboard related to the site's privacy settings and information requests." +COM_PRIVACY_DASHBOARD_VIEW_DEFAULT_TITLE="Privacy: Dashboard" +COM_PRIVACY_REMIND_VIEW_DEFAULT_DESC="Displays a form to extend the privacy consent" +COM_PRIVACY_REMIND_VIEW_DEFAULT_TITLE="Extend Consent" +COM_PRIVACY_REQUEST_VIEW_DEFAULT_DESC="Displays a form to submit an information request." +COM_PRIVACY_REQUEST_VIEW_DEFAULT_OPTION="Default" +COM_PRIVACY_REQUEST_VIEW_DEFAULT_TITLE="Create Request" +COM_PRIVACY_REQUESTS_VIEW_DEFAULT_DESC="Shows a list of user information requests" +COM_PRIVACY_REQUESTS_VIEW_DEFAULT_TITLE="Privacy: Information Requests" +COM_PRIVACY_XML_DESCRIPTION="Component for managing privacy related actions." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.com_redirect.ini b/Sites/pages/administrator/language/en-GB/en-GB.com_redirect.ini new file mode 100644 index 00000000..10741064 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.com_redirect.ini @@ -0,0 +1,100 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +COM_REDIRECT="Redirects" +COM_REDIRECT_ADVANCED_OPTIONS="Advanced" +COM_REDIRECT_BATCH_OPTIONS="Bulk process to add new URLs" +COM_REDIRECT_BATCH_TIP="Enter expired URL (mandatory) with a new URL (optional) separated with %1$s (eg old-url%1$snew-url). Each line one entry!" +COM_REDIRECT_BULK_SEPARATOR_DESC="The separator used for bulk import, by default it is '|' but it can be ',' for a copy / paste from a CSV file for instance." +COM_REDIRECT_BULK_SEPARATOR_LABEL="Bulk Import Separator" +COM_REDIRECT_BUTTON_UPDATE_LINKS="Update Links" +COM_REDIRECT_CLEAR_FAIL="Failed to delete disabled links." +COM_REDIRECT_CLEAR_SUCCESS="All disabled links have been deleted." +COM_REDIRECT_COLLECT_MODAL_URLS_DISABLED="%1$s The 'Collect URLs' option in the %2$s is disabled. Error page URLs will not be collected by this component." +COM_REDIRECT_COLLECT_URLS_ENABLED="%1$s The option 'Collect URLs' is enabled." +; The following string is deprecated and will be removed with 4.0. +COM_REDIRECT_COLLECT_URLS_DISABLED="The 'Collect URLs' option in the Redirect System Plugin is disabled. Error page URLs will not be collected by this component." +COM_REDIRECT_CONFIGURATION="Redirect: Options" +COM_REDIRECT_DEFAULT_IMPORT_STATE_DESC="When batch importing redirects, enable or disable by default." +COM_REDIRECT_DEFAULT_IMPORT_STATE_LABEL="Import State" +COM_REDIRECT_DISABLE_LINK="Disable Link" +COM_REDIRECT_EDIT_LINK="Edit Link #%d" +COM_REDIRECT_EDIT_PLUGIN_SETTINGS="Edit Plugin Settings" +COM_REDIRECT_ENABLE_LINK="Enable Link" +COM_REDIRECT_ERROR_DESTINATION_URL_REQUIRED="The redirect must have a destination URL" +COM_REDIRECT_ERROR_DUPLICATE_OLD_URL="The source URL must be unique." +COM_REDIRECT_ERROR_DUPLICATE_URLS="The source and destination URLs can't be the same." +COM_REDIRECT_ERROR_SOURCE_URL_REQUIRED="The redirect must have a source URL." +COM_REDIRECT_FILTER_SEARCH_DESC="Search in expired URL, new URL, referring page and comment. Prefix with ID: to search for a link ID." +COM_REDIRECT_FILTER_SEARCH_LABEL="Search Links" +COM_REDIRECT_FILTER_FILTER_HTTP_HEADER_LABEL="HTTP Status Code" +COM_REDIRECT_FILTER_FILTER_HTTP_HEADER_DESC="Filter by the redirect HTTP Status Code." +COM_REDIRECT_FILTER_SELECT_OPTION_HTTP_HEADER="- Select HTTP Status Code -" +COM_REDIRECT_FIELD_COMMENT_DESC="Sometimes it is helpful to describe the URLs for redirect management later on." +COM_REDIRECT_FIELD_COMMENT_LABEL="Comment" +COM_REDIRECT_FIELD_CREATED_DATE_LABEL="Created Date" +COM_REDIRECT_FIELD_NEW_URL_DESC="Enter the URL to be redirected to." +COM_REDIRECT_BATCH_UPDATE_WITH_NEW_URL="Batch update new URL(s)" +COM_REDIRECT_FIELD_NEW_URL_LABEL="New URL" +COM_REDIRECT_FIELD_OLD_URL_DESC="Enter the URL that has to be redirected." +COM_REDIRECT_FIELD_OLD_URL_LABEL="Expired URL" +COM_REDIRECT_FIELD_REFERRER_LABEL="Link Referrer" +COM_REDIRECT_FIELD_REDIRECT_STATUS_CODE_LABEL="Redirect Status Code" +COM_REDIRECT_FIELD_REDIRECT_STATUS_CODE_DESC="Choose the HTTP 1.1 status code to associate with the redirect." +COM_REDIRECT_FIELD_UPDATED_DATE_LABEL="Last Updated Date" +COM_REDIRECT_HEADING_CREATED_DATE="Created Date" +COM_REDIRECT_HEADING_CREATED_DATE_ASC="Created Date ascending" +COM_REDIRECT_HEADING_CREATED_DATE_DESC="Created Date descending" +COM_REDIRECT_HEADING_HITS="404 Hits" +COM_REDIRECT_HEADING_HITS_ASC="404 Hits ascending" +COM_REDIRECT_HEADING_HITS_DESC="404 Hits descending" +COM_REDIRECT_HEADING_NEW_URL="New URL" +COM_REDIRECT_HEADING_NEW_URL_ASC="New URL ascending" +COM_REDIRECT_HEADING_NEW_URL_DESC="New URL descending" +COM_REDIRECT_HEADING_OLD_URL="Expired URL" +COM_REDIRECT_HEADING_OLD_URL_ASC="Expired URL ascending" +COM_REDIRECT_HEADING_OLD_URL_DESC="Expired URL descending" +COM_REDIRECT_HEADING_REFERRER="Referring Page" +COM_REDIRECT_HEADING_REFERRER_ASC="Referring Page ascending" +COM_REDIRECT_HEADING_REFERRER_DESC="Referring Page descending" +COM_REDIRECT_HEADING_STATUS_CODE="Status Code" +COM_REDIRECT_HEADING_STATUS_CODE_ASC="Status Code ascending" +COM_REDIRECT_HEADING_STATUS_CODE_DESC="Status Code descending" +COM_REDIRECT_HEADING_UPDATE_LINKS="Update selected links to the following new URL." +COM_REDIRECT_MANAGER_LINK="Redirects: New/Edit" +COM_REDIRECT_MANAGER_LINK_EDIT="Redirects: Edit" +COM_REDIRECT_MANAGER_LINK_NEW="Redirects: New" +COM_REDIRECT_MANAGER_LINKS="Redirects: Links" +COM_REDIRECT_MODE_LABEL="Activate Advanced Mode" +COM_REDIRECT_MODE_DESC="Enable more advanced functionality for the component. Only use this if you know what you're doing." +COM_REDIRECT_N_ITEMS_ARCHIVED="%d links archived." +COM_REDIRECT_N_ITEMS_ARCHIVED_1="Link archived." +COM_REDIRECT_N_ITEMS_DELETED="%d links deleted." +COM_REDIRECT_N_ITEMS_DELETED_1="Link deleted." +COM_REDIRECT_N_ITEMS_PUBLISHED="%d links enabled." +COM_REDIRECT_N_ITEMS_PUBLISHED_1="Link enabled." +COM_REDIRECT_N_ITEMS_TRASHED="%d links trashed." +COM_REDIRECT_N_ITEMS_TRASHED_1="Link trashed." +COM_REDIRECT_N_ITEMS_UNPUBLISHED="%d links disabled." +COM_REDIRECT_N_ITEMS_UNPUBLISHED_1="Link disabled." +COM_REDIRECT_N_LINKS_ADDED="%d links added." +COM_REDIRECT_N_LINKS_ADDED_1="1 link has been added." +COM_REDIRECT_N_LINKS_UPDATED="%d links updated." +COM_REDIRECT_N_LINKS_UPDATED_1="1 link has been updated." +COM_REDIRECT_NEW_LINK="New Link" +COM_REDIRECT_NO_ITEM_ADDED="No links added." +COM_REDIRECT_NO_ITEM_SELECTED="No links selected." +COM_REDIRECT_NO_SEPARATOR_FOUND="The separator %s was not found in your import." +; The following string is deprecated and will be removed with 4.0. +COM_REDIRECT_PLUGIN_DISABLED="The Redirect System Plugin is disabled. It needs to be enabled for this component to work." +COM_REDIRECT_PLUGIN_ENABLED="The Redirect Plugin is enabled." +COM_REDIRECT_PLUGIN_MODAL_DISABLED="The %s is disabled. It needs to be enabled for this component to work." +COM_REDIRECT_REDIRECTED_ON="Redirected on: %s." +COM_REDIRECT_SAVE_SUCCESS="Link saved." +COM_REDIRECT_SEARCH_LINKS="Search in link fields." +COM_REDIRECT_SYSTEM_PLUGIN="Redirect System Plugin" +COM_REDIRECT_TOOLBAR_PURGE="Purge Disabled" +COM_REDIRECT_XML_DESCRIPTION="This component implements link redirection." +JLIB_RULES_SETTING_NOTES="Changes apply to this component only.
    Inherited - a Global Configuration setting or higher level setting is applied.
    Denied always wins - whatever is set at the Global or higher level and applies to all child elements.
    Allowed will enable the action for this component unless overruled by a Global Configuration setting." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.com_redirect.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.com_redirect.sys.ini new file mode 100644 index 00000000..0021245d --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.com_redirect.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +COM_REDIRECT="Redirects" +COM_REDIRECT_XML_DESCRIPTION="This component implements link redirection." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.com_search.ini b/Sites/pages/administrator/language/en-GB/en-GB.com_search.ini new file mode 100644 index 00000000..ee49e4dd --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.com_search.ini @@ -0,0 +1,47 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +COM_SEARCH="Search" +COM_SEARCH_ALL_WORDS="All Words" +COM_SEARCH_ALPHABETICAL="Alphabetical" +COM_SEARCH_ANY_WORDS="Any Words" +COM_SEARCH_CONFIG_FIELD_CREATED_DATE_DESC="Show created date." +COM_SEARCH_CONFIG_FIELD_CREATED_DATE_LABEL="Created Date" +COM_SEARCH_CONFIG_GATHER_SEARCH_STATISTICS_DESC="Record the search phrases submitted by visitors." +COM_SEARCH_CONFIG_GATHER_SEARCH_STATISTICS_LABEL="Gather Search Statistics" +COM_SEARCH_CONFIG_FIELD_OPENSEARCH_NAME_LABEL="OpenSearch Name" +COM_SEARCH_CONFIG_FIELD_OPENSEARCH_NAME_DESC="Name displayed for this site as a search provider." +COM_SEARCH_CONFIG_FIELD_OPENSEARCH_DESCRIPTON_LABEL="OpenSearch Description" +COM_SEARCH_CONFIG_FIELD_OPENSEARCH_DESCRIPTON_DESC="Description displayed for this site as a search provider." +COM_SEARCH_CONFIGURATION="Search: Options" +COM_SEARCH_EXACT_PHRASE="Exact phrase" +COM_SEARCH_FIELD_DESC="Word, words or phrase to search for." +COM_SEARCH_FIELD_LABEL="Search Term (Optional)" +COM_SEARCH_FIELD_SEARCH_PHRASES_DESC="Show the search options." +COM_SEARCH_FIELD_SEARCH_PHRASES_LABEL="Use Search Options" +COM_SEARCH_FIELD_SEARCH_AREAS_DESC="Show the search areas checkboxes." +COM_SEARCH_FIELD_SEARCH_AREAS_LABEL="Use Search Areas" +COM_SEARCH_FIELDSET_OPTIONAL_LABEL="Optional Search Term" +COM_SEARCH_FIELDSET_SEARCH_OPTIONS_LABEL="Search" +COM_SEARCH_FOR_DESC="The type of search." +COM_SEARCH_FOR_LABEL="Search For" +COM_SEARCH_HEADING_PHRASE="Search Phrase" +COM_SEARCH_HEADING_SEARCH_TERM_ASC="Search Phrase ascending" +COM_SEARCH_HEADING_SEARCH_TERM_DESC="Search Phrase descending" +COM_SEARCH_HEADING_RESULTS="Results" +COM_SEARCH_HIDE_SEARCH_RESULTS="Hide Search Results" +COM_SEARCH_LOGGING_DISABLED="Gathering statistics disabled. Enable it in the Options." +COM_SEARCH_LOGGING_ENABLED="Gathering statistics enabled" +COM_SEARCH_MANAGER_SEARCHES="Search Term Analysis" +COM_SEARCH_MOST_POPULAR="Popularity" +COM_SEARCH_NEWEST_FIRST="Newest First" +COM_SEARCH_NO_RESULTS="Off" +COM_SEARCH_OLDEST_FIRST="Oldest First" +COM_SEARCH_ORDERING_DESC="Defines what ordering results are listed in." +COM_SEARCH_ORDERING_LABEL="Results Ordering" +COM_SEARCH_SAVED_SEARCH_OPTIONS="Default Search Options" +COM_SEARCH_SEARCH_IN_PHRASE="Search in phrases." +COM_SEARCH_SHOW_SEARCH_RESULTS="Show Search Results" +COM_SEARCH_XML_DESCRIPTION="Component for search functions." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.com_search.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.com_search.sys.ini new file mode 100644 index 00000000..fdd12e2e --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.com_search.sys.ini @@ -0,0 +1,10 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +COM_SEARCH="Search" +COM_SEARCH_SEARCH_VIEW_DEFAULT_DESC="Display search results." +COM_SEARCH_SEARCH_VIEW_DEFAULT_OPTION="Default" +COM_SEARCH_SEARCH_VIEW_DEFAULT_TITLE="Search Form or Search Results" +COM_SEARCH_XML_DESCRIPTION="Component for search functions." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.com_tags.ini b/Sites/pages/administrator/language/en-GB/en-GB.com_tags.ini new file mode 100644 index 00000000..83558b71 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.com_tags.ini @@ -0,0 +1,189 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +COM_TAGS="Tags" +COM_TAGS_ALL="All" +COM_TAGS_ALL_TAGS_DESCRIPTION_DESC="Description to display at the heading of tags list." +COM_TAGS_ALL_TAGS_DESCRIPTION_LABEL="Heading Description" +COM_TAGS_ALL_TAGS_MEDIA_DESC="Select or upload the image to display in the heading of the tags list." +COM_TAGS_ALL_TAGS_MEDIA_LABEL="Heading Image File" +COM_TAGS_ANY="Any" +COM_TAGS_BASE_ADD_TITLE="Tags: New" +COM_TAGS_BASE_EDIT_TITLE="Tags: Edit" +COM_TAGS_BASIC_FIELDSET_LABEL="Options" +COM_TAGS_BATCH_CANNOT_CREATE="You are not allowed to create new tags." +COM_TAGS_BATCH_CANNOT_EDIT="You are not allowed to edit tags." +COM_TAGS_BATCH_OPTIONS="Batch process the selected tags" +COM_TAGS_BATCH_TIP="Actions will apply to chosen Tags." +COM_TAGS_COMPACT_COLUMNS_LABEL="Number of Columns" +COM_TAGS_CONFIG_TAG_MIN_LENGTH_LABEL="Minimum Search Length" +COM_TAGS_CONFIG_TAG_MIN_LENGTH_DESC="This setting controls the minimum character length for the search and adding tags using the tags field Ajax mode." +COM_TAGS_CONFIG_ALL_TAGS_FIELD_LAYOUT_DESC="Choose a default layout for List of all tags." +COM_TAGS_CONFIG_ALL_TAGS_FIELD_LAYOUT_LABEL="Default List All Tags Layout" +COM_TAGS_CONFIG_ALL_TAGS_SETTINGS_DESC="These settings apply for a List of all Tags unless they are changed for a specific menu item." +COM_TAGS_CONFIG_ALL_TAGS_SETTINGS_LABEL="List All Tags" +COM_TAGS_CONFIG_DATA_ENTRY_SETTINGS_DESC="These settings control the way tags are entered." +COM_TAGS_CONFIG_DATA_ENTRY_SETTINGS_LABEL="Data Entry" +COM_TAGS_CONFIG_INTEGRATION_SETTINGS_DESC="These settings determine how the Tags Component will integrate with other extensions." +COM_TAGS_CONFIG_NUMBER_OF_ITEMS="Number of Items Tagged" +COM_TAGS_CONFIG_SELECTION_SETTINGS_DESC="These settings control which items get selected in the Tagged Items list layouts." +COM_TAGS_CONFIG_SELECTION_SETTINGS_LABEL="Item Selection" +COM_TAGS_CONFIG_SHARED_SETTINGS_DESC="These settings apply to all tag layouts unless they are changed for a specific menu item." +COM_TAGS_CONFIG_SHARED_SETTINGS_LABEL="Shared Layout" +COM_TAGS_CONFIG_TAG_SETTINGS_DESC="These settings apply for a Tagged Items List or Compact List of Tagged Items unless they are changed for a specific menu item." +COM_TAGS_CONFIG_TAG_SETTINGS_LABEL="Tagged Items" +COM_TAGS_CONFIG_TAGGED_ITEMS_FIELD_LAYOUT_DESC="Choose a default layout for tagged items. This layout will be used when a user selects a tag that doesn't have a menu item defined." +COM_TAGS_CONFIG_TAGGED_ITEMS_FIELD_LAYOUT_LABEL="Default Tagged Items Layout" +COM_TAGS_CONFIGURATION="Tags: Options" +COM_TAGS_COUNT_ARCHIVED_ITEMS="Archived items" +COM_TAGS_COUNT_PUBLISHED_ITEMS="Published items" +COM_TAGS_COUNT_TRASHED_ITEMS="Trashed items" +COM_TAGS_COUNT_UNPUBLISHED_ITEMS="Unpublished items" +COM_TAGS_DELETE_NOT_ALLOWED="Delete not allowed for tag %s." +COM_TAGS_DESCRIPTION_DESC="Enter an optional tag description in the text area." +COM_TAGS_ERROR_UNIQUE_ALIAS="Another Tag has the same alias (remember it may be a trashed item)." +COM_TAGS_EXCLUDE="Exclude" +COM_TAGS_FIELD_CONFIG_HITS_DESC="Displays the number of hits." +COM_TAGS_FIELD_CONFIG_TAGDESCRIPTION_DESC="Configure com_tags." +COM_TAGS_FIELD_CONFIG_TAGDESCRIPTION_LABEL="Tags" +COM_TAGS_FIELD_CONTENT_TYPE_DESC="Only tagged items of these types will be displayed." +COM_TAGS_FIELD_CONTENT_TYPE_LABEL="Content types" +COM_TAGS_FIELD_CREATED_DATE_DESC="The date and time that the tag was created." +COM_TAGS_FIELD_FULL_DESC="Select or upload an image that will be displayed in the single tag view." +COM_TAGS_FIELD_FULL_LABEL="Full Image" +COM_TAGS_FIELD_HITS_DESC="Number of hits for this tag." +COM_TAGS_FIELD_IMAGE_ALT_DESC="Alt text for the image." +COM_TAGS_FIELD_IMAGE_ALT_LABEL="Alt" +COM_TAGS_FIELD_IMAGE_CAPTION_DESC="Caption for the image." +COM_TAGS_FIELD_IMAGE_CAPTION_LABEL="Caption" +COM_TAGS_FIELD_IMAGE_DESC="Select or upload an image for this tag." +COM_TAGS_FIELD_IMAGE_LABEL="Image" +COM_TAGS_FIELD_INTRO_DESC="Select or upload an image that will be displayed as part of a list." +COM_TAGS_FIELD_INTRO_LABEL="Teaser Image" +COM_TAGS_FIELD_ITEM_BODY_DESC="Show the body for each item." +COM_TAGS_FIELD_LANGUAGE_DESC="Assign a language to this tag." +COM_TAGS_FIELD_LANGUAGE_FILTER_DESC="Optionally filter the list of tags based on language." +COM_TAGS_FIELD_LANGUAGE_FILTER_LABEL="Language Filter" +COM_TAGS_FIELD_MODIFIED_DESC="The date and time that the tag was last modified." +COM_TAGS_FIELD_NOTE_DESC="An optional note to display in the tag list." +COM_TAGS_FIELD_NOTE_LABEL="Note" +COM_TAGS_FIELD_NUMBER_ITEMS_LIST_DESC="Default number of tagged items to list on a page." +COM_TAGS_FIELD_NUMBER_ITEMS_LIST_LABEL="# Items to List" +COM_TAGS_FIELD_PARENT_DESC="Select a parent tag." +COM_TAGS_FIELD_PARENT_LABEL="Parent" +COM_TAGS_FIELD_PARENT_TAG_DESC="If set only tags that are direct children of the selected tag will be displayed." +COM_TAGS_FIELD_PARENT_TAG_LABEL="Parent Tag" +COM_TAGS_FIELD_SELECT_TAG_DESC="Select one or more tags." +COM_TAGS_FIELD_TAG_BODY_DESC="Show or hide the tag description." +COM_TAGS_FIELD_TAG_BODY_LABEL="Description." +COM_TAGS_FIELD_TAG_LABEL="Tag" +COM_TAGS_FIELD_TAG_LINK_CLASS="CSS Class for tag link" +COM_TAGS_FIELD_TAG_LINK_CLASS_DESC="Add specific CSS classes for the tag link. If left blank the default 'label label-info' is used." +COM_TAGS_FIELD_TYPE_DESC="Only tags of the selected types will be displayed (optional)." +COM_TAGS_FIELD_TYPE_LABEL="Content Type" +COM_TAGS_FIELDSET_DETAILS="Tag Details" +COM_TAGS_FIELDSET_OPTIONS="Options" +COM_TAGS_FIELDSET_PUBLISHING="Publishing" +COM_TAGS_FIELDSET_TAGGED_ITEMS="Tagged Items" +COM_TAGS_FIELDSET_URLS_AND_IMAGES="Links and Images" +COM_TAGS_FILTER_SEARCH_DESC="Search in tag title, alias and note. Prefix with ID: to search for a tag ID." +COM_TAGS_FILTER_SEARCH_LABEL="Search Tags" +COM_TAGS_FLOAT_DESC="Float attribute for the image." +COM_TAGS_FLOAT_LABEL="Float" +COM_TAGS_HAS_SUBCATEGORY_ITEMS="%d items are assigned to this tag's subtags." +COM_TAGS_HAS_SUBCATEGORY_ITEMS_1="%d item is assigned to one of this tag's subtags." +COM_TAGS_INCLUDE="Include" +COM_TAGS_INCLUDE_CHILDREN_DESC="Include or exclude child tags from the result list for a tag." +COM_TAGS_INCLUDE_CHILDREN_LABEL="Child Tags" +COM_TAGS_ITEM_OPTIONS="Item Options" +COM_TAGS_ITEMS_SEARCH_FILTER="Search" +COM_TAGS_LEFT="Left" +COM_TAGS_LIST_ALL_SELECTION_OPTIONS="Selection Options" +COM_TAGS_LIST_MAX_CHARACTERS_DESC="The maximum number of characters to display from the description in each tag." +COM_TAGS_LIST_MAX_CHARACTERS_LABEL="Maximum Characters" +COM_TAGS_LIST_MAX_DESC="The maximum number of results to return." +COM_TAGS_LIST_MAX_LABEL="Maximum Items" +COM_TAGS_LIST_SELECTION_OPTIONS="Item Selection Options" +COM_TAGS_MANAGER_TAGS="Tags" +COM_TAGS_MATCH_COUNT="Number of matching tags" +COM_TAGS_N_ITEMS_ARCHIVED="%d tags archived." +COM_TAGS_N_ITEMS_ARCHIVED_1="%d tag archived." +COM_TAGS_N_ITEMS_CHECKED_IN_0="No tag checked in." +COM_TAGS_N_ITEMS_CHECKED_IN_1="%d tag checked in." +COM_TAGS_N_ITEMS_CHECKED_IN_MORE="%d tags checked in." +COM_TAGS_N_ITEMS_DELETED="%d tags deleted." +COM_TAGS_N_ITEMS_DELETED_1="%d tag deleted." +COM_TAGS_N_ITEMS_FAILED_PUBLISHING="Failed publishing %d tags as at least one of their parents is unpublished or one of their children is checked out." +COM_TAGS_N_ITEMS_FAILED_PUBLISHING_1="Failed publishing %d tag as at least one of its parents is unpublished or one of its children is checked out." +COM_TAGS_N_ITEMS_PUBLISHED="%d tags published." +COM_TAGS_N_ITEMS_PUBLISHED_1="%d tag published." +COM_TAGS_N_ITEMS_TRASHED="%d tags trashed." +COM_TAGS_N_ITEMS_TRASHED_1="%d tag trashed." +COM_TAGS_N_ITEMS_UNPUBLISHED="%d tags unpublished." +COM_TAGS_N_ITEMS_UNPUBLISHED_1="%d tag unpublished." +COM_TAGS_NONE="None" +COM_TAGS_NUMBER_COLUMNS_DESC="Number of columns to arrange the tags in. Note that this may not be the number displayed if 12 does not divide evenly into it because display is based on a 12 column grid." +COM_TAGS_NUMBER_TAG_ITEMS_DESC="Shows the number of items with a given tag." +COM_TAGS_NUMBER_TAG_ITEMS_LABEL="Show Number of Items" +COM_TAGS_OPTIONS="Tag Options" +COM_TAGS_PAGINATION_OPTIONS="Pagination Options" +COM_TAGS_REBUILD_FAILURE="Failed rebuilding Tags tree data." +COM_TAGS_REBUILD_SUCCESS="Tags tree data rebuilt." +COM_TAGS_RIGHT="Right" +COM_TAGS_SAVE_SUCCESS="Tag saved." +COM_TAGS_SEARCH_TYPE_DESC="All will return items that have all of the tags. Any will return items that have at least one of the tags." +COM_TAGS_SEARCH_TYPE_LABEL="Match Type" +COM_TAGS_SELECT_TAGTYPE="- Select Tag Type -" +COM_TAGS_SHOW_ALL_TAGS_DESCRIPTION_DESC="Optional description to show at the top of the all tags list." +COM_TAGS_SHOW_ALL_TAGS_DESCRIPTION_LABEL="Heading Description" +COM_TAGS_SHOW_ALL_TAGS_IMAGE_DESC="Shows an image at the heading of the tags list." +COM_TAGS_SHOW_ALL_TAGS_IMAGE_LABEL="Show Heading Image" +COM_TAGS_SHOW_EMPTY_TAG_DESC="Show empty tags." +COM_TAGS_SHOW_ITEM_BODY_DESC="Show or hide the body text for the tagged items." +COM_TAGS_SHOW_ITEM_BODY_LABEL="Item Body" +COM_TAGS_SHOW_ITEM_DESCRIPTION_DESC="Show or hide the description for each tag listed." +COM_TAGS_SHOW_ITEM_DESCRIPTION_LABEL="Tag Descriptions" +COM_TAGS_SHOW_ITEM_IMAGE_DESC="Shows the first image for each item in the list." +COM_TAGS_SHOW_ITEM_IMAGE_LABEL="Item Images" +COM_TAGS_SHOW_TAG_BODY_DESC="For a layout with one tag, show the tag description." +COM_TAGS_SHOW_TAG_BODY_LABEL="Show Tag Description" +COM_TAGS_SHOW_TAG_DESCRIPTION_DESC="Show or hide the description for the tag (only used when a single tag is selected)." +COM_TAGS_SHOW_TAG_DESCRIPTION_LABEL="Tag Description" +COM_TAGS_SHOW_TAG_IMAGE_DESC="For a layout with one tag, show the image for the tag." +COM_TAGS_SHOW_TAG_IMAGE_LABEL="Tag Image" +COM_TAGS_SHOW_TAG_LIST_DESCRIPTION_LABEL="Description" +COM_TAGS_SHOW_TAG_TITLE_DESC="For a layout with one tag, show the tag name." +COM_TAGS_SHOW_TAG_TITLE_LABEL="Show Tag Name" +COM_TAGS_SUBSLIDER_DRILL_TAG_LIST_LABEL="Options for each item in the list." +COM_TAGS_TAG_FIELD_MODE_AJAX="AJAX" +COM_TAGS_TAG_FIELD_MODE_DESC="Ajax mode searches tags while typing and allows you on the fly tag creation. Nested tags show you a nested view with all the available tags." +COM_TAGS_TAG_FIELD_MODE_LABEL="Tag Entry Mode" +COM_TAGS_TAG_FIELD_MODE_NESTED="Nested" +COM_TAGS_TAG_LIST_DESCRIPTION_DESC="Optional description to show at the top of the list. For example, this can be used when you have a layout that includes more than one tag." +COM_TAGS_TAG_LIST_DESCRIPTION_LABEL="Layout Description" +COM_TAGS_TAG_LIST_FIELD_ITEM_DESCRIPTION_LABEL="Item Body" +COM_TAGS_TAG_LIST_ITEM_DESCRIPTION_DESC="Shows the body text for the individual items (depends on the source table)." +COM_TAGS_TAG_LIST_ITEM_HITS_DESC="Shows the number of hits for each individual item." +COM_TAGS_TAG_LIST_MEDIA_DESC="Select or upload the tag image (full image)." +COM_TAGS_TAG_LIST_MEDIA_LABEL="Image" +COM_TAGS_TAG_LIST_SHOW_DATE_DESC="Show Date" +COM_TAGS_TAG_LIST_SHOW_DATE_LABEL="Show or hide a date column in the compact list layout. Select Hide to hide the date, or select which date you wish to show." +COM_TAGS_TAG_LIST_SHOW_HEADINGS_DESC="Show or hide the headings in the compact list layout." +COM_TAGS_TAG_LIST_SHOW_HEADINGS_LABEL="Table Headings" +COM_TAGS_TAG_LIST_SHOW_ITEM_IMAGE_DESC="Shows the image for each item." +COM_TAGS_TAG_LIST_SHOW_ITEM_IMAGE_LABEL="Item Image" +COM_TAGS_TAG_LIST_SHOW_ITEM_DESCRIPTION_DESC="Show or hide the description for each item in the list. The length may be limited using the Maximum Characters option." +COM_TAGS_TAG_LIST_SHOW_ITEM_DESCRIPTION_LABEL="Item Description" +COM_TAGS_TAG_VIEW_LIST_DESC="Displays a compact list of items with the selected tags." +COM_TAGS_TAG_VIEW_LIST_OPTION="List view options" +COM_TAGS_TAG_VIEW_LIST_TITLE="Tagged items list" +COM_TAGS_TAGGED_ITEMS_ACCESS="Access" +COM_TAGS_TAGGED_ITEMS_AUTHOR="Author" +COM_TAGS_TAGGED_ITEMS_DATE="Date" +COM_TAGS_TAGGED_ITEMS_ID="ID" +COM_TAGS_TAGGED_ITEMS_LANGUAGE="Language" +COM_TAGS_TAGGED_ITEMS_TITLE="Title" +COM_TAGS_XML_DESCRIPTION="This component manages tags." +JGLOBAL_NO_ITEM_SELECTED="No tags selected" diff --git a/Sites/pages/administrator/language/en-GB/en-GB.com_tags.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.com_tags.sys.ini new file mode 100644 index 00000000..10e4f853 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.com_tags.sys.ini @@ -0,0 +1,36 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +COM_TAGS="Tags" +COM_TAGS_CONTENT_TYPE_ARTICLE="Article" +COM_TAGS_CONTENT_TYPE_ARTICLE_CATEGORY="Article Category" +COM_TAGS_CONTENT_TYPE_BANNER="Banner" +COM_TAGS_CONTENT_TYPE_BANNER_CLIENT="Banner Client" +COM_TAGS_CONTENT_TYPE_BANNERS_CATEGORY="Banner Category" +COM_TAGS_CONTENT_TYPE_CONTACT="Contact" +COM_TAGS_CONTENT_TYPE_CONTACT_CATEGORY="Contact Category" +COM_TAGS_CONTENT_TYPE_NEWSFEED="News Feed" +COM_TAGS_CONTENT_TYPE_NEWSFEEDS_CATEGORY="News Feed Category" +COM_TAGS_CONTENT_TYPE_TAG="Tag" +COM_TAGS_CONTENT_TYPE_USER="User" +COM_TAGS_CONTENT_TYPE_USER_NOTES="User Notes" +COM_TAGS_CONTENT_TYPE_USER_NOTES_CATEGORY="User Notes Category" +COM_TAGS_CONTENT_TYPE_WEBLINK="Web Link" +COM_TAGS_CONTENT_TYPE_WEBLINKS_CATEGORY="Web Links Category" +COM_TAGS_TAG="Tag" +COM_TAGS_TAG_VIEW_DEFAULT_DESC="This links to a list of items with specific tags." +COM_TAGS_TAG_VIEW_DEFAULT_OPTION="Default" +COM_TAGS_TAG_VIEW_DEFAULT_TITLE="Tagged Items" +COM_TAGS_TAG_VIEW_LIST_COMPACT_OPTION="Compact layout" +COM_TAGS_TAG_VIEW_LIST_COMPACT_TITLE="Compact List of Tagged Items" +COM_TAGS_TAG_VIEW_LIST_DESC="List of items that have been tagged with the selected tags." +COM_TAGS_TAG_VIEW_LIST_OPTION="List view options" +COM_TAGS_TAG_VIEW_LIST_TITLE="Tagged items list" +COM_TAGS_TAGS="Tags" +COM_TAGS_TAGS_VIEW_COMPACT_DESC="Compact list of tags." +COM_TAGS_TAGS_VIEW_COMPACT_TITLE="Compact Tags View" +COM_TAGS_TAGS_VIEW_DEFAULT_DESC="This links to a detailed list of all tags." +COM_TAGS_TAGS_VIEW_DEFAULT_TITLE="List All Tags" +COM_TAGS_XML_DESCRIPTION="A component for tagging content items." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.com_templates.ini b/Sites/pages/administrator/language/en-GB/en-GB.com_templates.ini new file mode 100644 index 00000000..794d6253 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.com_templates.ini @@ -0,0 +1,247 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +COM_TEMPLATES="Templates" +COM_TEMPLATES_ADVANCED_FIELDSET_LABEL="Advanced" +COM_TEMPLATES_ARE_YOU_SURE="Are you sure?" +COM_TEMPLATES_ASSIGNED_1="Assigned to one menu item." +COM_TEMPLATES_ASSIGNED_MORE="Assigned to %d menu items." +COM_TEMPLATES_BASIC_FIELDSET_LABEL="Options" +COM_TEMPLATES_BUTTON_CLOSE_FILE="Close File" +COM_TEMPLATES_BUTTON_COPY_TEMPLATE="Copy Template" +COM_TEMPLATES_BUTTON_COPY_FILE="Copy File" +COM_TEMPLATES_BUTTON_CREATE="Create" +COM_TEMPLATES_BUTTON_CROP="Crop" +COM_TEMPLATES_BUTTON_DELETE="Delete" +COM_TEMPLATES_BUTTON_DELETE_FILE="Delete File" +COM_TEMPLATES_BUTTON_EXTRACT_ARCHIVE="Extract Here" +COM_TEMPLATES_BUTTON_FILE="New File" +COM_TEMPLATES_BUTTON_FOLDERS="Manage Folders" +COM_TEMPLATES_BUTTON_LESS="Compile LESS" +COM_TEMPLATES_BUTTON_PREVIEW="Template Preview" +COM_TEMPLATES_BUTTON_RENAME="Rename" +COM_TEMPLATES_BUTTON_RENAME_FILE="Rename File" +COM_TEMPLATES_BUTTON_RESIZE="Resize" +COM_TEMPLATES_BUTTON_UPLOAD="Upload" +COM_TEMPLATES_CHECK_FILE_OWNERSHIP="Check file ownership" +COM_TEMPLATES_CLICK_TO_ENLARGE="Select to enlarge." +COM_TEMPLATES_COMPILE_ERROR="An error occurred. Failed to compile." +COM_TEMPLATES_COMPILE_LESS="You should compile %s to generate a CSS file." +COM_TEMPLATES_COMPILE_SUCCESS="Successfully compiled LESS." +COM_TEMPLATES_CONFIG_FIELDSET_DESC="Global configuration for templates." +COM_TEMPLATES_CONFIG_POSITIONS_DESC="Enable the preview of the module positions in the template by appending tp=1 to the web address. Also enables the Preview button in the list of templates." +COM_TEMPLATES_CONFIG_POSITIONS_LABEL="Preview Module Positions" +COM_TEMPLATES_CONFIG_FONT_DESC="These file types will be available for font preview." +COM_TEMPLATES_CONFIG_FONT_LABEL="Valid Font Formats" +COM_TEMPLATES_CONFIG_IMAGE_DESC="These file types will be available for cropping and resizing." +COM_TEMPLATES_CONFIG_IMAGE_LABEL="Valid Image Formats" +COM_TEMPLATES_CONFIG_SOURCE_DESC="These file types will be available for editing." +COM_TEMPLATES_CONFIG_SOURCE_LABEL="Valid Source Formats" +COM_TEMPLATES_CONFIG_SUPPORTED_DESC="Be careful before changing the file types. Read the tool tips before editing." +COM_TEMPLATES_CONFIG_SUPPORTED_LABEL="Supported File Formats" +COM_TEMPLATES_CONFIG_UPLOAD_DESC="The maximum upload size for files inside Template Manager." +COM_TEMPLATES_CONFIG_UPLOAD_LABEL="Upload Size (MB)" +COM_TEMPLATES_CONFIGURATION="Template: Options" +COM_TEMPLATES_COPY_SUCCESS="New template called %s was installed." +COM_TEMPLATES_CROP_AREA_ERROR="Crop area not selected." +COM_TEMPLATES_DIRECTORY_NOT_WRITABLE="The template folder is not writable. Some features may not work." +COM_TEMPLATES_ERR_XML="Template XML data not available" +COM_TEMPLATES_ERROR_CANNOT_DELETE_LAST_STYLE="Can't delete the last style of a template. To uninstall/delete a template go to: Extensions-> Manage-> Manage-> Select template to be deleted-> Select 'Uninstall'." +COM_TEMPLATES_ERROR_CANNOT_UNSET_DEFAULT_STYLE="Can't unset default style." +COM_TEMPLATES_ERROR_COULD_NOT_COPY="Unable to copy template files to temporary folder." +COM_TEMPLATES_ERROR_COULD_NOT_INSTALL="Unable to install new template from temporary folder." +COM_TEMPLATES_ERROR_COULD_NOT_WRITE="Unable to delete temporary folder." +COM_TEMPLATES_ERROR_CREATE_NOT_PERMITTED="Unable to create temporary folder." +COM_TEMPLATES_ERROR_DUPLICATE_TEMPLATE_NAME="A template with this name already is installed." +COM_TEMPLATES_ERROR_EDITOR_DISABLED="Either the CodeMirror or the None editor plugin should be enabled to edit template files." +COM_TEMPLATES_ERROR_EXECUTABLE="Can't upload executable files." +COM_TEMPLATES_ERROR_EXTENSION_RECORD_NOT_FOUND="Extension record not found in database." +COM_TEMPLATES_ERROR_FAILED_TO_SAVE_FILENAME="An error occurred. The file %s could not be saved." +COM_TEMPLATES_ERROR_FILE_CREATE="Failed to create file." +COM_TEMPLATES_ERROR_FILE_DELETE="An error occurred. Failed to delete the file." +COM_TEMPLATES_ERROR_FILE_FORMAT="File format not supported." +COM_TEMPLATES_ERROR_FILE_RENAME="An error occurred. Failed to rename file." +COM_TEMPLATES_ERROR_FILE_UPLOAD="Failed to upload file." +COM_TEMPLATES_ERROR_FOLDER_CREATE="Failed to create folder." +COM_TEMPLATES_ERROR_FONT_FILE_NOT_FOUND="Font file not found." +COM_TEMPLATES_ERROR_IMAGE_FILE_NOT_FOUND="Image file not found." +COM_TEMPLATES_ERROR_INDEX_DELETE="The file index.php can't be deleted. Make changes in the editor if you want to change the file." +COM_TEMPLATES_ERROR_INVALID_FROM_NAME="Template to copy from can't be found." +COM_TEMPLATES_ERROR_INVALID_TEMPLATE_NAME="Invalid template name. Please use only letters, numbers, dashes and underscores." +COM_TEMPLATES_ERROR_RENAME_INDEX="The file index.php can't be renamed." +COM_TEMPLATES_ERROR_ROOT_DELETE="The root folder can't be deleted." +COM_TEMPLATES_ERROR_SAVE_DISABLED_TEMPLATE="Unable to save a style associated to a disabled template." +COM_TEMPLATES_ERROR_SOURCE_FILE_NOT_FOUND="Source file not found." +COM_TEMPLATES_ERROR_SOURCE_FILE_NOT_UNWRITABLE="Source file can't be returned to unwritable status." +COM_TEMPLATES_ERROR_SOURCE_FILE_NOT_WRITABLE="Source file not writable." +COM_TEMPLATES_ERROR_SOURCE_ID_FILENAME_MISMATCH="Stored ID does not match the submitted one." +COM_TEMPLATES_ERROR_STYLE_NOT_FOUND="Style not found." +COM_TEMPLATES_ERROR_STYLE_REQUIRES_TITLE="The style requires a title." +COM_TEMPLATES_ERROR_TEMPLATE_FOLDER_NOT_FOUND="Template folder not found." +COM_TEMPLATES_ERROR_UPLOAD_INPUT="No file was found." +COM_TEMPLATES_ERROR_WARNFILENAME="Invalid file name. Please correct the name of the file and upload again." +COM_TEMPLATES_ERROR_WARNFILETOOLARGE="File bigger than 2 MB can't be uploaded." +COM_TEMPLATES_ERROR_WARNFILETYPE="File format not supported." +COM_TEMPLATES_ERROR_WARNIEXSS="Can't be uploaded. Has XSS." +COM_TEMPLATES_FIELD_CLIENT_DESC="Whether this template is used for the Frontend (0) or the Backend (1)." +COM_TEMPLATES_FIELD_CLIENT_LABEL="Location" +COM_TEMPLATES_FIELD_HOME_ADMINISTRATOR_DESC="This template style is defined as the default." +COM_TEMPLATES_FIELD_HOME_LABEL="Default" +COM_TEMPLATES_FIELD_HOME_SITE_DESC="If the multilingual functionality is not implemented, please limit your choice between No and All. This template style will be defined as the global default template style.
    If the System - Language Filter plugin is enabled and you use different template styles depending on your content languages please assign a language to this style." +COM_TEMPLATES_FIELD_SOURCE_DESC="Source code." +COM_TEMPLATES_FIELD_SOURCE_LABEL="Source Code" +COM_TEMPLATES_FIELD_TEMPLATE_DESC="Template name." +COM_TEMPLATES_FIELD_TEMPLATE_LABEL="Template" +COM_TEMPLATES_FIELD_TITLE_DESC="Style name." +COM_TEMPLATES_FIELD_TITLE_LABEL="Style Name" +COM_TEMPLATES_FILE_ARCHIVE_OPEN_FAIL="Failed to open the archive file." +COM_TEMPLATES_FILE_ARCHIVE_EXISTS="Some files with the same name already exist." +COM_TEMPLATES_FILE_ARCHIVE_NOT_FOUND="Archive file not found." +COM_TEMPLATES_FILE_ARCHIVE_EXTRACT_SUCCESS="Successfully extracted the archive file." +COM_TEMPLATES_FILE_ARCHIVE_EXTRACT_FAIL="Failed to extract the archive file." +COM_TEMPLATES_FILE_CREATE_ERROR="An error occurred creating the file." +COM_TEMPLATES_FILE_CREATE_SUCCESS="File created." +COM_TEMPLATES_FILE_CONTENT_PREVIEW="File Content Preview" +COM_TEMPLATES_FILE_COPY_FAIL="Failed to copy the file." +COM_TEMPLATES_FILE_COPY_SUCCESS="The current file was copied as %s." +COM_TEMPLATES_FILE_CROP_ERROR="Failed to crop image." +COM_TEMPLATES_FILE_CROP_SUCCESS="Image cropped." +COM_TEMPLATES_FILE_DELETE_ERROR="Not able to delete the file." +COM_TEMPLATES_FILE_DELETE_FAIL="Not able to delete the file." +COM_TEMPLATES_FILE_DELETE_SUCCESS="File deleted." +COM_TEMPLATES_FILE_NEW_NAME_DESC="Enter the name of the new copied file." +COM_TEMPLATES_FILE_NEW_NAME_LABEL="Copied File Name" +COM_TEMPLATES_FILE_EXISTS="File with the same name already exists." +COM_TEMPLATES_FILE_INFO="File Information" +COM_TEMPLATES_FILE_NAME="File Name" +COM_TEMPLATES_FILE_PERMISSIONS="The File Permissions are %s" +COM_TEMPLATES_FILE_RENAME_ERROR="An error occurred renaming the file." +COM_TEMPLATES_FILE_RENAME_SUCCESS="File renamed." +COM_TEMPLATES_FILE_RESIZE_ERROR="Failed to resize image." +COM_TEMPLATES_FILE_RESIZE_SUCCESS="Image resized." +COM_TEMPLATES_FILE_SAVE_SUCCESS="File saved." +COM_TEMPLATES_FILE_UNSUPPORTED_ARCHIVE="Unsupported files present inside the zip file." +COM_TEMPLATES_FILE_UPLOAD_ERROR="There was an error uploading the file." +COM_TEMPLATES_FILE_UPLOAD_SUCCESS="Successfully uploaded file." +COM_TEMPLATES_FILTER_TEMPLATE="- Select Template -" +COM_TEMPLATES_FOLDER_CREATE_ERROR="There was an error creating the folder." +COM_TEMPLATES_FOLDER_CREATE_SUCCESS="Folder created." +COM_TEMPLATES_FOLDER_DELETE_ERROR="An error occurred. Failed to delete folder." +COM_TEMPLATES_FOLDER_DELETE_SUCCESS="Folder deleted." +COM_TEMPLATES_FOLDER_ERROR="Not able to create folder." +COM_TEMPLATES_FOLDER_EXISTS="Folder with the same name already exists." +COM_TEMPLATES_FOLDER_NAME="Folder Name" +COM_TEMPLATES_FOLDER_NOT_EXISTS="The folder does not exist." +COM_TEMPLATES_FTP_DESC="For updating the template source files, Joomla will most likely need your FTP account details. Please enter them in the form fields below." +COM_TEMPLATES_FTP_TITLE="FTP Login Details" +COM_TEMPLATES_GRID_UNSET_LANGUAGE="Unset %s Default" +COM_TEMPLATES_HOME_BUTTON="Documentation" +COM_TEMPLATES_HOME_HEADING="Select a File" +COM_TEMPLATES_HOME_TEXT="You can select from a number of options for customising the look of your templates. The Template Manager supports Source files, Image files, Font files, Zip archives and most of the operations that can be performed on those files. Select a file and you are good to go. Check the documentation if you want to know more." +COM_TEMPLATES_HEADING_ASSIGNED="Assigned" +COM_TEMPLATES_HEADING_DEFAULT="Default" +COM_TEMPLATES_HEADING_DEFAULT_ASC="Default ascending" +COM_TEMPLATES_HEADING_DEFAULT_DESC="Default descending" +COM_TEMPLATES_HEADING_IMAGE="Image" +COM_TEMPLATES_HEADING_LOCATION_ASC="Location ascending" +COM_TEMPLATES_HEADING_LOCATION_DESC="Location descending" +COM_TEMPLATES_HEADING_PAGES="Pages" +COM_TEMPLATES_HEADING_STYLE="Style" +COM_TEMPLATES_HEADING_STYLE_ASC="Style ascending" +COM_TEMPLATES_HEADING_STYLE_DESC="Style descending" +COM_TEMPLATES_HEADING_TEMPLATE="Template" +COM_TEMPLATES_HEADING_TEMPLATE_ASC="Template ascending" +COM_TEMPLATES_HEADING_TEMPLATE_DESC="Template descending" +COM_TEMPLATES_IMAGE_HEIGHT="Height" +COM_TEMPLATES_IMAGE_WIDTH="Width" +COM_TEMPLATES_INVALID_FILE_NAME="Invalid file name. Please choose a file name with a-z, A-Z, 0-9, - and _." +COM_TEMPLATES_INVALID_FILE_TYPE="File type not selected." +COM_TEMPLATES_INVALID_FOLDER_NAME="Invalid folder name. Please choose a folder name with a-z, A-Z, 0-9, - and _." +COM_TEMPLATES_MANAGER="Templates" +COM_TEMPLATES_MANAGER_ADD_STYLE="Templates: Add Style" +COM_TEMPLATES_MANAGER_EDIT_FILE="Templates: Edit File" +COM_TEMPLATES_MANAGER_EDIT_STYLE="Templates: Edit Style" +COM_TEMPLATES_MANAGE_FOLDERS="Manage Folders" +COM_TEMPLATES_MANAGER_STYLES="Templates: Styles" +COM_TEMPLATES_MANAGER_STYLES_ADMIN="Templates: Styles (Administrator)" +COM_TEMPLATES_MANAGER_STYLES_SITE="Templates: Styles (Site)" +COM_TEMPLATES_MANAGER_TEMPLATES="Templates" +COM_TEMPLATES_MANAGER_TEMPLATES_ADMIN="Templates: Templates (Administrator)" +COM_TEMPLATES_MANAGER_TEMPLATES_SITE="Templates: Templates (Site)" +COM_TEMPLATES_MANAGER_VIEW_TEMPLATE="Templates: Customise (%s)" +COM_TEMPLATES_MENU_CHANGED_1="1 menu item has been assigned or unassigned to this style." +COM_TEMPLATES_MENU_CHANGED_MORE="%d menu items have been assigned or unassigned to this style." +COM_TEMPLATES_MENUS_ASSIGNMENT="Menu Assignment" +COM_TEMPLATES_MODAL_FILE_DELETE="The file %s will be deleted." +COM_TEMPLATES_MSG_MANAGE_NO_STYLES="There are no styles installed matching your query." +COM_TEMPLATES_MSG_MANAGE_NO_TEMPLATES="There are no templates installed matching your query." +COM_TEMPLATES_N_ITEMS_DELETED="%d template styles deleted." +COM_TEMPLATES_N_ITEMS_DELETED_1="Template style deleted." +COM_TEMPLATES_NEW_FILE_HEADER="Create or Upload a new file." +COM_TEMPLATES_NEW_FILE_NAME="New File Name" +COM_TEMPLATES_NEW_FILE_SELECT="Select a file type" +COM_TEMPLATES_NEW_FILE_TYPE="File Type" +COM_TEMPLATES_NO_TEMPLATE_SELECTED="No template selected." +COM_TEMPLATES_OPTION_NONE=":: None ::" +; Deprecated 4.0 +COM_TEMPLATES_OPTION_SELECT_PAGE="- Select Page -" +COM_TEMPLATES_OPTION_SELECT_MENU_ITEM="- Select Menu Item -" +COM_TEMPLATES_OVERRIDE_CREATED="Override created in " +COM_TEMPLATES_OVERRIDE_EXISTS="Override already exists." +COM_TEMPLATES_OVERRIDE_FAILED="Failed to create override." +COM_TEMPLATES_OVERRIDE_SUCCESS="Successfully created the override." +COM_TEMPLATES_OVERRIDES_COMPONENTS="Components" +COM_TEMPLATES_OVERRIDES_LAYOUTS="Layouts" +COM_TEMPLATES_OVERRIDES_MODULES="Modules" +COM_TEMPLATES_OVERRIDES_PLUGINS="Plugins" +COM_TEMPLATES_PREVIEW="Preview" +COM_TEMPLATES_RENAME_FILE="Rename file %s" +COM_TEMPLATES_RESIZE_IMAGE="Resize Image" +COM_TEMPLATES_SOURCE_CODE="Source" +COM_TEMPLATES_SITE_PREVIEW="Site Preview" +COM_TEMPLATES_STYLE_CANNOT_DELETE_DEFAULT_STYLE="Can't delete default style." +COM_TEMPLATES_STYLE_SAVE_SUCCESS="Style saved." +COM_TEMPLATES_STYLES_FILTER_SEARCH_DESC="Search in style description." +COM_TEMPLATES_STYLES_PAGES_ALL="Default for all pages" +COM_TEMPLATES_STYLES_PAGES_ALL_LANGUAGE="Default for %s pages" +COM_TEMPLATES_STYLES_PAGES_SELECTED="Assigned on %s pages" +COM_TEMPLATES_STYLES_PAGES_NONE="Not assigned" +COM_TEMPLATES_SUBMENU_STYLES="Styles" +COM_TEMPLATES_SUBMENU_TEMPLATES="Templates" +COM_TEMPLATES_SUCCESS_DUPLICATED="Style duplicated." +COM_TEMPLATES_SUCCESS_HOME_SET="Default style set." +COM_TEMPLATES_SUCCESS_HOME_UNSET="Default style unset." +COM_TEMPLATES_TAB_DESCRIPTION="Template Description" +COM_TEMPLATES_TAB_EDITOR="Editor" +COM_TEMPLATES_TAB_OVERRIDES="Create Overrides" +COM_TEMPLATES_TEMPLATE_ADD_CSS="Add new stylesheet" +COM_TEMPLATES_TEMPLATE_ADD_ERROR="Add custom error page template (optional)." +COM_TEMPLATES_TEMPLATE_CLOSE="Close" +COM_TEMPLATES_TEMPLATE_COPY="Copy Template" +COM_TEMPLATES_TEMPLATE_CSS="Stylesheets" +COM_TEMPLATES_TEMPLATE_DESCRIPTION="Template description." +COM_TEMPLATES_TEMPLATE_DETAILS="%s Details and Files" +COM_TEMPLATES_TEMPLATE_EDIT_CSS="Edit %s" +COM_TEMPLATES_TEMPLATE_EDIT_ERROR="Edit error page template" +COM_TEMPLATES_TEMPLATE_EDIT_MAIN="Edit main page template" +COM_TEMPLATES_TEMPLATE_EDIT_OFFLINEVIEW="Edit offline page template" +COM_TEMPLATES_TEMPLATE_EDIT_PRINTVIEW="Edit print view template" +COM_TEMPLATES_TEMPLATE_FILENAME="Editing file "%s" in template "%s"." +COM_TEMPLATES_TEMPLATE_FILES="Template Files" +COM_TEMPLATES_TEMPLATE_HTML="HTML files" +COM_TEMPLATES_TEMPLATE_MASTER_FILES="Template Master Files" +COM_TEMPLATES_TEMPLATE_NEW_NAME_DESC="Enter the name of the new template. Please use letters, numbers and underscore only." +COM_TEMPLATES_TEMPLATE_NEW_NAME_LABEL="New Template Name" +COM_TEMPLATES_TEMPLATE_NO_PREVIEW="No preview available. You can enable preview in the options." +COM_TEMPLATES_TEMPLATE_NO_PREVIEW_ADMIN="No preview available for Administrator templates" +COM_TEMPLATES_TEMPLATE_NO_PREVIEW_DESC="To enable template previews, enable the Preview Module Positions option in Template Options." +COM_TEMPLATES_TEMPLATE_NOT_SPECIFIED="Template not specified." +COM_TEMPLATES_TEMPLATE_PREVIEW="Preview" +COM_TEMPLATES_TEMPLATES_FILTER_SEARCH_DESC="Search in template name or folder name." +COM_TEMPLATES_TOGGLE_FULL_SCREEN="Press Ctrl-Q to toggle Full Screen editing." +COM_TEMPLATES_TOOLBAR_SET_HOME="Default" +COM_TEMPLATES_WARNING_FORMAT_WILL_NOT_BE_VISIBLE="You have created a new file with the extension '%s'. This is supported but as you did not have that file extension in the list of supported formats this can't be displayed. Please double check the options for Templates and add the format if needed." +COM_TEMPLATES_XML_DESCRIPTION="This component manages templates" +JLIB_RULES_SETTING_NOTES="Changes apply to this component only.
    Inherited - a Global Configuration setting or higher level setting is applied.
    Denied always wins - whatever is set at the Global or higher level and applies to all child elements.
    Allowed will enable the action for this component unless overruled by a Global Configuration setting." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.com_templates.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.com_templates.sys.ini new file mode 100644 index 00000000..0a38655d --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.com_templates.sys.ini @@ -0,0 +1,11 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +COM_TEMPLATES="Templates" +COM_TEMPLATES_STYLE_VIEW_DEFAULT_DESC="Shows a List of Template styles" +COM_TEMPLATES_STYLE_VIEW_DEFAULT_TITLE="Template Styles" +COM_TEMPLATES_TEMPLATES_VIEW_DEFAULT_DESC="Shows a List of Installed Templates" +COM_TEMPLATES_TEMPLATES_VIEW_DEFAULT_TITLE="Templates" +COM_TEMPLATES_XML_DESCRIPTION="This component manages templates." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.com_users.ini b/Sites/pages/administrator/language/en-GB/en-GB.com_users.ini new file mode 100644 index 00000000..63421795 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.com_users.ini @@ -0,0 +1,397 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +COM_USERS="Users" +COM_USERS_ACTIONS_AVAILABLE="Actions Permitted" +COM_USERS_ACTIVATED="Activated" +COM_USERS_ADD_NOTE="Add a Note" +COM_USERS_ASSIGNED_GROUPS="Assigned User Groups" +COM_USERS_BATCH_ADD="Add To Group" +COM_USERS_BATCH_DELETE="Delete From Group" +COM_USERS_BATCH_GROUP="Select Group" +COM_USERS_BATCH_OPTIONS="Batch process the selected users" +COM_USERS_BATCH_SET="Set To Group" +COM_USERS_CATEGORIES_TITLE="User Notes: Categories" +COM_USERS_CATEGORY_HEADING="Category" +COM_USERS_CONFIG_DOMAIN_OPTIONS="Email Domain Options" +COM_USERS_CONFIG_FIELD_ALLOWREGISTRATION_DESC="If set to Yes, new Users are allowed to self-register." +COM_USERS_CONFIG_FIELD_ALLOWREGISTRATION_LABEL="Allow User Registration" +COM_USERS_CONFIG_FIELD_CAPTCHA_DESC="Select the captcha plugin that will be used in the registration, password and username reminder forms. You may need to enter required information for your captcha plugin in the Plugin Manager.
    If 'Use Global' is selected, make sure a captcha plugin is selected in Global Configuration." +COM_USERS_CONFIG_FIELD_CAPTCHA_LABEL="Captcha" +COM_USERS_CONFIG_FIELD_CHANGEUSERNAME_DESC="Allow users to change their Username when editing their profile." +COM_USERS_CONFIG_FIELD_CHANGEUSERNAME_LABEL="Change Username" +COM_USERS_CONFIG_FIELD_DOMAIN_NAME_DESC="Enter a domain name. Wildcards (*) are supported. For example:
    * allows or disallows all domains;
    *.com allows or disallows all .com domains;
    *.joomla.org allows or disallows all joomla.org subdomains." +COM_USERS_CONFIG_FIELD_DOMAIN_NAME_LABEL="Domain Name" +COM_USERS_CONFIG_FIELD_DOMAIN_RULE_DESC="Select whether to allow or disallow the domain." +COM_USERS_CONFIG_FIELD_DOMAIN_RULE_LABEL="Rule" +COM_USERS_CONFIG_FIELD_DOMAIN_RULE_OPTION_ALLOW="Allow" +COM_USERS_CONFIG_FIELD_DOMAIN_RULE_OPTION_DISALLOW="Disallow" +COM_USERS_CONFIG_FIELD_DOMAINS_DESC="Enter a list of allowed and disallowed email domains. By default, all domains are allowed." +COM_USERS_CONFIG_FIELD_DOMAINS_LABEL="Email Domains" +COM_USERS_CONFIG_FIELD_FRONTEND_LANG_DESC="If 'Frontend User Parameters' is set to 'Show', users will be able to select their Frontend language preference when registering." +COM_USERS_CONFIG_FIELD_FRONTEND_LANG_LABEL="Frontend Language" +COM_USERS_CONFIG_FIELD_FRONTEND_RESET_COUNT_DESC="The maximum number of password resets allowed within the time period. Zero indicates no limit." +COM_USERS_CONFIG_FIELD_FRONTEND_RESET_COUNT_LABEL="Maximum Reset Count" +COM_USERS_CONFIG_FIELD_FRONTEND_RESET_TIME_DESC="The time period, in hours, for the reset counter." +COM_USERS_CONFIG_FIELD_FRONTEND_RESET_TIME_LABEL="Reset Time" +COM_USERS_CONFIG_FIELD_FRONTEND_USERPARAMS_DESC="If set to Show, Users will be able to select their language, editor and Help Site preferences on their details screen when logged-in to the Frontend." +COM_USERS_CONFIG_FIELD_FRONTEND_USERPARAMS_LABEL="Frontend User Parameters" +COM_USERS_CONFIG_FIELD_GUEST_USER_GROUP_DESC="The default Group that will be applied to Guest (not logged-in) Users." +COM_USERS_CONFIG_FIELD_GUEST_USER_GROUP_LABEL="Guest User Group" +COM_USERS_CONFIG_FIELD_MAILBODY_SUFFIX_DESC="This is added after the mail text." +COM_USERS_CONFIG_FIELD_MAILBODY_SUFFIX_LABEL="Mailbody Suffix" +COM_USERS_CONFIG_FIELD_MAILTOADMIN_DESC="If set to Yes then a notification mail will be sent to administrators if 'New User Account Activation' is set to 'None' or 'Self'." +COM_USERS_CONFIG_FIELD_MAILTOADMIN_LABEL="Send Mail to Administrators" +COM_USERS_CONFIG_FIELD_MINIMUM_INTEGERS="Minimum Integers" +COM_USERS_CONFIG_FIELD_MINIMUM_INTEGERS_DESC="Set the minimum number of integers that must be included in a password." +COM_USERS_CONFIG_FIELD_MINIMUM_LOWERCASE="Minimum Lower Case" +COM_USERS_CONFIG_FIELD_MINIMUM_LOWERCASE_DESC="Set the minimum number of lower case alphabetical characters required for a password." +COM_USERS_CONFIG_FIELD_MINIMUM_PASSWORD_LENGTH="Minimum Length" +COM_USERS_CONFIG_FIELD_MINIMUM_PASSWORD_LENGTH_DESC="Set the minimum length for a password." +COM_USERS_CONFIG_FIELD_MINIMUM_SYMBOLS="Minimum Symbols" +COM_USERS_CONFIG_FIELD_MINIMUM_SYMBOLS_DESC="Set the minimum number of symbols (such as !@#$) required in a password." +COM_USERS_CONFIG_FIELD_MINIMUM_UPPERCASE="Minimum Upper Case" +COM_USERS_CONFIG_FIELD_MINIMUM_UPPERCASE_DESC="Set the minimum number of upper case alphabetical characters required for a password." +COM_USERS_CONFIG_FIELD_NEW_USER_TYPE_DESC="The default group that will be applied to New Users Registering via the Frontend." +COM_USERS_CONFIG_FIELD_NEW_USER_TYPE_LABEL="New User Registration Group" +COM_USERS_CONFIG_FIELD_NOTES_HISTORY="User Notes History" +COM_USERS_CONFIG_FIELD_SENDPASSWORD_LABEL="Send Password" +COM_USERS_CONFIG_FIELD_SENDPASSWORD_DESC="If set to Yes the user's first password will be emailed to the user as part of the registration mail." +COM_USERS_CONFIG_FIELD_SUBJECT_PREFIX_DESC="This is added in front of each mail subject." +COM_USERS_CONFIG_FIELD_SUBJECT_PREFIX_LABEL="Subject Prefix" +COM_USERS_CONFIG_FIELD_USERACTIVATION_DESC="If set to None the user will be registered immediately. If set to Self the User will be emailed a link to activate their account before they can log in. If set to Administrator the user will be emailed a link to verify their email address and then all users set to receive system emails and who have the permission to create users will be notified to activate the user's account." +COM_USERS_CONFIG_FIELD_USERACTIVATION_LABEL="New User Account Activation" +COM_USERS_CONFIG_FIELD_USERACTIVATION_OPTION_ADMINACTIVATION="Administrator" +COM_USERS_CONFIG_FIELD_USERACTIVATION_OPTION_SELFACTIVATION="Self" +COM_USERS_CONFIG_IMPORT_FAILED="An error was encountered while importing the configuration: %s." +COM_USERS_CONFIG_INTEGRATION_SETTINGS_DESC="These settings determine how the Users Component will integrate with other extensions." +COM_USERS_CONFIG_PASSWORD_OPTIONS="Password Options" +COM_USERS_CONFIG_SAVE_FAILED="An error was encountered while saving the configuration: %s." +COM_USERS_CONFIG_USER_OPTIONS="User Options" +COM_USERS_CONFIGURATION="Users: Options" +COM_USERS_COUNT_ENABLED_USERS="Enabled Users" +COM_USERS_COUNT_DISABLED_USERS="Disabled Users" +COM_USERS_DEBUG_DESC="Display the Advanced Permission Reports." +COM_USERS_DEBUG_EXPLICIT_ALLOW="Allowed" +COM_USERS_DEBUG_EXPLICIT_DENY="Forbidden" +COM_USERS_DEBUG_GROUP="Advanced Permissions Report" +COM_USERS_DEBUG_GROUPS_LABEL="Advanced Groups Permissions" +COM_USERS_DEBUG_GROUPS_DESC="Display the Advanced Groups Permissions Reports." +COM_USERS_DEBUG_IMPLICIT_DENY="Not Allowed" +COM_USERS_DEBUG_LABEL="Advanced" +COM_USERS_DEBUG_LEGEND="Legend:" +COM_USERS_DEBUG_USER="Advanced Permissions Report" +COM_USERS_DEBUG_USERS_LABEL="Advanced Users Permissions" +COM_USERS_DEBUG_USERS_DESC="Display the Advanced Users Permissions Reports." +COM_USERS_DELETE_ERROR_INVALID_GROUP="You can't delete user groups to which you belong." +COM_USERS_DESIRED_PASSWORD="Enter your desired password." +COM_USERS_EDIT_NOTE="Edit Note" +COM_USERS_EDIT_NOTE_N="Editing note with ID #%d" +COM_USERS_EDIT_USER="Edit User %s" +COM_USERS_EMPTY_REVIEW="-" +COM_USERS_EMPTY_SUBJECT="- No subject -" +COM_USERS_ERROR_CANNOT_BATCH_SUPERUSER="A non-Super User can't perform batch operations on Super Users." +COM_USERS_ERROR_INVALID_GROUP="Invalid Group" +COM_USERS_ERROR_LEVELS_NOLEVELS_SELECTED="No View Permission Level(s) selected." +COM_USERS_ERROR_NO_ADDITIONS="The selected user(s) are already assigned to the selected group." +COM_USERS_ERROR_VIEW_LEVEL_IN_USE="You can't delete the view access level '%d:%s' because it is being used by content." +COM_USERS_ERROR_SECRET_CODE_WITHOUT_TFA="You have entered a Secret Code but two factor authentication is not enabled in your user account. If you want to use a secret code to secure your login please edit your user profile and enable two factor authentication." +COM_USERS_FIELD_CATEGORY_ID_LABEL="Category" +COM_USERS_FIELD_ID_LABEL="ID" +COM_USERS_FIELD_LOGIN_MENUITEM="Menu Item" +COM_USERS_FIELD_LOGIN_REDIRECT_PLACEHOLDER="index.php?Itemid=999&lang=en-GB" +COM_USERS_FIELD_LOGIN_REDIRECT_CHOICE_DESC="'Internal URL' lets you manually enter any internal URL in the Redirect field. 'Menu Item' lets you directly select an existing menu item.
    For a multilingual site, it is recommended to use 'Menu Item'." +COM_USERS_FIELD_LOGIN_REDIRECT_CHOICE_LABEL="Choose Login Redirect Type" +COM_USERS_FIELD_LOGIN_REDIRECT_ERROR="Only one of the login redirect fields should have a value." +COM_USERS_FIELD_LOGIN_REDIRECTMENU_DESC="Select or create the page the user will be redirected to after a successful login. The default is to stay on the same page." +COM_USERS_FIELD_LOGIN_REDIRECTMENU_LABEL="Menu Item Login Redirect" +COM_USERS_FIELD_LOGIN_URL="Internal URL" +COM_USERS_FIELD_LOGOUT_REDIRECT_CHOICE_DESC="'Internal URL' lets you manually enter any internal URL in the Redirect field. 'Menu Item' lets you directly select an existing menu item.
    For a multilingual site, it is recommended to use 'Menu Item'." +COM_USERS_FIELD_LOGOUT_REDIRECT_CHOICE_LABEL="Choose Logout Redirect Type" +COM_USERS_FIELD_LOGOUT_REDIRECT_ERROR="Only one of the logout redirect fields should have a value." +COM_USERS_FIELD_LOGOUT_REDIRECTMENU_DESC="Select or create the page the user will be redirected to after ending their current session by logging out. The default is to stay on the same page." +COM_USERS_FIELD_LOGOUT_REDIRECTMENU_LABEL="Menu Item Logout Redirect" +COM_USERS_FIELD_NOTEBODY_DESC="Note" +COM_USERS_FIELD_NOTEBODY_LABEL="Note" +COM_USERS_FIELD_REVIEW_TIME_DESC="Review Date is a manually entered date you can use as fits in your workflow. Examples would be to put in a date when you want to review a user or the last date you reviewed the user." +COM_USERS_FIELD_REVIEW_TIME_LABEL="Review Date" +COM_USERS_FIELD_STATE_DESC="Set publication status." +COM_USERS_FIELD_SUBJECT_DESC="The subject line for the note." +COM_USERS_FIELD_SUBJECT_LABEL="Subject" +COM_USERS_FIELD_USER_ID_LABEL="User" +COM_USERS_FIELDS_USER_FIELDS_TITLE="Users: Fields" +COM_USERS_FIELDS_USER_FIELD_ADD_TITLE="Users: New Field" +COM_USERS_FIELDS_USER_FIELD_EDIT_TITLE="Users: Edit Field" +COM_USERS_FILTER_ACTIVE="- Select Active State -" +COM_USERS_FILTER_COMPONENT_LABEL="Component" +COM_USERS_FILTER_COMPONENT_DESC="Component to debug." +COM_USERS_FILTER_LABEL="Filter Users by: " +COM_USERS_FILTER_LEVEL_END_LABEL="Level End" +COM_USERS_FILTER_LEVEL_END_DESC="Asset end level." +COM_USERS_FILTER_LEVEL_START_LABEL="Level Start" +COM_USERS_FILTER_LEVEL_START_DESC="Asset start level." +COM_USERS_FILTER_NOTES="Show notes list for this user" +COM_USERS_FILTER_STATE="- Select State -" +COM_USERS_FILTER_USER_GROUP="Filter User Group" +COM_USERS_FILTER_USERGROUP="- Select Group -" +COM_USERS_GROUP_FIELD_PARENT_DESC="Choose a Parent for this Group." +COM_USERS_GROUP_FIELD_PARENT_LABEL="Group Parent" +COM_USERS_GROUP_FIELD_TITLE_DESC="Enter a Title for the Group." +COM_USERS_GROUP_FIELD_TITLE_LABEL="Group Title" +COM_USERS_GROUP_SAVE_SUCCESS="Group saved." +COM_USERS_GROUPS_CONFIRM_DELETE="Are you sure you wish to delete groups that have users?" +COM_USERS_GROUPS_N_ITEMS_DELETED="%d User Groups deleted." +COM_USERS_GROUPS_N_ITEMS_DELETED_1="1 User Group deleted." +COM_USERS_GROUPS_NO_ITEM_SELECTED="No User Groups selected." +COM_USERS_HEADING_ACTIVATED="Activated" +COM_USERS_HEADING_ACTIVATED_ASC="Activated ascending" +COM_USERS_HEADING_ACTIVATED_DESC="Activated descending" +COM_USERS_HEADING_ASSET_NAME="Asset Name" +COM_USERS_HEADING_ASSET_NAME_ASC="Asset Name ascending" +COM_USERS_HEADING_ASSET_NAME_DESC="Asset Name descending" +COM_USERS_HEADING_ASSET_TITLE="Asset Title" +COM_USERS_HEADING_ASSET_TITLE_ASC="Asset Title ascending" +COM_USERS_HEADING_ASSET_TITLE_DESC="Asset Title descending" +COM_USERS_HEADING_CATEGORY="Category" +COM_USERS_HEADING_CATEGORY_ASC="Category ascending" +COM_USERS_HEADING_CATEGORY_DESC="Category descending" +COM_USERS_HEADING_EMAIL_ASC="Email ascending" +COM_USERS_HEADING_EMAIL_DESC="Email descending" +COM_USERS_HEADING_ENABLED="Enabled" +COM_USERS_HEADING_ENABLED_ASC="Enabled ascending" +COM_USERS_HEADING_ENABLED_DESC="Enabled descending" +COM_USERS_HEADING_GROUP_TITLE="Group Title" +COM_USERS_HEADING_GROUP_TITLE_ASC="Group Title ascending" +COM_USERS_HEADING_GROUP_TITLE_DESC="Group Title descending" +COM_USERS_HEADING_GROUPS="User Groups" +COM_USERS_HEADING_LAST_VISIT_DATE="Last Visit Date" +COM_USERS_HEADING_LAST_VISIT_DATE_ASC="Last visit date ascending" +COM_USERS_HEADING_LAST_VISIT_DATE_DESC="Last visit date descending" +COM_USERS_HEADING_LEVEL_NAME="Level Name" +COM_USERS_HEADING_LEVEL_NAME_ASC="Level Name ascending" +COM_USERS_HEADING_LEVEL_NAME_DESC="Level Name descending" +COM_USERS_HEADING_LFT="LFT" +COM_USERS_HEADING_LFT_ASC="LFT ascending" +COM_USERS_HEADING_LFT_DESC="LFT descending" +COM_USERS_HEADING_NAME="Name" +COM_USERS_HEADING_NAME_ASC="Name ascending" +COM_USERS_HEADING_NAME_DESC="Name descending" +COM_USERS_HEADING_REGISTRATION_DATE="Registration Date" +COM_USERS_HEADING_REGISTRATION_DATE_ASC="Registration date ascending" +COM_USERS_HEADING_REGISTRATION_DATE_DESC="Registration date descending" +COM_USERS_HEADING_REVIEW="Review Date" +COM_USERS_HEADING_REVIEW_ASC="Review Date ascending" +COM_USERS_HEADING_REVIEW_DESC="Review Date descending" +COM_USERS_HEADING_SUBJECT="Subject" +COM_USERS_HEADING_SUBJECT_ASC="Subject ascending" +COM_USERS_HEADING_SUBJECT_DESC="Subject descending" +COM_USERS_HEADING_USER="User" +COM_USERS_HEADING_USER_ASC="User ascending" +COM_USERS_HEADING_USER_DESC="User descending" +COM_USERS_HEADING_USERNAME_ASC="Username ascending" +COM_USERS_HEADING_USERNAME_DESC="Username descending" +COM_USERS_HEADING_USERS_IN_GROUP="Users in group" +COM_USERS_LEVEL_DETAILS="Level Details" +COM_USERS_LEVEL_FIELD_TITLE_DESC="Enter a Title for this Access level." +COM_USERS_LEVEL_FIELD_TITLE_LABEL="Level Title" +COM_USERS_LEVEL_HEADER_ERROR="User header access level error." +COM_USERS_LEVEL_SAVE_SUCCESS="Access level saved." +COM_USERS_LEVELS_N_ITEMS_DELETED="%d View Permission Level deleted." +COM_USERS_LEVELS_N_ITEMS_DELETED_1="1 View Permission Level deleted." +COM_USERS_MAIL_DETAILS="Details" +COM_USERS_MAIL_EMAIL_SENT_TO_N_USERS="Email sent to %s users." +COM_USERS_MAIL_EMAIL_SENT_TO_N_USERS_1="Email sent to one user." +COM_USERS_MAIL_FIELD_EMAIL_DISABLED_USERS_DESC="If checked, disabled users will be included when sending mail." +COM_USERS_MAIL_FIELD_EMAIL_DISABLED_USERS_LABEL="Send to Disabled Users" +COM_USERS_MAIL_FIELD_GROUP_DESC="Choose a group to send the mail to." +COM_USERS_MAIL_FIELD_GROUP_LABEL="Group:" +COM_USERS_MAIL_FIELD_MESSAGE_DESC="Enter a default message." +COM_USERS_MAIL_FIELD_MESSAGE_LABEL="Message" +COM_USERS_MAIL_FIELD_RECURSE_DESC="If checked, the email will also be sent to users who are members of any child groups of the selected groups." +COM_USERS_MAIL_FIELD_RECURSE_LABEL="Mail to Child User Groups" +COM_USERS_MAIL_FIELD_SEND_AS_BLIND_CARBON_COPY_DESC="Hide the recipient list and use the site email address for the To: field." +COM_USERS_MAIL_FIELD_SEND_AS_BLIND_CARBON_COPY_LABEL="Recipients as BCC" +COM_USERS_MAIL_FIELD_SEND_IN_HTML_MODE_DESC="If checked, the email will be sent with HTML tags. If not checked, email will be sent in plain text." +COM_USERS_MAIL_FIELD_SEND_IN_HTML_MODE_LABEL="Send in HTML Mode" +COM_USERS_MAIL_FIELD_SUBJECT_DESC="Enter the subject of the mail." +COM_USERS_MAIL_FIELD_SUBJECT_LABEL="Subject" +COM_USERS_MAIL_FIELD_VALUE_ALL_USERS_GROUPS="All Users Groups" +COM_USERS_MAIL_MESSAGE="Message" +COM_USERS_MAIL_NO_USERS_COULD_BE_FOUND_IN_THIS_GROUP="No users could be found in this group." +COM_USERS_MAIL_ONLY_YOU_COULD_BE_FOUND_IN_THIS_GROUP="You are the only user in this group." +COM_USERS_MAIL_PLEASE_FILL_IN_THE_FORM_CORRECTLY="Please fill in the form correctly." +COM_USERS_MAIL_PLEASE_FILL_IN_THE_MESSAGE="Please enter a message" +COM_USERS_MAIL_PLEASE_FILL_IN_THE_SUBJECT="Please enter a subject" +COM_USERS_MAIL_PLEASE_SELECT_A_GROUP="Please select a Group" +COM_USERS_MAIL_THE_MAIL_COULD_NOT_BE_SENT="The mail could not be sent." +COM_USERS_MASS_MAIL="Mass Mail Users" +COM_USERS_MASS_MAIL_DESC="Mass Mail options." +COM_USERS_MSG_NOT_ENOUGH_INTEGERS_N="Password does not have enough digits. At least %s digits are required." +COM_USERS_MSG_NOT_ENOUGH_INTEGERS_N_1="Password does not have enough digits. At least 1 digit is required." +COM_USERS_MSG_NOT_ENOUGH_LOWERCASE_LETTERS_N="Password does not have enough lower case characters. At least %s lower case characters are required." +COM_USERS_MSG_NOT_ENOUGH_LOWERCASE_LETTERS_N_1="Password does not have enough lower case characters. At least 1 lower case character is required." +COM_USERS_MSG_NOT_ENOUGH_SYMBOLS_N="Password does not have enough symbols (such as !@#$). At least %s symbols are required." +COM_USERS_MSG_NOT_ENOUGH_SYMBOLS_N_1="Password does not have enough symbols (such as !@#$). At least 1 symbol is required." +COM_USERS_MSG_NOT_ENOUGH_UPPERCASE_LETTERS_N="Password does not have enough upper case characters. At least %s upper case characters are required." +COM_USERS_MSG_NOT_ENOUGH_UPPERCASE_LETTERS_N_1="Password does not have enough upper case characters. At least 1 upper case character is required." +COM_USERS_MSG_PASSWORD_TOO_LONG="Password is too long. Passwords must be less than 100 characters." +COM_USERS_MSG_PASSWORD_TOO_SHORT_N="Password is too short. Passwords must have at least %s characters." +COM_USERS_MSG_SPACES_IN_PASSWORD="Password must not have spaces at the beginning or end." +COM_USERS_N_LEVELS_DELETED="%d View Access Levels removed." +COM_USERS_N_LEVELS_DELETED_0="No View Access Levels removed." +COM_USERS_N_LEVELS_DELETED_1="%d View Access Level removed." +COM_USERS_N_USER_NOTES="Display %d notes" +COM_USERS_N_USER_NOTES_1="Display %d note" +COM_USERS_N_USER_NOTES_0="No notes to display" +COM_USERS_N_USERS_ACTIVATED="%s Users activated." +COM_USERS_N_USERS_ACTIVATED_0="No user activated." +COM_USERS_N_USERS_ACTIVATED_1="User activated." +COM_USERS_N_USERS_BLOCKED="%s Users blocked." +COM_USERS_N_USERS_BLOCKED_0="No User blocked." +COM_USERS_N_USERS_BLOCKED_1="User blocked." +COM_USERS_N_USERS_UNBLOCKED="%s Users enabled." +COM_USERS_N_USERS_UNBLOCKED_0="No User enabled." +COM_USERS_N_USERS_UNBLOCKED_1="User enabled." +COM_USERS_NEW_NOTE="New Note" +COM_USERS_NO_ACTION="No Action" +COM_USERS_NO_NOTES="No notes available for this user." +COM_USERS_NO_LEVELS_SELECTED="No Viewing Access Levels selected." +COM_USERS_NOTE_N_SUBJECT="#%d %s" +COM_USERS_NOTES="User Notes: New/Edit" +COM_USERS_NOTES_FOR_USER="Notes for user %s (ID #%d)" +COM_USERS_NOTES_N_ITEMS_ARCHIVED="%d User Notes archived." +COM_USERS_NOTES_N_ITEMS_ARCHIVED_1="%d User Note archived." +COM_USERS_NOTES_N_ITEMS_CHECKED_IN="%d User Notes checked in." +COM_USERS_NOTES_N_ITEMS_CHECKED_IN_1="%d User Note checked in." +COM_USERS_NOTES_N_ITEMS_DELETED="%d User Notes deleted." +COM_USERS_NOTES_N_ITEMS_DELETED_1="%d User Note deleted." +COM_USERS_NOTES_N_ITEMS_PUBLISHED="%d User Notes published." +COM_USERS_NOTES_N_ITEMS_PUBLISHED_1="%d User Note published." +COM_USERS_NOTES_N_ITEMS_TRASHED="%d User Notes trashed." +COM_USERS_NOTES_N_ITEMS_TRASHED_1="%d User Note trashed." +COM_USERS_NOTES_N_ITEMS_UNPUBLISHED="%d User Notes unpublished." +COM_USERS_NOTES_N_ITEMS_UNPUBLISHED_1="%d User Note unpublished." +COM_USERS_OPTION_FILTER_DATE="- Select Registration Date -" +COM_USERS_OPTION_FILTER_LAST_VISIT_DATE="- Select Last Visit Date -" +COM_USERS_OPTION_RANGE_NEVER="never" +COM_USERS_OPTION_RANGE_PAST_1MONTH="in the last month" +COM_USERS_OPTION_RANGE_PAST_3MONTH="in the last 3 months" +COM_USERS_OPTION_RANGE_PAST_6MONTH="in the last 6 months" +COM_USERS_OPTION_RANGE_PAST_WEEK="in the last week" +COM_USERS_OPTION_RANGE_PAST_YEAR="in the last year" +COM_USERS_OPTION_RANGE_POST_YEAR="more than a year ago" +COM_USERS_OPTION_RANGE_TODAY="today" +COM_USERS_OPTION_LEVEL_CATEGORY="%d (top category)" +COM_USERS_OPTION_LEVEL_COMPONENT="%d (component)" +COM_USERS_OPTION_LEVEL_DEEPER="%d (deeper)" +COM_USERS_OPTION_SELECT_COMPONENT="- Select Component -" +COM_USERS_OPTION_SELECT_LEVEL_END="- Select End Level -" +COM_USERS_OPTION_SELECT_LEVEL_START="- Select Start Level -" +COM_USERS_PASSWORD_RESET_REQUIRED="Password Reset Required" +COM_USERS_REQUIRE_PASSWORD_RESET="Require Password Reset" +COM_USERS_REVIEW_HEADING="Review Date" +COM_USERS_SEARCH_ACCESS_LEVELS="Search Viewing Access Levels" +COM_USERS_SEARCH_ASSETS="Search Assets" +COM_USERS_SEARCH_GROUPS_LABEL="Search User Groups" +COM_USERS_SEARCH_IN_GROUPS="Search in group title. Prefix with ID: to search for a group ID." +COM_USERS_SEARCH_IN_NAME="Search in name, username or email. Prefix with ID: to search for a user ID." +COM_USERS_SEARCH_IN_NOTE_TITLE="Search in subject, name or username. Prefix with ID: or UID: to search for a note ID or user ID." +COM_USERS_SEARCH_IN_LEVEL_NAME="Search in level name. Prefix with ID: to search for an access level ID." +COM_USERS_SEARCH_IN_ASSETS="Search in asset name or title." +COM_USERS_SEARCH_TITLE_LEVELS="Search Access Levels" +COM_USERS_SEARCH_USER_NOTES="Search User Notes" +COM_USERS_SEARCH_USERS="Search Users" +COM_USERS_SETTINGS_FIELDSET_LABEL="Basic Settings" +COM_USERS_SUBMENU_GROUPS="User Groups" +COM_USERS_SUBMENU_LEVELS="Viewing Access Levels" +COM_USERS_SUBMENU_NOTES="User Notes" +COM_USERS_SUBMENU_NOTE_CATEGORIES="User Note Categories" +COM_USERS_SUBMENU_USERS="Users" +COM_USERS_SUBJECT_HEADING="Subject" +COM_USERS_TOOLBAR_ACTIVATE="Activate" +COM_USERS_TOOLBAR_BLOCK="Block" +COM_USERS_TOOLBAR_MAIL_SEND_MAIL="Send email" +COM_USERS_TOOLBAR_UNBLOCK="Unblock" +COM_USERS_UNACTIVATED="Unactivated" +COM_USERS_USER_ACCOUNT_DETAILS="Account Details" +COM_USERS_USER_BATCH_FAILED="An error was encountered while performing the batch operation: %s." +COM_USERS_USER_BATCH_SUCCESS="Batch operation completed." +COM_USERS_USER_FIELD_BACKEND_LANGUAGE_DESC="Select the Language for the Administrator Backend interface. This will only affect this User." +COM_USERS_USER_FIELD_BACKEND_LANGUAGE_LABEL="Backend Language" +COM_USERS_USER_FIELD_BACKEND_TEMPLATE_DESC="Select the template style for the Administrator Backend interface. This will only affect this User." +COM_USERS_USER_FIELD_BACKEND_TEMPLATE_LABEL="Backend Template Style" +COM_USERS_USER_FIELD_BLOCK="Blocked" +COM_USERS_USER_FIELD_BLOCK_DESC="Enable or Block this user." +COM_USERS_USER_FIELD_BLOCK_LABEL="User Status" +COM_USERS_USER_FIELD_EDITOR_DESC="Editor for this user." +COM_USERS_USER_FIELD_EDITOR_LABEL="Editor" +COM_USERS_USER_FIELD_EMAIL_DESC="Enter an email address for the user." +COM_USERS_USER_FIELD_ENABLE="Enabled" +COM_USERS_USER_FIELD_FRONTEND_LANGUAGE_DESC="Select the Language for the Frontend interface. This will only affect this User." +COM_USERS_USER_FIELD_FRONTEND_LANGUAGE_LABEL="Frontend Language" +; The following two strings are deprecated and will be removed with 4.0. +COM_USERS_USER_FIELD_HELPSITE_DESC="Help site for this user." +COM_USERS_USER_FIELD_HELPSITE_LABEL="Help Site" +COM_USERS_USER_FIELD_LASTRESET_DESC="Date and time of last password reset." +COM_USERS_USER_FIELD_LASTRESET_LABEL="Last Reset Date" +COM_USERS_USER_FIELD_LASTVISIT_DESC="Last visit date." +COM_USERS_USER_FIELD_LASTVISIT_LABEL="Last Visit Date" +COM_USERS_USER_FIELD_NAME_DESC="Enter the name of the user." +COM_USERS_USER_FIELD_NAME_LABEL="Name" +COM_USERS_USER_FIELD_PASSWORD1_MESSAGE="The passwords you entered do not match. Please enter your desired password in the password field and confirm your entry by entering it in the confirm password field." +COM_USERS_USER_FIELD_PASSWORD2_DESC="Confirm the user's password." +COM_USERS_USER_FIELD_PASSWORD2_LABEL="Confirm Password" +COM_USERS_USER_FIELD_PASSWORD_DESC="Enter the password for the user." +COM_USERS_USER_FIELD_REGISTERDATE_DESC="Registration date." +COM_USERS_USER_FIELD_REGISTERDATE_LABEL="Registration Date" +COM_USERS_USER_FIELD_REQUIRERESET_DESC="Setting this option to yes requires the user to reset their password the next time they log into the site." +COM_USERS_USER_FIELD_REQUIRERESET_LABEL="Require Password Reset" +COM_USERS_USER_FIELD_RESETCOUNT_DESC="Number of password resets since last reset date." +COM_USERS_USER_FIELD_RESETCOUNT_LABEL="Password Reset Count" +COM_USERS_USER_FIELD_SENDEMAIL_DESC="If set to yes, the user will receive system emails." +COM_USERS_USER_FIELD_SENDEMAIL_LABEL="Receive System Emails" +COM_USERS_USER_FIELD_TIMEZONE_DESC="Time zone for this user." +COM_USERS_USER_FIELD_TIMEZONE_LABEL="Time Zone" +COM_USERS_USER_FIELD_TWOFACTOR_LABEL="Authentication Method" +COM_USERS_USER_FIELD_TWOFACTOR_DESC="Which two factor authentication method you want to activate on the user account." +COM_USERS_USER_FIELD_USERNAME_DESC="Enter the login name (Username) for the user." +COM_USERS_USER_FIELD_USERNAME_LABEL="Login Name" +COM_USERS_USER_GROUPS_HAVING_ACCESS="User Groups Having Viewing Access" +COM_USERS_USER_HEADING="User" +COM_USERS_USER_OTEPS="One time emergency passwords" +COM_USERS_USER_OTEPS_DESC="If you do not have access to your two factor authentication device you can use any of the following passwords instead of a regular security code. Each one of these emergency passwords is immediately destroyed upon use. We recommend printing these passwords out and keeping the printout in a safe and accessible location, eg your wallet or a safety deposit box." +COM_USERS_USER_OTEPS_WAIT_DESC="There are no emergency one time passwords generated in your account. The passwords will be generated automatically and displayed here as soon as you activate two factor authentication." +COM_USERS_USER_SAVE_FAILED="An error was encountered while saving the member: %s." +COM_USERS_USER_SAVE_SUCCESS="User saved." +COM_USERS_USER_TWO_FACTOR_AUTH="Two Factor Authentication" +COM_USERS_USERGROUP_DETAILS="User Group Details" +COM_USERS_USERS_ERROR_CANNOT_BLOCK_SELF="You can't block yourself." +COM_USERS_USERS_ERROR_CANNOT_EDIT_OWN_GROUP="You can't edit your own user groups. User groups saving was skipped." +COM_USERS_USERS_ERROR_CANNOT_DELETE_SELF="You can't delete yourself." +COM_USERS_USERS_ERROR_CANNOT_DEMOTE_SELF="You can't remove your own Super User permissions." +COM_USERS_USERS_ERROR_CANNOT_REQUIRERESET_SELF="You can't require a Password reset for yourself." +COM_USERS_USERS_ERROR_CANNOT_SAVE_ACCOUNT_WITHOUT_GROUPS="You can't save a user account without selecting at least one user group." +COM_USERS_USERS_MULTIPLE_GROUPS="Multiple groups" +COM_USERS_USERS_N_ITEMS_DELETED="%d users deleted." +COM_USERS_USERS_N_ITEMS_DELETED_1="1 user deleted." +COM_USERS_USERS_NO_ITEM_SELECTED="No Users selected." +COM_USERS_VIEW_DEBUG_GROUP_TITLE="Advanced Permissions Report for Group #%d, %s" +COM_USERS_VIEW_DEBUG_USER_TITLE="Advanced Permissions Report for User #%d, %s" +COM_USERS_VIEW_EDIT_GROUP_TITLE="Users: Edit Group" +COM_USERS_VIEW_EDIT_LEVEL_TITLE="Users: Edit Viewing Access Level" +COM_USERS_VIEW_EDIT_PROFILE_TITLE="Users: Edit Profile" +COM_USERS_VIEW_EDIT_USER_TITLE="Users: Edit" +COM_USERS_VIEW_GROUPS_TITLE="Users: Groups" +COM_USERS_VIEW_LEVELS_TITLE="Users: Viewing Access Levels" +COM_USERS_VIEW_NEW_GROUP_TITLE="Users: New Group" +COM_USERS_VIEW_NEW_LEVEL_TITLE="Users: New Viewing Access Level" +COM_USERS_VIEW_NEW_USER_TITLE="Users: New" +COM_USERS_VIEW_NOTES_TITLE="User Notes" +COM_USERS_VIEW_USERS_TITLE="Users" +COM_USERS_XML_DESCRIPTION="Component for managing users" +JLIB_RULES_SETTING_NOTES="Changes apply to this component only.
    Inherited - a Global Configuration setting or higher level setting is applied.
    Denied always wins - whatever is set at the Global or higher level and applies to all child elements.
    Allowed will enable the action for this component unless overruled by a Global Configuration setting." +; Categories overrides +COM_CATEGORIES_CATEGORY_ADD_TITLE="User Notes: New Category" +COM_CATEGORIES_CATEGORY_EDIT_TITLE="User Notes: Edit Category" diff --git a/Sites/pages/administrator/language/en-GB/en-GB.com_users.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.com_users.sys.ini new file mode 100644 index 00000000..f3ccb774 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.com_users.sys.ini @@ -0,0 +1,50 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +COM_USERS="Users" +COM_USERS_CONTENT_TYPE_CATEGORY="User Notes Category" +COM_USERS_CONTENT_TYPE_NOTE="User Notes" +COM_USERS_CONTENT_TYPE_USER="User" +COM_USERS_GROUPS_VIEW_DEFAULT_DESC="Shows a List of User Groups" +COM_USERS_GROUPS_VIEW_DEFAULT_TITLE="User Groups" +COM_USERS_GROUP_VIEW_EDIT_DESC="Shows a form to create a new User Group" +COM_USERS_GROUP_VIEW_EDIT_TITLE="Create User Group" +COM_USERS_LEVELS_VIEW_DEFAULT_DESC="Shows a List of Access Levels" +COM_USERS_LEVELS_VIEW_DEFAULT_TITLE="Access Levels" +COM_USERS_LEVEL_VIEW_EDIT_DESC="Shows a form to create a new Access Level" +COM_USERS_LEVEL_VIEW_EDIT_TITLE="Create Access Level" +COM_USERS_MAIL_VIEW_DEFAULT_DESC="Shows a form to send mass email to multiple users." +COM_USERS_MAIL_VIEW_DEFAULT_TITLE="Mass Mail Users" +COM_USERS_NOTES_VIEW_DEFAULT_DESC="Shows a List of User Notes" +COM_USERS_NOTES_VIEW_DEFAULT_TITLE="User Notes" +COM_USERS_NOTE_VIEW_EDIT_DESC="Shows a form to create a new User Note" +COM_USERS_NOTE_VIEW_EDIT_TITLE="Create User Note" +COM_USERS_TAGS_CATEGORY="User Note Category" +COM_USERS_USERS_VIEW_DEFAULT_DESC="Shows a List of Users" +COM_USERS_USERS_VIEW_DEFAULT_TITLE="Users" +COM_USERS_USER_VIEW_EDIT_DESC="Shows a form to create a new User Account" +COM_USERS_USER_VIEW_EDIT_TITLE="Create User" +COM_USER_LOGIN_VIEW_DEFAULT_DESC="Displays a login form." +COM_USER_LOGIN_VIEW_DEFAULT_OPTION="Login Form" +COM_USER_LOGIN_VIEW_DEFAULT_TITLE="Login Form" +COM_USER_LOGOUT_VIEW_DEFAULT_DESC="Direct logout and redirect to page." +COM_USER_LOGOUT_VIEW_DEFAULT_OPTION="Logout" +COM_USER_LOGOUT_VIEW_DEFAULT_TITLE="Logout" +COM_USER_PROFILE_EDIT_DEFAULT_DESC="Edit a user profile." +COM_USER_PROFILE_EDIT_DEFAULT_OPTION="Edit User Profile" +COM_USER_PROFILE_EDIT_DEFAULT_TITLE="Edit User Profile" +COM_USER_PROFILE_VIEW_DEFAULT_DESC="Displays a user profile." +COM_USER_PROFILE_VIEW_DEFAULT_OPTION="User Profile" +COM_USER_PROFILE_VIEW_DEFAULT_TITLE="User Profile" +COM_USER_REGISTRATION_VIEW_DEFAULT_DESC="Displays a registration form." +COM_USER_REGISTRATION_VIEW_DEFAULT_OPTION="Default" +COM_USER_REGISTRATION_VIEW_DEFAULT_TITLE="Registration Form" +COM_USER_REMIND_VIEW_DEFAULT_DESC="Displays a username reminder request." +COM_USER_REMIND_VIEW_DEFAULT_OPTION="Default" +COM_USER_REMIND_VIEW_DEFAULT_TITLE="Username Reminder Request" +COM_USER_RESET_VIEW_DEFAULT_DESC="Displays a request to reset password." +COM_USER_RESET_VIEW_DEFAULT_OPTION="Default" +COM_USER_RESET_VIEW_DEFAULT_TITLE="Password Reset" +COM_USERS_XML_DESCRIPTION="Component for managing users." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.com_weblinks.ini b/Sites/pages/administrator/language/en-GB/en-GB.com_weblinks.ini new file mode 100644 index 00000000..d4331053 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.com_weblinks.ini @@ -0,0 +1,133 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +COM_WEBLINKS="Web Links" +COM_WEBLINKS_ACCESS_HEADING="Access" +COM_WEBLINKS_BATCH_OPTIONS="Batch process the selected links" +COM_WEBLINKS_BATCH_TIP="If a category is selected for move/copy, any actions selected will be applied to the copied or moved links. Otherwise, all actions are applied to the selected links." +COM_WEBLINKS_CATEGORIES_DESC="These settings apply for Web Links Categories Options unless they are changed for a specific menu item." +COM_WEBLINKS_CATEGORY_DESC="These settings apply for Web Links Category Options unless they are changed for a specific menu item." +COM_WEBLINKS_CHANGE_WEBLINK="Select or Change Web Link" +COM_WEBLINKS_COMPONENT_DESC="These settings apply for Web Links unless they are changed for a specific menu item or web link." +COM_WEBLINKS_COMPONENT_LABEL="Web Link" +COM_WEBLINKS_CONFIG_INTEGRATION_SETTINGS_DESC="These settings determine how the Web Links Component will integrate with other extensions." +COM_WEBLINKS_CONFIGURATION="Web Links Manager Options" +COM_WEBLINKS_EDIT_WEBLINK="Edit Web Link" +COM_WEBLINKS_ERR_TABLES_NAME="There is already a Web Link with that name in this category. Please try again." +COM_WEBLINKS_ERR_TABLES_PROVIDE_URL="Please provide a valid URL" +COM_WEBLINKS_ERR_TABLES_TITLE="Your web link must have a title." +COM_WEBLINKS_ERROR_UNIQUE_ALIAS="Another web link from this category has the same alias (remember it may be a trashed item)." +COM_WEBLINKS_FIELD_ALIAS_DESC="The alias is for internal use only. Leave this blank and Joomla will fill in a default value from the title. It has to be unique for each web link in the same category." +COM_WEBLINKS_FIELD_CATEGORY_DESC="Choose a category for this Web link." +COM_WEBLINKS_FIELD_CATEGORYCHOOSE_DESC="Please choose a Web Links category to display." +COM_WEBLINKS_FIELD_CAPTCHA_DESC="Select the captcha plugin that will be used in the web link submit form. You may need to enter required information for your captcha plugin in the Plugin Manager.
    If 'Use Default' is selected, make sure a captcha plugin is selected in Global Configuration." +COM_WEBLINKS_FIELD_CAPTCHA_LABEL="Allow Captcha on Web Link" +COM_WEBLINKS_FIELD_CONFIG_CAT_SHOWNUMBERS_DESC="Show or hide the number of Web Links in each Category." +COM_WEBLINKS_FIELD_CONFIG_CAT_SHOWNUMBERS_LABEL="# Web Links" +COM_WEBLINKS_FIELD_CONFIG_COUNTCLICKS_DESC="If set to yes, the number of times the link has been clicked will be recorded." +COM_WEBLINKS_FIELD_CONFIG_COUNTCLICKS_LABEL="Count Clicks" +COM_WEBLINKS_FIELD_CONFIG_DESCRIPTION_DESC="Show or hide the description below." +COM_WEBLINKS_FIELD_CONFIG_HITS_DESC="Show or hide hits." +COM_WEBLINKS_FIELD_CONFIG_ICON_DESC="If Icon is chosen above, select an icon to display with the Web Links. If none is selected, the default icon will be used." +COM_WEBLINKS_FIELD_CONFIG_ICON_LABEL="Select Icon" +COM_WEBLINKS_FIELD_CONFIG_LINKDESCRIPTION_DESC="Show or hide the links description." +COM_WEBLINKS_FIELD_CONFIG_LINKDESCRIPTION_LABEL="Links Description" +COM_WEBLINKS_FIELD_CONFIG_OTHERCATS_DESC="Show or hide other categories." +COM_WEBLINKS_FIELD_CONFIG_OTHERCATS_LABEL="Other Categories" +COM_WEBLINKS_FIELD_CONFIG_SHOWREPORT_DESC="Show or hide the Report Bad Link option." +COM_WEBLINKS_FIELD_CONFIG_SHOWREPORT_LABEL="Reports" +COM_WEBLINKS_FIELD_COUNTCLICKS_DESC="If set to yes, the number of times the link has been clicked will be recorded." +COM_WEBLINKS_FIELD_COUNTCLICKS_LABEL="Count Clicks" +COM_WEBLINKS_FIELD_DESCRIPTION_DESC="Enter a description for the web link." +COM_WEBLINKS_FIELD_DISPLAY_NUM_DESC="Default number of Web links to list on a page." +COM_WEBLINKS_FIELD_DISPLAY_NUM_LABEL="# of Web links to List" +COM_WEBLINKS_FIELD_FIRST_DESC="The image to be displayed." +COM_WEBLINKS_FIELD_FIRST_LABEL="First Image" + +COM_WEBLINKS_FIELD_HEIGHT_DESC="Height of the target popup or modal window. Defaults to 600x500 if one field is left empty." +COM_WEBLINKS_FIELD_HEIGHT_LABEL="Height" +COM_WEBLINKS_FIELD_ICON_DESC="Displays a text, an icon or nothing with the Web links. Default is 'Icon'." +COM_WEBLINKS_FIELD_ICON_LABEL="Text/Icon/Web Link Only" +COM_WEBLINKS_FIELD_ICON_OPTION_ICON="Icon" +COM_WEBLINKS_FIELD_ICON_OPTION_TEXT="Text" +COM_WEBLINKS_FIELD_ICON_OPTION_WEBLINK="Web Link Only" +COM_WEBLINKS_FIELD_IMAGE_ALT_DESC="Alternative text used for visitors without access to images. Replaced with caption text if it is present." +COM_WEBLINKS_FIELD_IMAGE_ALT_LABEL="Alt Text" +COM_WEBLINKS_FIELD_IMAGE_CAPTION_DESC="Caption attached to the image." +COM_WEBLINKS_FIELD_IMAGE_CAPTION_LABEL="Caption" + +COM_WEBLINKS_FIELD_LANGUAGE_DESC="Assign a language to this web link." +COM_WEBLINKS_FIELD_MODIFIED_DESC="The date and time the link was last modified." +COM_WEBLINKS_FIELD_SECOND_DESC="The second image to be displayed." +COM_WEBLINKS_FIELD_SECOND_LABEL="Second Image" +COM_WEBLINKS_FIELD_SELECT_CATEGORY_DESC="Select a web links category to display." +COM_WEBLINKS_FIELD_SELECT_CATEGORY_LABEL="Select a Category" +COM_WEBLINKS_FIELD_SHOW_CAT_TAGS_DESC="Show the tags for a category." +COM_WEBLINKS_FIELD_SHOW_CAT_TAGS_LABEL="Show Tags" +COM_WEBLINKS_FIELD_SHOW_TAGS_DESC="Show the tags for a web link." +COM_WEBLINKS_FIELD_SHOW_TAGS_LABEL="Show Tags" +COM_WEBLINKS_FIELD_STATE_DESC="Set publication status." +COM_WEBLINKS_FIELD_TARGET_DESC="Target browser window when the link is selected." +COM_WEBLINKS_FIELD_TARGET_LABEL="Target" +COM_WEBLINKS_FIELD_TITLE_DESC="Web Link must have a title." +COM_WEBLINKS_FIELD_URL_DESC="You must enter a URL. IDN (International) Links are converted to punycode when they are saved." +COM_WEBLINKS_FIELD_URL_LABEL="URL" +COM_WEBLINKS_FIELD_VALUE_REPORTED="Reported" +COM_WEBLINKS_FIELD_VERSION_DESC="A count of the number of times this web link has been revised." +COM_WEBLINKS_FIELD_VERSION_LABEL="Revision" +COM_WEBLINKS_FIELD_WIDTH_DESC="Width of the target popup or modal window. Defaults to 600x500 if one field is left empty." +COM_WEBLINKS_FIELD_WIDTH_LABEL="Width" +COM_WEBLINKS_FIELDSET_IMAGES="Images" +COM_WEBLINKS_FIELDSET_OPTIONS="Options" +COM_WEBLINKS_FILTER_CATEGORY="Filter Category" +COM_WEBLINKS_FILTER_SEARCH_DESC="Search in web link title and alias. Prefix with ID: to search for a web link ID." +COM_WEBLINKS_FILTER_SEARCH_LABEL="Search Web Links" +COM_WEBLINKS_FILTER_STATE="Filter State" +COM_WEBLINKS_FLOAT_FIRST_DESC="Controls placement of the first image." +COM_WEBLINKS_FLOAT_FIRST_LABEL="First Image Float" +COM_WEBLINKS_FLOAT_SECOND_DESC="Controls placement of the second image." +COM_WEBLINKS_FLOAT_SECOND_LABEL="Second Image Float" +COM_WEBLINKS_HEADING_ASSOCIATION="Association" +COM_WEBLINKS_HITS_DESC="Number of hits for this web link." +COM_WEBLINKS_LEFT="Left" +COM_WEBLINKS_LIST_LAYOUT_DESC="These settings apply for Web Links List Layout Options unless they are changed for a specific menu item." +COM_WEBLINKS_MANAGER_WEBLINK="Web Links" +COM_WEBLINKS_MANAGER_WEBLINKS="Web Links" +COM_WEBLINKS_MANAGER_WEBLINK_EDIT="Web Link: Edit" +COM_WEBLINKS_MANAGER_WEBLINK_NEW="Web Link: New" +COM_WEBLINKS_N_ITEMS_ARCHIVED="%d web links archived." +COM_WEBLINKS_N_ITEMS_ARCHIVED_1="%d web link archived." +COM_WEBLINKS_N_ITEMS_CHECKED_IN_0="No web link checked in." +COM_WEBLINKS_N_ITEMS_CHECKED_IN_1="%d web link checked in." +COM_WEBLINKS_N_ITEMS_CHECKED_IN_MORE="%d web links checked in." +COM_WEBLINKS_N_ITEMS_DELETED="%d web links deleted." +COM_WEBLINKS_N_ITEMS_DELETED_1="%d web link deleted." +COM_WEBLINKS_N_ITEMS_PUBLISHED="%d web links published." +COM_WEBLINKS_N_ITEMS_PUBLISHED_1="%d web link published." +COM_WEBLINKS_N_ITEMS_TRASHED="%d web links trashed." +COM_WEBLINKS_N_ITEMS_TRASHED_1="%d web link trashed." +COM_WEBLINKS_N_ITEMS_UNPUBLISHED="%d web links unpublished." +COM_WEBLINKS_N_ITEMS_UNPUBLISHED_1="%d web link unpublished." +COM_WEBLINKS_NEW_WEBLINK="New Web Link" +COM_WEBLINKS_NONE="None" +COM_WEBLINKS_OPTION_FILTER_ACCESS="- Filter Access -" +COM_WEBLINKS_OPTION_FILTER_CATEGORY="- Filter Category -" +COM_WEBLINKS_OPTION_FILTER_PUBLISHED="- Filter State -" +COM_WEBLINKS_OPTIONS="Options" +COM_WEBLINKS_ORDER_HEADING="Order" +COM_WEBLINKS_RIGHT="Right" +COM_WEBLINKS_SAVE_SUCCESS="Web link saved" +COM_WEBLINKS_SEARCH_IN_TITLE="Search in title" +COM_WEBLINKS_SELECT_A_WEBLINK="Select Web Link" +COM_WEBLINKS_SHOW_EMPTY_CATEGORIES_DESC="If Show, empty categories will display. A category is only empty if it has no Web links or subcategories." +COM_WEBLINKS_SUBMENU_CATEGORIES="Categories" +COM_WEBLINKS_SUBMENU_WEBLINKS="Web Links" +COM_WEBLINKS_WEBLINKS="Web Links" +COM_WEBLINKS_XML_DESCRIPTION="Component for web links management" +JGLOBAL_NO_ITEM_SELECTED="No web links selected" +JGLOBAL_NEWITEMSLAST_DESC="New Web links default to the last position. Ordering can be changed after this Web link is saved." +JLIB_APPLICATION_ERROR_BATCH_CANNOT_CREATE="You are not allowed to create new web links in this category." +JLIB_APPLICATION_ERROR_BATCH_CANNOT_EDIT="You are not allowed to edit one or more of these web links." +JLIB_RULES_SETTING_NOTES="Changes apply to this component only.
    Inherited - a Global Configuration setting or higher level setting is applied.
    Denied always wins - whatever is set at the Global or higher level and applies to all child elements.
    Allowed will enable the action for this component unless overruled by a Global Configuration setting." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.com_weblinks.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.com_weblinks.sys.ini new file mode 100644 index 00000000..170e5ba7 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.com_weblinks.sys.ini @@ -0,0 +1,25 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +COM_WEBLINKS="Web Links" +COM_WEBLINKS_CATEGORIES="Categories" +COM_WEBLINKS_CATEGORIES_VIEW_DEFAULT_DESC="Show all the web link categories within a category." +COM_WEBLINKS_CATEGORIES_VIEW_DEFAULT_OPTION="Default" +COM_WEBLINKS_CATEGORIES_VIEW_DEFAULT_TITLE="List All Web Link Categories" +COM_WEBLINKS_CATEGORY_ADD_TITLE="Category Manager: Add A New Web Links Category" +COM_WEBLINKS_CATEGORY_EDIT_TITLE="Category Manager: Edit A Web Links Category" +COM_WEBLINKS_CATEGORY_VIEW_DEFAULT_DESC="Displays a list of Web Links for a category." +COM_WEBLINKS_CATEGORY_VIEW_DEFAULT_OPTION="Default" +COM_WEBLINKS_CATEGORY_VIEW_DEFAULT_TITLE="List Web Links in a Category" +COM_WEBLINKS_CONTENT_TYPE_WEBLINK="Web Link" +COM_WEBLINKS_CONTENT_TYPE_CATEGORY="Web Links Category" +COM_WEBLINKS_FORM_VIEW_DEFAULT_DESC="Display a form to submit a web link in the Frontend." +COM_WEBLINKS_FORM_VIEW_DEFAULT_OPTION="Default" +COM_WEBLINKS_FORM_VIEW_DEFAULT_TITLE="Submit a Web Link" +COM_WEBLINKS_LINKS="Links" +COM_WEBLINKS_TAGS_WEBLINK="Web Link" +COM_WEBLINKS_TAGS_CATEGORY="Web Link Category" +COM_WEBLINKS_XML_DESCRIPTION="Component for web links management." + diff --git a/Sites/pages/administrator/language/en-GB/en-GB.com_wrapper.ini b/Sites/pages/administrator/language/en-GB/en-GB.com_wrapper.ini new file mode 100644 index 00000000..635f2314 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.com_wrapper.ini @@ -0,0 +1,22 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +COM_WRAPPER="Wrapper" +COM_WRAPPER_FIELD_ADD_DESC="By default, http:// will be added unless it detects http:// or https:// in the URL you provide. This allows you to switch off this functionality." +COM_WRAPPER_FIELD_ADD_LABEL="Auto Add" +COM_WRAPPER_FIELD_FRAME_DESC="Show frame border which wrap the iframe." +COM_WRAPPER_FIELD_FRAME_LABEL="Frame Border" +COM_WRAPPER_FIELD_HEIGHT_DESC="Height of the iframe window in pixels." +COM_WRAPPER_FIELD_HEIGHT_LABEL="Height" +COM_WRAPPER_FIELD_HEIGHTAUTO_DESC="If height is set to auto, the height will automatically be set to the size of the external page. This will only work for pages on your own domain. If you see a JavaScript error, make sure this parameter is disabled. This will break XHTML compatibility for this page." +COM_WRAPPER_FIELD_HEIGHTAUTO_LABEL="Auto Height" +COM_WRAPPER_FIELD_LABEL_SCROLLBARSPARAMS="Scroll Bar Parameters" +COM_WRAPPER_FIELD_SCROLLBARS_DESC="Show or hide the horizontal & vertical scrollbars. If you choose 'Auto', make sure the Auto advanced parameter is set." +COM_WRAPPER_FIELD_SCROLLBARS_LABEL="Scroll Bars" +COM_WRAPPER_FIELD_URL_DESC="URL to site/file you wish to display within the iframe." +COM_WRAPPER_FIELD_URL_LABEL="URL" +COM_WRAPPER_FIELD_VALUE_AUTO="Auto" +COM_WRAPPER_FIELD_WIDTH_DESC="Width of the iframe window. You may enter an absolute figure in pixels or a relative figure by adding a %." +COM_WRAPPER_XML_DESCRIPTION="Displays an iframe to wrap an external page or site into Joomla!" diff --git a/Sites/pages/administrator/language/en-GB/en-GB.com_wrapper.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.com_wrapper.sys.ini new file mode 100644 index 00000000..7cd0fa28 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.com_wrapper.sys.ini @@ -0,0 +1,10 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +COM_WRAPPER="Wrapper" +COM_WRAPPER_XML_DESCRIPTION="Displays an iframe to wrap an external page or site into Joomla!" +COM_WRAPPER_WRAPPER_VIEW_DEFAULT_DESC="Displays a URL in an iframe." +COM_WRAPPER_WRAPPER_VIEW_DEFAULT_OPTION="Default" +COM_WRAPPER_WRAPPER_VIEW_DEFAULT_TITLE="Iframe Wrapper" diff --git a/Sites/pages/administrator/language/en-GB/en-GB.ini b/Sites/pages/administrator/language/en-GB/en-GB.ini new file mode 100644 index 00000000..d257d79e --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.ini @@ -0,0 +1,1102 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +; Common boolean values +; Note: YES, NO, TRUE, FALSE are reserved words in INI format. + +; Keep this string on top +JERROR_PARSING_LANGUAGE_FILE=" : error(s) in line(s) %s" + +J1="1" +J2="2" +J3="3" +J4="4" +J5="5" +J6="6" +J7="7" +J8="8" +J9="9" +J10="10" +J15="15" +J20="20" +J25="25" +J30="30" +J50="50" +J75="75" +J100="100" +J150="150" +J200="200" +J250="250" +J300="300" +J500="500" + +JH1="h1" +JH2="h2" +JH3="h3" +JH4="h4" +JH5="h5" +JH6="h6" + +ERROR="Error" +INFO="Info" +MESSAGE="Message" +NOTICE="Notice" +WARNING="Warning" + +JADMINISTRATION="Administration" +JADMINISTRATOR="Administrator" +JALL="All" +JALL_LANGUAGE="All" +JAPPLY="Save" +JARCHIVED="Archived" +JAUTHOR="Author" +JAUTHOR_ASC="Author ascending" +JAUTHOR_DESC="Author descending" +JASSOCIATIONS_ASC="Associations ascending" +JASSOCIATIONS_DESC="Associations descending" +JCANCEL="Cancel" +JCATEGORIES="Categories" +JCATEGORY="Category" +JCATEGORY_ASC="Category ascending" +JCATEGORY_DESC="Category descending" +JCATEGORY_SPRINTF="Category: %s" +JCLEAR="Clear" +JCLIENT="Location" +JCONFIG_PERMISSIONS_DESC="Default permissions used for all content in this component." +JCONFIG_PERMISSIONS_LABEL="Permissions" +JCURRENT="Current" +JDATE="Date" +JDATE_ASC="Date ascending" +JDATE_DESC="Date descending" +JDAY="Day" +JDEFAULT="Default" +JDEFAULTLANGUAGE="Language - Default" +JDETAILS="Details" +JDISABLED="Disabled" +JENABLED="Enabled" +JFALSE="False" +JFEATURED="Featured" +JFEATURED_ASC="Featured ascending" +JFEATURED_DESC="Featured descending" +JUNFEATURED="Unfeatured" +JFEATURE="Feature" +JUNFEATURE="Unfeature" +JHELP="Help" +JHIDE="Hide" +JINVALID_TOKEN="The most recent request was denied because it had an invalid security token. Please refresh the page and try again." +JINVALID_TOKEN_NOTICE="The security token did not match. The request was aborted to prevent any security breach. Please try again." +JLOGIN="Log in" +JLOGOUT="Log out" +JMENU_MULTILANG_WARNING_MISSING_MODULES="An administrator menu module for %s does not exist.
    Create a custom administrator menu and module for each administrator language or publish a menu module set to All languages." +JMODIFY="Modify" +JMONTH="Month" +JMONTH_PUBLISHED="Month (published)" +JNEVER="Never" +JNEXT="Next" +JNEXT_TITLE="Next article: %s" +JNO="No" +JNONE="None" +JOFF="Off" +JON="On" +JONLY="Only" +JOPTIONS="Options" +JPREV="Prev" +JPREVIOUS="Previous" +JPREVIOUS_TITLE="Previous article: %s" +JPROTECTED="Protected" +JPUBLISHED="Published" +JRECORD_NUMBER="Record Number" +JREGISTER="Register" +JORDERINGDISABLED="Please sort by order to enable reordering" +JSAVE="Save & Close" +JSELECT="Select" +JSTATUS="Status" +JSTATUS_ASC="Status ascending" +JSTATUS_DESC="Status descending" +JSHOW="Show" +JSITE="Site" +JSUBMIT="Submit" +JTAG="Tags" +JTAG_DESC="Assign tags to content items. You may select a tag from the pre-defined list or enter a new tag by typing the name in the field and pressing enter." +JTAG_FIELD_SELECT_DESC="Select the tag to use." +JTOOLBAR="Toolbar" +JTRASH="Trash" +JTRASHED="Trashed" +JTRUE="True" +JUNARCHIVE="Remove from archive status" +JUNDEFINED="Undefined" +JUNPROTECTED="Unprotected" +JUNPUBLISHED="Unpublished" +JYEAR="Year" +JVERSION="Version" +JYES="Yes" +JACTIONS="Actions for: %s" + +JACTION_ADMIN="Configure ACL & Options" +JACTION_ADMIN_COMPONENT_DESC="Allows users in the group to edit the options and permissions of this extension." +JACTION_ADMIN_GLOBAL="Super User" +JACTION_ADMIN_GLOBAL_DESC="Allows users in the group to perform any action regardless of the settings." +JACTION_COMPONENT_SETTINGS="Component Settings" +JACTION_CREATE="Create" +JACTION_CREATE_COMPONENT_DESC="Allows users in the group to create any content in this extension." +JACTION_DELETE="Delete" +JACTION_DELETE_COMPONENT_DESC="Allows users in the group to delete any content in this extension." +JACTION_EDIT="Edit" +JACTION_EDIT_COMPONENT_DESC="Allows users in the group to edit any content in this extension." +JACTION_EDITOWN="Edit Own" +JACTION_EDITOWN_COMPONENT_DESC="Allows users in the group to edit any content they submitted in this extension." +JACTION_EDITVALUE="Edit Custom Field Value" +JACTION_EDITVALUE_COMPONENT_DESC="Allows users in the group to edit any value of custom fields submitted in this extension." +JACTION_EDITSTATE="Edit State" +JACTION_EDITSTATE_COMPONENT_DESC="Allows users in the group to change the state of any content in this extension." +JACTION_LOGIN_ADMIN="Administrator Login" +JACTION_LOGIN_OFFLINE="Offline Access" +JACTION_LOGIN_SITE="Site Login" +JACTION_MANAGE="Access Administration Interface" +JACTION_MANAGE_COMPONENT_DESC="Allows users in the group to access the administration interface for this extension." +JACTION_OPTIONS="Configure Options Only" +JACTION_OPTIONS_COMPONENT_DESC="Allows users in the group to edit the options except the permissions of this extension." + +JBROWSERTARGET_MODAL="Modal" +JBROWSERTARGET_NEW="Open in new window" +JBROWSERTARGET_PARENT="Open in parent window" +JBROWSERTARGET_POPUP="Open in popup" + +JERROR_ALERTNOAUTHOR="You are not authorised to view this resource." +JERROR_ALERTNOTEMPLATE="The template for this display is not available." +JERROR_AN_ERROR_HAS_OCCURRED="An error has occurred." +JERROR_CORE_CREATE_NOT_PERMITTED="Create not permitted." +JERROR_CORE_DELETE_NOT_PERMITTED="Delete not permitted." +JERROR_COULD_NOT_FIND_TEMPLATE="Could not find template "_QQ_"%s"_QQ_"." +JERROR_INVALID_CONTROLLER="Invalid controller" +JERROR_INVALID_CONTROLLER_CLASS="Invalid controller class" +JERROR_LAYOUT_PREVIOUS_ERROR="Previous Error" +JERROR_LOADFILE_FAILED="Error loading form file" +JERROR_LOADING_MENUS="Error loading Menus: %s" +JERROR_LOGIN_DENIED="You do not have access to the Administrator section of this site." +JERROR_MAGIC_QUOTES="Your host needs to disable magic_quotes_gpc to run this version of Joomla!" +JERROR_NO_ITEMS_SELECTED="No item(s) selected." +JERROR_NOLOGIN_BLOCKED="Login denied! Your account has either been blocked or you have not activated it yet." +JERROR_SENDING_EMAIL="Email could not be sent." +JERROR_SESSION_STARTUP="Error starting the session." +JERROR_SAVE_FAILED="Could not save data. Error: %s" + +JFIELD_ACCESS_DESC="The access level group that is allowed to view this item." +JFIELD_ACCESS_LABEL="Access" +JFIELD_ALIAS_DESC="The Alias will be used in the SEF URL. Leave this blank and Joomla will fill in a default value from the title. This value will depend on the SEO settings (Global Configuration->Site).
    Using Unicode will produce UTF-8 aliases. You may also enter manually any UTF-8 character. Spaces and some forbidden characters will be changed to hyphens.
    When using default transliteration it will produce an alias in lower case and with dashes instead of spaces. You may enter the Alias manually. Use lowercase letters and hyphens (-). No spaces or underscores are allowed. Default value will be a date and time if the title is typed in non-latin letters." +JFIELD_ALIAS_LABEL="Alias" +JFIELD_ALIAS_PLACEHOLDER="Auto-generate from title" +JFIELD_ALT_COMPONENT_LAYOUT_DESC="Use a layout from the supplied component view or overrides in the templates." +JFIELD_ALT_LAYOUT_LABEL="Layout" +JFIELD_ALT_MODULE_LAYOUT_DESC="Use a layout from the supplied module or overrides in the templates." +JFIELD_ALT_PAGE_TITLE_DESC="An optional alternative page title to set that will change the TITLE tag in the HTML output." +JFIELD_ALT_PAGE_TITLE_LABEL="Alternative Page Title" +JFIELD_ASSET_ID_DESC="Asset ID" +JFIELD_ASSET_ID_LABEL="Asset ID" +JFIELD_BASIS_LOGIN_DESCRIPTION_DESC="Text to display on login page." +JFIELD_BASIS_LOGIN_DESCRIPTION_LABEL="Login Description Text" +JFIELD_BASIS_LOGIN_DESCRIPTION_SHOW_DESC="Show or hide login description." +JFIELD_BASIS_LOGIN_DESCRIPTION_SHOW_LABEL="Login Description" +JFIELD_BASIS_LOGOUT_DESCRIPTION_DESC="Text for logout page." +JFIELD_BASIS_LOGOUT_DESCRIPTION_LABEL="Logout Description Text" +JFIELD_BASIS_LOGOUT_DESCRIPTION_SHOW_DESC="Show or hide logout description." +JFIELD_BASIS_LOGOUT_DESCRIPTION_SHOW_LABEL="Logout Description" +JFIELD_CATEGORY_DESC="The category that this item is assigned to. You may select an existing category or enter a new category by typing the name in the field and pressing enter." +JFIELD_DISPLAY_READONLY_DESC="Whether to display the field on forms when read-only. Inherit defaults to value set in field group." +JFIELD_DISPLAY_READONLY_LABEL="Display When Read-Only" +JFIELD_ENABLED_DESC="The enabled status of this item." +JFIELD_FIELDS_CATEGORY_DESC="Select the category that this field is assigned to." +JFIELD_KEY_REFERENCE_DESC="Used to store information referring to an external resource." +JFIELD_KEY_REFERENCE_LABEL="Key Reference" +JFIELD_LANGUAGE_DESC="Assign a language to this article." +JFIELD_LANGUAGE_LABEL="Language" +JFIELD_LOGIN_IMAGE_DESC="Select or upload an image to display on login page." +JFIELD_LOGIN_IMAGE_LABEL="Login Image" +JFIELD_LOGIN_REDIRECT_URL_DESC="If a URL is entered here, users will be redirected to it after login.
    The URL must be internal (eg: index.php?Itemid=999)." +JFIELD_LOGIN_REDIRECT_URL_LABEL="Login Redirect" +JFIELD_LOGOUT_IMAGE_DESC="Select or upload an image to display on logout page." +JFIELD_LOGOUT_IMAGE_LABEL="Logout Image" +JFIELD_LOGOUT_REDIRECT_URL_DESC="If a URL is entered here, users will be redirected to it after logout.
    The URL must be internal (eg: index.php?Itemid=999)." +JFIELD_LOGOUT_REDIRECT_URL_LABEL="Logout Redirect" +JFIELD_LOGOUT_REDIRECT_PAGE_DESC="Select or create the page the user will be redirected to after ending their current session by logging out. The default is to stay on the same page." +JFIELD_LOGOUT_REDIRECT_PAGE_LABEL="Logout Redirection Page" +JFIELD_META_DESCRIPTION_DESC="An optional paragraph to be used as the description of the page in the HTML output. This will generally display in the results of search engines." +JFIELD_META_DESCRIPTION_LABEL="Meta Description" +JFIELD_META_KEYWORDS_DESC="An optional comma-separated list of keywords and/or phrases to be used in the HTML output." +JFIELD_META_KEYWORDS_LABEL="Meta Keywords" +JFIELD_META_RIGHTS_DESC="Describe what rights others have to use this content." +JFIELD_META_RIGHTS_LABEL="Content Rights" +JFIELD_METADATA_AUTHOR_DESC="The author of this content." +JFIELD_METADATA_RIGHTS_DESC="Publication rights for the content." +JFIELD_METADATA_RIGHTS_LABEL="Rights" +JFIELD_METADATA_ROBOTS_DESC="Robots instructions." +JFIELD_METADATA_ROBOTS_LABEL="Robots" +JFIELD_METADATA_XREFERENCE_DESC="An optional reference used to link to external data sources." +JFIELD_METADATA_XREFERENCE_LABEL="Cross Reference" +JFIELD_MODULE_LANGUAGE_DESC="Assign a language to this module." +JFIELD_NAME_DESC="The name will be used to identify the field. Leave this blank and Joomla will fill in a default value from the title." +JFIELD_NAME_LABEL="Name" +JFIELD_NAME_PLACEHOLDER="Auto-generate from title" +JFIELD_NOTE_DESC="Note" +JFIELD_NOTE_LABEL="Note" +JFIELD_OPTION_NONE="None" +JFIELD_ORDERING_DESC="Select the ordering." +JFIELD_ORDERING_LABEL="Ordering" +JFIELD_PARAMS_LABEL="Options" +JFIELD_PLG_SEARCH_ALL_DESC="Include published items in the search." +JFIELD_PLG_SEARCH_ALL_LABEL="Search Published" +JFIELD_PLG_SEARCH_ARCHIVED_DESC="Include archived items in the search." +JFIELD_PLG_SEARCH_ARCHIVED_LABEL="Search Archived" +JFIELD_PLG_SEARCH_SEARCHLIMIT_DESC="Sets the maximum number of results to return." +JFIELD_PLG_SEARCH_SEARCHLIMIT_LABEL="Search Limit" +JFIELD_PUBLISHED_DESC="Set publication status." +JFIELD_READMORE_DESC="Add a custom text instead of Read More." +JFIELD_READMORE_LABEL="Read More Text" +JFIELD_SPACER_LABEL="
    " +JFIELD_TITLE_DESC="Title" +JFIELD_VERSION_HISTORY_DESC="This button allows you to open a window to view older versions of this item." +JFIELD_VERSION_HISTORY_LABEL="Prior Versions" +JFIELD_VERSION_HISTORY_SELECT="View Prior Versions" +JFIELD_XREFERENCE_DESC="An optional field to allow this record to be cross-referenced to an external data system if required." +JFIELD_XREFERENCE_LABEL="External Reference" +JGLOBAL_ACROSS="Across" +JGLOBAL_ACTION_PERMISSIONS_LABEL="Permissions" +JGLOBAL_ACTION_PERMISSIONS_DESCRIPTION="Set the action permissions for this asset" +JGLOBAL_ADD_CUSTOM_CATEGORY="Add new Category" +JGLOBAL_ALL_ARTICLE="Max Levels Articles" +JGLOBAL_ALL_LIST="Max Levels as List" +JGLOBAL_ALLOW_COMMENTS_DESC="If Yes, viewers will be able to add and view comments for the article." +JGLOBAL_ALLOW_COMMENTS_LABEL="Allow Comments" +JGLOBAL_ALLOW_RATINGS_DESC="If Yes, viewers will be able to add and view ratings for the article." +JGLOBAL_ALLOW_RATINGS_LABEL="Allow Ratings" +JGLOBAL_ARCHIVE_ARTICLES_FIELD_INTROTEXTLIMIT_DESC="Please enter in a numeric character limit value. The introtext will be trimmed to the number of characters you enter." +JGLOBAL_ARCHIVE_ARTICLES_FIELD_INTROTEXTLIMIT_LABEL="Intro text Limit" +JGLOBAL_ARCHIVE_OPTIONS="Archive" +JGLOBAL_ARTICLE_COUNT_DESC="Show or hide a count of articles in each category." +JGLOBAL_ARTICLE_COUNT_LABEL="Article Count" +JGLOBAL_ARTICLE_MANAGER_ORDER="Ordering" +JGLOBAL_ARTICLE_MANAGER_REVERSE_ORDER="Ordering Reverse" +JGLOBAL_ARTICLE_ORDER_DESC="The order that articles will show in." +JGLOBAL_ARTICLE_ORDER_LABEL="Article Order" +JGLOBAL_ARTICLES="Articles" +JGLOBAL_ASSOC_NOT_POSSIBLE="To define associations, please make sure the item language is not set to 'All'." +JGLOBAL_ASSOCIATIONS_NEW_ITEM_WARNING="To create associations, first save the item." +JGLOBAL_ASSOCIATIONS_PROPAGATE_BUTTON="Propagate" +JGLOBAL_ASSOCIATIONS_PROPAGATE_FAILED="Failed propagating associations. You may have to select or create them manually." +JGLOBAL_ASSOCIATIONS_PROPAGATE_MESSAGE_ALL="All existing associations have been set." +JGLOBAL_ASSOCIATIONS_PROPAGATE_MESSAGE_NONE="No associations exist to propagate." +JGLOBAL_ASSOCIATIONS_PROPAGATE_MESSAGE_SOME="Associations have been set for: %s" +JGLOBAL_ASSOCIATIONS_PROPAGATE_TIP="Propagates this item's existing associations." +JGLOBAL_ASSOCIATIONS_RESET_WARNING="The language has been changed. If you save this item again it will reset the available associations. If this was not intended, close the item." +JGLOBAL_AUTH_ACCESS_DENIED="Access Denied" +JGLOBAL_AUTH_ACCESS_GRANTED="Access Granted" +JGLOBAL_AUTH_BIND_FAILED="Failed binding to LDAP server" +JGLOBAL_AUTH_CANCEL="Authentication cancelled" +JGLOBAL_AUTH_CURL_NOT_INSTALLED="Curl isn't installed" +JGLOBAL_AUTH_EMPTY_PASS_NOT_ALLOWED="Empty password not allowed." +JGLOBAL_AUTH_FAIL="Authentication failed" +JGLOBAL_AUTH_FAILED="Failed to authenticate: %s" +JGLOBAL_AUTH_INCORRECT="Incorrect username/password" +JGLOBAL_AUTH_INVALID_PASS="Username and password do not match or you do not have an account yet." +JGLOBAL_AUTH_INVALID_SECRETKEY="The two factor authentication Secret Key is invalid." +; The following 2 strings are deprecated and will be removed with 4.0. +JGLOBAL_AUTH_NO_BIND="Unable to bind to LDAP" +JGLOBAL_AUTH_NO_CONNECT="Unable to connect to LDAP server" +JGLOBAL_AUTH_NO_REDIRECT="Could not redirect to server: %s" +JGLOBAL_AUTH_NO_USER="Username and password do not match or you do not have an account yet." +JGLOBAL_AUTH_NOT_CONNECT="Unable to connect to authentication service." +JGLOBAL_AUTH_NOT_CREATE_DIR="Could not create the FileStore folder %s. Please check the effective permissions." +JGLOBAL_AUTH_PASS_BLANK="LDAP can't have blank password" +JGLOBAL_AUTH_UNKNOWN_ACCESS_DENIED="Result Unknown. Access Denied" +JGLOBAL_AUTH_USER_BLACKLISTED="User is blacklisted." +JGLOBAL_AUTH_USER_NOT_FOUND="Unable to find user." +JGLOBAL_AUTHOR_ALPHABETICAL="Author Alphabetical" +JGLOBAL_AUTHOR_REVERSE_ALPHABETICAL="Author Reverse Alphabetical" +JGLOBAL_AUTO="Auto" +JGLOBAL_BATCH_MOVE_PARENT_NOT_FOUND="Can't find the destination parent for this move." +JGLOBAL_BATCH_MOVE_ROW_NOT_FOUND="Can't find the destination row for this move." +JGLOBAL_BATCH_PROCESS="Process" +JGLOBAL_BLOG="Blog" +JGLOBAL_BLOG_LAYOUT_OPTIONS="Blog Layout" +JGLOBAL_CATEGORIES_OPTIONS="Categories" +JGLOBAL_CATEGORY_LAYOUT_DESC="Layout" +JGLOBAL_CATEGORY_LAYOUT_LABEL="Choose a Layout" +JGLOBAL_CATEGORY_MANAGER_ORDER="Category Order" +JGLOBAL_CATEGORY_NOT_FOUND="Category not found" +JGLOBAL_CATEGORY_OPTIONS="Category" +JGLOBAL_CATEGORY_ORDER_DESC="The order that categories will show in." +JGLOBAL_CATEGORY_ORDER_LABEL="Category Order" +JGLOBAL_CENTER="Center" +JGLOBAL_CHECK_ALL="Check All Items" +JGLOBAL_CHOOSE_CATEGORY_DESC="Select or create a category to be displayed." +JGLOBAL_CHOOSE_CATEGORY_LABEL="Choose a Category" +JGLOBAL_CHOOSE_COMPONENT_DESC="Choose a component from the list." +JGLOBAL_CHOOSE_COMPONENT_LABEL="Choose a component" +JGLOBAL_CLICK_TO_SORT_THIS_COLUMN="Select to sort by this column" +JGLOBAL_CLICK_TO_TOGGLE_STATE="Select icon to toggle state." +JGLOBAL_CONFIRM_DELETE="Are you sure you want to delete? Confirming will permanently delete the selected item(s)!" +JGLOBAL_COPY="(copy)" +JGLOBAL_CREATED="Created" +JGLOBAL_CREATED_DATE="Created Date" +JGLOBAL_CUSTOM_CATEGORY="New Categories" +JGLOBAL_CUSTOM_FIELDS_ENABLE_DESC="Enable the creation of custom fields." +JGLOBAL_CUSTOM_FIELDS_ENABLE_LABEL="Enable Custom Fields" +JGLOBAL_DATE_FORMAT_DESC="Optional format string for showing the date. For example, D M Y for day month year or you can use d-m-y for a short version eg. 28-12-16. See https://php.net/date. If left blank, it uses DATE_FORMAT_LC1 from your language file." +JGLOBAL_DATE_FORMAT_LABEL="Date Format" +JGLOBAL_DESCRIPTION="Description" +JGLOBAL_DISPLAY_NUM="Display #" +JGLOBAL_DISPLAY_SELECT_DESC="Show or hide the Display Select dropdown listbox." +JGLOBAL_DISPLAY_SELECT_LABEL="Display Select" +JGLOBAL_DOWN="Down" +JGLOBAL_EDIT_ITEM="Edit item" +JGLOBAL_EDIT_PREFERENCES="Edit Preferences" +JGLOBAL_EMAIL="Email" +JGLOBAL_EMAIL_DOMAIN_NOT_ALLOWED="The email domain %s is not allowed. Please enter another email address." +JGLOBAL_EMPTY_CATEGORIES_DESC="Show or hide categories that have no articles and no subcategories." +JGLOBAL_EMPTY_CATEGORIES_LABEL="Empty Categories" +JGLOBAL_ERROR_INSUFFICIENT_BATCH_INFORMATION="Insufficient information to perform the batch operation" +JGLOBAL_FEED_SHOW_READMORE_DESC="Displays a "Read More" link in the news feeds if Intro Text is set to Show." +JGLOBAL_FEED_SHOW_READMORE_LABEL="Show "Read More"" +JGLOBAL_FEED_SUMMARY_DESC="If set to Intro Text, only the Intro Text of each article will show in the news feed. If set to Full Text, the whole article will show in the news feed." +JGLOBAL_FEED_SUMMARY_LABEL="Include in Feed" +JGLOBAL_FEED_TITLE="News Feeds" +JGLOBAL_FIELDS="Fields" +JGLOBAL_FIELDS_TITLE="Custom Fields" +JGLOBAL_FIELD_ADD="Add" +JGLOBAL_FIELD_GROUPS="Field Groups" +JGLOBAL_FIELD_CATEGORIES_CHOOSE_CATEGORY_DESC="Categories that are within this category will be displayed." +JGLOBAL_FIELD_CATEGORIES_CHOOSE_CATEGORY_LABEL="Select a Top Level Category" +JGLOBAL_FIELD_CATEGORIES_DESC_DESC="If you enter some text in this field, it will replace the Top Level Category Description, if it has one." +JGLOBAL_FIELD_CATEGORIES_DESC_LABEL="Alternative Description" +JGLOBAL_FIELD_CREATED_BY_ALIAS_DESC="Uses another name than the author's for display." +JGLOBAL_FIELD_CREATED_BY_ALIAS_LABEL="Author's Alias" +JGLOBAL_FIELD_CREATED_BY_DESC="The user who created this." +JGLOBAL_FIELD_CREATED_BY_LABEL="Created By" +JGLOBAL_FIELD_CREATED_DESC="Created Date." +JGLOBAL_FIELD_CREATED_LABEL="Created Date" +JGLOBAL_FIELD_FIELD_CACHETIME_DESC="The number of minutes before the cache is refreshed." +JGLOBAL_FIELD_FIELD_ORDERING_LABEL="Order" +JGLOBAL_FIELD_FIELD_ORDERING_DESC="Order items will be displayed in." +JGLOBAL_FIELD_ID_DESC="Record number in the database." +JGLOBAL_FIELD_ID_LABEL="ID" +JGLOBAL_FIELD_LAYOUT_DESC="Default layout to use for items." +JGLOBAL_FIELD_LAYOUT_LABEL="Choose a Layout" +JGLOBAL_FIELD_MODIFIED_LABEL="Modified Date" +JGLOBAL_FIELD_MODIFIED_BY_DESC="The user who did the last modification." +JGLOBAL_FIELD_MODIFIED_BY_LABEL="Modified By" +JGLOBAL_FIELD_MOVE="Move" +JGLOBAL_FIELD_NUM_CATEGORY_ITEMS_DESC="Number of categories to display for each level." +JGLOBAL_FIELD_NUM_CATEGORY_ITEMS_LABEL="Number of Categories" +JGLOBAL_FIELD_PUBLISH_DOWN_DESC="An optional date to stop publishing." +JGLOBAL_FIELD_PUBLISH_DOWN_LABEL="Finish Publishing" +JGLOBAL_FIELD_PUBLISH_UP_DESC="An optional date to start publishing." +JGLOBAL_FIELD_PUBLISH_UP_LABEL="Start Publishing" +JGLOBAL_FIELD_REMOVE="Remove" +JGLOBAL_FIELD_SHOW_BASE_DESCRIPTION_DESC="Show description of the top level category or alternatively replace with the text from the description field found in the menu item. If using Root as a top level category, the description field has to be filled." +JGLOBAL_FIELD_SHOW_BASE_DESCRIPTION_LABEL="Top Level Category Description" +JGLOBAL_FIELD_VERSION_NOTE_DESC="Enter an optional note for this version of the item." +JGLOBAL_FIELD_VERSION_NOTE_LABEL="Version Note" +JGLOBAL_FIELDSET_ASSOCIATIONS="Associations" +JGLOBAL_FIELDSET_DISPLAY_OPTIONS="Display" +JGLOBAL_FIELDSET_IMAGE_OPTIONS="Images" +JGLOBAL_FIELDSET_INTEGRATION="Integration" +JGLOBAL_FIELDSET_METADATA_OPTIONS="Metadata" +JGLOBAL_FIELDSET_OPTIONS="Options" +JGLOBAL_FIELDSET_CONTENT="Content" +JGLOBAL_FIELDSET_PUBLISHING="Publishing" +JGLOBAL_FIELDSET_DESCRIPTION="Description" +JGLOBAL_FIELDSET_ADVANCED="Advanced" +JGLOBAL_FIELDSET_BASIC="Options" +JGLOBAL_FILTER_ATTRIBUTES_DESC="3. List additional attributes, separating each attribute name with a space or comma. For example: class,title,id." +JGLOBAL_FILTER_ATTRIBUTES_LABEL="Filter Attributes3" +JGLOBAL_FILTER_CLIENT="- Select Location -" +JGLOBAL_FILTER_FIELD_DESC="Show or hide a filter field for the list." +JGLOBAL_FILTER_FIELD_LABEL="Filter Field" +JGLOBAL_FILTER_GROUPS_DESC="This sets the user groups that you want filters applied to. Other groups will have no filtering performed." +JGLOBAL_FILTER_GROUPS_LABEL="Filter Groups" +JGLOBAL_FILTER_TAGS_DESC="2. List additional tags, separating each tag name with a space or comma. For example: p,div,span." +JGLOBAL_FILTER_TAGS_LABEL="Filter Tags2" +JGLOBAL_FILTER_TYPE_DESC="1. Blacklist allows all tags and attributes except for those in the blacklist.
    -- Tags for the Default Blacklist include: 'applet', 'body', 'bgsound', 'base', 'basefont', 'canvas', 'embed', 'frame', 'frameset', 'head', 'html', 'id', 'iframe', 'ilayer', 'layer', 'link', 'meta', 'name', 'object', 'script', 'style', 'title', 'xml'
    -- Attributes for the Default Blacklist include: 'action', 'background', 'codebase', 'dynsrc', 'lowsrc', 'formaction'
    -- You can blacklist additional tags and attributes by adding to the Filter Tags and Filter Attributes fields, separating each tag or attribute name with a comma.
    -- Custom Blacklist allows you to override the Default Blacklist. Add the tags and attributes to be blacklisted in the Filter Tags and Filter Attributes fields.

    Whitelist allows only the tags listed in the Filter Tags and Filter Attributes fields.

    No HTML removes all HTML tags from the content when it is saved.

    Please note that these settings work regardless of the editor that you are using.
    Even if you are using a WYSIWYG editor, the filtering settings may strip additional tags and attributes prior to saving information in the database." +JGLOBAL_FILTER_TYPE_LABEL="Filter Type1" +JGLOBAL_FULL_TEXT="Full Text" +JGLOBAL_GT=">" +; The following strings is deprecated and will be removed with 4.0. +JGLOBAL_HELPREFRESH_BUTTON="Refresh" +JGLOBAL_HISTORY_LIMIT_OPTIONS_DESC="The maximum number of old versions of an item to save. If zero, all old versions will be saved." +JGLOBAL_HISTORY_LIMIT_OPTIONS_LABEL="Maximum Versions" +JGLOBAL_HITS="Hits" +JGLOBAL_HITS_ASC="Hits ascending" +JGLOBAL_HITS_DESC="Hits descending" +; Deprecated, will be removed with 4.0. Please do not translate the following language string +JGLOBAL_INDEX_FOLLOW="index, follow" +; Deprecated, will be removed with 4.0. Please do not translate the following language string +JGLOBAL_INDEX_NOFOLLOW="index, nofollow" +JGLOBAL_INHERIT="Inherit" +JGLOBAL_INTEGRATION_LABEL="Integration" +JGLOBAL_INTRO_TEXT="Intro Text" +JGLOBAL_ISFREESOFTWARE="%s is free software released under the GNU General Public License." +JGLOBAL_KEEP_TYPING="Keep typing ..." +JGLOBAL_LANGUAGE_VERSION_NOT_PLATFORM="Language pack does not match this Joomla! version. Some strings may be missing and will be displayed in English." +JGLOBAL_LEAST_HITS="Least Hits" +JGLOBAL_LEFT="Left" +JGLOBAL_LINK_AUTHOR_DESC="If set to Yes, the Name of the article's Author will be linked to its contact page. You must create a contact linked to the author's user record, and the "Content - Contact" plugin must be enabled, for this to be in effect." +JGLOBAL_LINK_AUTHOR_LABEL="Link Author" +JGLOBAL_LINK_CATEGORY_DESC="If set to Yes, and if Show Category is set to 'Show', the Category Title will link to a layout showing articles in that Category." +JGLOBAL_LINK_CATEGORY_LABEL="Link Category" +JGLOBAL_LINK_PARENT_CATEGORY_DESC="If set to Yes, and if Show Parent is set to 'Show', the Parent Category Title will link to a layout showing articles in that Category." +JGLOBAL_LINK_PARENT_CATEGORY_LABEL="Link Parent" +JGLOBAL_LINKED_TITLES_DESC="If set to Yes, the article title will be a link to the article." +JGLOBAL_LINKED_TITLES_LABEL="Linked Titles" +JGLOBAL_LIST="List" +JGLOBAL_LIST_ALIAS="(Alias: %s)" +JGLOBAL_LIST_ALIAS_NOTE="(Alias: %s, Note: %s)" +JGLOBAL_LIST_AUTHOR_DESC="Show or hide the article author in the list of articles." +JGLOBAL_LIST_AUTHOR_LABEL="Show Author in List" +JGLOBAL_LIST_HITS_DESC="Show or hide article hits in the list of articles." +JGLOBAL_LIST_HITS_LABEL="Show Hits in List" +JGLOBAL_LIST_LAYOUT_OPTIONS="List Layouts" +JGLOBAL_LIST_NAME="(Name: %s)" +JGLOBAL_LIST_NAME_NOTE="(Name: %s, Note: %s)" +JGLOBAL_LIST_NOTE="(Note: %s)" +JGLOBAL_LIST_RATINGS_DESC="Whether to show article ratings in the list of articles." +JGLOBAL_LIST_RATINGS_LABEL="Show Ratings in List" +JGLOBAL_LIST_TITLE_DESC="If Show, Category Title will show in the list of categories." +JGLOBAL_LIST_TITLE_LABEL="Category Title" +JGLOBAL_LIST_VOTES_DESC="Whether to show article votes in the list of articles." +JGLOBAL_LIST_VOTES_LABEL="Show Votes in List" +JGLOBAL_LOOKING_FOR="Looking for" +JGLOBAL_LT="<" +JGLOBAL_MAXIMUM_CATEGORY_LEVELS_DESC="The number of subcategory levels to display." +JGLOBAL_MAXIMUM_CATEGORY_LEVELS_LABEL="Subcategory Levels" +JGLOBAL_MAXIMUM_UPLOAD_SIZE_LIMIT="Maximum upload size: %s" +JGLOBAL_MAXLEVEL_DESC="Maximum number of levels of subcategories to show." +JGLOBAL_MAXLEVEL_LABEL="Subcategory Levels" +JGLOBAL_MENU_SELECTION="Menu Selection:" +JGLOBAL_MODIFIED="Modified" +JGLOBAL_MODIFIED_DATE="Modified Date" +JGLOBAL_MOST_HITS="Most Hits" +JGLOBAL_MOST_RECENT_FIRST="Most Recent First" +JGLOBAL_MULTI_COLUMN_ORDER_DESC="Order articles down or across columns." +JGLOBAL_MULTI_COLUMN_ORDER_LABEL="Multi Column Order" +JGLOBAL_MULTI_LEVEL="Multi Level" +JGLOBAL_NEWITEMSFIRST_DESC="New items default to the first position. The ordering can be changed after this item is saved." +JGLOBAL_NEWITEMSLAST_DESC="New items default to the last position. The ordering can be changed after this item is saved." +JGLOBAL_NO_ITEM_SELECTED="No items selected" +JGLOBAL_NO_ORDER="No Order" +; Deprecated, will be removed with 4.0. Please do not translate the following language string +JGLOBAL_NOINDEX_FOLLOW="noindex, follow" +; Deprecated, will be removed with 4.0. Please do not translate the following language string +JGLOBAL_NOINDEX_NOFOLLOW="noindex, nofollow" +JGLOBAL_NONAPPLICABLE="N/A" +JGLOBAL_NUM_COLUMNS_DESC="The number of columns in which to show Intro Articles. Normally 1, 2, or 3." +JGLOBAL_NUM_COLUMNS_LABEL="# Columns" +JGLOBAL_NUM_INTRO_ARTICLES_DESC="Number of articles to show after the leading article. Articles will be shown in columns." +JGLOBAL_NUM_INTRO_ARTICLES_LABEL="# Intro Articles" +JGLOBAL_NUM_LEADING_ARTICLES_DESC="Number of leading articles to display as full-width at the beginning of the page." +JGLOBAL_NUM_LEADING_ARTICLES_LABEL="# Leading Articles" +JGLOBAL_NUM_LINKS_DESC="Number of articles to display as links, normally below the Intro Articles." +JGLOBAL_NUM_LINKS_LABEL="# Links" +JGLOBAL_NUMBER_CATEGORY_ITEMS_DESC="If Show, the number of articles in the category will show." +JGLOBAL_NUMBER_CATEGORY_ITEMS_LABEL="Show Article Count" +JGLOBAL_NUMBER_ITEMS_LIST_DESC="Default number of articles to list on a page." +JGLOBAL_NUMBER_ITEMS_LIST_LABEL="# Articles to List" +JGLOBAL_NO_MATCHING_RESULTS="No Matching Results" +JGLOBAL_OLDEST_FIRST="Oldest First" +JGLOBAL_ORDER_ASCENDING="Ascending" +JGLOBAL_ORDER_DESCENDING="Descending" +JGLOBAL_ORDER_DIRECTION_LABEL="Direction" +JGLOBAL_ORDER_DIRECTION_DESC="Sort order. Descending is highest to lowest. Ascending is lowest to highest." +JGLOBAL_ORDERING="Article Order" +JGLOBAL_ORDERING_DATE_DESC="If articles are ordered by date, which date to use." +JGLOBAL_ORDERING_DATE_LABEL="Date for Ordering" +JGLOBAL_OTPMETHOD_NONE="Disable Two Factor Authentication" +JGLOBAL_PAGINATION_DESC="Show or hide Pagination support. Pagination provides page links at the bottom of the page that allow the User to navigate to additional pages. These are needed if the Information will not fit on one page." +JGLOBAL_PAGINATION_LABEL="Pagination" +JGLOBAL_PAGINATION_RESULTS_DESC="Show or hide pagination results information, for example, "Page 1 of 4"." +JGLOBAL_PAGINATION_RESULTS_LABEL="Pagination Results" +JGLOBAL_PASSWORD="Password" +JGLOBAL_PASSWORD_RESET_REQUIRED="You are required to reset your password before proceeding." +JGLOBAL_PERMISSIONS_ANCHOR="Set Permissions" +JGLOBAL_PREVIEW="Preview" +JGLOBAL_PUBLISHED_DATE="Published Date" +JGLOBAL_RANDOM_ORDER="Random Order" +JGLOBAL_RATINGS="Ratings" +JGLOBAL_RATINGS_ASC="Ratings ascending" +JGLOBAL_RATINGS_DESC="Ratings descending" +JGLOBAL_RECORD_HITS_DESC="Record the number of hits." +JGLOBAL_RECORD_HITS_LABEL="Record Hits" +JGLOBAL_RECORD_NUMBER="Record ID: %d" +JGLOBAL_REMEMBER_ME="Remember Me" +JGLOBAL_REVERSE_ORDERING="Article Reverse Order" +JGLOBAL_RIGHT="Right" +JGLOBAL_ROOT="Root" +JGLOBAL_ROOT_PARENT="- No parent -" +JGLOBAL_SAVE_HISTORY_OPTIONS_DESC="Automatically save old versions of an item. If set to Yes, old versions of items are saved automatically. When editing, you may restore from a previous version of the item." +JGLOBAL_SAVE_HISTORY_OPTIONS_LABEL="Enable Versions" +JGLOBAL_SECRETKEY="Secret Key" +JGLOBAL_SECRETKEY_HELP="If you have enabled two factor authentication in your user account please enter your secret key. If you do not know what this means, you can leave this field blank." +; The following 4 strings are deprecated and will be removed with 4.0. +JGLOBAL_SEF_ADVANCED_DESC="Modern routing enables advanced features but may change your URLs. Legacy routing ensures full compatibility for existing sites. This is configured per component." +JGLOBAL_SEF_ADVANCED_LABEL="URL Routing" +JGLOBAL_SEF_ADVANCED_LEGACY="Legacy" +JGLOBAL_SEF_ADVANCED_MODERN="Modern" +JGLOBAL_SEF_NOIDS_DESC="Remove the IDs from the URLs of this component." +JGLOBAL_SEF_NOIDS_LABEL="Remove IDs from URLs" +JGLOBAL_SEF_TITLE="Routing" +JGLOBAL_SELECT_ALLOW_DENY_GROUP="Change %s permission for %s group." +JGLOBAL_SELECT_AN_OPTION="Select an option" +JGLOBAL_SELECT_NO_RESULTS_MATCH="No results match" +JGLOBAL_SELECT_SOME_OPTIONS="Select some options" +JGLOBAL_SELECTED_UPLOAD_FILE_SIZE="Selected file size: %s" +JGLOBAL_SELECTION_ALL="Select All" +JGLOBAL_SELECTION_INVERT="Toggle Selection" +JGLOBAL_SELECTION_INVERT_ALL="Toggle All Selections" +JGLOBAL_SELECTION_NONE="Clear Selection" +JGLOBAL_SHOW_ASSOCIATIONS_DESC="Multilingual only. If set to Show, the associated articles flags or URL Language Code will be displayed." +JGLOBAL_SHOW_ASSOCIATIONS_LABEL="Show Associations" +JGLOBAL_SHOW_AUTHOR_DESC="If set to Show, the Name of the article's Author will be displayed." +JGLOBAL_SHOW_AUTHOR_LABEL="Show Author" +JGLOBAL_SHOW_CATEGORY_DESC="If set to Show, the title of the article’s category will show." +JGLOBAL_SHOW_CATEGORY_DESCRIPTION_DESC="Show or hide the description of the selected Category." +JGLOBAL_SHOW_CATEGORY_DESCRIPTION_LABEL="Category Description" +JGLOBAL_SHOW_CATEGORY_IMAGE_DESC="Show or hide the image of the selected Category." +JGLOBAL_SHOW_CATEGORY_IMAGE_LABEL="Category Image" +JGLOBAL_SHOW_CATEGORY_HEADING_TITLE_TEXT_LABEL="Show Subcategories Text" +JGLOBAL_SHOW_CATEGORY_HEADING_TITLE_TEXT_DESC="If Show, the "Subcategories" will show as a subheading on the page. The subheading is usually displayed inside the "H3" tag." +JGLOBAL_SHOW_CATEGORY_LABEL="Show Category" +JGLOBAL_SHOW_CATEGORY_TITLE="Category Title" +JGLOBAL_SHOW_CATEGORY_TITLE_DESC="If Show, the Category Title will show as a subheading on the page. The subheading is usually displayed inside the "H2" tag." +JGLOBAL_SHOW_CREATE_DATE_DESC="If set to Show, the date and time an Article was created will be displayed." +JGLOBAL_SHOW_CREATE_DATE_LABEL="Show Create Date" +JGLOBAL_SHOW_DATE_DESC="Show or hide a date column in the list of articles, or select which date you wish to show." +JGLOBAL_SHOW_DATE_LABEL="Show Date" +JGLOBAL_SHOW_EMAIL_ICON_DESC="Show or hide the email link. This allows you to email an article." +JGLOBAL_SHOW_EMAIL_ICON_LABEL="Show Email" +JGLOBAL_SHOW_EMPTY_CATEGORIES_DESC="If Show, empty categories will display. A category is only empty if it has no items or subcategories." +JGLOBAL_SHOW_EMPTY_CATEGORIES_LABEL="Empty Categories" +JGLOBAL_SHOW_FEATURED_ARTICLES_DESC="Select to show, hide or only display featured articles." +JGLOBAL_SHOW_FEATURED_ARTICLES_LABEL="Featured Articles" +JGLOBAL_SHOW_FEED_LINK_DESC="Show or hide an RSS Feed Link. (A Feed Link will show up as a feed icon in the address bar of most modern browsers)." +JGLOBAL_SHOW_FEED_LINK_LABEL="Show Feed Link" +JGLOBAL_SHOW_FLAG_DESC="If set to 'Yes', will display language choice as image flags. Otherwise will use the content language URL Language Code." +JGLOBAL_SHOW_FLAG_LABEL="Use Image Flags" +JGLOBAL_SHOW_FULL_DESCRIPTION="Show full description ..." +JGLOBAL_SHOW_HEADINGS_DESC="Show or hide the headings in list layouts." +JGLOBAL_SHOW_HEADINGS_LABEL="Table Headings" +JGLOBAL_SHOW_HITS_DESC="If set to Show, the number of Hits on a particular Article will be displayed." +JGLOBAL_SHOW_HITS_LABEL="Show Hits" +JGLOBAL_SHOW_ICONS_DESC="Print and email will utilise icons or text." +JGLOBAL_SHOW_ICONS_LABEL="Show Icons" +JGLOBAL_SHOW_INTRO_DESC="If set to Show, the Intro Text of the article will show when you drill down to the article. If set to Hide, only the part of the article after the "Read More" break will show." +JGLOBAL_SHOW_INTRO_LABEL="Show Intro Text" +JGLOBAL_SHOW_MODIFY_DATE_DESC="If set to Show, the date and time an Article was last modified will be displayed." +JGLOBAL_SHOW_MODIFY_DATE_LABEL="Show Modify Date" +JGLOBAL_SHOW_NAVIGATION_DESC="If set to Show, shows a navigation link (Next, Previous) between articles." +JGLOBAL_SHOW_NAVIGATION_LABEL="Show Navigation" +JGLOBAL_SHOW_PARENT_CATEGORY_DESC="If set to Show, the title of the article’s parent category will show." +JGLOBAL_SHOW_PARENT_CATEGORY_LABEL="Show Parent" +JGLOBAL_SHOW_PRINT_ICON_DESC="Show or hide the print. This allows you to print an article." +JGLOBAL_SHOW_PRINT_ICON_LABEL="Show Print" +JGLOBAL_SHOW_PUBLISH_DATE_DESC="If set to Show, the date and time an Article was published will be displayed." +JGLOBAL_SHOW_PUBLISH_DATE_LABEL="Show Publish Date" +JGLOBAL_SHOW_READMORE_DESC="If set to Show, the Read more ...Link will show if Main text has been provided for the Article." +JGLOBAL_SHOW_READMORE_LABEL="Show "Read More"" +JGLOBAL_SHOW_READMORE_TITLE_DESC="If set to show the title of the Article will be shown on the Read More button." +JGLOBAL_SHOW_READMORE_TITLE_LABEL="Show Title with Read More" +JGLOBAL_SHOW_READMORE_LIMIT_DESC="Set a limit of number of characters in Article Title to show in Read More button." +JGLOBAL_SHOW_READMORE_LIMIT_LABEL="Read More Limit" +JGLOBAL_SHOW_SUBCATEGORIES_DESCRIPTION_DESC="Show or hide the subcategories descriptions." +JGLOBAL_SHOW_SUBCATEGORIES_DESCRIPTION_LABEL="Subcategories Descriptions" +JGLOBAL_SHOW_SUBCATEGORY_CONTENT_LABEL="Include Subcategories" +JGLOBAL_SHOW_SUBCATEGORY_CONTENT_DESC="If None, only articles from this category will show. If a number, all articles from the category and the subcategories up to and including that level will show in the blog." +JGLOBAL_SHOW_TAGS_DESC="Show the tags for this link." +JGLOBAL_SHOW_TAGS_LABEL="Show Tags" +JGLOBAL_SHOW_TITLE_DESC="If set to Show, the article title is shown." +JGLOBAL_SHOW_TITLE_LABEL="Show Title" +JGLOBAL_SHOW_UNAUTH_LINKS_DESC="If set to Yes, links to registered content will be shown even if you are not logged-in. You will need to log in to access the full item." +JGLOBAL_SHOW_UNAUTH_LINKS_LABEL="Show Unauthorised Links" +JGLOBAL_SHOW_VOTE_DESC="If set to show, a voting system will be enabled for Articles." +JGLOBAL_SHOW_VOTE_LABEL="Show Voting" +JGLOBAL_SINGLE_LEVEL="Single Level" +JGLOBAL_SORT_BY="Sort Table By:" +JGLOBAL_START_PUBLISH_AFTER_FINISH="Item start publishing date must be before finish publishing date" +JGLOBAL_SUBHEADING_DESC="Optional text to show as a subheading." +JGLOBAL_SUBHEADING_LABEL="Page Subheading" +JGLOBAL_SUBMENU_CHECKIN="Check-in" +JGLOBAL_SUBMENU_CLEAR_CACHE="Clear Cache" +JGLOBAL_SUBMENU_PURGE_EXPIRED_CACHE="Clear Expired Cache" +JGLOBAL_SUBSLIDER_BLOG_EXTENDED_LABEL="The option below gives the ability to include articles from subcategories in the Blog layout." +JGLOBAL_SUBSLIDER_BLOG_LAYOUT_LABEL="If a field is left blank, global settings will be used." +JGLOBAL_SUBSLIDER_DRILL_CATEGORIES_LABEL="These options are also used when you select
    one of the category links, on the first page and/or thereafter,
    unless they are changed for a specific menu item." +JGLOBAL_TITLE="Title" +JGLOBAL_TITLE_ASC="Title ascending" +JGLOBAL_TITLE_DESC="Title descending" +JGLOBAL_TITLE_ALPHABETICAL="Title Alphabetical" +JGLOBAL_TITLE_REVERSE_ALPHABETICAL="Title Reverse Alphabetical" +JGLOBAL_TOGGLE_FEATURED="Toggle featured status." +JGLOBAL_TOP="Top" +JGLOBAL_TPL_CPANEL_LINK_TEXT="Return to Control Panel" +JGLOBAL_TYPE_OR_SELECT_CATEGORY="Type or Select a Category" +JGLOBAL_TYPE_OR_SELECT_SOME_OPTIONS="Type or select some options" +JGLOBAL_TYPE_OR_SELECT_SOME_TAGS="Type or select some tags" +JGLOBAL_USE_GLOBAL="Use Global" +JGLOBAL_USE_GLOBAL_VALUE="Use Global (%s)" +JGLOBAL_USERNAME="Username" +JGLOBAL_VALIDATION_FORM_FAILED="Invalid form" +JGLOBAL_VIEW_SITE="View Site" +JGLOBAL_VOTES="Votes" +JGLOBAL_VOTES_ASC="Votes ascending" +JGLOBAL_VOTES_DESC="Votes descending" +JGLOBAL_WARNJAVASCRIPT="Warning! JavaScript must be enabled for proper operation of the Administrator Backend." +JGLOBAL_WIDTH="Width" + +JGRID_HEADING_ACCESS="Access" +JGRID_HEADING_ACCESS_ASC="Access ascending" +JGRID_HEADING_ACCESS_DESC="Access descending" +JGRID_HEADING_CREATED_BY="Created by" +JGRID_HEADING_ID="ID" +JGRID_HEADING_ID_ASC="ID ascending" +JGRID_HEADING_ID_DESC="ID descending" +JGRID_HEADING_LANGUAGE="Language" +JGRID_HEADING_LANGUAGE_ASC="Language ascending" +JGRID_HEADING_LANGUAGE_DESC="Language descending" +JGRID_HEADING_MENU_ITEM_TYPE="Menu Item Type" +JGRID_HEADING_ORDERING="Ordering" +JGRID_HEADING_ORDERING_ASC="Ordering ascending" +JGRID_HEADING_ORDERING_DESC="Ordering descending" + +JHELP_COMPONENTS_ACTIONLOGS="Components_Actionlogs" +JHELP_COMPONENTS_ASSOCIATIONS="Components_Associations" +JHELP_COMPONENTS_ASSOCIATIONS_EDIT="Components_Associations_Edit" +JHELP_COMPONENTS_BANNERS_BANNERS_EDIT="Components_Banners_Banners_Edit" +JHELP_COMPONENTS_BANNERS_BANNERS="Components_Banners_Banners" +JHELP_COMPONENTS_BANNERS_CATEGORIES="Components_Banners_Categories" +JHELP_COMPONENTS_BANNERS_CATEGORY_ADD="Components_Banners_Categories_Edit" +JHELP_COMPONENTS_BANNERS_CATEGORY_EDIT="Components_Banners_Categories_Edit" +JHELP_COMPONENTS_BANNERS_CLIENTS_EDIT="Components_Banners_Clients_Edit" +JHELP_COMPONENTS_BANNERS_CLIENTS="Components_Banners_Clients" +JHELP_COMPONENTS_BANNERS_TRACKS="Components_Banners_Tracks" +JHELP_COMPONENTS_CACHE_MANAGER_SETTINGS="Components_Cache_Manager_Settings" +JHELP_COMPONENTS_CHECK-IN_CONFIGURATION="Components_Check-in_Configuration" +JHELP_COMPONENTS_COM_ACTIONLOGS_OPTIONS="Components_User_Actionlogs_Options" +JHELP_COMPONENTS_COM_ASSOCIATIONS_OPTIONS="Components_Associations_Options" +JHELP_COMPONENTS_COM_BANNERS_OPTIONS="Components_Banner_Manager_Options" +JHELP_COMPONENTS_COM_CACHE_OPTIONS="Components_Cache_Manager_Settings" +JHELP_COMPONENTS_COM_CHECKIN_OPTIONS="Components_Check_in_Configuration" +JHELP_COMPONENTS_COM_CONTACT_OPTIONS="Components_Contact_Manager_Options" +JHELP_COMPONENTS_COM_CONTENT_OPTIONS="Components_Article_Manager_Options" +JHELP_COMPONENTS_COM_FINDER_OPTIONS="Components_Smart_Search_Configuration" +JHELP_COMPONENTS_COM_INSTALLER_OPTIONS="Components_Installer_Configuration" +JHELP_COMPONENTS_COM_JOOMLAUPDATE_OPTIONS="Components_Joomla_Update_Configuration" +JHELP_COMPONENTS_COM_LANGUAGES_OPTIONS="Components_Language_Manager_Options" +JHELP_COMPONENTS_COM_MEDIA_OPTIONS="Components_Media_Manager_Options" +JHELP_COMPONENTS_COM_MENUS_OPTIONS="Components_Menus_Configuration" +JHELP_COMPONENTS_COM_MESSAGES_OPTIONS="Components_Messages_Configuration" +JHELP_COMPONENTS_COM_MODULES_OPTIONS="Components_Module_Manager_Options" +JHELP_COMPONENTS_COM_NEWSFEEDS_OPTIONS="Components_News_Feed_Manager_Options" +JHELP_COMPONENTS_COM_PLUGINS_OPTIONS="Components_Plugin_Manager_Options" +JHELP_COMPONENTS_COM_PRIVACY_OPTIONS="Components_Privacy_Options" +JHELP_COMPONENTS_COM_POSTINSTALL_OPTIONS="Components_Post_installation_Messages_Configuration" +JHELP_COMPONENTS_COM_REDIRECT_OPTIONS="Components_Redirect_Manager_Options" +JHELP_COMPONENTS_COM_SEARCH_OPTIONS="Components_Search_Manager_Options" +JHELP_COMPONENTS_COM_TAGS_OPTIONS="Components_Tags_Manager_Options" +JHELP_COMPONENTS_COM_TEMPLATES_OPTIONS="Components_Template_Manager_Options" +JHELP_COMPONENTS_COM_USERS_OPTIONS="Components_Users_Configuration" +JHELP_COMPONENTS_COM_WEBLINKS_OPTIONS="Components_Web_Links_Manager_Options" +JHELP_COMPONENTS_CONTACT_CATEGORIES="Components_Contacts_Categories" +JHELP_COMPONENTS_CONTACT_CATEGORY_ADD="Components_Contacts_Categories_Edit" +JHELP_COMPONENTS_CONTACT_CATEGORY_EDIT="Components_Contacts_Categories_Edit" +JHELP_COMPONENTS_CONTACTS_CONTACTS_EDIT="Components_Contacts_Contacts_Edit" +JHELP_COMPONENTS_CONTACTS_CONTACTS="Components_Contacts_Contacts" +JHELP_COMPONENTS_CONTENT_CATEGORIES="Components_Content_Categories" +JHELP_COMPONENTS_CONTENT_CATEGORY_ADD="Components_Content_Categories_Edit" +JHELP_COMPONENTS_CONTENT_CATEGORY_EDIT="Components_Content_Categories_Edit" +JHELP_COMPONENTS_FIELDS_FIELDS="Components_Fields_Fields" +JHELP_COMPONENTS_FIELDS_FIELDS_EDIT="Components_Fields_Fields_Edit" +JHELP_COMPONENTS_FIELDS_FIELD_GROUPS="Components_Fields_Field_Groups" +JHELP_COMPONENTS_FIELDS_FIELD_GROUPS_EDIT="Components_Fields_Field_Groups_Edit" +JHELP_COMPONENTS_FINDER_MANAGE_CONTENT_MAPS="Components_Finder_Manage_Content_Maps" +JHELP_COMPONENTS_FINDER_MANAGE_INDEXED_CONTENT="Components_Finder_Manage_Indexed_Content" +JHELP_COMPONENTS_FINDER_MANAGE_SEARCH_FILTERS_EDIT="Components_Finder_Manage_Search_Filters_Edit" +JHELP_COMPONENTS_FINDER_MANAGE_SEARCH_FILTERS="Components_Finder_Manage_Search_Filters" +JHELP_COMPONENTS_INSTALLER_CONFIGURATION="Components_Installer_Configuration" +JHELP_COMPONENTS_JOOMLA_UPDATE="Components_Joomla_Update" +JHELP_COMPONENTS_JOOMLA_UPDATE_CONFIGURATION="Components_Joomla_Update_Configuration" +JHELP_COMPONENTS_MENUS_CONFIGURATION="Components_Menus_Configuration" +JHELP_COMPONENTS_MESSAGES_CONFIGURATION="Components_Messages_Configuration" +JHELP_COMPONENTS_MESSAGING_INBOX="Components_Messaging_Inbox" +JHELP_COMPONENTS_MESSAGING_READ="Components_Messaging_Read" +JHELP_COMPONENTS_MESSAGING_WRITE="Components_Messaging_Write" +JHELP_COMPONENTS_NEWSFEEDS_CATEGORIES="Components_Newsfeeds_Categories" +JHELP_COMPONENTS_NEWSFEEDS_CATEGORY_ADD="Components_Newsfeeds_Categories_Edit" +JHELP_COMPONENTS_NEWSFEEDS_CATEGORY_EDIT="Components_Newsfeeds_Categories_Edit" +JHELP_COMPONENTS_NEWSFEEDS_FEEDS_EDIT="Components_Newsfeeds_Feeds_Edit" +JHELP_COMPONENTS_NEWSFEEDS_FEEDS="Components_Newsfeeds_Feeds" +JHELP_COMPONENTS_POST_INSTALLATION_MESSAGES="Components_Post_installation_Messages" +JHELP_COMPONENTS_PRIVACY_CAPABILITIES="Components_Privacy_Capabilities" +JHELP_COMPONENTS_PRIVACY_CONSENTS="Components_Privacy_Consents" +JHELP_COMPONENTS_PRIVACY_DASHBOARD="Components_Privacy_Dashboard" +JHELP_COMPONENTS_PRIVACY_REQUEST="Components_Privacy_Request" +JHELP_COMPONENTS_PRIVACY_REQUEST_EDIT="Components_Privacy_Request_Edit" +JHELP_COMPONENTS_PRIVACY_REQUESTS="Components_Privacy_Requests" +JHELP_COMPONENTS_REDIRECT_MANAGER_EDIT="Components_Redirect_Manager_Edit" +JHELP_COMPONENTS_REDIRECT_MANAGER="Components_Redirect_Manager" +JHELP_COMPONENTS_SEARCH="Components_Search" +JHELP_COMPONENTS_SMART_SEARCH_CONFIGURATION="Components_Smart_Search_Configuration" +JHELP_COMPONENTS_TAGS_MANAGER="Components_Tags_Manager" +JHELP_COMPONENTS_TAGS_MANAGER_EDIT="Components_Tags_Manager_Edit" +JHELP_COMPONENTS_USERS_CATEGORIES="Users_User_Note_Categories" +JHELP_COMPONENTS_USERS_CATEGORY_ADD="Users_User_Note_Category_Edit" +JHELP_COMPONENTS_USERS_CATEGORY_EDIT="Users_User_Note_Category_Edit" +JHELP_COMPONENTS_WEBLINKS_CATEGORIES="Components_Weblinks_Categories" +JHELP_COMPONENTS_WEBLINKS_CATEGORY_ADD="Components_Weblinks_Categories_Edit" +JHELP_COMPONENTS_WEBLINKS_CATEGORY_EDIT="Components_Weblinks_Categories_Edit" +JHELP_COMPONENTS_WEBLINKS_LINKS_EDIT="Components_Weblinks_Links_Edit" +JHELP_COMPONENTS_WEBLINKS_LINKS="Components_Weblinks_Links" +JHELP_CONTENT_ARTICLE_MANAGER="Content_Article_Manager" +JHELP_CONTENT_ARTICLE_MANAGER_EDIT="Content_Article_Manager_Edit" +JHELP_CONTENT_FEATURED_ARTICLES="Content_Featured_Articles" +JHELP_CONTENT_MEDIA_MANAGER="Content_Media_Manager" +JHELP_EXTENSIONS_EXTENSION_MANAGER_DATABASE="Extensions_Extension_Manager_Database" +JHELP_EXTENSIONS_EXTENSION_MANAGER_DISCOVER="Extensions_Extension_Manager_Discover" +JHELP_EXTENSIONS_EXTENSION_MANAGER_INSTALL="Extensions_Extension_Manager_Install" +JHELP_EXTENSIONS_EXTENSION_MANAGER_LANGUAGES="Extensions_Extension_Manager_languages" +JHELP_EXTENSIONS_EXTENSION_MANAGER_MANAGE="Extensions_Extension_Manager_Manage" +JHELP_EXTENSIONS_EXTENSION_MANAGER_UPDATE="Extensions_Extension_Manager_Update" +JHELP_EXTENSIONS_EXTENSION_MANAGER_UPDATESITES="Extensions_Extension_Manager_Updatesites" +JHELP_EXTENSIONS_EXTENSION_MANAGER_WARNINGS="Extensions_Extension_Manager_Warnings" +JHELP_EXTENSIONS_LANGUAGE_MANAGER_CONTENT="Extensions_Language_Manager_Content" +JHELP_EXTENSIONS_LANGUAGE_MANAGER_EDIT="Extensions_Language_Manager_Edit" +JHELP_EXTENSIONS_LANGUAGE_MANAGER_INSTALLED="Extensions_Language_Manager_Installed" +JHELP_EXTENSIONS_LANGUAGE_MANAGER_OVERRIDES="Extensions_Language_Manager_Overrides" +JHELP_EXTENSIONS_LANGUAGE_MANAGER_OVERRIDES_EDIT="Extensions_Language_Manager_Overrides_Edit" +JHELP_EXTENSIONS_MODULE_MANAGER="Extensions_Module_Manager" +JHELP_EXTENSIONS_MODULE_MANAGER_ADMIN_CUSTOM="Extensions_Module_Manager_Admin_Custom" +JHELP_EXTENSIONS_MODULE_MANAGER_ADMIN_FEED="Extensions_Module_Manager_Admin_Feed" +JHELP_EXTENSIONS_MODULE_MANAGER_ADMIN_LATEST="Extensions_Module_Manager_Admin_Latest" +JHELP_EXTENSIONS_MODULE_MANAGER_ADMIN_LATESTACTIONS="Extensions_Module_Manager_Admin_Latestactions" +JHELP_EXTENSIONS_MODULE_MANAGER_ADMIN_LOGGED="Extensions_Module_Manager_Admin_Logged" +JHELP_EXTENSIONS_MODULE_MANAGER_ADMIN_LOGIN="Extensions_Module_Manager_Admin_Login" +JHELP_EXTENSIONS_MODULE_MANAGER_ADMIN_MENU="Extensions_Module_Manager_Admin_Menu" +JHELP_EXTENSIONS_MODULE_MANAGER_ADMIN_MULTILANG="Extensions_Module_Manager_Admin_Multilang" +JHELP_EXTENSIONS_MODULE_MANAGER_ADMIN_ONLINE="Extensions_Module_Manager_Admin_Online" +JHELP_EXTENSIONS_MODULE_MANAGER_ADMIN_POPULAR="Extensions_Module_Manager_Admin_Popular" +JHELP_EXTENSIONS_MODULE_MANAGER_ADMIN_PRIVACY_DASHBOARD="Extensions_Module_Manager_Admin_Privacy_Dashboard" +JHELP_EXTENSIONS_MODULE_MANAGER_ADMIN_QUICKICON="Extensions_Module_Manager_Admin_Quickicon" +JHELP_EXTENSIONS_MODULE_MANAGER_ADMIN_STATUS="Extensions_Module_Manager_Admin_Status" +JHELP_EXTENSIONS_MODULE_MANAGER_ADMIN_SUBMENU="Extensions_Module_Manager_Admin_Submenu" +JHELP_EXTENSIONS_MODULE_MANAGER_ADMIN_TITLE="Extensions_Module_Manager_Admin_Title" +JHELP_EXTENSIONS_MODULE_MANAGER_ADMIN_TOOLBAR="Extensions_Module_Manager_Admin_Toolbar" +JHELP_EXTENSIONS_MODULE_MANAGER_ADMIN_UNREAD="Extensions_Module_Manager_Admin_Unread" +JHELP_EXTENSIONS_MODULE_MANAGER_ARTICLES_ARCHIVE="Extensions_Module_Manager_Articles_Archive" +JHELP_EXTENSIONS_MODULE_MANAGER_ARTICLES_CATEGORIES="Extensions_Module_Manager_Articles_Categories" +JHELP_EXTENSIONS_MODULE_MANAGER_ARTICLES_CATEGORY="Extensions_Module_Manager_Articles_Category" +JHELP_EXTENSIONS_MODULE_MANAGER_ARTICLES_NEWSFLASH="Extensions_Module_Manager_Articles_Newsflash" +JHELP_EXTENSIONS_MODULE_MANAGER_ARTICLES_RELATED="Extensions_Module_Manager_Articles_Related" +JHELP_EXTENSIONS_MODULE_MANAGER_BANNERS="Extensions_Module_Manager_Banners" +JHELP_EXTENSIONS_MODULE_MANAGER_BREADCRUMBS="Extensions_Module_Manager_Breadcrumbs" +JHELP_EXTENSIONS_MODULE_MANAGER_CUSTOM_HTML="Extensions_Module_Manager_Custom_HTML" +JHELP_EXTENSIONS_MODULE_MANAGER_EDIT="Extensions_Module_Manager_Edit" +JHELP_EXTENSIONS_MODULE_MANAGER_FEED_DISPLAY="Extensions_Module_Manager_Feed_Display" +JHELP_EXTENSIONS_MODULE_MANAGER_FOOTER="Extensions_Module_Manager_Footer" +JHELP_EXTENSIONS_MODULE_MANAGER_LANGUAGE_SWITCHER="Extensions_Module_Manager_Language_Switcher" +JHELP_EXTENSIONS_MODULE_MANAGER_LATEST_NEWS="Extensions_Module_Manager_Latest_News" +JHELP_EXTENSIONS_MODULE_MANAGER_LATEST_USERS="Extensions_Module_Manager_Latest_Users" +JHELP_EXTENSIONS_MODULE_MANAGER_LOGIN="Extensions_Module_Manager_Login" +JHELP_EXTENSIONS_MODULE_MANAGER_MENU="Extensions_Module_Manager_Menu" +JHELP_EXTENSIONS_MODULE_MANAGER_MOST_READ="Extensions_Module_Manager_Most_Read" +JHELP_EXTENSIONS_MODULE_MANAGER_RANDOM_IMAGE="Extensions_Module_Manager_Random_Image" +JHELP_EXTENSIONS_MODULE_MANAGER_SEARCH="Extensions_Module_Manager_Search" +JHELP_EXTENSIONS_MODULE_MANAGER_SMART_SEARCH="Extensions_Module_Manager_Smart_Search" +JHELP_EXTENSIONS_MODULE_MANAGER_STATISTICS="Extensions_Module_Manager_Statistics" +JHELP_EXTENSIONS_MODULE_MANAGER_SYNDICATION_FEEDS="Extensions_Module_Manager_Syndication_Feeds" +JHELP_EXTENSIONS_MODULE_MANAGER_TAGS_POPULAR="Extensions_Module_Manager_Tags_Popular" +JHELP_EXTENSIONS_MODULE_MANAGER_TAGS_SIMILAR="Extensions_Module_Manager_Tags_Similar" +JHELP_EXTENSIONS_MODULE_MANAGER_WEBLINKS="Extensions_Module_Manager_Weblinks" +JHELP_EXTENSIONS_MODULE_MANAGER_WHO_ONLINE="Extensions_Module_Manager_Who_Online" +JHELP_EXTENSIONS_MODULE_MANAGER_WRAPPER="Extensions_Module_Manager_Wrapper" +JHELP_EXTENSIONS_PLUGIN_MANAGER="Extensions_Plugin_Manager" +JHELP_EXTENSIONS_PLUGIN_MANAGER_EDIT="Extensions_Plugin_Manager_Edit" +JHELP_EXTENSIONS_TEMPLATE_MANAGER_STYLES="Extensions_Template_Manager_Styles" +JHELP_EXTENSIONS_TEMPLATE_MANAGER_STYLES_EDIT="Extensions_Template_Manager_Styles_Edit" +JHELP_EXTENSIONS_TEMPLATE_MANAGER_TEMPLATES="Extensions_Template_Manager_Templates" +JHELP_EXTENSIONS_TEMPLATE_MANAGER_TEMPLATES_EDIT="Extensions_Template_Manager_Templates_Edit" +JHELP_EXTENSIONS_TEMPLATE_MANAGER_TEMPLATES_EDIT_SOURCE="Extensions_Template_Manager_Templates_Edit_Source" +JHELP_GLOSSARY="Glossary" +JHELP_MENUS_MENU_ITEM_ARTICLE_ARCHIVED="Menus_Menu_Item_Article_Archived" +JHELP_MENUS_MENU_ITEM_ARTICLE_CATEGORIES="Menus_Menu_Item_Article_Categories" +JHELP_MENUS_MENU_ITEM_ARTICLE_CATEGORY_BLOG="Menus_Menu_Item_Article_Category_Blog" +JHELP_MENUS_MENU_ITEM_ARTICLE_CATEGORY_LIST="Menus_Menu_Item_Article_Category_List" +JHELP_MENUS_MENU_ITEM_ARTICLE_CREATE="Menus_Menu_Item_Article_Create" +JHELP_MENUS_MENU_ITEM_ARTICLE_FEATURED="Menus_Menu_Item_Article_Featured" +JHELP_MENUS_MENU_ITEM_ARTICLE_SINGLE_ARTICLE="Menus_Menu_Item_Article_Single_Article" +JHELP_MENUS_MENU_ITEM_CONTACT_CATEGORIES="Menus_Menu_Item_Contact_Categories" +JHELP_MENUS_MENU_ITEM_CONTACT_CATEGORY="Menus_Menu_Item_Contact_Category" +JHELP_MENUS_MENU_ITEM_CONTACT_FEATURED="Menus_Menu_Item_Contact_Featured" +JHELP_MENUS_MENU_ITEM_CONTACT_SINGLE_CONTACT="Menus_Menu_Item_Contact_Single_Contact" +JHELP_MENUS_MENU_ITEM_DISPLAY_SITE_CONFIGURATION="Menus_Menu_Item_Display_Site_Configuration" +JHELP_MENUS_MENU_ITEM_DISPLAY_TEMPLATE_OPTIONS="Menus_Menu_Item_Display_Template_Options" +JHELP_MENUS_MENU_ITEM_EXTERNAL_URL="Menus_Menu_Item_External_URL" +JHELP_MENUS_MENU_ITEM_FINDER_SEARCH="Menus_Menu_Item_Finder_Search" +JHELP_MENUS_MENU_ITEM_MANAGER="Menus_Menu_Item_Manager" +JHELP_MENUS_MENU_ITEM_MANAGER_EDIT="Menus_Menu_Item_Manager_Edit" +JHELP_MENUS_MENU_ITEM_MENU_ITEM_ALIAS="Menus_Menu_Item_Menu_Item_Alias" +JHELP_MENUS_MENU_ITEM_MENU_ITEM_HEADING="Menus_Menu_Item_Menu_Item_Heading" +JHELP_MENUS_MENU_ITEM_NEWSFEED_CATEGORIES="Menus_Menu_Item_Newsfeed_Categories" +JHELP_MENUS_MENU_ITEM_NEWSFEED_CATEGORY="Menus_Menu_Item_Newsfeed_Category" +JHELP_MENUS_MENU_ITEM_NEWSFEED_SINGLE_NEWSFEED="Menus_Menu_Item_Newsfeed_Single_Newsfeed" +JHELP_MENUS_MENU_ITEM_PRIVACY_CONFIRM_REQUEST="Menus_Menu_Item_Privacy_Confirm_Request" +JHELP_MENUS_MENU_ITEM_PRIVACY_CREATE_REQUEST="Menus_Menu_Item_Privacy_Create_Request" +JHELP_MENUS_MENU_ITEM_PRIVACY_REMIND_REQUEST="Menus_Menu_Item_Privacy_Remind_Request" +JHELP_MENUS_MENU_ITEM_SEARCH_RESULTS="Menus_Menu_Item_Search_Results" +JHELP_MENUS_MENU_ITEM_TAGS_ITEMS_COMPACT_LIST="Menus_Menu_Item_Tags_Items_Compact_List" +JHELP_MENUS_MENU_ITEM_TAGS_ITEMS_LIST="Menus_Menu_Item_Tags_Items_List" +JHELP_MENUS_MENU_ITEM_TAGS_ITEMS_LIST_ALL="Menus_Menu_Item_Tags_Items_List_All" +JHELP_MENUS_MENU_ITEM_TEXT_SEPARATOR="Menus_Menu_Item_Text_Separator" +JHELP_MENUS_MENU_ITEM_USER_LOGIN="Menus_Menu_Item_User_Login" +JHELP_MENUS_MENU_ITEM_USER_LOGOUT="Menus_Menu_Item_User_Logout" +JHELP_MENUS_MENU_ITEM_USER_PASSWORD_RESET="Menus_Menu_Item_User_Password_Reset" +JHELP_MENUS_MENU_ITEM_USER_PROFILE="Menus_Menu_Item_User_Profile" +JHELP_MENUS_MENU_ITEM_USER_PROFILE_EDIT="Menus_Menu_Item_User_Profile_Edit" +JHELP_MENUS_MENU_ITEM_USER_REGISTRATION="Menus_Menu_Item_User_Registration" +JHELP_MENUS_MENU_ITEM_USER_REMINDER="Menus_Menu_Item_User_Reminder" +JHELP_MENUS_MENU_ITEM_WEBLINK_CATEGORIES="Menus_Menu_Item_Weblink_Categories" +JHELP_MENUS_MENU_ITEM_WEBLINK_CATEGORY="Menus_Menu_Item_Weblink_Category" +JHELP_MENUS_MENU_ITEM_WEBLINK_SUBMIT="Menus_Menu_Item_Weblink_Submit" +JHELP_MENUS_MENU_ITEM_WRAPPER="Menus_Menu_Item_Wrapper" +JHELP_MENUS_MENU_MANAGER="Menus_Menu_Manager" +JHELP_MENUS_MENU_MANAGER_EDIT="Menus_Menu_Manager_Edit" +JHELP_SITE_GLOBAL_CONFIGURATION="Site_Global_Configuration" +JHELP_SITE_MAINTENANCE_CLEAR_CACHE="Site_Maintenance_Clear_Cache" +JHELP_SITE_MAINTENANCE_GLOBAL_CHECK-IN="Site_Maintenance_Global_Check-in" +JHELP_SITE_MAINTENANCE_PURGE_EXPIRED_CACHE="Site_Maintenance_Purge_Expired_Cache" +JHELP_SITE_SYSTEM_INFORMATION="Site_System_Information" +JHELP_ADMIN_USER_PROFILE_EDIT="Site_My_Profile" +JHELP_START_HERE="Start_Here" +JHELP_USERS_ACCESS_LEVELS="Users_Access_Levels" +JHELP_USERS_ACCESS_LEVELS_EDIT="Users_Access_Levels_Edit" +JHELP_USERS_DEBUG_GROUPS="Users_Debug_Groups" +JHELP_USERS_DEBUG_USERS="Users_Debug_Users" +JHELP_USERS_GROUPS="Users_Groups" +JHELP_USERS_GROUPS_EDIT="Users_Groups_Edit" +JHELP_USERS_MASS_MAIL_USERS="Users_Mass_Mail_Users" +JHELP_USERS_USER_MANAGER="Users_User_Manager" +JHELP_USERS_USER_MANAGER_EDIT="Users_User_Manager_Edit" +JHELP_USERS_USER_NOTES="Users_User_Notes" +JHELP_USERS_USER_NOTES_EDIT="Users_User_Notes_Edit" + +; if there is an error connecting database before initialisation, en-GB.lib_joomla.ini can't be loaded +; we therefore have to load the strings from en-GB.ini + +JLIB_DATABASE_ERROR_ADAPTER_MYSQL="The MySQL adapter 'mysql' is not available." +JLIB_DATABASE_ERROR_ADAPTER_MYSQLI="The MySQL adapter 'mysqli' is not available." +JLIB_DATABASE_ERROR_CONNECT_DATABASE="Unable to connect to the Database: %s" +JLIB_DATABASE_ERROR_CONNECT_MYSQL="Could not connect to MySQL." +JLIB_DATABASE_ERROR_DATABASE_CONNECT="Could not connect to database" +JLIB_DATABASE_ERROR_LOAD_DATABASE_DRIVER="Unable to load Database Driver: %s" +JLIB_ERROR_INFINITE_LOOP="Infinite loop detected in JError" + +JOPTION_ACCESS_SHOW_ALL_ACCESS="Show All Access" +JOPTION_ACCESS_SHOW_ALL_GROUPS="Show All Groups" +JOPTION_ACCESS_SHOW_ALL_LEVELS="Show All Access Levels" +JOPTION_ALL_CATEGORIES="- All Categories -" +JOPTION_ANY_CATEGORY="Any Category" +JOPTION_ANY="Any" +JOPTION_DO_NOT_USE="- None Selected -" +JOPTION_FROM_COMPONENT="---From Component---" +JOPTION_FROM_MODULE="---From Module---" +JOPTION_FROM_TEMPLATE="---From %s Template---" +JOPTION_FROM_STANDARD="---From Global Options---" +JOPTION_MENUS="Menus" +JOPTION_NO_USER="- No User -" +JOPTION_OPTIONAL="Optional" +JOPTION_ORDER_FIRST="Order First" +JOPTION_ORDER_LAST="Order Last" +JOPTION_REQUIRED="Required" +JOPTION_SELECT_ACCESS="- Select Access -" +JOPTION_SELECT_AUTHOR_ALIAS="- Select Author Alias -" +JOPTION_SELECT_AUTHOR_ALIASES="- Select Author Aliases -" +JOPTION_SELECT_AUTHOR="- Select Author -" +JOPTION_SELECT_AUTHORS="- Select Authors -" +JOPTION_SELECT_CATEGORY="- Select Category -" +JOPTION_SELECT_EDITOR="- Select Editor -" +JOPTION_SELECT_IMAGE="- Select Image -" +JOPTION_SELECT_LANGUAGE="- Select Language -" +JOPTION_SELECT_MENU="- Select Menu -" +JOPTION_SELECT_MENU_ITEM="- Select Menu Item -" +JOPTION_SELECT_PUBLISHED="- Select Status -" +JOPTION_SELECT_TEMPLATE="- Select Template -" +JOPTION_SELECT_MAX_LEVELS="- Select Max Levels -" +JOPTION_SELECT_TAG="- Select Tag -" +JOPTION_UNASSIGNED="Unassigned" +JOPTION_USE_DEFAULT_MODULE_SETTING="- Use Default Module Setting -" +JOPTION_USE_DEFAULT="- Use Default -" +JOPTION_USE_MENU_REQUEST_SETTING="- Use Menu or Request Setting -" + +JSEARCH_FILTER_LABEL="Filter:" +JSEARCH_FILTER_CLEAR="Clear" +JSEARCH_FILTER_SUBMIT="Search" +JSEARCH_FILTER="Search" +JSEARCH_TITLE="Search %s" +JSEARCH_RESET="Reset" + +JTOGGLE_SIDEBAR_LABEL="Sidebar" +JTOGGLE_HIDE_SIDEBAR="Hide the sidebar" +JTOGGLE_SHOW_SIDEBAR="Show the sidebar" + +JTOOLBAR_APPLY="Save" +JTOOLBAR_ARCHIVE="Archive" +JTOOLBAR_ASSIGN="Assign" +JTOOLBAR_ASSOCIATIONS="Associations" +JTOOLBAR_BACK="Back" +JTOOLBAR_BATCH="Batch" +JTOOLBAR_BULK_IMPORT="Bulk Import" +JTOOLBAR_CANCEL="Cancel" +JTOOLBAR_CHECKIN="Check-in" +JTOOLBAR_CLOSE="Close" +JTOOLBAR_DEFAULT="Default" +JTOOLBAR_DELETE="Delete" +JTOOLBAR_DELETE_ALL="Delete All" +JTOOLBAR_DISABLE="Disable" +JTOOLBAR_DUPLICATE="Duplicate" +JTOOLBAR_EDIT="Edit" +JTOOLBAR_EDIT_CSS="Edit CSS" +JTOOLBAR_EDIT_HTML="Edit HTML" +JTOOLBAR_EMPTY_TRASH="Empty trash" +JTOOLBAR_ENABLE="Enable" +JTOOLBAR_EXPORT="Export" +JTOOLBAR_HELP="Help" +JTOOLBAR_INSTALL="Install" +JTOOLBAR_NEW="New" +JTOOLBAR_OPTIONS="Options" +JTOOLBAR_PUBLISH="Publish" +JTOOLBAR_PURGE_CACHE="Clear Cache" +JTOOLBAR_REBUILD="Rebuild" +JTOOLBAR_REBUILD_FAILED="Rebuild failed: %s" +JTOOLBAR_REBUILD_SUCCESS="Successfully rebuilt" +JTOOLBAR_REFRESH_CACHE="Refresh Cache" +JTOOLBAR_REMOVE="Remove" +JTOOLBAR_SAVE="Save & Close" +JTOOLBAR_SAVE_AND_NEW="Save & New" +JTOOLBAR_SAVE_AS_COPY="Save as Copy" +JTOOLBAR_UNARCHIVE="Unarchive" +JTOOLBAR_UNINSTALL="Uninstall" +JTOOLBAR_UNPUBLISH="Unpublish" +JTOOLBAR_UPLOAD="Upload" +JTOOLBAR_TRASH="Trash" +JTOOLBAR_UNTRASH="Untrash" +JTOOLBAR_VERSIONS="Versions" + +JWARNING_PUBLISH_MUST_SELECT="You must select at least one item to publish." +JWARNING_ARCHIVE_MUST_SELECT="You must select at least one item to archive." +JWARNING_UNPUBLISH_MUST_SELECT="You must select at least one item to unpublish." +JWARNING_TRASH_MUST_SELECT="You must select at least one item to remove." +JWARNING_DELETE_MUST_SELECT="You must select at least one item to permanently delete." +JWARNING_REMOVE_ROOT_USER="You are logged-in using the emergency Root User setting in configuration.php.
    You should remove $root_user from the configuration.php as soon as you have restored control to your site to avoid future security breaches.
    Select here to try to do it automatically." +JWARNING_REMOVE_ROOT_USER_ADMIN="The emergency Root User setting is enabled for the user(id): %s.
    You should remove $root_user from the configuration.php as soon as you have restored control to your site to avoid future security breaches.
    Select here to try to do it automatically." + +; Date format + +DATE_FORMAT_LC="l, d F Y" +DATE_FORMAT_LC1="l, d F Y" +DATE_FORMAT_LC2="l, d F Y H:i" +DATE_FORMAT_LC3="d F Y" +DATE_FORMAT_LC4="Y-m-d" +DATE_FORMAT_LC5="Y-m-d H:i" +DATE_FORMAT_LC6="Y-m-d H:i:s" +DATE_FORMAT_JS1="y-m-d" +DATE_FORMAT_CALENDAR_DATE="%Y-%m-%d" +DATE_FORMAT_CALENDAR_DATETIME="%Y-%m-%d %H:%M:%S" +DATE_FORMAT_FILTER_DATE="Y-m-d" +DATE_FORMAT_FILTER_DATETIME="Y-m-d H:i:s" + +; Months + +JANUARY_SHORT="Jan" +JANUARY="January" +FEBRUARY_SHORT="Feb" +FEBRUARY="February" +MARCH_SHORT="Mar" +MARCH="March" +APRIL_SHORT="Apr" +APRIL="April" +MAY_SHORT="May" +MAY="May" +JUNE_SHORT="Jun" +JUNE="June" +JULY_SHORT="Jul" +JULY="July" +AUGUST_SHORT="Aug" +AUGUST="August" +SEPTEMBER_SHORT="Sep" +SEPTEMBER="September" +OCTOBER_SHORT="Oct" +OCTOBER="October" +NOVEMBER_SHORT="Nov" +NOVEMBER="November" +DECEMBER_SHORT="Dec" +DECEMBER="December" + +; Days of the Week + +SAT="Sat" +SATURDAY="Saturday" +SUN="Sun" +SUNDAY="Sunday" +MON="Mon" +MONDAY="Monday" +TUE="Tue" +TUESDAY="Tuesday" +WED="Wed" +WEDNESDAY="Wednesday" +THU="Thu" +THURSDAY="Thursday" +FRI="Fri" +FRIDAY="Friday" + +; Localised number format + +DECIMALS_SEPARATOR="." +THOUSANDS_SEPARATOR="," + +; Time Zones - this data has been removed as it is no longer used by Joomla 3.x + +; Mailer Codes +PHPMAILER_PROVIDE_ADDRESS="You must provide at least one recipient email address." +PHPMAILER_MAILER_IS_NOT_SUPPORTED="Mailer is not supported." +PHPMAILER_EXECUTE="Could not execute: " +PHPMAILER_EXTENSION_MISSING="Extension missing: " +PHPMAILER_INSTANTIATE="Could not start mail function." +PHPMAILER_AUTHENTICATE="SMTP Error! Could not authenticate." +PHPMAILER_FROM_FAILED="The following from address failed: " +PHPMAILER_RECIPIENTS_FAILED="SMTP Error! The following recipients failed: " +PHPMAILER_DATA_NOT_ACCEPTED="SMTP Error! Data not accepted." +PHPMAILER_CONNECT_HOST="SMTP Error! Could not connect to SMTP host." +PHPMAILER_FILE_ACCESS="Could not access file: " +PHPMAILER_FILE_OPEN="File Error: Could not open file: " +PHPMAILER_ENCODING="Unknown encoding: " +PHPMAILER_SIGNING_ERROR="Signing error: " +PHPMAILER_SMTP_ERROR="SMTP server error: " +PHPMAILER_EMPTY_MESSAGE="Empty message body" +PHPMAILER_INVALID_ADDRESS="Invalid address" +PHPMAILER_VARIABLE_SET="Can't set or reset variable: " +PHPMAILER_SMTP_CONNECT_FAILED="SMTP connect failed" +PHPMAILER_TLS="Could not start TLS" + +; Database types (allows for a more descriptive label than the internal name) +MYSQL="MySQL" +MYSQLI="MySQLi" +ORACLE="Oracle" +PGSQL="PostgreSQL (PDO)" +PDOMYSQL="MySQL (PDO)" +POSTGRESQL="PostgreSQL" +SQLAZURE="Microsoft SQL Azure" +SQLITE="SQLite" +SQLSRV="Microsoft SQL Server" + +; Search tools +JSEARCH_TOOLS="Search Tools" +JSEARCH_TOOLS_DESC="Filter the list items." +JSEARCH_TOOLS_ORDERING="Order by:" diff --git a/Sites/pages/administrator/language/en-GB/en-GB.lib_joomla.ini b/Sites/pages/administrator/language/en-GB/en-GB.lib_joomla.ini new file mode 100644 index 00000000..e96ed9cc --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.lib_joomla.ini @@ -0,0 +1,755 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +; Common boolean values +; Note: YES, NO, TRUE, FALSE are reserved words in INI format. + +; Keep this string on top +JERROR_PARSING_LANGUAGE_FILE=" : error(s) in line(s) %s" + +JLIB_APPLICATION_ERROR_ACCESS_FORBIDDEN="Access forbidden." +JLIB_APPLICATION_ERROR_APPLICATION_GET_NAME="JApplication: :getName() : Can't get or parse class name." +JLIB_APPLICATION_ERROR_APPLICATION_LOAD="Unable to load application: %s" +JLIB_APPLICATION_ERROR_BATCH_CANNOT_CREATE="You are not allowed to create new items in this category." +JLIB_APPLICATION_ERROR_BATCH_CANNOT_EDIT="You are not allowed to edit one or more of these items." +JLIB_APPLICATION_ERROR_BATCH_FAILED="Batch process failed with following error: %s" +JLIB_APPLICATION_ERROR_BATCH_MOVE_CATEGORY_NOT_FOUND="Can't find the destination category for this move." +JLIB_APPLICATION_ERROR_BATCH_MOVE_ROW_NOT_FOUND="Can't find the item being moved." +JLIB_APPLICATION_ERROR_CHECKIN_FAILED="Check-in failed with the following error: %s" +JLIB_APPLICATION_ERROR_CHECKIN_NOT_CHECKED="Item is not checked out." +JLIB_APPLICATION_ERROR_CHECKIN_USER_MISMATCH="The user checking in does not match the user who checked out the item." +JLIB_APPLICATION_ERROR_CHECKOUT_FAILED="Check-out failed with the following error: %s" +JLIB_APPLICATION_ERROR_CHECKOUT_USER_MISMATCH="The user checking out does not match the user who checked out the item." +JLIB_APPLICATION_ERROR_COMPONENT_NOT_FOUND="Component not found." +JLIB_APPLICATION_ERROR_COMPONENT_NOT_LOADING="Error loading component: %1$s, %2$s" +JLIB_APPLICATION_ERROR_CONTROLLER_GET_NAME="JController: :getName() : Can't get or parse class name." +JLIB_APPLICATION_ERROR_CREATE_RECORD_NOT_PERMITTED="Create record not permitted." +JLIB_APPLICATION_ERROR_DELETE_NOT_PERMITTED="Delete not permitted." +JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED="Edit state is not permitted." +JLIB_APPLICATION_ERROR_EDIT_ITEM_NOT_PERMITTED="Edit is not permitted." +JLIB_APPLICATION_ERROR_EDIT_NOT_PERMITTED="Edit not permitted." +JLIB_APPLICATION_ERROR_HISTORY_ID_MISMATCH="Error restoring item version from history." +JLIB_APPLICATION_ERROR_INSUFFICIENT_BATCH_INFORMATION="Insufficient information to perform the batch operation." +JLIB_APPLICATION_ERROR_INVALID_CONTROLLER_CLASS="Invalid controller class: %s" +JLIB_APPLICATION_ERROR_INVALID_CONTROLLER="Invalid controller: name='%s', format='%s'" +JLIB_APPLICATION_ERROR_LAYOUTFILE_NOT_FOUND="Layout %s not found." +JLIB_APPLICATION_ERROR_LIBRARY_NOT_FOUND="Library not found." +JLIB_APPLICATION_ERROR_LIBRARY_NOT_LOADING="Error loading library: %1$s, %2$s" +JLIB_APPLICATION_ERROR_MENU_LOAD="Error loading menu: %s" +JLIB_APPLICATION_ERROR_MODEL_GET_NAME="JModel: :getName() : Can't get or parse class name." +JLIB_APPLICATION_ERROR_MODULE_LOAD="Error loading module %s" +JLIB_APPLICATION_ERROR_PATHWAY_LOAD="Unable to load pathway: %s" +JLIB_APPLICATION_ERROR_REORDER_FAILED="Reorder failed. Error: %s" +JLIB_APPLICATION_ERROR_ROUTER_LOAD="Unable to load router: %s" +JLIB_APPLICATION_ERROR_MODELCLASS_NOT_FOUND="Model class %s not found in file." +JLIB_APPLICATION_ERROR_SAVE_FAILED="Save failed with the following error: %s" +JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED="Save not permitted." +JLIB_APPLICATION_ERROR_TABLE_NAME_NOT_SUPPORTED="Table %s not supported. File not found." +JLIB_APPLICATION_ERROR_TASK_NOT_FOUND="Task [%s] not found." +JLIB_APPLICATION_ERROR_UNHELD_ID="You are not permitted to use that link to directly access that page (#%d)." +JLIB_APPLICATION_ERROR_VIEW_CLASS_NOT_FOUND="View class not found [class, file]: %1$s, %2$s" +JLIB_APPLICATION_ERROR_VIEW_GET_NAME_SUBSTRING="JView: :getName() : Your classname has the substring 'view'. This causes problems when extracting the classname from the name of your objects view. Avoid Object names with the substring 'view'." +JLIB_APPLICATION_ERROR_VIEW_GET_NAME="JView: :getName() : Can't get or parse class name." +JLIB_APPLICATION_ERROR_VIEW_NOT_FOUND="View not found [name, type, prefix]: %1$s, %2$s, %3$s" +JLIB_APPLICATION_SAVE_SUCCESS="Item saved." +JLIB_APPLICATION_SUBMIT_SAVE_SUCCESS="Item submitted." +JLIB_APPLICATION_SUCCESS_BATCH="Batch process completed." +JLIB_APPLICATION_SUCCESS_ITEM_REORDERED="Ordering saved." +JLIB_APPLICATION_SUCCESS_ORDERING_SAVED="Ordering saved." +JLIB_APPLICATION_SUCCESS_LOAD_HISTORY="Prior version restored. Saved on %s %s." + +JLIB_LOGIN_AUTHENTICATE="Username and password do not match or you do not have an account yet." + +JLIB_CACHE_ERROR_CACHE_HANDLER_LOAD="Unable to load Cache Handler: %s" +JLIB_CACHE_ERROR_CACHE_STORAGE_LOAD="Unable to load Cache Storage: %s" + +JLIB_CAPTCHA_ERROR_PLUGIN_NOT_FOUND="Captcha plugin not set or not found. Please contact a site administrator." + +JLIB_CLIENT_ERROR_JFTP_NO_CONNECT="JFTP: :connect: Could not connect to host ' %1$s ' on port ' %2$s '" +JLIB_CLIENT_ERROR_JFTP_NO_CONNECT_SOCKET="JFTP: :connect: Could not connect to host ' %1$s ' on port ' %2$s '. Socket error number: %3$s and error message: %4$s" +JLIB_CLIENT_ERROR_JFTP_BAD_RESPONSE="JFTP: :connect: Bad response. Server response: %s [Expected: 220]" +JLIB_CLIENT_ERROR_JFTP_BAD_USERNAME="JFTP: :login: Bad Username. Server response: %1$s [Expected: 331]. Username sent: %2$s" +JLIB_CLIENT_ERROR_JFTP_BAD_PASSWORD="JFTP: :login: Bad Password. Server response: %1$s [Expected: 230]. Password sent: %2$s" +JLIB_CLIENT_ERROR_JFTP_PWD_BAD_RESPONSE_NATIVE="FTP: :pwd: Bad response." +JLIB_CLIENT_ERROR_JFTP_PWD_BAD_RESPONSE="JFTP: :pwd: Bad response. Server response: %s [Expected: 257]" +JLIB_CLIENT_ERROR_JFTP_SYST_BAD_RESPONSE_NATIVE="JFTP: :syst: Bad response." +JLIB_CLIENT_ERROR_JFTP_SYST_BAD_RESPONSE="JFTP: :syst: Bad response. Server response: %s [Expected: 215]" +JLIB_CLIENT_ERROR_JFTP_CHDIR_BAD_RESPONSE_NATIVE="JFTP: :chdir: Bad response." +JLIB_CLIENT_ERROR_JFTP_CHDIR_BAD_RESPONSE="JFTP: :chdir: Bad response. Server response: %1$s [Expected: 250]. Path sent: %2$s" +JLIB_CLIENT_ERROR_JFTP_REINIT_BAD_RESPONSE_NATIVE="JFTP: :reinit: Bad response." +JLIB_CLIENT_ERROR_JFTP_REINIT_BAD_RESPONSE="JFTP: :reinit: Bad response. Server response: %s [Expected: 220]" +JLIB_CLIENT_ERROR_JFTP_RENAME_BAD_RESPONSE_NATIVE="JFTP: :rename: Bad response." +JLIB_CLIENT_ERROR_JFTP_RENAME_BAD_RESPONSE_FROM="JFTP: :rename: Bad response. Server response: %1$s [Expected: 350]. From path sent: %2$s" +JLIB_CLIENT_ERROR_JFTP_RENAME_BAD_RESPONSE_TO="JFTP: :rename: Bad response. Server response: %1$s [Expected: 250]. To path sent: %2$s" +JLIB_CLIENT_ERROR_JFTP_CHMOD_BAD_RESPONSE_NATIVE="JFTP: :chmod: Bad response." +JLIB_CLIENT_ERROR_JFTP_CHMOD_BAD_RESPONSE="JFTP: :chmod: Bad response. Server response: %1$s [Expected: 250]. Path sent: %2$s. Mode sent: %3$s" +JLIB_CLIENT_ERROR_JFTP_DELETE_BAD_RESPONSE_NATIVE="JFTP: :delete: Bad response." +JLIB_CLIENT_ERROR_JFTP_DELETE_BAD_RESPONSE="JFTP: :delete: Bad response. Server response: %1$s [Expected: 250]. Path sent: %2$s" +JLIB_CLIENT_ERROR_JFTP_MKDIR_BAD_RESPONSE_NATIVE="JFTP: :mkdir: Bad response." +JLIB_CLIENT_ERROR_JFTP_MKDIR_BAD_RESPONSE="JFTP: :mkdir: Bad response. Server response: %1$s [Expected: 257]. Path sent: %2$s" +JLIB_CLIENT_ERROR_JFTP_RESTART_BAD_RESPONSE_NATIVE="JFTP: :restart: Bad response." +JLIB_CLIENT_ERROR_JFTP_RESTART_BAD_RESPONSE="JFTP: :restart: Bad response. Server response: %1$s [Expected: 350]. Restart point sent: %2$s" +JLIB_CLIENT_ERROR_JFTP_CREATE_BAD_RESPONSE_BUFFER="JFTP: :create: Bad response." +JLIB_CLIENT_ERROR_JFTP_CREATE_BAD_RESPONSE_PASSIVE="JFTP: :create: Unable to use passive mode." +JLIB_CLIENT_ERROR_JFTP_CREATE_BAD_RESPONSE="JFTP: :create: Bad response. Server response: %1$s [Expected: 150 or 125]. Path sent: %2$s" +JLIB_CLIENT_ERROR_JFTP_CREATE_BAD_RESPONSE_TRANSFER="JFTP: :create: Transfer Failed. Server response: %1$s [Expected: 226]. Path sent: %2$s" +JLIB_CLIENT_ERROR_JFTP_READ_BAD_RESPONSE_BUFFER="JFTP: :read: Bad response." +JLIB_CLIENT_ERROR_JFTP_READ_BAD_RESPONSE_PASSIVE="JFTP: :read: Unable to use passive mode." +JLIB_CLIENT_ERROR_JFTP_READ_BAD_RESPONSE="JFTP: :read: Bad response. Server response: %1$s [Expected: 150 or 125]. Path sent: %2$s" +JLIB_CLIENT_ERROR_JFTP_READ_BAD_RESPONSE_TRANSFER="JFTP: :read: Transfer Failed. Server response: %1$s [Expected: 226]. Path sent: %2$s" +JLIB_CLIENT_ERROR_JFTP_GET_BAD_RESPONSE="JFTP: :get: Bad response." +JLIB_CLIENT_ERROR_JFTP_GET_PASSIVE="JFTP: :get: Unable to use passive mode." +JLIB_CLIENT_ERROR_JFTP_GET_WRITING_LOCAL="JFTP: :get: Unable to open local file for writing. Local path: %s" +JLIB_CLIENT_ERROR_JFTP_GET_BAD_RESPONSE_RETR="JFTP: :get: Bad response. Server response: %1$s [Expected: 150 or 125]. Path sent: %2$s" +JLIB_CLIENT_ERROR_JFTP_GET_BAD_RESPONSE_TRANSFER="JFTP: :get: Transfer Failed. Server response: %1$s [Expected: 226]. Path sent: %2$s" +JLIB_CLIENT_ERROR_JFTP_STORE_PASSIVE="JFTP: :store: Unable to use passive mode." +JLIB_CLIENT_ERROR_JFTP_STORE_BAD_RESPONSE="JFTP: :store: Bad response." +JLIB_CLIENT_ERROR_JFTP_STORE_READING_LOCAL="JFTP: :store: Unable to open local file for reading. Local path: %s" +JLIB_CLIENT_ERROR_JFTP_STORE_FIND_LOCAL="JFTP: :store: Unable to find local file. Local path: %s" +JLIB_CLIENT_ERROR_JFTP_STORE_BAD_RESPONSE_STOR="JFTP: :store: Bad response. Server response: %1$s [Expected: 150 or 125]. Path sent: %2$s" +JLIB_CLIENT_ERROR_JFTP_STORE_DATA_PORT="JFTP: :store: Unable to write to data port socket." +JLIB_CLIENT_ERROR_JFTP_STORE_BAD_RESPONSE_TRANSFER="JFTP: :store: Transfer Failed. Server response: %1$s [Expected: 226]. Path sent: %2$s" +JLIB_CLIENT_ERROR_JFTP_WRITE_PASSIVE="JFTP: :write: Unable to use passive mode." +JLIB_CLIENT_ERROR_JFTP_WRITE_BAD_RESPONSE="JFTP: :write: Bad response." +JLIB_CLIENT_ERROR_JFTP_WRITE_BAD_RESPONSE_STOR="JFTP: :write: Bad response. Server response: %1$s [Expected: 150 or 125]. Path sent: %2$s" +JLIB_CLIENT_ERROR_JFTP_WRITE_DATA_PORT="JFTP: :write: Unable to write to data port socket." +JLIB_CLIENT_ERROR_JFTP_WRITE_BAD_RESPONSE_TRANSFER="JFTP: :write: Transfer Failed. Server response: %1$s [Expected: 226]. Path sent: %2$s" +JLIB_CLIENT_ERROR_JFTP_APPEND_PASSIVE="JFTP: :append: Unable to use passive mode" +JLIB_CLIENT_ERROR_JFTP_APPEND_BAD_RESPONSE="JFTP: :append: Bad response" +JLIB_CLIENT_ERROR_JFTP_APPEND_BAD_RESPONSE_APPE="JFTP: :append: Bad response. Server response: %1$s [Expected: 150 or 125]. Path sent: %2$s" +JLIB_CLIENT_ERROR_JFTP_APPEND_DATA_PORT="JFTP: :append: Unable to write to data port socket" +JLIB_CLIENT_ERROR_JFTP_APPEND_BAD_RESPONSE_TRANSFER="JFTP: :append: Transfer Failed. Server response: %1$s [Expected: 226]. Path sent: %2$s" +JLIB_CLIENT_ERROR_JFTP_SIZE_BAD_RESPONSE="JFTP: :size: Bad response" +JLIB_CLIENT_ERROR_JFTP_SIZE_PASSIVE="JFTP: :size: Unable to use passive mode" +JLIB_CLIENT_ERROR_JFTP_LISTNAMES_PASSIVE="JFTP: :listNames: Unable to use passive mode" +JLIB_CLIENT_ERROR_JFTP_LISTNAMES_BAD_RESPONSE="JFTP: :listNames: Bad response" +JLIB_CLIENT_ERROR_JFTP_LISTNAMES_BAD_RESPONSE_NLST="JFTP: :listNames: Bad response. Server response: %1$s [Expected: 150 or 125]. Path sent: %2$s" +JLIB_CLIENT_ERROR_JFTP_LISTNAMES_BAD_RESPONSE_TRANSFER="JFTP: :listNames: Transfer Failed. Server response: %1$s [Expected: 226]. Path sent: %2$s" +JLIB_CLIENT_ERROR_JFTP_LISTDETAILS_BAD_RESPONSE="JFTP: :listDetails: Bad response." +JLIB_CLIENT_ERROR_JFTP_LISTDETAILS_PASSIVE="JFTP: :listDetails: Unable to use passive mode." +JLIB_CLIENT_ERROR_JFTP_LISTDETAILS_BAD_RESPONSE_LIST="JFTP: :listDetails: Bad response. Server response: %1$s [Expected: 150 or 125]. Path sent: %2$s" +JLIB_CLIENT_ERROR_JFTP_LISTDETAILS_BAD_RESPONSE_TRANSFER="JFTP: :listDetails: Transfer Failed. Server response: %1$s [Expected: 226]. Path sent: %2$s" +JLIB_CLIENT_ERROR_JFTP_LISTDETAILS_UNRECOGNISED="JFTP: :listDetails: Unrecognised folder listing format." +JLIB_CLIENT_ERROR_JFTP_PUTCMD_UNCONNECTED="JFTP: :_putCmd: Not connected to the control port." +JLIB_CLIENT_ERROR_JFTP_PUTCMD_SEND="JFTP: :_putCmd: Unable to send command: %s" +JLIB_CLIENT_ERROR_JFTP_VERIFYRESPONSE="JFTP: :_verifyResponse: Timeout or unrecognised response while waiting for a response from the server. Server response: %s" +JLIB_CLIENT_ERROR_JFTP_PASSIVE_CONNECT_PORT="JFTP: :_passive: Not connected to the control port." +JLIB_CLIENT_ERROR_JFTP_PASSIVE_RESPONSE="JFTP: :_passive: Timeout or unrecognised response while waiting for a response from the server. Server response: %s" +JLIB_CLIENT_ERROR_JFTP_PASSIVE_IP_OBTAIN="JFTP: :_passive: Unable to obtain IP and port for data transfer. Server response: %s" +JLIB_CLIENT_ERROR_JFTP_PASSIVE_IP_VALID="JFTP: :_passive: IP and port for data transfer not valid. Server response: %s" +JLIB_CLIENT_ERROR_JFTP_PASSIVE_CONNECT="JFTP: :_passive: Could not connect to host %1$s on port %2$s. Socket error number: %3$s and error message: %4$s" +JLIB_CLIENT_ERROR_JFTP_MODE_BINARY="JFTP: :_mode: Bad response. Server response: %s [Expected: 200]. Mode sent: Binary." +JLIB_CLIENT_ERROR_JFTP_MODE_ASCII="JFTP: :_mode: Bad response. Server response: %s [Expected: 200]. Mode sent: Ascii." +JLIB_CLIENT_ERROR_HELPER_SETCREDENTIALSFROMREQUEST_FAILED="Looks like User's credentials are no good." +JLIB_CLIENT_ERROR_LDAP_ADDRESS_NOT_AVAILABLE="Address not available." + +JLIB_CMS_WARNING_PROVIDE_VALID_NAME="Please provide a valid, non-blank title." + +JLIB_DATABASE_ERROR_ADAPTER_MYSQL="The MySQL adapter 'mysql' is not available." +JLIB_DATABASE_ERROR_ADAPTER_MYSQLI="The MySQL adapter 'mysqli' is not available." +JLIB_DATABASE_ERROR_BIND_FAILED_INVALID_SOURCE_ARGUMENT="%s: :bind failed. Invalid source argument." +JLIB_DATABASE_ERROR_ARTICLE_UNIQUE_ALIAS="Another article from this category has the same alias (remember it may be a trashed item)." +JLIB_DATABASE_ERROR_CATEGORY_UNIQUE_ALIAS="Another category with the same parent category has the same alias (remember it may be a trashed item)." +JLIB_DATABASE_ERROR_CHECK_FAILED="%s: :check Failed - %s" +JLIB_DATABASE_ERROR_CHECKIN_FAILED="%s: :check-in failed - %s" +JLIB_DATABASE_ERROR_CHECKOUT_FAILED="%s: :check-out failed - %s" +JLIB_DATABASE_ERROR_CHILD_ROWS_CHECKED_OUT="Child rows checked out." +JLIB_DATABASE_ERROR_CLASS_DOES_NOT_SUPPORT_ORDERING="%s does not support ordering." +JLIB_DATABASE_ERROR_CLASS_IS_MISSING_FIELD="Missing field in the database: %s   %s." +JLIB_DATABASE_ERROR_CLASS_NOT_FOUND_IN_FILE="Table class %s not found in file." +JLIB_DATABASE_ERROR_CONNECT_DATABASE="Unable to connect to the Database: %s" +JLIB_DATABASE_ERROR_CONNECT_MYSQL="Could not connect to MySQL." +JLIB_DATABASE_ERROR_DATABASE_CONNECT="Could not connect to database." +JLIB_DATABASE_ERROR_DATABASE_UPGRADE_FAILED="MySQL Database Upgrade failed. Please check the Database Fixer." +JLIB_DATABASE_ERROR_DELETE_CATEGORY="Left-Right data inconsistency. Can't delete category." +JLIB_DATABASE_ERROR_DELETE_FAILED="%s: :delete failed - %s" +JLIB_DATABASE_ERROR_DELETE_ROOT_CATEGORIES="Root categories can't be deleted." +JLIB_DATABASE_ERROR_EMAIL_INUSE="The email address you entered is already in use. Please enter another email address." +JLIB_DATABASE_ERROR_EMPTY_ROW_RETURNED="The database row is empty." +JLIB_DATABASE_ERROR_FUNCTION_FAILED="DB function failed with error number %s
    %s" +JLIB_DATABASE_ERROR_GET_NEXT_ORDER_FAILED="%s: :getNextOrder failed - %s" +JLIB_DATABASE_ERROR_GET_TREE_FAILED="%s: :getTree Failed - %s" +JLIB_DATABASE_ERROR_GETNODE_FAILED="%s: :_getNode Failed - %s" +JLIB_DATABASE_ERROR_GETROOTID_FAILED="%s: :getRootId Failed - %s" +JLIB_DATABASE_ERROR_HIT_FAILED="%s: :hit failed - %s" +JLIB_DATABASE_ERROR_INVALID_LOCATION="%s: :setLocation - Invalid location." +JLIB_DATABASE_ERROR_INVALID_NODE_RECURSION="%s: :move Failed - Can't move the node to be a child of itself." +JLIB_DATABASE_ERROR_INVALID_PARENT_ID="Invalid parent ID." +JLIB_DATABASE_ERROR_LANGUAGE_NO_TITLE="The language should have a title." +JLIB_DATABASE_ERROR_LANGUAGE_UNIQUE_IMAGE="A content language already exists with this Image." +JLIB_DATABASE_ERROR_LANGUAGE_UNIQUE_LANG_CODE="A content language already exists with this Language Tag." +JLIB_DATABASE_ERROR_LANGUAGE_UNIQUE_SEF="A content language already exists with this URL Language Code." +JLIB_DATABASE_ERROR_LOAD_DATABASE_DRIVER="Unable to load Database Driver: %s" +JLIB_DATABASE_ERROR_MENUTYPE="Some menu items or some menu modules related to this menutype are checked out by another user or the default menu item is in this menu." +JLIB_DATABASE_ERROR_MENUTYPE_CHECKOUT="The user checking out does not match the user who checked out this menu and/or its linked menu module." +JLIB_DATABASE_ERROR_MENUTYPE_EMPTY="Menu type empty." +JLIB_DATABASE_ERROR_MENUTYPE_EXISTS="Menu type exists: %s" +JLIB_DATABASE_ERROR_MENU_CANNOT_UNSET_DEFAULT="The Language parameter for this menu item must be set to 'All'. At least one Default menu item must have Language set to All, even if the site is multilingual." +JLIB_DATABASE_ERROR_MENU_CANNOT_UNSET_DEFAULT_DEFAULT="At least one menu item has to be set as Default." +JLIB_DATABASE_ERROR_MENU_UNPUBLISH_DEFAULT_HOME="Can't unpublish default home." +JLIB_DATABASE_ERROR_MENU_DEFAULT_CHECKIN_USER_MISMATCH="The current home menu for this language is checked out." +JLIB_DATABASE_ERROR_MENU_UNIQUE_ALIAS="The alias %1$s is already being used by %2$s menu item in the %3$s menu (remember it may be a trashed item)." +JLIB_DATABASE_ERROR_MENU_UNIQUE_ALIAS_ROOT="Another menu item has the same alias in Root (remember it may be a trashed item). Root is the top level parent." +JLIB_DATABASE_ERROR_MENU_HOME_NOT_COMPONENT="The home menu item must be a component." +JLIB_DATABASE_ERROR_MENU_HOME_NOT_UNIQUE_IN_MENU="A menu should have only one Default home." +JLIB_DATABASE_ERROR_MENU_ROOT_ALIAS_COMPONENT="A first level menu item alias can't be 'component'." +JLIB_DATABASE_ERROR_MENU_ROOT_ALIAS_FOLDER="A first level menu item alias can't be '%s' because '%s' is a sub-folder of your joomla installation folder." +JLIB_DATABASE_ERROR_MOVE_FAILED="%s: :move failed - %s" +JLIB_DATABASE_ERROR_MUSTCONTAIN_A_TITLE_CATEGORY="Category must have a title." +JLIB_DATABASE_ERROR_MUSTCONTAIN_A_TITLE_EXTENSION="Extension must have a title." +JLIB_DATABASE_ERROR_MUSTCONTAIN_A_TITLE_MENUITEM="Menu Item must have a title." +JLIB_DATABASE_ERROR_MUSTCONTAIN_A_TITLE_MODULE="Module must have a title." +JLIB_DATABASE_ERROR_MUSTCONTAIN_A_TITLE_UPDATESITE="Update site must have a title." +JLIB_DATABASE_ERROR_NEGATIVE_NOT_PERMITTED="%s can't be negative." +JLIB_DATABASE_ERROR_NO_ROWS_SELECTED="No rows selected." +JLIB_DATABASE_ERROR_NOT_SUPPORTED_FILE_NOT_FOUND="Table %s not supported. File not found." +JLIB_DATABASE_ERROR_NULL_PRIMARY_KEY="Null primary key not allowed." +JLIB_DATABASE_ERROR_ORDERDOWN_FAILED="%s: :orderDown Failed - %s" +JLIB_DATABASE_ERROR_ORDERUP_FAILED="%s: :orderUp Failed - %s" +JLIB_DATABASE_ERROR_PLEASE_ENTER_A_USER_NAME="Please enter a username." +JLIB_DATABASE_ERROR_PLEASE_ENTER_YOUR_NAME="Please enter your name." +JLIB_DATABASE_ERROR_PUBLISH_FAILED="%s: :publish failed - %s" +JLIB_DATABASE_ERROR_REBUILD_FAILED="%s: :rebuild Failed - %s" +JLIB_DATABASE_ERROR_REBUILDPATH_FAILED="%s: :rebuildPath Failed - %s" +JLIB_DATABASE_ERROR_REORDER_FAILED="%s: :reorder failed - %s" +JLIB_DATABASE_ERROR_REORDER_UPDATE_ROW_FAILED="%s: :reorder update the row %s failed - %s" +JLIB_DATABASE_ERROR_ROOT_NODE_NOT_FOUND="Root node not found." +JLIB_DATABASE_ERROR_STORE_FAILED_UPDATE_ASSET_ID="The asset_id field could not be updated." +JLIB_DATABASE_ERROR_STORE_FAILED="%1$s: :store failed
    %2$s" +JLIB_DATABASE_ERROR_USERGROUP_PARENT_ID_NOT_VALID="There has to be at least one root usergroup" +JLIB_DATABASE_ERROR_USERGROUP_TITLE="User group must have a title." +JLIB_DATABASE_ERROR_USERGROUP_TITLE_EXISTS="User group title already exists. Title must be unique with the same parent." +JLIB_DATABASE_ERROR_USERLEVEL_NAME_EXISTS="Level with the name "%s" already exists." +JLIB_DATABASE_ERROR_USERNAME_CANNOT_CHANGE="Can't use this username." +JLIB_DATABASE_ERROR_USERNAME_INUSE="Username in use." +JLIB_DATABASE_ERROR_VALID_AZ09="Please enter a valid username. No space at beginning or end, at least %d characters, must not have the following characters: < > \ " ' % ; ( ) & and be less than 150 characters long." +JLIB_DATABASE_ERROR_VALID_MAIL="The email address you entered is invalid. Please enter another email address." +JLIB_DATABASE_ERROR_VIEWLEVEL="Viewlevel must have a title." +JLIB_DATABASE_FUNCTION_NOERROR="DB function reports no errors." +JLIB_DATABASE_QUERY_FAILED="Database query failed (error # %s): %s" + +JLIB_DOCUMENT_ERROR_UNABLE_LOAD_DOC_CLASS="Unable to load document class." +JLIB_ENVIRONMENT_SESSION_EXPIRED="Your session has expired. Please log in again." +JLIB_ENVIRONMENT_SESSION_INVALID="Invalid session cookie. Please check that you have cookies enabled in your web browser." +JLIB_ERROR_COMPONENTS_ACL_CONFIGURATION_FILE_MISSING_OR_IMPROPERLY_STRUCTURED="The %s component's ACL configuration file is either missing or improperly structured." +JLIB_ERROR_INFINITE_LOOP="Infinite loop detected in JError." +JLIB_EVENT_ERROR_DISPATCHER="JEventDispatcher: :register: Event handler not recognised. Handler: %s" +JLIB_FILESYSTEM_BZIP_NOT_SUPPORTED="BZip2 Not Supported." +JLIB_FILESYSTEM_BZIP_UNABLE_TO_READ="Unable to read archive (bz2)." +JLIB_FILESYSTEM_BZIP_UNABLE_TO_WRITE="Unable to write archive (bz2)." +JLIB_FILESYSTEM_BZIP_UNABLE_TO_WRITE_FILE="Unable to write file (bz2)." +JLIB_FILESYSTEM_GZIP_NOT_SUPPORTED="GZlib Not Supported." +JLIB_FILESYSTEM_GZIP_UNABLE_TO_READ="Unable to read archive (gz)." +JLIB_FILESYSTEM_GZIP_UNABLE_TO_WRITE="Unable to write archive (gz)." +JLIB_FILESYSTEM_GZIP_UNABLE_TO_WRITE_FILE="Unable to write file (gz)." +JLIB_FILESYSTEM_GZIP_UNABLE_TO_DECOMPRESS="Unable to decompress data." +JLIB_FILESYSTEM_TAR_UNABLE_TO_READ="Unable to read archive (tar)." +JLIB_FILESYSTEM_TAR_UNABLE_TO_DECOMPRESS="Unable to decompress data." +JLIB_FILESYSTEM_TAR_UNABLE_TO_CREATE_DESTINATION="Unable to create destination." +JLIB_FILESYSTEM_TAR_UNABLE_TO_WRITE_ENTRY="Unable to write entry." +JLIB_FILESYSTEM_ZIP_NOT_SUPPORTED="Zlib Not Supported." +JLIB_FILESYSTEM_ZIP_UNABLE_TO_READ="Unable to read archive (zip)." +JLIB_FILESYSTEM_ZIP_INFO_FAILED="Get ZIP Information failed." +JLIB_FILESYSTEM_ZIP_UNABLE_TO_CREATE_DESTINATION="Unable to create destination." +JLIB_FILESYSTEM_ZIP_UNABLE_TO_WRITE_ENTRY="Unable to write entry." +JLIB_FILESYSTEM_ZIP_UNABLE_TO_READ_ENTRY="Unable to read entry." +JLIB_FILESYSTEM_ZIP_UNABLE_TO_OPEN_ARCHIVE="Unable to open archive." +JLIB_FILESYSTEM_ZIP_INVALID_ZIP_DATA="Invalid ZIP data." +JLIB_FILESYSTEM_STREAM_FAILED="Failed to register string stream." +JLIB_FILESYSTEM_UNKNOWNARCHIVETYPE="Unknown Archive type." +JLIB_FILESYSTEM_UNABLE_TO_LOAD_ARCHIVE="Unable to load archive." +JLIB_FILESYSTEM_ERROR_JFILE_FIND_COPY="JFile: :copy: Can't find or read file: %s" +JLIB_FILESYSTEM_ERROR_JFILE_STREAMS="JFile: :copy(%1$s, %2$s): %3$s" +JLIB_FILESYSTEM_ERROR_COPY_FAILED="Copy failed." +JLIB_FILESYSTEM_ERROR_COPY_FAILED_ERR01="Copy failed: %1$s to %2$s" +JLIB_FILESYSTEM_DELETE_FAILED="Failed deleting %s" +JLIB_FILESYSTEM_CANNOT_FIND_SOURCE_FILE="Can't find source file." +JLIB_FILESYSTEM_ERROR_JFILE_MOVE_STREAMS="JFile: :move: %s" +JLIB_FILESYSTEM_ERROR_RENAME_FILE="Rename failed." +JLIB_FILESYSTEM_ERROR_READ_UNABLE_TO_OPEN_FILE="JFile: :read: Unable to open file: %s" +JLIB_FILESYSTEM_ERROR_WRITE_STREAMS="JFile: :write(%1$s): %2$s" +JLIB_FILESYSTEM_ERROR_UPLOAD="JFile: :upload: %s" +JLIB_FILESYSTEM_ERROR_WARNFS_ERR01="Warning: Failed to change file permissions!" +JLIB_FILESYSTEM_ERROR_WARNFS_ERR02="Warning: Failed to move file!" +JLIB_FILESYSTEM_ERROR_WARNFS_ERR03="Warning: File %s not uploaded for security reasons!" +JLIB_FILESYSTEM_ERROR_WARNFS_ERR04="Warning: Failed to move file: %1$s to %2$s" +JLIB_FILESYSTEM_ERROR_FIND_SOURCE_FOLDER="Can't find source folder." +JLIB_FILESYSTEM_ERROR_FOLDER_EXISTS="Folder already exists." +JLIB_FILESYSTEM_ERROR_FOLDER_CREATE="Unable to create target folder." +JLIB_FILESYSTEM_ERROR_FOLDER_OPEN="Unable to open source folder." +JLIB_FILESYSTEM_ERROR_FOLDER_LOOP="Infinite loop detected." +JLIB_FILESYSTEM_ERROR_FOLDER_PATH="Path not in open_basedir paths." +JLIB_FILESYSTEM_ERROR_COULD_NOT_CREATE_DIRECTORY="Could not create folder." +JLIB_FILESYSTEM_ERROR_DELETE_BASE_DIRECTORY="You can't delete a base folder." +JLIB_FILESYSTEM_ERROR_PATH_IS_NOT_A_FOLDER="JFolder: :delete: Path is not a folder. Path: %s" +JLIB_FILESYSTEM_ERROR_FOLDER_DELETE="JFolder: :delete: Could not delete folder. Path: %s" +JLIB_FILESYSTEM_ERROR_FOLDER_RENAME="Rename failed: %s" +JLIB_FILESYSTEM_ERROR_PATH_IS_NOT_A_FOLDER_FILES="JFolder: :files: Path is not a folder. Path: %s" +JLIB_FILESYSTEM_ERROR_PATH_IS_NOT_A_FOLDER_FOLDER="JFolder: :folder: Path is not a folder. Path: %s" +JLIB_FILESYSTEM_ERROR_STREAMS_FILE_SIZE="Failed to get file size. This may not work for all streams!" +JLIB_FILESYSTEM_ERROR_STREAMS_FILE_NOT_OPEN="File not open." +JLIB_FILESYSTEM_ERROR_STREAMS_FILENAME="File name not set." +JLIB_FILESYSTEM_ERROR_NO_DATA_WRITTEN="Warning: No data written." +JLIB_FILESYSTEM_ERROR_STREAMS_FAILED_TO_OPEN_WRITER="Failed to open writer: %s" +JLIB_FILESYSTEM_ERROR_STREAMS_FAILED_TO_OPEN_READER="Failed to open reader: %s" +JLIB_FILESYSTEM_ERROR_STREAMS_NOT_UPLOADED_FILE="Not an uploaded file!" + +JLIB_FILTER_PARAMS_ALNUM="Alpha Numeric" +JLIB_FILTER_PARAMS_FLOAT="Float" +JLIB_FILTER_PARAMS_INTEGER="Integer" +JLIB_FILTER_PARAMS_RAW="Raw" +JLIB_FILTER_PARAMS_SAFEHTML="Safe HTML" +JLIB_FILTER_PARAMS_TEL="Telephone" +JLIB_FILTER_PARAMS_TEXT="Text" + +JLIB_FORM_BUTTON_CLEAR="Clear" +JLIB_FORM_BUTTON_SELECT="Select" +JLIB_FORM_CHANGE_IMAGE="Change Image" +JLIB_FORM_CHANGE_IMAGE_BUTTON="Change Image Button" +JLIB_FORM_CHANGE_USER="Select User" +JLIB_FORM_ERROR_FIELDS_CATEGORY_ERROR_EXTENSION_EMPTY="Extension attribute is empty in the category field." +JLIB_FORM_ERROR_FIELDS_GROUPEDLIST_ELEMENT_NAME="Unknown element type: %s" +JLIB_FORM_ERROR_NO_DATA="No data." +JLIB_FORM_ERROR_VALIDATE_FIELD="Invalid xml field." +JLIB_FORM_ERROR_XML_FILE_DID_NOT_LOAD="XML file did not load." +JLIB_FORM_FIELD_INVALID="Invalid field: " +JLIB_FORM_INPUTMODE="latin" +JLIB_FORM_INVALID_FORM_OBJECT="Invalid Form Object: :%s" +JLIB_FORM_INVALID_FORM_RULE="Invalid Form Rule: :%s" +JLIB_FORM_MEDIA_PREVIEW_ALT="Selected image." +JLIB_FORM_MEDIA_PREVIEW_EMPTY="No image selected." +JLIB_FORM_MEDIA_PREVIEW_SELECTED_IMAGE="Selected image." +JLIB_FORM_MEDIA_PREVIEW_TIP_TITLE="Preview" +JLIB_FORM_SELECT_USER="Select a User" +JLIB_FORM_VALIDATE_FIELD_INVALID="Invalid field: %s" +JLIB_FORM_VALIDATE_FIELD_REQUIRED="Field required: %s" +JLIB_FORM_VALIDATE_FIELD_RULE_MISSING="Validation Rule missing: %s" +JLIB_FORM_VALIDATE_FIELD_URL_SCHEMA_MISSING="Invalid URL: URL schema is missing in %1$s. Please add one of the following at the beginning: %2$s." +JLIB_FORM_VALUE_CACHE_APC="Alternative PHP Cache" +JLIB_FORM_VALUE_CACHE_APCU="APC User Cache" +JLIB_FORM_VALUE_CACHE_CACHELITE="Cache_Lite" +JLIB_FORM_VALUE_CACHE_EACCELERATOR="eAccelerator" +JLIB_FORM_VALUE_CACHE_FILE="File" +JLIB_FORM_VALUE_CACHE_MEMCACHE="Memcache" +JLIB_FORM_VALUE_CACHE_MEMCACHED="Memcached (Experimental)" +JLIB_FORM_VALUE_CACHE_REDIS="Redis" +JLIB_FORM_VALUE_CACHE_WINCACHE="Windows Cache" +JLIB_FORM_VALUE_CACHE_XCACHE="XCache" +JLIB_FORM_VALUE_SESSION_APC="Alternative PHP Cache" +JLIB_FORM_VALUE_SESSION_APCU="APC User Cache" +JLIB_FORM_VALUE_SESSION_DATABASE="Database" +JLIB_FORM_VALUE_SESSION_EACCELERATOR="eAccelerator" +JLIB_FORM_VALUE_SESSION_MEMCACHE="Memcache" +JLIB_FORM_VALUE_SESSION_MEMCACHED="Memcached (Experimental)" +JLIB_FORM_VALUE_SESSION_NONE="PHP" +JLIB_FORM_VALUE_SESSION_REDIS="Redis" +JLIB_FORM_VALUE_SESSION_WINCACHE="Windows Cache" +JLIB_FORM_VALUE_SESSION_XCACHE="XCache" +JLIB_FORM_VALUE_TIMEZONE_UTC="Universal Time, Coordinated (UTC)" +JLIB_FORM_VALUE_FROM_TEMPLATE="From Template" +JLIB_FORM_VALUE_INHERITED="Inherited" + +JLIB_HTML_ACCESS_MODIFY_DESC_CAPTION_ACL="ACL" +JLIB_HTML_ACCESS_MODIFY_DESC_CAPTION_TABLE="Table" +JLIB_HTML_ACCESS_SUMMARY_DESC_CAPTION="ACL Summary Table" +JLIB_HTML_ACCESS_SUMMARY_DESC="Shown below is an overview of the permission settings for this article. Select the tabs above to customise these settings by action." +JLIB_HTML_ACCESS_SUMMARY="Summary." +JLIB_HTML_ADD_TO_ROOT="Add to root." +JLIB_HTML_ADD_TO_THIS_MENU="Add to this menu." +JLIB_HTML_BATCH_ACCESS_LABEL="Set Access Level" +JLIB_HTML_BATCH_ACCESS_LABEL_DESC="Not making a selection will keep the original access levels when processing." +JLIB_HTML_BATCH_COPY="Copy" +JLIB_HTML_BATCH_FLIPORDERING_LABEL="Reverse the ordering of all articles in the selected categories" +JLIB_HTML_BATCH_LANGUAGE_LABEL="Set Language" +JLIB_HTML_BATCH_LANGUAGE_LABEL_DESC="Not making a selection will keep the original language when processing." +JLIB_HTML_BATCH_LANGUAGE_NOCHANGE="- Keep original Language -" +JLIB_HTML_BATCH_MENU_LABEL="To Move or Copy your selection please select a Category." +JLIB_HTML_BATCH_MOVE="Move" +JLIB_HTML_BATCH_MOVE_QUESTION="Do you want to move the items or make a copy of them?" +JLIB_HTML_BATCH_NO_CATEGORY="- Don't move or copy -" +JLIB_HTML_BATCH_NOCHANGE="- Keep original Access Levels -" +JLIB_HTML_BATCH_TAG_LABEL="Add Tag" +JLIB_HTML_BATCH_TAG_LABEL_DESC="Add a tag to selected items." +JLIB_HTML_BATCH_TAG_NOCHANGE="- Keep original Tags -" +JLIB_HTML_BATCH_USER_LABEL="Set User." +JLIB_HTML_BATCH_USER_LABEL_DESC="Not making a selection will keep the original user when processing." +JLIB_HTML_BATCH_USER_NOCHANGE="- Keep original User -" +JLIB_HTML_BATCH_USER_NOUSER="No User." +JLIB_HTML_BEHAVIOR_ABOUT_THE_CALENDAR="About the Calendar" +JLIB_HTML_BEHAVIOR_CLOSE="Close" +JLIB_HTML_BEHAVIOR_DATE_SELECTION="Date selection:\n" +JLIB_HTML_BEHAVIOR_DISPLAY_S_FIRST="Display %s first" +JLIB_HTML_BEHAVIOR_DRAG_TO_MOVE="Drag to move." +JLIB_HTML_BEHAVIOR_GO_TODAY="Go to today" +JLIB_HTML_BEHAVIOR_GREEN="Green" +JLIB_HTML_BEHAVIOR_HOLD_MOUSE="- Hold mouse button on any of the buttons above for faster selection." +JLIB_HTML_BEHAVIOR_MONTH_SELECT="- Use the < and > buttons to select month\n" +JLIB_HTML_BEHAVIOR_NEXT_MONTH_HOLD_FOR_MENU="Select to move to the next month. Select and hold for a list of the months." +JLIB_HTML_BEHAVIOR_NEXT_YEAR_HOLD_FOR_MENU="Select to move to the next year. Select and hold for a list of years." +JLIB_HTML_BEHAVIOR_OPEN_CALENDAR="Open the calendar" +JLIB_HTML_BEHAVIOR_PREV_MONTH_HOLD_FOR_MENU="Select to move to the previous month. Select and hold for a list of the months." +JLIB_HTML_BEHAVIOR_PREV_YEAR_HOLD_FOR_MENU="Select to move to the previous year. Select and hold for a list of years." +JLIB_HTML_BEHAVIOR_SELECT_DATE="Select a date." +JLIB_HTML_BEHAVIOR_SHIFT_CLICK_OR_DRAG_TO_CHANGE_VALUE="(Shift-)Select or Drag to change the value." +JLIB_HTML_BEHAVIOR_TIME="Time:" +JLIB_HTML_BEHAVIOR_TODAY="Today" +JLIB_HTML_BEHAVIOR_TT_DATE_FORMAT="%a, %b %e" +JLIB_HTML_BEHAVIOR_WK="wk" +JLIB_HTML_BEHAVIOR_YEAR_SELECT="- Use the « and » buttons to select year\n" +JLIB_HTML_BUTTON_BASE_CLASS="Could not load button base class." +JLIB_HTML_BUTTON_NO_LOAD="Could not load button %s (%s);" +JLIB_HTML_BUTTON_NOT_DEFINED="Button not defined for type = %s" +JLIB_HTML_CALENDAR="Calendar" +JLIB_HTML_CHECKED_OUT="Checked out" +JLIB_HTML_CHECKIN="Check-in" +JLIB_HTML_CLOAKING="This email address is being protected from spambots. You need JavaScript enabled to view it." +JLIB_HTML_DATE_RELATIVE_DAYS="%s days ago." +JLIB_HTML_DATE_RELATIVE_DAYS_1="%s day ago." +JLIB_HTML_DATE_RELATIVE_DAYS_0="%s days ago." +JLIB_HTML_DATE_RELATIVE_HOURS="%s hours ago." +JLIB_HTML_DATE_RELATIVE_HOURS_1="%s hour ago." +JLIB_HTML_DATE_RELATIVE_HOURS_0="%s hours ago." +JLIB_HTML_DATE_RELATIVE_LESSTHANAMINUTE="Less than a minute ago." +JLIB_HTML_DATE_RELATIVE_MINUTES="%s minutes ago." +JLIB_HTML_DATE_RELATIVE_MINUTES_1="%s minute ago." +JLIB_HTML_DATE_RELATIVE_MINUTES_0="%s minutes ago." +JLIB_HTML_DATE_RELATIVE_WEEKS="%s weeks ago." +JLIB_HTML_DATE_RELATIVE_WEEKS_1="%s week ago." +JLIB_HTML_DATE_RELATIVE_WEEKS_0="%s weeks ago." +JLIB_HTML_EDIT_MENU_ITEM="Edit menu item." +JLIB_HTML_EDIT_MENU_ITEM_ID="Item ID: %s" +JLIB_HTML_EDIT_MODULE="Edit module" +JLIB_HTML_EDIT_MODULE_IN_POSITION="Position: %s" +JLIB_HTML_EDITOR_CANNOT_LOAD="Can't load the editor." +JLIB_HTML_END="End" +JLIB_HTML_ERROR_FUNCTION_NOT_SUPPORTED="Function not supported." +JLIB_HTML_ERROR_NOTFOUNDINFILE="%s: :%s not found in file." +JLIB_HTML_ERROR_NOTSUPPORTED_NOFILE="%s: :%s not supported. File not found." +JLIB_HTML_ERROR_NOTSUPPORTED="%s: :%s not supported." +JLIB_HTML_GOTO_PAGE="Go to page %s" +JLIB_HTML_GOTO_POSITION="Go to %s page" +JLIB_HTML_MOVE_DOWN="Move Down" +JLIB_HTML_MOVE_UP="Move Up" +JLIB_HTML_NO_PARAMETERS_FOR_THIS_ITEM="There are no parameters for this item." +JLIB_HTML_NO_RECORDS_FOUND="No records found." +JLIB_HTML_PAGE_CURRENT="Page %s" +JLIB_HTML_PAGE_CURRENT_OF_TOTAL="Page %s of %s" +JLIB_HTML_PAGINATION="Pagination" +JLIB_HTML_PLEASE_MAKE_A_SELECTION_FROM_THE_LIST="Please first make a selection from the list." +JLIB_HTML_PUBLISH_ITEM="Publish Item" +JLIB_HTML_PUBLISHED_EXPIRED_ITEM="Published, but has Expired." +JLIB_HTML_PUBLISHED_FINISHED="Finish: %s" +JLIB_HTML_PUBLISHED_ITEM="Published and is Current." +JLIB_HTML_PUBLISHED_PENDING_ITEM="Published, but is Pending." +JLIB_HTML_PUBLISHED_START="Start: %s" +JLIB_HTML_RESULTS_OF="Results %s - %s of %s" +JLIB_HTML_SAVE_ORDER="Save Order" +JLIB_HTML_SELECT_STATE="Select State" +JLIB_HTML_START="Start" +JLIB_HTML_UNPUBLISH_ITEM="Unpublish Item" +JLIB_HTML_VIEW_ALL="View All" +JLIB_HTML_SETDEFAULT_ITEM="Set default" +JLIB_HTML_UNSETDEFAULT_ITEM="Unset default" + +JLIB_INSTALLER_ABORT="Aborting language installation: %s" +JLIB_INSTALLER_ABORT_ALREADYINSTALLED="Extension is already installed." +JLIB_INSTALLER_ABORT_ALREADY_EXISTS="Extension %1$s: Extension %2$s already exists." +JLIB_INSTALLER_ABORT_COMP_BUILDADMINMENUS_FAILED="Error building Administrator Menus." +JLIB_INSTALLER_ABORT_COMP_COPY_MANIFEST="Component %1$s: Could not copy PHP manifest file." +JLIB_INSTALLER_ABORT_COMP_COPY_SETUP="Component %1$s: Could not copy setup file." +JLIB_INSTALLER_ABORT_COMP_FAIL_ADMIN_FILES="Component %s: Failed to copy administrator files." +JLIB_INSTALLER_ABORT_COMP_FAIL_SITE_FILES="Component %s: Failed to copy site files." +JLIB_INSTALLER_ABORT_COMP_INSTALL_COPY_SETUP="Component Install: Could not copy setup file." +JLIB_INSTALLER_ABORT_COMP_INSTALL_CUSTOM_INSTALL_FAILURE="Component Install: Custom install routine failure." +JLIB_INSTALLER_ABORT_COMP_INSTALL_MANIFEST="Component Install: Could not copy PHP manifest file." +JLIB_INSTALLER_ABORT_COMP_INSTALL_PHP_INSTALL="Component Install: Could not copy PHP install file." +JLIB_INSTALLER_ABORT_COMP_INSTALL_PHP_UNINSTALL="Component Install: Could not copy PHP uninstall file." +JLIB_INSTALLER_ABORT_COMP_INSTALL_ROLLBACK="Component Install: %s" +JLIB_INSTALLER_ABORT_COMP_INSTALL_SQL_ERROR="Component Install: SQL error file %s" +JLIB_INSTALLER_ABORT_COMP_UPDATESITEMENUS_FAILED="Component Install: Failed to update menu items." +JLIB_INSTALLER_ABORT_COMP_UPDATE_ADMIN_ELEMENT="Component Update: The XML file did not have an administration element." +JLIB_INSTALLER_ABORT_COMP_UPDATE_COPY_SETUP="Component Update: Could not copy setup file." +JLIB_INSTALLER_ABORT_COMP_UPDATE_MANIFEST="Component Update: Could not copy PHP manifest file." +JLIB_INSTALLER_ABORT_COMP_UPDATE_PHP_INSTALL="Component Update: Could not copy PHP install file." +JLIB_INSTALLER_ABORT_COMP_UPDATE_PHP_UNINSTALL="Component Update: Could not copy PHP uninstall file." +JLIB_INSTALLER_ABORT_COMP_UPDATE_ROLLBACK="Component Update: %s" +JLIB_INSTALLER_ABORT_COMP_UPDATE_SQL_ERROR="Component Update: SQL error file %s" +JLIB_INSTALLER_ABORT_CREATE_DIRECTORY="Extension %1$s: Failed to create folder: %2$s" +JLIB_INSTALLER_ABORT_DEBUG="Installation unexpectedly stopped:" +JLIB_INSTALLER_ABORT_DETECTMANIFEST="Unable to detect manifest file." +JLIB_INSTALLER_ABORT_DIRECTORY="Extension %1$s: Another %2$s is already using the named folder: %3$s. Are you trying to install the same extension again?" +JLIB_INSTALLER_ABORT_ERROR_DELETING_EXTENSIONS_RECORD="Could not delete the extension's record from the database." +JLIB_INSTALLER_ABORT_EXTENSIONNOTVALID="Extension is not valid." +JLIB_INSTALLER_ABORT_FILE_INSTALL_COPY_SETUP="Files Install: Could not copy setup file." +JLIB_INSTALLER_ABORT_FILE_INSTALL_CUSTOM_INSTALL_FAILURE="Files Install: Custom install routine failure." +JLIB_INSTALLER_ABORT_FILE_INSTALL_FAIL_SOURCE_DIRECTORY="Files Install: Failed to find source folder: %s" +JLIB_INSTALLER_ABORT_FILE_INSTALL_ROLLBACK="Files Install: %s" +JLIB_INSTALLER_ABORT_FILE_INSTALL_SQL_ERROR="Files %1$s: SQL error file %2$s" +JLIB_INSTALLER_ABORT_FILE_ROLLBACK="Files Install: %s" +JLIB_INSTALLER_ABORT_FILE_SAME_NAME="Files Install: Another extension with same name already exists." +JLIB_INSTALLER_ABORT_FILE_UPDATE_SQL_ERROR="Files Update: SQL error file %s" +JLIB_INSTALLER_ABORT_INSTALL_CUSTOM_INSTALL_FAILURE="Extension %s: Custom install routine failure." +JLIB_INSTALLER_ABORT_LIB_COPY_FILES="Library %s: Could not copy files from the source." +JLIB_INSTALLER_ABORT_LIB_INSTALL_ALREADY_INSTALLED="Library Install: Library already installed." +JLIB_INSTALLER_ABORT_LIB_INSTALL_COPY_SETUP="Library Install: Could not copy setup file." +JLIB_INSTALLER_ABORT_LIB_INSTALL_CORE_FOLDER="Library Install: Library has the same name as a core folder." +JLIB_INSTALLER_ABORT_LIB_INSTALL_FAILED_TO_CREATE_DIRECTORY="Library Install: Failed to create folder: %s" +JLIB_INSTALLER_ABORT_LIB_INSTALL_NOFILE="Library Install: No library file specified." +JLIB_INSTALLER_ABORT_LIB_INSTALL_ROLLBACK="Library Install: %s" +JLIB_INSTALLER_ABORT_LOAD_DETAILS="Failed to load extension details." +JLIB_INSTALLER_ABORT_MANIFEST="Extension %1$s: Could not copy PHP manifest file." +JLIB_INSTALLER_ABORT_METHODNOTSUPPORTED="Method not supported for this extension type." +JLIB_INSTALLER_ABORT_METHODNOTSUPPORTED_TYPE="Method not supported for this extension type: %s" +JLIB_INSTALLER_ABORT_MOD_COPY_FILES="Module %s: Could not copy files from the source." +JLIB_INSTALLER_ABORT_MOD_INSTALL_COPY_SETUP="Module Install: Could not copy setup file." +JLIB_INSTALLER_ABORT_MOD_INSTALL_CREATE_DIRECTORY="Module %1$s: Failed to create folder: %2$s" +JLIB_INSTALLER_ABORT_MOD_INSTALL_CUSTOM_INSTALL_FAILURE="Module Install: Custom install routine failure." +JLIB_INSTALLER_ABORT_MOD_INSTALL_DIRECTORY="Module %1$s: Another module is already using folder: %2$s" +JLIB_INSTALLER_ABORT_MOD_INSTALL_MANIFEST="Module Install: Could not copy PHP manifest file." +JLIB_INSTALLER_ABORT_MOD_INSTALL_NOFILE="Module %s: No module file specified." +JLIB_INSTALLER_ABORT_MOD_INSTALL_SQL_ERROR="Module %1$s: SQL error file %2$s" +JLIB_INSTALLER_ABORT_MOD_ROLLBACK="Module %1$s: %2$s" +JLIB_INSTALLER_ABORT_MOD_UNINSTALL_UNKNOWN_CLIENT="Module Uninstall: Unknown client type [%s]" +JLIB_INSTALLER_ABORT_MOD_UNKNOWN_CLIENT="Module %1$s: Unknown client type [%2$s]" +JLIB_INSTALLER_ABORT_NOINSTALLPATH="Install path does not exist." +JLIB_INSTALLER_ABORT_NOUPDATEPATH="Update path does not exist." +JLIB_INSTALLER_ABORT_PACK_INSTALL_COPY_SETUP="Package Install: Could not copy setup file." +JLIB_INSTALLER_ABORT_PACK_INSTALL_CREATE_DIRECTORY="Package Install: Failed to create folder: %s." +JLIB_INSTALLER_ABORT_PACKAGE_INSTALL_CUSTOM_INSTALL_FAILURE="Package Install: Custom install routine failure." +JLIB_INSTALLER_ABORT_PACKAGE_INSTALL_MANIFEST="Installation failed: Could not copy PHP manifest file." +JLIB_INSTALLER_ABORT_PACK_INSTALL_ERROR_EXTENSION="Package %1$s: There was an error installing an extension: %2$s" +JLIB_INSTALLER_ABORT_PACK_INSTALL_NO_FILES="Package %s: There were no files to install!" +JLIB_INSTALLER_ABORT_PACK_INSTALL_NO_PACK="Package %s: No package file specified." +JLIB_INSTALLER_ABORT_PACK_INSTALL_ROLLBACK="Package Install: %s" +JLIB_INSTALLER_ABORT_PLG_COPY_FILES="Plugin %s: Could not copy files from the source." +JLIB_INSTALLER_ABORT_PLG_INSTALL_ALLREADY_EXISTS="Plugin %1$s: Plugin %2$s already exists." +JLIB_INSTALLER_ABORT_PLG_INSTALL_COPY_SETUP="Plugin %s: Could not copy setup file." +JLIB_INSTALLER_ABORT_PLG_INSTALL_CREATE_DIRECTORY="Plugin %1$s: Failed to create folder: %2$s" +JLIB_INSTALLER_ABORT_PLG_INSTALL_CUSTOM_INSTALL_FAILURE="Plugin Install: Custom install routine failure." +JLIB_INSTALLER_ABORT_PLG_INSTALL_DIRECTORY="Plugin %1$s: Another plugin is already using folder: %2$s" +JLIB_INSTALLER_ABORT_PLG_INSTALL_MANIFEST="Plugin %s: Could not copy PHP manifest file." +JLIB_INSTALLER_ABORT_PLG_INSTALL_NO_FILE="Plugin %s: No plugin file specified." +JLIB_INSTALLER_ABORT_PLG_INSTALL_ROLLBACK="Plugin %1$s: %2$s" +JLIB_INSTALLER_ABORT_PLG_INSTALL_SQL_ERROR="Plugin %1$s: SQL error file %2$s" +JLIB_INSTALLER_ABORT_PLG_UNINSTALL_SQL_ERROR="Plugin Uninstall: SQL error file %s" +JLIB_INSTALLER_ABORT_REFRESH_MANIFEST_CACHE="Refresh Manifest Cache failed: %s Extension is not currently installed." +JLIB_INSTALLER_ABORT_REFRESH_MANIFEST_CACHE_VALID="Refresh Manifest Cache failed: Extension is not valid." +JLIB_INSTALLER_ABORT_ROLLBACK="Extension %1$s: %2$s" +JLIB_INSTALLER_ABORT_SQL_ERROR="Extension %1$s: SQL error processing query: %2$s" +JLIB_INSTALLER_ABORT_TPL_INSTALL_ALREADY_INSTALLED="Template Install: Template already installed." +JLIB_INSTALLER_ABORT_TPL_INSTALL_ANOTHER_TEMPLATE_USING_DIRECTORY="Template Install: There is already a Template using the named folder: %s. Are you trying to install the same template again?" +JLIB_INSTALLER_ABORT_TPL_INSTALL_COPY_FILES="Template Install: Could not copy files from the %s source." +JLIB_INSTALLER_ABORT_TPL_INSTALL_COPY_SETUP="Template Install: Could not copy setup file." +JLIB_INSTALLER_ABORT_TPL_INSTALL_FAILED_CREATE_DIRECTORY="Template Install: Failed to create folder: %s" +JLIB_INSTALLER_ABORT_TPL_INSTALL_ROLLBACK="Template Install: %s" +JLIB_INSTALLER_ABORT_TPL_INSTALL_UNKNOWN_CLIENT="Template Install: Unknown client type [%s]" +JLIB_INSTALLER_AVAILABLE_UPDATE_PHP_VERSION="For the extension %1$s version %2$s is available, but it requires at least PHP version %3$s while your system only has %4$s" +JLIB_INSTALLER_AVAILABLE_UPDATE_DB_MINIMUM="For the extension %1$s version %2$s is available, but your current database %3$s is version %4$s and is not supported. Please contact your web host to update your Database version to at least version %5$s." +JLIB_INSTALLER_AVAILABLE_UPDATE_DB_TYPE="For the extension %1$s version %2$s is available, but your current database %3$s is not supported anymore." +JLIB_INSTALLER_PURGED_UPDATES="Cleared updates" +JLIB_INSTALLER_FAILED_TO_PURGE_UPDATES="Failed to clear updates." +JLIB_INSTALLER_DEFAULT_STYLE="%s - Default" +JLIB_INSTALLER_DISCOVER="Discover" +JLIB_INSTALLER_DISCOVER_INSTALL="Discover Install" +JLIB_INSTALLER_ERROR_CANNOT_UNINSTALL_CHILD_OF_PACKAGE="The %s extension is part of a package which does not allow individual extensions to be uninstalled." +JLIB_INSTALLER_ERROR_COMP_DISCOVER_STORE_DETAILS="Component Discover install: Failed to store component details." +JLIB_INSTALLER_ERROR_COMP_FAILED_TO_CREATE_DIRECTORY="Component %1$s: Failed to create folder: %2$s." +JLIB_INSTALLER_ERROR_COMP_INSTALL_ADMIN_ELEMENT="Component Install: The XML file did not have an administration element." +JLIB_INSTALLER_ERROR_COMP_INSTALL_DIR_ADMIN="Component Install: Another component is already using folder: %s" +JLIB_INSTALLER_ERROR_COMP_INSTALL_DIR_SITE="Component Install: Another component is already using folder: %s" +JLIB_INSTALLER_ERROR_COMP_INSTALL_FAILED_TO_CREATE_DIRECTORY_ADMIN="Component Install: Failed to create administrator folder: %s" +JLIB_INSTALLER_ERROR_COMP_INSTALL_FAILED_TO_CREATE_DIRECTORY_SITE="Component Install: Failed to create site folder: %s" +JLIB_INSTALLER_ERROR_COMP_REFRESH_MANIFEST_CACHE="Component Refresh manifest cache: Failed to store component details." +JLIB_INSTALLER_ERROR_COMP_REMOVING_ADMIN_MENUS_FAILED="Could not delete the Administrator menus." +JLIB_INSTALLER_ERROR_COMP_UNINSTALL_CUSTOM="Component Uninstall: Custom Uninstall script unsuccessful." +JLIB_INSTALLER_ERROR_COMP_UNINSTALL_FAILED_DELETE_CATEGORIES="Component Uninstall: Unable to delete the component categories." +JLIB_INSTALLER_ERROR_COMP_UNINSTALL_ERRORREMOVEMANUALLY="Component Uninstall: Can't uninstall. Please remove manually." +JLIB_INSTALLER_ERROR_COMP_UNINSTALL_ERRORUNKOWNEXTENSION="Component Uninstall: Unknown Extension." +JLIB_INSTALLER_ERROR_COMP_UNINSTALL_FAILED_REMOVE_DIRECTORY_ADMIN="Component Uninstall: Unable to remove the component administrator folder." +JLIB_INSTALLER_ERROR_COMP_UNINSTALL_FAILED_REMOVE_DIRECTORY_SITE="Component Uninstall: Unable to remove the component site folder." +JLIB_INSTALLER_ERROR_COMP_UNINSTALL_NO_OPTION="Component Uninstall: Option field empty, can't remove files." +JLIB_INSTALLER_ERROR_COMP_UNINSTALL_SQL_ERROR="Component Uninstall: SQL error file %s" +JLIB_INSTALLER_ERROR_COMP_UNINSTALL_WARNCORECOMPONENT="Component Uninstall: Trying to uninstall a core component." +JLIB_INSTALLER_ERROR_COMP_UPDATE_FAILED_TO_CREATE_DIRECTORY_ADMIN="Component Update: Failed to create administrator folder: %s" +JLIB_INSTALLER_ERROR_COMP_UPDATE_FAILED_TO_CREATE_DIRECTORY_SITE="Component Update: Failed to create site folder: %s" +JLIB_INSTALLER_ERROR_CREATE_DIRECTORY="JInstaller: :Install: Failed to create folder: %s" +JLIB_INSTALLER_ERROR_CREATE_FOLDER_FAILED="Failed to create folder [%s]" +JLIB_INSTALLER_ERROR_DEPRECATED_FORMAT="Deprecated install format (client="_QQ_"both"_QQ_"), use package installer in future." +JLIB_INSTALLER_ERROR_DISCOVER_INSTALL_UNSUPPORTED="A %s extension can not be installed using the discover method. Please install this extension from Extension Manager: Install." +JLIB_INSTALLER_ERROR_DOWNGRADE="Sorry! You cannot downgrade from version %s to %s" +JLIB_INSTALLER_ERROR_DOWNLOAD_SERVER_CONNECT="Error connecting to the server: %s" +JLIB_INSTALLER_ERROR_FAIL_COPY_FILE="JInstaller: :Install: Failed to copy file %1$s to %2$s" +JLIB_INSTALLER_ERROR_FAIL_COPY_FOLDER="JInstaller: :Install: Failed to copy folder %1$s to %2$s" +JLIB_INSTALLER_ERROR_FAILED_READING_NETWORK_RESOURCES="Failed reading network resource: %s" +JLIB_INSTALLER_ERROR_FILE_EXISTS="JInstaller: :Install: File already exists %s" +JLIB_INSTALLER_ERROR_FILE_FOLDER="Error on deleting file or folder %s" +JLIB_INSTALLER_ERROR_FILE_UNINSTALL_INVALID_MANIFEST="Files Uninstall: Invalid manifest file." +JLIB_INSTALLER_ERROR_FILE_UNINSTALL_INVALID_NOTFOUND_MANIFEST="Files Uninstall: Manifest file invalid or not found." +JLIB_INSTALLER_ERROR_FILE_UNINSTALL_LOAD_ENTRY="Files Uninstall: Could not load extension entry." +JLIB_INSTALLER_ERROR_FILE_UNINSTALL_LOAD_MANIFEST="Files Uninstall: Could not load manifest file." +JLIB_INSTALLER_ERROR_FILE_UNINSTALL_SQL_ERROR="Files Uninstall: SQL error file %s" +JLIB_INSTALLER_ERROR_FILE_UNINSTALL_WARNCOREFILE="File Uninstall: Trying to uninstall core files." +JLIB_INSTALLER_ERROR_FOLDER_IN_USE="Another extension is already using folder [%s]" +JLIB_INSTALLER_ERROR_LANG_DISCOVER_STORE_DETAILS="Language Discover install: Failed to store language details." +JLIB_INSTALLER_ERROR_LANG_UNINSTALL_DEFAULT="This language can't be uninstalled as long as it is defined as a default language." +JLIB_INSTALLER_ERROR_LANG_UNINSTALL_DIRECTORY="Language Uninstall: Unable to remove the specified Language folder." +JLIB_INSTALLER_ERROR_LANG_UNINSTALL_ELEMENT_EMPTY="Language Uninstall: Element is empty, can't uninstall files." +JLIB_INSTALLER_ERROR_LANG_UNINSTALL_PATH_EMPTY="Language Uninstall: Language path is empty, can't uninstall files." +JLIB_INSTALLER_ERROR_LANG_UNINSTALL_PROTECTED="This language can't be uninstalled. It is protected in the database (usually en-GB)." +JLIB_INSTALLER_ERROR_LIB_DISCOVER_STORE_DETAILS="Library Discover install: Failed to store library details." +JLIB_INSTALLER_ERROR_LIB_REFRESH_MANIFEST_CACHE="Library Refresh manifest cache: Failed to store library details." +JLIB_INSTALLER_ERROR_LIB_UNINSTALL_INVALID_MANIFEST="Library Uninstall: Invalid manifest file." +JLIB_INSTALLER_ERROR_LIB_UNINSTALL_INVALID_NOTFOUND_MANIFEST="Library Uninstall: Manifest file invalid or not found." +JLIB_INSTALLER_ERROR_LIB_UNINSTALL_LOAD_MANIFEST="Library Uninstall: Could not load manifest file." +JLIB_INSTALLER_ERROR_LIB_UNINSTALL_WARNCORELIBRARY="Library Uninstall: Trying to uninstall a core library." +JLIB_INSTALLER_ERROR_LOAD_XML="JInstaller: :Install: Failed to load XML File: %s" +JLIB_INSTALLER_ERROR_MOD_DISCOVER_STORE_DETAILS="Module Discover install: Failed to store module details." +JLIB_INSTALLER_ERROR_MOD_REFRESH_MANIFEST_CACHE="Module Refresh manifest cache: Failed to store module details." +JLIB_INSTALLER_ERROR_MOD_UNINSTALL_ERRORUNKOWNEXTENSION="Module Uninstall: Unknown Extension." +JLIB_INSTALLER_ERROR_MOD_UNINSTALL_EXCEPTION="Module Uninstall: %s" +JLIB_INSTALLER_ERROR_MOD_UNINSTALL_INVALID_NOTFOUND_MANIFEST="Module Uninstall: Manifest file invalid or not found." +JLIB_INSTALLER_ERROR_MOD_UNINSTALL_SQL_ERROR="Module Uninstall: SQL error file %s" +JLIB_INSTALLER_ERROR_MOD_UNINSTALL_WARNCOREMODULE="Module Uninstall: Trying to uninstall a core module: %s" +JLIB_INSTALLER_ERROR_NO_CORE_LANGUAGE="No core pack exists for the language [%s]" +JLIB_INSTALLER_ERROR_NO_FILE="JInstaller: :Install: File does not exist %s" +JLIB_INSTALLER_ERROR_NO_LANGUAGE_TAG="The package did not specify a language tag. Are you trying to install an old language package?" +JLIB_INSTALLER_ERROR_NOTFINDJOOMLAXMLSETUPFILE="JInstaller: :Install: Can't find Joomla XML setup file." +JLIB_INSTALLER_ERROR_NOTFINDXMLSETUPFILE="JInstaller: :Install: Can't find XML setup file." +JLIB_INSTALLER_ERROR_PACK_REFRESH_MANIFEST_CACHE="Package Refresh manifest cache: Failed to store package details." +JLIB_INSTALLER_ERROR_PACK_SETTING_PACKAGE_ID="Could not record the package ID for this package's extensions." +JLIB_INSTALLER_ERROR_PACK_UNINSTALL_INVALID_MANIFEST="Package Uninstall: Invalid manifest file." +JLIB_INSTALLER_ERROR_PACK_UNINSTALL_INVALID_NOTFOUND_MANIFEST="Package Uninstall: Manifest file invalid or not found: %s" +JLIB_INSTALLER_ERROR_PACK_UNINSTALL_LOAD_MANIFEST="Package Uninstall: Could not load manifest file." +JLIB_INSTALLER_ERROR_PACK_UNINSTALL_MANIFEST_NOT_REMOVED="Package Uninstall: Errors were detected, manifest file not removed!" +JLIB_INSTALLER_ERROR_PACK_UNINSTALL_MISSINGMANIFEST="Package Uninstall: Missing manifest file." +JLIB_INSTALLER_ERROR_PACK_UNINSTALL_NOT_PROPER="Package Uninstall: This extension may have already been uninstalled or might not have been uninstall properly: %s" +JLIB_INSTALLER_ERROR_PACK_UNINSTALL_WARNCOREPACK="Package Uninstall: Trying to uninstall core package." +JLIB_INSTALLER_ERROR_PLG_DISCOVER_STORE_DETAILS="Plugin Discover install: Failed to store plugin details." +JLIB_INSTALLER_ERROR_PLG_REFRESH_MANIFEST_CACHE="Plugin Refresh manifest cache: Failed to store plugin details." +JLIB_INSTALLER_ERROR_PLG_UNINSTALL_ERRORUNKOWNEXTENSION="Plugin Uninstall: Unknown Extension." +JLIB_INSTALLER_ERROR_PLG_UNINSTALL_FOLDER_FIELD_EMPTY="Plugin Uninstall: Folder field empty, can't remove files." +JLIB_INSTALLER_ERROR_PLG_UNINSTALL_INVALID_MANIFEST="Plugin Uninstall: Invalid manifest file." +JLIB_INSTALLER_ERROR_PLG_UNINSTALL_INVALID_NOTFOUND_MANIFEST="Plugin Uninstall: Manifest file invalid or not found." +JLIB_INSTALLER_ERROR_PLG_UNINSTALL_LOAD_MANIFEST="Plugin Uninstall: Could not load manifest file." +JLIB_INSTALLER_ERROR_PLG_UNINSTALL_WARNCOREPLUGIN="Plugin Uninstall: Trying to uninstall a core plugin: %s" +JLIB_INSTALLER_ERROR_SQL_ERROR="JInstaller: :Install: Error SQL %s" +JLIB_INSTALLER_ERROR_SQL_FILENOTFOUND="JInstaller: :Install: SQL File not found %s" +JLIB_INSTALLER_ERROR_SQL_READBUFFER="JInstaller: :Install: SQL File Buffer Read Error." +JLIB_INSTALLER_ERROR_TPL_DISCOVER_STORE_DETAILS="Template Discover install: Failed to store template details." +JLIB_INSTALLER_ERROR_TPL_REFRESH_MANIFEST_CACHE="Template Refresh manifest cache: Failed to store template details." +JLIB_INSTALLER_ERROR_TPL_UNINSTALL_ERRORUNKOWNEXTENSION="Template Uninstall: Unknown Extension." +JLIB_INSTALLER_ERROR_TPL_UNINSTALL_INVALID_CLIENT="Template Uninstall: Invalid client." +JLIB_INSTALLER_ERROR_TPL_UNINSTALL_INVALID_NOTFOUND_MANIFEST="Template Uninstall: Manifest file invalid or not found." +JLIB_INSTALLER_ERROR_TPL_UNINSTALL_TEMPLATE_DEFAULT="Template Uninstall: Can't remove default template." +JLIB_INSTALLER_ERROR_TPL_UNINSTALL_TEMPLATE_DIRECTORY="Template Uninstall: Folder does not exist, can't remove files." +JLIB_INSTALLER_ERROR_TPL_UNINSTALL_TEMPLATE_ID_EMPTY="Template Uninstall: Template ID is empty, can't uninstall files." +JLIB_INSTALLER_ERROR_TPL_UNINSTALL_WARNCORETEMPLATE="Template Uninstall: Trying to uninstall a core template: %s" +JLIB_INSTALLER_ERROR_UNKNOWN_CLIENT_TYPE="Unknown Client Type [%s]" +JLIB_INSTALLER_FILE_ERROR_MOVE="Error on moving file %s" +JLIB_INSTALLER_INCORRECT_SEQUENCE="Downgrading from version %1$s to version %2$s is not allowed." +JLIB_INSTALLER_INSTALL="Install" +JLIB_INSTALLER_MINIMUM_JOOMLA="You don't have the minimum Joomla version requirement of J%s" +JLIB_INSTALLER_MINIMUM_PHP="Your server doesn't meet the minimum PHP version requirement of %s" +JLIB_INSTALLER_NOTICE_LANG_RESET_USERS="Language set to Default for %d users." +JLIB_INSTALLER_NOTICE_LANG_RESET_USERS_1="Language set to Default for %d user." +JLIB_INSTALLER_UNINSTALL="Uninstall" +JLIB_INSTALLER_UPDATE="Update" +JLIB_INSTALLER_ERROR_EXTENSION_INVALID_CLIENT_IDENTIFIER="Invalid client identifier specified in extension manifest." +JLIB_INSTALLER_ERROR_PACK_UNINSTALL_UNKNOWN_EXTENSION="Trying to uninstall unknown extension from package. This extension may have already been removed earlier." +JLIB_INSTALLER_NOT_ERROR="If the error is related to the installation of TinyMCE language files it has no effect on the installation of the language(s). Some language packs created prior to Joomla! 3.2.0 may try to install separate TinyMCE language files. As these are now included in the core they no longer need to be installed." +JLIB_INSTALLER_UPDATE_LOG_QUERY="Ran query from file %1$s. Query text: %2$s." +JLIB_INSTALLER_WARNING_UNABLE_TO_INSTALL_CONTENT_LANGUAGE="Unable to create a content language for %s language: %s" + +JLIB_JS_AJAX_ERROR_CONNECTION_ABORT="A connection abort has occurred while fetching the JSON data." +JLIB_JS_AJAX_ERROR_NO_CONTENT="No content was returned." +JLIB_JS_AJAX_ERROR_OTHER="An error has occurred while fetching the JSON data: HTTP %s status code." +JLIB_JS_AJAX_ERROR_PARSE="A parse error has occurred while processing the following JSON data:
    %s" +JLIB_JS_AJAX_ERROR_TIMEOUT="A timeout has occurred while fetching the JSON data." + +JLIB_LANGUAGE_ERROR_CANNOT_LOAD_METAFILE="Could not load %s language XML file from %s." +JLIB_LANGUAGE_ERROR_CANNOT_LOAD_METADATA="Could not load %s metadata from %s." + +JLIB_LOGIN_AUTHORISATION="Your access has been authorised." +JLIB_LOGIN_DENIED="Your access has been denied." +JLIB_LOGIN_EXPIRED="Your authentication has expired." + +JLIB_MAIL_FUNCTION_DISABLED="The mail() function has been disabled and the mail can't be sent." +JLIB_MAIL_FUNCTION_OFFLINE="The mail function has been disabled by an administrator." +JLIB_MAIL_INVALID_EMAIL_SENDER="JMail: : Invalid email Sender: %s, JMail: :setSender(%s)." + +JLIB_MEDIA_ERROR_UPLOAD_INPUT="Unable to upload file." +JLIB_MEDIA_ERROR_WARNFILENAME="File name must only have alphanumeric characters and no spaces." +JLIB_MEDIA_ERROR_WARNFILETOOLARGE="This file is too large to upload." +JLIB_MEDIA_ERROR_WARNFILETYPE="This file type is not supported." +JLIB_MEDIA_ERROR_WARNIEXSS="Possible IE XSS Attack found." +JLIB_MEDIA_ERROR_WARNINVALID_IMG="Not a valid image." +JLIB_MEDIA_ERROR_WARNINVALID_MIME="Invalid mime type detected." +JLIB_MEDIA_ERROR_WARNINVALID_MIMETYPE="Illegal mime type detected: %s" +JLIB_MEDIA_ERROR_WARNNOTADMIN="Uploaded file is not an image file and you do not have permission." + +JLIB_MENUS_PRESET_JOOMLA="Preset - Joomla" +JLIB_MENUS_PRESET_MODERN="Preset - Modern" + +JLIB_NO_EDITOR_PLUGIN_PUBLISHED="Unable to display an editor because no editor plugin is published." + +JLIB_PLUGIN_ERROR_LOADING_PLUGINS="Error loading Plugins: %s" +JLIB_REGISTRY_EXCEPTION_LOAD_FORMAT_CLASS="Unable to load format class." + +JLIB_RULES_ACTION="Action" +JLIB_RULES_ALLOWED="Allowed" +JLIB_RULES_ALLOWED_ADMIN="Allowed (Super User)" +JLIB_RULES_ALLOWED_INHERITED="Allowed (Inherited)" +JLIB_RULES_CALCULATED_SETTING="Calculated Setting" +JLIB_RULES_CONFLICT="Conflict" +JLIB_RULES_DATABASE_FAILURE="Failed storing the data to the database." +JLIB_RULES_DENIED="Denied" +JLIB_RULES_GROUP="%s" +JLIB_RULES_GROUPS="Groups" +JLIB_RULES_INHERIT="Inherit" +JLIB_RULES_INHERITED="Inherited" +JLIB_RULES_NOT_ALLOWED="Not Allowed" +JLIB_RULES_NOT_ALLOWED_ADMIN_CONFLICT="Conflict" +JLIB_RULES_NOT_ALLOWED_DEFAULT="Not Allowed (Default)" +JLIB_RULES_NOT_ALLOWED_INHERITED="Not Allowed (Inherited)" +JLIB_RULES_NOT_ALLOWED_LOCKED="Not Allowed (Locked)" +JLIB_RULES_NOT_SET="Not Set" +JLIB_RULES_NOTICE_RECALCULATE_GROUP_PERMISSIONS="Super User permissions changed. Save or reload to recalculate this group permissions." +JLIB_RULES_NOTICE_RECALCULATE_GROUP_CHILDS_PERMISSIONS="Permissions changed in a group with child groups. Save or reload to recalculate the child groups permissions." +JLIB_RULES_REQUEST_FAILURE="Failed sending the data to server." +JLIB_RULES_SAVE_BEFORE_CHANGE_PERMISSIONS="Please save before changing permissions." +JLIB_RULES_SELECT_ALLOW_DENY_GROUP="Allow or deny %s for users in the %s group." +JLIB_RULES_SELECT_SETTING="Select New Setting" +JLIB_RULES_SETTING_NOTES="If you change the setting, it will apply to this and all child groups, components and content. Note that Denied will overrule any inherited setting and also the setting in any child group, component or content. In the case of a setting conflict, Deny will take precedence. Not Set is equivalent to Denied but can be changed in child groups, components and content." +JLIB_RULES_SETTING_NOTES_ITEM="If you change the setting, it will apply to this item. Note that:
    Inherited means that the permissions from global configuration, parent group and category will be used.
    Denied means that no matter what the global configuration, parent group or category settings are, the group being edited can't take this action on this item.
    Allowed means that the group being edited will be able to take this action for this item (but if this is in conflict with the global configuration, parent group or category it will have no impact; a conflict will be indicated by Not Allowed (Inherited) under Calculated Settings)." +JLIB_RULES_SETTINGS_DESC="Manage the permission settings for the user groups below. See notes at the bottom." + +JLIB_STEMMER_INVALID_STEMMER="Invalid stemmer type %s" + +JLIB_UNKNOWN="Unknown" +JLIB_UPDATER_ERROR_COLLECTION_FOPEN="The PHP allow_url_fopen setting is disabled. This setting must be enabled for the updater to work." +JLIB_UPDATER_ERROR_COLLECTION_OPEN_URL="Update: :Collection: Could not open %s" +JLIB_UPDATER_ERROR_COLLECTION_PARSE_URL="Update: :Collection: Could not parse %s" +JLIB_UPDATER_ERROR_EXTENSION_OPEN_URL="Update: :Extension: Could not open %s" +JLIB_UPDATER_ERROR_EXTENSION_PARSE_URL="Update: :Extension: Could not parse %s" +JLIB_UPDATER_ERROR_OPEN_UPDATE_SITE="Update: Could not open update site #%d "%s", URL: %s" +JLIB_USER_ERROR_AUTHENTICATION_FAILED_LOAD_PLUGIN="JAuthentication: :authenticate: Failed to load plugin: %s" +JLIB_USER_ERROR_AUTHENTICATION_LIBRARIES="JAuthentication: :__construct: Could not load authentication libraries." +JLIB_USER_ERROR_BIND_ARRAY="Unable to bind array to user object." +JLIB_USER_ERROR_CANNOT_CHANGE_SUPER_USER="A user is not allowed to change permissions of a Super User group." +JLIB_USER_ERROR_CANNOT_CHANGE_OWN_GROUPS="A user is not allowed to change permissions of their own group(s)." +JLIB_USER_ERROR_CANNOT_CHANGE_OWN_PARENT_GROUPS="A user is not allowed to change permissions of their own group(s) parent group(s)." +JLIB_USER_ERROR_CANNOT_DEMOTE_SELF="You can't remove your own Super User permissions." +JLIB_USER_ERROR_CANNOT_REUSE_PASSWORD="You can't reuse your current password, please enter a new password." +JLIB_USER_ERROR_ID_NOT_EXISTS="JUser: :_load: User %s does not exist." +JLIB_USER_ERROR_NOT_SUPERADMIN="Only users with Super User permissions can change other Super User user accounts." +JLIB_USER_ERROR_PASSWORD_NOT_MATCH="Passwords do not match. Please re-enter password." +JLIB_USER_ERROR_UNABLE_TO_FIND_USER="Unable to find a user with given activation string." +JLIB_USER_ERROR_UNABLE_TO_LOAD_USER="JUser: :_load: Unable to load user with ID: %s" +JLIB_USER_EXCEPTION_ACCESS_USERGROUP_INVALID="User group does not exist." +JLIB_UTIL_ERROR_APP_INSTANTIATION="Application Startup Error." +JLIB_UTIL_ERROR_CONNECT_DATABASE="JDatabase: :getInstance: Could not connect to database
    joomla.library: %1$s - %2$s" +JLIB_UTIL_ERROR_DOMIT="DommitDocument is deprecated. Use DomDocument instead." +JLIB_UTIL_ERROR_LOADING_FEED_DATA="Error loading feed data." +JLIB_UTIL_ERROR_XML_LOAD="Failed loading XML file." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.localise.php b/Sites/pages/administrator/language/en-GB/en-GB.localise.php new file mode 100644 index 00000000..798e63c5 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.localise.php @@ -0,0 +1,90 @@ +Non existent" +MOD_LATEST_XML_DESCRIPTION="This module shows a list of the most recently created Articles." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.mod_latest.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.mod_latest.sys.ini new file mode 100644 index 00000000..03c7ac76 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.mod_latest.sys.ini @@ -0,0 +1,10 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + + +MOD_LATEST="Articles - Latest" +MOD_LATEST_XML_DESCRIPTION="This module shows a list of the most recently created Articles." +MOD_LATEST_LAYOUT_DEFAULT="Default" + diff --git a/Sites/pages/administrator/language/en-GB/en-GB.mod_latestactions.ini b/Sites/pages/administrator/language/en-GB/en-GB.mod_latestactions.ini new file mode 100644 index 00000000..72695684 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.mod_latestactions.ini @@ -0,0 +1,14 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +MOD_LATESTACTIONS="Action Logs - Latest" +MOD_LATESTACTIONS_FIELD_COUNT_LABEL="Count" +MOD_LATESTACTIONS_FIELD_COUNT_DESC="The number of items to display (default 5)." +MOD_LATESTACTIONS_LAYOUT_DEFAULT="Default" +MOD_LATEST_ACTIONS_NO_MATCHING_RESULTS="No Matching Results" +MOD_LATESTACTIONS_TITLE="Last Actions" +MOD_LATESTACTIONS_TITLE_1="Last Action" +MOD_LATESTACTIONS_TITLE_MORE="Last %s Actions" +MOD_LATESTACTIONS_XML_DESCRIPTION="This module shows a list of the most recent actions." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.mod_latestactions.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.mod_latestactions.sys.ini new file mode 100644 index 00000000..07f37d9a --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.mod_latestactions.sys.ini @@ -0,0 +1,9 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + + +MOD_LATESTACTIONS="Action Logs - Latest" +MOD_LATESTACTIONS_XML_DESCRIPTION="This module shows a list of the most recent actions." + diff --git a/Sites/pages/administrator/language/en-GB/en-GB.mod_logged.ini b/Sites/pages/administrator/language/en-GB/en-GB.mod_logged.ini new file mode 100644 index 00000000..ca0265a9 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.mod_logged.ini @@ -0,0 +1,20 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + + +MOD_LOGGED="Logged-in Users" +MOD_LOGGED_ADMINISTRATOR="Administrator" +MOD_LOGGED_EDIT_USER="Edit user" +MOD_LOGGED_FIELD_COUNT_DESC="The number of items to display (default 5)." +MOD_LOGGED_FIELD_COUNT_LABEL="Count" +MOD_LOGGED_FIELD_NAME_DESC="Displays name or username." +MOD_LOGGED_LAST_ACTIVITY="Last Activity" +MOD_LOGGED_LOGOUT="Logout" +MOD_LOGGED_NAME="Name" +MOD_LOGGED_SITE="Site" +MOD_LOGGED_TITLE="Last Logged-in Users" +MOD_LOGGED_TITLE_1="Last Logged-in User" +MOD_LOGGED_TITLE_MORE="Last %s Logged-in Users" +MOD_LOGGED_XML_DESCRIPTION="This module shows a list of the Logged-in Users." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.mod_logged.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.mod_logged.sys.ini new file mode 100644 index 00000000..35596931 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.mod_logged.sys.ini @@ -0,0 +1,10 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + + +MOD_LOGGED="Logged-in Users" +MOD_LOGGED_XML_DESCRIPTION="This module shows a list of the Logged-in Users." +MOD_LOGGED_LAYOUT_DEFAULT="Default" + diff --git a/Sites/pages/administrator/language/en-GB/en-GB.mod_login.ini b/Sites/pages/administrator/language/en-GB/en-GB.mod_login.ini new file mode 100644 index 00000000..6dfa540f --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.mod_login.ini @@ -0,0 +1,13 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +MOD_LOGIN="Login Form" +MOD_LOGIN_FIELD_USESECURE_DESC="Submit encrypted login data using HTTPS (encrypted HTTP connections with the https:// protocol prefix). Note, you must have HTTPS enabled on your server to utilise this option." +MOD_LOGIN_FIELD_USESECURE_LABEL="Encrypt Login Form" +MOD_LOGIN_LANGUAGE="Language" +MOD_LOGIN_LOGIN="Log in" +MOD_LOGIN_XML_DESCRIPTION="This module displays a username and password login form. It should not be unpublished." +MOD_LOGIN_REMIND="Forgot your username?" +MOD_LOGIN_RESET="Forgot your password?" diff --git a/Sites/pages/administrator/language/en-GB/en-GB.mod_login.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.mod_login.sys.ini new file mode 100644 index 00000000..95cdbdbf --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.mod_login.sys.ini @@ -0,0 +1,9 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +MOD_LOGIN_XML_DESCRIPTION="This module displays a username and password login form. It can't be unpublished." +MOD_LOGIN="Login Form" +MOD_LOGIN_LAYOUT_DEFAULT="Default" + diff --git a/Sites/pages/administrator/language/en-GB/en-GB.mod_menu.ini b/Sites/pages/administrator/language/en-GB/en-GB.mod_menu.ini new file mode 100644 index 00000000..b279b72e --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.mod_menu.ini @@ -0,0 +1,111 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +MOD_MENU="Administrator Menu" +MOD_MENU_CLEAR_CACHE="Clear Cache" +MOD_MENU_COMPONENTS="Components" +MOD_MENU_COM_ACTIONLOGS="User Actions Log" +MOD_MENU_COM_CONTENT="Content" +MOD_MENU_COM_CONTENT_ARTICLE_MANAGER="Articles" +MOD_MENU_COM_CONTENT_CATEGORY_MANAGER="Categories" +MOD_MENU_COM_CONTENT_FEATURED="Featured Articles" +MOD_MENU_COM_CONTENT_NEW_ARTICLE="Add New Article" +MOD_MENU_COM_CONTENT_NEW_CATEGORY="Add New Category" +MOD_MENU_COM_LANGUAGES_SUBMENU_CONTENT="Content Languages" +MOD_MENU_COM_LANGUAGES_SUBMENU_INSTALLED="Installed" +MOD_MENU_COM_LANGUAGES_SUBMENU_OVERRIDES="Overrides" +MOD_MENU_COM_PRIVACY="Privacy" +MOD_MENU_COM_TEMPLATES_SUBMENU_STYLES="Styles" +MOD_MENU_COM_TEMPLATES_SUBMENU_TEMPLATES="Templates" +MOD_MENU_COM_USERS="Users" +MOD_MENU_COM_USERS_ADD_GROUP="Add New Group" +MOD_MENU_COM_USERS_ADD_LEVEL="Add New Access Level" +MOD_MENU_COM_USERS_ADD_USER="Add New User" +MOD_MENU_COM_USERS_GROUPS="Groups" +MOD_MENU_COM_USERS_LEVELS="Access Levels" +MOD_MENU_COM_USERS_USERS="Users" +MOD_MENU_COM_USERS_USER_MANAGER="Manage" +MOD_MENU_COM_USERS_ADD_NOTE="Add User Note" +MOD_MENU_COM_USERS_NOTES="User Notes" +MOD_MENU_COM_USERS_NOTE_CATEGORIES="User Note Categories" +MOD_MENU_CONFIGURATION="Global Configuration" +MOD_MENU_CONTROL_PANEL="Control Panel" +MOD_MENU_EXTENSIONS_EXTENSIONS="Extensions" +MOD_MENU_EXTENSIONS_EXTENSION_MANAGER="Manage" +MOD_MENU_EXTENSIONS_LANGUAGE_MANAGER="Language(s)" +MOD_MENU_EXTENSIONS_MODULE_MANAGER="Modules" +MOD_MENU_EXTENSIONS_PLUGIN_MANAGER="Plugins" +MOD_MENU_EXTENSIONS_TEMPLATE_MANAGER="Templates" +MOD_MENU_FIELD_CHECK_DESC="Check for the presence of important menu items." +MOD_MENU_FIELD_CHECK_LABEL="Check Menu" +MOD_MENU_FIELD_FORUMURL_DESC="Enter the URL to a forum other than the default." +MOD_MENU_FIELD_FORUMURL_LABEL="Custom Support Forum" +MOD_MENU_FIELD_MENUTYPE_LABEL="Menu to Show" +MOD_MENU_FIELD_MENUTYPE_DESC="Choose which menu should be rendered with this instance of module." +MOD_MENU_FIELD_MENUTYPE_OPTION_PREDEFINED="Use a Preset" +MOD_MENU_FIELD_PRESET_LABEL="Choose Preset" +MOD_MENU_FIELD_PRESET_DESC="Choose a preset to use as the backend menu" +MOD_MENU_FIELD_SHOWHELP="Help Menu" +MOD_MENU_FIELD_SHOWHELP_DESC="Show or hide the Help menu which includes links to various joomla.org sites useful to users." +MOD_MENU_FIELD_SHOWNEW="Add New Shortcuts" +MOD_MENU_FIELD_SHOWNEW_DESC="Show or hide various 'Add New ...' shortcuts against users, groups, access levels, articles and categories." +MOD_MENU_FIELDS="Fields" +MOD_MENU_FIELDS_GROUP="Field Groups" +MOD_MENU_GLOBAL_CHECKIN="Global Check-in" +MOD_MENU_HELP="Help" +MOD_MENU_HELP_COMMUNITY="Community Portal" +MOD_MENU_HELP_CURRENT="Help with this page" +MOD_MENU_HELP_DEVELOPER="Developer Resources" +MOD_MENU_HELP_DOCUMENTATION="Documentation Wiki" +MOD_MENU_HELP_EXTENSIONS="Joomla! Extensions" +MOD_MENU_HELP_JOOMLA="Joomla! Help" +MOD_MENU_HELP_LINKS="Useful Joomla! links" +MOD_MENU_HELP_RESOURCES="Joomla! Resources" +MOD_MENU_HELP_SECURITY="Security Centre" +MOD_MENU_HELP_SHOP="Joomla! Shop" +MOD_MENU_HELP_SUPPORT_OFFICIAL_FORUM="Official Support Forum" +; the string below will be used if the localised sample data has a URL for the desired community forum or if the 'Custom Support Forum' field parameter in the Administrator Menu module has a URL +MOD_MENU_HELP_SUPPORT_CUSTOM_FORUM="Custom Support Forum" +; Enter in the string below the # of the specific language forum in https://forum.joomla.org/ (example: 19 for French). If left empty, it will use '511' which is the section for all languages forums. +MOD_MENU_HELP_SUPPORT_OFFICIAL_LANGUAGE_FORUM_VALUE="511" +; If you have chosen to display in the string above the section for all languages, translate the string below. +; If you have displayed the specific language forum, use something like "Official French Forum" in your language. +MOD_MENU_HELP_SUPPORT_OFFICIAL_LANGUAGE_FORUM="Official Language Forums" +MOD_MENU_HELP_TRANSLATIONS="Joomla! Translations" +MOD_MENU_HELP_XCHANGE="Stack Exchange" +MOD_MENU_HOME_DEFAULT="Home" +MOD_MENU_HOME_MULTIPLE="Warning! Multiple homes!" +MOD_MENU_IMPORTANT_ITEM_MENU_MANAGER="Menu Manager" +MOD_MENU_IMPORTANT_ITEM_MODULE_MANAGER="Module Manager" +MOD_MENU_IMPORTANT_ITEM_COMPONENTS_CONTAINER="Components Container" +MOD_MENU_IMPORTANT_ITEMS_INACCESSIBLE_LIST_WARNING="The administrator menu %1$s does not have - %2$s. Select to turn on the menu recovery mode." +MOD_MENU_INSTALLER_SUBMENU_DATABASE="Database" +MOD_MENU_INSTALLER_SUBMENU_DISCOVER="Discover" +MOD_MENU_INSTALLER_SUBMENU_INSTALL="Install" +MOD_MENU_INSTALLER_SUBMENU_LANGUAGES="Install Languages" +MOD_MENU_INSTALLER_SUBMENU_MANAGE="Manage" +MOD_MENU_INSTALLER_SUBMENU_UPDATE="Update" +MOD_MENU_INSTALLER_SUBMENU_UPDATESITES="Update Sites" +MOD_MENU_INSTALLER_SUBMENU_WARNINGS="Warnings" +MOD_MENU_LOGOUT="Logout" +MOD_MENU_MASS_MAIL_USERS="Mass Mail Users" +MOD_MENU_MEDIA_MANAGER="Media" +MOD_MENU_MENUS="Menus" +MOD_MENU_MENUS_ALL_ITEMS="All Menu Items" +MOD_MENU_MENU_MANAGER="Manage" +MOD_MENU_MENU_MANAGER_NEW_MENU="Add New Menu" +MOD_MENU_MENU_MANAGER_NEW_MENU_ITEM="Add New Menu Item" +MOD_MENU_NEW_PRIVATE_MESSAGE="New Private Message" +MOD_MENU_PURGE_EXPIRED_CACHE="Clear Expired Cache" +MOD_MENU_READ_PRIVATE_MESSAGES="Read Private Messages" +MOD_MENU_RECOVERY_EXIT="Exit Recovery Mode" +MOD_MENU_RECOVERY_MENU_ROOT="Menu Recovery" +MOD_MENU_SETTINGS="Settings" +MOD_MENU_MAINTENANCE="Maintenance" +MOD_MENU_SYSTEM_INFORMATION="System Information" +MOD_MENU_SYSTEM="System" +MOD_MENU_TOOLS="Tools" +MOD_MENU_USER_PROFILE="My Profile" +MOD_MENU_XML_DESCRIPTION="This module displays an administrator menu module." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.mod_menu.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.mod_menu.sys.ini new file mode 100644 index 00000000..1fe16106 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.mod_menu.sys.ini @@ -0,0 +1,9 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +MOD_MENU="Administrator Menu" +MOD_MENU_XML_DESCRIPTION="This module displays an administrator menu module." +MOD_MENU_LAYOUT_DEFAULT="Default" + diff --git a/Sites/pages/administrator/language/en-GB/en-GB.mod_multilangstatus.ini b/Sites/pages/administrator/language/en-GB/en-GB.mod_multilangstatus.ini new file mode 100644 index 00000000..0ce8e66d --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.mod_multilangstatus.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +MOD_MULTILANGSTATUS="Multilingual Status" +MOD_MULTILANGSTATUS_XML_DESCRIPTION="This module shows the status of the multilingual parameters." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.mod_multilangstatus.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.mod_multilangstatus.sys.ini new file mode 100644 index 00000000..78f35b0e --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.mod_multilangstatus.sys.ini @@ -0,0 +1,8 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +MOD_MULTILANGSTATUS="Multilingual Status" +MOD_MULTILANGSTATUS_XML_DESCRIPTION="This module shows the status of the multilingual parameters." + diff --git a/Sites/pages/administrator/language/en-GB/en-GB.mod_popular.ini b/Sites/pages/administrator/language/en-GB/en-GB.mod_popular.ini new file mode 100644 index 00000000..d07ec556 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.mod_popular.ini @@ -0,0 +1,37 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +MOD_POPULAR="Popular Articles" +MOD_POPULAR_CREATED="Created" +MOD_POPULAR_FIELD_AUTHORS_DESC="A filter for the Authors." +MOD_POPULAR_FIELD_AUTHORS_LABEL="Authors" +MOD_POPULAR_FIELD_CATEGORY_DESC="Select Articles from a specific Category or all Categories." +MOD_POPULAR_FIELD_COUNT_DESC="The number of items to display (default 5)." +MOD_POPULAR_FIELD_COUNT_LABEL="Count" +MOD_POPULAR_FIELD_VALUE_ADDED_OR_MODIFIED_BY_ME="Added or modified by me" +MOD_POPULAR_FIELD_VALUE_ANYONE="Anyone" +MOD_POPULAR_FIELD_VALUE_NOT_ADDED_OR_MODIFIED_BY_ME="Not added or modified by me" +MOD_POPULAR_ITEMS="Popular Items" +MOD_POPULAR_NO_MATCHING_RESULTS="No Matching Results" +MOD_POPULAR_TITLE="Popular Articles" +MOD_POPULAR_TITLE_1="Top Popular Article" +MOD_POPULAR_TITLE_MORE="Top %1$s Popular Articles" +MOD_POPULAR_TITLE_BY_ME="Top Popular Articles By Me" +MOD_POPULAR_TITLE_BY_ME_1="Top Popular Article By Me" +MOD_POPULAR_TITLE_BY_ME_MORE="Top %1$s Popular Articles By Me" +MOD_POPULAR_TITLE_NOT_ME="Top Popular Articles Not By Me" +MOD_POPULAR_TITLE_NOT_ME_1="Top Popular Article Not By Me" +MOD_POPULAR_TITLE_NOT_ME_MORE="Top %1$s Popular Articles Not By Me" +MOD_POPULAR_TITLE_CATEGORY="Top Popular Articles (%2$s category)" +MOD_POPULAR_TITLE_CATEGORY_1="Top Popular Article (%2$s category)" +MOD_POPULAR_TITLE_CATEGORY_MORE="Top %1$s Popular Articles (%2$s category)" +MOD_POPULAR_TITLE_CATEGORY_BY_ME="Top Popular Articles By Me (%2$s category)" +MOD_POPULAR_TITLE_CATEGORY_BY_ME_1="Top Popular Article By Me (%2$s category)" +MOD_POPULAR_TITLE_CATEGORY_BY_ME_MORE="Top %1$s Popular Articles By Me (%2$s category)" +MOD_POPULAR_TITLE_CATEGORY_NOT_ME="Top Popular Articles Not By Me (%2$s category)" +MOD_POPULAR_TITLE_CATEGORY_NOT_ME_1="Top Popular Article Not By Me (%2$s category)" +MOD_POPULAR_TITLE_CATEGORY_NOT_ME_MORE="Top %1$s Popular Articles Not By Me (%2$s category)" +MOD_POPULAR_UNEXISTING="Non existent" +MOD_POPULAR_XML_DESCRIPTION="This module shows a list of the most popular published Articles that are still current. Some that are shown may have expired even though they are the most recent." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.mod_popular.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.mod_popular.sys.ini new file mode 100644 index 00000000..d08c5430 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.mod_popular.sys.ini @@ -0,0 +1,9 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +MOD_POPULAR_XML_DESCRIPTION="This module shows a list of the most popular published Articles that are still current. Some that are shown may have expired even though they are the most recent." +MOD_POPULAR="Popular Articles" +MOD_POPULAR_LAYOUT_DEFAULT="Default" + diff --git a/Sites/pages/administrator/language/en-GB/en-GB.mod_privacy_dashboard.ini b/Sites/pages/administrator/language/en-GB/en-GB.mod_privacy_dashboard.ini new file mode 100644 index 00000000..1e906558 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.mod_privacy_dashboard.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +MOD_PRIVACY_DASHBOARD="Privacy Dashboard" +MOD_PRIVACY_DASHBOARD_XML_DESCRIPTION="The Privacy Dashboard Module shows information about privacy requests." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.mod_privacy_dashboard.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.mod_privacy_dashboard.sys.ini new file mode 100644 index 00000000..66ca5b2c --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.mod_privacy_dashboard.sys.ini @@ -0,0 +1,9 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +MOD_PRIVACY_DASHBOARD="Privacy Dashboard" +MOD_PRIVACY_DASHBOARD_XML_DESCRIPTION="The Privacy Dashboard Module shows information about privacy requests." +MOD_PRIVACY_DASHBOARD_LAYOUT_DEFAULT="Default" + diff --git a/Sites/pages/administrator/language/en-GB/en-GB.mod_quickicon.ini b/Sites/pages/administrator/language/en-GB/en-GB.mod_quickicon.ini new file mode 100644 index 00000000..491e9349 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.mod_quickicon.ini @@ -0,0 +1,33 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +MOD_QUICKICON="Quick Icons" +MOD_QUICKICON_ADD_NEW_ARTICLE="New Article" +MOD_QUICKICON_ARTICLE_MANAGER="Articles" +MOD_QUICKICON_CATEGORY_MANAGER="Categories" +MOD_QUICKICON_CLEAR_CACHE="Clear Cache" +MOD_QUICKICON_CONFIGURATION="Configuration" +MOD_QUICKICON_CONTENT="Content" +MOD_QUICKICON_EXTENSIONS="Extensions" +MOD_QUICKICON_EXTENSION_MANAGER="Extension Manager" +MOD_QUICKICON_FRONTPAGE_MANAGER="Front Page Manager" +MOD_QUICKICON_GLOBAL_CHECKIN="Global Check-in" +MOD_QUICKICON_GLOBAL_CONFIGURATION="Global" +MOD_QUICKICON_GROUP_DESC="The group of this module (this value is compared with the group value used in Quick Icons plugins to inject icons). The 'mod_quickicon' group always displays the Joomla! core icons." +MOD_QUICKICON_GROUP_LABEL="Group" +MOD_QUICKICON_INSTALL_EXTENSIONS="Install Extensions" +MOD_QUICKICON_LANGUAGE_MANAGER="Language(s)" +MOD_QUICKICON_MAINTENANCE="Maintenance" +MOD_QUICKICON_MEDIA_MANAGER="Media" +MOD_QUICKICON_MENU_MANAGER="Menu(s)" +MOD_QUICKICON_MODULE_MANAGER="Modules" +MOD_QUICKICON_PROFILE="Edit Profile" +MOD_QUICKICON_STRUCTURE="Structure" +MOD_QUICKICON_SYSTEM_INFORMATION="System Information" +MOD_QUICKICON_TEMPLATE_MANAGER="Templates" +MOD_QUICKICON_TITLE="Quick Icons" +MOD_QUICKICON_USER_MANAGER="Users" +MOD_QUICKICON_USERS="Users" +MOD_QUICKICON_XML_DESCRIPTION="This module shows Quick Icons that are visible on the Control Panel (administrator area home page)." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.mod_quickicon.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.mod_quickicon.sys.ini new file mode 100644 index 00000000..975b8291 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.mod_quickicon.sys.ini @@ -0,0 +1,9 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +MOD_QUICKICON="Quick Icons" +MOD_QUICKICON_XML_DESCRIPTION="This module shows Quick Icons that are visible on the Control Panel (administrator area home page)" +MOD_QUICKICON_LAYOUT_DEFAULT="Default" + diff --git a/Sites/pages/administrator/language/en-GB/en-GB.mod_sampledata.ini b/Sites/pages/administrator/language/en-GB/en-GB.mod_sampledata.ini new file mode 100644 index 00000000..cb77571f --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.mod_sampledata.ini @@ -0,0 +1,10 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +MOD_SAMPLEDATA="Sample Data" +MOD_SAMPLEDATA_CONFIRM_START="Proceeding will install a sample data set into your Joomla website. This process can't be reverted once done." +MOD_SAMPLEDATA_INVALID_RESPONSE="There is an error in a sample data plugin. Response is invalid." +MOD_SAMPLEDATA_ITEM_ALREADY_PROCESSED="This sample data set is already installed." +MOD_SAMPLEDATA_XML_DESCRIPTION="This Module allows to install sample data." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.mod_sampledata.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.mod_sampledata.sys.ini new file mode 100644 index 00000000..0af069c6 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.mod_sampledata.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +MOD_SAMPLEDATA="Sample Data" +MOD_SAMPLEDATA_XML_DESCRIPTION="This Module allows to install sample data." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.mod_stats_admin.ini b/Sites/pages/administrator/language/en-GB/en-GB.mod_stats_admin.ini new file mode 100644 index 00000000..890875bf --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.mod_stats_admin.ini @@ -0,0 +1,25 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +MOD_STATS_ADMIN="Statistics" +MOD_STATS_ARTICLES="Articles" +MOD_STATS_ARTICLES_VIEW_HITS="Articles View Hits" +MOD_STATS_CACHING="Caching" +MOD_STATS_FIELD_COUNTER_DESC="Display hit counter." +MOD_STATS_FIELD_COUNTER_LABEL="Hit Counter" +MOD_STATS_FIELD_INCREASECOUNTER_DESC="Enter the number of hits to increase the counter by." +MOD_STATS_FIELD_INCREASECOUNTER_LABEL="Increase Counter" +MOD_STATS_FIELD_SERVERINFO_DESC="Display server information." +MOD_STATS_FIELD_SERVERINFO_LABEL="Server Information" +MOD_STATS_FIELD_SITEINFO_DESC="Display site information." +MOD_STATS_FIELD_SITEINFO_LABEL="Site Information" +MOD_STATS_GZIP="Gzip" +MOD_STATS_MYSQL="MySQL" +MOD_STATS_OS="OS" +MOD_STATS_PHP="PHP" +MOD_STATS_TIME="Time" +MOD_STATS_USERS="Users" +MOD_STATS_WEBLINKS="Web Links" +MOD_STATS_XML_DESCRIPTION="The Statistics Module shows information about your server installation together with statistics on the website users and the number of Articles in your database." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.mod_stats_admin.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.mod_stats_admin.sys.ini new file mode 100644 index 00000000..eb7787c6 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.mod_stats_admin.sys.ini @@ -0,0 +1,9 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +MOD_STATS_ADMIN="Statistics" +MOD_STATS_LAYOUT_DEFAULT="Default" +MOD_STATS_XML_DESCRIPTION="The Statistics Module shows information about your server installation together with statistics on the website users and the number of Articles in your database." + diff --git a/Sites/pages/administrator/language/en-GB/en-GB.mod_status.ini b/Sites/pages/administrator/language/en-GB/en-GB.mod_status.ini new file mode 100644 index 00000000..ace8e2c7 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.mod_status.ini @@ -0,0 +1,34 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +MOD_STATUS="User Status" +MOD_STATUS_BACKEND_USERS_0="Administrators" +MOD_STATUS_BACKEND_USERS_1="Administrator" +MOD_STATUS_BACKEND_USERS_MORE="Administrators" +MOD_STATUS_FIELD_SHOW_VIEWSITE_LABEL="View Site" +MOD_STATUS_FIELD_SHOW_VIEWSITE_DESC="Show a link to the website home page." +MOD_STATUS_FIELD_LINK_VIEWADMIN_LABEL="Show Admin" +MOD_STATUS_FIELD_SHOW_VIEWADMIN_LABEL="View Administrator" +MOD_STATUS_FIELD_SHOW_VIEWADMIN_DESC="Show a link to open a new Administrator window." +MOD_STATUS_FIELD_SHOW_LOGGEDIN_USERS_ADMIN_DESC="Show the number of users logged-in to the Backend." +MOD_STATUS_FIELD_SHOW_LOGGEDIN_USERS_ADMIN_LABEL="Logged-in Backend Users" +MOD_STATUS_FIELD_SHOW_LOGGEDIN_USERS_DESC="Show the number of users logged-in to the Frontend." +MOD_STATUS_FIELD_SHOW_LOGGEDIN_USERS_LABEL="Logged-in Users" +MOD_STATUS_FIELD_SHOW_MESSAGES_DESC="Show the messages count for the current user's inbox." +MOD_STATUS_FIELD_SHOW_MESSAGES_LABEL="Messages" +MOD_STATUS_LOG_OUT="Log out" +MOD_STATUS_MESSAGES_0="%d Messages" +MOD_STATUS_MESSAGES_1="%d Message" +MOD_STATUS_MESSAGES_MORE="%d Messages" +MOD_STATUS_MESSAGES_LABEL_0="Messages" +MOD_STATUS_MESSAGES_LABEL_1="Message" +MOD_STATUS_MESSAGES_LABEL_MORE="Messages" +MOD_STATUS_TOTAL_USERS_0="Users" +MOD_STATUS_TOTAL_USERS_1="User" +MOD_STATUS_TOTAL_USERS_MORE="Users" +MOD_STATUS_USERS_0="Visitors" +MOD_STATUS_USERS_1="Visitor" +MOD_STATUS_USERS_MORE="Visitors" +MOD_STATUS_XML_DESCRIPTION="This module shows the status of the logged-in users and various shortcut links." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.mod_status.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.mod_status.sys.ini new file mode 100644 index 00000000..4818bc5e --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.mod_status.sys.ini @@ -0,0 +1,9 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +MOD_STATUS="User Status" +MOD_STATUS_XML_DESCRIPTION="This module shows the status of the logged-in users and various shortcut links." +MOD_STATUS_LAYOUT_DEFAULT="Default" + diff --git a/Sites/pages/administrator/language/en-GB/en-GB.mod_submenu.ini b/Sites/pages/administrator/language/en-GB/en-GB.mod_submenu.ini new file mode 100644 index 00000000..8bea4a4d --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.mod_submenu.ini @@ -0,0 +1,8 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +MOD_SUBMENU="Administrator Sub-Menu" +MOD_SUBMENU_XML_DESCRIPTION="This module shows the Sub-Menu Navigation Module." + diff --git a/Sites/pages/administrator/language/en-GB/en-GB.mod_submenu.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.mod_submenu.sys.ini new file mode 100644 index 00000000..8baa9544 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.mod_submenu.sys.ini @@ -0,0 +1,9 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +MOD_SUBMENU="Administrator Sub-Menu" +MOD_SUBMENU_XML_DESCRIPTION="This module shows the Sub-Menu Navigation Module." +MOD_SUBMENU_LAYOUT_DEFAULT="Default" + diff --git a/Sites/pages/administrator/language/en-GB/en-GB.mod_title.ini b/Sites/pages/administrator/language/en-GB/en-GB.mod_title.ini new file mode 100644 index 00000000..15f75410 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.mod_title.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +MOD_TITLE="Title" +MOD_TITLE_XML_DESCRIPTION="This module shows the Toolbar Component Title." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.mod_title.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.mod_title.sys.ini new file mode 100644 index 00000000..265dc9c8 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.mod_title.sys.ini @@ -0,0 +1,9 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +MOD_TITLE="Title" +MOD_TITLE_XML_DESCRIPTION="This module shows the Toolbar Component Title." +MOD_TITLE_LAYOUT_DEFAULT="Default" + diff --git a/Sites/pages/administrator/language/en-GB/en-GB.mod_toolbar.ini b/Sites/pages/administrator/language/en-GB/en-GB.mod_toolbar.ini new file mode 100644 index 00000000..8cac3f4d --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.mod_toolbar.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +MOD_TOOLBAR="Toolbar" +MOD_TOOLBAR_XML_DESCRIPTION="This module shows the toolbar icons used to control actions throughout the Administrator area." \ No newline at end of file diff --git a/Sites/pages/administrator/language/en-GB/en-GB.mod_toolbar.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.mod_toolbar.sys.ini new file mode 100644 index 00000000..ebdbebee --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.mod_toolbar.sys.ini @@ -0,0 +1,9 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +MOD_TOOLBAR="Toolbar" +MOD_TOOLBAR_XML_DESCRIPTION="This module shows the toolbar icons used to control actions throughout the Administrator area." +MOD_TOOLBAR_LAYOUT_DEFAULT="Default" + diff --git a/Sites/pages/administrator/language/en-GB/en-GB.mod_version.ini b/Sites/pages/administrator/language/en-GB/en-GB.mod_version.ini new file mode 100644 index 00000000..bc317e1c --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.mod_version.ini @@ -0,0 +1,13 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +MOD_VERSION="Joomla! Version Information" +MOD_VERSION_FORMAT_DESC="The long version includes code name and date." +MOD_VERSION_FORMAT_LABEL="Version Format" +MOD_VERSION_FORMAT_LONG="Long" +MOD_VERSION_FORMAT_SHORT="Short" +MOD_VERSION_PRODUCT_DESC="Include the text "Joomla!"." +MOD_VERSION_PRODUCT_LABEL="Show Joomla!" +MOD_VERSION_XML_DESCRIPTION="This module displays the Joomla! version." \ No newline at end of file diff --git a/Sites/pages/administrator/language/en-GB/en-GB.mod_version.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.mod_version.sys.ini new file mode 100644 index 00000000..88f7539f --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.mod_version.sys.ini @@ -0,0 +1,8 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +MOD_VERSION="Joomla! Version Information" +MOD_VERSION_LAYOUT_DEFAULT="Default" +MOD_VERSION_XML_DESCRIPTION="This module displays the Joomla! version." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_actionlog_joomla.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_actionlog_joomla.ini new file mode 100644 index 00000000..526c9564 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_actionlog_joomla.ini @@ -0,0 +1,58 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_ACTIONLOG_JOOMLA="Action Log - Joomla" +PLG_ACTIONLOG_JOOMLA_APPLICATION_ADMINISTRATOR="admin" +PLG_ACTIONLOG_JOOMLA_APPLICATION_SITE="site" +PLG_ACTIONLOG_JOOMLA_XML_DESCRIPTION="Record the actions of users on the site for Joomla core extensions so they can be reviewed if required." +; Content types title +PLG_ACTIONLOG_JOOMLA_TYPE_ACCESS_LEVEL="access level" +PLG_ACTIONLOG_JOOMLA_TYPE_APPLICATION_CONFIG="Global Configuration" +PLG_ACTIONLOG_JOOMLA_TYPE_ARTICLE="article" +PLG_ACTIONLOG_JOOMLA_TYPE_BANNER="banner" +PLG_ACTIONLOG_JOOMLA_TYPE_BANNER_CLIENT="banner client" +PLG_ACTIONLOG_JOOMLA_TYPE_CATEGORY="category" +PLG_ACTIONLOG_JOOMLA_TYPE_COMPONENT="component" +PLG_ACTIONLOG_JOOMLA_TYPE_COMPONENT_CONFIG="Component Configuration" +PLG_ACTIONLOG_JOOMLA_TYPE_CONTACT="contact" +PLG_ACTIONLOG_JOOMLA_TYPE_FILE="file" +PLG_ACTIONLOG_JOOMLA_TYPE_LANGUAGE="language" +PLG_ACTIONLOG_JOOMLA_TYPE_LIBRARY="library" +PLG_ACTIONLOG_JOOMLA_TYPE_LINK="link redirect" +PLG_ACTIONLOG_JOOMLA_TYPE_LINK_REDIRECT="link redirect" +PLG_ACTIONLOG_JOOMLA_TYPE_MEDIA="media" +PLG_ACTIONLOG_JOOMLA_TYPE_MENU="menu" +PLG_ACTIONLOG_JOOMLA_TYPE_MENU_ITEM="menu item" +PLG_ACTIONLOG_JOOMLA_TYPE_MODULE="module" +PLG_ACTIONLOG_JOOMLA_TYPE_NEWSFEED="newsfeed" +PLG_ACTIONLOG_JOOMLA_TYPE_PACKAGE="package" +PLG_ACTIONLOG_JOOMLA_TYPE_PLUGIN="plugin" +PLG_ACTIONLOG_JOOMLA_TYPE_STYLE="template style" +PLG_ACTIONLOG_JOOMLA_TYPE_TAG="tag" +PLG_ACTIONLOG_JOOMLA_TYPE_TEMPLATE="template" +PLG_ACTIONLOG_JOOMLA_TYPE_USER="user" +PLG_ACTIONLOG_JOOMLA_TYPE_USER_GROUP="user group" +PLG_ACTIONLOG_JOOMLA_TYPE_USER_NOTE="user note" +PLG_ACTIONLOG_JOOMLA_USER_CACHE="User {username} deleted cache group {group}" +PLG_ACTIONLOG_JOOMLA_USER_CHECKIN="User {username} performed a check in to table {table}" +PLG_ACTIONLOG_JOOMLA_USER_LOG="User {username} purged one or more rows from the action log" +PLG_ACTIONLOG_JOOMLA_USER_LOGEXPORT="User {username} exported one or more rows from the action log" +PLG_ACTIONLOG_JOOMLA_USER_LOGGED_IN="User {username} logged in to {app}" +PLG_ACTIONLOG_JOOMLA_USER_LOGGED_OUT="User {username} logged out from {app}" +PLG_ACTIONLOG_JOOMLA_USER_LOGIN_FAILED="User {username} tried to login to {app}" +PLG_ACTIONLOG_JOOMLA_USER_REGISTRATION_ACTIVATE="User {username} activated the account" +PLG_ACTIONLOG_JOOMLA_USER_REGISTERED="User {username} registered for an account" +PLG_ACTIONLOG_JOOMLA_USER_REMIND="User {username} requested a username reminder for their account" +PLG_ACTIONLOG_JOOMLA_USER_RESET_COMPLETE="User {username} completed the password reset for their account" +PLG_ACTIONLOG_JOOMLA_USER_RESET_REQUEST="User {username} requested a password reset for their account" +PLG_ACTIONLOG_JOOMLA_USER_UPDATE="User {username} updated Joomla from {oldversion} to {version}" +; Component +PLG_ACTIONLOG_JOOMLA_APPLICATION_CONFIG_UPDATED="User {username} changed settings of the application configuration" +PLG_ACTIONLOG_JOOMLA_COMPONENT_CONFIG_UPDATED="User {username} changed settings of the component {extension_name}" +; Extensions +PLG_ACTIONLOG_JOOMLA_EXTENSION_INSTALLED="User {username} installed the {type} {extension_name}" +PLG_ACTIONLOG_JOOMLA_EXTENSION_UNINSTALLED="User {username} uninstalled the {type} {extension_name}" +PLG_ACTIONLOG_JOOMLA_EXTENSION_UPDATED="User {username} updated the {type} {extension_name}" +PLG_ACTIONLOG_JOOMLA_PLUGIN_INSTALLED="User {username} installed the plugin {extension_name}" diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_actionlog_joomla.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_actionlog_joomla.sys.ini new file mode 100644 index 00000000..4d0e03f5 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_actionlog_joomla.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_ACTIONLOG_JOOMLA="Action Log - Joomla" +PLG_ACTIONLOG_JOOMLA_XML_DESCRIPTION="Record the actions of users on the site for Joomla core extensions so they can be reviewed if required." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_authentication_cookie.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_authentication_cookie.ini new file mode 100644 index 00000000..773d48db --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_authentication_cookie.ini @@ -0,0 +1,14 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_AUTH_COOKIE_ERROR_LOG_INVALIDATED_COOKIES="The authentication tokens were invalidated for user %u because there was no matching record." +PLG_AUTH_COOKIE_ERROR_LOG_LOGIN_FAILED="Cookie login failed for user %u." +PLG_AUTH_COOKIE_FIELD_COOKIE_LIFETIME_DESC="The number of days until the authentication cookie will expire. Other factors may cause it to expire before this. Longer lengths are less secure." +PLG_AUTH_COOKIE_FIELD_COOKIE_LIFETIME_LABEL="Cookie Lifetime" +PLG_AUTH_COOKIE_FIELD_KEY_LENGTH_DESC="The length of the key to use to encrypt the cookie. Longer lengths are more secure, but they will slow performance." +PLG_AUTH_COOKIE_FIELD_KEY_LENGTH_LABEL="Key Length" +PLG_AUTH_COOKIE_PRIVACY_CAPABILITY_COOKIE="In conjunction with a plugin which supports a \"Remember Me\" feature, such as the \"System - Remember Me\" plugin, this plugin creates a cookie in the user's browser if a \"Remember Me\" checkbox is selected when logging into the website. This cookie can be identified with the prefix `joomla_remember_me` and is used to automatically log users into the website when they visit and are not already logged in." +PLG_AUTH_COOKIE_XML_DESCRIPTION="Handles Joomla's cookie User authentication.
    Warning! You must have at least one other authentication plugin enabled.
    You will also need a plugin such as the System - Remember Me plugin to implement cookie login." +PLG_AUTHENTICATION_COOKIE="Authentication - Cookie" diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_authentication_cookie.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_authentication_cookie.sys.ini new file mode 100644 index 00000000..53318d1e --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_authentication_cookie.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_AUTH_COOKIE_XML_DESCRIPTION="Handles Joomla's cookie User authentication.
    Warning! You must have at least one other authentication plugin enabled.
    You will also need a plugin such as the System - Remember Me plugin to implement cookie login." +PLG_AUTHENTICATION_COOKIE="Authentication - Cookie" diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_authentication_gmail.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_authentication_gmail.ini new file mode 100644 index 00000000..1f9e1b48 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_authentication_gmail.ini @@ -0,0 +1,22 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_AUTHENTICATION_GMAIL="Authentication - Gmail" +PLG_GMAIL_ERROR_ACCOUNT_DISABLED_OR_NOT_ACTIVATED="Your local account is disabled or not activated." +PLG_GMAIL_ERROR_LOCAL_USERNAME_CONFLICT="A local username conflicts with your Gmail username." +PLG_GMAIL_FIELD_APPLYSUFFIX_DESC="Options for applying the suffix: Don't apply the suffix, only apply the suffix if missing (any user supplied suffix will be used) or always apply the suffix replacing any user supplied suffix." +PLG_GMAIL_FIELD_APPLYSUFFIX_LABEL="Apply Username Suffix" +PLG_GMAIL_FIELD_BACKEND_LOGIN_DESC="Allow Backend login via Gmail account?" +PLG_GMAIL_FIELD_BACKEND_LOGIN_LABEL="Backend Login" +PLG_GMAIL_FIELD_SUFFIX_DESC="A suffix to use for the username, typically gmail.com (or googlemail.com) is the suffix but you may wish to use a Google Apps for Your Domain suffix, this doesn't include the @ symbol. If left blank username suffix will be ignored." +PLG_GMAIL_FIELD_SUFFIX_LABEL="Username Suffix" +PLG_GMAIL_FIELD_USER_BLACKLIST_DESC="A list of usernames not permitted to log in via the Gmail plugin. The usernames should be separated by a comma." +PLG_GMAIL_FIELD_USER_BLACKLIST_LABEL="User Blacklist" +PLG_GMAIL_FIELD_VALUE_APPLYSUFFIXALWAYS="Always use suffix" +PLG_GMAIL_FIELD_VALUE_APPLYSUFFIXMISSING="Apply suffix if missing" +PLG_GMAIL_FIELD_VALUE_NOAPPLYSUFFIX="Don't Apply Suffix" +PLG_GMAIL_FIELD_VERIFYPEER_DESC="Verify the peer connection using a CA certificate. In some situations authentication will fail due to certificate issues, disabling this should resolve the situation in that case." +PLG_GMAIL_FIELD_VERIFYPEER_LABEL="Verify Peer" +PLG_GMAIL_XML_DESCRIPTION="Handles User Authentication with a Gmail or Googlemail account (Requires cURL).
    Users may need to enable Access for less secure apps at https://www.google.com/settings/security/lesssecureapps to be able to log in using this method.
    Warning! You must have at least one authentication plugin enabled or you will lose all access to your site." \ No newline at end of file diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_authentication_gmail.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_authentication_gmail.sys.ini new file mode 100644 index 00000000..9d1ca0ac --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_authentication_gmail.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_AUTHENTICATION_GMAIL="Authentication - Gmail" +PLG_GMAIL_XML_DESCRIPTION="Handles User Authentication with a Gmail or Googlemail account (Requires cURL).
    Users may need to enable Access for less secure apps at https://www.google.com/settings/security/lesssecureapps to be able to log in using this method.
    Warning! You must have at least one authentication plugin enabled or you will lose all access to your site." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_authentication_joomla.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_authentication_joomla.ini new file mode 100644 index 00000000..9fd45e2f --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_authentication_joomla.ini @@ -0,0 +1,8 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_AUTH_JOOMLA_ERR_SECRET_CODE_WITHOUT_TFA="You need to enable two factor authentication in your user profile to use the secret code field." +PLG_AUTH_JOOMLA_XML_DESCRIPTION="Handles Joomla's default User authentication.
    Warning! You must have at least one authentication plugin enabled or you will lose all access to your site." +PLG_AUTHENTICATION_JOOMLA="Authentication - Joomla" \ No newline at end of file diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_authentication_joomla.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_authentication_joomla.sys.ini new file mode 100644 index 00000000..9a602648 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_authentication_joomla.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_AUTH_JOOMLA_XML_DESCRIPTION="Handles Joomla's default User authentication.
    Warning! You must have at least one authentication plugin enabled or you will lose all access to your site." +PLG_AUTHENTICATION_JOOMLA="Authentication - Joomla" \ No newline at end of file diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_authentication_ldap.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_authentication_ldap.ini new file mode 100644 index 00000000..8c1586b5 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_authentication_ldap.ini @@ -0,0 +1,41 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_AUTHENTICATION_LDAP="Authentication - LDAP" +PLG_LDAP_FIELD_AUTHMETHOD_DESC="The authorisation method to validate the credentials." +PLG_LDAP_FIELD_AUTHMETHOD_LABEL="Authorisation Method" +PLG_LDAP_FIELD_BASEDN_DESC="The base DN of your LDAP server, eg o=example.com." +PLG_LDAP_FIELD_BASEDN_LABEL="Base DN" +PLG_LDAP_FIELD_EMAIL_DESC="LDAP attribute which has the User's email address." +PLG_LDAP_FIELD_EMAIL_LABEL="Map: Email" +PLG_LDAP_FIELD_FULLNAME_DESC="LDAP attribute which has the User's full name." +PLG_LDAP_FIELD_FULLNAME_LABEL="Map: Full Name" +PLG_LDAP_FIELD_IGNORE_REQCERT_TLS_DESC="When enabled ignore the server certificate, this is useful when running for example Samba 4 with a self-signed certificate." +PLG_LDAP_FIELD_IGNORE_REQCERT_TLS_LABEL="Ignore Certificate" +PLG_LDAP_FIELD_HOST_DESC="Eg: openldap.example.com." +PLG_LDAP_FIELD_HOST_LABEL="Host" +PLG_LDAP_FIELD_LDAPDEBUG_DESC="Enables debug hardcoded to level 7" +PLG_LDAP_FIELD_LDAPDEBUG_LABEL="Debug" +PLG_LDAP_FIELD_NEGOCIATE_DESC="Negotiate TLS encryption with the LDAP server. This requires all traffic to and from the LDAP server to be encrypted." +PLG_LDAP_FIELD_NEGOCIATE_LABEL="Negotiate TLS" +PLG_LDAP_FIELD_PASSWORD_DESC="The Connect Password is the password of an administrative account. This is used in Authenticate then Bind and Authenticated Compare authorisation methods." +PLG_LDAP_FIELD_PASSWORD_LABEL="Connect Password" +PLG_LDAP_FIELD_PORT_DESC="Default port is 389." +PLG_LDAP_FIELD_PORT_LABEL="Port" +PLG_LDAP_FIELD_REFERRALS_DESC="This option sets the value of the LDAP_OPT_REFERRALS flag. You will need to set it to No for Windows 2003 servers." +PLG_LDAP_FIELD_REFERRALS_LABEL="Follow Referrals" +PLG_LDAP_FIELD_SEARCHSTRING_DESC="A query string used to search for a given User. The [search] keyword is dynamically replaced by the User-provided login. An example string is: uid=[search]. Several strings can be used separated by semicolons. Only used when searching." +PLG_LDAP_FIELD_SEARCHSTRING_LABEL="Search String" +PLG_LDAP_FIELD_UID_DESC="LDAP Attribute which has the User's Login ID. For Active Directory this is sAMAccountName." +PLG_LDAP_FIELD_UID_LABEL="Map: User ID" +PLG_LDAP_FIELD_USERNAME_DESC="The Connect Username and Connect Password define connection parameters for the DN lookup phase. Two options are available:- Anonymous DN lookup (leave both fields blank); Administrative connection: Connect Username is the username of an administrative account, for example Administrator. Connect password is the actual password of your administrative account." +PLG_LDAP_FIELD_USERNAME_LABEL="Connect Username" +PLG_LDAP_FIELD_USERSDN_DESC="The [username] keyword is dynamically replaced by the User-provided login. An example string is: uid=[username], dc=my-domain, dc=com. Several strings can be used, separated by semicolons. Only used for direct binds." +PLG_LDAP_FIELD_USERSDN_LABEL="User's DN" +PLG_LDAP_FIELD_V3_DESC="Default is LDAP2, but the latest versions of OpenLdap require clients to use LDAPV3." +PLG_LDAP_FIELD_V3_LABEL="LDAP V3" +PLG_LDAP_FIELD_VALUE_BINDSEARCH="Bind and Search" +PLG_LDAP_FIELD_VALUE_BINDUSER="Bind Directly as User" +PLG_LDAP_XML_DESCRIPTION="Handles User Authentication against an LDAP server.
    Warning! You must have at least one authentication plugin enabled or you will lose all access to your site." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_authentication_ldap.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_authentication_ldap.sys.ini new file mode 100644 index 00000000..7826e0b1 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_authentication_ldap.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_AUTHENTICATION_LDAP="Authentication - LDAP" +PLG_LDAP_XML_DESCRIPTION="Handles User Authentication against an LDAP server.
    Warning! You must have at least one authentication plugin enabled or you will lose all access to your site." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_captcha_recaptcha.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_captcha_recaptcha.ini new file mode 100644 index 00000000..0571daf9 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_captcha_recaptcha.ini @@ -0,0 +1,73 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_CAPTCHA_RECAPTCHA="CAPTCHA - reCAPTCHA" +PLG_CAPTCHA_RECAPTCHA_XML_DESCRIPTION="This CAPTCHA plugin uses the reCAPTCHA service to prevent spammers while it helps to digitize books, newspapers and old radio shows. To get a site and secret key for your domain, go to https://www.google.com/recaptcha. To use this for new account registration, go to Options in the User Manager and select CAPTCHA - reCAPTCHA as the CAPTCHA." +PLG_PLG_RECAPTCHA_VERSION_1_POSTINSTALL_ACTION="Update reCAPTCHA settings" +PLG_PLG_RECAPTCHA_VERSION_1_POSTINSTALL_BODY="Support for reCAPTCHA v1 will be turned off by Google on March 31, 2018. Please update the settings in the reCAPTCHA plugin to use Version 2.0." +PLG_PLG_RECAPTCHA_VERSION_1_POSTINSTALL_TITLE="reCAPTCHA v1 - discontinued" +; Params +PLG_RECAPTCHA_VERSION_1_WARNING_LABEL="You have selected Version 1.0. As of March 31, 2018 this will no longer work and you should use Version 2.0." +PLG_RECAPTCHA_VERSION_DESC="Version 2.0 is the recommended version." +PLG_RECAPTCHA_VERSION_LABEL="Version" +PLG_RECAPTCHA_CALLBACK_DESC="(Optional) JavaScript callback, executed after successful reCAPTCHA response." +PLG_RECAPTCHA_CALLBACK_LABEL="Callback" +PLG_RECAPTCHA_ERROR_CALLBACK_DESC="(Optional) JavaScript callback, executed when the reCAPTCHA encounters an error." +PLG_RECAPTCHA_ERROR_CALLBACK_LABEL="Error Callback" +PLG_RECAPTCHA_EXPIRED_CALLBACK_DESC="(Optional) JavaScript callback, executed when the reCAPTCHA expired." +PLG_RECAPTCHA_EXPIRED_CALLBACK_LABEL="Expired Callback" +PLG_RECAPTCHA_LANG_DESC="Select the language for the reCAPTCHA. If default is set and the language file has a custom translation, it will be used." +PLG_RECAPTCHA_LANG_LABEL="Language" +PLG_RECAPTCHA_PRIVATE_KEY_DESC="Used in the communication between your server and the reCAPTCHA server. Be sure to keep it a secret. See the plugin description for instructions on getting a secret key." +PLG_RECAPTCHA_PRIVATE_KEY_LABEL="Secret Key" +PLG_RECAPTCHA_PUBLIC_KEY_DESC="Used in the JavaScript code that is served to your users. See the plugin description for instructions on getting a site key." +PLG_RECAPTCHA_PUBLIC_KEY_LABEL="Site Key" +PLG_RECAPTCHA_SIZE_DESC="Select the size for the reCAPTCHA field." +PLG_RECAPTCHA_SIZE_LABEL="Size" +PLG_RECAPTCHA_TABINDEX_DESC="The tabindex of the reCAPTCHA widget." +PLG_RECAPTCHA_TABINDEX_LABEL="Tabindex" +PLG_RECAPTCHA_THEME_BLACKGLASS="BlackGlass" +PLG_RECAPTCHA_THEME_CLEAN="Clean" +PLG_RECAPTCHA_THEME_COMPACT="Compact" +PLG_RECAPTCHA_THEME_DARK="Dark" +PLG_RECAPTCHA_THEME_DESC="Defines which theme to use for reCAPTCHA." +PLG_RECAPTCHA_THEME_LABEL="Theme" +PLG_RECAPTCHA_THEME_LIGHT="Light" +PLG_RECAPTCHA_THEME_NORMAL="Normal" +PLG_RECAPTCHA_THEME_RED="Red" +PLG_RECAPTCHA_THEME_WHITE="White" +; The following two strings are deprecated and will be removed with 4.0. They generate wrong plural detection in Crowdin. +PLG_RECAPTCHA_VERSION_1="1.0" +PLG_RECAPTCHA_VERSION_2="2.0" +PLG_RECAPTCHA_VERSION_V1="1.0" +PLG_RECAPTCHA_VERSION_V2="2.0" +; Error messages +PLG_RECAPTCHA_ERROR_EMPTY_SOLUTION="Please complete the CAPTCHA." +PLG_RECAPTCHA_ERROR_INCORRECT_CAPTCHA_SOL="The CAPTCHA was incorrect." +PLG_RECAPTCHA_ERROR_INVALID_REFERRER="reCAPTCHA API keys are tied to a specific domain name for security reasons." +PLG_RECAPTCHA_ERROR_INVALID_REQUEST_COOKIE="The challenge parameter of the verify script was incorrect." +PLG_RECAPTCHA_ERROR_INVALID_SITE_PRIVATE_KEY="We weren't able to verify the secret key." +PLG_RECAPTCHA_ERROR_INVALID_SITE_PUBLIC_KEY="We weren't able to verify the site key." +PLG_RECAPTCHA_ERROR_NO_IP="For security reasons, you must pass the remote IP address to reCAPTCHA." +PLG_RECAPTCHA_ERROR_NO_PRIVATE_KEY="reCAPTCHA plugin needs a secret key to be set in its parameters. Please contact a site administrator." +PLG_RECAPTCHA_ERROR_NO_PUBLIC_KEY="reCAPTCHA plugin needs a site key to be set in its parameters. Please contact a site administrator." +PLG_RECAPTCHA_ERROR_RECAPTCHA_NOT_REACHABLE="Unable to contact the reCAPTCHA verify server." +PLG_RECAPTCHA_ERROR_UNKNOWN="Unknown error." +PLG_RECAPTCHA_ERROR_VERIFY_PARAMS_INCORRECT="The parameters to verify were incorrect, make sure you are passing all the required parameters." +; Privacy notice +PLG_RECAPTCHA_PRIVACY_CAPABILITY_IP_ADDRESS="The reCAPTCHA plugin integrates with Google's reCAPTCHA system as a spam protection service. As part of this service, the IP address of the user answering the captcha challenge is transmitted to Google." +; Uncomment(remove the ";" from the beginning of the line) the following lines if reCAPTCHA is not available in your language +; When uncommenting, do NOT translate PLG_RECAPTCHA_CUSTOM_LANG +; As of 01/01/2012, the following languages do not need translation: en, nl, fr, de, pt, ru, es, tr +;PLG_RECAPTCHA_AUDIO_CHALLENGE="Get an audio challenge" +;PLG_RECAPTCHA_CANT_HEAR_THIS="Download sound as MP3" +;PLG_RECAPTCHA_CUSTOM_LANG="true" +;PLG_RECAPTCHA_HELP_BTN="Help" +;PLG_RECAPTCHA_INCORRECT_TRY_AGAIN="Incorrect. Try again." +;PLG_RECAPTCHA_INSTRUCTIONS_AUDIO="Type what you hear:" +;PLG_RECAPTCHA_INSTRUCTIONS_VISUAL="Type the two words:" +;PLG_RECAPTCHA_PLAY_AGAIN="Play sound again" +;PLG_RECAPTCHA_REFRESH_BTN="Get a new challenge" +;PLG_RECAPTCHA_VISUAL_CHALLENGE="Get a visual challenge" diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_captcha_recaptcha.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_captcha_recaptcha.sys.ini new file mode 100644 index 00000000..df43a2b5 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_captcha_recaptcha.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_CAPTCHA_RECAPTCHA_XML_DESCRIPTION="This CAPTCHA plugin uses the reCAPTCHA service to prevent spammers while it helps to digitize books, newspapers and old radio shows. To get a site and secret key for your domain, go to https://www.google.com/recaptcha. To use this for new account registration, go to Options in the User Manager and select CAPTCHA - reCAPTCHA as the CAPTCHA." +PLG_CAPTCHA_RECAPTCHA="CAPTCHA - reCAPTCHA" diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_captcha_recaptcha_invisible.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_captcha_recaptcha_invisible.ini new file mode 100644 index 00000000..b20c02e2 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_captcha_recaptcha_invisible.ini @@ -0,0 +1,32 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_CAPTCHA_RECAPTCHA_INVISIBLE="CAPTCHA - Invisible reCAPTCHA" +PLG_CAPTCHA_RECAPTCHA_INVISIBLE_XML_DESCRIPTION="This CAPTCHA plugin uses the Invisible reCAPTCHA service. To get a site and secret key for your domain, go to https://www.google.com/recaptcha." +; Params +PLG_RECAPTCHA_INVISIBLE_BADGE_BOTTOMLEFT="Bottom left" +PLG_RECAPTCHA_INVISIBLE_BADGE_BOTTOMRIGHT="Bottom right" +PLG_RECAPTCHA_INVISIBLE_BADGE_DESC="Positioning of the reCAPTCHA badge." +PLG_RECAPTCHA_INVISIBLE_BADGE_INLINE="Inline" +PLG_RECAPTCHA_INVISIBLE_BADGE_LABEL="Badge" +PLG_RECAPTCHA_INVISIBLE_CALLBACK_DESC="(Optional) JavaScript callback, executed after successful reCAPTCHA response." +PLG_RECAPTCHA_INVISIBLE_CALLBACK_LABEL="Callback" +PLG_RECAPTCHA_INVISIBLE_ERROR_CALLBACK_DESC="(Optional) JavaScript callback, executed when the reCAPTCHA encounters an error." +PLG_RECAPTCHA_INVISIBLE_ERROR_CALLBACK_LABEL="Error Callback" +PLG_RECAPTCHA_INVISIBLE_EXPIRED_CALLBACK_DESC="(Optional) JavaScript callback, executed when the reCAPTCHA expired." +PLG_RECAPTCHA_INVISIBLE_EXPIRED_CALLBACK_LABEL="Expired Callback" +PLG_RECAPTCHA_INVISIBLE_PRIVATE_KEY_DESC="Used in the communication between your server and the reCAPTCHA server. Be sure to keep it a secret." +PLG_RECAPTCHA_INVISIBLE_PRIVATE_KEY_LABEL="Secret Key" +PLG_RECAPTCHA_INVISIBLE_PUBLIC_KEY_DESC="Used in the JavaScript code that is served to your users." +PLG_RECAPTCHA_INVISIBLE_PUBLIC_KEY_LABEL="Site Key" +PLG_RECAPTCHA_INVISIBLE_TABINDEX_DESC="The tabindex of the challenge." +PLG_RECAPTCHA_INVISIBLE_TABINDEX_LABEL="Tabindex" +; Privacy notice +PLG_RECAPTCHA_INVISIBLE_PRIVACY_CAPABILITY_IP_ADDRESS="The Invisible reCAPTCHA plugin integrates with Google's reCAPTCHA system as a spam protection service. As part of this service, the IP address of the user answering the captcha challenge is transmitted to Google." +; Error messages +PLG_RECAPTCHA_INVISIBLE_ERROR_EMPTY_SOLUTION="Empty solution not allowed." +PLG_RECAPTCHA_INVISIBLE_ERROR_NO_IP="For security reasons, you must pass the remote IP address to reCAPTCHA." +PLG_RECAPTCHA_INVISIBLE_ERROR_NO_PRIVATE_KEY="reCAPTCHA plugin needs a secret key to be set in its parameters. Please contact a site administrator." +PLG_RECAPTCHA_INVISIBLE_ERROR_NO_PUBLIC_KEY="reCAPTCHA plugin needs a site key to be set in its parameters. Please contact a site administrator." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_captcha_recaptcha_invisible.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_captcha_recaptcha_invisible.sys.ini new file mode 100644 index 00000000..87af6e47 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_captcha_recaptcha_invisible.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_CAPTCHA_RECAPTCHA_INVISIBLE="CAPTCHA - Invisible reCAPTCHA" +PLG_CAPTCHA_RECAPTCHA_INVISIBLE_XML_DESCRIPTION="This CAPTCHA plugin uses the Invisible reCAPTCHA service. To get a site and secret key for your domain, go to https://www.google.com/recaptcha." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_content_confirmconsent.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_content_confirmconsent.ini new file mode 100644 index 00000000..0818359b --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_content_confirmconsent.ini @@ -0,0 +1,13 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_CONTENT_CONFIRMCONSENT="Content - Confirm Consent" +PLG_CONTENT_CONFIRMCONSENT_CONSENTBOX_LABEL="Privacy Note" +PLG_CONTENT_CONFIRMCONSENT_FIELD_ARTICLE_DESC="Select the article from the list or create a new one." +PLG_CONTENT_CONFIRMCONSENT_FIELD_ARTICLE_LABEL="Privacy Article" +PLG_CONTENT_CONFIRMCONSENT_FIELD_NOTE_DEFAULT="By submitting this form you agree to the Privacy Policy of this website and the storing of the submitted information." +PLG_CONTENT_CONFIRMCONSENT_FIELD_NOTE_DESC="A summary of the site's privacy policy. If left blank then the default message will be used." +PLG_CONTENT_CONFIRMCONSENT_FIELD_NOTE_LABEL="Short Privacy Policy" +PLG_CONTENT_CONFIRMCONSENT_XML_DESCRIPTION="This plugin adds a required consent checkbox to a form eg the core contact component." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_content_confirmconsent.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_content_confirmconsent.sys.ini new file mode 100644 index 00000000..fdce86d6 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_content_confirmconsent.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_CONTENT_CONFIRMCONSENT="Content - Confirm Consent" +PLG_CONTENT_CONFIRMCONSENT_XML_DESCRIPTION="This plugin adds a required consent checkbox to a form eg the core contact component." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_content_contact.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_content_contact.ini new file mode 100644 index 00000000..20e3c1d3 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_content_contact.ini @@ -0,0 +1,14 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_CONTENT_CONTACT="Content - Contact" +PLG_CONTENT_CONTACT_XML_DESCRIPTION="Provides a link between the content author and the contact item that can be used for an Author Profile." +PLG_CONTENT_CONTACT_PARAM_URL_LABEL="Redirection" +PLG_CONTENT_CONTACT_PARAM_URL_DESCRIPTION="You can link the author name to:

    • Associated contact page.
    • Webpage specified in the associated contact profile.
    • Email specified in the associated contact profile.
    " +PLG_CONTENT_CONTACT_PARAM_URL_URL="Internal contact page" +PLG_CONTENT_CONTACT_PARAM_URL_WEBPAGE="Webpage from contact" +PLG_CONTENT_CONTACT_PARAM_URL_EMAIL="Email from contact" +PLG_CONTENT_CONTACT_PARAM_ALIAS_LABEL="Apply link also to alias name" +PLG_CONTENT_CONTACT_PARAM_ALIAS_DESCRIPTION="Link to the real user data even if an author alias is set in article options." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_content_contact.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_content_contact.sys.ini new file mode 100644 index 00000000..d332741a --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_content_contact.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_CONTENT_CONTACT="Content - Contact" +PLG_CONTENT_CONTACT_XML_DESCRIPTION="Provides a link between the content author and the contact item that can be used for an Author Profile." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_content_emailcloak.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_content_emailcloak.ini new file mode 100644 index 00000000..6861b0f3 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_content_emailcloak.ini @@ -0,0 +1,11 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_CONTENT_EMAILCLOAK="Content - Email Cloaking" +PLG_CONTENT_EMAILCLOAK_LINKABLE="As linkable mailto address" +PLG_CONTENT_EMAILCLOAK_MODE_DESC="Select how email addresses will be displayed." +PLG_CONTENT_EMAILCLOAK_MODE_LABEL="Mode" +PLG_CONTENT_EMAILCLOAK_NONLINKABLE="Non-linkable Text" +PLG_CONTENT_EMAILCLOAK_XML_DESCRIPTION="Cloaks all email addresses in content from spambots using JavaScript." \ No newline at end of file diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_content_emailcloak.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_content_emailcloak.sys.ini new file mode 100644 index 00000000..f3a46ca3 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_content_emailcloak.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_CONTENT_EMAILCLOAK="Content - Email Cloaking" +PLG_CONTENT_EMAILCLOAK_XML_DESCRIPTION="Cloaks all email addresses in content from spambots using JavaScript." \ No newline at end of file diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_content_fields.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_content_fields.ini new file mode 100644 index 00000000..d4d987df --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_content_fields.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_CONTENT_FIELDS="Content - Fields" +PLG_CONTENT_FIELDS_XML_DESCRIPTION="This plugin allows you to display a custom field which has been inserted with the 'Button - Fields' plugin or using Syntax: {field #} directly into the editor area.
    Possible Syntax:
    • {field 1} will display the field with the ID 1
    • {field 1,foo} will display the selected field using the alternative layout 'foo'.
    • {fieldgroup 2} will display all fields within the fieldgroup with the ID 2.
    " diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_content_fields.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_content_fields.sys.ini new file mode 100644 index 00000000..5fe9eb12 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_content_fields.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_CONTENT_FIELDS="Content - Fields" +PLG_CONTENT_FIELDS_XML_DESCRIPTION="This plugin allows you to display a custom field which has been inserted with the 'Button - Fields' plugin or using Syntax: {field #} directly into the editor area." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_content_finder.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_content_finder.ini new file mode 100644 index 00000000..d5b52824 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_content_finder.ini @@ -0,0 +1,17 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_CONTENT_FINDER="Content - Smart Search" +PLG_CONTENT_FINDER_XML_DESCRIPTION="Changes to content will not update the Smart Search index if you do not enable this plugin." + +PLG_FINDER_QUERY_FILTER_BRANCH_P__="All" + +PLG_FINDER_QUERY_FILTER_BRANCH_S_TYPE="Type" +PLG_FINDER_QUERY_FILTER_BRANCH_S_LANGUAGE="Language" +PLG_FINDER_QUERY_FILTER_BRANCH_S_CATEGORY="Category" + +PLG_FINDER_QUERY_FILTER_BRANCH_P_TYPE="Types" +PLG_FINDER_QUERY_FILTER_BRANCH_P_LANGUAGE="Languages" +PLG_FINDER_QUERY_FILTER_BRANCH_P_CATEGORY="Categories" diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_content_finder.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_content_finder.sys.ini new file mode 100644 index 00000000..0d1148ae --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_content_finder.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_CONTENT_FINDER="Content - Smart Search" +PLG_CONTENT_FINDER_XML_DESCRIPTION="Changes to content will not update the Smart Search index if you do not enable this plugin." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_content_joomla.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_content_joomla.ini new file mode 100644 index 00000000..5accc87b --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_content_joomla.ini @@ -0,0 +1,11 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_CONTENT_JOOMLA="Content - Joomla" +PLG_CONTENT_JOOMLA_FIELD_CHECK_CATEGORIES_DESC="Check that categories are fully empty before they are deleted." +PLG_CONTENT_JOOMLA_FIELD_CHECK_CATEGORIES_LABEL="Check Category Deletion" +PLG_CONTENT_JOOMLA_FIELD_EMAIL_NEW_FE_DESC="Email users if 'Send email' is on when there is a new article submitted via the Frontend." +PLG_CONTENT_JOOMLA_FIELD_EMAIL_NEW_FE_LABEL="Email on New Site Article" +PLG_CONTENT_JOOMLA_XML_DESCRIPTION="This plugin does category processing for core extensions; sends an email when new article is submitted in the Frontend." \ No newline at end of file diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_content_joomla.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_content_joomla.sys.ini new file mode 100644 index 00000000..ed5c6c14 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_content_joomla.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_CONTENT_JOOMLA="Content - Joomla" +PLG_CONTENT_JOOMLA_XML_DESCRIPTION="This plugin does category processing for core extensions; sends an email when new article is submitted in the Frontend." \ No newline at end of file diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_content_loadmodule.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_content_loadmodule.ini new file mode 100644 index 00000000..fe62b268 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_content_loadmodule.ini @@ -0,0 +1,14 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_CONTENT_LOADMODULE="Content - Load Modules" +PLG_LOADMODULE_FIELD_STYLE_DESC="Code that will wrap Modules." +PLG_LOADMODULE_FIELD_STYLE_LABEL="Style" +PLG_LOADMODULE_FIELD_VALUE_DIVS="Wrapped by Divs" +PLG_LOADMODULE_FIELD_VALUE_HORIZONTAL="Wrapped by table (horizontal)" +PLG_LOADMODULE_FIELD_VALUE_MULTIPLEDIVS="Wrapped by Multiple Divs" +PLG_LOADMODULE_FIELD_VALUE_RAW="No wrapping (raw output)" +PLG_LOADMODULE_FIELD_VALUE_TABLE="Wrapped by table (column)" +PLG_LOADMODULE_XML_DESCRIPTION="Within content this plugin loads a Module by ID, Syntax: {loadmoduleid 1} or a Module by position, Syntax: {loadposition user1} or a Module by name, Syntax: {loadmodule mod_login}. Optionally can specify module style and for loadmodule a specific module by title, Syntax: {loadmodule mod_login,module title,style}." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_content_loadmodule.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_content_loadmodule.sys.ini new file mode 100644 index 00000000..6937ac1b --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_content_loadmodule.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_CONTENT_LOADMODULE="Content - Load Modules" +PLG_LOADMODULE_XML_DESCRIPTION="Within content this plugin loads a Module by ID, Syntax: {loadmoduleid 1} or a Module by position, Syntax: {loadposition user1} or a Module by name, Syntax: {loadmodule mod_login}. Optionally can specify module style and for loadmodule a specific module by title, Syntax: {loadmodule mod_login,module title,style}." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_content_pagebreak.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_content_pagebreak.ini new file mode 100644 index 00000000..49a8f69c --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_content_pagebreak.ini @@ -0,0 +1,27 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + + +PLG_CONTENT_PAGEBREAK="Content - Page Break" +PLG_CONTENT_PAGEBREAK_ALL_PAGES="All Pages" +PLG_CONTENT_PAGEBREAK_ARTICLE_INDEX="Article Index" +PLG_CONTENT_PAGEBREAK_NO_TITLE="No title" +PLG_CONTENT_PAGEBREAK_PAGES="Pages" +PLG_CONTENT_PAGEBREAK_PAGE_NUM="Page %s" +PLG_CONTENT_PAGEBREAK_SHOW_ALL_DESC="Displays the full article." +PLG_CONTENT_PAGEBREAK_SHOW_ALL_LABEL="Show All" +PLG_CONTENT_PAGEBREAK_SITE_ARTICLEINDEXTEXT="Custom Article Index Heading" +PLG_CONTENT_PAGEBREAK_SITE_ARTICLEINDEXTEXT_DESC="Enter a custom text for the Article Index Heading. If empty, standard will be used." +PLG_CONTENT_PAGEBREAK_SITE_ARTICLEINDEX_DESC="Show or hide Article Index Heading. The Heading displays on top of the Table of Contents." +PLG_CONTENT_PAGEBREAK_SITE_ARTICLEINDEX_LABEL="Article Index Heading" +PLG_CONTENT_PAGEBREAK_SITE_TITLE_DESC="Title and heading attributes from Plugin added to Site Title tag." +PLG_CONTENT_PAGEBREAK_SITE_TITLE_LABEL="Show Site Title" +PLG_CONTENT_PAGEBREAK_SLIDERS="Sliders" +PLG_CONTENT_PAGEBREAK_STYLE_DESC="Display the article with separate pages, tabs or sliders." +PLG_CONTENT_PAGEBREAK_STYLE_LABEL="Presentation Style" +PLG_CONTENT_PAGEBREAK_TABS="Tabs" +PLG_CONTENT_PAGEBREAK_TOC_DESC="Display a table of contents on multipage Articles." +PLG_CONTENT_PAGEBREAK_TOC_LABEL="Table of Contents" +PLG_CONTENT_PAGEBREAK_XML_DESCRIPTION="Allow the creation of a paginated article with an optional table of contents.

    Insert page breaks through the use of the page break button normally found in the WYSIWYG editor toolbar. The location of the page break in an article will be displayed in the editor as a simple horizontal line.

    The text displayed will depend on the options chosen and may be either the title, alternate text (if provided) or page numbers.

    The HTML usage is:
    <hr class="system-pagebreak" />
    <hr class="system-pagebreak" title="The page title" /> or
    <hr class="system-pagebreak" alt="The first page" /> or
    <hr class="system-pagebreak" title="The page title" alt="The first page" /> or
    <hr class="system-pagebreak" alt="The first page" title="The page title" />" diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_content_pagebreak.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_content_pagebreak.sys.ini new file mode 100644 index 00000000..849f402d --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_content_pagebreak.sys.ini @@ -0,0 +1,8 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + + +PLG_CONTENT_PAGEBREAK="Content - Page Break" +PLG_CONTENT_PAGEBREAK_XML_DESCRIPTION="Allow the creation of a paginated article with an optional table of contents.

    Insert page breaks through the use of the page break button normally found in the WYSIWYG editor toolbar. The location of the page break in an article will be displayed in the editor as a simple horizontal line.

    The text displayed will depend on the options chosen and may be either the title, alternate text (if provided) or page numbers.

    The HTML usage is:
    <hr class="system-pagebreak" />
    <hr class="system-pagebreak" title="The page title" /> or
    <hr class="system-pagebreak" alt="The first page" /> or
    <hr class="system-pagebreak" title="The page title" alt="The first page" /> or
    <hr class="system-pagebreak" alt="The first page" title="The page title" />" diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_content_pagenavigation.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_content_pagenavigation.ini new file mode 100644 index 00000000..613c99ff --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_content_pagenavigation.ini @@ -0,0 +1,19 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_CONTENT_PAGENAVIGATION="Content - Page Navigation" +PLG_PAGENAVIGATION_FIELD_DISPLAY_DESC="Choose what to display as the link text." +PLG_PAGENAVIGATION_FIELD_DISPLAY_LABEL="Link Text" +PLG_PAGENAVIGATION_FIELD_POSITION_DESC="The position of the Page Navigation function on the viewed page in relation to the text." +PLG_PAGENAVIGATION_FIELD_POSITION_LABEL="Position" +PLG_PAGENAVIGATION_FIELD_RELATIVE_DESC="Assigns the relative location for the Position parameter. Text will place it directly above or below the article content. Full Article will place it above or below the full display including title and readmore." +PLG_PAGENAVIGATION_FIELD_RELATIVE_LABEL="Relative To" +PLG_PAGENAVIGATION_FIELD_VALUE_ABOVE="Above" +PLG_PAGENAVIGATION_FIELD_VALUE_ARTICLE="Full Article" +PLG_PAGENAVIGATION_FIELD_VALUE_BELOW="Below" +PLG_PAGENAVIGATION_FIELD_VALUE_NEXTPREV="Next/Previous (static text)" +PLG_PAGENAVIGATION_FIELD_VALUE_TEXT="Text" +PLG_PAGENAVIGATION_FIELD_VALUE_TITLE="Title of the Article" +PLG_PAGENAVIGATION_XML_DESCRIPTION="Enables you to add Next & Previous functionality to an Article." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_content_pagenavigation.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_content_pagenavigation.sys.ini new file mode 100644 index 00000000..588c9c99 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_content_pagenavigation.sys.ini @@ -0,0 +1,9 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_CONTENT_PAGENAVIGATION="Content - Page Navigation" +PLG_PAGENAVIGATION_XML_DESCRIPTION="Enables you to add Next & Previous functionality to an Article." + + diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_content_vote.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_content_vote.ini new file mode 100644 index 00000000..d6a0c85f --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_content_vote.ini @@ -0,0 +1,17 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_CONTENT_VOTE="Content - Vote" +PLG_VOTE_BOTTOM="Bottom" +PLG_VOTE_LABEL="Please Rate" +PLG_VOTE_POSITION_DESC="Set where the voting is displayed." +PLG_VOTE_POSITION_LABEL="Position" +PLG_VOTE_RATE="Rate" +PLG_VOTE_STAR_ACTIVE="Star Active" +PLG_VOTE_STAR_INACTIVE="Star Inactive" +PLG_VOTE_TOP="Top" +PLG_VOTE_USER_RATING="User Rating: %1$s / %2$s" +PLG_VOTE_VOTE="Vote %s" +PLG_VOTE_XML_DESCRIPTION="Add Voting functionality to Articles." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_content_vote.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_content_vote.sys.ini new file mode 100644 index 00000000..3eb6f09d --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_content_vote.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_CONTENT_VOTE="Content - Vote" +PLG_VOTE_XML_DESCRIPTION="Add Voting functionality to Articles." \ No newline at end of file diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_editors-xtd_article.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_editors-xtd_article.ini new file mode 100644 index 00000000..4b61fb88 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_editors-xtd_article.ini @@ -0,0 +1,8 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_ARTICLE_BUTTON_ARTICLE="Article" +PLG_ARTICLE_XML_DESCRIPTION="Displays a button to insert links to articles into an Article. Displays a popup allowing you to choose the article." +PLG_EDITORS-XTD_ARTICLE="Button - Article" diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_editors-xtd_article.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_editors-xtd_article.sys.ini new file mode 100644 index 00000000..cea88bb2 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_editors-xtd_article.sys.ini @@ -0,0 +1,9 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_ARTICLE_XML_DESCRIPTION="Displays a button to insert links to articles into an Article. Displays a popup allowing you to choose the article." +PLG_EDITORS-XTD_ARTICLE="Button - Article" + + diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_editors-xtd_contact.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_editors-xtd_contact.ini new file mode 100644 index 00000000..aaaeb6a2 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_editors-xtd_contact.ini @@ -0,0 +1,8 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_EDITORS-XTD_CONTACT="Button - Contact" +PLG_EDITORS-XTD_CONTACT_BUTTON_CONTACT="Contact" +PLG_EDITORS-XTD_CONTACT_XML_DESCRIPTION="Displays a button to insert links to Contacts in an article. Displays a popup allowing you to choose the contact." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_editors-xtd_contact.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_editors-xtd_contact.sys.ini new file mode 100644 index 00000000..47930cfd --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_editors-xtd_contact.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_EDITORS-XTD_CONTACT="Button - Contact" +PLG_EDITORS-XTD_CONTACT_XML_DESCRIPTION="Displays a button to insert links to Contacts in an article. Displays a popup allowing you to choose the contact." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_editors-xtd_fields.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_editors-xtd_fields.ini new file mode 100644 index 00000000..1a09623e --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_editors-xtd_fields.ini @@ -0,0 +1,8 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_EDITORS-XTD_FIELDS="Button - Field" +PLG_EDITORS-XTD_FIELDS_BUTTON_FIELD="Field" +PLG_EDITORS-XTD_FIELDS_XML_DESCRIPTION="Displays a button to insert a custom field into an editor area. Displays a popup allowing you to choose the field.
    Warning!: the custom field will not be rendered if the Content - Fields plugin is not enabled." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_editors-xtd_fields.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_editors-xtd_fields.sys.ini new file mode 100644 index 00000000..df1dfcfa --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_editors-xtd_fields.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_EDITORS-XTD_FIELDS="Button - Field" +PLG_EDITORS-XTD_FIELDS_XML_DESCRIPTION="Displays a button to insert a custom field into an editor area. Displays a popup allowing you to choose the field.
    Warning!: the custom field will not be rendered if the Content - Fields plugin is not enabled." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_editors-xtd_image.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_editors-xtd_image.ini new file mode 100644 index 00000000..c3bd88e0 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_editors-xtd_image.ini @@ -0,0 +1,9 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_EDITORS-XTD_IMAGE="Button - Image" +PLG_IMAGE_BUTTON_IMAGE="Image" +PLG_IMAGE_XML_DESCRIPTION="Displays a button to insert images into an Article. Displays a popup allowing you to configure an image's properties and upload new image files." + diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_editors-xtd_image.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_editors-xtd_image.sys.ini new file mode 100644 index 00000000..28be7bf7 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_editors-xtd_image.sys.ini @@ -0,0 +1,8 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_EDITORS-XTD_IMAGE="Button - Image" +PLG_IMAGE_XML_DESCRIPTION="Displays a button to insert images into an Article. Displays a popup allowing you to configure an image's properties and upload new image files." + diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_editors-xtd_menu.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_editors-xtd_menu.ini new file mode 100644 index 00000000..c6e7df28 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_editors-xtd_menu.ini @@ -0,0 +1,8 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_EDITORS-XTD_MENU="Button - Menu" +PLG_EDITORS-XTD_MENU_BUTTON_MENU="Menu" +PLG_EDITORS-XTD_MENU_XML_DESCRIPTION="Displays a button to insert menu item links into an Article. Displays a popup allowing you to choose the menu item." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_editors-xtd_menu.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_editors-xtd_menu.sys.ini new file mode 100644 index 00000000..92aee26d --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_editors-xtd_menu.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_EDITORS-XTD_MENU="Button - Menu" +PLG_EDITORS-XTD_MENU_XML_DESCRIPTION="Displays a button to insert menu item links into an Article. Displays a popup allowing you to choose the menu item." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_editors-xtd_module.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_editors-xtd_module.ini new file mode 100644 index 00000000..db7def68 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_editors-xtd_module.ini @@ -0,0 +1,8 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_EDITORS-XTD_MODULE="Button - Module" +PLG_MODULE_BUTTON_MODULE="Module" +PLG_MODULE_XML_DESCRIPTION="Displays a button to insert a module into an Article. Displays a popup allowing you to choose the module." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_editors-xtd_module.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_editors-xtd_module.sys.ini new file mode 100644 index 00000000..180494b3 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_editors-xtd_module.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_EDITORS-XTD_MODULE="Button - Module" +PLG_MODULE_XML_DESCRIPTION="Displays a button to insert a module into an Article. Displays a popup allowing you to choose the module." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_editors-xtd_pagebreak.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_editors-xtd_pagebreak.ini new file mode 100644 index 00000000..9c5d2f38 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_editors-xtd_pagebreak.ini @@ -0,0 +1,8 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_EDITORS-XTD_PAGEBREAK="Button - Page Break" +PLG_EDITORSXTD_PAGEBREAK_BUTTON_PAGEBREAK="Page Break" +PLG_EDITORSXTD_PAGEBREAK_XML_DESCRIPTION="Provides a button to enable a page break to be inserted into an Article. A popup allows you to configure the settings to be used." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_editors-xtd_pagebreak.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_editors-xtd_pagebreak.sys.ini new file mode 100644 index 00000000..eec553fb --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_editors-xtd_pagebreak.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_EDITORS-XTD_PAGEBREAK="Button - Page Break" +PLG_EDITORSXTD_PAGEBREAK_XML_DESCRIPTION="Provides a button to enable a page break to be inserted into an Article. A popup allows you to configure the settings to be used." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_editors-xtd_readmore.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_editors-xtd_readmore.ini new file mode 100644 index 00000000..6160003d --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_editors-xtd_readmore.ini @@ -0,0 +1,9 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_EDITORS-XTD_READMORE="Button - Readmore" +PLG_READMORE_ALREADY_EXISTS="There is already a Read more ... link that has been inserted. Only one link is permitted. Use {pagebreak} to split the page up further." +PLG_READMORE_BUTTON_READMORE="Read More" +PLG_READMORE_XML_DESCRIPTION="Enables a button which allows you to insert the Read more ... link into an Article." \ No newline at end of file diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_editors-xtd_readmore.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_editors-xtd_readmore.sys.ini new file mode 100644 index 00000000..e8861615 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_editors-xtd_readmore.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_EDITORS-XTD_READMORE="Button - Readmore" +PLG_READMORE_XML_DESCRIPTION="Enables a button which allows you to insert the Read more ... link into an Article." \ No newline at end of file diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_editors-xtd_weblink.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_editors-xtd_weblink.ini new file mode 100644 index 00000000..08435f23 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_editors-xtd_weblink.ini @@ -0,0 +1,8 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; Note : All ini files need to be saved as UTF-8 + +PLG_EDITORS-XTD_WEBLINK="Button - Web Link" +PLG_EDITORS-XTD_WEBLINK_BUTTON_WEBLINK="Web Link" +PLG_EDITORS-XTD_WEBLINK_XML_DESCRIPTION="Displays a button to make it possible to insert web links into an Article. Displays a popup allowing you to choose the web link." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_editors-xtd_weblink.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_editors-xtd_weblink.sys.ini new file mode 100644 index 00000000..760ccc32 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_editors-xtd_weblink.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; Note : All ini files need to be saved as UTF-8 + +PLG_EDITORS-XTD_WEBLINK="Button - Web Link" +PLG_EDITORS-XTD_WEBLINK_XML_DESCRIPTION="Displays a button to make it possible to insert web links into an Article. Displays a popup allowing you to choose the web link." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_editors_codemirror.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_editors_codemirror.ini new file mode 100644 index 00000000..9673ac60 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_editors_codemirror.ini @@ -0,0 +1,70 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_CODEMIRROR_FIELD_ACTIVELINE_COLOR_DESC="The colour to use for highlighting the active line. Will be displayed at 50% opacity." +PLG_CODEMIRROR_FIELD_ACTIVELINE_COLOR_LABEL="Active Line Colour" +PLG_CODEMIRROR_FIELD_ACTIVELINE_DESC="Adds a highlight to the line the cursor is on." +PLG_CODEMIRROR_FIELD_ACTIVELINE_LABEL="Highlight Active Line" +PLG_CODEMIRROR_FIELD_AUTOCLOSEBRACKET_DESC="Automatic bracket completion." +PLG_CODEMIRROR_FIELD_AUTOCLOSEBRACKET_LABEL="Bracket Completion" +PLG_CODEMIRROR_FIELD_AUTOCLOSETAGS_DESC="Automatic tag completion." +PLG_CODEMIRROR_FIELD_AUTOCLOSETAGS_LABEL="Tag Completion" +; The following two strings are deprecated and will be removed in J4 +PLG_CODEMIRROR_FIELD_AUTOFOCUS_DESC="Auto focus." +PLG_CODEMIRROR_FIELD_AUTOFOCUS_LABEL="Auto Focus" +PLG_CODEMIRROR_FIELD_CODEFOLDING_DESC="Allow blocks of code to be folded." +PLG_CODEMIRROR_FIELD_CODEFOLDING_LABEL="Code Folding" +PLG_CODEMIRROR_FIELD_FONT_FAMILY_DESC="The font to use in the editor. If not installed, will be loaded from https://www.google.com/fonts/." +PLG_CODEMIRROR_FIELD_FONT_FAMILY_LABEL="Font" +PLG_CODEMIRROR_FIELD_FONT_SIZE_DESC="The size of the font in the editor." +PLG_CODEMIRROR_FIELD_FONT_SIZE_LABEL="Font Size (px)" +PLG_CODEMIRROR_FIELD_FULLSCREEN_DESC="Select the function key to use to toggle fullscreen mode." +PLG_CODEMIRROR_FIELD_FULLSCREEN_LABEL="Toggle Fullscreen" +PLG_CODEMIRROR_FIELD_FULLSCREEN_MOD_DESC="Select any modifier keys to use with the fullscreen toggle key." +PLG_CODEMIRROR_FIELD_FULLSCREEN_MOD_LABEL="Use Modifiers" +PLG_CODEMIRROR_FIELD_HIGHLIGHT_MATCH_COLOR_DESC="The background colour to use for highlighting matching tags. Will be displayed at 50% opacity." +PLG_CODEMIRROR_FIELD_HIGHLIGHT_MATCH_COLOR_LABEL="Matching Tag Colour" +PLG_CODEMIRROR_FIELD_KEYMAP_DESC="Make CodeMirror work like other popular editors." +PLG_CODEMIRROR_FIELD_KEYMAP_EMACS="Emacs" +PLG_CODEMIRROR_FIELD_KEYMAP_LABEL="Key Map" +PLG_CODEMIRROR_FIELD_KEYMAP_SUBLIME="Sublime Text" +PLG_CODEMIRROR_FIELD_KEYMAP_VIM="Vim" +PLG_CODEMIRROR_FIELD_LINE_HEIGHT_DESC="The height of one line of text. This is in ems, meaning that 1.0 is equal to the font size and 2.0 is equal to 2x the font size." +PLG_CODEMIRROR_FIELD_LINE_HEIGHT_LABEL="Line Height (em)" +PLG_CODEMIRROR_FIELD_LINENUMBERS_DESC="Display line numbers." +PLG_CODEMIRROR_FIELD_LINENUMBERS_LABEL="Line Numbers" +PLG_CODEMIRROR_FIELD_LINEWRAPPING_DESC="Enable/Disable line wrapping." +PLG_CODEMIRROR_FIELD_LINEWRAPPING_LABEL="Line Wrapping" +PLG_CODEMIRROR_FIELD_MARKERGUTTER_DESC="Code Marker and Code Folding." +PLG_CODEMIRROR_FIELD_MARKERGUTTER_LABEL="Gutters" +PLG_CODEMIRROR_FIELD_MATCHBRACKETS_DESC="Highlight matching brackets." +PLG_CODEMIRROR_FIELD_MATCHBRACKETS_LABEL="Match Brackets" +PLG_CODEMIRROR_FIELD_MATCHTAGS_DESC="Highlight matching tags." +PLG_CODEMIRROR_FIELD_MATCHTAGS_LABEL="Match Tags" +PLG_CODEMIRROR_FIELD_PREVIEW_DESC="An example of what your CodeMirror editor fields will look like with the current settings (save to update)." +PLG_CODEMIRROR_FIELD_PREVIEW_LABEL="Preview" +PLG_CODEMIRROR_FIELD_SELECTIONMATCHES_DESC="Highlight instances of the selected word throughout the document." +PLG_CODEMIRROR_FIELD_SELECTIONMATCHES_LABEL="Highlight Selection Matches" +PLG_CODEMIRROR_FIELD_THEME_DESC="Sets the colours for the editor." +PLG_CODEMIRROR_FIELD_THEME_LABEL="Theme" +PLG_CODEMIRROR_FIELD_VALUE_FONT_FAMILY_DEFAULT="Browser Default" +PLG_CODEMIRROR_FIELD_VALUE_FULLSCREEN_MOD_ALT="Alt" +PLG_CODEMIRROR_FIELD_VALUE_FULLSCREEN_MOD_CMD="Command" +PLG_CODEMIRROR_FIELD_VALUE_FULLSCREEN_MOD_CTRL="Control" +PLG_CODEMIRROR_FIELD_VALUE_FULLSCREEN_MOD_SHIFT="Shift" +PLG_CODEMIRROR_FIELD_VALUE_SCROLLBARSTYLE_DEFAULT="Default" +PLG_CODEMIRROR_FIELD_VALUE_SCROLLBARSTYLE_DESC="Select the scrollbar style you'd like CodeMirror to use." +PLG_CODEMIRROR_FIELD_VALUE_SCROLLBARSTYLE_LABEL="Scrollbar Style" +PLG_CODEMIRROR_FIELD_VALUE_SCROLLBARSTYLE_OVERLAY="Overlay" +PLG_CODEMIRROR_FIELD_VALUE_SCROLLBARSTYLE_SIMPLE="Simple" +PLG_CODEMIRROR_FIELD_VALUE_THEME_DARK="Dark" +PLG_CODEMIRROR_FIELD_VALUE_THEME_LIGHT="Light" +PLG_CODEMIRROR_FIELD_VIM_KEYBINDING_DESC="Select this option to make CodeMirror work in Vim mode." +PLG_CODEMIRROR_FIELD_VIM_KEYBINDING_LABEL="Vim Keybinding" +PLG_CODEMIRROR_FIELDSET_APPEARANCE_OPTIONS_LABEL="Appearance Options" +PLG_CODEMIRROR_FIELDSET_TOOLBAR_OPTIONS_LABEL="Toolbar Options" +PLG_CODEMIRROR_TOGGLE_FULL_SCREEN="Press %1$s %2$s to toggle Full Screen editing." +PLG_CODEMIRROR_XML_DESCRIPTION="This plugin loads the CodeMirror editor." +PLG_EDITORS_CODEMIRROR="Editor - CodeMirror" diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_editors_codemirror.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_editors_codemirror.sys.ini new file mode 100644 index 00000000..d46708f8 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_editors_codemirror.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_CODEMIRROR_XML_DESCRIPTION="This plugin loads the CodeMirror editor." +PLG_EDITORS_CODEMIRROR="Editor - CodeMirror" diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_editors_none.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_editors_none.ini new file mode 100644 index 00000000..b99d3f1d --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_editors_none.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_EDITORS_NONE="Editor - None" +PLG_NONE_XML_DESCRIPTION="This loads a basic text entry field." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_editors_none.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_editors_none.sys.ini new file mode 100644 index 00000000..b99d3f1d --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_editors_none.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_EDITORS_NONE="Editor - None" +PLG_NONE_XML_DESCRIPTION="This loads a basic text entry field." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_editors_tinymce.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_editors_tinymce.ini new file mode 100644 index 00000000..d6fedf63 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_editors_tinymce.ini @@ -0,0 +1,160 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_EDITORS_TINYMCE="Editor - TinyMCE" +PLG_TINY_BUTTON_TOGGLE_EDITOR="Toggle editor" +PLG_TINY_CONFIG_TEXTFILTER_ACL_DESC="If on, the text filter from the Joomla Global Configuration for every user group is applied.
    If off, the filters as defined here are used for all user groups." +PLG_TINY_CONFIG_TEXTFILTER_ACL_LABEL="Use Joomla Text Filter" +PLG_TINY_ERR_CUSTOMCSSFILENOTPRESENT="The file name %s was entered in the TinyMCE Custom CSS field. This file could not be found in the default template folder. No styles are available." +PLG_TINY_ERR_EDITORCSSFILENOTPRESENT="Could not find the file 'editor.css' in the template or templates/system folder. No styles are available." +PLG_TINY_ERR_UNSUPPORTEDBROWSER="Drag and drop image upload is not available for your browser. Please consider using a fully HTML5 compatible browser." +PLG_TINY_FIELD_ADVIMAGE_DESC="Turn on/off a more advanced image dialog." +PLG_TINY_FIELD_ADVIMAGE_LABEL="Advanced Image" +PLG_TINY_FIELD_ADVLIST_DESC="Turn on/off to enable to set number formats and bullet types in ordered and unordered lists." +PLG_TINY_FIELD_ADVLIST_LABEL="Advanced List" +PLG_TINY_FIELD_ALIGN_DESC="Turn on/off to enable the alignment of the text." +PLG_TINY_FIELD_ALIGN_LABEL="Text Alignment" +PLG_TINY_FIELD_BLOCKQUOTE_DESC="Turn on/off blockquotes." +PLG_TINY_FIELD_BLOCKQUOTE_LABEL="Blockquote" +PLG_TINY_FIELD_CODESAMPLE_DESC="Turn on/off code highlighting" +PLG_TINY_FIELD_CODESAMPLE_LABEL="Code Sample" +PLG_TINY_FIELD_COLORS_DESC="Show or hide the Colours control buttons." +PLG_TINY_FIELD_COLORS_LABEL="Colours" +PLG_TINY_FIELD_CONTEXTMENU_DESC="Turn on/off Context Menu." +PLG_TINY_FIELD_CONTEXTMENU_LABEL="Context Menu" +PLG_TINY_FIELD_CSS_DESC="By default the Plugin looks for an editor.css file. If it can't find one in the default template CSS folder, it loads the editor.css file from the system template." +PLG_TINY_FIELD_CSS_LABEL="Template CSS Classes" +PLG_TINY_FIELD_CUSTOMBUTTON_DESC="Add custom button(s)." +PLG_TINY_FIELD_CUSTOMBUTTON_LABEL="Custom Button" +PLG_TINY_FIELD_CUSTOMPLUGIN_DESC="Add custom plugin(s)." +PLG_TINY_FIELD_CUSTOMPLUGIN_LABEL="Custom Plugin" +PLG_TINY_FIELD_CUSTOM_CSS_DESC="Optional CSS file that will override the standard editor.css file. Enter a file name to point to a file in the CSS folder of the default template (for example, templates/beez3/css/). Or enter a full URL path to the custom CSS file. If you enter a value in this field, this file will be used instead of the editor.css file." +PLG_TINY_FIELD_CUSTOM_CSS_LABEL="Custom CSS Classes" +PLG_TINY_FIELD_CUSTOM_PATH_DESC="The directory with the image files to be listed relative to the default image folder (set in Media > Options)." +PLG_TINY_FIELD_CUSTOM_PATH_LABEL="Images Directory" +PLG_TINY_FIELD_DATE_DESC="Show or hide the Insert Date button." +PLG_TINY_FIELD_DATE_LABEL="Insert Date" +PLG_TINY_FIELD_DIRECTION_DESC="Choose default text direction." +PLG_TINY_FIELD_DIRECTION_LABEL="Text Direction" +PLG_TINY_FIELD_DRAG_DROP_DESC="Enable drag and drop for uploading images" +PLG_TINY_FIELD_DRAG_DROP_LABEL="Images Drag and Drop" +PLG_TINY_FIELD_ELEMENTS_DESC="Allows the addition of specific valid elements to the existing rule set." +PLG_TINY_FIELD_ELEMENTS_LABEL="Extended Valid Elements" +PLG_TINY_FIELD_ENCODING_DESC="Controls how HTML entities are encoded. Recommended setting is 'raw'. 'named' = used named entity encoding (for example, '<'). 'numeric' = use numeric HTML encoding (for example, '%03c'). raw = Do not encode HTML entities. Note that searching content may not work properly if setting is not 'raw'." +PLG_TINY_FIELD_ENCODING_LABEL="Entity Encoding" +PLG_TINY_FIELD_FONTS_DESC="Show or hide the Font control selectors." +PLG_TINY_FIELD_FONTS_LABEL="Fonts" +PLG_TINY_FIELD_FULLSCREEN_DESC="Show or hide the Fullscreen button." +PLG_TINY_FIELD_FULLSCREEN_LABEL="Fullscreen" +PLG_TINY_FIELD_FUNCTIONALITY_DESC="Select level of functionality." +PLG_TINY_FIELD_FUNCTIONALITY_LABEL="Functionality" +PLG_TINY_FIELD_HR_DESC="Show or hide the Horizontal Rule button." +PLG_TINY_FIELD_HR_LABEL="Horizontal Rule" +PLG_TINY_FIELD_HTMLHEIGHT_DESC="Height of HTML editor. Only applies in Advanced and Extended mode." +PLG_TINY_FIELD_HTMLHEIGHT_LABEL="HTML Height" +PLG_TINY_FIELD_HTMLWIDTH_DESC="Width of HTML editor. Should normally be left empty to let it flow. Only applies in Advanced and Extended mode." +PLG_TINY_FIELD_HTMLWIDTH_LABEL="HTML Width" +PLG_TINY_FIELD_INLINEPOPUPS_DESC="All dialogs to open as floating div layers instead of popup windows. This option can be very useful to get around popup blockers." +PLG_TINY_FIELD_INLINEPOPUPS_LABEL="Inline Popups" +PLG_TINY_FIELD_LABEL_ADVANCEDPARAMS="Advanced" +PLG_TINY_FIELD_LANGCODE_DESC="Editor UI Language. The value will be used if Automatic language is not set." +PLG_TINY_FIELD_LANGCODE_LABEL="Language Code" +PLG_TINY_FIELD_LANGSELECT_DESC="If Yes, editor language will automatically match selected UI language. If the tiny language does not exist, the editor language will default to English." +PLG_TINY_FIELD_LANGSELECT_LABEL="Automatic Language Selection" +PLG_TINY_FIELD_LINK_DESC="Select to enable the Link icons." +PLG_TINY_FIELD_LINK_LABEL="Links" +PLG_TINY_FIELD_MEDIA_DESC="Show or hide the Media button." +PLG_TINY_FIELD_MEDIA_LABEL="Media" +PLG_TINY_FIELD_MOBILE_DESC="This mode puts any mobile devices into the simple functionality with enlarged buttons for easy access." +PLG_TINY_FIELD_MOBILE_LABEL="Mobile Mode" +PLG_TINY_FIELD_NAME_EXTENDED_LABEL="Extended Mode Options
    Below you can set the access level for each one of the fields individually.
    Please keep in mind that these options will only have an effect in Extended mode." +PLG_TINY_FIELD_NEWLINES_DESC="New lines will be created using the selected option." +PLG_TINY_FIELD_NEWLINES_LABEL="New Lines" +PLG_TINY_FIELD_NONBREAKING_DESC="Insert non-breaking space entities." +PLG_TINY_FIELD_NONBREAKING_LABEL="Non-breaking" +PLG_TINY_FIELD_NUMBER_OF_SETS_LABEL="Number of Sets" +PLG_TINY_FIELD_NUMBER_OF_SETS_DESC="Number of sets that can be created. Minimum 3" +PLG_TINY_FIELD_PASTE_DESC="Show or hide the Paste button." +PLG_TINY_FIELD_PASTE_LABEL="Paste" +PLG_TINY_FIELD_PATH_DESC="If set to ON, it displays the set classes for the marked text." +PLG_TINY_FIELD_PATH_LABEL="Element Path" +PLG_TINY_FIELD_PRINT_DESC="Turn on/off the print and print preview icons in the editor." +PLG_TINY_FIELD_PRINT_LABEL="Print/Preview" +PLG_TINY_FIELD_PROHIBITED_DESC="Elements that will be cleaned from the text. Do not leave empty - if you do not want to prohibit anything enter dummy text eg cms." +PLG_TINY_FIELD_PROHIBITED_LABEL="Prohibited Elements" +PLG_TINY_FIELD_RESIZE_HORIZONTAL_DESC="Enable/disable the horizontal resizing." +PLG_TINY_FIELD_RESIZE_HORIZONTAL_LABEL="Horizontal Resizing" +PLG_TINY_FIELD_RESIZING_DESC="Enable/disable the resizing of the editor area (vertically and also horizontally if 'Horizontal Resizing' is enabled)." +PLG_TINY_FIELD_RESIZING_LABEL="Resizing" +PLG_TINY_FIELD_RTL_DESC="Show or hide the RTL button." +PLG_TINY_FIELD_RTL_LABEL="Directionality" +; The two following strings are deprecated +PLG_TINY_FIELD_SAVEWARNING_DESC="Gives warning if you cancel without saving changes." +PLG_TINY_FIELD_SAVEWARNING_LABEL="Save Warning" +PLG_TINY_FIELD_SEARCH-REPLACE_DESC="Show or hide the Search & Replace button." +PLG_TINY_FIELD_SEARCH-REPLACE_LABEL="Search & Replace" +PLG_TINY_FIELD_SETACCESS_DESC="Restrict users that will use this set to those in the selected user groups.
    If a user belongs to multiple groups, the set used will be the one which is assigned to a group higher in the hierarchy.
    Example: if a set is assigned to Author and another set to Publishers, if the user belongs to both groups, the set assigned to Publishers will be used." +PLG_TINY_FIELD_SETACCESS_LABEL="Assign this Set to" +PLG_TINY_FIELD_SKIN_ADMIN_DESC="Select skin for the Administrator Backend interface." +PLG_TINY_FIELD_SKIN_ADMIN_LABEL="Administrator Skin" +PLG_TINY_FIELD_SKIN_DESC="Select skin for the Frontend interface." +PLG_TINY_FIELD_SKIN_INFO_DESC="Copy your new skins to: /media/editors/tinymce/skins." +PLG_TINY_FIELD_SKIN_INFO_LABEL="For customised skins go to: Skin Creator" +PLG_TINY_FIELD_SKIN_LABEL="Site Skin" +PLG_TINY_FIELD_SMILIES_DESC="Show or hide the Smilies buttons." +PLG_TINY_FIELD_SMILIES_LABEL="Smilies" +PLG_TINY_FIELD_TABLE_DESC="Show or hide the Table control buttons." +PLG_TINY_FIELD_TABLE_LABEL="Table" +PLG_TINY_FIELD_TEMPLATE_DESC="Show or hide the Insert predefined template content button." +PLG_TINY_FIELD_TEMPLATE_LABEL="Template" +PLG_TINY_FIELD_URLS_DESC="URL behaviour." +PLG_TINY_FIELD_URLS_LABEL="URLs" +PLG_TINY_FIELD_VALIDELEMENTS_DESC="Defines which elements will stay in the edited text when the editor saves (the default rule set for this option is a mixture of the full HTML5 and HTML4 specification)." +PLG_TINY_FIELD_VALIDELEMENTS_LABEL="Valid Elements" +PLG_TINY_FIELD_VALUE_ABSOLUTE="Absolute" +PLG_TINY_FIELD_VALUE_ADVANCED="Advanced" +PLG_TINY_FIELD_VALUE_ALWAYS="Always" +PLG_TINY_FIELD_VALUE_BOTTOM="Bottom" +PLG_TINY_FIELD_VALUE_BR="BR Elements" +PLG_TINY_FIELD_VALUE_CENTER="Center" +PLG_TINY_FIELD_VALUE_DEFAULT="Default" +PLG_TINY_FIELD_VALUE_EXTENDED="Extended" +PLG_TINY_FIELD_VALUE_FRONT="Front Only" +PLG_TINY_FIELD_VALUE_LEFT="Left" +PLG_TINY_FIELD_VALUE_LTR="Left to Right" +PLG_TINY_FIELD_VALUE_NAMED="named" +PLG_TINY_FIELD_VALUE_NEVER="Never" +PLG_TINY_FIELD_VALUE_NUMERIC="numeric" +PLG_TINY_FIELD_VALUE_P="P Elements" +PLG_TINY_FIELD_VALUE_RAW="raw" +PLG_TINY_FIELD_VALUE_RELATIVE="Relative" +PLG_TINY_FIELD_VALUE_RIGHT="Right" +PLG_TINY_FIELD_VALUE_RTL="Right to Left" +PLG_TINY_FIELD_VALUE_SIMPLE="Simple" +PLG_TINY_FIELD_VALUE_TOP="Top" +PLG_TINY_FIELD_VISUALBLOCKS_DESC="See the outline of HTML block elements." +PLG_TINY_FIELD_VISUALBLOCKS_LABEL="Visualblocks" +PLG_TINY_FIELD_VISUALCHARS_DESC="See invisible characters, specifically non-breaking spaces." +PLG_TINY_FIELD_VISUALCHARS_LABEL="Visualchars" +PLG_TINY_FIELD_WORDCOUNT_DESC="Turn on/off word count." +PLG_TINY_FIELD_WORDCOUNT_LABEL="Word Count" +PLG_TINY_LEGACY_WARNING="The TinyMCE Editor Plugin has been updated. Currently it uses your existing configuration. By editing the plugin, you can now assign and customise various layouts to specific user groups.
    Warning: when editing the plugin, you will lose all your previous settings!" +PLG_TINY_SET_TARGET_PANEL_DESCRIPTION="Existing sets of the TinyMCE panel, and options for each set.
    In each set you can add or remove from the available menus and buttons." +PLG_TINY_SET_TITLE="Set %s" +PLG_TINY_SET_PRESET_BUTTON_ADVANCED="Use advanced preset" +PLG_TINY_SET_PRESET_BUTTON_MEDIUM="Use medium preset" +PLG_TINY_SET_PRESET_BUTTON_SIMPLE="Use simple preset" +PLG_TINY_SET_SOURCE_PANEL_DESCRIPTION="All available menus and buttons.
    Use them (drag and drop) to edit or build your custom TinyMCE panel." +PLG_TINY_TEMPLATE_LAYOUT1_DESC="HTML layout." +PLG_TINY_TEMPLATE_LAYOUT1_TITLE="Layout" +PLG_TINY_TEMPLATE_SNIPPET1_DESC="Simple HTML snippet." +PLG_TINY_TEMPLATE_SNIPPET1_TITLE="Simple Snippet" +; TinyMCE toolbar buttons +PLG_TINY_TOOLBAR_BUTTON_FONTSELECT="Font Select" +PLG_TINY_TOOLBAR_BUTTON_FONTSIZESELECT="Font Size Select" +PLG_TINY_TOOLBAR_BUTTON_FORMATSELECT="Format Select" +PLG_TINY_TOOLBAR_BUTTON_STYLESELECT="Style Select" +PLG_TINY_TOOLBAR_BUTTON_SEPARATOR="Separator" +PLG_TINY_XML_DESCRIPTION="TinyMCE is a platform independent web based JavaScript HTML WYSIWYG Editor." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_editors_tinymce.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_editors_tinymce.sys.ini new file mode 100644 index 00000000..dc2d5907 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_editors_tinymce.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_EDITORS_TINYMCE="Editor - TinyMCE" +PLG_TINY_XML_DESCRIPTION="TinyMCE is a platform independent web based JavaScript HTML WYSIWYG Editor." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_extension_joomla.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_extension_joomla.ini new file mode 100644 index 00000000..9d7e0e8a --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_extension_joomla.ini @@ -0,0 +1,8 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_EXTENSION_JOOMLA="Extension - Joomla" +PLG_EXTENSION_JOOMLA_XML_DESCRIPTION="Manage the update sites for extensions." +PLG_EXTENSION_JOOMLA_UNKNOWN_SITE="Unknown Site" diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_extension_joomla.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_extension_joomla.sys.ini new file mode 100644 index 00000000..79f6eb32 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_extension_joomla.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_EXTENSION_JOOMLA="Extension - Joomla" +PLG_EXTENSION_JOOMLA_XML_DESCRIPTION="Manage the update sites for extensions." \ No newline at end of file diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_calendar.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_calendar.ini new file mode 100644 index 00000000..fbefb2ac --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_calendar.ini @@ -0,0 +1,12 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_FIELDS_CALENDAR="Fields - Calendar" +PLG_FIELDS_CALENDAR_DEFAULT_VALUE_LABEL="Default Date" +PLG_FIELDS_CALENDAR_DEFAULT_VALUE_DESC="This is the default date. The value can be an ISO 8601 format (YYYY-MM-DD HH:MM:SS) or NOW, which displays the actual date." +PLG_FIELDS_CALENDAR_LABEL="Calendar (%s)" +PLG_FIELDS_CALENDAR_PARAMS_SHOWTIME_DESC="If enabled, the calendar field expects a date and time and will also display the time. The formats are localised using the regular language strings." +PLG_FIELDS_CALENDAR_PARAMS_SHOWTIME_LABEL="Show Time" +PLG_FIELDS_CALENDAR_XML_DESCRIPTION="This plugin lets you create new fields of type 'calendar' in any extensions where custom fields are supported." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_calendar.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_calendar.sys.ini new file mode 100644 index 00000000..339db71b --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_calendar.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_FIELDS_CALENDAR="Fields - Calendar" +PLG_FIELDS_CALENDAR_XML_DESCRIPTION="This plugin lets you create new fields of type 'calendar' in any extensions where custom fields are supported." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_checkboxes.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_checkboxes.ini new file mode 100644 index 00000000..f0bc6b5e --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_checkboxes.ini @@ -0,0 +1,12 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_FIELDS_CHECKBOXES="Fields - Checkboxes" +PLG_FIELDS_CHECKBOXES_LABEL="Checkboxes (%s)" +PLG_FIELDS_CHECKBOXES_PARAMS_OPTIONS_DESC="The values of the checkboxes." +PLG_FIELDS_CHECKBOXES_PARAMS_OPTIONS_LABEL="Checkbox Values" +PLG_FIELDS_CHECKBOXES_PARAMS_OPTIONS_VALUE_LABEL="Value" +PLG_FIELDS_CHECKBOXES_PARAMS_OPTIONS_NAME_LABEL="Text" +PLG_FIELDS_CHECKBOXES_XML_DESCRIPTION="This plugin lets you create new fields of type 'checkboxes' in any extensions where custom fields are supported." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_checkboxes.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_checkboxes.sys.ini new file mode 100644 index 00000000..6482c3d3 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_checkboxes.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_FIELDS_CHECKBOXES="Fields - Checkboxes" +PLG_FIELDS_CHECKBOXES_XML_DESCRIPTION="This plugin lets you create new fields of type 'checkboxes' in any extensions where custom fields are supported." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_color.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_color.ini new file mode 100644 index 00000000..4faee1fc --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_color.ini @@ -0,0 +1,8 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_FIELDS_COLOR="Fields - Colour" +PLG_FIELDS_COLOR_LABEL="Colour (%s)" +PLG_FIELDS_COLOR_XML_DESCRIPTION="This plugin lets you create new fields of type 'color' in any extensions where custom fields are supported." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_color.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_color.sys.ini new file mode 100644 index 00000000..0a671d7b --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_color.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_FIELDS_COLOR="Fields - Colour" +PLG_FIELDS_COLOR_XML_DESCRIPTION="This plugin lets you create new fields of type 'color' in any extensions where custom fields are supported." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_editor.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_editor.ini new file mode 100644 index 00000000..5dc95f04 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_editor.ini @@ -0,0 +1,17 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_FIELDS_EDITOR="Fields - Editor" +PLG_FIELDS_EDITOR_LABEL="Editor (%s)" +PLG_FIELDS_EDITOR_PARAMS_BUTTONS_HIDE_LABEL="Hide Buttons" +PLG_FIELDS_EDITOR_PARAMS_FILTER_DESC="Allow the system to save certain html tags or raw data." +PLG_FIELDS_EDITOR_PARAMS_FILTER_LABEL="Filter" +PLG_FIELDS_EDITOR_PARAMS_HEIGHT_DESC="Defines the height (in pixels) of the WYSIWYG editor and defaults to 250px." +PLG_FIELDS_EDITOR_PARAMS_HEIGHT_LABEL="Height" +PLG_FIELDS_EDITOR_PARAMS_SHOW_BUTTONS_DESC="Should the editors-xtd plugin buttons be shown?" +PLG_FIELDS_EDITOR_PARAMS_SHOW_BUTTONS_LABEL="Show Buttons" +PLG_FIELDS_EDITOR_PARAMS_WIDTH_DESC="Defines the width (in pixels) of the WYSIWYG editor and defaults to 100%." +PLG_FIELDS_EDITOR_PARAMS_WIDTH_LABEL="Width" +PLG_FIELDS_EDITOR_XML_DESCRIPTION="This plugin lets you create new fields of type 'editor' in any extensions where custom fields are supported." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_editor.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_editor.sys.ini new file mode 100644 index 00000000..65c07dc1 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_editor.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_FIELDS_EDITOR="Fields - Editor" +PLG_FIELDS_EDITOR_XML_DESCRIPTION="This plugin lets you create new fields of type 'editor' in any extensions where custom fields are supported." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_image.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_image.ini new file mode 100644 index 00000000..a8cdc0c5 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_image.ini @@ -0,0 +1,8 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_FIELDS_IMAGE="Fields - Image" +PLG_FIELDS_IMAGE_LABEL="Image (%s)" +PLG_FIELDS_IMAGE_XML_DESCRIPTION="This plugin lets you create new fields of type 'image' in any extensions where custom fields are supported." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_image.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_image.sys.ini new file mode 100644 index 00000000..e8c6d025 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_image.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_FIELDS_IMAGE="Fields - Image" +PLG_FIELDS_IMAGE_XML_DESCRIPTION="This plugin lets you create new fields of type 'image' in any extensions where custom fields are supported." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_imagelist.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_imagelist.ini new file mode 100644 index 00000000..aefa04e9 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_imagelist.ini @@ -0,0 +1,15 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_FIELDS_IMAGELIST="Fields - Imagelist" +PLG_FIELDS_IMAGELIST_LABEL="List of Images (%s)" +; Don't translate "images" in the string below. +PLG_FIELDS_IMAGELIST_PARAMS_DIRECTORY_DESC="The directory with the image files to be listed, relative to \"images\" directory in Joomla! root." +PLG_FIELDS_IMAGELIST_PARAMS_DIRECTORY_LABEL="Directory" +PLG_FIELDS_IMAGELIST_PARAMS_IMAGE_CLASS_DESC="The class which is added to the image (src tag)." +PLG_FIELDS_IMAGELIST_PARAMS_IMAGE_CLASS_LABEL="Image Class" +PLG_FIELDS_IMAGELIST_PARAMS_MULTIPLE_DESC="Allow multiple values to be selected." +PLG_FIELDS_IMAGELIST_PARAMS_MULTIPLE_LABEL="Multiple" +PLG_FIELDS_IMAGELIST_XML_DESCRIPTION="This plugin lets you create new fields of type 'imagelist' in any extensions where custom fields are supported." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_imagelist.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_imagelist.sys.ini new file mode 100644 index 00000000..b81509de --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_imagelist.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_FIELDS_IMAGELIST="Fields - Imagelist" +PLG_FIELDS_IMAGELIST_XML_DESCRIPTION="This plugin lets you create new fields of type 'imagelist' in any extensions where custom fields are supported." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_integer.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_integer.ini new file mode 100644 index 00000000..a4c4eaf6 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_integer.ini @@ -0,0 +1,16 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_FIELDS_INTEGER="Fields - Integer" +PLG_FIELDS_INTEGER_LABEL="Integer (%s)" +PLG_FIELDS_INTEGER_PARAMS_FIRST_DESC="This value is the lowest on the list." +PLG_FIELDS_INTEGER_PARAMS_FIRST_LABEL="First" +PLG_FIELDS_INTEGER_PARAMS_LAST_DESC="This value is the highest on the list." +PLG_FIELDS_INTEGER_PARAMS_LAST_LABEL="Last" +PLG_FIELDS_INTEGER_PARAMS_MULTIPLE_DESC="Allow multiple values to be selected." +PLG_FIELDS_INTEGER_PARAMS_MULTIPLE_LABEL="Multiple" +PLG_FIELDS_INTEGER_PARAMS_STEP_DESC="Each option will be the previous option incremented by this integer, starting with the first value until the last value is reached." +PLG_FIELDS_INTEGER_PARAMS_STEP_LABEL="Step" +PLG_FIELDS_INTEGER_XML_DESCRIPTION="This plugin lets you create new fields of type 'integer' in any extensions where custom fields are supported." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_integer.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_integer.sys.ini new file mode 100644 index 00000000..37d314d2 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_integer.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_FIELDS_INTEGER="Fields - Integer" +PLG_FIELDS_INTEGER_XML_DESCRIPTION="This plugin lets you create new fields of type 'integer' in any extensions where custom fields are supported." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_list.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_list.ini new file mode 100644 index 00000000..07c3a9da --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_list.ini @@ -0,0 +1,14 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_FIELDS_LIST="Fields - List" +PLG_FIELDS_LIST_LABEL="List (%s)" +PLG_FIELDS_LIST_PARAMS_MULTIPLE_DESC="Allow multiple values to be selected." +PLG_FIELDS_LIST_PARAMS_MULTIPLE_LABEL="Multiple" +PLG_FIELDS_LIST_PARAMS_OPTIONS_DESC="The values of the list." +PLG_FIELDS_LIST_PARAMS_OPTIONS_LABEL="List Values" +PLG_FIELDS_LIST_PARAMS_OPTIONS_VALUE_LABEL="Value" +PLG_FIELDS_LIST_PARAMS_OPTIONS_NAME_LABEL="Text" +PLG_FIELDS_LIST_XML_DESCRIPTION="This plugin lets you create new fields of type 'list' in any extensions where custom fields are supported." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_list.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_list.sys.ini new file mode 100644 index 00000000..c3ea85a7 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_list.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_FIELDS_LIST="Fields - List" +PLG_FIELDS_LIST_XML_DESCRIPTION="This plugin lets you create new fields of type 'list' in any extensions where custom fields are supported." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_media.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_media.ini new file mode 100644 index 00000000..caa90249 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_media.ini @@ -0,0 +1,16 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_FIELDS_MEDIA="Fields - Media" +PLG_FIELDS_MEDIA_LABEL="Media (%s)" +PLG_FIELDS_MEDIA_PARAMS_DIRECTORY_DESC="The directory with the image files to be listed relative to the default image folder (set in Media > Options)." +PLG_FIELDS_MEDIA_PARAMS_DIRECTORY_LABEL="Directory" +PLG_FIELDS_MEDIA_PARAMS_IMAGE_CLASS_DESC="The class which is added to the image (src tag)." +PLG_FIELDS_MEDIA_PARAMS_IMAGE_CLASS_LABEL="Image Class" +PLG_FIELDS_MEDIA_PARAMS_PREVIEW_DESC="Shows or hides the preview of the selected image." +PLG_FIELDS_MEDIA_PARAMS_PREVIEW_INLINE="Inline" +PLG_FIELDS_MEDIA_PARAMS_PREVIEW_LABEL="Preview" +PLG_FIELDS_MEDIA_PARAMS_PREVIEW_TOOLTIP="Tooltip" +PLG_FIELDS_MEDIA_XML_DESCRIPTION="This plugin lets you create new fields of type 'media' in any extensions where custom fields are supported." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_media.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_media.sys.ini new file mode 100644 index 00000000..46b95f8b --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_media.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_FIELDS_MEDIA="Fields - Media" +PLG_FIELDS_MEDIA_XML_DESCRIPTION="This plugin lets you create new fields of type 'media' in any extensions where custom fields are supported." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_radio.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_radio.ini new file mode 100644 index 00000000..26ff275b --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_radio.ini @@ -0,0 +1,12 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_FIELDS_RADIO="Fields - Radio" +PLG_FIELDS_RADIO_LABEL="Radio (%s)" +PLG_FIELDS_RADIO_PARAMS_OPTIONS_DESC="The values of the radio list." +PLG_FIELDS_RADIO_PARAMS_OPTIONS_NAME_LABEL="Text" +PLG_FIELDS_RADIO_PARAMS_OPTIONS_LABEL="Radio Values" +PLG_FIELDS_RADIO_PARAMS_OPTIONS_VALUE_LABEL="Value" +PLG_FIELDS_RADIO_XML_DESCRIPTION="This plugin lets you create new fields of type 'radio' in any extensions where custom fields are supported." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_radio.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_radio.sys.ini new file mode 100644 index 00000000..d9aa096a --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_radio.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_FIELDS_RADIO="Fields - Radio" +PLG_FIELDS_RADIO_XML_DESCRIPTION="This plugin lets you create new fields of type 'radio' in any extensions where custom fields are supported." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_repeatable.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_repeatable.ini new file mode 100644 index 00000000..8afc827a --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_repeatable.ini @@ -0,0 +1,19 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_FIELDS_REPEATABLE="Fields - Repeatable" +PLG_FIELDS_REPEATABLE_LABEL="Repeatable (%s)" +PLG_FIELDS_REPEATABLE_PARAMS_FIELDNAME_NAME_DESC="The name of the field to display in the form" +PLG_FIELDS_REPEATABLE_PARAMS_FIELDNAME_NAME_LABEL="Name" +PLG_FIELDS_REPEATABLE_PARAMS_FIELDNAME_TYPE_DESC="Set the field type" +PLG_FIELDS_REPEATABLE_PARAMS_FIELDNAME_TYPE_EDITOR="Editor" +PLG_FIELDS_REPEATABLE_PARAMS_FIELDNAME_TYPE_LABEL="Type" +PLG_FIELDS_REPEATABLE_PARAMS_FIELDNAME_TYPE_MEDIA="Media" +PLG_FIELDS_REPEATABLE_PARAMS_FIELDNAME_TYPE_NUMBER="Number" +PLG_FIELDS_REPEATABLE_PARAMS_FIELDNAME_TYPE_TEXT="Text" +PLG_FIELDS_REPEATABLE_PARAMS_FIELDNAME_TYPE_TEXTAREA="Text Area" +PLG_FIELDS_REPEATABLE_PARAMS_FIELDS_DESC="Add one or more form fields" +PLG_FIELDS_REPEATABLE_PARAMS_FIELDS_LABEL="Form Fields" +PLG_FIELDS_REPEATABLE_XML_DESCRIPTION="Plugin to create a repeatable form with customizable fields." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_repeatable.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_repeatable.sys.ini new file mode 100644 index 00000000..be9755e3 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_repeatable.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_FIELDS_REPEATABLE="Fields - Repeatable" +PLG_FIELDS_REPEATABLE_XML_DESCRIPTION="Plugin to create a repeatable form with customizable fields." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_sql.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_sql.ini new file mode 100644 index 00000000..2fcf74af --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_sql.ini @@ -0,0 +1,16 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_FIELDS_SQL="Fields - SQL" +PLG_FIELDS_SQL_CREATE_NOT_POSSIBLE="Only a Super User can create or edit an SQL field!" +PLG_FIELDS_SQL_LABEL="SQL (%s)" +PLG_FIELDS_SQL_PARAMS_MULTIPLE_DESC="Allow multiple values to be selected." +PLG_FIELDS_SQL_PARAMS_MULTIPLE_LABEL="Multiple" +; In the string below the terms 'value' and 'text' should not be translated +PLG_FIELDS_SQL_PARAMS_QUERY_DESC="The SQL query which will provide the data for the dropdown list. The query must return two columns; one called 'value' which will hold the values of the list items; the other called 'text' with the text in the dropdown list." +PLG_FIELDS_SQL_PARAMS_QUERY_LABEL="Query" +; This string is deprecated and will be removed with 4.0. +PLG_FIELDS_SQL_RULES_ADAPTED="For increased security the edit permission for this SQL field was set to denied for all non Super Users." +PLG_FIELDS_SQL_XML_DESCRIPTION="This plugin lets you create new fields of type 'sql' in any extensions where custom fields are supported." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_sql.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_sql.sys.ini new file mode 100644 index 00000000..54e6d1ad --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_sql.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_FIELDS_SQL="Fields - SQL" +PLG_FIELDS_SQL_XML_DESCRIPTION="This plugin lets you create new fields of type 'sql' in any extensions where custom fields are supported." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_text.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_text.ini new file mode 100644 index 00000000..d3b13185 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_text.ini @@ -0,0 +1,12 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_FIELDS_TEXT="Fields - Text" +PLG_FIELDS_TEXT_LABEL="Text (%s)" +PLG_FIELDS_TEXT_PARAMS_FILTER_DESC="Allow the system to save certain html tags or raw data." +PLG_FIELDS_TEXT_PARAMS_FILTER_LABEL="Filter" +PLG_FIELDS_TEXT_PARAMS_MAXLENGTH_LABEL="Maximum Length" +PLG_FIELDS_TEXT_PARAMS_MAXLENGTH_DESC="The maximum number of characters that can be entered." +PLG_FIELDS_TEXT_XML_DESCRIPTION="This plugin lets you create new fields of type 'text' in any extensions where custom fields are supported." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_text.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_text.sys.ini new file mode 100644 index 00000000..33f32bba --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_text.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_FIELDS_TEXT="Fields - Text" +PLG_FIELDS_TEXT_XML_DESCRIPTION="This plugin lets you create new fields of type 'text' in any extensions where custom fields are supported." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_textarea.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_textarea.ini new file mode 100644 index 00000000..4b1ca34c --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_textarea.ini @@ -0,0 +1,16 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_FIELDS_TEXTAREA="Fields - Textarea" +PLG_FIELDS_TEXTAREA_LABEL="Text Area (%s)" +PLG_FIELDS_TEXTAREA_PARAMS_COLS_DESC="The width of the visible text area in characters. If omitted the width is determined by the browser. The value does not limit the number of characters that may be entered." +PLG_FIELDS_TEXTAREA_PARAMS_COLS_LABEL="Columns" +PLG_FIELDS_TEXTAREA_PARAMS_FILTER_DESC="Allow the system to save certain html tags or raw data." +PLG_FIELDS_TEXTAREA_PARAMS_FILTER_LABEL="Filter" +PLG_FIELDS_TEXTAREA_PARAMS_MAXLENGTH_LABEL="Maximum Length" +PLG_FIELDS_TEXTAREA_PARAMS_MAXLENGTH_DESC="The maximum number of characters that can be entered." +PLG_FIELDS_TEXTAREA_PARAMS_ROWS_DESC="The height of the visible text area in lines. If omitted the height is determined by the browser. The value does not limit the number of lines that may be entered." +PLG_FIELDS_TEXTAREA_PARAMS_ROWS_LABEL="Rows" +PLG_FIELDS_TEXTAREA_XML_DESCRIPTION="This plugin lets you create new fields of type 'textarea' in any extensions where custom fields are supported." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_textarea.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_textarea.sys.ini new file mode 100644 index 00000000..c7d3312f --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_textarea.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_FIELDS_TEXTAREA="Fields - Textarea" +PLG_FIELDS_TEXTAREA_XML_DESCRIPTION="This plugin lets you create new fields of type 'textarea' in any extensions where custom fields are supported." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_url.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_url.ini new file mode 100644 index 00000000..bb665886 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_url.ini @@ -0,0 +1,12 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_FIELDS_URL="Fields - URL" +PLG_FIELDS_URL_LABEL="URL (%s)" +PLG_FIELDS_URL_PARAMS_RELATIVE_DESC="Are relative URLs allowed." +PLG_FIELDS_URL_PARAMS_RELATIVE_LABEL="Relative" +PLG_FIELDS_URL_PARAMS_SCHEMES_DESC="The allowed schemes." +PLG_FIELDS_URL_PARAMS_SCHEMES_LABEL="Schemes" +PLG_FIELDS_URL_XML_DESCRIPTION="This plugin lets you create new fields of type 'URL' in any extensions where custom fields are supported." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_url.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_url.sys.ini new file mode 100644 index 00000000..506f8113 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_url.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_FIELDS_URL="Fields - URL" +PLG_FIELDS_URL_XML_DESCRIPTION="This plugin lets you create new fields of type 'URL' in any extensions where custom fields are supported." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_user.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_user.ini new file mode 100644 index 00000000..52a96112 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_user.ini @@ -0,0 +1,10 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_FIELDS_USER="Fields - User" +PLG_FIELDS_USER_DEFAULT_VALUE_DESC="The default user." +PLG_FIELDS_USER_DEFAULT_VALUE_LABEL="Default User" +PLG_FIELDS_USER_LABEL="User (%s)" +PLG_FIELDS_USER_XML_DESCRIPTION="This plugin lets you create new fields of type 'user' in any extensions where custom fields are supported." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_user.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_user.sys.ini new file mode 100644 index 00000000..155e02f8 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_user.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_FIELDS_USER="Fields - User" +PLG_FIELDS_USER_XML_DESCRIPTION="This plugin lets you create new fields of type 'user' in any extensions where custom fields are supported." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_usergrouplist.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_usergrouplist.ini new file mode 100644 index 00000000..289fe05d --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_usergrouplist.ini @@ -0,0 +1,12 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_FIELDS_USERGROUPLIST="Fields - Usergrouplist" +PLG_FIELDS_USERGROUPLIST_DEFAULT_VALUE_DESC="A comma separated list of user group ids." +PLG_FIELDS_USERGROUPLIST_DEFAULT_VALUE_LABEL="Default User Groups" +PLG_FIELDS_USERGROUPLIST_LABEL="User Groups (%s)" +PLG_FIELDS_USERGROUPLIST_PARAMS_MULTIPLE_DESC="Allow multiple values to be selected." +PLG_FIELDS_USERGROUPLIST_PARAMS_MULTIPLE_LABEL="Multiple" +PLG_FIELDS_USERGROUPLIST_XML_DESCRIPTION="This plugin lets you create new fields of type 'usergrouplist' in any extensions where custom fields are supported." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_usergrouplist.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_usergrouplist.sys.ini new file mode 100644 index 00000000..c2fe17fe --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_fields_usergrouplist.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_FIELDS_USERGROUPLIST="Fields - Usergrouplist" +PLG_FIELDS_USERGROUPLIST_XML_DESCRIPTION="This plugin lets you create new fields of type 'usergrouplist' in any extensions where custom fields are supported." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_finder_categories.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_finder_categories.ini new file mode 100644 index 00000000..da92ff28 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_finder_categories.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_FINDER_CATEGORIES="Smart Search - Categories" +PLG_FINDER_CATEGORIES_XML_DESCRIPTION="This plugin indexes Joomla! Categories." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_finder_categories.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_finder_categories.sys.ini new file mode 100644 index 00000000..0de3f2df --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_finder_categories.sys.ini @@ -0,0 +1,9 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_FINDER_CATEGORIES="Smart Search - Categories" +PLG_FINDER_CATEGORIES_ERROR_ACTIVATING_PLUGIN="Could not automatically activate the "Smart Search - Categories" plugin." +PLG_FINDER_CATEGORIES_XML_DESCRIPTION="This plugin indexes Joomla! Categories." +PLG_FINDER_STATISTICS_CATEGORY="Category" diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_finder_contacts.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_finder_contacts.ini new file mode 100644 index 00000000..8f2950ab --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_finder_contacts.ini @@ -0,0 +1,16 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_FINDER_CONTACTS="Smart Search - Contacts" +PLG_FINDER_CONTACTS_XML_DESCRIPTION="This plugin indexes Joomla! Contacts." + +PLG_FINDER_QUERY_FILTER_BRANCH_P_CONTACT="Contacts" +PLG_FINDER_QUERY_FILTER_BRANCH_P_COUNTRY="Countries" +PLG_FINDER_QUERY_FILTER_BRANCH_P_REGION="Regions" + +PLG_FINDER_QUERY_FILTER_BRANCH_S_CONTACT="Contact" +PLG_FINDER_QUERY_FILTER_BRANCH_S_COUNTRY="Country" +PLG_FINDER_QUERY_FILTER_BRANCH_S_REGION="Region" + diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_finder_contacts.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_finder_contacts.sys.ini new file mode 100644 index 00000000..c189ceb0 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_finder_contacts.sys.ini @@ -0,0 +1,9 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_FINDER_CONTACTS="Smart Search - Contacts" +PLG_FINDER_CONTACTS_ERROR_ACTIVATING_PLUGIN="Could not automatically activate the "Smart Search - Contacts" plugin." +PLG_FINDER_CONTACTS_XML_DESCRIPTION="This plugin indexes Joomla! Contacts." +PLG_FINDER_STATISTICS_CONTACT="Contact" diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_finder_content.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_finder_content.ini new file mode 100644 index 00000000..8ed83b5a --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_finder_content.ini @@ -0,0 +1,15 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_FINDER_CONTENT="Smart Search - Content" +PLG_FINDER_CONTENT_XML_DESCRIPTION="Updates the indexes of Joomla! Articles whenever an article is created, modified or deleted. NOTE the Content - Smart Search plugin must be enabled." + +PLG_FINDER_QUERY_FILTER_BRANCH_P_ARTICLE="Articles" +PLG_FINDER_QUERY_FILTER_BRANCH_P_AUTHOR="Authors" + +PLG_FINDER_QUERY_FILTER_BRANCH_S_ARTICLE="Article" +PLG_FINDER_QUERY_FILTER_BRANCH_S_AUTHOR="Author" + + diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_finder_content.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_finder_content.sys.ini new file mode 100644 index 00000000..29eda933 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_finder_content.sys.ini @@ -0,0 +1,9 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_FINDER_CONTENT="Smart Search - Content" +PLG_FINDER_CONTENT_ERROR_ACTIVATING_PLUGIN="Could not automatically activate the "Smart Search - Content" plugin." +PLG_FINDER_CONTENT_XML_DESCRIPTION="Updates the indexes of Joomla! Articles whenever an article is created, modified or deleted. NOTE the Content - Smart Search plugin must be enabled." +PLG_FINDER_STATISTICS_ARTICLE="Article" diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_finder_newsfeeds.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_finder_newsfeeds.ini new file mode 100644 index 00000000..e32a0f4a --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_finder_newsfeeds.ini @@ -0,0 +1,11 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_FINDER_NEWSFEEDS="Smart Search - News Feeds" +PLG_FINDER_NEWSFEEDS_XML_DESCRIPTION="This plugin indexes Joomla! News feeds." + +PLG_FINDER_QUERY_FILTER_BRANCH_P_NEWS_FEED="News feeds" +PLG_FINDER_QUERY_FILTER_BRANCH_S_NEWS_FEED="News feed" + diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_finder_newsfeeds.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_finder_newsfeeds.sys.ini new file mode 100644 index 00000000..9e07dd25 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_finder_newsfeeds.sys.ini @@ -0,0 +1,9 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_FINDER_NEWSFEEDS="Smart Search - News Feeds" +PLG_FINDER_NEWSFEEDS_ERROR_ACTIVATING_PLUGIN="Could not automatically activate the "Smart Search - Joomla! News Feeds" plugin." +PLG_FINDER_NEWSFEEDS_XML_DESCRIPTION="This plugin indexes Joomla! News feeds." +PLG_FINDER_STATISTICS_NEWS_FEED="News Feed" diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_finder_tags.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_finder_tags.ini new file mode 100644 index 00000000..940512da --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_finder_tags.ini @@ -0,0 +1,10 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + + +PLG_FINDER_QUERY_FILTER_BRANCH_P_TAG="Tags" +PLG_FINDER_QUERY_FILTER_BRANCH_S_TAG="Tag" +PLG_FINDER_TAGS="Smart Search - Tags" +PLG_FINDER_TAGS_XML_DESCRIPTION="This plugin indexes Joomla! Tags." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_finder_tags.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_finder_tags.sys.ini new file mode 100644 index 00000000..246b4991 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_finder_tags.sys.ini @@ -0,0 +1,9 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_FINDER_STATISTICS_TAG="Tag" +PLG_FINDER_TAGS="Smart Search - Tags" +PLG_FINDER_TAGS_ERROR_ACTIVATING_PLUGIN="Could not automatically activate the "Smart Search - Tags" plugin." +PLG_FINDER_TAGS_XML_DESCRIPTION="This plugin indexes Joomla! Tags." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_finder_weblinks.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_finder_weblinks.ini new file mode 100644 index 00000000..4b5fa9dc --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_finder_weblinks.ini @@ -0,0 +1,10 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_FINDER_WEBLINKS="Smart Search - Web Links" +PLG_FINDER_WEBLINKS_XML_DESCRIPTION="This plugin indexes Joomla! Web Links." + +PLG_FINDER_QUERY_FILTER_BRANCH_P_WEB_LINK="Web links" +PLG_FINDER_QUERY_FILTER_BRANCH_S_WEB_LINK="Web link" diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_finder_weblinks.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_finder_weblinks.sys.ini new file mode 100644 index 00000000..e3c74371 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_finder_weblinks.sys.ini @@ -0,0 +1,9 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_FINDER_STATISTICS_WEB_LINK="Web Link" +PLG_FINDER_WEBLINKS="Smart Search - Web Links" +PLG_FINDER_WEBLINKS_ERROR_ACTIVATING_PLUGIN="Could not automatically activate the "Smart Search - Web Links" plugin." +PLG_FINDER_WEBLINKS_XML_DESCRIPTION="This plugin indexes Joomla! Web Links." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_installer_folderinstaller.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_installer_folderinstaller.ini new file mode 100644 index 00000000..3cae090a --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_installer_folderinstaller.ini @@ -0,0 +1,9 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_INSTALLER_FOLDERINSTALLER_TEXT="Install from Folder" +PLG_INSTALLER_FOLDERINSTALLER_BUTTON="Check and Install" +PLG_INSTALLER_FOLDERINSTALLER_NO_INSTALL_PATH="Please enter a Folder." +PLG_INSTALLER_FOLDERINSTALLER_PLUGIN_XML_DESCRIPTION="This plugin allows you to install packages from a folder." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_installer_folderinstaller.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_installer_folderinstaller.sys.ini new file mode 100644 index 00000000..2e401a30 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_installer_folderinstaller.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_INSTALLER_FOLDERINSTALLER="Installer - Install from Folder" +PLG_INSTALLER_FOLDERINSTALLER_PLUGIN_XML_DESCRIPTION="This plugin allows you to install packages from a folder." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_installer_packageinstaller.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_installer_packageinstaller.ini new file mode 100644 index 00000000..1deb8da1 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_installer_packageinstaller.ini @@ -0,0 +1,17 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_INSTALLER_PACKAGEINSTALLER_DRAG_FILE_HERE="Drag and drop file here to upload." +PLG_INSTALLER_PACKAGEINSTALLER_EXTENSION_PACKAGE_FILE="Extension package file" +PLG_INSTALLER_PACKAGEINSTALLER_INSTALLING="Installing ..." +PLG_INSTALLER_PACKAGEINSTALLER_NO_PACKAGE="Please select a package to upload" +PLG_INSTALLER_PACKAGEINSTALLER_PLUGIN_XML_DESCRIPTION="This plugin allows you to install packages from your local computer." +PLG_INSTALLER_PACKAGEINSTALLER_SELECT_FILE="Or browse for file" +PLG_INSTALLER_PACKAGEINSTALLER_UPLOAD_AND_INSTALL="Upload & Install" +PLG_INSTALLER_PACKAGEINSTALLER_UPLOAD_ERROR_EMPTY="Error: Server returns empty response." +PLG_INSTALLER_PACKAGEINSTALLER_UPLOAD_ERROR_UNKNOWN="Error: Unknown error or invalid JSON output." +PLG_INSTALLER_PACKAGEINSTALLER_UPLOAD_INSTALL_JOOMLA_EXTENSION="Upload & Install Joomla Extension" +PLG_INSTALLER_PACKAGEINSTALLER_UPLOAD_PACKAGE_FILE="Upload Package File" +PLG_INSTALLER_PACKAGEINSTALLER_UPLOADING="Uploading ..." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_installer_packageinstaller.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_installer_packageinstaller.sys.ini new file mode 100644 index 00000000..2e7b89f6 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_installer_packageinstaller.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_INSTALLER_PACKAGEINSTALLER="Installer - Install from Upload" +PLG_INSTALLER_PACKAGEINSTALLER_PLUGIN_XML_DESCRIPTION="This plugin allows you to install packages from your local computer." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_installer_urlinstaller.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_installer_urlinstaller.ini new file mode 100644 index 00000000..40264f3d --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_installer_urlinstaller.ini @@ -0,0 +1,9 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_INSTALLER_URLINSTALLER_BUTTON="Check and Install" +PLG_INSTALLER_URLINSTALLER_INSTALLER_URLFOLDERINSTALLER="Installer - Install from URL." +PLG_INSTALLER_URLINSTALLER_PLUGIN_XML_DESCRIPTION="This plugin allows you to install packages from a URL." +PLG_INSTALLER_URLINSTALLER_TEXT="Install from URL" diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_installer_urlinstaller.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_installer_urlinstaller.sys.ini new file mode 100644 index 00000000..7af8a3d9 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_installer_urlinstaller.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_INSTALLER_URLINSTALLER_PLUGIN_XML_DESCRIPTION="This plugin allows you to install packages from a URL." +PLG_INSTALLER_URLINSTALLER="Installer - Install from URL" diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_installer_webinstaller.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_installer_webinstaller.ini new file mode 100644 index 00000000..1a862934 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_installer_webinstaller.ini @@ -0,0 +1,21 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_INSTALLER_WEBINSTALLER="Installer - Install from Web" +PLG_INSTALLER_WEBINSTALLER_CANNOT_INSTALL_EXTENSION_IN_PLUGIN="This extension cannot be installed using the install from web system. Please visit the developer's website to purchase/download." +PLG_INSTALLER_WEBINSTALLER_ERROR_PLUGIN_INCLUDED_IN_CORE="Plugin installation has been aborted. The Install from Web plugin is included in core as of Joomla! 4.0." +; This string is not used. +PLG_INSTALLER_WEBINSTALLER_LOAD_APPS="Display the extensions" +; The [SITEURL] placeholder should not be translated as it is used in the JavaScript API to insert the correct URL +PLG_INSTALLER_WEBINSTALLER_REDIRECT_TO_EXTERNAL_SITE_TO_INSTALL="You will be redirected to the following link to complete the registration/purchase: [SITEURL]" +; This string is deprecated and not used in version 2.0 of the plugin but is required for compatibility with 1.x releases due to the language files being bundled in the CMS package. +PLG_INSTALLER_WEBINSTALLER_TAB_POSITION_DESC="Place the Install from Web tab first or last." +; This string is deprecated and not used in version 2.0 of the plugin but is required for compatibility with 1.x releases due to the language files being bundled in the CMS package. +PLG_INSTALLER_WEBINSTALLER_TAB_POSITION_LABEL="Tab Position" +; This string is deprecated and not used in version 2.0 of the plugin but is required for compatibility with 1.x releases due to the language files being bundled in the CMS package. +PLG_INSTALLER_WEBINSTALLER_TAB_POSITION_FIRST="First" +; This string is deprecated and not used in version 2.0 of the plugin but is required for compatibility with 1.x releases due to the language files being bundled in the CMS package. +PLG_INSTALLER_WEBINSTALLER_TAB_POSITION_LAST="Last" +PLG_INSTALLER_WEBINSTALLER_XML_DESCRIPTION="This plugin offers functionality for the 'Install from Web' tab." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_installer_webinstaller.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_installer_webinstaller.sys.ini new file mode 100644 index 00000000..03471e1a --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_installer_webinstaller.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_INSTALLER_WEBINSTALLER="Installer - Install from Web" +PLG_INSTALLER_WEBINSTALLER_XML_DESCRIPTION="This plugin offers functionality for the 'Install from Web' tab." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_privacy_actionlogs.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_privacy_actionlogs.ini new file mode 100644 index 00000000..c80bc65d --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_privacy_actionlogs.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_PRIVACY_ACTIONLOGS="Privacy - Action Logs" +PLG_PRIVACY_ACTIONLOGS_XML_DESCRIPTION="Responsible for exporting the action log data for a user's privacy request." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_privacy_actionlogs.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_privacy_actionlogs.sys.ini new file mode 100644 index 00000000..c80bc65d --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_privacy_actionlogs.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_PRIVACY_ACTIONLOGS="Privacy - Action Logs" +PLG_PRIVACY_ACTIONLOGS_XML_DESCRIPTION="Responsible for exporting the action log data for a user's privacy request." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_privacy_consents.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_privacy_consents.ini new file mode 100644 index 00000000..28a85bac --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_privacy_consents.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_PRIVACY_CONSENTS="Privacy - Consents" +PLG_PRIVACY_CONSENTS_XML_DESCRIPTION="Responsible for processing privacy related requests for the core Joomla privacy consents data." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_privacy_consents.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_privacy_consents.sys.ini new file mode 100644 index 00000000..28a85bac --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_privacy_consents.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_PRIVACY_CONSENTS="Privacy - Consents" +PLG_PRIVACY_CONSENTS_XML_DESCRIPTION="Responsible for processing privacy related requests for the core Joomla privacy consents data." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_privacy_contact.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_privacy_contact.ini new file mode 100644 index 00000000..773bbb71 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_privacy_contact.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_PRIVACY_CONTACT="Privacy - Contacts" +PLG_PRIVACY_CONTACT_XML_DESCRIPTION="Responsible for processing privacy related requests for the core Joomla contact data." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_privacy_contact.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_privacy_contact.sys.ini new file mode 100644 index 00000000..773bbb71 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_privacy_contact.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_PRIVACY_CONTACT="Privacy - Contacts" +PLG_PRIVACY_CONTACT_XML_DESCRIPTION="Responsible for processing privacy related requests for the core Joomla contact data." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_privacy_content.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_privacy_content.ini new file mode 100644 index 00000000..b257e2b8 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_privacy_content.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_PRIVACY_CONTENT="Privacy - Content" +PLG_PRIVACY_CONTENT_XML_DESCRIPTION="Responsible for processing privacy related requests for the core Joomla content data." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_privacy_content.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_privacy_content.sys.ini new file mode 100644 index 00000000..b257e2b8 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_privacy_content.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_PRIVACY_CONTENT="Privacy - Content" +PLG_PRIVACY_CONTENT_XML_DESCRIPTION="Responsible for processing privacy related requests for the core Joomla content data." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_privacy_message.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_privacy_message.ini new file mode 100644 index 00000000..054f5e92 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_privacy_message.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_PRIVACY_MESSAGE="Privacy - User Messages" +PLG_PRIVACY_MESSAGE_XML_DESCRIPTION="Responsible for processing privacy related requests for the core Joomla user messages data." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_privacy_message.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_privacy_message.sys.ini new file mode 100644 index 00000000..054f5e92 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_privacy_message.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_PRIVACY_MESSAGE="Privacy - User Messages" +PLG_PRIVACY_MESSAGE_XML_DESCRIPTION="Responsible for processing privacy related requests for the core Joomla user messages data." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_privacy_user.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_privacy_user.ini new file mode 100644 index 00000000..e125ace0 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_privacy_user.ini @@ -0,0 +1,8 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_PRIVACY_USER="Privacy - User Accounts" +PLG_PRIVACY_USER_ERROR_CANNOT_REMOVE_SUPER_USER="Cannot remove a super user account." +PLG_PRIVACY_USER_XML_DESCRIPTION="Responsible for processing privacy related requests for the core Joomla user data." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_privacy_user.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_privacy_user.sys.ini new file mode 100644 index 00000000..6a310979 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_privacy_user.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_PRIVACY_USER="Privacy - User Accounts" +PLG_PRIVACY_USER_XML_DESCRIPTION="Responsible for processing privacy related requests for the core Joomla user data." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_quickicon_extensionupdate.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_quickicon_extensionupdate.ini new file mode 100644 index 00000000..1fbe2e30 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_quickicon_extensionupdate.ini @@ -0,0 +1,15 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_QUICKICON_EXTENSIONUPDATE="Quick Icon - Joomla! Extensions Updates Notification" +PLG_QUICKICON_EXTENSIONUPDATE_CHECKING="Checking extensions ..." +PLG_QUICKICON_EXTENSIONUPDATE_ERROR="Unknown extensions ..." +PLG_QUICKICON_EXTENSIONUPDATE_GROUP_DESC="The group of this plugin (this value is compared with the group value used in Quick Icons modules to inject icons)." +PLG_QUICKICON_EXTENSIONUPDATE_GROUP_LABEL="Group" +PLG_QUICKICON_EXTENSIONUPDATE_UPDATEFOUND="Updates are available! %s" +PLG_QUICKICON_EXTENSIONUPDATE_UPDATEFOUND_BUTTON="View Updates" +PLG_QUICKICON_EXTENSIONUPDATE_UPDATEFOUND_MESSAGE="%s Extension Update(s) are available:" +PLG_QUICKICON_EXTENSIONUPDATE_UPTODATE="All extensions are up to date." +PLG_QUICKICON_EXTENSIONUPDATE_XML_DESCRIPTION="Checks for updates of your installed third-party extensions and notifies you when you visit the Control Panel page." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_quickicon_extensionupdate.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_quickicon_extensionupdate.sys.ini new file mode 100644 index 00000000..4748b7a8 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_quickicon_extensionupdate.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_QUICKICON_EXTENSIONUPDATE="Quick Icon - Joomla! Extensions Updates Notification" +PLG_QUICKICON_EXTENSIONUPDATE_XML_DESCRIPTION="Checks for updates of your installed third-party extensions and notifies you when you visit the Control Panel page." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_quickicon_joomlaupdate.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_quickicon_joomlaupdate.ini new file mode 100644 index 00000000..0c81da47 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_quickicon_joomlaupdate.ini @@ -0,0 +1,15 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_QUICKICON_JOOMLAUPDATE="Quick Icon - Joomla Update Notification" +PLG_QUICKICON_JOOMLAUPDATE_CHECKING="Checking Joomla..." +PLG_QUICKICON_JOOMLAUPDATE_ERROR="Unknown Joomla..." +PLG_QUICKICON_JOOMLAUPDATE_GROUP_DESC="The group of this plugin (this value is compared with the group value used in Quick Icons modules to inject icons)." +PLG_QUICKICON_JOOMLAUPDATE_GROUP_LABEL="Group" +PLG_QUICKICON_JOOMLAUPDATE_UPDATEFOUND="Joomla %s, Update now!" +PLG_QUICKICON_JOOMLAUPDATE_UPDATEFOUND_BUTTON="Update Now" +PLG_QUICKICON_JOOMLAUPDATE_UPDATEFOUND_MESSAGE="Joomla %s is available:" +PLG_QUICKICON_JOOMLAUPDATE_UPTODATE="Joomla is up to date." +PLG_QUICKICON_JOOMLAUPDATE_XML_DESCRIPTION="Checks for Joomla updates and notifies you when you visit the Control Panel page." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_quickicon_joomlaupdate.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_quickicon_joomlaupdate.sys.ini new file mode 100644 index 00000000..ec35918a --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_quickicon_joomlaupdate.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_QUICKICON_JOOMLAUPDATE="Quick Icon - Joomla! Update Notification" +PLG_QUICKICON_JOOMLAUPDATE_XML_DESCRIPTION="Checks for Joomla! updates and notifies you when you visit the Control Panel page." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_quickicon_phpversioncheck.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_quickicon_phpversioncheck.ini new file mode 100644 index 00000000..4064aa46 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_quickicon_phpversioncheck.ini @@ -0,0 +1,13 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_QUICKICON_PHPVERSIONCHECK="Quick Icon - PHP Version Check" +; Key 1 is the server's current PHP version, key 2 is the date at which support will end for the current PHP version +PLG_QUICKICON_PHPVERSIONCHECK_SECURITY_ONLY="Your PHP version, %1$s, is only receiving security fixes from the PHP project at this time. This means your PHP version will soon no longer be supported. We recommend planning to upgrade to a newer PHP version before it reaches end of support on %2$s. Joomla will be faster and more secure if you upgrade to a newer PHP version. Please contact your host for upgrade instructions." +; Key 1 is the server's current PHP version, key 2 is the recommended PHP version, and key 3 is the date at which support will end for the recommended PHP version +PLG_QUICKICON_PHPVERSIONCHECK_UNSUPPORTED="We have detected that your server is using PHP %1$s which is obsolete and no longer receives official security updates by its developers. The Joomla! Project recommends upgrading your site to PHP %2$s or later which will receive security updates at least until %3$s. Please ask your host to make PHP %2$s or a later version the default version for your site. If your host is already PHP %2$s ready please enable PHP %2$s on your site's root and 'administrator' directories – typically you can do this yourself through a tool in your hosting control panel, but it's best to ask your host if you are unsure." +; Key 1 is the server's current PHP version +PLG_QUICKICON_PHPVERSIONCHECK_UNSUPPORTED_JOOMLA_OUTDATED="We have detected that your server is using PHP %1$s which is obsolete and no longer receives official security updates by its developers. Furthermore, we cannot recommend a newer PHP version because you are using an outdated Joomla! version. We recommend updating Joomla! and then following further PHP upgrade instructions." +PLG_QUICKICON_PHPVERSIONCHECK_XML_DESCRIPTION="Checks the support status of your installation's PHP version and raises a warning if not fully supported." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_quickicon_phpversioncheck.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_quickicon_phpversioncheck.sys.ini new file mode 100644 index 00000000..a34b6aa5 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_quickicon_phpversioncheck.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_QUICKICON_PHPVERSIONCHECK="Quick Icon - PHP Version Check" +PLG_QUICKICON_PHPVERSIONCHECK_XML_DESCRIPTION="Checks the support status of your installation's PHP version and raises a warning if not fully supported." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_quickicon_privacycheck.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_quickicon_privacycheck.ini new file mode 100644 index 00000000..31188765 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_quickicon_privacycheck.ini @@ -0,0 +1,15 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_QUICKICON_PRIVACYCHECK="Quick Icon - Joomla! Privacy Requests Notification" +PLG_QUICKICON_PRIVACYCHECK_CHECKING="Checking requests ..." +PLG_QUICKICON_PRIVACYCHECK_ERROR="Unknown requests ..." +PLG_QUICKICON_PRIVACYCHECK_GROUP_DESC="The group of this plugin (this value is compared with the group value used in Quick Icons modules to inject icons)." +PLG_QUICKICON_PRIVACYCHECK_GROUP_LABEL="Group" +PLG_QUICKICON_PRIVACYCHECK_REQUESTFOUND="Urgent Privacy Requests" +PLG_QUICKICON_PRIVACYCHECK_REQUESTFOUND_BUTTON="View Requests" +PLG_QUICKICON_PRIVACYCHECK_REQUESTFOUND_MESSAGE="Urgent Privacy Request(s) to manage." +PLG_QUICKICON_PRIVACYCHECK_NOREQUEST="No Urgent Requests." +PLG_QUICKICON_PRIVACYCHECK_XML_DESCRIPTION="Checks for privacy requests that need to be handled and notifies you when you visit the Control Panel page." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_quickicon_privacycheck.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_quickicon_privacycheck.sys.ini new file mode 100644 index 00000000..a9acbc71 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_quickicon_privacycheck.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_QUICKICON_PRIVACYCHECK="Quick Icon - Joomla! Privacy Requests Notification" +PLG_QUICKICON_PRIVACYCHECK_XML_DESCRIPTION="Checks for privacy requests that need to be handled and notifies you when you visit the Control Panel page." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_sampledata_blog.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_sampledata_blog.ini new file mode 100644 index 00000000..ede71f2d --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_sampledata_blog.ini @@ -0,0 +1,64 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_SAMPLEDATA_BLOG="Sample Data - Blog" +PLG_SAMPLEDATA_BLOG_OVERVIEW_DESC="Sample data which will set up a blog site.
    If the site is multilingual, the data will be tagged to the active backend language." +PLG_SAMPLEDATA_BLOG_OVERVIEW_TITLE="Blog Sample data" +PLG_SAMPLEDATA_BLOG_SAMPLEDATA_CONTENT_ARTICLE_0_FULLTEXT="" +PLG_SAMPLEDATA_BLOG_SAMPLEDATA_CONTENT_ARTICLE_0_INTROTEXT="

    This tells you a bit about this blog and the person who writes it.

    When you are logged in you will be able to edit this page by selecting the edit icon.

    " +PLG_SAMPLEDATA_BLOG_SAMPLEDATA_CONTENT_ARTICLE_0_TITLE="About" +PLG_SAMPLEDATA_BLOG_SAMPLEDATA_CONTENT_ARTICLE_1_FULLTEXT="" +PLG_SAMPLEDATA_BLOG_SAMPLEDATA_CONTENT_ARTICLE_1_INTROTEXT="

    Here are some basic tips for working on your site.

    • Joomla! has a 'front end' that you are looking at now and an 'administrator' or 'back end' which is where you do the more advanced work of creating your site such as setting up the menus and deciding what modules to show. You need to login to the administrator separately using the same user name and password that you used to login to this part of the site.
    • One of the first things you will probably want to do is change the site title and tag line and to add a logo. To do this select the Template Settings link in the top menu. To change your site description, browser title, default email and other items, select Site Settings. More advanced configuration options are available in the administrator.
    • To totally change the look of your site you will probably want to install a new template. In the Extensions menu select Extensions Manager and then go to the Install tab. There are many free and commercial templates available for Joomla.
    • As you have already seen, you can control who can see different parts of you site. When you work with modules, articles or weblinks setting the Access level to Registered will mean that only logged in users can see them
    • When you create a new article or other kind of content you also can save it as Published or Unpublished. If it is Unpublished site visitors will not be able to see it but you will.
    • You can learn much more about working with Joomla from the Joomla documentation site and get help from other users at the Joomla forums. In the administrator there are help buttons on every page that provide detailed information about the functions on that page.
    " +PLG_SAMPLEDATA_BLOG_SAMPLEDATA_CONTENT_ARTICLE_1_TITLE="Working on Your Site" +PLG_SAMPLEDATA_BLOG_SAMPLEDATA_CONTENT_ARTICLE_2_FULLTEXT="" +PLG_SAMPLEDATA_BLOG_SAMPLEDATA_CONTENT_ARTICLE_2_INTROTEXT="

    This is a sample blog posting.

    If you log in to the site (the Author Login link is on the very bottom of this page) you will be able to edit it and all of the other existing articles. You will also be able to create a new article and make other changes to the site.

    As you add and modify articles you will see how your site changes and also how you can customise it in various ways.

    Go ahead, you can't break it.

    " +PLG_SAMPLEDATA_BLOG_SAMPLEDATA_CONTENT_ARTICLE_2_TITLE="Welcome to your blog" +PLG_SAMPLEDATA_BLOG_SAMPLEDATA_CONTENT_ARTICLE_3_FULLTEXT="

    On the full page you will see both the introductory content and the rest of the article. You can change the settings to hide the introduction if you want.

    " +PLG_SAMPLEDATA_BLOG_SAMPLEDATA_CONTENT_ARTICLE_3_INTROTEXT="

    Your home page is set to display the four most recent articles from the blog category in a column. Then there are links to the next two oldest articles. You can change those numbers by editing the content options settings in the blog tab in your site administrator. There is a link to your site administrator in the top menu.

    If you want to have your blog post broken into two parts, an introduction and then a full length separate page, use the Read More button to insert a break.

    " +PLG_SAMPLEDATA_BLOG_SAMPLEDATA_CONTENT_ARTICLE_3_TITLE="About your home page" +PLG_SAMPLEDATA_BLOG_SAMPLEDATA_CONTENT_ARTICLE_4_FULLTEXT="" +PLG_SAMPLEDATA_BLOG_SAMPLEDATA_CONTENT_ARTICLE_4_INTROTEXT="

    Your site has some commonly used modules already preconfigured. These include:

    • Image Module which holds the image beneath the menu. This is a Custom module that you can edit to change the image.
    • Most Read Posts which lists articles based on the number of times they have been read.
    • Older Articles which lists out articles by month.
    • Syndicate which allows your readers to read your posts in a news reader.
    • Popular Tags, which will appear if you use tagging on your articles. Enter a tag in the Tags field when editing.

    Each of these modules has many options which you can experiment with in the Module Manager in your site Administrator. Moving your mouse over a module and selecting the edit icon will take you to an edit screen for that module. Always be sure to save and close any module you edit.

    Joomla! also includes many other modules you can incorporate in your site. As you develop your site you may want to add more module that you can find at the Joomla Extensions Directory.

    " +PLG_SAMPLEDATA_BLOG_SAMPLEDATA_CONTENT_ARTICLE_4_TITLE="Your Modules" +PLG_SAMPLEDATA_BLOG_SAMPLEDATA_CONTENT_ARTICLE_5_FULLTEXT="" +PLG_SAMPLEDATA_BLOG_SAMPLEDATA_CONTENT_ARTICLE_5_INTROTEXT="

    Templates control the look and feel of your website.

    This blog is installed with the Protostar template.

    You can edit the options by selecting the Working on Your Site, Template Settings link in the top menu (visible when you login).

    For example you can change the site background color, highlights color, site title, site description and title font used.

    More options are available in the site administrator. You may also install a new template using the extension manager.

    " +PLG_SAMPLEDATA_BLOG_SAMPLEDATA_CONTENT_ARTICLE_5_TITLE="Your Template" +PLG_SAMPLEDATA_BLOG_SAMPLEDATA_CONTENT_CATEGORY_0_TITLE="Blog" +PLG_SAMPLEDATA_BLOG_SAMPLEDATA_CONTENT_CATEGORY_1_TITLE="Help" +PLG_SAMPLEDATA_BLOG_SAMPLEDATA_MENUS_ITEM_0_TITLE="Blog" +PLG_SAMPLEDATA_BLOG_SAMPLEDATA_MENUS_ITEM_1_TITLE="About" +PLG_SAMPLEDATA_BLOG_SAMPLEDATA_MENUS_ITEM_2_TITLE="Author Login" +PLG_SAMPLEDATA_BLOG_SAMPLEDATA_MENUS_ITEM_3_TITLE="Create a Post" +PLG_SAMPLEDATA_BLOG_SAMPLEDATA_MENUS_ITEM_4_TITLE="Working on Your Site" +PLG_SAMPLEDATA_BLOG_SAMPLEDATA_MENUS_ITEM_5_TITLE="Site Administrator" +PLG_SAMPLEDATA_BLOG_SAMPLEDATA_MENUS_ITEM_6_TITLE="Change Password" +PLG_SAMPLEDATA_BLOG_SAMPLEDATA_MENUS_ITEM_7_TITLE="Log out" +PLG_SAMPLEDATA_BLOG_SAMPLEDATA_MENUS_ITEM_8_TITLE="Author Login" +PLG_SAMPLEDATA_BLOG_SAMPLEDATA_MENUS_ITEM_9_TITLE="Site Settings" +PLG_SAMPLEDATA_BLOG_SAMPLEDATA_MENUS_ITEM_10_TITLE="Template Settings" +PLG_SAMPLEDATA_BLOG_SAMPLEDATA_MENUS_MENU_0_DESCRIPTION="The main menu for the site" +PLG_SAMPLEDATA_BLOG_SAMPLEDATA_MENUS_MENU_0_TITLE="Main Menu Blog" +PLG_SAMPLEDATA_BLOG_SAMPLEDATA_MENUS_MENU_1_DESCRIPTION="" +PLG_SAMPLEDATA_BLOG_SAMPLEDATA_MENUS_MENU_1_TITLE="Author Menu" +PLG_SAMPLEDATA_BLOG_SAMPLEDATA_MENUS_MENU_2_DESCRIPTION="" +PLG_SAMPLEDATA_BLOG_SAMPLEDATA_MENUS_MENU_2_TITLE="Bottom Menu" +PLG_SAMPLEDATA_BLOG_SAMPLEDATA_MODULES_MODULE_0_TITLE="Main Menu Blog" +PLG_SAMPLEDATA_BLOG_SAMPLEDATA_MODULES_MODULE_1_TITLE="Author Menu" +PLG_SAMPLEDATA_BLOG_SAMPLEDATA_MODULES_MODULE_2_TITLE="Syndication" +PLG_SAMPLEDATA_BLOG_SAMPLEDATA_MODULES_MODULE_3_TITLE="Archived Articles" +PLG_SAMPLEDATA_BLOG_SAMPLEDATA_MODULES_MODULE_4_TITLE="Most Read Posts" +PLG_SAMPLEDATA_BLOG_SAMPLEDATA_MODULES_MODULE_5_TITLE="Older Posts" +PLG_SAMPLEDATA_BLOG_SAMPLEDATA_MODULES_MODULE_6_TITLE="Bottom Menu" +PLG_SAMPLEDATA_BLOG_SAMPLEDATA_MODULES_MODULE_7_TITLE="Search" +PLG_SAMPLEDATA_BLOG_SAMPLEDATA_MODULES_MODULE_8_TITLE="Image" +PLG_SAMPLEDATA_BLOG_SAMPLEDATA_MODULES_MODULE_9_TITLE="Popular Tags" +PLG_SAMPLEDATA_BLOG_SAMPLEDATA_MODULES_MODULE_10_TITLE="Similar Items" +PLG_SAMPLEDATA_BLOG_SAMPLEDATA_MODULES_MODULE_11_TITLE="Site Information" +PLG_SAMPLEDATA_BLOG_SAMPLEDATA_MODULES_MODULE_12_TITLE="Release News" +PLG_SAMPLEDATA_BLOG_STEP_FAILED="Step %1$u Failed: %2$s" +PLG_SAMPLEDATA_BLOG_STEP_SKIPPED="Step %1$u Skipped: '%2$s' is either not installed or disabled." +PLG_SAMPLEDATA_BLOG_STEP1_SUCCESS="Step 1: Articles done!" +PLG_SAMPLEDATA_BLOG_STEP2_SUCCESS="Step 2: Menus done!" +PLG_SAMPLEDATA_BLOG_STEP3_SUCCESS="Step 3: Modules done!" +PLG_SAMPLEDATA_BLOG_XML_DESCRIPTION="Provides the blog sample data. Can be installed using the sample data module." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_sampledata_blog.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_sampledata_blog.sys.ini new file mode 100644 index 00000000..5bebb13b --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_sampledata_blog.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_SAMPLEDATA_BLOG="Sample Data - Blog" +PLG_SAMPLEDATA_BLOG_XML_DESCRIPTION="Provides the blog sample data. Can be installed using the sample data module." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_search_categories.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_search_categories.ini new file mode 100644 index 00000000..75fbe7a2 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_search_categories.ini @@ -0,0 +1,11 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + + +PLG_SEARCH_CATEGORIES_CATEGORIES="Categories" +PLG_SEARCH_CATEGORIES="Search - Categories" +PLG_SEARCH_CATEGORIES_FIELD_SEARCHLIMIT_DESC="Number of search items to return." +PLG_SEARCH_CATEGORIES_FIELD_SEARCHLIMIT_LABEL="Search Limit" +PLG_SEARCH_CATEGORIES_XML_DESCRIPTION="Enables searching of Category information." \ No newline at end of file diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_search_categories.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_search_categories.sys.ini new file mode 100644 index 00000000..bf7af944 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_search_categories.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_SEARCH_CATEGORIES="Search - Categories" +PLG_SEARCH_CATEGORIES_XML_DESCRIPTION="Enables searching of Category information." \ No newline at end of file diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_search_contacts.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_search_contacts.ini new file mode 100644 index 00000000..6732e1b4 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_search_contacts.ini @@ -0,0 +1,10 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_SEARCH_CONTACTS="Search - Contacts" +PLG_SEARCH_CONTACTS_CONTACTS="Contacts" +PLG_SEARCH_CONTACTS_FIELD_SEARCHLIMIT_DESC="Number of search items to return." +PLG_SEARCH_CONTACTS_FIELD_SEARCHLIMIT_LABEL="Search Limit" +PLG_SEARCH_CONTACTS_XML_DESCRIPTION="Enables searching of the Contact Component." \ No newline at end of file diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_search_contacts.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_search_contacts.sys.ini new file mode 100644 index 00000000..86986326 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_search_contacts.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_SEARCH_CONTACTS="Search - Contacts" +PLG_SEARCH_CONTACTS_XML_DESCRIPTION="Enables searching of the Contact Component." \ No newline at end of file diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_search_content.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_search_content.ini new file mode 100644 index 00000000..fc3c0a76 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_search_content.ini @@ -0,0 +1,13 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_SEARCH_CONTENT="Search - Content" +PLG_SEARCH_CONTENT_FIELD_ARCHIVED_DESC="Enables searching of Archived Articles." +PLG_SEARCH_CONTENT_FIELD_ARCHIVED_LABEL="Archived Articles" +PLG_SEARCH_CONTENT_FIELD_CONTENT_DESC="Enables searching of all Articles." +PLG_SEARCH_CONTENT_FIELD_CONTENT_LABEL="Articles" +PLG_SEARCH_CONTENT_FIELD_SEARCHLIMIT_DESC="Number of search items to return." +PLG_SEARCH_CONTENT_FIELD_SEARCHLIMIT_LABEL="Search Limit" +PLG_SEARCH_CONTENT_XML_DESCRIPTION="Enables searching in Articles." \ No newline at end of file diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_search_content.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_search_content.sys.ini new file mode 100644 index 00000000..9301f065 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_search_content.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_SEARCH_CONTENT="Search - Content" +PLG_SEARCH_CONTENT_XML_DESCRIPTION="Enables searching in Articles." \ No newline at end of file diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_search_newsfeeds.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_search_newsfeeds.ini new file mode 100644 index 00000000..7dffd047 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_search_newsfeeds.ini @@ -0,0 +1,10 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_SEARCH_NEWSFEEDS="Search - News Feeds" +PLG_SEARCH_NEWSFEEDS_FIELD_SEARCHLIMIT_DESC="Number of search items to return." +PLG_SEARCH_NEWSFEEDS_FIELD_SEARCHLIMIT_LABEL="Search Limit" +PLG_SEARCH_NEWSFEEDS_NEWSFEEDS="News Feeds" +PLG_SEARCH_NEWSFEEDS_XML_DESCRIPTION="Enables searching of News feeds." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_search_newsfeeds.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_search_newsfeeds.sys.ini new file mode 100644 index 00000000..e731a1ca --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_search_newsfeeds.sys.ini @@ -0,0 +1,8 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_SEARCH_NEWSFEEDS="Search - News Feeds" +PLG_SEARCH_NEWSFEEDS_XML_DESCRIPTION="Enables searching of news feeds." + diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_search_tags.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_search_tags.ini new file mode 100644 index 00000000..fcd2b2d8 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_search_tags.ini @@ -0,0 +1,13 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_SEARCH_TAGS="Search - Tags" +PLG_SEARCH_TAGS_FIELD_SEARCHLIMIT_DESC="Number of search items to return." +PLG_SEARCH_TAGS_FIELD_SEARCHLIMIT_LABEL="Search Limit" +PLG_SEARCH_TAGS_FIELD_SHOW_TAGGED_ITEMS_DESC="Display or not the items that hold the tags related to the search." +PLG_SEARCH_TAGS_FIELD_SHOW_TAGGED_ITEMS_LABEL="Show Tagged Items" +PLG_SEARCH_TAGS_ITEM_TAGGED_WITH="%s tagged with: %s" +PLG_SEARCH_TAGS_TAGS="Tags" +PLG_SEARCH_TAGS_XML_DESCRIPTION="Enables searching in Tags." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_search_tags.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_search_tags.sys.ini new file mode 100644 index 00000000..3e2acc73 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_search_tags.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_SEARCH_TAGS="Search - Tags" +PLG_SEARCH_TAGS_XML_DESCRIPTION="Enables searching in Tags." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_search_weblinks.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_search_weblinks.ini new file mode 100644 index 00000000..84601237 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_search_weblinks.ini @@ -0,0 +1,10 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_SEARCH_WEBLINKS="Search - Web Links" +PLG_SEARCH_WEBLINKS_FIELD_SEARCHLIMIT_DESC="Number of search items to return." +PLG_SEARCH_WEBLINKS_FIELD_SEARCHLIMIT_LABEL="Search Limit" +PLG_SEARCH_WEBLINKS_WEBLINKS="Web Links" +PLG_SEARCH_WEBLINKS_XML_DESCRIPTION="Enables searching of Web Links Component." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_search_weblinks.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_search_weblinks.sys.ini new file mode 100644 index 00000000..3371115b --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_search_weblinks.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_SEARCH_WEBLINKS="Search - Web Links" +PLG_SEARCH_WEBLINKS_XML_DESCRIPTION="Enables searching of Web Links Component." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_system_actionlogs.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_actionlogs.ini new file mode 100644 index 00000000..0dab3660 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_actionlogs.ini @@ -0,0 +1,26 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_SYSTEM_ACTIONLOGS="System - User Actions Log" +PLG_SYSTEM_ACTIONLOGS_EXTENSIONS_NOTIFICATIONS="Select events to be notified for" +PLG_SYSTEM_ACTIONLOGS_EXTENSIONS_NOTIFICATIONS_DESC="Select events to be sent to your email as notifications" +PLG_SYSTEM_ACTIONLOGS_INFO_DESC="The Action Log - Joomla plugin is disabled" +PLG_SYSTEM_ACTIONLOGS_INFO_LABEL="Information" +PLG_SYSTEM_ACTIONLOGS_JOOMLA_ACTIONLOG_DISABLED="Action Log - Joomla" +PLG_SYSTEM_ACTIONLOGS_JOOMLA_ACTIONLOG_DISABLED_REDIRECT="The %s plugin is disabled." +PLG_SYSTEM_ACTIONLOGS_LOG_DELETE_PERIOD="Days to delete logs after" +PLG_SYSTEM_ACTIONLOGS_LOG_DELETE_PERIOD_DESC="Enter 0 if you don't want to delete the logs." +PLG_SYSTEM_ACTIONLOGS_NOTIFICATIONS="Send notifications for User Actions Log" +PLG_SYSTEM_ACTIONLOGS_NOTIFICATIONS_DESC="Send a notifications of users' actions log to your email" +PLG_SYSTEM_ACTIONLOGS_OPTIONS="User Actions Log Options" +PLG_SYSTEM_ACTIONLOGS_XML_DESCRIPTION="Records the actions of users on the site so they can be reviewed if required." +; Common content type log messages +PLG_SYSTEM_ACTIONLOGS_CONTENT_ADDED="User {username} added new {type} {title}" +PLG_SYSTEM_ACTIONLOGS_CONTENT_ARCHIVED="User {username} archived the {type} {title}" +PLG_SYSTEM_ACTIONLOGS_CONTENT_UPDATED="User {username} updated the {type} {title}" +PLG_SYSTEM_ACTIONLOGS_CONTENT_PUBLISHED="User {username} published the {type} {title}" +PLG_SYSTEM_ACTIONLOGS_CONTENT_UNPUBLISHED="User {username} unpublished the {type} {title}" +PLG_SYSTEM_ACTIONLOGS_CONTENT_TRASHED="User {username} trashed the {type} {title}" +PLG_SYSTEM_ACTIONLOGS_CONTENT_DELETED="User {username} deleted the {type} {title}" diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_system_actionlogs.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_actionlogs.sys.ini new file mode 100644 index 00000000..3724013e --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_actionlogs.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_SYSTEM_ACTIONLOGS="System - User Actions Log" +PLG_SYSTEM_ACTIONLOGS_XML_DESCRIPTION="Records the actions of users on the site so they can be reviewed if required." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_system_cache.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_cache.ini new file mode 100644 index 00000000..933cf60a --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_cache.ini @@ -0,0 +1,15 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_CACHE_FIELD_BROWSERCACHE_DESC="If yes, use mechanism for storing page cache in the browser." +PLG_CACHE_FIELD_BROWSERCACHE_LABEL="Use Browser Caching" +PLG_CACHE_FIELD_EXCLUDE_DESC="Specify which URLs you want to exclude from caching, each on a separate line. Regular expressions are supported, eg.
    about\-[a-z]+ - will exclude all URLs that have 'about-', for example 'about-us', 'about-me', 'about-joomla' etc.
    /component/users/ - will exclude all URLs that have /component/users/.
    com_users - will exclude all Users component pages." +PLG_CACHE_FIELD_EXCLUDE_LABEL="Exclude URLs" +PLG_CACHE_FIELD_EXCLUDE_MENU_ITEMS_DESC="Select which menu items you want to exclude from caching." +PLG_CACHE_FIELD_EXCLUDE_MENU_ITEMS_LABEL="Exclude Menu Items" +PLG_CACHE_FIELD_LIFETIME_DESC="Page cache lifetime in minutes." +PLG_CACHE_FIELD_LIFETIME_LABEL="Cache Lifetime" +PLG_CACHE_XML_DESCRIPTION="Provides page caching." +PLG_SYSTEM_CACHE="System - Page Cache" diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_system_cache.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_cache.sys.ini new file mode 100644 index 00000000..c1dc294b --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_cache.sys.ini @@ -0,0 +1,8 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + + +PLG_CACHE_XML_DESCRIPTION="Provides page caching." +PLG_SYSTEM_CACHE="System - Page Cache" diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_system_debug.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_debug.ini new file mode 100644 index 00000000..39019cdc --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_debug.ini @@ -0,0 +1,106 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_DEBUG_BYTES="Bytes" +PLG_DEBUG_CALL_STACK="Call Stack" +PLG_DEBUG_CALL_STACK_CALLER="Caller" +PLG_DEBUG_CALL_STACK_FILE_AND_LINE="File and line number" +PLG_DEBUG_CALL_STACK_SAME_FILE="Same as call in the line below." +PLG_DEBUG_ERRORS="Errors" +PLG_DEBUG_EXPLAIN="Explain" +PLG_DEBUG_FIELD_ALLOWED_GROUPS_DESC="Optionally restrict users that can see debug information to those in the selected user groups. If none selected, all users will see the debug information." +PLG_DEBUG_FIELD_ALLOWED_GROUPS_LABEL="Allowed Groups" +PLG_DEBUG_FIELD_EXECUTEDSQL_DESC="If enabled, executed SQL queries will be logged. Only use this setting for short periods of time and for benchmarking purposes." +PLG_DEBUG_FIELD_EXECUTEDSQL_LABEL="Log Executed Queries" +PLG_DEBUG_FIELD_LANGUAGE_ERRORFILES_DESC="Display a list of the language files that are in error according to the Joomla ini specification." +PLG_DEBUG_FIELD_LANGUAGE_ERRORFILES_LABEL="Show Errors When Parsing Language Files" +PLG_DEBUG_FIELD_LANGUAGE_FILES_DESC="Display a list of the language files that Joomla has tried to load." +PLG_DEBUG_FIELD_LANGUAGE_FILES_LABEL="Show Language Files" +PLG_DEBUG_FIELD_LANGUAGE_STRING_DESC="Display a list of the untranslated language strings." +PLG_DEBUG_FIELD_LANGUAGE_STRING_LABEL="Show Language String" +PLG_DEBUG_FIELD_LOGS_DESC="Display a list of logged messages." +PLG_DEBUG_FIELD_LOGS_LABEL="Show Log Entries" +PLG_DEBUG_FIELD_LOG_CATEGORIES_DESC="A comma separated list of log categories to include. Common log categories include but are not limited to: database, databasequery, database-error, deprecated and jerror. If empty, all categories will be shown." +PLG_DEBUG_FIELD_LOG_CATEGORIES_LABEL="Log Categories" +PLG_DEBUG_FIELD_LOG_CATEGORY_MODE_DESC="Select if the listed categories should be included or excluded." +PLG_DEBUG_FIELD_LOG_CATEGORY_MODE_EXCLUDE="Exclude" +PLG_DEBUG_FIELD_LOG_CATEGORY_MODE_INCLUDE="Include" +PLG_DEBUG_FIELD_LOG_CATEGORY_MODE_LABEL="Log Category Mode" +PLG_DEBUG_FIELD_LOG_DEPRECATED_DESC="If enabled, API marked as deprecated will be logged. Only use this setting for short periods of time for refactoring purposes." +PLG_DEBUG_FIELD_LOG_DEPRECATED_LABEL="Log Deprecated API" +PLG_DEBUG_FIELD_LOG_EVERYTHING_DESC="If enabled, all log messages produced by Joomla! will be logged except for deprecated API and database queries. Only use this setting for short periods of time for site debugging purposes." +PLG_DEBUG_FIELD_LOG_EVERYTHING_LABEL="Log Almost Everything" +PLG_DEBUG_FIELD_LOG_PRIORITIES_ALERT="Alert" +PLG_DEBUG_FIELD_LOG_PRIORITIES_ALL="All" +PLG_DEBUG_FIELD_LOG_PRIORITIES_CRITICAL="Critical" +PLG_DEBUG_FIELD_LOG_PRIORITIES_DEBUG="Debug" +PLG_DEBUG_FIELD_LOG_PRIORITIES_DESC="Select which log priority levels to display." +PLG_DEBUG_FIELD_LOG_PRIORITIES_EMERGENCY="Emergency" +PLG_DEBUG_FIELD_LOG_PRIORITIES_ERROR="Error" +PLG_DEBUG_FIELD_LOG_PRIORITIES_INFO="Info" +PLG_DEBUG_FIELD_LOG_PRIORITIES_LABEL="Log Priorities" +PLG_DEBUG_FIELD_LOG_PRIORITIES_NOTICE="Notice" +PLG_DEBUG_FIELD_LOG_PRIORITIES_WARNING="Warning" +PLG_DEBUG_FIELD_MEMORY_DESC="Display the total memory usage." +PLG_DEBUG_FIELD_MEMORY_LABEL="Show Memory Usage" +PLG_DEBUG_FIELD_PROFILING_DESC="Display the profiling waypoints." +PLG_DEBUG_FIELD_PROFILING_LABEL="Show Profiling" +PLG_DEBUG_FIELD_QUERIES_DESC="Display a list of the queries executed while displaying the page." +PLG_DEBUG_FIELD_QUERIES_LABEL="Show Queries" +PLG_DEBUG_FIELD_QUERY_TYPES_DESC="Display a list of unique query types and their number of occurrences for the current page. Useful for finding out about repeated queries that are either redundant or which can be grouped into a single, more efficient query." +PLG_DEBUG_FIELD_QUERY_TYPES_LABEL="Show Query Types" +PLG_DEBUG_FIELD_REFRESH_ASSETS_DESC="If enabled will, on each page reload, add a different hash to every script/stylesheet file with auto version so that they never use the browser cache." +PLG_DEBUG_FIELD_REFRESH_ASSETS_LABEL="Refresh Assets" +PLG_DEBUG_FIELD_SESSION_DESC="Display the session data." +PLG_DEBUG_FIELD_SESSION_LABEL="Show Session Data" +PLG_DEBUG_FIELD_STRIP_FIRST_DESC="In multi-word strings, always strip the first word." +PLG_DEBUG_FIELD_STRIP_FIRST_LABEL="Strip First Word" +PLG_DEBUG_FIELD_STRIP_PREFIX_DESC="Strip words from the beginning of the string. For multiple words, use the format: (word1|word2)." +PLG_DEBUG_FIELD_STRIP_PREFIX_LABEL="Strip From Start" +PLG_DEBUG_FIELD_STRIP_SUFFIX_DESC="Strip words from the end of the string. For multiple words, use the format: (word1|word2)." +PLG_DEBUG_FIELD_STRIP_SUFFIX_LABEL="Strip From End" +PLG_DEBUG_LANGUAGE_FIELDSET_LABEL="Language" +PLG_DEBUG_LANGUAGE_FILES_IN_ERROR="Parsing errors in language files" +PLG_DEBUG_LANGUAGE_FILES_LOADED="Language Files Loaded" +PLG_DEBUG_LANG_LOADED="Loaded" +PLG_DEBUG_LANG_NOT_LOADED="Not loaded" +PLG_DEBUG_LINK_FORMAT="Add xdebug.file_link_format directive to your php.ini file to have links for files." +PLG_DEBUG_LOGGING_FIELDSET_LABEL="Logging" +PLG_DEBUG_LOGS="Log Messages" +PLG_DEBUG_LOGS_DEPRECATED_FOUND_TEXT="The code that is marked as deprecated will not work in upcoming Joomla versions, please review it." +PLG_DEBUG_LOGS_DEPRECATED_FOUND_TITLE="%s deprecated messages logged!" +PLG_DEBUG_LOGS_LOGGED="%s messages logged" +PLG_DEBUG_MEMORY="Memory" +PLG_DEBUG_MEMORY_USED_FOR_QUERY="Query memory: %s Memory before query: %s" +PLG_DEBUG_MEMORY_USAGE="Memory Usage" +PLG_DEBUG_NO_PROFILE="No SHOW PROFILE (maybe because there are more than 100 queries)" +PLG_DEBUG_OTHER_QUERIES="OTHER Tables:" +PLG_DEBUG_PROFILE="Profile" +PLG_DEBUG_PROFILE_INFORMATION="Profile Information" +PLG_DEBUG_QUERIES="Database Queries" +PLG_DEBUG_QUERIES_LOGGED="%d Queries Logged" +PLG_DEBUG_QUERIES_TIME="Database queries total: %s" +PLG_DEBUG_QUERY_AFTER_LAST="After last query: %s" +PLG_DEBUG_QUERY_DUPLICATES="Duplicate queries" +PLG_DEBUG_QUERY_DUPLICATES_FOUND="Duplicate found!" +PLG_DEBUG_QUERY_DUPLICATES_NUMBER="%s duplicates" +PLG_DEBUG_QUERY_DUPLICATES_TOTAL_NUMBER="%s duplicate found!" +PLG_DEBUG_QUERY_EXPLAIN_NOT_POSSIBLE="EXPLAIN not possible on query: %s" +PLG_DEBUG_QUERY_TIME="Query Time: %s" +PLG_DEBUG_QUERY_TYPES_LOGGED="%d Query Types Logged, Sorted by Occurrences." +PLG_DEBUG_QUERY_TYPE_AND_OCCURRENCES="%2$d × %1$s" +PLG_DEBUG_ROWS_RETURNED_BY_QUERY="Rows returned: %s" +PLG_DEBUG_SELECT_QUERIES="SELECT Tables:" +PLG_DEBUG_SESSION="Session" +PLG_DEBUG_TIME="Time" +PLG_DEBUG_TITLE="Joomla! Debug Console" +PLG_DEBUG_UNKNOWN_FILE="Unknown file" +PLG_DEBUG_UNTRANSLATED_STRINGS="Untranslated Strings" +PLG_DEBUG_WARNING_NO_INDEX="NO INDEX KEY COULD BE USED" +PLG_DEBUG_WARNING_NO_INDEX_DESC="This table probably has a missing index on WHERE equalities and/or JOIN ON column(s) or is written in a way that no index can be used, causing a time-consuming full table scan." +PLG_DEBUG_WARNING_USING_FILESORT="Using filesort" +PLG_DEBUG_WARNING_USING_FILESORT_DESC="This table probably has a missing index on WHERE/ON equality column(s) ending by the ORDER BY column(s) or is written in a way that no index can be used, causing a time-consuming filesort." +PLG_DEBUG_XML_DESCRIPTION="This plugin provides a variety of system information as well as help for the creation of translation files." +PLG_SYSTEM_DEBUG="System - Debug" diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_system_debug.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_debug.sys.ini new file mode 100644 index 00000000..03d5ef97 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_debug.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_DEBUG_XML_DESCRIPTION="This plugin provides a variety of system information and help for the creation of translation files." +PLG_SYSTEM_DEBUG="System - Debug" diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_system_fields.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_fields.ini new file mode 100644 index 00000000..45dac3b8 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_fields.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_SYSTEM_FIELDS="System - Fields" +PLG_SYSTEM_FIELDS_XML_DESCRIPTION="The system fields plugin that is required to display the custom fields." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_system_fields.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_fields.sys.ini new file mode 100644 index 00000000..45dac3b8 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_fields.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_SYSTEM_FIELDS="System - Fields" +PLG_SYSTEM_FIELDS_XML_DESCRIPTION="The system fields plugin that is required to display the custom fields." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_system_highlight.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_highlight.ini new file mode 100644 index 00000000..fc9ec64a --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_highlight.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_SYSTEM_HIGHLIGHT="System - Highlight" +PLG_SYSTEM_HIGHLIGHT_XML_DESCRIPTION="System plugin to highlight specified terms." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_system_highlight.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_highlight.sys.ini new file mode 100644 index 00000000..a204714f --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_highlight.sys.ini @@ -0,0 +1,8 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_SYSTEM_HIGHLIGHT="System - Highlight" +PLG_SYSTEM_HIGHLIGHT_ERROR_ACTIVATING_PLUGIN="Could not automatically activate the "System - Highlight" plugin" +PLG_SYSTEM_HIGHLIGHT_XML_DESCRIPTION="System plugin to highlight specified terms." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_system_languagecode.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_languagecode.ini new file mode 100644 index 00000000..6d0279eb --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_languagecode.ini @@ -0,0 +1,10 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_SYSTEM_LANGUAGECODE="System - Language Code" +PLG_SYSTEM_LANGUAGECODE_FIELD_DESC="Changes the language code used for the %s language." +PLG_SYSTEM_LANGUAGECODE_FIELDSET_DESC="Changes the language code for the generated HTML document. Example usage: You have installed the fr-FR language pack and want the Search Engines to recognise the page as aimed at French-speaking Canada. Add the tag 'fr-CA' to the corresponding field for 'fr-FR' to resolve this." +PLG_SYSTEM_LANGUAGECODE_FIELDSET_LABEL="Language Codes" +PLG_SYSTEM_LANGUAGECODE_XML_DESCRIPTION="Provides the ability to change the language code in the generated HTML document to improve SEO.
    The fields will appear when the plugin is enabled and saved." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_system_languagecode.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_languagecode.sys.ini new file mode 100644 index 00000000..e2e2447e --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_languagecode.sys.ini @@ -0,0 +1,8 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_SYSTEM_LANGUAGECODE="System - Language Code" +PLG_SYSTEM_LANGUAGECODE_XML_DESCRIPTION="Provides ability to change the language code in the generated HTML document to improve SEO." + diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_system_languagefilter.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_languagefilter.ini new file mode 100644 index 00000000..bbef9f34 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_languagefilter.ini @@ -0,0 +1,29 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_SYSTEM_LANGUAGEFILTER="System - Language Filter" +PLG_SYSTEM_LANGUAGEFILTER_BROWSER_SETTINGS="Browser Settings" +PLG_SYSTEM_LANGUAGEFILTER_FIELD_ALTERNATE_META_DESC="Add alternative meta tags for items with associated items in other languages." +PLG_SYSTEM_LANGUAGEFILTER_FIELD_ALTERNATE_META_LABEL="Add Alternate Meta Tags" +PLG_SYSTEM_LANGUAGEFILTER_FIELD_AUTOMATIC_CHANGE_DESC="This option will automatically change the content language used in the Frontend when a user site language is changed." +PLG_SYSTEM_LANGUAGEFILTER_FIELD_AUTOMATIC_CHANGE_LABEL="Automatic Language Change" +PLG_SYSTEM_LANGUAGEFILTER_FIELD_COOKIE_DESC="Language cookies can be set to expire at the end of the session or after a year. Default is session." +PLG_SYSTEM_LANGUAGEFILTER_FIELD_COOKIE_LABEL="Cookie Lifetime" +PLG_SYSTEM_LANGUAGEFILTER_FIELD_DETECT_BROWSER_DESC="Choose site default language or try to detect the browser settings language. It will default to site language if browser settings can't be found." +PLG_SYSTEM_LANGUAGEFILTER_FIELD_DETECT_BROWSER_LABEL="Language Selection for new Visitors" +PLG_SYSTEM_LANGUAGEFILTER_FIELD_ITEM_ASSOCIATIONS_DESC="This option will allow item associations when switching from one language to another. Default home menu items are always associated." +PLG_SYSTEM_LANGUAGEFILTER_FIELD_ITEM_ASSOCIATIONS_LABEL="Associations" +PLG_SYSTEM_LANGUAGEFILTER_FIELD_XDEFAULT_DESC="This option will add the x-default meta tag to improve SEO." +PLG_SYSTEM_LANGUAGEFILTER_FIELD_XDEFAULT_LABEL="Add x-default Meta Tag" +PLG_SYSTEM_LANGUAGEFILTER_FIELD_XDEFAULT_LANGUAGE_DESC="Choose the x-default language." +PLG_SYSTEM_LANGUAGEFILTER_FIELD_XDEFAULT_LANGUAGE_LABEL="x-default Language" +PLG_SYSTEM_LANGUAGEFILTER_OPTION_DEFAULT_LANGUAGE="Default frontend language" +PLG_SYSTEM_LANGUAGEFILTER_FIELD_REMOVE_DEFAULT_PREFIX_DESC="Remove the defined URL Language Code of the Content Language that corresponds to the default site language when Search Engine Friendly URLs is set to 'Yes'." +PLG_SYSTEM_LANGUAGEFILTER_FIELD_REMOVE_DEFAULT_PREFIX_LABEL="Remove URL Language Code" +PLG_SYSTEM_LANGUAGEFILTER_OPTION_SESSION="Session" +PLG_SYSTEM_LANGUAGEFILTER_OPTION_YEAR="Year" +PLG_SYSTEM_LANGUAGEFILTER_PRIVACY_CAPABILITY_LANGUAGE_COOKIE="On a site which supports multiple languages, this plugin can be configured to set a cookie on the user's browser which remembers their language preference. This cookie is used to redirect users to their preferred language when visiting the site and creating a new session. The cookie's name is based on a randomly generated hash and therefore does not have a constant identifier." +PLG_SYSTEM_LANGUAGEFILTER_SITE_LANGUAGE="Site Language" +PLG_SYSTEM_LANGUAGEFILTER_XML_DESCRIPTION="This plugin filters the displayed content depending on language.
    This plugin is to be enabled only when the Language Switcher module is published.
    If this plugin is activated, it is recommended to also publish the Administrator multilingual status module." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_system_languagefilter.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_languagefilter.sys.ini new file mode 100644 index 00000000..ab1f9feb --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_languagefilter.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_SYSTEM_LANGUAGEFILTER="System - Language Filter" +PLG_SYSTEM_LANGUAGEFILTER_XML_DESCRIPTION="This plugin filters the displayed content depending on language." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_system_log.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_log.ini new file mode 100644 index 00000000..2d9fb13f --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_log.ini @@ -0,0 +1,9 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_LOG_XML_DESCRIPTION="Provides logging when the user login fails." +PLG_SYSTEM_LOG="System - User Log" +PLG_SYSTEM_LOG_FIELD_LOG_USERNAME_DESC="This option will log the username used when an authentication fails." +PLG_SYSTEM_LOG_FIELD_LOG_USERNAME_LABEL="Log Usernames" diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_system_log.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_log.sys.ini new file mode 100644 index 00000000..e011c6a1 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_log.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_LOG_XML_DESCRIPTION="Provides logging when the user login fails." +PLG_SYSTEM_LOG="System - User Log" diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_system_logout.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_logout.ini new file mode 100644 index 00000000..5c012bc0 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_logout.ini @@ -0,0 +1,9 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_SYSTEM_LOGOUT_XML_DESCRIPTION="The system logout plugin enables Joomla to redirect the user to the home page if they choose to logout while they are on a protected access page." +PLG_SYSTEM_LOGOUT="System - Logout" +PLG_SYSTEM_LOGOUT_REDIRECT="You have been redirected to the home page following logout." + diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_system_logout.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_logout.sys.ini new file mode 100644 index 00000000..4096422c --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_logout.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_SYSTEM_LOGOUT_XML_DESCRIPTION="The system logout plugin enables Joomla to redirect the user to the home page if they choose to logout while they are on a protected access page." +PLG_SYSTEM_LOGOUT="System - Logout" diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_system_logrotation.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_logrotation.ini new file mode 100644 index 00000000..9304feb5 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_logrotation.ini @@ -0,0 +1,11 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_SYSTEM_LOGROTATION="System - Log Rotation" +PLG_SYSTEM_LOGROTATION_XML_DESCRIPTION="This plugin periodically rotates system log files." +PLG_SYSTEM_LOGROTATION_CACHETIMEOUT_LABEL="Log Rotation (in days)" +PLG_SYSTEM_LOGROTATION_CACHETIMEOUT_DESC="How often should the logs be rotated." +PLG_SYSTEM_LOGROTATION_LOGSTOKEEP_DESC="The maximum number of old logs to keep." +PLG_SYSTEM_LOGROTATION_LOGSTOKEEP_LABEL="Maximum Logs" diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_system_logrotation.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_logrotation.sys.ini new file mode 100644 index 00000000..1a638664 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_logrotation.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_SYSTEM_LOGROTATION="System - Log Rotation" +PLG_SYSTEM_LOGROTATION_XML_DESCRIPTION="This plugin periodically rotates system log files." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_system_p3p.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_p3p.ini new file mode 100644 index 00000000..768fb7a7 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_p3p.ini @@ -0,0 +1,9 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_P3P_XML_DESCRIPTION="The system P3P policy plugin allows Joomla! to send a customised string of P3P policy tags in the HTTP header. This is required for the sessions to work on certain browsers, ie Internet Explorer 6 and 7." +PLG_SYSTEM_P3P="System - P3P Policy" +PLG_P3P_HEADER_DESCRIPTION="Enter your P3P policy tags. For more information consult The Platform for Privacy Preferences specification, https://www.w3.org/TR/P3P/" +PLG_P3P_HEADER_LABEL="P3P Tags" \ No newline at end of file diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_system_p3p.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_p3p.sys.ini new file mode 100644 index 00000000..40abbc9a --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_p3p.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_P3P_XML_DESCRIPTION="The system P3P policy plugin allows Joomla! to send a customised string of P3P policy tags in the HTTP header. This is required for the sessions to work on certain browsers, ie Internet Explorer 6 and 7." +PLG_SYSTEM_P3P="System - P3P Policy" diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_system_privacyconsent.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_privacyconsent.ini new file mode 100644 index 00000000..fd3a3eff --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_privacyconsent.ini @@ -0,0 +1,43 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_SYSTEM_PRIVACYCONSENT="System - Privacy Consent" +PLG_SYSTEM_PRIVACYCONSENT_BODY="

    The user consented to storing their user information using the IP address %s

    The user agent string of the user's browser was:
    %s

    This information was automatically recorded when the user submitted their details on the web site and checked the confirm box

    " +PLG_SYSTEM_PRIVACYCONSENT_CACHETIMEOUT_DESC="How often the check is performed" +PLG_SYSTEM_PRIVACYCONSENT_CACHETIMEOUT_LABEL="Periodic check (days)" +PLG_SYSTEM_PRIVACYCONSENT_CONSENT="User {username} consented to the privacy policy." +PLG_SYSTEM_PRIVACYCONSENT_CONSENTEXPIRATION_DESC="Number of days after which the privacy consent shall expire." +PLG_SYSTEM_PRIVACYCONSENT_CONSENTEXPIRATION_LABEL="Expiration" +; You can use the following merge codes for the EMAIL strings: +; [SITENAME] Site name, as set in Global Configuration. +; [URL] URL of the site's frontend page. +; [TOKENURL] URL of the remind page with the token prefilled. +; [FORMURL] URL of the remind page where the user can paste their token. +; [TOKEN] The remind token. +; \n Newline character. Use it to start a new line in the email. +PLG_SYSTEM_PRIVACYCONSENT_EMAIL_REMIND_BODY="Your Privacy Consent given at [URL] will expire in few days, you can renew the privacy consent for this website.\n\nIn order to do this, you can complete one of the following tasks:\n\n1. Visit the following URL: [TOKENURL]\n\n2. Copy your token from this email, visit the referenced URL, and paste your token into the form.\nURL: [FORMURL]\nToken: [TOKEN]\n\nPlease note that this token is only valid for this account." +PLG_SYSTEM_PRIVACYCONSENT_EMAIL_REMIND_SUBJECT="Privacy Consent at [SITENAME]" +PLG_SYSTEM_PRIVACYCONSENT_EXPIRATION_FIELDSET_LABEL="Expiration" +PLG_SYSTEM_PRIVACYCONSENT_FIELD_ARTICLE_DESC="Select the article from the list or create a new one." +PLG_SYSTEM_PRIVACYCONSENT_FIELD_ARTICLE_LABEL="Privacy Article" +PLG_SYSTEM_PRIVACYCONSENT_FIELD_DESC="Read the full privacy policy" +PLG_SYSTEM_PRIVACYCONSENT_FIELD_ENABLED_DESC="When enabled it performs checks for consent expiration" +PLG_SYSTEM_PRIVACYCONSENT_FIELD_ENABLED_LABEL="Enable" +PLG_SYSTEM_PRIVACYCONSENT_FIELD_ERROR="Agreement to the site's Privacy Policy is required." +PLG_SYSTEM_PRIVACYCONSENT_FIELD_LABEL="Privacy Policy" +PLG_SYSTEM_PRIVACYCONSENT_LABEL="Web Site Privacy" +PLG_SYSTEM_PRIVACYCONSENT_NOTE_FIELD_DEFAULT="By signing up to this web site and agreeing to the Privacy Policy you agree to this web site storing your information." +PLG_SYSTEM_PRIVACYCONSENT_NOTE_FIELD_DESC="A summary of the site's privacy policy. If left blank then the default message will be used." +PLG_SYSTEM_PRIVACYCONSENT_NOTE_FIELD_LABEL="Short Privacy Policy" +PLG_SYSTEM_PRIVACYCONSENT_NOTIFICATION_USER_PRIVACY_EXPIRED_SUBJECT="Privacy Consent Expired" +PLG_SYSTEM_PRIVACYCONSENT_NOTIFICATION_USER_PRIVACY_EXPIRED_MESSAGE="Privacy consent has expired for %1$s." +PLG_SYSTEM_PRIVACYCONSENT_OPTION_AGREE="I agree" +PLG_SYSTEM_PRIVACYCONSENT_REDIRECT_MESSAGE_DEFAULT="Please confirm that you consent to this web site storing your information by agreeing to the privacy policy." +PLG_SYSTEM_PRIVACYCONSENT_REDIRECT_MESSAGE_DESC="Custom message to be displayed on redirect. If left blank then the default message will be used." +PLG_SYSTEM_PRIVACYCONSENT_REDIRECT_MESSAGE_LABEL="Redirect Message" +PLG_SYSTEM_PRIVACYCONSENT_REMINDBEFORE_DESC="Number of days to send a reminder before the expiration of the privacy consent." +PLG_SYSTEM_PRIVACYCONSENT_REMINDBEFORE_LABEL="Remind" +PLG_SYSTEM_PRIVACYCONSENT_SUBJECT="Privacy Policy" +PLG_SYSTEM_PRIVACYCONSENT_XML_DESCRIPTION="Basic plugin to request user's consent to the site's privacy policy. Existing users who have not consented yet will be redirected on login to update their profile." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_system_privacyconsent.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_privacyconsent.sys.ini new file mode 100644 index 00000000..ad3fa0b5 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_privacyconsent.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_SYSTEM_PRIVACYCONSENT="System - Privacy Consent" +PLG_SYSTEM_PRIVACYCONSENT_XML_DESCRIPTION="Basic plugin to request user's consent to the site's privacy policy. Existing users who have not consented yet will be redirected on login to update their profile." \ No newline at end of file diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_system_redirect.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_redirect.ini new file mode 100644 index 00000000..235f3669 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_redirect.ini @@ -0,0 +1,18 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_SYSTEM_REDIRECT="System - Redirect" +PLG_SYSTEM_REDIRECT_ERROR_UPDATING_DATABASE="An error occurred while updating the database." +PLG_SYSTEM_REDIRECT_FIELD_COLLECT_URLS_DESC="This option controls the collection of URLs. This is useful to avoid unnecessary load on the database." +PLG_SYSTEM_REDIRECT_FIELD_COLLECT_URLS_LABEL="Collect URLs" +PLG_SYSTEM_REDIRECT_FIELD_EXCLUDE_URLS_DESC="Define regular expressions or terms which should be excluded in saving." +PLG_SYSTEM_REDIRECT_FIELD_EXCLUDE_URLS_LABEL="Exclude URLs" +PLG_SYSTEM_REDIRECT_FIELD_EXCLUDE_URLS_REGEXP_DESC="Should the term be handled as regular expression." +PLG_SYSTEM_REDIRECT_FIELD_EXCLUDE_URLS_REGEXP_LABEL="Regular Expression" +PLG_SYSTEM_REDIRECT_FIELD_EXCLUDE_URLS_TERM_DESC="A regular expression or a term which should be excluded." +PLG_SYSTEM_REDIRECT_FIELD_EXCLUDE_URLS_TERM_LABEL="Term" +PLG_SYSTEM_REDIRECT_FIELD_STORE_FULL_URL_DESC="Save the expired URL as absolute (include domain) or relative (exclude domain)." +PLG_SYSTEM_REDIRECT_FIELD_STORE_FULL_URL_LABEL="Include Domain Name in Expired URL" +PLG_SYSTEM_REDIRECT_XML_DESCRIPTION="The system redirect plugin enables the Joomla Redirect system to catch missing pages and redirect users." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_system_redirect.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_redirect.sys.ini new file mode 100644 index 00000000..a45e8a39 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_redirect.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_SYSTEM_REDIRECT="System - Redirect" +PLG_SYSTEM_REDIRECT_XML_DESCRIPTION="The system redirect plugin enables the Joomla Redirect system to catch missing pages and redirect users." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_system_remember.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_remember.ini new file mode 100644 index 00000000..89f9d270 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_remember.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_REMEMBER_XML_DESCRIPTION="Provides remember me functionality. The cookie authentication plugin must be enabled for this plugin to function." +PLG_SYSTEM_REMEMBER="System - Remember Me" diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_system_remember.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_remember.sys.ini new file mode 100644 index 00000000..6fc3d8cf --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_remember.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_REMEMBER_XML_DESCRIPTION="Provides remember me functionality." +PLG_SYSTEM_REMEMBER="System - Remember Me" diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_system_sef.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_sef.ini new file mode 100644 index 00000000..6e75b611 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_sef.ini @@ -0,0 +1,9 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_SEF_XML_DESCRIPTION="Adds SEF support to links in the document. It operates directly on the HTML and does not require a special tag." +PLG_SYSTEM_SEF="System - SEF" +PLG_SEF_DOMAIN_LABEL="Site Domain" +PLG_SEF_DOMAIN_DESCRIPTION="If your site can be accessed through more than one domain enter the preferred (sometimes referred to as canonical) domain here.
    Note: https://example.com and https://www.example.com are different domains." \ No newline at end of file diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_system_sef.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_sef.sys.ini new file mode 100644 index 00000000..eb72cae2 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_sef.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_SEF_XML_DESCRIPTION="Adds SEF support to links in the document. It operates directly on the HTML and does not require a special tag." +PLG_SYSTEM_SEF="System - SEF" \ No newline at end of file diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_system_sessiongc.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_sessiongc.ini new file mode 100644 index 00000000..3d33eed6 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_sessiongc.ini @@ -0,0 +1,15 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_SYSTEM_SESSIONGC="System - Session Data Purge" +PLG_SYSTEM_SESSIONGC_ENABLE_SESSION_GC_DESC="When enabled, this plugin will attempt to purge expired data based on the frequency calculated by the probability and divisor." +PLG_SYSTEM_SESSIONGC_ENABLE_SESSION_GC_LABEL="Enable Session Data Cleanup" +PLG_SYSTEM_SESSIONGC_ENABLE_SESSION_METADATA_GC_DESC="When enabled, this plugin will clean optional session metadata from the database. Note that this operation will not run when the database handler is in use as that data is cleared as part of the Session Data Cleanup operation." +PLG_SYSTEM_SESSIONGC_ENABLE_SESSION_METADATA_GC_LABEL="Enable Session Metadata Cleanup" +PLG_SYSTEM_SESSIONGC_GC_DIVISOR_DESC="In combination with the probability field, these two fields are used to determine the frequency of the session data cleanup operation being triggered on a request. The probability is calculated by using probability/divisor, e.g. 1/100 means there is a 1% chance that the process runs on each request." +PLG_SYSTEM_SESSIONGC_GC_DIVISOR_LABEL="Divisor" +PLG_SYSTEM_SESSIONGC_GC_PROBABILITY_DESC="In combination with the divisor field, these two fields are used to determine the frequency of the session data cleanup operation being triggered on a request." +PLG_SYSTEM_SESSIONGC_GC_PROBABILITY_LABEL="Probability" +PLG_SYSTEM_SESSIONGC_XML_DESCRIPTION="System Plugin that purges expired data and metadata depending on the session handler set in Global Configuration." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_system_sessiongc.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_sessiongc.sys.ini new file mode 100644 index 00000000..cca36002 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_sessiongc.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_SYSTEM_SESSIONGC="System - Session Data Purge" +PLG_SYSTEM_SESSIONGC_XML_DESCRIPTION="System Plugin that purges expired data and metadata depending on the session handler set in Global Configuration." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_system_stats.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_stats.ini new file mode 100644 index 00000000..0a4ac2af --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_stats.ini @@ -0,0 +1,33 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_SYSTEM_STATS="System - Joomla! Statistics" +PLG_SYSTEM_STATS_BTN_NEVER_SEND="Never" +PLG_SYSTEM_STATS_BTN_SEND_ALWAYS="Always" +PLG_SYSTEM_STATS_BTN_SEND_NOW="Once" +; The following two strings are deprecated for 4.0 +PLG_SYSTEM_STATS_DEBUG_DESC="Enable debug for testing purposes. Statistics will be sent on every page load." +PLG_SYSTEM_STATS_DEBUG_LABEL="Debug" +PLG_SYSTEM_STATS_INTERVAL_DESC="Statistics will be sent every X hours. The default is 12." +PLG_SYSTEM_STATS_INTERVAL_LABEL="Interval (hours)" +PLG_SYSTEM_STATS_LABEL_CMS_VERSION="CMS Version" +PLG_SYSTEM_STATS_LABEL_DB_TYPE="DB Type" +PLG_SYSTEM_STATS_LABEL_DB_VERSION="DB Version" +PLG_SYSTEM_STATS_LABEL_MESSAGE_TITLE="Joomla! would like your permission to collect some basic statistics." +PLG_SYSTEM_STATS_LABEL_PHP_VERSION="PHP Version" +PLG_SYSTEM_STATS_LABEL_SERVER_OS="Server OS" +PLG_SYSTEM_STATS_LABEL_UNIQUE_ID="Unique ID" +PLG_SYSTEM_STATS_MODE_DESC="Select the way that you want the statistics to be sent." +PLG_SYSTEM_STATS_MODE_LABEL="Mode" +PLG_SYSTEM_STATS_MODE_OPTION_ALWAYS_SEND="Always send" +PLG_SYSTEM_STATS_MODE_OPTION_NEVER_SEND="Never send" +PLG_SYSTEM_STATS_MODE_OPTION_ON_DEMAND="On demand" +PLG_SYSTEM_STATS_MSG_ALLOW_SENDING_DATA="Enable Joomla Statistics?" +PLG_SYSTEM_STATS_MSG_JOOMLA_WANTS_TO_SEND_DATA="To better understand our install base and end user environments it is helpful if you send some site information back to a Joomla! controlled central server. No identifying data is captured at any point. You can change these settings later from Plugins > System - Joomla! Statistics." +PLG_SYSTEM_STATS_MSG_WHAT_DATA_WILL_BE_SENT="Select here to see the information that will be sent." +PLG_SYSTEM_STATS_RESET_UNIQUE_ID="Reset Unique ID" +PLG_SYSTEM_STATS_UNIQUE_ID_DESC="An identifier that allows the Joomla! project to count unique installs of the plugin. This is sent with the statistics back to the server." +PLG_SYSTEM_STATS_UNIQUE_ID_LABEL="Unique ID" +PLG_SYSTEM_STATS_XML_DESCRIPTION="System Plugin that sends environment statistics to a server controlled by the Joomla! project for statistical analysis. Statistics sent include PHP version, CMS version, Database type, Database version and Server type." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_system_stats.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_stats.sys.ini new file mode 100644 index 00000000..a73f3194 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_stats.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_SYSTEM_STATS="System - Joomla! Statistics" +PLG_SYSTEM_STATS_XML_DESCRIPTION="System Plugin that sends environment statistics to a server controlled by the Joomla! project for statistical analysis. Statistics sent include PHP version, CMS version, Database type, Database version and Server type." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_system_updatenotification.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_updatenotification.ini new file mode 100644 index 00000000..0aef7a42 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_updatenotification.ini @@ -0,0 +1,25 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_SYSTEM_UPDATENOTIFICATION="System - Joomla! Update Notification" +PLG_SYSTEM_UPDATENOTIFICATION_EMAIL_LBL="Super User Emails" +PLG_SYSTEM_UPDATENOTIFICATION_EMAIL_DESC="A comma separated list of the email addresses which will receive the update notification emails. The addresses in the list MUST belong to existing users of your site who have the Super User privilege. If none of the listed emails belongs to Super Users, or if it's left blank, all Super Users of this site will receive the update notification email." +; You can use the following merge codes: +; [NEWVERSION] New Joomla! version, e.g. 1.2.3 +; [CURVERSION] Currently installed Joomla! version, e.g. 1.2.0 +; [SITENAME] Site name, as set in Global Configuration. +; [URL] URL of the site's frontend page. +; [LINK] Update URL (link to com_joomlaupdate, will request login if the Super User isn't already logged in). +; [RELEASENEWS] URL to the release news on joomla.org +; \n Newline character. Use it to start a new line in the email. +PLG_SYSTEM_UPDATENOTIFICATION_EMAIL_SUBJECT="Joomla! Update available for [SITENAME] – [URL]" +PLG_SYSTEM_UPDATENOTIFICATION_EMAIL_BODY="This email IS NOT sent by Joomla.org. It is sent automatically by your own site,\n[SITENAME] - [URL] \n\n================================================================================\nUPDATE INFORMATION\n================================================================================\n\nYour site has discovered that there is an updated version of Joomla! available for download.\n\nJoomla! version currently installed: [CURVERSION]\nJoomla! version available for installation: [NEWVERSION]\n\nThis email is sent to you by your site to remind you of this fact.\nThe Joomla! project will never contact you directly about available updates of Joomla! on your site.\n\n================================================================================\nUPDATE INSTRUCTIONS\n================================================================================\n\nTo install the update on [SITENAME] please select the following link. (If the URL is not a link, copy & paste it to your browser).\n\nUpdate link: [LINK]\n\nRelease News can be found here: [RELEASENEWS]\n\n================================================================================\nWHY AM I RECEIVING THIS EMAIL?\n================================================================================\n\nThis email has been automatically sent by a plugin provided by Joomla!, the software which powers your site.\nThis plugin looks for updated versions of Joomla! and sends an email notification to its administrators.\nYou will receive several similar emails from your site until you either update the software or disable these emails.\n\nTo disable these emails, please unpublish the 'System - Joomla! Update Notification' plugin in the Plugin Manager on your site.\n\nIf you do not understand what Joomla! is and what you need to do please do not contact the Joomla! project.\nThey are NOT sending you this email and they cannot help you. Instead, please contact the person who built or manages your site.\n\nIf you are the person who built or manages your website, please note that this plugin may have been activated automatically when you installed or updated Joomla! on your site.\n\n================================================================================\nWHO SENT ME THIS EMAIL?\n================================================================================\n\nThis email is sent to you by your own site, [SITENAME]" +PLG_SYSTEM_UPDATENOTIFICATION_LANGUAGE_OVERRIDE_LBL="Email Language" +PLG_SYSTEM_UPDATENOTIFICATION_LANGUAGE_OVERRIDE_DESC="Select a language for the update notification emails. Set to Auto to send them in the site language at the time." +PLG_SYSTEM_UPDATENOTIFICATION_LANGUAGE_OVERRIDE_NONE="Auto" +PLG_SYSTEM_UPDATENOTIFICATION_POSTINSTALL_UPDATECACHETIME="The Joomla! Update Notification will not run in this configuration" +PLG_SYSTEM_UPDATENOTIFICATION_POSTINSTALL_UPDATECACHETIME_BODY="In your Installer Configuration you have set the Option Update Cache (in Hours) to 0 this means that Joomla is not caching the Update. This means an email should be sent on every page visit but this is not possible. Please increase the value (6 is default) or confirm that the Joomla! Update Notification will never send you mails." +PLG_SYSTEM_UPDATENOTIFICATION_POSTINSTALL_UPDATECACHETIME_ACTION="Set it back to the default setting (6 Hours)" +PLG_SYSTEM_UPDATENOTIFICATION_XML_DESCRIPTION="This plugin periodically checks for the availability of new Joomla! versions. When one is found it will send you an email, reminding you to update Joomla!. Pro Tip: You can customise the email message by overriding the language string keys PLG_SYSTEM_UPDATENOTIFICATION_EMAIL_SUBJECT and PLG_SYSTEM_UPDATENOTIFICATION_EMAIL_BODY." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_system_updatenotification.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_updatenotification.sys.ini new file mode 100644 index 00000000..37b3c552 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_updatenotification.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_SYSTEM_UPDATENOTIFICATION="System - Joomla! Update Notification" +PLG_SYSTEM_UPDATENOTIFICATION_XML_DESCRIPTION="This plugin periodically checks for the availability of new Joomla! versions. When one is found it will send you an email, reminding you to update Joomla!. Pro Tip: You can customise the email message by overriding the language string keys PLG_SYSTEM_UPDATENOTIFICATION_EMAIL_SUBJECT and PLG_SYSTEM_UPDATENOTIFICATION_EMAIL_BODY." \ No newline at end of file diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_system_weblinks.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_weblinks.ini new file mode 100644 index 00000000..f38ccb9b --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_weblinks.ini @@ -0,0 +1,8 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; Note : All ini files need to be saved as UTF-8 + +PLG_SYSTEM_WEBLINKS="System - Web Links" +PLG_SYSTEM_WEBLINKS_STATISTICS="Web Links" +PLG_SYSTEM_WEBLINKS_XML_DESCRIPTION="This plugin returns statistical information about Joomla! Web Links." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_system_weblinks.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_weblinks.sys.ini new file mode 100644 index 00000000..f706d5c7 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_system_weblinks.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; Note : All ini files need to be saved as UTF-8 + +PLG_SYSTEM_WEBLINKS="System - Web Links" +PLG_SYSTEM_WEBLINKS_XML_DESCRIPTION="This plugin returns statistical information about Joomla! Web Links." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_twofactorauth_totp.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_twofactorauth_totp.ini new file mode 100644 index 00000000..703447db --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_twofactorauth_totp.ini @@ -0,0 +1,36 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_TWOFACTORAUTH_TOTP="Two Factor Authentication - Google Authenticator" +PLG_TWOFACTORAUTH_TOTP_ERR_VALIDATIONFAILED="You did not enter a valid security code. Please check your Google Authenticator setup and make sure that the time on your device matches the time on the site." +PLG_TWOFACTORAUTH_TOTP_INTRO="This feature allows you to use Google Authenticator, or a compatible application such as FreeOTP, for two factor authentication. In addition to your username and password you will also need to provide a six digit security code to be able to login to this site. The security code is rotated every 30 seconds. This provides extra protection against hackers logging in to your account even if they were able to get hold of your password." +PLG_TWOFACTORAUTH_TOTP_METHOD_TITLE="Google Authenticator" +PLG_TWOFACTORAUTH_TOTP_POSTINSTALL_TITLE="Two Factor Authentication is Available" +PLG_TWOFACTORAUTH_TOTP_POSTINSTALL_BODY="

    Joomla! comes with a built-in two factor authentication system. It secures your site login with a secondary secret code that's changing every 30 seconds. You can use your mobile device and the Google Authenticator app to produce that code.

    By selecting the button below:

    • Joomla! will enable the two factor authentication plugins
    • Two Factor Authentication is going to be available for all users.
    • Each user can configure Two Factor Authentication in User Details.
    • You can always disable Two Factor Authentication plugin, or configure it for Backend usage only.
    • You will be taken to your user profile page where you can find more information on two factor authentication and enable it for your user account.
    " +PLG_TWOFACTORAUTH_TOTP_POSTINSTALL_ACTION="Enable two factor authentication" +PLG_TWOFACTORAUTH_TOTP_SECTION_ADMIN="Administrator (Backend)" +PLG_TWOFACTORAUTH_TOTP_SECTION_BOTH="Both" +PLG_TWOFACTORAUTH_TOTP_SECTION_DESC="In which sections of your site do you want to enable two factor authentication?" +PLG_TWOFACTORAUTH_TOTP_SECTION_LABEL="Site Section" +PLG_TWOFACTORAUTH_TOTP_SECTION_SITE="Site (Frontend)" +PLG_TWOFACTORAUTH_TOTP_STEP1_HEAD="Step 1 - Get Google Authenticator" +PLG_TWOFACTORAUTH_TOTP_STEP1_ITEM1="Official Google Authenticator app for Android, iOS and BlackBerry" +; Check the URL and change the part hl=en to your language tag if this is available (example hl=de; hl=zh-cn; hl=zh-tw) +PLG_TWOFACTORAUTH_TOTP_STEP1_ITEM1_LINK="https://support.google.com/accounts/bin/answer.py?hl=en&answer=1066447" +PLG_TWOFACTORAUTH_TOTP_STEP1_ITEM2="Compatible clients for other devices and operating system (listed in Wikipedia)." +; Change and check this link if there is a translation in your language available. (current: German, Spanish, French, Japanese, Polish) +PLG_TWOFACTORAUTH_TOTP_STEP1_ITEM2_LINK="https://en.wikipedia.org/wiki/Google_Authenticator#Implementation" +PLG_TWOFACTORAUTH_TOTP_STEP1_TEXT="Download and install Google Authenticator, or a compatible application such as FreeOTP, on your smartphone or desktop. Use one of the following:" +PLG_TWOFACTORAUTH_TOTP_STEP1_WARN="Please remember to sync your device's clock with a time-server. Time drift in your device may cause an inability to log in to your site." +PLG_TWOFACTORAUTH_TOTP_STEP2_ACCOUNT="Account" +PLG_TWOFACTORAUTH_TOTP_STEP2_ALTTEXT="Alternatively, you can scan the following QR code in Google Authenticator." +PLG_TWOFACTORAUTH_TOTP_STEP2_HEAD="Step 2 - Set up" +PLG_TWOFACTORAUTH_TOTP_STEP2_KEY="Key" +PLG_TWOFACTORAUTH_TOTP_STEP2_RESET="If you want to change the key, disable the two factor authentication. When you try enabling it again it will generate a new key." +PLG_TWOFACTORAUTH_TOTP_STEP2_TEXT="You will need to enter the following information to Google Authenticator or a compatible app." +PLG_TWOFACTORAUTH_TOTP_STEP3_HEAD="Step 3 - Activate Two Factor Authentication" +PLG_TWOFACTORAUTH_TOTP_STEP3_SECURITYCODE="Security Code" +PLG_TWOFACTORAUTH_TOTP_STEP3_TEXT="To verify that everything is set up properly, please enter the security code displayed in Google Authenticator in the field below. Afterwards, please save your user profile. If the code is correct, the Two Factor Authentication feature will be enabled." +PLG_TWOFACTORAUTH_TOTP_XML_DESCRIPTION="Allows users on your site to use two factor authentication using Google Authenticator or other compatible time-based One Time Password generators such as FreeOTP. To use two factor authentication please edit the user profile and enable two factor authentication." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_twofactorauth_totp.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_twofactorauth_totp.sys.ini new file mode 100644 index 00000000..b8c5f101 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_twofactorauth_totp.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_TWOFACTORAUTH_TOTP="Two Factor Authentication - Google Authenticator" +PLG_TWOFACTORAUTH_TOTP_XML_DESCRIPTION="Allows users on your site to use two factor authentication using Google Authenticator or other compatible time-based One Time Password generators such as FreeOTP. To use two factor authentication please edit the user profile and enable two factor authentication." \ No newline at end of file diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_twofactorauth_yubikey.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_twofactorauth_yubikey.ini new file mode 100644 index 00000000..5bd6b6b6 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_twofactorauth_yubikey.ini @@ -0,0 +1,22 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_TWOFACTORAUTH_YUBIKEY="Two Factor Authentication - YubiKey" + +PLG_TWOFACTORAUTH_YUBIKEY_ERR_VALIDATIONFAILED="You did not enter a valid YubiKey secret code or the YubiCloud servers are unreachable at this time." +PLG_TWOFACTORAUTH_YUBIKEY_INTRO="This feature allows you to use a YubiKey secure hardware token for two factor authentication. In addition to your username and password you will also need to insert your YubiKey into your computer's USB port, select inside the Secret Key area of the site's login area and touch YubiKey's gold disk. The secret code generated by your YubiKey is unique to your device and changes constantly. This provides extra protection against hackers logging in to your account even if they were able to get hold of your password." +PLG_TWOFACTORAUTH_YUBIKEY_METHOD_TITLE="YubiKey" +PLG_TWOFACTORAUTH_TOTP_RESET_HEAD="Your YubiKey is already linked to your user account." +PLG_TWOFACTORAUTH_TOTP_RESET_TEXT="Your YubiKey is already linked to your user account. If you want to unlink your YubiKey from your user account or use another YubiKey, please first disable two factor authentication and save your user profile. Then come back to this user profile page and re-activate two factor authentication with the YubiKey method." +PLG_TWOFACTORAUTH_YUBIKEY_SECTION_ADMIN="Administrator (Backend)" +PLG_TWOFACTORAUTH_YUBIKEY_SECTION_BOTH="Both" +PLG_TWOFACTORAUTH_YUBIKEY_SECTION_DESC="In which sections of your site do you want to enable two factor authentication?" +PLG_TWOFACTORAUTH_YUBIKEY_SECTION_LABEL="Site Section" +PLG_TWOFACTORAUTH_YUBIKEY_SECTION_SITE="Site (Frontend)" +PLG_TWOFACTORAUTH_YUBIKEY_SECURITYCODE="Security Code" +PLG_TWOFACTORAUTH_YUBIKEY_STEP1_HEAD="Set up" +PLG_TWOFACTORAUTH_YUBIKEY_STEP1_TEXT="Please insert your YubiKey device into your computer's USB port. Select the Security Code field below. Then touch the gold disk on your YubiKey device for one second. Afterwards, please save your user profile. If the code generated by your YubiKey is validated by YubiCloud the Two Factor Authentication feature will be enabled and this YubiKey will be linked with your user account." +PLG_TWOFACTORAUTH_YUBIKEY_XML_DESCRIPTION="Allows users on your site to use two factor authentication using a YubiKey secure hardware token. Users need their own Yubikey available from https://www.yubico.com/. To use two factor authentication users have to edit their user profile and enable two factor authentication." + diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_twofactorauth_yubikey.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_twofactorauth_yubikey.sys.ini new file mode 100644 index 00000000..316f965a --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_twofactorauth_yubikey.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_TWOFACTORAUTH_YUBIKEY="Two Factor Authentication - YubiKey" +PLG_TWOFACTORAUTH_YUBIKEY_XML_DESCRIPTION="Allows users on your site to use two factor authentication using a YubiKey secure hardware token. Users need their own Yubikey available from https://www.yubico.com/. To use two factor authentication users have to edit their user profile and enable two factor authentication." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_user_contactcreator.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_user_contactcreator.ini new file mode 100644 index 00000000..0a79ad34 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_user_contactcreator.ini @@ -0,0 +1,14 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_CONTACTCREATOR_ERR_FAILED_CREATING_CONTACT="Automatic contact creation failed. Please contact a site administrator." +PLG_CONTACTCREATOR_ERR_NO_CATEGORY="Contact automatic creation failed because contact category is not set!" +PLG_CONTACTCREATOR_FIELD_AUTOMATIC_WEBPAGE_DESC="A formatted string to automatically generate a contact's web page. [name] is replaced with the name, [username] is replaced with the username, [userid] is replaced with the user ID and [email] is replaced with the email." +PLG_CONTACTCREATOR_FIELD_AUTOMATIC_WEBPAGE_LABEL="Automatic Webpage" +PLG_CONTACTCREATOR_FIELD_AUTOPUBLISH_DESC="Optionally have the contact default to published or unpublished." +PLG_CONTACTCREATOR_FIELD_AUTOPUBLISH_LABEL="Automatically Publish the Contact" +PLG_CONTACTCREATOR_FIELD_CATEGORY_DESC="Category to assign contacts to by default." +PLG_CONTACTCREATOR_XML_DESCRIPTION="Plugin to automatically create contact information for new users." +PLG_USER_CONTACTCREATOR="User - Contact Creator" diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_user_contactcreator.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_user_contactcreator.sys.ini new file mode 100644 index 00000000..d1d88cea --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_user_contactcreator.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_CONTACTCREATOR_XML_DESCRIPTION="Plugin to automatically create contact information for new users." +PLG_USER_CONTACTCREATOR="User - Contact Creator" diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_user_joomla.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_user_joomla.ini new file mode 100644 index 00000000..5ebf8026 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_user_joomla.ini @@ -0,0 +1,20 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_USER_JOOMLA="User - Joomla!" +PLG_USER_JOOMLA_FIELD_AUTOREGISTER_DESC="Automatically create Registered Users where possible." +PLG_USER_JOOMLA_FIELD_AUTOREGISTER_LABEL="Auto-create Users" +PLG_USER_JOOMLA_FIELD_FORCELOGOUT_DESC="Set to No to disable this." +PLG_USER_JOOMLA_FIELD_FORCELOGOUT_LABEL="Force Logout for all Sessions?" +PLG_USER_JOOMLA_FIELD_MAILTOUSER_DESC="When an administrator creates a user account, this determines if an email, which has their username and password, is sent to the user." +PLG_USER_JOOMLA_FIELD_MAILTOUSER_LABEL="Notification Mail to User" +PLG_USER_JOOMLA_FIELD_STRONG_PASSWORDS_DESC="If set to yes, use the bcrypt encryption method if available in this version of PHP." +PLG_USER_JOOMLA_FIELD_STRONG_PASSWORDS_LABEL="Strong Passwords" +PLG_USER_JOOMLA_NEW_USER_EMAIL_BODY="Hello %s,\n\n\nYou have been added as a User to %s by an Administrator.\n\nThis email has your username and password to log in to %s\n\nUsername: %s\nPassword: %s\n\n\nPlease do not respond to this message as it is automatically generated and is for information purposes only." +PLG_USER_JOOMLA_NEW_USER_EMAIL_SUBJECT="New User Details" +PLG_USER_JOOMLA_POSTINSTALL_STRONGPW_BTN="Enable Strong Password Encryption" +PLG_USER_JOOMLA_POSTINSTALL_STRONGPW_TEXT="As a security feature, Joomla allows you to switch to strong password encryption.
    To turn strong passwords on select the button below. Alternatively you can edit the User - Joomla plugin and change the strong password setting to On.
    Before enabling you should verify that all third party registration/login, user management or bridge extensions installed on your site support this strong password encryption." +PLG_USER_JOOMLA_POSTINSTALL_STRONGPW_TITLE="Strong passwords" +PLG_USER_JOOMLA_XML_DESCRIPTION="Handles Joomla's default User synchronisation.
    Warning! You must have enabled at least one plugin that handles the user session management or you will lose all access to your site." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_user_joomla.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_user_joomla.sys.ini new file mode 100644 index 00000000..cba158ab --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_user_joomla.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_USER_JOOMLA="User - Joomla!" +PLG_USER_JOOMLA_XML_DESCRIPTION="Handles Joomla's default User synchronisation.
    Warning! You must have enabled at least one plugin that handles the user session management or you will lose all access to your site." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_user_profile.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_user_profile.ini new file mode 100644 index 00000000..2fa2a079 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_user_profile.ini @@ -0,0 +1,46 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +COM_CONTENT_CHANGE_ARTICLE="Select or Change article" +COM_CONTENT_CHANGE_ARTICLE_BUTTON="Select/Change" +COM_CONTENT_SELECT_AN_ARTICLE="Select an Article" +PLG_USER_PROFILE="User - Profile" +PLG_USER_PROFILE_ERROR_INVALID_DOB="The date of birth you entered is invalid. Please enter a valid date." +PLG_USER_PROFILE_ERROR_INVALID_DOB_FUTURE_DATE="The date of birth you entered is in the future." +PLG_USER_PROFILE_FIELD_ABOUT_ME_DESC="Choose an option for the field About Me." +PLG_USER_PROFILE_FIELD_ABOUT_ME_LABEL="About Me" +PLG_USER_PROFILE_FIELD_ADDRESS1_DESC="Choose an option for the field Address1." +PLG_USER_PROFILE_FIELD_ADDRESS1_LABEL="Address 1" +PLG_USER_PROFILE_FIELD_ADDRESS2_DESC="Choose an option for the field Address2." +PLG_USER_PROFILE_FIELD_ADDRESS2_LABEL="Address 2" +PLG_USER_PROFILE_FIELD_CITY_DESC="Choose an option for the field City." +PLG_USER_PROFILE_FIELD_CITY_LABEL="City" +PLG_USER_PROFILE_FIELD_COUNTRY_DESC="Choose an option for the field Country." +PLG_USER_PROFILE_FIELD_COUNTRY_LABEL="Country" +PLG_USER_PROFILE_FIELD_DOB_DESC="Choose an option for the field Date of Birth." +PLG_USER_PROFILE_FIELD_DOB_LABEL="Date of Birth" +PLG_USER_PROFILE_FIELD_FAVORITE_BOOK_DESC="Choose an option for the field Favourite Book." +PLG_USER_PROFILE_FIELD_FAVORITE_BOOK_LABEL="Favourite Book" +PLG_USER_PROFILE_FIELD_NAME_PROFILE_REQUIRE_USER="User profile fields for profile edit form" +PLG_USER_PROFILE_FIELD_NAME_REGISTER_REQUIRE_USER="User profile fields for registration and administrator user forms" +PLG_USER_PROFILE_FIELD_PHONE_DESC="Choose an option for the field Phone." +PLG_USER_PROFILE_FIELD_PHONE_LABEL="Phone" +PLG_USER_PROFILE_FIELD_POSTAL_CODE_DESC="Choose an option for the field Postal/ZIP Code." +PLG_USER_PROFILE_FIELD_POSTAL_CODE_LABEL="Postal/ZIP Code" +PLG_USER_PROFILE_FIELD_REGION_DESC="Choose an option for the field Region." +PLG_USER_PROFILE_FIELD_REGION_LABEL="Region" +PLG_USER_PROFILE_FIELD_TOS_ARTICLE_DESC="Select the desired Terms of Service article from the list." +PLG_USER_PROFILE_FIELD_TOS_ARTICLE_LABEL="Select TOS Article" +PLG_USER_PROFILE_FIELD_TOS_DESC="Agree to terms of service." +PLG_USER_PROFILE_FIELD_TOS_DESC_SITE="Please read the Terms of Service. You will not be able to register if you do not agree with them." +PLG_USER_PROFILE_FIELD_TOS_LABEL="Terms of Service" +PLG_USER_PROFILE_FIELD_WEB_SITE_DESC="Choose an option for the field website." +PLG_USER_PROFILE_FIELD_WEB_SITE_LABEL="Website" +PLG_USER_PROFILE_FILL_FIELD_DESC_SITE="If required, please fill this field." +PLG_USER_PROFILE_OPTION_AGREE="Agree" +PLG_USER_PROFILE_SLIDER_LABEL="User Profile" +; Adapt the following string to the format you entered in the 'DATE_FORMAT_CALENDAR_DATE' +PLG_USER_PROFILE_SPACER_DOB="The date of birth entered should use the format Year-Month-Day, ie 0000-00-00" +PLG_USER_PROFILE_XML_DESCRIPTION="User Profile Plugin" diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_user_profile.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_user_profile.sys.ini new file mode 100644 index 00000000..e26eeaeb --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_user_profile.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_USER_PROFILE="User - Profile" +PLG_USER_PROFILE_XML_DESCRIPTION="User Profile Plugin" diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_user_terms.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_user_terms.ini new file mode 100644 index 00000000..d75c4b13 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_user_terms.ini @@ -0,0 +1,19 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_USER_TERMS="User - Terms and Conditions" +PLG_USER_TERMS_FIELD_ARTICLE_DESC="Select the article from the list or create a new one." +PLG_USER_TERMS_FIELD_ARTICLE_LABEL="Terms & Conditions Article" +PLG_USER_TERMS_FIELD_DESC="Read the full terms and conditions." +PLG_USER_TERMS_FIELD_ERROR="Agreement to the site's Terms & Conditions is required." +PLG_USER_TERMS_FIELD_LABEL="Terms & Conditions" +PLG_USER_TERMS_LABEL="Terms & Conditions" +PLG_USER_TERMS_LOGGING_CONSENT_TO_TERMS="User {username} consented to the terms and conditions during registration." +PLG_USER_TERMS_NOTE_FIELD_DEFAULT="By signing up to this web site you accept the Terms & Conditions." +PLG_USER_TERMS_NOTE_FIELD_DESC="A summary of the site's terms & conditions. If left blank then the default message will be used." +PLG_USER_TERMS_NOTE_FIELD_LABEL="Short Terms & Conditions" +PLG_USER_TERMS_OPTION_AGREE="I agree" +PLG_USER_TERMS_SUBJECT="Privacy Policy" +PLG_USER_TERMS_XML_DESCRIPTION="Basic plugin to request user's consent to the site's terms and conditions." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.plg_user_terms.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.plg_user_terms.sys.ini new file mode 100644 index 00000000..051fba10 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.plg_user_terms.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_USER_TERMS="User - Terms and Conditions" +PLG_USER_TERMS_XML_DESCRIPTION="Basic plugin to request user's consent to the site's terms and conditions." \ No newline at end of file diff --git a/Sites/pages/administrator/language/en-GB/en-GB.tpl_hathor.ini b/Sites/pages/administrator/language/en-GB/en-GB.tpl_hathor.ini new file mode 100644 index 00000000..86389cc8 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.tpl_hathor.ini @@ -0,0 +1,33 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +HATHOR="Hathor Administrator template" +TPL_HATHOR_ALTERNATE_MENU_DESC="Use the alternative menu which integrates mouse and keyboard. JavaScript Required. The regular menu for Hathor is accessible with or without JavaScript, but leaves the mouse and keyboard independent." +TPL_HATHOR_ALTERNATE_MENU_LABEL="Alternative Menu" +TPL_HATHOR_BOLD_TEXT_DESC="Use bold text." +TPL_HATHOR_BOLD_TEXT_LABEL="Bold Text" +TPL_HATHOR_CHANGED_DEFAULT_TEMPLATE_TO_ISIS="We have set the default administrator template style to '%s'" +TPL_HATHOR_CHECKMARK_ALL="Checkmark All" +TPL_HATHOR_COLOUR_CHOICE_BLUE="Blue" +TPL_HATHOR_COLOUR_CHOICE_DESC="Select the colour palette to use with the template. You can use this option to select a high contrast version or use it to create custom branding." +TPL_HATHOR_COLOUR_CHOICE_LABEL="Select Colour" +TPL_HATHOR_COLOUR_CHOICE_STANDARD="Standard" +TPL_HATHOR_COLOUR_CHOICE_HIGH_CONTRAST="High Contrast" +TPL_HATHOR_COLOUR_CHOICE_BROWN="Brown" +TPL_HATHOR_COM_MENUS_MENU="Menu" +TPL_HATHOR_COM_MODULES_CUSTOM_POSITION_LABEL="Select" +TPL_HATHOR_CPANEL_LINK_TEXT="Return to Control Panel" +TPL_HATHOR_GO="Go" +TPL_HATHOR_LOGO_DESC="Select or upload a custom logo for the administrator template." +TPL_HATHOR_LOGO_LABEL="Logo" +TPL_HATHOR_MAIN_MENU="Main Menu" +TPL_HATHOR_MESSAGE_POSTINSTALL_TITLE="Information about the Hathor administrator template" +TPL_HATHOR_MESSAGE_POSTINSTALL_BODY="The Hathor administrator template style is set as your personal or global default administrator template. Please note - any new features for Joomla will only be available with the Isis template. We recommend that you switch your default backend template style to Isis. You can do this by selecting the button below. This will only change the default setting for the administrator template, if you have access to it, as well as your personal default style, if necessary. It does not change the frontend template or any other user's settings." +TPL_HATHOR_MESSAGE_POSTINSTALL_ACTION="Set the default administrator template style to Isis" +TPL_HATHOR_SHOW_SITE_NAME_DESC="Show the site name in the template header." +TPL_HATHOR_SHOW_SITE_NAME_LABEL="Show Site Name" +TPL_HATHOR_SKIP_TO_MAIN_CONTENT="Skip to Main Content" +TPL_HATHOR_SUB_MENU="Sub Menu" +TPL_HATHOR_XML_DESCRIPTION="Hathor is an accessible Administrator template for Joomla! The Colour CSS files can also be used for custom colour branding." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.tpl_hathor.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.tpl_hathor.sys.ini new file mode 100644 index 00000000..af2c8a65 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.tpl_hathor.sys.ini @@ -0,0 +1,19 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +HATHOR="Hathor Administrator template" +TPL_HATHOR_POSITION_CP_SHELL="Unused" +TPL_HATHOR_POSITION_CPANEL="Control Panel" +TPL_HATHOR_POSITION_DEBUG="Debug" +TPL_HATHOR_POSITION_FOOTER="Footer" +TPL_HATHOR_POSITION_ICON="Quick Icons" +TPL_HATHOR_POSITION_LOGIN="Login" +TPL_HATHOR_POSITION_MENU="Menu" +TPL_HATHOR_POSITION_POSTINSTALL="Postinstall" +TPL_HATHOR_POSITION_STATUS="Status" +TPL_HATHOR_POSITION_SUBMENU="Submenu" +TPL_HATHOR_POSITION_TITLE="Title" +TPL_HATHOR_POSITION_TOOLBAR="Toolbar" +TPL_HATHOR_XML_DESCRIPTION="Hathor is an accessible Administrator template for Joomla! The Colour CSS files can also be used for custom colour branding." \ No newline at end of file diff --git a/Sites/pages/administrator/language/en-GB/en-GB.tpl_isis.ini b/Sites/pages/administrator/language/en-GB/en-GB.tpl_isis.ini new file mode 100644 index 00000000..748d9b6c --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.tpl_isis.ini @@ -0,0 +1,43 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +ISIS="Isis Administrator template" +TPL_ISIS_CLEAR_CACHE="Clear Cache" +TPL_ISIS_COLOR_DESC="Choose a colour for the navigation bar. If left blank, the default value will be used." +TPL_ISIS_COLOR_HEADER_DESC="Choose a colour for the header. If left blank, the default value will be used." +TPL_ISIS_COLOR_HEADER_LABEL="Header Colour" +TPL_ISIS_COLOR_LABEL="Nav Bar Colour" +TPL_ISIS_COLOR_LOGIN_BACKGROUND_DESC="Choose a colour for the background of the login screen. If left blank, the default value will be used." +TPL_ISIS_COLOR_LOGIN_BACKGROUND_LABEL="Login Background Colour" +TPL_ISIS_COLOR_SIDEBAR_DESC="Choose a colour for the Sidebar Background. If left blank, the default value will be used." +TPL_ISIS_COLOR_SIDEBAR_LABEL="Sidebar Colour" +TPL_ISIS_COLOR_LINK_DESC="Choose a colour for the Link. If left blank, the default value will be used." +TPL_ISIS_COLOR_LINK_LABEL="Link Colour" +TPL_ISIS_CONTROL_PANEL="Control Panel" +TPL_ISIS_EDIT_ACCOUNT="Edit Account" +TPL_ISIS_FIELD_ADMIN_MENUS_DESC="If you intend to use Joomla Administrator on a monitor, set this to 'No'. It will prevent the collapse of the Administrator menus when reducing the width of the window. Default is 'Yes'." +TPL_ISIS_FIELD_ADMIN_MENUS_LABEL="Collapse Administrator Menu" +TPL_ISIS_HEADER_DESC="Optional display of header." +TPL_ISIS_HEADER_LABEL="Display Header" +TPL_ISIS_INSTALLER="Installer" +TPL_ISIS_ISFREESOFTWARE="Joomla is free software released under the GNU General Public License." +TPL_ISIS_LOGIN_LOGO_DESC="Select or upload a custom logo for the login area of administrator template." +TPL_ISIS_LOGIN_LOGO_LABEL="Login Logo" +TPL_ISIS_LOGO_DESC="Upload a custom logo for the administrator template." +TPL_ISIS_LOGO_LABEL="Logo" +TPL_ISIS_LOGOUT="Logout" +TPL_ISIS_PREVIEW="Preview %s" +TPL_ISIS_SKIP_TO_MAIN_CONTENT="Skip to Main Content" +TPL_ISIS_SKIP_TO_MAIN_CONTENT_HERE="Main content begins here" +TPL_ISIS_STATUS_BOTTOM="Fixed bottom" +TPL_ISIS_STATUS_DESC="Choose the location of the status module." +TPL_ISIS_STATUS_LABEL="Status Module Position" +TPL_ISIS_STATUS_TOP="Top" +TPL_ISIS_STICKY_DESC="Optionally set the toolbar to a fixed (pinned) location." +TPL_ISIS_STICKY_LABEL="Pinned Toolbar" +TPL_ISIS_TOGGLE_MENU="Toggle Navigation" +TPL_ISIS_TOOLBAR="Toolbar" +TPL_ISIS_USERMENU="User Menu" +TPL_ISIS_XML_DESCRIPTION="Continuing the Egyptian god/goddess theme (Khepri from 1.5 and Hathor from 1.6), Isis is the Joomla 3 administrator template based on Bootstrap and the launch of the Joomla User Interface library (JUI)." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.tpl_isis.sys.ini b/Sites/pages/administrator/language/en-GB/en-GB.tpl_isis.sys.ini new file mode 100644 index 00000000..4db5416c --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.tpl_isis.sys.ini @@ -0,0 +1,20 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +ISIS="Isis Administrator template" +TPL_ISIS_POSITION_BOTTOM="Bottom" +TPL_ISIS_POSITION_CPANEL="Cpanel" +TPL_ISIS_POSITION_CP_SHELL="Unused" +TPL_ISIS_POSITION_DEBUG="Debug" +TPL_ISIS_POSITION_FOOTER="Footer" +TPL_ISIS_POSITION_ICON="Quick Icons" +TPL_ISIS_POSITION_LOGIN="Login" +TPL_ISIS_POSITION_MENU="Menu" +TPL_ISIS_POSITION_POSTINSTALL="Postinstall" +TPL_ISIS_POSITION_STATUS="Status" +TPL_ISIS_POSITION_SUBMENU="Submenu" +TPL_ISIS_POSITION_TITLE="Title" +TPL_ISIS_POSITION_TOOLBAR="Toolbar" +TPL_ISIS_XML_DESCRIPTION="Continuing the Egyptian god/goddess theme (Khepri from 1.5 and Hathor from 1.6), Isis is the Joomla 3 administrator template based on Bootstrap and the launch of the Joomla User Interface library (JUI)." diff --git a/Sites/pages/administrator/language/en-GB/en-GB.xml b/Sites/pages/administrator/language/en-GB/en-GB.xml new file mode 100644 index 00000000..8ddc2b03 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/en-GB.xml @@ -0,0 +1,23 @@ + + + English (en-GB) + 3.9.25 + February 2021 + Joomla! Project + admin@joomla.org + www.joomla.org + Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. + GNU General Public License version 2 or later; see LICENSE.txt + + + English (United Kingdom) + English (United Kingdom) + en-GB + 0 + en_GB.utf8, en_GB.UTF-8, en_GB, eng_GB, en, english, english-uk, uk, gbr, britain, england, great britain, uk, united kingdom, united-kingdom + 0 + 0,6 + gregorian + + + diff --git a/Sites/pages/administrator/language/en-GB/install.xml b/Sites/pages/administrator/language/en-GB/install.xml new file mode 100644 index 00000000..45c291f1 --- /dev/null +++ b/Sites/pages/administrator/language/en-GB/install.xml @@ -0,0 +1,18 @@ + + + English (en-GB) + en-GB + 3.9.25 + February 2021 + Joomla! Project + admin@joomla.org + www.joomla.org + Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. + GNU General Public License version 2 or later; see LICENSE.txt + en-GB administrator language + + / + install.xml + + + diff --git a/Sites/pages/administrator/language/overrides/index.html b/Sites/pages/administrator/language/overrides/index.html new file mode 100644 index 00000000..2efb97f3 --- /dev/null +++ b/Sites/pages/administrator/language/overrides/index.html @@ -0,0 +1 @@ + diff --git a/Sites/pages/administrator/logs/index.html b/Sites/pages/administrator/logs/index.html new file mode 100644 index 00000000..2efb97f3 --- /dev/null +++ b/Sites/pages/administrator/logs/index.html @@ -0,0 +1 @@ + diff --git a/Sites/pages/administrator/manifests/files/joomla.xml b/Sites/pages/administrator/manifests/files/joomla.xml new file mode 100644 index 00000000..e54d21f2 --- /dev/null +++ b/Sites/pages/administrator/manifests/files/joomla.xml @@ -0,0 +1,52 @@ + + + files_joomla + Joomla! Project + admin@joomla.org + www.joomla.org + (C) 2005 - 2020 Open Source Matters. All rights reserved + GNU General Public License version 2 or later; see LICENSE.txt + 3.9.25 + February 2021 + FILES_JOOMLA_XML_DESCRIPTION + + administrator/components/com_admin/script.php + + + + administrator/components/com_admin/sql/updates/mysql + administrator/components/com_admin/sql/updates/sqlazure + administrator/components/com_admin/sql/updates/sqlazure + administrator/components/com_admin/sql/updates/postgresql + + + + + + administrator + bin + cache + cli + components + images + includes + language + layouts + libraries + media + modules + plugins + templates + tmp + htaccess.txt + web.config.txt + LICENSE.txt + README.txt + index.php + + + + + https://update.joomla.org/core/list.xml + + diff --git a/Sites/pages/administrator/manifests/libraries/fof.xml b/Sites/pages/administrator/manifests/libraries/fof.xml new file mode 100644 index 00000000..1b91bb7f --- /dev/null +++ b/Sites/pages/administrator/manifests/libraries/fof.xml @@ -0,0 +1,49 @@ + + + FOF + fof + LIB_FOF_XML_DESCRIPTION + 2015-04-22 13:15:32 + Nicholas K. Dionysopoulos / Akeeba Ltd + nicholas@akeebabackup.com + https://www.akeebabackup.com + (C)2011-2015 Nicholas K. Dionysopoulos + GNU GPLv2 or later + 2.4.3 + Akeeba Ltd + https://www.AkeebaBackup.com/download.html + + + en-GB/en-GB.lib_fof.ini + + + + autoloader + config + controller + database + dispatcher + download + encrypt + form + hal + inflector + integration + input + layout + less + model + platform + query + render + string + table + template + toolbar + utils + view + LICENSE.txt + include.php + version.txt + + diff --git a/Sites/pages/administrator/manifests/libraries/idna_convert.xml b/Sites/pages/administrator/manifests/libraries/idna_convert.xml new file mode 100644 index 00000000..6f8c36da --- /dev/null +++ b/Sites/pages/administrator/manifests/libraries/idna_convert.xml @@ -0,0 +1,18 @@ + + + LIB_IDNA + idna_convert + 0.8.0 + LIB_IDNA_XML_DESCRIPTION + 2004 + 2004-2011 phlyLabs Berlin, http://phlylabs.de + https://www.gnu.org/licenses/lgpl-2.1.html GNU/LGPL + phlyLabs + phlymail@phlylabs.de + http://phlylabs.de + Joomla! + https://www.joomla.org + + idna_convert + + diff --git a/Sites/pages/administrator/manifests/libraries/joomla.xml b/Sites/pages/administrator/manifests/libraries/joomla.xml new file mode 100644 index 00000000..0876df1d --- /dev/null +++ b/Sites/pages/administrator/manifests/libraries/joomla.xml @@ -0,0 +1,24 @@ + + + LIB_JOOMLA + joomla + 13.1 + LIB_JOOMLA_XML_DESCRIPTION + 2008 + Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. + GNU General Public License version 2 or later; see LICENSE.txt + Joomla! Project + admin@joomla.org + https://www.joomla.org + Joomla! + https://www.joomla.org + + compat + joomla + legacy + import.legacy.php + import.php + loader.php + platform.php + + diff --git a/Sites/pages/administrator/manifests/libraries/phpass.xml b/Sites/pages/administrator/manifests/libraries/phpass.xml new file mode 100644 index 00000000..55bb9d50 --- /dev/null +++ b/Sites/pages/administrator/manifests/libraries/phpass.xml @@ -0,0 +1,17 @@ + + + LIB_PHPASS + phpass + LIB_PHPASS_XML_DESCRIPTION + 2004-2006 + Solar Designer + solar@openwall.com + http://www.openwall.com/phpass/ + PD / GWC + 0.3 + http://www.openwall.com/phpass/ + + + PasswordHash.php + + diff --git a/Sites/pages/administrator/manifests/libraries/phputf8.xml b/Sites/pages/administrator/manifests/libraries/phputf8.xml new file mode 100644 index 00000000..9c809fad --- /dev/null +++ b/Sites/pages/administrator/manifests/libraries/phputf8.xml @@ -0,0 +1,18 @@ + + + LIB_PHPUTF8 + phputf8 + 0.5 + LIB_PHPUTF8_XML_DESCRIPTION + 2006 + Copyright various authors + https://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + Harry Fuecks + hfuecks@gmail.com + http://sourceforge.net/projects/phputf8 + Joomla! + https://www.joomla.org + + phputf8 + + diff --git a/Sites/pages/administrator/manifests/packages/index.html b/Sites/pages/administrator/manifests/packages/index.html new file mode 100644 index 00000000..2efb97f3 --- /dev/null +++ b/Sites/pages/administrator/manifests/packages/index.html @@ -0,0 +1 @@ + diff --git a/Sites/pages/administrator/manifests/packages/pkg_en-GB.xml b/Sites/pages/administrator/manifests/packages/pkg_en-GB.xml new file mode 100644 index 00000000..d9f37a26 --- /dev/null +++ b/Sites/pages/administrator/manifests/packages/pkg_en-GB.xml @@ -0,0 +1,26 @@ + + + English (en-GB) Language Pack + en-GB + 3.9.25.1 + February 2021 + Joomla! Project + admin@joomla.org + www.joomla.org + Copyright (C) 2005 - 2020 Open Source Matters, Inc. All rights reserved. + https://www.gnu.org/licenses/gpl-2.0.html GNU/GPL + https://github.com/joomla/joomla-cms + Joomla! Project + www.joomla.org + + true + + language/en-GB + administrator/language/en-GB + + + + https://update.joomla.org/language/translationlist_3.xml + + + diff --git a/Sites/pages/administrator/modules/mod_custom/mod_custom.php b/Sites/pages/administrator/modules/mod_custom/mod_custom.php new file mode 100644 index 00000000..9b896aba --- /dev/null +++ b/Sites/pages/administrator/modules/mod_custom/mod_custom.php @@ -0,0 +1,21 @@ +def('prepare_content', 1)) +{ + JPluginHelper::importPlugin('content'); + $module->content = JHtml::_('content.prepare', $module->content, '', 'mod_custom.content'); +} + +// Replace 'images/' to '../images/' when using an image from /images in backend. +$module->content = preg_replace('*src\=\"(?!administrator\/)images/*', 'src="../images/', $module->content); + +require JModuleHelper::getLayoutPath('mod_custom', $params->get('layout', 'default')); diff --git a/Sites/pages/administrator/modules/mod_custom/mod_custom.xml b/Sites/pages/administrator/modules/mod_custom/mod_custom.xml new file mode 100644 index 00000000..7e1f2924 --- /dev/null +++ b/Sites/pages/administrator/modules/mod_custom/mod_custom.xml @@ -0,0 +1,80 @@ + + + mod_custom + Joomla! Project + July 2004 + Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. + GNU General Public License version 2 or later; see LICENSE.txt + admin@joomla.org + www.joomla.org + 3.0.0 + MOD_CUSTOM_XML_DESCRIPTION + + + + + mod_custom.php + tmpl + + + en-GB.mod_custom.ini + en-GB.mod_custom.sys.ini + + + + +
    + + + + +
    +
    + + + + + + + + + + +
    +
    +
    +
    diff --git a/Sites/pages/administrator/modules/mod_custom/tmpl/default.php b/Sites/pages/administrator/modules/mod_custom/tmpl/default.php new file mode 100644 index 00000000..071f1780 --- /dev/null +++ b/Sites/pages/administrator/modules/mod_custom/tmpl/default.php @@ -0,0 +1,12 @@ +content; diff --git a/Sites/pages/administrator/modules/mod_feed/helper.php b/Sites/pages/administrator/modules/mod_feed/helper.php new file mode 100644 index 00000000..6b203dc6 --- /dev/null +++ b/Sites/pages/administrator/modules/mod_feed/helper.php @@ -0,0 +1,52 @@ +get('rssurl', ''); + + // Get RSS parsed object + try + { + jimport('joomla.feed.factory'); + $feed = new JFeedFactory; + $rssDoc = $feed->getFeed($rssurl); + } + catch (Exception $e) + { + return JText::_('MOD_FEED_ERR_FEED_NOT_RETRIEVED'); + } + + if (empty($rssDoc)) + { + return JText::_('MOD_FEED_ERR_FEED_NOT_RETRIEVED'); + } + + return $rssDoc; + } +} diff --git a/Sites/pages/administrator/modules/mod_feed/mod_feed.php b/Sites/pages/administrator/modules/mod_feed/mod_feed.php new file mode 100644 index 00000000..0c095419 --- /dev/null +++ b/Sites/pages/administrator/modules/mod_feed/mod_feed.php @@ -0,0 +1,31 @@ +get('rssurl', ''); +$rssrtl = $params->get('rssrtl', 0); + +// Check if feed URL has been set +if (empty ($rssurl)) +{ + echo '
    '; + echo JText::_('MOD_FEED_ERR_NO_URL'); + echo '
    '; + + return; +} + +$feed = ModFeedHelper::getFeed($params); +$moduleclass_sfx = htmlspecialchars($params->get('moduleclass_sfx'), ENT_COMPAT, 'UTF-8'); + +require JModuleHelper::getLayoutPath('mod_feed', $params->get('layout', 'default')); diff --git a/Sites/pages/administrator/modules/mod_feed/mod_feed.xml b/Sites/pages/administrator/modules/mod_feed/mod_feed.xml new file mode 100644 index 00000000..51cf6979 --- /dev/null +++ b/Sites/pages/administrator/modules/mod_feed/mod_feed.xml @@ -0,0 +1,184 @@ + + + mod_feed + Joomla! Project + July 2005 + Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. + GNU General Public License version 2 or later; see LICENSE.txt + admin@joomla.org + www.joomla.org + 3.0.0 + MOD_FEED_XML_DESCRIPTION + + mod_feed.php + helper.php + tmpl + + + en-GB.mod_feed.ini + en-GB.mod_feed.sys.ini + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + + + + + + + + +
    +
    +
    +
    diff --git a/Sites/pages/administrator/modules/mod_feed/tmpl/default.php b/Sites/pages/administrator/modules/mod_feed/tmpl/default.php new file mode 100644 index 00000000..6ae383d5 --- /dev/null +++ b/Sites/pages/administrator/modules/mod_feed/tmpl/default.php @@ -0,0 +1,128 @@ +get('rssrtl', 0); + $direction = ' '; + + if ($lang->isRtl() && $myrtl == 0) + { + $direction = ' redirect-rtl'; + } + + // Feed description + elseif ($lang->isRtl() && $myrtl == 1) + { + $direction = ' redirect-ltr'; + } + + elseif ($lang->isRtl() && $myrtl == 2) + { + $direction = ' redirect-rtl'; + } + + elseif ($myrtl == 0) + { + $direction = ' redirect-ltr'; + } + elseif ($myrtl == 1) + { + $direction = ' redirect-ltr'; + } + elseif ($myrtl == 2) + { + $direction = ' redirect-rtl'; + } + + if ($feed != false) : + ?> +
    + title) && $params->get('rsstitle', 1)) : ?> +

    + + title; ?> +

    + get('rssdate', 1)) : ?> +

    + publishedDate, JText::_('DATE_FORMAT_LC3')); ?> +

    + + + + get('rssdesc', 1)) : ?> + description; ?> + + + + get('rssimage', 1) && $feed->image) : ?> + <?php echo $feed->image->title; ?> + + + + + + + + +
      > + +
        + + get('rssitems', 3); $i++) : + + if (!$feed->offsetExists($i)) : + break; + endif; + $uri = $feed[$i]->uri || !$feed[$i]->isPermaLink ? trim($feed[$i]->uri) : trim($feed[$i]->guid); + $uri = !$uri || stripos($uri, 'http') !== 0 ? $rssurl : $uri; + $text = $feed[$i]->content !== '' ? trim($feed[$i]->content) : ''; + ?> +
      • + + + + + + get('rssitemdate', 0)) : ?> +
        + publishedDate, JText::_('DATE_FORMAT_LC3')); ?> +
        + + get('rssitemdesc', 1) && $text !== '') : ?> +
        + get('word_count', 0), true, false); + echo str_replace(''', "'", $text); + ?> +
        + +
      • + +
      + +
    + true)); + + // Set List SELECT + $model->setState('list.select', 'a.id, a.title, a.checked_out, a.checked_out_time, ' . + ' a.access, a.created, a.created_by, a.created_by_alias, a.featured, a.state, a.publish_up, a.publish_down'); + + // Set Ordering filter + switch ($params->get('ordering', 'c_dsc')) + { + case 'm_dsc': + $model->setState('list.ordering', 'modified DESC, created'); + $model->setState('list.direction', 'DESC'); + break; + + case 'c_dsc': + default: + $model->setState('list.ordering', 'created'); + $model->setState('list.direction', 'DESC'); + break; + } + + // Set Category Filter + $categoryId = $params->get('catid', null); + + if (is_numeric($categoryId)) + { + $model->setState('filter.category_id', $categoryId); + } + + // Set User Filter. + $userId = $user->get('id'); + + switch ($params->get('user_id', '0')) + { + case 'by_me': + $model->setState('filter.author_id', $userId); + break; + + case 'not_me': + $model->setState('filter.author_id', $userId); + $model->setState('filter.author_id.include', false); + break; + } + + // Set the Start and Limit + $model->setState('list.start', 0); + $model->setState('list.limit', $params->get('count', 5)); + + $items = $model->getItems(); + + if ($error = $model->getError()) + { + JError::raiseError(500, $error); + + return false; + } + + // Set the links + foreach ($items as &$item) + { + if ($user->authorise('core.edit', 'com_content.article.' . $item->id)) + { + $item->link = JRoute::_('index.php?option=com_content&task=article.edit&id=' . $item->id); + } + else + { + $item->link = ''; + } + } + + return $items; + } + + /** + * Get the alternate title for the module. + * + * @param \Joomla\Registry\Registry $params The module parameters. + * + * @return string The alternate title for the module. + */ + public static function getTitle($params) + { + $who = $params->get('user_id', '0'); + $catid = (int) $params->get('catid', null); + $type = $params->get('ordering', 'c_dsc') == 'c_dsc' ? '_CREATED' : '_MODIFIED'; + + if ($catid) + { + $category = JCategories::getInstance('Content')->get($catid); + + if ($category) + { + $title = $category->title; + } + else + { + $title = JText::_('MOD_POPULAR_UNEXISTING'); + } + } + else + { + $title = ''; + } + + return JText::plural( + 'MOD_LATEST_TITLE' . $type . ($catid ? '_CATEGORY' : '') . ($who != '0' ? "_$who" : ''), + (int) $params->get('count', 5), + $title + ); + } +} diff --git a/Sites/pages/administrator/modules/mod_latest/mod_latest.php b/Sites/pages/administrator/modules/mod_latest/mod_latest.php new file mode 100644 index 00000000..a0ee3d43 --- /dev/null +++ b/Sites/pages/administrator/modules/mod_latest/mod_latest.php @@ -0,0 +1,22 @@ +get('automatic_title', 0)) +{ + $module->title = ModLatestHelper::getTitle($params); +} + +require JModuleHelper::getLayoutPath('mod_latest', $params->get('layout', 'default')); diff --git a/Sites/pages/administrator/modules/mod_latest/mod_latest.xml b/Sites/pages/administrator/modules/mod_latest/mod_latest.xml new file mode 100644 index 00000000..f011d60f --- /dev/null +++ b/Sites/pages/administrator/modules/mod_latest/mod_latest.xml @@ -0,0 +1,101 @@ + + + mod_latest + Joomla! Project + July 2004 + Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. + GNU General Public License version 2 or later; see LICENSE.txt + admin@joomla.org + www.joomla.org + 3.0.0 + MOD_LATEST_XML_DESCRIPTION + + mod_latest.php + helper.php + tmpl + + + en-GB.mod_latest.ini + en-GB.mod_latest.sys.ini + + + + +
    + + + + + + + + + + + + + + + + +
    +
    + + + + + + + + +
    +
    +
    +
    diff --git a/Sites/pages/administrator/modules/mod_latest/tmpl/default.php b/Sites/pages/administrator/modules/mod_latest/tmpl/default.php new file mode 100644 index 00000000..b2a17be3 --- /dev/null +++ b/Sites/pages/administrator/modules/mod_latest/tmpl/default.php @@ -0,0 +1,51 @@ + +
    + + $item) : ?> +
    +
    + state, $i, 'articles.', false, 'cb', $item->publish_up, $item->publish_down); ?> + checked_out) : ?> + editor, $item->checked_out_time); ?> + + + + link) : ?> + + title, ENT_QUOTES, 'UTF-8'); ?> + + title, ENT_QUOTES, 'UTF-8'); ?> + + + + + author_name; ?> + +
    +
    +
    + created, JText::_('DATE_FORMAT_LC5')); ?> +
    +
    +
    + + +
    +
    +
    +
    +
    + +
    diff --git a/Sites/pages/administrator/modules/mod_latestactions/helper.php b/Sites/pages/administrator/modules/mod_latestactions/helper.php new file mode 100644 index 00000000..1b9f8ff0 --- /dev/null +++ b/Sites/pages/administrator/modules/mod_latestactions/helper.php @@ -0,0 +1,69 @@ + true)); + + // Set the Start and Limit + $model->setState('list.start', 0); + $model->setState('list.limit', $params->get('count', 5)); + $model->setState('list.ordering', 'a.id'); + $model->setState('list.direction', 'DESC'); + + $rows = $model->getItems(); + + // Load all actionlog plugins language files + ActionlogsHelper::loadActionLogPluginsLanguage(); + + foreach ($rows as $row) + { + $row->message = ActionlogsHelper::getHumanReadableLogMessage($row); + } + + return $rows; + } + + /** + * Get the alternate title for the module + * + * @param \Joomla\Registry\Registry $params The module parameters. + * + * @return string The alternate title for the module. + * + * @since 3.9.1 + */ + public static function getTitle($params) + { + return Text::plural('MOD_LATESTACTIONS_TITLE', $params->get('count', 5)); + } +} diff --git a/Sites/pages/administrator/modules/mod_latestactions/mod_latestactions.php b/Sites/pages/administrator/modules/mod_latestactions/mod_latestactions.php new file mode 100644 index 00000000..7b8a4401 --- /dev/null +++ b/Sites/pages/administrator/modules/mod_latestactions/mod_latestactions.php @@ -0,0 +1,31 @@ +authorise('core.admin')) +{ + return; +} + +// Include dependencies. +JLoader::register('ModLatestActionsHelper', __DIR__ . '/helper.php'); + +$list = ModLatestActionsHelper::getList($params); + +if ($params->get('automatic_title', 0)) +{ + $module->title = ModLatestActionsHelper::getTitle($params); +} + +require ModuleHelper::getLayoutPath('mod_latestactions', $params->get('layout', 'default')); diff --git a/Sites/pages/administrator/modules/mod_latestactions/mod_latestactions.xml b/Sites/pages/administrator/modules/mod_latestactions/mod_latestactions.xml new file mode 100644 index 00000000..852bf5dd --- /dev/null +++ b/Sites/pages/administrator/modules/mod_latestactions/mod_latestactions.xml @@ -0,0 +1,94 @@ + + + mod_latestactions + Joomla! Project + May 2018 + Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. + GNU General Public License version 2 or later; see LICENSE.txt + admin@joomla.org + www.joomla.org + 3.9.0 + MOD_LATESTACTIONS_XML_DESCRIPTION + + mod_latestactions.php + helper.php + tmpl + + + en-GB.mod_latestactions.ini + en-GB.mod_latestactions.sys.ini + + + + +
    + +
    +
    + + + + + + + + + + + + + + + + + + + +
    +
    +
    +
    diff --git a/Sites/pages/administrator/modules/mod_latestactions/tmpl/default.php b/Sites/pages/administrator/modules/mod_latestactions/tmpl/default.php new file mode 100644 index 00000000..e89087d7 --- /dev/null +++ b/Sites/pages/administrator/modules/mod_latestactions/tmpl/default.php @@ -0,0 +1,38 @@ + +
    + + $item) : ?> +
    +
    + message; ?> +
    +
    +
    + log_date, JText::_('DATE_FORMAT_LC5')); ?> +
    +
    +
    + + +
    +
    +
    +
    +
    + +
    diff --git a/Sites/pages/administrator/modules/mod_logged/helper.php b/Sites/pages/administrator/modules/mod_logged/helper.php new file mode 100644 index 00000000..eb12f8b0 --- /dev/null +++ b/Sites/pages/administrator/modules/mod_logged/helper.php @@ -0,0 +1,78 @@ +getQuery(true) + ->select('s.time, s.client_id, u.id, u.name, u.username') + ->from('#__session AS s') + ->join('LEFT', '#__users AS u ON s.userid = u.id') + ->where('s.guest = 0'); + $db->setQuery($query, 0, $params->get('count', 5)); + + try + { + $results = $db->loadObjectList(); + } + catch (RuntimeException $e) + { + throw $e; + } + + foreach ($results as $k => $result) + { + $results[$k]->logoutLink = ''; + + if ($user->authorise('core.manage', 'com_users')) + { + $results[$k]->editLink = JRoute::_('index.php?option=com_users&task=user.edit&id=' . $result->id); + $results[$k]->logoutLink = JRoute::_('index.php?option=com_login&task=logout&uid=' . $result->id . '&' . JSession::getFormToken() . '=1'); + } + + if ($params->get('name', 1) == 0) + { + $results[$k]->name = $results[$k]->username; + } + } + + return $results; + } + + /** + * Get the alternate title for the module + * + * @param \Joomla\Registry\Registry $params The module parameters. + * + * @return string The alternate title for the module. + */ + public static function getTitle($params) + { + return JText::plural('MOD_LOGGED_TITLE', $params->get('count', 5)); + } +} diff --git a/Sites/pages/administrator/modules/mod_logged/mod_logged.php b/Sites/pages/administrator/modules/mod_logged/mod_logged.php new file mode 100644 index 00000000..8f93b181 --- /dev/null +++ b/Sites/pages/administrator/modules/mod_logged/mod_logged.php @@ -0,0 +1,22 @@ +get('automatic_title', 0)) +{ + $module->title = ModLoggedHelper::getTitle($params); +} + +require JModuleHelper::getLayoutPath('mod_logged', $params->get('layout', 'default')); diff --git a/Sites/pages/administrator/modules/mod_logged/mod_logged.xml b/Sites/pages/administrator/modules/mod_logged/mod_logged.xml new file mode 100644 index 00000000..946143e7 --- /dev/null +++ b/Sites/pages/administrator/modules/mod_logged/mod_logged.xml @@ -0,0 +1,76 @@ + + + mod_logged + Joomla! Project + January 2005 + Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. + GNU General Public License version 2 or later; see LICENSE.txt + admin@joomla.org + www.joomla.org + 3.0.0 + MOD_LOGGED_XML_DESCRIPTION + + mod_logged.php + tmpl + + + en-GB.mod_logged.ini + en-GB.mod_logged.sys.ini + + + + +
    + + + + + + +
    +
    + + + + + + + + +
    +
    +
    +
    diff --git a/Sites/pages/administrator/modules/mod_logged/tmpl/default.php b/Sites/pages/administrator/modules/mod_logged/tmpl/default.php new file mode 100644 index 00000000..c56b4e08 --- /dev/null +++ b/Sites/pages/administrator/modules/mod_logged/tmpl/default.php @@ -0,0 +1,50 @@ + +
    + +
    +
    + client_id == 0) : ?> + + + + + + + editLink)) : ?> + + name; ?> + + name; ?> + + + + + client_id === null) : ?> + + client_id) : ?> + + + + + +
    +
    +
    + time, JText::_('DATE_FORMAT_LC5')); ?> +
    +
    +
    + +
    diff --git a/Sites/pages/administrator/modules/mod_login/helper.php b/Sites/pages/administrator/modules/mod_login/helper.php new file mode 100644 index 00000000..9cb72995 --- /dev/null +++ b/Sites/pages/administrator/modules/mod_login/helper.php @@ -0,0 +1,100 @@ +isRtl()) + { + foreach ($languages as &$language) + { + $language['text'] = $language['text'] . '‎'; + } + } + + array_unshift($languages, JHtml::_('select.option', '', JText::_('JDEFAULTLANGUAGE'))); + + return JHtml::_('select.genericlist', $languages, 'lang', 'class="advancedSelect" tabindex="4"', 'value', 'text', null); + } + + /** + * Get the redirect URI after login. + * + * @return string + */ + public static function getReturnUri() + { + $uri = JUri::getInstance(); + $return = 'index.php' . $uri->toString(array('query')); + + if ($return != 'index.php?option=com_login') + { + return base64_encode($return); + } + else + { + return base64_encode('index.php'); + } + } + + /** + * Creates a list of two factor authentication methods used in com_users + * on user view + * + * @return array + * + * @deprecated 4.0 Use JAuthenticationHelper::getTwoFactorMethods() instead. + */ + public static function getTwoFactorMethods() + { + try + { + JLog::add( + sprintf('%s() is deprecated, use JAuthenticationHelper::getTwoFactorMethods() instead.', __METHOD__), + JLog::WARNING, + 'deprecated' + ); + } + catch (RuntimeException $exception) + { + // Informational log only + } + + return JAuthenticationHelper::getTwoFactorMethods(); + } +} diff --git a/Sites/pages/administrator/modules/mod_login/mod_login.php b/Sites/pages/administrator/modules/mod_login/mod_login.php new file mode 100644 index 00000000..881e9d1b --- /dev/null +++ b/Sites/pages/administrator/modules/mod_login/mod_login.php @@ -0,0 +1,19 @@ +get('layout', 'default')); diff --git a/Sites/pages/administrator/modules/mod_login/mod_login.xml b/Sites/pages/administrator/modules/mod_login/mod_login.xml new file mode 100644 index 00000000..f27d866d --- /dev/null +++ b/Sites/pages/administrator/modules/mod_login/mod_login.xml @@ -0,0 +1,56 @@ + + + mod_login + Joomla! Project + March 2005 + Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. + GNU General Public License version 2 or later; see LICENSE.txt + admin@joomla.org + www.joomla.org + 3.0.0 + MOD_LOGIN_XML_DESCRIPTION + + mod_login.php + tmpl + helper.php + + + en-GB.mod_login.ini + en-GB.mod_login.sys.ini + + + + +
    + + + + +
    +
    + + + +
    +
    +
    +
    diff --git a/Sites/pages/administrator/modules/mod_login/tmpl/default.php b/Sites/pages/administrator/modules/mod_login/tmpl/default.php new file mode 100644 index 00000000..ca40a059 --- /dev/null +++ b/Sites/pages/administrator/modules/mod_login/tmpl/default.php @@ -0,0 +1,102 @@ + +
    +
    +
    +
    +
    + + + + + + + + +
    +
    +
    +
    +
    +
    + + + + + + + + +
    +
    +
    + 1): ?> +
    +
    +
    + + + + + + + + +
    +
    +
    + + +
    +
    +
    + + + + + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + + + + +
    +
    diff --git a/Sites/pages/administrator/modules/mod_menu/helper.php b/Sites/pages/administrator/modules/mod_menu/helper.php new file mode 100644 index 00000000..93547884 --- /dev/null +++ b/Sites/pages/administrator/modules/mod_menu/helper.php @@ -0,0 +1,60 @@ +getQuery(true) + ->select('b.menutype, b.home, b.language, l.image, l.sef, l.title_native') + ->from('#__menu AS b') + ->leftJoin('#__languages AS l ON l.lang_code = b.language') + ->where('b.home != 0') + ->where('(b.client_id = 0 OR b.client_id IS NULL)'); + + // Get all menu types with optional home menu and language + $query = $db->getQuery(true) + ->select('a.id, a.asset_id, a.menutype, a.title, a.description, a.client_id') + ->select('c.home, c.language, c.image, c.sef, c.title_native') + ->from('#__menu_types AS a') + ->leftJoin('(' . (string) $subQuery . ') c ON c.menutype = a.menutype') + ->order('a.id'); + + $db->setQuery($query); + + try + { + $result = $db->loadObjectList(); + } + catch (RuntimeException $e) + { + $result = array(); + JFactory::getApplication()->enqueueMessage(JText::sprintf('JERROR_LOADING_MENUS', $e->getMessage()), 'error'); + } + + return $result; + } +} diff --git a/Sites/pages/administrator/modules/mod_menu/menu.php b/Sites/pages/administrator/modules/mod_menu/menu.php new file mode 100644 index 00000000..320aba9a --- /dev/null +++ b/Sites/pages/administrator/modules/mod_menu/menu.php @@ -0,0 +1,515 @@ +user = $user; + } + + /** + * Get the current menu tree + * + * @return Tree + * + * @since 3.8.0 + */ + public function getTree() + { + if (!$this->tree) + { + $this->tree = new Tree; + } + + return $this->tree; + } + + /** + * Populate the menu items in the menu tree object + * + * @param Registry $params Menu configuration parameters + * @param bool $enabled Whether the menu should be enabled or disabled + * + * @return void + * + * @since 3.7.0 + */ + public function load($params, $enabled) + { + $this->tree = $this->getTree(); + $this->params = $params; + $this->enabled = $enabled; + $menutype = $this->params->get('menutype', '*'); + + if ($menutype === '*') + { + $name = $this->params->get('preset', 'joomla'); + $levels = MenuHelper::loadPreset($name); + } + else + { + $items = MenusHelper::getMenuItems($menutype, true); + + if ($this->enabled && $this->params->get('check', 1)) + { + if ($this->check($items, $this->params)) + { + $this->params->set('recovery', true); + + // In recovery mode, load the preset inside a special root node. + $this->tree->addChild(new Node\Heading('MOD_MENU_RECOVERY_MENU_ROOT'), true); + + $levels = MenuHelper::loadPreset('joomla'); + $levels = $this->preprocess($levels); + + $this->populateTree($levels); + + $this->tree->addChild(new Node\Separator); + + // Add link to exit recovery mode + $uri = clone JUri::getInstance(); + $uri->setVar('recover_menu', 0); + + $this->tree->addChild(new Node\Url('MOD_MENU_RECOVERY_EXIT', $uri->toString())); + + $this->tree->getParent(); + } + } + + $levels = MenuHelper::createLevels($items); + } + + $levels = $this->preprocess($levels); + + $this->populateTree($levels); + } + + /** + * Method to render a given level of a menu using provided layout file + * + * @param string $layoutFile The layout file to be used to render + * + * @return void + * + * @since 3.8.0 + */ + public function renderSubmenu($layoutFile) + { + if (is_file($layoutFile)) + { + $children = $this->tree->getCurrent()->getChildren(); + + foreach ($children as $child) + { + $this->tree->setCurrent($child); + + // This sets the scope to this object for the layout file and also isolates other `include`s + require $layoutFile; + } + } + } + + /** + * Check the flat list of menu items for important links + * + * @param array $items The menu items array + * @param Registry $params Module options + * + * @return boolean Whether to show recovery menu + * + * @since 3.8.0 + */ + protected function check($items, Registry $params) + { + $authMenus = $this->user->authorise('core.manage', 'com_menus'); + $authModules = $this->user->authorise('core.manage', 'com_modules'); + + if (!$authMenus && !$authModules) + { + return false; + } + + $app = JFactory::getApplication(); + $types = ArrayHelper::getColumn($items, 'type'); + $elements = ArrayHelper::getColumn($items, 'element'); + $rMenu = $authMenus && !in_array('com_menus', $elements); + $rModule = $authModules && !in_array('com_modules', $elements); + $rContainer = !in_array('container', $types); + + if ($rMenu || $rModule || $rContainer) + { + $recovery = $app->getUserStateFromRequest('mod_menu.recovery', 'recover_menu', 0, 'int'); + + if ($recovery) + { + return true; + } + + $missing = array(); + + if ($rMenu) + { + $missing[] = JText::_('MOD_MENU_IMPORTANT_ITEM_MENU_MANAGER'); + } + + if ($rModule) + { + $missing[] = JText::_('MOD_MENU_IMPORTANT_ITEM_MODULE_MANAGER'); + } + + if ($rContainer) + { + $missing[] = JText::_('MOD_MENU_IMPORTANT_ITEM_COMPONENTS_CONTAINER'); + } + + $uri = clone JUri::getInstance(); + $uri->setVar('recover_menu', 1); + + $table = JTable::getInstance('MenuType'); + $menutype = $params->get('menutype'); + + $table->load(array('menutype' => $menutype)); + + $menutype = $table->get('title', $menutype); + $message = JText::sprintf('MOD_MENU_IMPORTANT_ITEMS_INACCESSIBLE_LIST_WARNING', $menutype, implode(', ', $missing), $uri); + + $app->enqueueMessage($message, 'warning'); + } + + return false; + } + + /** + * Filter and perform other preparatory tasks for loaded menu items based on access rights and module configurations for display + * + * @param \stdClass[] $items The levelled array of menu item objects + * + * @return array + * + * @since 3.8.0 + */ + protected function preprocess($items) + { + $result = array(); + $language = JFactory::getLanguage(); + + $noSeparator = true; + + // Call preprocess for the menu items on plugins. + // Plugins should normally process the current level only unless their logic needs deep levels too. + $dispatcher = JEventDispatcher::getInstance(); + $dispatcher->trigger('onPreprocessMenuItems', array('com_menus.administrator.module', &$items, $this->params, $this->enabled)); + + foreach ($items as $i => &$item) + { + // Exclude item with menu item option set to exclude from menu modules + if ($item->params->get('menu_show', 1) == 0) + { + continue; + } + + $item->scope = isset($item->scope) ? $item->scope : 'default'; + $item->icon = isset($item->icon) ? $item->icon : ''; + + // Whether this scope can be displayed. Applies only to preset items. Db driven items should use un/published state. + if (($item->scope === 'help' && !$this->params->get('showhelp', 1)) || ($item->scope === 'edit' && !$this->params->get('shownew', 1))) + { + continue; + } + + if (substr($item->link, 0, 8) === 'special:') + { + $special = substr($item->link, 8); + + if ($special === 'language-forum') + { + $item->link = 'index.php?option=com_admin&view=help&layout=langforum'; + } + elseif ($special === 'custom-forum') + { + $item->link = $this->params->get('forum_url'); + } + } + + // Exclude item if is not enabled + if ($item->element && !JComponentHelper::isEnabled($item->element)) + { + continue; + } + + // Exclude Mass Mail if disabled in global configuration + if ($item->scope === 'massmail' && (JFactory::getApplication()->get('massmailoff', 0) == 1)) + { + continue; + } + + // Exclude item if the component is not authorised + $assetName = $item->element; + + if ($item->element === 'com_categories') + { + parse_str($item->link, $query); + $assetName = isset($query['extension']) ? $query['extension'] : 'com_content'; + } + elseif ($item->element === 'com_fields') + { + parse_str($item->link, $query); + + // Only display Fields menus when enabled in the component + $createFields = null; + + if (isset($query['context'])) + { + $createFields = JComponentHelper::getParams(strstr($query['context'], '.', true))->get('custom_fields_enable', 1); + } + + if (!$createFields) + { + continue; + } + + list($assetName) = isset($query['context']) ? explode('.', $query['context'], 2) : array('com_fields'); + } + // Special case for components which only allow super user access + elseif (in_array($item->element, array('com_config', 'com_privacy', 'com_actionlogs'), true) && !$this->user->authorise('core.admin')) + { + continue; + } + elseif ($item->element === 'com_joomlaupdate' && !$this->user->authorise('core.admin')) + { + continue; + } + elseif ($item->element === 'com_admin') + { + parse_str($item->link, $query); + + if (isset($query['view']) && $query['view'] === 'sysinfo' && !$this->user->authorise('core.admin')) + { + continue; + } + } + + if ($assetName && !$this->user->authorise(($item->scope === 'edit') ? 'core.create' : 'core.manage', $assetName)) + { + continue; + } + + // Exclude if link is invalid + if (!in_array($item->type, array('separator', 'heading', 'container')) && trim($item->link) === '') + { + continue; + } + + // Process any children if exists + $item->submenu = $this->preprocess($item->submenu); + + // Populate automatic children for container items + if ($item->type === 'container') + { + $exclude = (array) $item->params->get('hideitems') ?: array(); + $components = MenusHelper::getMenuItems('main', false, $exclude); + + $item->components = MenuHelper::createLevels($components); + $item->components = $this->preprocess($item->components); + $item->components = ArrayHelper::sortObjects($item->components, 'text', 1, false, true); + } + + // Exclude if there are no child items under heading or container + if (in_array($item->type, array('heading', 'container')) && empty($item->submenu) && empty($item->components)) + { + continue; + } + + // Remove repeated and edge positioned separators, It is important to put this check at the end of any logical filtering. + if ($item->type === 'separator') + { + if ($noSeparator) + { + continue; + } + + $noSeparator = true; + } + else + { + $noSeparator = false; + } + + // Ok we passed everything, load language at last only + if ($item->element) + { + $language->load($item->element . '.sys', JPATH_ADMINISTRATOR, null, false, true) || + $language->load($item->element . '.sys', JPATH_ADMINISTRATOR . '/components/' . $item->element, null, false, true); + } + + if ($item->type === 'separator' && $item->params->get('text_separator') == 0) + { + $item->title = ''; + } + + $item->text = JText::_($item->title); + + $result[$i] = $item; + } + + // If last one was a separator remove it too. + if ($noSeparator && isset($i)) + { + unset($result[$i]); + } + + return $result; + } + + /** + * Load the menu items from a hierarchical list of items into the menu tree + * + * @param stdClass[] $levels Menu items as a hierarchical list format + * + * @return void + * + * @since 3.8.0 + */ + protected function populateTree($levels) + { + foreach ($levels as $item) + { + $class = $this->enabled ? $item->class : 'disabled'; + + if ($item->type === 'separator') + { + $this->tree->addChild(new Node\Separator($item->title)); + } + elseif ($item->type === 'heading') + { + // We already excluded heading type menu item with no children. + $this->tree->addChild(new Node\Heading($item->title, $class, null, $item->icon), $this->enabled); + + if ($this->enabled) + { + $this->populateTree($item->submenu); + $this->tree->getParent(); + } + } + elseif ($item->type === 'url') + { + $cNode = new Node\Url($item->title, $item->link, $item->browserNav, $class, null, $item->icon); + $this->tree->addChild($cNode, $this->enabled); + + if ($this->enabled) + { + $this->populateTree($item->submenu); + $this->tree->getParent(); + } + } + elseif ($item->type === 'component') + { + $cNode = new Node\Component($item->title, $item->element, $item->link, $item->browserNav, $class, null, $item->icon); + $this->tree->addChild($cNode, $this->enabled); + + if ($this->enabled) + { + $this->populateTree($item->submenu); + $this->tree->getParent(); + } + } + elseif ($item->type === 'container') + { + // We already excluded container type menu item with no children. + $this->tree->addChild(new Node\Container($item->title, $item->class, null, $item->icon), $this->enabled); + + if ($this->enabled) + { + $this->populateTree($item->submenu); + + // Add a separator between dynamic menu items and components menu items + if (count($item->submenu) && count($item->components)) + { + $this->tree->addChild(new Node\Separator); + } + + $this->populateTree($item->components); + + $this->tree->getParent(); + } + } + } + } +} diff --git a/Sites/pages/administrator/modules/mod_menu/mod_menu.php b/Sites/pages/administrator/modules/mod_menu/mod_menu.php new file mode 100644 index 00000000..34154c05 --- /dev/null +++ b/Sites/pages/administrator/modules/mod_menu/mod_menu.php @@ -0,0 +1,29 @@ +input; +$enabled = !$input->getBool('hidemainmenu'); + +$menu = new JAdminCssMenu($user); +$menu->load($params, $enabled); + +// Render the module layout +require JModuleHelper::getLayoutPath('mod_menu', $params->get('layout', 'default')); diff --git a/Sites/pages/administrator/modules/mod_menu/mod_menu.xml b/Sites/pages/administrator/modules/mod_menu/mod_menu.xml new file mode 100644 index 00000000..38105648 --- /dev/null +++ b/Sites/pages/administrator/modules/mod_menu/mod_menu.xml @@ -0,0 +1,119 @@ + + + mod_menu + Joomla! Project + March 2006 + Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. + GNU General Public License version 2 or later; see LICENSE.txt + admin@joomla.org + www.joomla.org + 3.0.0 + MOD_MENU_XML_DESCRIPTION + + mod_menu.php + preset + tmpl + helper.php + menu.php + + + en-GB.mod_menu.ini + en-GB.mod_menu.sys.ini + + + + +
    + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + +
    +
    +
    +
    diff --git a/Sites/pages/administrator/modules/mod_menu/tmpl/default.php b/Sites/pages/administrator/modules/mod_menu/tmpl/default.php new file mode 100644 index 00000000..9a8af493 --- /dev/null +++ b/Sites/pages/administrator/modules/mod_menu/tmpl/default.php @@ -0,0 +1,35 @@ +direction == 'rtl' ? 'pull-right' : ''; +$class = $enabled ? 'nav ' . $direction : 'nav disabled ' . $direction; + +// Recurse through children of root node if they exist +$menuTree = $menu->getTree(); +$root = $menuTree->reset(); + +if ($root->hasChildren()) +{ + echo '\n"; + + echo ''; + + if ($css = $menuTree->getCss()) + { + $doc->addStyleDeclaration(implode("\n", $css)); + } +} diff --git a/Sites/pages/administrator/modules/mod_menu/tmpl/default_submenu.php b/Sites/pages/administrator/modules/mod_menu/tmpl/default_submenu.php new file mode 100644 index 00000000..26eb5f96 --- /dev/null +++ b/Sites/pages/administrator/modules/mod_menu/tmpl/default_submenu.php @@ -0,0 +1,138 @@ +tree->getCurrent(); + +// Build the CSS class suffix +if (!$this->enabled) +{ + $class = ' class="disabled"'; +} +elseif ($current instanceOf Separator) +{ + $class = $current->get('title') ? ' class="menuitem-group"' : ' class="divider"'; +} +elseif ($current->hasChildren()) +{ + if ($current->getLevel() == 1) + { + $class = ' class="dropdown"'; + } + elseif ($current->get('class') == 'scrollable-menu') + { + $class = ' class="dropdown scrollable-menu"'; + } + else + { + $class = ' class="dropdown-submenu"'; + } +} +else +{ + $class = ''; +} + +// Print the item +echo ''; + +// Print a link if it exists +$linkClass = array(); +$dataToggle = ''; +$dropdownCaret = ''; + +if ($current->hasChildren()) +{ + $linkClass[] = 'dropdown-toggle'; + $dataToggle = ' data-toggle="dropdown"'; + + if ($current->getLevel() == 1) + { + $dropdownCaret = ' '; + } +} +else +{ + $linkClass[] = 'no-dropdown'; +} + +if (!($current instanceof Separator) && ($current->getLevel() > 1)) +{ + $iconClass = $this->tree->getIconClass(); + + if (trim($iconClass)) + { + $linkClass[] = $iconClass; + } +} + +// Implode out $linkClass for rendering +$linkClass = ' class="' . implode(' ', $linkClass) . '" '; + +// Links: component/url/heading/container +if ($link = $current->get('link')) +{ + $icon = $current->get('icon'); + + if ($icon) + { + if (substr($icon, 0, 6) == 'class:') + { + $icon = ''; + } + elseif (substr($icon, 0, 6) == 'image:') + { + $icon = JHtml::_('image', substr($icon, 6), null, null, true); + } + else + { + $icon = JHtml::_('image', $icon, null); + } + } + + $target = $current->get('target') ? 'target="' . $current->get('target') . '"' : ''; + + echo '' . + JText::_($current->get('title')) . $icon . $dropdownCaret . ''; +} +// Separator +else +{ + echo '' . JText::_($current->get('title')) . ''; +} + +// Recurse through children if they exist +if ($this->enabled && $current->hasChildren()) +{ + if ($current->getLevel() > 1) + { + $id = $current->get('id') ? ' id="menu-' . strtolower($current->get('id')) . '"' : ''; + + echo '' . "\n"; + } + else + { + echo '\n"; +} + +echo "\n"; diff --git a/Sites/pages/administrator/modules/mod_multilangstatus/language/en-GB/en-GB.mod_multilangstatus.ini b/Sites/pages/administrator/modules/mod_multilangstatus/language/en-GB/en-GB.mod_multilangstatus.ini new file mode 100644 index 00000000..1727696c --- /dev/null +++ b/Sites/pages/administrator/modules/mod_multilangstatus/language/en-GB/en-GB.mod_multilangstatus.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +MOD_MULTILANGSTATUS="Multilanguage Status" +MOD_MULTILANGSTATUS_XML_DESCRIPTION="This module shows the status of the multilanguage parameters." diff --git a/Sites/pages/administrator/modules/mod_multilangstatus/language/en-GB/en-GB.mod_multilangstatus.sys.ini b/Sites/pages/administrator/modules/mod_multilangstatus/language/en-GB/en-GB.mod_multilangstatus.sys.ini new file mode 100644 index 00000000..1727696c --- /dev/null +++ b/Sites/pages/administrator/modules/mod_multilangstatus/language/en-GB/en-GB.mod_multilangstatus.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +MOD_MULTILANGSTATUS="Multilanguage Status" +MOD_MULTILANGSTATUS_XML_DESCRIPTION="This module shows the status of the multilanguage parameters." diff --git a/Sites/pages/administrator/modules/mod_multilangstatus/mod_multilangstatus.php b/Sites/pages/administrator/modules/mod_multilangstatus/mod_multilangstatus.php new file mode 100644 index 00000000..803c963a --- /dev/null +++ b/Sites/pages/administrator/modules/mod_multilangstatus/mod_multilangstatus.php @@ -0,0 +1,12 @@ +get('layout', 'default')); diff --git a/Sites/pages/administrator/modules/mod_multilangstatus/mod_multilangstatus.xml b/Sites/pages/administrator/modules/mod_multilangstatus/mod_multilangstatus.xml new file mode 100644 index 00000000..72bd9d96 --- /dev/null +++ b/Sites/pages/administrator/modules/mod_multilangstatus/mod_multilangstatus.xml @@ -0,0 +1,50 @@ + + + mod_multilangstatus + Joomla! Project + September 2011 + Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. + GNU General Public License version 2 or later; see LICENSE.txt + admin@joomla.org + www.joomla.org + 3.0.0 + MOD_MULTILANGSTATUS_XML_DESCRIPTION + + + mod_multilangstatus.php + tmpl + language + + + + language/en-GB/en-GB.mod_multilangstatus.ini + language/en-GB/en-GB.mod_multilangstatus.sys.ini + + + + + + + + +
    + + + + + +
    +
    +
    +
    diff --git a/Sites/pages/administrator/modules/mod_multilangstatus/tmpl/default.php b/Sites/pages/administrator/modules/mod_multilangstatus/tmpl/default.php new file mode 100644 index 00000000..49f9eaaf --- /dev/null +++ b/Sites/pages/administrator/modules/mod_multilangstatus/tmpl/default.php @@ -0,0 +1,48 @@ +addScriptDeclaration(" + jQuery(document).ready(function($) { + var multilangueModal = $('#multiLangModal').clone(); + $('#multiLangModal').remove(); + $('body').append(multilangueModal); + }); +"); +?> + +
    + + + + +
    + + JText::_('MOD_MULTILANGSTATUS'), + 'url' => JRoute::_('index.php?option=com_languages&view=multilangstatus&tmpl=component'), + 'height' => '400px', + 'width' => '800px', + 'bodyHeight' => '70', + 'modalWidth' => '80', + 'footer' => '', + ) +); diff --git a/Sites/pages/administrator/modules/mod_popular/helper.php b/Sites/pages/administrator/modules/mod_popular/helper.php new file mode 100644 index 00000000..eb0e5b26 --- /dev/null +++ b/Sites/pages/administrator/modules/mod_popular/helper.php @@ -0,0 +1,131 @@ + true)); + + // Set List SELECT + $model->setState('list.select', 'a.id, a.title, a.checked_out, a.checked_out_time, ' . + ' a.created, a.hits'); + + // Set Ordering filter + $model->setState('list.ordering', 'a.hits'); + $model->setState('list.direction', 'DESC'); + + // Set Category Filter + $categoryId = $params->get('catid', null); + + if (is_numeric($categoryId)) + { + $model->setState('filter.category_id', $categoryId); + } + + // Set User Filter. + $userId = $user->get('id'); + + switch ($params->get('user_id', '0')) + { + case 'by_me': + $model->setState('filter.author_id', $userId); + break; + + case 'not_me': + $model->setState('filter.author_id', $userId); + $model->setState('filter.author_id.include', false); + break; + } + + // Set the Start and Limit + $model->setState('list.start', 0); + $model->setState('list.limit', $params->get('count', 5)); + + $items = $model->getItems(); + + if ($error = $model->getError()) + { + JError::raiseError(500, $error); + + return false; + } + + // Set the links + foreach ($items as &$item) + { + if ($user->authorise('core.edit', 'com_content.article.' . $item->id)) + { + $item->link = JRoute::_('index.php?option=com_content&task=article.edit&id=' . $item->id); + } + else + { + $item->link = ''; + } + } + + return $items; + } + + /** + * Get the alternate title for the module + * + * @param JObject $params The module parameters. + * + * @return string The alternate title for the module. + */ + public static function getTitle($params) + { + $who = $params->get('user_id', '0'); + $catid = (int) $params->get('catid', null); + + if ($catid) + { + $category = JCategories::getInstance('Content')->get($catid); + + if ($category) + { + $title = $category->title; + } + else + { + $title = JText::_('MOD_POPULAR_UNEXISTING'); + } + } + else + { + $title = ''; + } + + return JText::plural( + 'MOD_POPULAR_TITLE' . ($catid ? '_CATEGORY' : '') . ($who != '0' ? "_$who" : ''), + (int) $params->get('count', 5), + $title + ); + } +} diff --git a/Sites/pages/administrator/modules/mod_popular/mod_popular.php b/Sites/pages/administrator/modules/mod_popular/mod_popular.php new file mode 100644 index 00000000..ee4a6ef1 --- /dev/null +++ b/Sites/pages/administrator/modules/mod_popular/mod_popular.php @@ -0,0 +1,24 @@ +get('automatic_title', 0)) +{ + $module->title = ModPopularHelper::getTitle($params); +} + +// Render the module +require JModuleHelper::getLayoutPath('mod_popular', $params->get('layout', 'default')); diff --git a/Sites/pages/administrator/modules/mod_popular/mod_popular.xml b/Sites/pages/administrator/modules/mod_popular/mod_popular.xml new file mode 100644 index 00000000..5cc0f95e --- /dev/null +++ b/Sites/pages/administrator/modules/mod_popular/mod_popular.xml @@ -0,0 +1,91 @@ + + + mod_popular + Joomla! Project + July 2004 + Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. + GNU General Public License version 2 or later; see LICENSE.txt + admin@joomla.org + www.joomla.org + 3.0.0 + MOD_POPULAR_XML_DESCRIPTION + + mod_popular.php + tmpl + helper.php + + + en-GB.mod_popular.ini + en-GB.mod_popular.sys.ini + + + + +
    + + + + + + + + + + + +
    + +
    + + + + + + + + +
    +
    +
    +
    diff --git a/Sites/pages/administrator/modules/mod_popular/tmpl/default.php b/Sites/pages/administrator/modules/mod_popular/tmpl/default.php new file mode 100644 index 00000000..2fe8826f --- /dev/null +++ b/Sites/pages/administrator/modules/mod_popular/tmpl/default.php @@ -0,0 +1,50 @@ + +
    + + $item) : ?> + + hits; ?> + = 10000 ? 'important' : ($hits >= 1000 ? 'warning' : ($hits >= 100 ? 'info' : ''))); ?> +
    +
    + hits; ?> + checked_out) : ?> + editor, $item->checked_out_time); ?> + + + + link) : ?> + + title, ENT_QUOTES, 'UTF-8'); ?> + + title, ENT_QUOTES, 'UTF-8'); ?> + + +
    +
    +
    + created, JText::_('DATE_FORMAT_LC5')); ?> +
    +
    +
    + + +
    +
    +
    +
    +
    + +
    diff --git a/Sites/pages/administrator/modules/mod_privacy_dashboard/helper.php b/Sites/pages/administrator/modules/mod_privacy_dashboard/helper.php new file mode 100644 index 00000000..40907f2b --- /dev/null +++ b/Sites/pages/administrator/modules/mod_privacy_dashboard/helper.php @@ -0,0 +1,42 @@ +getRequestCounts(); + } + catch (JDatabaseException $e) + { + return array(); + } + } +} diff --git a/Sites/pages/administrator/modules/mod_privacy_dashboard/mod_privacy_dashboard.php b/Sites/pages/administrator/modules/mod_privacy_dashboard/mod_privacy_dashboard.php new file mode 100644 index 00000000..8078e2ed --- /dev/null +++ b/Sites/pages/administrator/modules/mod_privacy_dashboard/mod_privacy_dashboard.php @@ -0,0 +1,30 @@ +authorise('core.admin')) +{ + return; +} + +// Load the privacy component language file. +$lang = JFactory::getLanguage(); +$lang->load('com_privacy', JPATH_ADMINISTRATOR, null, false, true) + || $lang->load('com_privacy', JPATH_ADMINISTRATOR . '/components/com_privacy', null, false, true); + +JHtml::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_privacy/helpers/html'); + +JLoader::register('ModPrivacyDashboardHelper', __DIR__ . '/helper.php'); + +$list = ModPrivacyDashboardHelper::getData(); +$moduleclass_sfx = htmlspecialchars($params->get('moduleclass_sfx'), ENT_COMPAT, 'UTF-8'); + +require JModuleHelper::getLayoutPath('mod_privacy_dashboard', $params->get('layout', 'default')); diff --git a/Sites/pages/administrator/modules/mod_privacy_dashboard/mod_privacy_dashboard.xml b/Sites/pages/administrator/modules/mod_privacy_dashboard/mod_privacy_dashboard.xml new file mode 100644 index 00000000..9b05ee05 --- /dev/null +++ b/Sites/pages/administrator/modules/mod_privacy_dashboard/mod_privacy_dashboard.xml @@ -0,0 +1,73 @@ + + + mod_privacy_dashboard + Joomla! Project + June 2018 + Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. + GNU General Public License version 2 or later; see LICENSE.txt + admin@joomla.org + www.joomla.org + 3.9.0 + MOD_PRIVACY_DASHBOARD_XML_DESCRIPTION + + mod_privacy_dashboard.php + tmpl + helper.php + + + en-GB.mod_privacy_dashboard.ini + en-GB.mod_privacy_dashboard.sys.ini + + + + +
    +
    +
    + + + + + + + + + + + + + + +
    +
    +
    +
    diff --git a/Sites/pages/administrator/modules/mod_privacy_dashboard/tmpl/default.php b/Sites/pages/administrator/modules/mod_privacy_dashboard/tmpl/default.php new file mode 100644 index 00000000..8f1db4b0 --- /dev/null +++ b/Sites/pages/administrator/modules/mod_privacy_dashboard/tmpl/default.php @@ -0,0 +1,51 @@ + +
    + +
    +
    +
    +
    +
    + +
    + +
    status); ?>
    +
    count; ?>
    +
    + status, array(0, 1))) : ?> + count; ?> + + count; ?> + +
    +
    +
    +
    + +
    +
    +
    +
    +
    + +
    diff --git a/Sites/pages/administrator/modules/mod_quickicon/helper.php b/Sites/pages/administrator/modules/mod_quickicon/helper.php new file mode 100644 index 00000000..b6ffca04 --- /dev/null +++ b/Sites/pages/administrator/modules/mod_quickicon/helper.php @@ -0,0 +1,220 @@ +get('context', 'mod_quickicon'); + + if ($context == 'mod_quickicon') + { + // Load mod_quickicon language file in case this method is called before rendering the module + JFactory::getLanguage()->load('mod_quickicon'); + + self::$buttons[$key] = array( + array( + 'link' => JRoute::_('index.php?option=com_content&task=article.add'), + 'image' => 'pencil-2', + 'icon' => 'header/icon-48-article-add.png', + 'text' => JText::_('MOD_QUICKICON_ADD_NEW_ARTICLE'), + 'access' => array('core.manage', 'com_content', 'core.create', 'com_content'), + 'group' => 'MOD_QUICKICON_CONTENT', + ), + array( + 'link' => JRoute::_('index.php?option=com_content'), + 'image' => 'stack', + 'icon' => 'header/icon-48-article.png', + 'text' => JText::_('MOD_QUICKICON_ARTICLE_MANAGER'), + 'access' => array('core.manage', 'com_content'), + 'group' => 'MOD_QUICKICON_CONTENT', + ), + array( + 'link' => JRoute::_('index.php?option=com_categories&extension=com_content'), + 'image' => 'folder', + 'icon' => 'header/icon-48-category.png', + 'text' => JText::_('MOD_QUICKICON_CATEGORY_MANAGER'), + 'access' => array('core.manage', 'com_content'), + 'group' => 'MOD_QUICKICON_CONTENT', + ), + array( + 'link' => JRoute::_('index.php?option=com_media'), + 'image' => 'pictures', + 'icon' => 'header/icon-48-media.png', + 'text' => JText::_('MOD_QUICKICON_MEDIA_MANAGER'), + 'access' => array('core.manage', 'com_media'), + 'group' => 'MOD_QUICKICON_CONTENT', + ), + array( + 'link' => JRoute::_('index.php?option=com_menus'), + 'image' => 'list-view', + 'icon' => 'header/icon-48-menumgr.png', + 'text' => JText::_('MOD_QUICKICON_MENU_MANAGER'), + 'access' => array('core.manage', 'com_menus'), + 'group' => 'MOD_QUICKICON_STRUCTURE', + ), + array( + 'link' => JRoute::_('index.php?option=com_users'), + 'image' => 'users', + 'icon' => 'header/icon-48-user.png', + 'text' => JText::_('MOD_QUICKICON_USER_MANAGER'), + 'access' => array('core.manage', 'com_users'), + 'group' => 'MOD_QUICKICON_USERS', + ), + array( + 'link' => JRoute::_('index.php?option=com_modules'), + 'image' => 'cube', + 'icon' => 'header/icon-48-module.png', + 'text' => JText::_('MOD_QUICKICON_MODULE_MANAGER'), + 'access' => array('core.manage', 'com_modules'), + 'group' => 'MOD_QUICKICON_STRUCTURE', + ), + array( + 'link' => JRoute::_('index.php?option=com_config'), + 'image' => 'cog', + 'icon' => 'header/icon-48-config.png', + 'text' => JText::_('MOD_QUICKICON_GLOBAL_CONFIGURATION'), + 'access' => array('core.manage', 'com_config', 'core.admin', 'com_config'), + 'group' => 'MOD_QUICKICON_CONFIGURATION', + ), + array( + 'link' => JRoute::_('index.php?option=com_templates'), + 'image' => 'eye', + 'icon' => 'header/icon-48-themes.png', + 'text' => JText::_('MOD_QUICKICON_TEMPLATE_MANAGER'), + 'access' => array('core.manage', 'com_templates'), + 'group' => 'MOD_QUICKICON_CONFIGURATION', + ), + array( + 'link' => JRoute::_('index.php?option=com_languages'), + 'image' => 'comments-2', + 'icon' => 'header/icon-48-language.png', + 'text' => JText::_('MOD_QUICKICON_LANGUAGE_MANAGER'), + 'access' => array('core.manage', 'com_languages'), + 'group' => 'MOD_QUICKICON_CONFIGURATION', + ), + array( + 'link' => JRoute::_('index.php?option=com_installer'), + 'image' => 'download', + 'icon' => 'header/icon-48-extension.png', + 'text' => JText::_('MOD_QUICKICON_INSTALL_EXTENSIONS'), + 'access' => array('core.manage', 'com_installer'), + 'group' => 'MOD_QUICKICON_EXTENSIONS', + ), + ); + } + else + { + self::$buttons[$key] = array(); + } + + // Include buttons defined by published quickicon plugins + JPluginHelper::importPlugin('quickicon'); + $app = JFactory::getApplication(); + $arrays = (array) $app->triggerEvent('onGetIcons', array($context)); + + foreach ($arrays as $response) + { + foreach ($response as $icon) + { + $default = array( + 'link' => null, + 'image' => 'cog', + 'text' => null, + 'access' => true, + 'group' => 'MOD_QUICKICON_EXTENSIONS', + ); + $icon = array_merge($default, $icon); + + if (!is_null($icon['link']) && !is_null($icon['text'])) + { + self::$buttons[$key][] = $icon; + } + } + } + } + + return self::$buttons[$key]; + } + + /** + * Classifies the $buttons by group + * + * @param array $buttons The buttons + * + * @return array The buttons sorted by groups + * + * @since 3.2 + */ + public static function groupButtons($buttons) + { + $groupedButtons = array(); + + foreach ($buttons as $button) + { + $groupedButtons[$button['group']][] = $button; + } + + return $groupedButtons; + } + + /** + * Get the alternate title for the module + * + * @param JObject $params The module parameters. + * @param JObject $module The module. + * + * @return string The alternate title for the module. + * + * @deprecated 4.0 Unused. Title can be adjusted in module itself if needed. + */ + public static function getTitle($params, $module) + { + $key = $params->get('context', 'mod_quickicon') . '_title'; + + if (JFactory::getLanguage()->hasKey($key)) + { + return JText::_($key); + } + else + { + return $module->title; + } + } +} diff --git a/Sites/pages/administrator/modules/mod_quickicon/mod_quickicon.php b/Sites/pages/administrator/modules/mod_quickicon/mod_quickicon.php new file mode 100644 index 00000000..767b6146 --- /dev/null +++ b/Sites/pages/administrator/modules/mod_quickicon/mod_quickicon.php @@ -0,0 +1,16 @@ +get('layout', 'default')); diff --git a/Sites/pages/administrator/modules/mod_quickicon/mod_quickicon.xml b/Sites/pages/administrator/modules/mod_quickicon/mod_quickicon.xml new file mode 100644 index 00000000..7499da97 --- /dev/null +++ b/Sites/pages/administrator/modules/mod_quickicon/mod_quickicon.xml @@ -0,0 +1,72 @@ + + + mod_quickicon + Joomla! Project + November 2005 + Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. + GNU General Public License version 2 or later; see LICENSE.txt + admin@joomla.org + www.joomla.org + 3.0.0 + MOD_QUICKICON_XML_DESCRIPTION + + mod_quickicon.php + tmpl + helper.php + + + en-GB.mod_quickicon.ini + en-GB.mod_quickicon.sys.ini + + + + +
    + +
    +
    + + + + + + + + + + +
    +
    +
    +
    diff --git a/Sites/pages/administrator/modules/mod_quickicon/tmpl/default.php b/Sites/pages/administrator/modules/mod_quickicon/tmpl/default.php new file mode 100644 index 00000000..2052a45e --- /dev/null +++ b/Sites/pages/administrator/modules/mod_quickicon/tmpl/default.php @@ -0,0 +1,18 @@ + + + + diff --git a/Sites/pages/administrator/modules/mod_sampledata/helper.php b/Sites/pages/administrator/modules/mod_sampledata/helper.php new file mode 100644 index 00000000..f8411384 --- /dev/null +++ b/Sites/pages/administrator/modules/mod_sampledata/helper.php @@ -0,0 +1,34 @@ +trigger('onSampledataGetOverview', array('test', 'foo')); + + return $data; + } +} diff --git a/Sites/pages/administrator/modules/mod_sampledata/mod_sampledata.php b/Sites/pages/administrator/modules/mod_sampledata/mod_sampledata.php new file mode 100644 index 00000000..0331b929 --- /dev/null +++ b/Sites/pages/administrator/modules/mod_sampledata/mod_sampledata.php @@ -0,0 +1,20 @@ +get('layout', 'default')); diff --git a/Sites/pages/administrator/modules/mod_sampledata/mod_sampledata.xml b/Sites/pages/administrator/modules/mod_sampledata/mod_sampledata.xml new file mode 100644 index 00000000..47c90886 --- /dev/null +++ b/Sites/pages/administrator/modules/mod_sampledata/mod_sampledata.xml @@ -0,0 +1,37 @@ + + + mod_sampledata + Joomla! Project + July 2017 + Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. + GNU General Public License version 2 or later; see LICENSE.txt + admin@joomla.org + www.joomla.org + 3.8.0 + MOD_SAMPLEDATA_XML_DESCRIPTION + + mod_sampledata.php + helper.php + tmpl + + + js + + + en-GB.mod_sampledata.ini + en-GB.mod_sampledata.sys.ini + + + + +
    + +
    +
    +
    +
    diff --git a/Sites/pages/administrator/modules/mod_sampledata/tmpl/default.php b/Sites/pages/administrator/modules/mod_sampledata/tmpl/default.php new file mode 100644 index 00000000..101e19f3 --- /dev/null +++ b/Sites/pages/administrator/modules/mod_sampledata/tmpl/default.php @@ -0,0 +1,59 @@ +addScriptDeclaration(' + var modSampledataUrl = "index.php?option=com_ajax&format=json&group=sampledata&' . Session::getFormToken() . '=1", + modSampledataIconProgress = "' . JUri::root(true) . '/media/jui/images/ajax-loader.gif"; +'); +?> +
    + +
    + $item) : ?> +
    + +
    + + description; ?> + +
    +
    + +
    + +
    + +
    +
      +
      + +
      + +
      + +
      diff --git a/Sites/pages/administrator/modules/mod_stats_admin/helper.php b/Sites/pages/administrator/modules/mod_stats_admin/helper.php new file mode 100644 index 00000000..63a72058 --- /dev/null +++ b/Sites/pages/administrator/modules/mod_stats_admin/helper.php @@ -0,0 +1,184 @@ +getQuery(true); + + $serverinfo = $params->get('serverinfo', 0); + $siteinfo = $params->get('siteinfo', 0); + $counter = $params->get('counter', 0); + $increase = $params->get('increase', 0); + + $i = 0; + + if ($serverinfo) + { + $rows[$i] = new stdClass; + $rows[$i]->title = JText::_('MOD_STATS_OS'); + $rows[$i]->icon = 'screen'; + $rows[$i]->data = substr(php_uname(), 0, 7); + $i++; + + $rows[$i] = new stdClass; + $rows[$i]->title = JText::_('MOD_STATS_PHP'); + $rows[$i]->icon = 'cogs'; + $rows[$i]->data = phpversion(); + $i++; + + $rows[$i] = new stdClass; + $rows[$i]->title = JText::_($db->name); + $rows[$i]->icon = 'database'; + $rows[$i]->data = $db->getVersion(); + $i++; + + $rows[$i] = new stdClass; + $rows[$i]->title = JText::_('MOD_STATS_TIME'); + $rows[$i]->icon = 'clock'; + $rows[$i]->data = JHtml::_('date', 'now', 'H:i'); + $i++; + + $rows[$i] = new stdClass; + $rows[$i]->title = JText::_('MOD_STATS_CACHING'); + $rows[$i]->icon = 'dashboard'; + $rows[$i]->data = $app->get('caching') ? JText::_('JENABLED') : JText::_('JDISABLED'); + $i++; + + $rows[$i] = new stdClass; + $rows[$i]->title = JText::_('MOD_STATS_GZIP'); + $rows[$i]->icon = 'lightning'; + $rows[$i]->data = $app->get('gzip') ? JText::_('JENABLED') : JText::_('JDISABLED'); + $i++; + } + + if ($siteinfo) + { + $query->select('COUNT(id) AS count_users') + ->from('#__users'); + $db->setQuery($query); + + try + { + $users = $db->loadResult(); + } + catch (RuntimeException $e) + { + $users = false; + } + + $query->clear() + ->select('COUNT(id) AS count_items') + ->from('#__content') + ->where('state = 1'); + $db->setQuery($query); + + try + { + $items = $db->loadResult(); + } + catch (RuntimeException $e) + { + $items = false; + } + + if ($users) + { + $rows[$i] = new stdClass; + $rows[$i]->title = JText::_('MOD_STATS_USERS'); + $rows[$i]->icon = 'users'; + $rows[$i]->data = $users; + $rows[$i]->link = JRoute::_('index.php?option=com_users'); + $i++; + } + + if ($items) + { + $rows[$i] = new stdClass; + $rows[$i]->title = JText::_('MOD_STATS_ARTICLES'); + $rows[$i]->icon = 'file'; + $rows[$i]->data = $items; + $rows[$i]->link = JRoute::_('index.php?option=com_content&view=articles&filter[published]=1'); + $i++; + } + } + + if ($counter) + { + $query->clear() + ->select('SUM(hits) AS count_hits') + ->from('#__content') + ->where('state = 1'); + $db->setQuery($query); + + try + { + $hits = $db->loadResult(); + } + catch (RuntimeException $e) + { + $hits = false; + } + + if ($hits) + { + $rows[$i] = new stdClass; + $rows[$i]->title = JText::_('MOD_STATS_ARTICLES_VIEW_HITS'); + $rows[$i]->icon = 'eye'; + $rows[$i]->data = number_format($hits + $increase, 0, JText::_('DECIMALS_SEPARATOR'), JText::_('THOUSANDS_SEPARATOR')); + $i++; + } + } + + // Include additional data defined by published system plugins + JPluginHelper::importPlugin('system'); + + $app = JFactory::getApplication(); + $arrays = (array) $app->triggerEvent('onGetStats', array('mod_stats_admin')); + + foreach ($arrays as $response) + { + foreach ($response as $row) + { + // We only add a row if the title and data are given + if (isset($row['title']) && isset($row['data'])) + { + $rows[$i] = new stdClass; + $rows[$i]->title = $row['title']; + $rows[$i]->icon = isset($row['icon']) ? $row['icon'] : 'info'; + $rows[$i]->data = $row['data']; + $rows[$i]->link = isset($row['link']) ? $row['link'] : null; + $i++; + } + } + } + + return $rows; + } +} diff --git a/Sites/pages/administrator/modules/mod_stats_admin/language/en-GB.mod_stats_admin.ini b/Sites/pages/administrator/modules/mod_stats_admin/language/en-GB.mod_stats_admin.ini new file mode 100644 index 00000000..3fed56e9 --- /dev/null +++ b/Sites/pages/administrator/modules/mod_stats_admin/language/en-GB.mod_stats_admin.ini @@ -0,0 +1,24 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +MOD_STATS_ADMIN="Statistics" +MOD_STATS_ARTICLES="Articles" +MOD_STATS_ARTICLES_VIEW_HITS="Articles View Hits" +MOD_STATS_CACHING="Caching" +MOD_STATS_FIELD_COUNTER_DESC="Display hit counter." +MOD_STATS_FIELD_COUNTER_LABEL="Hit Counter" +MOD_STATS_FIELD_INCREASECOUNTER_DESC="Enter the number of hits to increase the counter by." +MOD_STATS_FIELD_INCREASECOUNTER_LABEL="Increase Counter" +MOD_STATS_FIELD_SERVERINFO_DESC="Display server information." +MOD_STATS_FIELD_SERVERINFO_LABEL="Server Information" +MOD_STATS_FIELD_SITEINFO_DESC="Display site information." +MOD_STATS_FIELD_SITEINFO_LABEL="Site Information" +MOD_STATS_GZIP="Gzip" +MOD_STATS_OS="OS" +MOD_STATS_PHP="PHP" +MOD_STATS_TIME="Time" +MOD_STATS_USERS="Users" +MOD_STATS_WEBLINKS="Web Links" +MOD_STATS_XML_DESCRIPTION="The Statistics Module shows information about your server installation together with statistics on the website users and the number of Articles in your database." diff --git a/Sites/pages/administrator/modules/mod_stats_admin/language/en-GB.mod_stats_admin.sys.ini b/Sites/pages/administrator/modules/mod_stats_admin/language/en-GB.mod_stats_admin.sys.ini new file mode 100644 index 00000000..a8f2609b --- /dev/null +++ b/Sites/pages/administrator/modules/mod_stats_admin/language/en-GB.mod_stats_admin.sys.ini @@ -0,0 +1,9 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +MOD_STATS_ADMIN="Statistics" +MOD_STATS_XML_DESCRIPTION="The Statistics Module shows information about your server installation together with statistics on the website users and the number of Articles in your database." +MOD_STATS_LAYOUT_DEFAULT="Default" + diff --git a/Sites/pages/administrator/modules/mod_stats_admin/mod_stats_admin.php b/Sites/pages/administrator/modules/mod_stats_admin/mod_stats_admin.php new file mode 100644 index 00000000..92b6752f --- /dev/null +++ b/Sites/pages/administrator/modules/mod_stats_admin/mod_stats_admin.php @@ -0,0 +1,20 @@ +get('serverinfo'); +$siteinfo = $params->get('siteinfo'); +$list = ModStatsHelper::getStats($params); +$moduleclass_sfx = htmlspecialchars($params->get('moduleclass_sfx'), ENT_COMPAT, 'UTF-8'); + +require JModuleHelper::getLayoutPath('mod_stats_admin', $params->get('layout', 'default')); diff --git a/Sites/pages/administrator/modules/mod_stats_admin/mod_stats_admin.xml b/Sites/pages/administrator/modules/mod_stats_admin/mod_stats_admin.xml new file mode 100644 index 00000000..da520de4 --- /dev/null +++ b/Sites/pages/administrator/modules/mod_stats_admin/mod_stats_admin.xml @@ -0,0 +1,121 @@ + + + mod_stats_admin + Joomla! Project + July 2004 + Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. + GNU General Public License version 2 or later; see LICENSE.txt + admin@joomla.org + www.joomla.org + 3.0.0 + MOD_STATS_XML_DESCRIPTION + + mod_stats_admin.php + tmpl + language + helper.php + + + en-GB.mod_stats.ini + en-GB.mod_stats.sys.ini + + + + +
      + + + + + + + + + + + + + + + + +
      +
      + + + + + + + + + + + + + + +
      +
      +
      +
      diff --git a/Sites/pages/administrator/modules/mod_stats_admin/tmpl/default.php b/Sites/pages/administrator/modules/mod_stats_admin/tmpl/default.php new file mode 100644 index 00000000..1854c91c --- /dev/null +++ b/Sites/pages/administrator/modules/mod_stats_admin/tmpl/default.php @@ -0,0 +1,44 @@ +addScriptDeclaration(' + jQuery(document).ready(function($) { + $("a.js-revert").on("click", function(e) { + e.preventDefault(); + e.stopPropagation(); + + var activeTab = []; + activeTab.push("#" + e.target.href.split("#")[1]); + var path = window.location.pathname; + localStorage.removeItem(e.target.href.replace(/&return=[a-zA-Z0-9%]+/, "").replace(/&[a-zA-Z-_]+=[0-9]+/, "")); + localStorage.setItem(path + e.target.href.split("index.php")[1].split("#")[0], JSON.stringify(activeTab)); + return window.location.href = e.target.href.split("#")[0]; + }); + }); +'); +?> +
      + +
      +
      + title; ?> +
      +
      + link)) : ?> + data; ?> + + data; ?> + +
      +
      + +
      diff --git a/Sites/pages/administrator/modules/mod_status/mod_status.php b/Sites/pages/administrator/modules/mod_status/mod_status.php new file mode 100644 index 00000000..ba90ced2 --- /dev/null +++ b/Sites/pages/administrator/modules/mod_status/mod_status.php @@ -0,0 +1,89 @@ +input; + +// Get the number of unread messages in your inbox. +$query = $db->getQuery(true) + ->select('COUNT(*)') + ->from('#__messages') + ->where('state = 0 AND user_id_to = ' . (int) $user->get('id')); + +$db->setQuery($query); +$unread = (int) $db->loadResult(); + +$count = 0; + +// Get the number of backend logged in users if shared sessions is not enabled. +if (!$config->get('shared_session', '0')) +{ + $query->clear() + ->select('COUNT(session_id)') + ->from('#__session') + ->where('guest = 0 AND client_id = 1'); + + $db->setQuery($query); + $count = (int) $db->loadResult(); +} + +// Set the inbox link. +if ($input->getBool('hidemainmenu')) +{ + $inboxLink = ''; +} +else +{ + $inboxLink = JRoute::_('index.php?option=com_messages'); +} + +// Set the inbox class. +if ($unread) +{ + $inboxClass = 'unread-messages'; +} +else +{ + $inboxClass = 'no-unread-messages'; +} + +$online_num = 0; + +// Get the number of frontend logged in users if shared sessions is not enabled. +if (!$config->get('shared_session', '0')) +{ + $query->clear() + ->select('COUNT(session_id)') + ->from('#__session') + ->where('guest = 0 AND client_id = 0'); + + $db->setQuery($query); + $online_num = (int) $db->loadResult(); +} + +$total_users = 0; + +// Get the number of logged in users if shared sessions is enabled. +if ($config->get('shared_session', '0')) +{ + $query->clear() + ->select('COUNT(session_id)') + ->from('#__session') + ->where('guest = 0'); + + $db->setQuery($query); + $total_users = (int) $db->loadResult(); +} + +require JModuleHelper::getLayoutPath('mod_status', $params->get('layout', 'default')); diff --git a/Sites/pages/administrator/modules/mod_status/mod_status.xml b/Sites/pages/administrator/modules/mod_status/mod_status.xml new file mode 100644 index 00000000..21456dd9 --- /dev/null +++ b/Sites/pages/administrator/modules/mod_status/mod_status.xml @@ -0,0 +1,108 @@ + + + mod_status + Joomla! Project + February 2006 + (C) 2005 - 2020 Open Source Matters. All rights reserved. + GNU General Public License version 2 or later; see LICENSE.txt + admin@joomla.org + www.joomla.org + 3.0.0 + MOD_STATUS_XML_DESCRIPTION + + mod_status.php + tmpl + + + en-GB.mod_status.ini + en-GB.mod_status.sys.ini + + + + +
      + + + + + + + + + + + + + + + + + + + + + + + + +
      + +
      + + + +
      +
      +
      +
      diff --git a/Sites/pages/administrator/modules/mod_status/tmpl/default.php b/Sites/pages/administrator/modules/mod_status/tmpl/default.php new file mode 100644 index 00000000..1fcc2b48 --- /dev/null +++ b/Sites/pages/administrator/modules/mod_status/tmpl/default.php @@ -0,0 +1,114 @@ +getBool('hidemainmenu'); +$task = $input->getCmd('task'); +$output = array(); + +// Print the Preview link to Main site. +if ($params->get('show_viewsite', 1)) +{ + // Gets the FrontEnd Main page Uri + $frontEndUri = JUri::getInstance(JUri::root()); + $frontEndUri->setScheme(((int) JFactory::getApplication()->get('force_ssl', 0) === 2) ? 'https' : 'http'); + + $output[] = ''; +} + +// Print the link to open a new Administrator window. +if ($params->get('show_viewadmin', 0)) +{ + $output[] = ''; +} + +// Print logged in user count based on the shared session state +if (JFactory::getConfig()->get('shared_session', '0')) +{ + // Print the frontend logged in users. + if ($params->get('show_loggedin_users', 1)) + { + $output[] = '
      ' + . '' . $total_users . '' + . JText::plural('MOD_STATUS_TOTAL_USERS', $total_users) + . '' + . '
      '; + } +} +else +{ + // Print the frontend logged in users. + if ($params->get('show_loggedin_users', 1)) + { + $output[] = '
      ' + . '' . $online_num . '' + . JText::plural('MOD_STATUS_USERS', $online_num) + . '' + . '
      '; + } + + // Print the backend logged in users. + if ($params->get('show_loggedin_users_admin', 1)) + { + $output[] = '
      ' + . '' . $count . '' + . JText::plural('MOD_STATUS_BACKEND_USERS', $count) + . '' + . '
      '; + } +} + +// Print the inbox message. +if ($params->get('show_messages', 1)) +{ + $active = $unread ? ' badge-warning' : ''; + $output[] = ''; +} + +// Print the logout link. +if ($task == 'edit' || $task == 'editA' || $input->getInt('hidemainmenu')) +{ + $logoutLink = ''; +} +else +{ + $logoutLink = JRoute::_('index.php?option=com_login&task=logout&' . JSession::getFormToken() . '=1'); +} + +if ($params->get('show_logout', 1)) +{ + $output[] = ''; +} + +// Output the items. +foreach ($output as $item) +{ + echo $item; +} diff --git a/Sites/pages/administrator/modules/mod_submenu/mod_submenu.php b/Sites/pages/administrator/modules/mod_submenu/mod_submenu.php new file mode 100644 index 00000000..4ae13230 --- /dev/null +++ b/Sites/pages/administrator/modules/mod_submenu/mod_submenu.php @@ -0,0 +1,24 @@ +input->getBool('hidemainmenu'); + +if ($displayMenu || $displayFilters) +{ + require JModuleHelper::getLayoutPath('mod_submenu', $params->get('layout', 'default')); +} diff --git a/Sites/pages/administrator/modules/mod_submenu/mod_submenu.xml b/Sites/pages/administrator/modules/mod_submenu/mod_submenu.xml new file mode 100644 index 00000000..4f3b9b46 --- /dev/null +++ b/Sites/pages/administrator/modules/mod_submenu/mod_submenu.xml @@ -0,0 +1,41 @@ + + + mod_submenu + Joomla! Project + February 2006 + Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. + GNU General Public License version 2 or later; see LICENSE.txt + admin@joomla.org + www.joomla.org + 3.0.0 + MOD_SUBMENU_XML_DESCRIPTION + + mod_submenu.php + tmpl + + + en-GB.mod_submenu.ini + en-GB.mod_submenu.sys.ini + + + + +
      + + + +
      +
      +
      +
      diff --git a/Sites/pages/administrator/modules/mod_submenu/tmpl/default.php b/Sites/pages/administrator/modules/mod_submenu/tmpl/default.php new file mode 100644 index 00000000..1b43f744 --- /dev/null +++ b/Sites/pages/administrator/modules/mod_submenu/tmpl/default.php @@ -0,0 +1,57 @@ + + diff --git a/Sites/pages/administrator/modules/mod_title/mod_title.php b/Sites/pages/administrator/modules/mod_title/mod_title.php new file mode 100644 index 00000000..3e639179 --- /dev/null +++ b/Sites/pages/administrator/modules/mod_title/mod_title.php @@ -0,0 +1,18 @@ +JComponentTitle)) +{ + $title = JFactory::getApplication()->JComponentTitle; +} + +require JModuleHelper::getLayoutPath('mod_title', $params->get('layout', 'default')); diff --git a/Sites/pages/administrator/modules/mod_title/mod_title.xml b/Sites/pages/administrator/modules/mod_title/mod_title.xml new file mode 100644 index 00000000..14901224 --- /dev/null +++ b/Sites/pages/administrator/modules/mod_title/mod_title.xml @@ -0,0 +1,41 @@ + + + mod_title + Joomla! Project + November 2005 + Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. + GNU General Public License version 2 or later; see LICENSE.txt + admin@joomla.org + www.joomla.org + 3.0.0 + MOD_TITLE_XML_DESCRIPTION + + mod_title.php + tmpl + + + en-GB.mod_title.ini + en-GB.mod_title.sys.ini + + + + +
      + + + +
      +
      +
      +
      diff --git a/Sites/pages/administrator/modules/mod_title/tmpl/default.php b/Sites/pages/administrator/modules/mod_title/tmpl/default.php new file mode 100644 index 00000000..18c214d8 --- /dev/null +++ b/Sites/pages/administrator/modules/mod_title/tmpl/default.php @@ -0,0 +1,14 @@ + + + + diff --git a/Sites/pages/administrator/modules/mod_toolbar/mod_toolbar.php b/Sites/pages/administrator/modules/mod_toolbar/mod_toolbar.php new file mode 100644 index 00000000..7b6f347c --- /dev/null +++ b/Sites/pages/administrator/modules/mod_toolbar/mod_toolbar.php @@ -0,0 +1,14 @@ +render('toolbar'); + +require JModuleHelper::getLayoutPath('mod_toolbar', $params->get('layout', 'default')); diff --git a/Sites/pages/administrator/modules/mod_toolbar/mod_toolbar.xml b/Sites/pages/administrator/modules/mod_toolbar/mod_toolbar.xml new file mode 100644 index 00000000..505b376f --- /dev/null +++ b/Sites/pages/administrator/modules/mod_toolbar/mod_toolbar.xml @@ -0,0 +1,41 @@ + + + mod_toolbar + Joomla! Project + November 2005 + Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. + GNU General Public License version 2 or later; see LICENSE.txt + admin@joomla.org + www.joomla.org + 3.0.0 + MOD_TOOLBAR_XML_DESCRIPTION + + mod_toolbar.php + tmpl + + + en-GB.mod_toolbar.ini + en-GB.mod_toolbar.sys.ini + + + + +
      + + + +
      +
      +
      +
      diff --git a/Sites/pages/administrator/modules/mod_toolbar/tmpl/default.php b/Sites/pages/administrator/modules/mod_toolbar/tmpl/default.php new file mode 100644 index 00000000..04a59a7a --- /dev/null +++ b/Sites/pages/administrator/modules/mod_toolbar/tmpl/default.php @@ -0,0 +1,13 @@ +getShortVersion(); + $product = $params->get('product', 1); + + if ($params->get('format', 'short') === 'long') + { + $versionText = str_replace($version::PRODUCT . ' ', '', $version->getLongVersion()); + } + + if (!empty($product)) + { + $versionText = $version::PRODUCT . ' ' . $versionText; + } + + return $versionText; + } +} diff --git a/Sites/pages/administrator/modules/mod_version/language/en-GB/en-GB.mod_version.ini b/Sites/pages/administrator/modules/mod_version/language/en-GB/en-GB.mod_version.ini new file mode 100644 index 00000000..3e6bfb65 --- /dev/null +++ b/Sites/pages/administrator/modules/mod_version/language/en-GB/en-GB.mod_version.ini @@ -0,0 +1,13 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +MOD_VERSION="Joomla! Version Information" +MOD_VERSION_FORMAT_DESC="The long version includes code name and date." +MOD_VERSION_FORMAT_LABEL="Version Format" +MOD_VERSION_FORMAT_LONG="Long" +MOD_VERSION_FORMAT_SHORT="Short" +MOD_VERSION_PRODUCT_DESC="Include Joomla! name when using short format." +MOD_VERSION_PRODUCT_LABEL="Show Joomla!" +MOD_VERSION_XML_DESCRIPTION="This module displays the Joomla! version." \ No newline at end of file diff --git a/Sites/pages/administrator/modules/mod_version/language/en-GB/en-GB.mod_version.sys.ini b/Sites/pages/administrator/modules/mod_version/language/en-GB/en-GB.mod_version.sys.ini new file mode 100644 index 00000000..88f7539f --- /dev/null +++ b/Sites/pages/administrator/modules/mod_version/language/en-GB/en-GB.mod_version.sys.ini @@ -0,0 +1,8 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +MOD_VERSION="Joomla! Version Information" +MOD_VERSION_LAYOUT_DEFAULT="Default" +MOD_VERSION_XML_DESCRIPTION="This module displays the Joomla! version." diff --git a/Sites/pages/administrator/modules/mod_version/mod_version.php b/Sites/pages/administrator/modules/mod_version/mod_version.php new file mode 100644 index 00000000..52424fbf --- /dev/null +++ b/Sites/pages/administrator/modules/mod_version/mod_version.php @@ -0,0 +1,16 @@ +get('layout', 'default')); diff --git a/Sites/pages/administrator/modules/mod_version/mod_version.xml b/Sites/pages/administrator/modules/mod_version/mod_version.xml new file mode 100644 index 00000000..7e54e3ac --- /dev/null +++ b/Sites/pages/administrator/modules/mod_version/mod_version.xml @@ -0,0 +1,68 @@ + + + mod_version + Joomla! Project + January 2012 + Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. + GNU General Public License version 2 or later; see LICENSE.txt + admin@joomla.org + www.joomla.org + 3.0.0 + MOD_VERSION_XML_DESCRIPTION + + mod_version.php + language + tmpl + helper.php + + + language/en-GB/en-GB.mod_version.ini + language/en-GB/en-GB.mod_version.sys.ini + + + + +
      + + + + + + + + + +
      +
      + + + +
      +
      +
      +
      diff --git a/Sites/pages/administrator/modules/mod_version/tmpl/default.php b/Sites/pages/administrator/modules/mod_version/tmpl/default.php new file mode 100644 index 00000000..8de19fcd --- /dev/null +++ b/Sites/pages/administrator/modules/mod_version/tmpl/default.php @@ -0,0 +1,14 @@ + + +

      + diff --git a/Sites/pages/administrator/templates/hathor/LICENSE.txt b/Sites/pages/administrator/templates/hathor/LICENSE.txt new file mode 100644 index 00000000..df50810b --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/LICENSE.txt @@ -0,0 +1,340 @@ +GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/Sites/pages/administrator/templates/hathor/component.php b/Sites/pages/administrator/templates/hathor/component.php new file mode 100644 index 00000000..52f2bf4b --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/component.php @@ -0,0 +1,98 @@ +load('tpl_hathor', JPATH_ADMINISTRATOR) +|| $lang->load('tpl_hathor', JPATH_ADMINISTRATOR . '/templates/hathor/language'); + +$app = JFactory::getApplication(); + +// Output as HTML5 +$this->setHtml5(true); + +// jQuery needed by template.js +JHtml::_('jquery.framework'); + +// Add template js +JHtml::_('script', 'template.js', array('version' => 'auto', 'relative' => true)); + +// Add html5 shiv +JHtml::_('script', 'jui/html5.js', array('version' => 'auto', 'relative' => true, 'conditional' => 'lt IE 9')); + +// Load optional RTL Bootstrap CSS +JHtml::_('bootstrap.loadCss', false, $this->direction); + +// Load system style CSS +JHtml::_('stylesheet', 'templates/system/css/system.css', array('version' => 'auto')); + +// Loadtemplate CSS +JHtml::_('stylesheet', 'template.css', array('version' => 'auto', 'relative' => true)); + +// Load additional CSS styles for colors +if (!$this->params->get('colourChoice')) +{ + $colour = 'standard'; +} +else +{ + $colour = htmlspecialchars($this->params->get('colourChoice')); +} + +JHtml::_('stylesheet', 'colour_' . $colour . '.css', array('version' => 'auto', 'relative' => true)); + +// Load additional CSS styles for rtl sites +if ($this->direction === 'rtl') +{ + JHtml::_('stylesheet', 'template_rtl.css', array('version' => 'auto', 'relative' => true)); + JHtml::_('stylesheet', 'colour_' . $colour . '_rtl.css', array('version' => 'auto', 'relative' => true)); +} + +// Load additional CSS styles for bold Text +if ($this->params->get('boldText')) +{ + JHtml::_('stylesheet', 'boldtext.css', array('version' => 'auto', 'relative' => true)); +} + +// Load specific language related CSS +JHtml::_('stylesheet', 'administrator/language/' . $lang->getTag() . '/' . $lang->getTag() . '.css', array('version' => 'auto')); + +// Load custom.css +JHtml::_('stylesheet', 'custom.css', array('version' => 'auto', 'relative' => true)); + +// IE specific +JHtml::_('stylesheet', 'ie8.css', array('version' => 'auto', 'relative' => true, 'conditional' => 'IE 8')); +JHtml::_('stylesheet', 'ie7.css', array('version' => 'auto', 'relative' => true, 'conditional' => 'IE 7')); + +// Logo file +if ($this->params->get('logoFile')) +{ + $logo = JUri::root() . $this->params->get('logoFile'); +} +else +{ + $logo = $this->baseurl . '/templates/' . $this->template . '/images/logo.png'; +} + +?> + + + + + + + + + + diff --git a/Sites/pages/administrator/templates/hathor/cpanel.php b/Sites/pages/administrator/templates/hathor/cpanel.php new file mode 100644 index 00000000..abe75f96 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/cpanel.php @@ -0,0 +1,158 @@ +setHtml5(true); + +// Add template js +JHtml::_('script', 'template.js', array('version' => 'auto', 'relative' => true)); + +// Add html5 shiv +JHtml::_('script', 'jui/html5.js', array('version' => 'auto', 'relative' => true, 'conditional' => 'lt IE 9')); + +// Load optional RTL Bootstrap CSS +JHtml::_('bootstrap.loadCss', false, $this->direction); + +// Load system style CSS +JHtml::_('stylesheet', 'templates/system/css/system.css', array('version' => 'auto')); + +// Load template CSS +JHtml::_('stylesheet', 'template.css', array('version' => 'auto', 'relative' => true)); + +// Load additional CSS styles for colors +if (!$this->params->get('colourChoice')) +{ + $colour = 'standard'; +} +else +{ + $colour = htmlspecialchars($this->params->get('colourChoice')); +} + +JHtml::_('stylesheet', 'colour_' . $colour . '.css', array('version' => 'auto', 'relative' => true)); + +// Load additional CSS styles for rtl sites +if ($this->direction === 'rtl') +{ + JHtml::_('stylesheet', 'template_rtl.css', array('version' => 'auto', 'relative' => true)); + JHtml::_('stylesheet', 'colour_' . $colour . '_rtl.css', array('version' => 'auto', 'relative' => true)); +} + +// Load additional CSS styles for bold Text +if ($this->params->get('boldText')) +{ + JHtml::_('stylesheet', 'boldtext.css', array('version' => 'auto', 'relative' => true)); +} + +// Load specific language related CSS +JHtml::_('stylesheet', 'administrator/language/' . $lang->getTag() . '/' . $lang->getTag() . '.css', array('version' => 'auto')); + +// Load custom.css +JHtml::_('stylesheet', 'custom.css', array('version' => 'auto', 'relative' => true)); + +// IE specific +JHtml::_('stylesheet', 'ie8.css', array('version' => 'auto', 'relative' => true, 'conditional' => 'IE 8')); +JHtml::_('stylesheet', 'ie7.css', array('version' => 'auto', 'relative' => true, 'conditional' => 'IE 7')); + +// Logo file +if ($this->params->get('logoFile')) +{ + $logo = JUri::root() . $this->params->get('logoFile'); +} +else +{ + $logo = $this->baseurl . '/templates/' . $this->template . '/images/logo.png'; +} + +?> + + + + + + +
      + + + + + +
      + +
      + +
      + + + + + +
      +
      + +
      +

      +
      + +
      + +
      + +
      + +
      +
      +
      +
      + +
      +
      +
      +
      + + + + diff --git a/Sites/pages/administrator/templates/hathor/css/boldtext.css b/Sites/pages/administrator/templates/hathor/css/boldtext.css new file mode 100644 index 00000000..02758b88 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/css/boldtext.css @@ -0,0 +1,18 @@ +@charset "UTF-8"; + +/** + * @package Joomla.Administrator + * @subpackage templates.hathor + * @copyright Copyright (C) 2005 - 2020 Open Source Matters, Inc. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + * @since 1.6 + * + * Changes to use bold text as the default + */ + +/** + * Default to bold text + */ +body { + font-weight: bold; +} diff --git a/Sites/pages/administrator/templates/hathor/css/colour_blue.css b/Sites/pages/administrator/templates/hathor/css/colour_blue.css new file mode 100644 index 00000000..1151b5fb --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/css/colour_blue.css @@ -0,0 +1,1802 @@ +.clearfix { + *zoom: 1; +} +.clearfix:before, +.clearfix:after { + display: table; + content: ""; + line-height: 0; +} +.clearfix:after { + clear: both; +} +.hide-text { + font: 0/0 a; + color: transparent; + text-shadow: none; + background-color: transparent; + border: 0; +} +.input-block-level { + display: block; + width: 100%; + min-height: 25px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +#form-login .btn { + display: inline-block; + *display: inline; + *zoom: 1; + padding: 4px 14px; + margin-bottom: 0; + font-size: 13px; + line-height: 15px; + *line-height: 15px; + text-align: center; + vertical-align: middle; + cursor: pointer; + color: #333333; + text-shadow: 0 1px 1px rgba(255,255,255,0.75); + background-color: #f5f5f5; + background-image: -moz-linear-gradient(top,#ffffff,#e6e6e6); + background-image: -webkit-gradient(linear,0 0,0 100%,from(#ffffff),to(#e6e6e6)); + background-image: -webkit-linear-gradient(top,#ffffff,#e6e6e6); + background-image: -o-linear-gradient(top,#ffffff,#e6e6e6); + background-image: linear-gradient(to bottom,#ffffff,#e6e6e6); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe5e5e5', GradientType=0); + border-color: #e6e6e6 #e6e6e6 #bfbfbf; + *background-color: #e6e6e6; + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + border: 1px solid #bbb; + *border: 0; + border-bottom-color: #a2a2a2; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + *margin-left: .3em; + -webkit-box-shadow: inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); + -moz-box-shadow: inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); + box-shadow: inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); +} +#form-login .btn:hover, +#form-login .btn:focus, +#form-login .btn:active, +#form-login .btn.active, +#form-login .btn.disabled, +#form-login .btn[disabled] { + color: #333333; + background-color: #e6e6e6; + *background-color: #d9d9d9; +} +#form-login .btn:active, +#form-login .btn.active { + background-color: #cccccc \9; +} +#form-login .btn:first-child { + *margin-left: 0; +} +#form-login .btn:hover { + color: #333333; + text-decoration: none; + background-color: #e6e6e6; + *background-color: #d9d9d9; + background-position: 0 -15px; + -webkit-transition: background-position .1s linear; + -moz-transition: background-position .1s linear; + -o-transition: background-position .1s linear; + transition: background-position .1s linear; +} +#form-login .btn:focus { + outline: thin dotted #333; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +#form-login .btn.active, +#form-login .btn:active { + background-color: #e6e6e6; + background-color: #d9d9d9 \9; + background-image: none; + outline: 0; + -webkit-box-shadow: inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05); + -moz-box-shadow: inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05); + box-shadow: inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05); +} +#form-login .btn.disabled, +#form-login .btn[disabled] { + cursor: default; + background-color: #e6e6e6; + background-image: none; + opacity: 0.65; + filter: alpha(opacity=65); + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; +} +.btn-large { + padding: 9px 14px; + font-size: 15px; + line-height: normal; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; +} +.btn-large [class^="icon-"] { + margin-top: 2px; +} +.input-append input[class*="span"], +.input-append .uneditable-input[class*="span"], +.input-prepend input[class*="span"], +.input-prepend .uneditable-input[class*="span"], +.row-fluid input[class*="span"], +.row-fluid select[class*="span"], +.row-fluid textarea[class*="span"], +.row-fluid .uneditable-input[class*="span"], +.row-fluid .input-prepend [class*="span"], +.row-fluid .input-append [class*="span"] { + display: inline-block; +} +.input-append, +.input-prepend { + margin-bottom: 5px; + font-size: 0; + white-space: nowrap; +} +.input-append input, +.input-append select, +.input-append .uneditable-input, +.input-prepend input, +.input-prepend select, +.input-prepend .uneditable-input { + position: relative; + margin-bottom: 0; + *margin-left: 0; + font-size: 13px; + vertical-align: top; + -webkit-border-radius: 0 3px 3px 0; + -moz-border-radius: 0 3px 3px 0; + border-radius: 0 3px 3px 0; +} +.input-append input:focus, +.input-append select:focus, +.input-append .uneditable-input:focus, +.input-prepend input:focus, +.input-prepend select:focus, +.input-prepend .uneditable-input:focus { + z-index: 2; +} +.input-append .add-on, +.input-prepend .add-on { + display: inline-block; + width: auto; + height: 15px; + min-width: 16px; + padding: 4px 5px; + font-size: 13px; + font-weight: normal; + line-height: 15px; + text-align: center; + text-shadow: 0 1px 0 #ffffff; + background-color: #eeeeee; + border: 1px solid #ccc; +} +.input-append .add-on, +.input-append .btn, +.input-prepend .add-on, +.input-prepend .btn { + margin-left: -1px; + vertical-align: top; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.input-append .active, +.input-prepend .active { + background-color: #a9dba9; + border-color: #46a546; +} +.input-prepend .add-on, +.input-prepend .btn { + margin-right: -1px; +} +.input-prepend .add-on:first-child, +.input-prepend .btn:first-child { + -webkit-border-radius: 3px 0 0 3px; + -moz-border-radius: 3px 0 0 3px; + border-radius: 3px 0 0 3px; +} +.input-append input, +.input-append select, +.input-append .uneditable-input { + -webkit-border-radius: 3px 0 0 3px; + -moz-border-radius: 3px 0 0 3px; + border-radius: 3px 0 0 3px; +} +.input-append .add-on:last-child, +.input-append .btn:last-child { + -webkit-border-radius: 0 3px 3px 0; + -moz-border-radius: 0 3px 3px 0; + border-radius: 0 3px 3px 0; +} +.input-prepend.input-append input, +.input-prepend.input-append select, +.input-prepend.input-append .uneditable-input { + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.input-prepend.input-append .add-on:first-child, +.input-prepend.input-append .btn:first-child { + margin-right: -1px; + -webkit-border-radius: 3px 0 0 3px; + -moz-border-radius: 3px 0 0 3px; + border-radius: 3px 0 0 3px; +} +.input-prepend.input-append .add-on:last-child, +.input-prepend.input-append .btn:last-child { + margin-left: -1px; + -webkit-border-radius: 0 3px 3px 0; + -moz-border-radius: 0 3px 3px 0; + border-radius: 0 3px 3px 0; +} +.form-search .input-append .search-query, +.form-search .input-prepend .search-query { + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.form-search .input-append .search-query { + -webkit-border-radius: 14px 0 0 14px; + -moz-border-radius: 14px 0 0 14px; + border-radius: 14px 0 0 14px; +} +.form-search .input-append .btn { + -webkit-border-radius: 0 14px 14px 0; + -moz-border-radius: 0 14px 14px 0; + border-radius: 0 14px 14px 0; +} +.form-search .input-prepend .search-query { + -webkit-border-radius: 0 14px 14px 0; + -moz-border-radius: 0 14px 14px 0; + border-radius: 0 14px 14px 0; +} +.form-search .input-prepend .btn { + -webkit-border-radius: 14px 0 0 14px; + -moz-border-radius: 14px 0 0 14px; + border-radius: 14px 0 0 14px; +} +.form-search input, +.form-search textarea, +.form-search select, +.form-search .help-inline, +.form-search .uneditable-input, +.form-search .input-prepend, +.form-search .input-append, +.form-inline input, +.form-inline textarea, +.form-inline select, +.form-inline .help-inline, +.form-inline .uneditable-input, +.form-inline .input-prepend, +.form-inline .input-append, +.form-horizontal input, +.form-horizontal textarea, +.form-horizontal select, +.form-horizontal .help-inline, +.form-horizontal .uneditable-input, +.form-horizontal .input-prepend, +.form-horizontal .input-append { + display: inline-block; + *display: inline; + *zoom: 1; + margin-bottom: 0; + vertical-align: middle; +} +.form-search .hide, +.form-inline .hide, +.form-horizontal .hide { + display: none; +} +.form-search .input-append, +.form-inline .input-append, +.form-search .input-prepend, +.form-inline .input-prepend { + margin-bottom: 0; +} +.element-invisible { + position: absolute; + padding: 0 !important; + margin: 0 !important; + border: 0; + height: 1px; + width: 1px !important; + overflow: hidden; +} +#form-login select, +#form-login input[type="text"], +#form-login input[type="password"] { + display: inline-block; + padding: 4px 6px; + margin-bottom: 9px; + font-size: 13px; + line-height: 15px; + color: #555555; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + width: 175px; +} +.subform-repeatable-wrapper div.btn-toolbar { + float: none; +} +.subform-repeatable-wrapper .text-right { + text-align: right; +} +.subform-repeatable-wrapper .ui-sortable-helper { + background: #ffffff; +} +.subform-repeatable-wrapper tr.ui-sortable-helper { + display: table; +} +.subform-repeatable-wrapper .subform-repeatable-group { + clear: both; +} +.label, +.badge { + display: inline-block; + padding: 2px 4px; + font-size: 10.998px; + font-weight: bold; + line-height: 14px; + color: #ffffff; + vertical-align: baseline; + white-space: nowrap; + text-shadow: 0 -1px 0 rgba(0,0,0,0.25); + background-color: #999999; +} +.label { + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} +.badge { + padding-left: 9px; + padding-right: 9px; + -webkit-border-radius: 9px; + -moz-border-radius: 9px; + border-radius: 9px; +} +.label:empty, +.badge:empty { + display: none; +} +a.label:hover, +a.label:focus, +a.badge:hover, +a.badge:focus { + color: #ffffff; + text-decoration: none; + cursor: pointer; +} +.label-important, +.badge-important { + background-color: #a20000; +} +.label-important[href], +.badge-important[href] { + background-color: #6f0000; +} +.label-warning, +.badge-warning { + background-color: #f89406; +} +.label-warning[href], +.badge-warning[href] { + background-color: #c67605; +} +.label-success, +.badge-success { + background-color: #005800; +} +.label-success[href], +.badge-success[href] { + background-color: #002500; +} +.label-info, +.badge-info { + background-color: #3a87ad; +} +.label-info[href], +.badge-info[href] { + background-color: #2d6987; +} +.label-inverse, +.badge-inverse { + background-color: #333333; +} +.label-inverse[href], +.badge-inverse[href] { + background-color: #1a1a1a; +} +.btn .label, +.btn .badge { + position: relative; + top: -1px; +} +.btn-mini .label, +.btn-mini .badge { + top: 0; +} +body { + background-color: #ffffff; + color: #2c2c2c; +} +h1 { + color: #2c2c2c; +} +a:link { + color: #054993; +} +a:visited { + color: #054993; +} +#header { + background: #ffffff url(../images/j_logo.png) no-repeat; +} +#header h1.title { + color: #2c2c2c; +} +#nav { + background-color: #b1c4db; + background-image: -moz-linear-gradient(top,#a5bbd4,#c3d2e5); + background-image: -webkit-gradient(linear,0 0,0 100%,from(#a5bbd4),to(#c3d2e5)); + background-image: -webkit-linear-gradient(top,#a5bbd4,#c3d2e5); + background-image: -o-linear-gradient(top,#a5bbd4,#c3d2e5); + background-image: linear-gradient(to bottom,#a5bbd4,#c3d2e5); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffa5bbd4', endColorstr='#ffc3d2e5', GradientType=0); + border: 1px solid #738498; +} +#content { + background: #ffffff; +} +#no-submenu { + border-bottom: 1px solid #738498; +} +#element-box { + background: #ffffff; + border-right: 1px solid #738498; + border-bottom: 1px solid #738498; + border-left: 1px solid #738498; +} +#element-box.login { + border-top: 1px solid #738498; +} +.enabled, +.success, +.allow, +span.writable { + color: #005800; +} +.disabled, +p.error, +.warning, +.deny, +span.unwritable { + color: #a20000; +} +.nowarning { + color: #2c2c2c; +} +.none, +.protected { + color: #738498; +} +span.note { + background: #ffffff; + color: #2c2c2c; +} +div.checkin-tick { + background: url(../images/admin/tick.png) 20px 50% no-repeat; +} +.ol-foreground { + background-color: #c3d2e5; +} +.ol-background { + background-color: #005800; +} +.ol-textfont { + color: #2c2c2c; +} +.ol-captionfont { + color: #ffffff; +} +.ol-captionfont a { + color: #054993; +} +div.subheader .padding { + background: #ffffff; +} +.pagetitle h2 { + color: #2c2c2c; +} +div.configuration { + color: #2c2c2c; + background-image: url(../images/menu/icon-16-config.png); + background-repeat: no-repeat; +} +div.toolbar-box { + border-right: 1px solid #738498; + border-bottom: 1px solid #738498; + border-left: 1px solid #738498; + background: #ffffff; +} +div.toolbar-list li { + color: #2c2c2c; +} +div.toolbar-list li.divider { + border-right: 1px dotted #e5d9c3; +} +div.toolbar-list a { + border-left: 1px solid #e5d9c3; + border-top: 1px solid #e5d9c3; + border-right: 1px solid #738498; + border-bottom: 1px solid #738498; + background: #c3d2e5; +} +div.toolbar-list a:hover { + border-left: 1px solid #868778; + border-top: 1px solid #868778; + border-right: 1px solid #f6f7db; + border-bottom: 1px solid #f6f7db; + background: #e5d9c3; + color: #054993; +} +div.btn-toolbar { + margin-left: 5px; + padding-top: 3px; +} +div.btn-toolbar li.divider { + border-right: 1px dotted #e5d9c3; +} +div.btn-toolbar div.btn-group button { + border-left: 1px solid #e5d9c3; + border-top: 1px solid #e5d9c3; + border-right: 1px solid #738498; + border-bottom: 1px solid #738498; + background-color: #b1c4db; + background-image: -moz-linear-gradient(top,#a5bbd4,#c3d2e5); + background-image: -webkit-gradient(linear,0 0,0 100%,from(#a5bbd4),to(#c3d2e5)); + background-image: -webkit-linear-gradient(top,#a5bbd4,#c3d2e5); + background-image: -o-linear-gradient(top,#a5bbd4,#c3d2e5); + background-image: linear-gradient(to bottom,#a5bbd4,#c3d2e5); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffa5bbd4', endColorstr='#ffc3d2e5', GradientType=0); + padding: 5px 4px 5px 4px; +} +div.btn-toolbar div.btn-group button:hover { + border-left: 1px solid #868778; + border-top: 1px solid #868778; + border-right: 1px solid #f6f7db; + border-bottom: 1px solid #f6f7db; + background: #e5d9c3; + color: #054993; + cursor: pointer; +} +div.btn-toolbar a { + border-left: 1px solid #e5d9c3; + border-top: 1px solid #e5d9c3; + border-right: 1px solid #738498; + border-bottom: 1px solid #738498; + background-color: #b1c4db; + background-image: -moz-linear-gradient(top,#a5bbd4,#c3d2e5); + background-image: -webkit-gradient(linear,0 0,0 100%,from(#a5bbd4),to(#c3d2e5)); + background-image: -webkit-linear-gradient(top,#a5bbd4,#c3d2e5); + background-image: -o-linear-gradient(top,#a5bbd4,#c3d2e5); + background-image: linear-gradient(to bottom,#a5bbd4,#c3d2e5); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffa5bbd4', endColorstr='#ffc3d2e5', GradientType=0); + padding: 6px 5px; + text-align: center; + white-space: nowrap; + font-size: 1.2em; + text-decoration: none; +} +div.btn-toolbar a:hover { + border-left: 1px solid #868778; + border-top: 1px solid #868778; + border-right: 1px solid #f6f7db; + border-bottom: 1px solid #f6f7db; + background: #e5d9c3; + color: #054993; + cursor: pointer; +} +div.btn-toolbar div.btn-group button.inactive { + background: #c3d2e5; +} +.pane-sliders .title { + color: #2c2c2c; +} +.pane-sliders .panel { + border: 1px solid #738498; +} +.pane-sliders .panel h3 { + background-color: #b1c4db; + background-image: -moz-linear-gradient(top,#a5bbd4,#c3d2e5); + background-image: -webkit-gradient(linear,0 0,0 100%,from(#a5bbd4),to(#c3d2e5)); + background-image: -webkit-linear-gradient(top,#a5bbd4,#c3d2e5); + background-image: -o-linear-gradient(top,#a5bbd4,#c3d2e5); + background-image: linear-gradient(to bottom,#a5bbd4,#c3d2e5); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffa5bbd4', endColorstr='#ffc3d2e5', GradientType=0); + color: #054993; +} +.pane-sliders .panel h3:hover { + background: #e5d9c3; +} +.pane-sliders .panel h3:hover a { + text-decoration: none; +} +.pane-sliders .adminlist { + border: 0 none; +} +.pane-sliders .adminlist td { + border: 0 none; +} +.pane-toggler span { + background: transparent url(../images/j_arrow.png) 5px 50% no-repeat; +} +.pane-toggler-down span { + background: transparent url(../images/j_arrow_down.png) 5px 50% no-repeat; +} +.pane-toggler-down { + border-bottom: 1px solid #738498; +} +dl.tabs dt { + border: 1px solid #738498; + background-color: #b1c4db; + background-image: -moz-linear-gradient(top,#a5bbd4,#c3d2e5); + background-image: -webkit-gradient(linear,0 0,0 100%,from(#a5bbd4),to(#c3d2e5)); + background-image: -webkit-linear-gradient(top,#a5bbd4,#c3d2e5); + background-image: -o-linear-gradient(top,#a5bbd4,#c3d2e5); + background-image: linear-gradient(to bottom,#a5bbd4,#c3d2e5); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffa5bbd4', endColorstr='#ffc3d2e5', GradientType=0); + color: #054993; +} +dl.tabs dt:hover { + background: #e5d9c3; +} +dl.tabs dt.open { + background: #ffffff; + border-bottom: 1px solid #ffffff; + color: #2c2c2c; +} +dl.tabs dt.open a:visited { + color: #2c2c2c; +} +dl.tabs dt a:hover { + text-decoration: none; +} +dl.tabs dt a:focus { + text-decoration: underline; +} +div.current { + border: 1px solid #738498; + background: #ffffff; +} +div.current fieldset { + border: none 0; +} +div.current fieldset.adminform { + border: 1px solid #738498; +} +#login-page .pagetitle h2 { + background: transparent; +} +#login-page #header { + border-bottom: 1px solid #738498; +} +#login-page #lock { + background: url(../images/j_login_lock.png) 50% 0 no-repeat; +} +#login-page #element-box.login { + background-color: #b1c4db; + background-image: -moz-linear-gradient(top,#a5bbd4,#c3d2e5); + background-image: -webkit-gradient(linear,0 0,0 100%,from(#a5bbd4),to(#c3d2e5)); + background-image: -webkit-linear-gradient(top,#a5bbd4,#c3d2e5); + background-image: -o-linear-gradient(top,#a5bbd4,#c3d2e5); + background-image: linear-gradient(to bottom,#a5bbd4,#c3d2e5); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffa5bbd4', endColorstr='#ffc3d2e5', GradientType=0); +} +#form-login { + background: #ffffff; + border: 1px solid #738498; +} +#form-login label { + color: #2c2c2c; +} +#form-login div.button1 a { + color: #054993; +} +#cpanel div.icon a, +.cpanel div.icon a { + color: #054993; + border-left: 1px solid #e5d9c3; + border-top: 1px solid #e5d9c3; + border-right: 1px solid #738498; + border-bottom: 1px solid #738498; + background-color: #b1c4db; + background-image: -moz-linear-gradient(top,#a5bbd4,#c3d2e5); + background-image: -webkit-gradient(linear,0 0,0 100%,from(#a5bbd4),to(#c3d2e5)); + background-image: -webkit-linear-gradient(top,#a5bbd4,#c3d2e5); + background-image: -o-linear-gradient(top,#a5bbd4,#c3d2e5); + background-image: linear-gradient(to bottom,#a5bbd4,#c3d2e5); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffa5bbd4', endColorstr='#ffc3d2e5', GradientType=0); +} +#cpanel div.icon a:hover, +#cpanel div.icon a:focus, +.cpanel div.icon a:hover, +.cpanel div.icon a:focus { + border-left: 1px solid #868778; + border-top: 1px solid #868778; + border-right: 1px solid #f6f7db; + border-bottom: 1px solid #f6f7db; + color: #054993; + background: #e5d9c3; +} +fieldset { + border: 1px #738498 solid; +} +legend { + color: #2c2c2c; +} +fieldset ul.checklist input:focus { + outline: thin dotted #2c2c2c; +} +fieldset#filter-bar { + border-top: 0 solid #738498; + border-right: 0 solid #738498; + border-bottom: 1px solid #738498; + border-left: 0 solid #738498; +} +fieldset#filter-bar ol, +fieldset#filter-bar ul { + border: 0; +} +fieldset#filter-bar ol li fieldset, +fieldset#filter-bar ul li fieldset { + border: 0; +} +.invalid { + color: #a20000; +} +input.invalid { + border: 1px solid #a20000; +} +input.readonly, +span.faux-input { + border: 0; +} +input.required { + background-color: #e5f0fa; +} +input.disabled { + background-color: #eeeeee; +} +input, +select, +span.faux-input { + background-color: #ffffff; + border: 1px solid #738498; +} +input[type="button"], +input[type="submit"], +input[type="reset"] { + color: #054993; + background-color: #b1c4db; + background-image: -moz-linear-gradient(top,#a5bbd4,#c3d2e5); + background-image: -webkit-gradient(linear,0 0,0 100%,from(#a5bbd4),to(#c3d2e5)); + background-image: -webkit-linear-gradient(top,#a5bbd4,#c3d2e5); + background-image: -o-linear-gradient(top,#a5bbd4,#c3d2e5); + background-image: linear-gradient(to bottom,#a5bbd4,#c3d2e5); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffa5bbd4', endColorstr='#ffc3d2e5', GradientType=0); +} +input[type="button"]:hover, +input[type="button"]:focus, +input[type="submit"]:hover, +input[type="submit"]:focus, +input[type="reset"]:hover, +input[type="reset"]:focus { + background: #e5d9c3; +} +textarea { + background-color: #ffffff; + border: 1px solid #738498; +} +input:focus, +select:focus, +textarea:focus, +option:focus, +input:hover, +select:hover, +textarea:hover, +option:hover { + background-color: #e5d9c3; + color: #054993; +} +.paramrules { + background: #c3d2e5; +} +span.gi { + color: #738498; +} +table.admintable td.key, +table.admintable td.paramlist_key { + background-color: #c3d2e5; + color: #2c2c2c; + border-bottom: 1px solid #738498; + border-right: 1px solid #738498; +} +table.paramlist td.paramlist_description { + background-color: #c3d2e5; + color: #2c2c2c; + border-bottom: 1px solid #738498; + border-right: 1px solid #738498; +} +fieldset.adminform { + border: 1px solid #738498; +} +table.adminform { + background-color: #ffffff; +} +table.adminform tr.row0 { + background-color: #ffffff; +} +table.adminform tr.row1 { + background-color: #e5d9c3; +} +table.adminform th { + color: #2c2c2c; + background: #ffffff; +} +table.adminform tr { + border-bottom: 1px solid #738498; + border-right: 1px solid #738498; +} +table.adminlist { + border-spacing: 1px; + background-color: #ffffff; + color: #2c2c2c; +} +table.adminlist.modal { + border-top: 1px solid #738498; + border-right: 1px solid #738498; + border-left: 1px solid #738498; +} +table.adminlist a { + color: #054993; +} +table.adminlist thead th { + background: #ffffff; + color: #2c2c2c; + border-bottom: 1px solid #738498; +} +table.adminlist tbody tr { + background: #ffffff; +} +table.adminlist tbody tr.row1 { + background: #ffffff; +} +table.adminlist tbody tr.row1:last-child td, +table.adminlist tbody tr.row1:last-child th { + border-bottom: 1px solid #738498; +} +table.adminlist tbody tr.row0:hover td, +table.adminlist tbody tr.row1:hover td, +table.adminlist tbody tr.row0:hover th, +table.adminlist tbody tr.row1:hover th, +table.adminlist tbody tr.row0:focus td, +table.adminlist tbody tr.row1:focus td, +table.adminlist tbody tr.row0:focus th, +table.adminlist tbody tr.row1:focus th { + background-color: #e5d9c3; +} +table.adminlist tbody tr td, +table.adminlist tbody tr th { + border-right: 1px solid #738498; +} +table.adminlist tbody tr td:last-child { + border-right: none; +} +table.adminlist tbody tr.row0:last-child td, +table.adminlist tbody tr.row0:last-child th { + border-bottom: 1px solid #738498; +} +table.adminlist tbody tr.row0 td, +table.adminlist tbody tr.row0 th { + background-color: #b1c4db; + background-image: -moz-linear-gradient(top,#a5bbd4,#c3d2e5); + background-image: -webkit-gradient(linear,0 0,0 100%,from(#a5bbd4),to(#c3d2e5)); + background-image: -webkit-linear-gradient(top,#a5bbd4,#c3d2e5); + background-image: -o-linear-gradient(top,#a5bbd4,#c3d2e5); + background-image: linear-gradient(to bottom,#a5bbd4,#c3d2e5); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffa5bbd4', endColorstr='#ffc3d2e5', GradientType=0); +} +table.adminlist { + border-bottom: 0 solid #738498; +} +table.adminlist tfoot tr { + color: #2c2c2c; +} +table.adminlist tfoot td, +table.adminlist tfoot th { + background-color: #ffffff; + border-top: 1px solid #738498; +} +table.adminlist tr td.btns a { + border: 1px solid #738498; + background-color: #b1c4db; + background-image: -moz-linear-gradient(top,#a5bbd4,#c3d2e5); + background-image: -webkit-gradient(linear,0 0,0 100%,from(#a5bbd4),to(#c3d2e5)); + background-image: -webkit-linear-gradient(top,#a5bbd4,#c3d2e5); + background-image: -o-linear-gradient(top,#a5bbd4,#c3d2e5); + background-image: linear-gradient(to bottom,#a5bbd4,#c3d2e5); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffa5bbd4', endColorstr='#ffc3d2e5', GradientType=0); + color: #054993; +} +table.adminlist tr td.btns a:hover, +table.adminlist tr td.btns a:active, +table.adminlist tr td.btns a:focus { + background-color: #ffffff; +} +a.saveorder { + background: url(../images/admin/filesave.png) no-repeat; +} +a.saveorder.inactive { + background-position: 0 -16px; +} +fieldset.batch { + background: #ffffff; +} +button { + color: #054993; + border: 1px solid #738498; + background-color: #b1c4db; + background-image: -moz-linear-gradient(top,#a5bbd4,#c3d2e5); + background-image: -webkit-gradient(linear,0 0,0 100%,from(#a5bbd4),to(#c3d2e5)); + background-image: -webkit-linear-gradient(top,#a5bbd4,#c3d2e5); + background-image: -o-linear-gradient(top,#a5bbd4,#c3d2e5); + background-image: linear-gradient(to bottom,#a5bbd4,#c3d2e5); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffa5bbd4', endColorstr='#ffc3d2e5', GradientType=0); +} +button:hover, +button:focus { + background: #e5d9c3; +} +.invalid { + color: #ff0000; +} +.button1 { + border: 1px solid #738498; + color: #054993; + background-color: #b1c4db; + background-image: -moz-linear-gradient(top,#a5bbd4,#c3d2e5); + background-image: -webkit-gradient(linear,0 0,0 100%,from(#a5bbd4),to(#c3d2e5)); + background-image: -webkit-linear-gradient(top,#a5bbd4,#c3d2e5); + background-image: -o-linear-gradient(top,#a5bbd4,#c3d2e5); + background-image: linear-gradient(to bottom,#a5bbd4,#c3d2e5); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffa5bbd4', endColorstr='#ffc3d2e5', GradientType=0); +} +.button1 a { + color: #054993; +} +.button1 a:hover, +.button1 a:focus { + background: #e5d9c3; +} +.button2-left, +.button2-right { + border: 1px solid #738498; + background-color: #b1c4db; + background-image: -moz-linear-gradient(top,#a5bbd4,#c3d2e5); + background-image: -webkit-gradient(linear,0 0,0 100%,from(#a5bbd4),to(#c3d2e5)); + background-image: -webkit-linear-gradient(top,#a5bbd4,#c3d2e5); + background-image: -o-linear-gradient(top,#a5bbd4,#c3d2e5); + background-image: linear-gradient(to bottom,#a5bbd4,#c3d2e5); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffa5bbd4', endColorstr='#ffc3d2e5', GradientType=0); +} +.button2-left a, +.button2-right a, +.button2-left span, +.button2-right span { + color: #054993; +} +.button2-left span, +.button2-right span { + color: #999999; +} +.page span, +.blank span { + color: #054993; +} +.button2-left a:hover, +.button2-right a:hover, +.button2-left a:focus, +.button2-right a:focus { + background: #e5d9c3; +} +.pagination .page span { + color: #999999; +} +.tip { + background: #000000; + border: 1px solid #FFFFFF; +} +.tip-title { + background: url(../images/selector-arrow-std.png) no-repeat; +} +a img.calendar { + background: url(../images/calendar.png) no-repeat; +} +.jgrid span.publish { + background-image: url(../images/admin/tick.png); +} +.jgrid span.unpublish { + background-image: url(../images/admin/publish_x.png); +} +.jgrid span.archive { + background-image: url(../images/menu/icon-16-archive.png); +} +.jgrid span.trash { + background-image: url(../images/menu/icon-16-trash.png); +} +.jgrid span.default { + background-image: url(../images/menu/icon-16-default.png); +} +.jgrid span.notdefault { + background-image: url(../images/menu/icon-16-notdefault.png); +} +.jgrid span.checkedout { + background-image: url(../images/admin/checked_out.png); +} +.jgrid span.downarrow { + background-image: url(../images/admin/downarrow.png); +} +.jgrid span.downarrow_disabled { + background-image: url(../images/admin/downarrow0.png); +} +.jgrid span.uparrow { + background-image: url(../images/admin/uparrow.png); +} +.jgrid span.uparrow_disabled { + background-image: url(../images/admin/uparrow0.png); +} +.jgrid span.published { + background-image: url(../images/admin/publish_g.png); +} +.jgrid span.expired { + background-image: url(../images/admin/publish_r.png); +} +.jgrid span.pending { + background-image: url(../images/admin/publish_y.png); +} +.jgrid span.warning { + background-image: url(../images/admin/publish_y.png); +} +.icon-32-send { + background-image: url(../images/toolbar/icon-32-send.png); +} +.icon-32-delete { + background-image: url(../images/toolbar/icon-32-delete.png); +} +.icon-32-help { + background-image: url(../images/toolbar/icon-32-help.png); +} +.icon-32-cancel { + background-image: url(../images/toolbar/icon-32-cancel.png); +} +.icon-32-checkin { + background-image: url(../images/toolbar/icon-32-checkin.png); +} +.icon-32-options { + background-image: url(../images/toolbar/icon-32-config.png); +} +.icon-32-apply { + background-image: url(../images/toolbar/icon-32-apply.png); +} +.icon-32-back { + background-image: url(../images/toolbar/icon-32-back.png); +} +.icon-32-forward { + background-image: url(../images/toolbar/icon-32-forward.png); +} +.icon-32-save { + background-image: url(../images/toolbar/icon-32-save.png); +} +.icon-32-edit { + background-image: url(../images/toolbar/icon-32-edit.png); +} +.icon-32-copy { + background-image: url(../images/toolbar/icon-32-copy.png); +} +.icon-32-move { + background-image: url(../images/toolbar/icon-32-move.png); +} +.icon-32-new { + background-image: url(../images/toolbar/icon-32-new.png); +} +.icon-32-upload { + background-image: url(../images/toolbar/icon-32-upload.png); +} +.icon-32-assign { + background-image: url(../images/toolbar/icon-32-publish.png); +} +.icon-32-html { + background-image: url(../images/toolbar/icon-32-html.png); +} +.icon-32-css { + background-image: url(../images/toolbar/icon-32-css.png); +} +.icon-32-menus { + background-image: url(../images/toolbar/icon-32-menu.png); +} +.icon-32-publish { + background-image: url(../images/toolbar/icon-32-publish.png); +} +.icon-32-unblock { + background-image: url(../images/toolbar/icon-32-unblock.png); +} +.icon-32-unpublish { + background-image: url(../images/toolbar/icon-32-unpublish.png); +} +.icon-32-restore { + background-image: url(../images/toolbar/icon-32-revert.png); +} +.icon-32-trash { + background-image: url(../images/toolbar/icon-32-trash.png); +} +.icon-32-archive { + background-image: url(../images/toolbar/icon-32-archive.png); +} +.icon-32-unarchive { + background-image: url(../images/toolbar/icon-32-unarchive.png); +} +.icon-32-preview { + background-image: url(../images/toolbar/icon-32-preview.png); +} +.icon-32-default { + background-image: url(../images/toolbar/icon-32-default.png); +} +.icon-32-refresh { + background-image: url(../images/toolbar/icon-32-refresh.png); +} +.icon-32-save-new { + background-image: url(../images/toolbar/icon-32-save-new.png); +} +.icon-32-save-copy { + background-image: url(../images/toolbar/icon-32-save-copy.png); +} +.icon-32-error { + background-image: url(../images/toolbar/icon-32-error.png); +} +.icon-32-new-style { + background-image: url(../images/toolbar/icon-32-new-style.png); +} +.icon-32-delete-style { + background-image: url(../images/toolbar/icon-32-delete-style.png); +} +.icon-32-purge { + background-image: url(../images/toolbar/icon-32-purge.png); +} +.icon-32-remove { + background-image: url(../images/toolbar/icon-32-remove.png); +} +.icon-32-featured { + background-image: url(../images/toolbar/icon-32-featured.png); +} +.icon-32-unfeatured { + background-image: url(../images/toolbar/icon-32-featured.png); + background-position: 0% 100%; +} +.icon-32-export { + background-image: url(../images/toolbar/icon-32-export.png); +} +.icon-32-stats { + background-image: url(../images/toolbar/icon-32-stats.png); +} +.icon-32-print { + background-image: url(../images/toolbar/icon-32-print.png); +} +.icon-32-batch { + background-image: url(../images/toolbar/icon-32-batch.png); +} +.icon-32-envelope { + background-image: url(../images/toolbar/icon-32-messaging.png); +} +.icon-32-download { + background-image: url(../images/toolbar/icon-32-export.png); +} +.icon-32-bars { + background-image: url(../images/toolbar/icon-32-stats.png); +} +.icon-48-categories { + background-image: url(../images/header/icon-48-category.png); +} +.icon-48-category-edit { + background-image: url(../images/header/icon-48-category.png); +} +.icon-48-category-add { + background-image: url(../images/header/icon-48-category-add.png); +} +.icon-48-generic { + background-image: url(../images/header/icon-48-generic.png); +} +.icon-48-banners { + background-image: url(../images/header/icon-48-banner.png); +} +.icon-48-banners-categories { + background-image: url(../images/header/icon-48-banner-categories.png); +} +.icon-48-banners-category-edit { + background-image: url(../images/header/icon-48-banner-categories.png); +} +.icon-48-banners-category-add { + background-image: url(../images/header/icon-48-category-add.png); +} +.icon-48-banners-clients { + background-image: url(../images/header/icon-48-banner-client.png); +} +.icon-48-banners-tracks { + background-image: url(../images/header/icon-48-banner-tracks.png); +} +.icon-48-checkin { + background-image: url(../images/header/icon-48-checkin.png); +} +.icon-48-clear { + background-image: url(../images/header/icon-48-clear.png); +} +.icon-48-contact { + background-image: url(../images/header/icon-48-contacts.png); +} +.icon-48-contact-categories { + background-image: url(../images/header/icon-48-contacts-categories.png); +} +.icon-48-contact-category-edit { + background-image: url(../images/header/icon-48-contacts-categories.png); +} +.icon-48-contact-category-add { + background-image: url(../images/header/icon-48-category-add.png); +} +.icon-48-purge { + background-image: url(../images/header/icon-48-purge.png); +} +.icon-48-cpanel { + background-image: url(../images/header/icon-48-cpanel.png); +} +.icon-48-config { + background-image: url(../images/header/icon-48-config.png); +} +.icon-48-groups { + background-image: url(../images/header/icon-48-groups.png); +} +.icon-48-groups-add { + background-image: url(../images/header/icon-48-groups-add.png); +} +.icon-48-levels { + background-image: url(../images/header/icon-48-levels.png); +} +.icon-48-levels-add { + background-image: url(../images/header/icon-48-levels-add.png); +} +.icon-48-module { + background-image: url(../images/header/icon-48-module.png); +} +.icon-48-menu { + background-image: url(../images/header/icon-48-menu.png); +} +.icon-48-menu-add { + background-image: url(../images/header/icon-48-menu-add.png); +} +.icon-48-menumgr { + background-image: url(../images/header/icon-48-menumgr.png); +} +.icon-48-trash { + background-image: url(../images/header/icon-48-trash.png); +} +.icon-48-user { + background-image: url(../images/header/icon-48-user.png); +} +.icon-48-user-add { + background-image: url(../images/header/icon-48-user-add.png); +} +.icon-48-user-edit { + background-image: url(../images/header/icon-48-user-edit.png); +} +.icon-48-user-profile { + background-image: url(../images/header/icon-48-user-profile.png); +} +.icon-48-inbox { + background-image: url(../images/header/icon-48-inbox.png); +} +.icon-48-new-privatemessage { + background-image: url(../images/header/icon-48-new-privatemessage.png); +} +.icon-48-msgconfig { + background-image: url(../images/header/icon-48-message_config.png); +} +.icon-48-langmanager { + background-image: url(../images/header/icon-48-language.png); +} +.icon-48-mediamanager { + background-image: url(../images/header/icon-48-media.png); +} +.icon-48-plugin { + background-image: url(../images/header/icon-48-plugin.png); +} +.icon-48-help_header { + background-image: url(../images/header/icon-48-help_header.png); +} +.icon-48-impressions { + background-image: url(../images/header/icon-48-stats.png); +} +.icon-48-browser { + background-image: url(../images/header/icon-48-stats.png); +} +.icon-48-searchtext { + background-image: url(../images/header/icon-48-stats.png); +} +.icon-48-thememanager { + background-image: url(../images/header/icon-48-themes.png); +} +.icon-48-writemess { + background-image: url(../images/header/icon-48-writemess.png); +} +.icon-48-featured { + background-image: url(../images/header/icon-48-featured.png); +} +.icon-48-sections { + background-image: url(../images/header/icon-48-section.png); +} +.icon-48-article-add { + background-image: url(../images/header/icon-48-article-add.png); +} +.icon-48-article-edit { + background-image: url(../images/header/icon-48-article-edit.png); +} +.icon-48-article { + background-image: url(../images/header/icon-48-article.png); +} +.icon-48-content-categories { + background-image: url(../images/header/icon-48-category.png); +} +.icon-48-content-category-edit { + background-image: url(../images/header/icon-48-category.png); +} +.icon-48-content-category-add { + background-image: url(../images/header/icon-48-category-add.png); +} +.icon-48-install { + background-image: url(../images/header/icon-48-extension.png); +} +.icon-48-dbbackup { + background-image: url(../images/header/icon-48-backup.png); +} +.icon-48-dbrestore { + background-image: url(../images/header/icon-48-dbrestore.png); +} +.icon-48-dbquery { + background-image: url(../images/header/icon-48-query.png); +} +.icon-48-systeminfo { + background-image: url(../images/header/icon-48-info.png); +} +.icon-48-massmail { + background-image: url(../images/header/icon-48-massmail.png); +} +.icon-48-redirect { + background-image: url(../images/header/icon-48-redirect.png); +} +.icon-48-search { + background-image: url(../images/header/icon-48-search.png); +} +.icon-48-finder { + background-image: url(../images/header/icon-48-search.png); +} +.icon-48-newsfeeds { + background-image: url(../images/header/icon-48-newsfeeds.png); +} +.icon-48-newsfeeds-categories { + background-image: url(../images/header/icon-48-newsfeeds-cat.png); +} +.icon-48-newsfeeds-category-edit { + background-image: url(../images/header/icon-48-newsfeeds-cat.png); +} +.icon-48-newsfeeds-category-add { + background-image: url(../images/header/icon-48-category-add.png); +} +.icon-48-weblinks { + background-image: url(../images/header/icon-48-links.png); +} +.icon-48-weblinks-categories { + background-image: url(../images/header/icon-48-links-cat.png); +} +.icon-48-weblinks-category-edit { + background-image: url(../images/header/icon-48-links-cat.png); +} +.icon-48-weblinks-category-add { + background-image: url(../images/header/icon-48-category-add.png); +} +.icon-48-tags { + background-image: url(../images/header/icon-48-tags.png); +} +.icon-48-assoc { + background-image: url(../images/header/icon-48-assoc.png); +} +.icon-48-puzzle { + background-image: url(../images/header/icon-48-puzzle.png); +} +div.message { + border: 1px solid #738498; + color: #2c2c2c; +} +.helpFrame { + border-left: 0 solid #738498; + border-right: none; + border-top: none; + border-bottom: none; +} +.outline { + border: 1px solid #738498; + background: #ffffff; +} +dl.menu_type dt { + border-bottom: 1px solid #738498; +} +ul#new-modules-list { + border-top: 1px solid #738498; +} +#skiplinkholder a, +#skiplinkholder a:link, +#skiplinkholder a:visited { + color: #ffffff; + background: #054993; + border-bottom: solid #336 2px; +} +fieldset.panelform { + border: none 0; +} +a.move_up { + background-image: url('../images/admin/uparrow.png'); +} +span.move_up { + background-image: url('../images/admin/uparrow0.png'); +} +a.move_down { + background-image: url('../images/admin/downarrow.png'); +} +span.move_down { + background-image: url('../images/admin/downarrow0.png'); +} +a.grid_false { + background-image: url('../images/admin/publish_x.png'); +} +a.grid_true { + background-image: url('../images/admin/tick.png'); +} +a.grid_trash { + background-image: url('../images/admin/icon-16-trash.png'); +} +tr.row1 { + background-color: #c3d2e5; +} +table.aclsummary-table td.col2, +table.aclsummary-table th.col2, +table.aclsummary-table td.col3, +table.aclsummary-table th.col3, +table.aclsummary-table td.col4, +table.aclsummary-table th.col4, +table.aclsummary-table td.col5, +table.aclsummary-table th.col5, +table.aclsummary-table td.col6, +table.aclsummary-table th.col6, +table.aclmodify-table td.col2, +table.aclmodify-table th.col2 { + border-left: 1px solid #738498; +} +span.icon-16-unset { + background: url(../images/admin/icon-16-denyinactive.png) no-repeat; +} +span.icon-16-allowed { + background: url(../images/admin/icon-16-allow.png) no-repeat; +} +span.icon-16-denied { + background: url(../images/admin/icon-16-deny.png) no-repeat; +} +span.icon-16-locked { + background: url(../images/admin/checked_out.png) 0 0 no-repeat; +} +label.icon-16-allow { + background: url(../images/admin/icon-16-allow.png) no-repeat; +} +label.icon-16-deny { + background: url(../images/admin/icon-16-deny.png) no-repeat; +} +a.icon-16-allow { + background: url(../images/admin/icon-16-allow.png) no-repeat; +} +a.icon-16-deny { + background: url(../images/admin/icon-16-deny.png) no-repeat; +} +a.icon-16-allowinactive { + background: url(../images/admin/icon-16-allowinactive.png) no-repeat; +} +a.icon-16-denyinactive { + background: url(../images/admin/icon-16-denyinactive.png) no-repeat; +} +ul.acllegend li.acl-allowed { + background: url(../images/admin/icon-16-allow.png) no-repeat left; +} +ul.acllegend li.acl-denied { + background: url(../images/admin/icon-16-deny.png) no-repeat left; +} +li.acl-editgroups, +li.acl-resetbtn { + background-color: #c3d2e5; + border: 1px solid #738498; +} +li.acl-editgroups a, +li.acl-resetbtn a { + color: #054993; +} +li.acl-editgroups:hover, +li.acl-resetbtn:hover, +li.acl-editgroups:focus, +li.acl-resetbtn:focus { + background-color: #e5d9c3; +} +table#acl-config { + border: 1px solid #738498; +} +table#acl-config th, +table#acl-config td { + background: #c3d2e5; + border-bottom: 1px solid #738498; +} +table#acl-config th.acl-groups { + border-right: 1px solid #738498; +} +#jform_sef_rewrite-lbl { + background: url(../images/admin/icon-16-notice-note.png) right top no-repeat; +} +#permissions-sliders .tip { + background: #ffffff; + border: 1px solid #738498; +} +#permissions-sliders ul#rules, +#permissions-sliders ul#rules ul { + border: solid 0 #738498; + background: #ffffff; +} +ul#rules li .pane-sliders .panel h3.title { + border: solid 0 #738498; +} +#permissions-sliders ul#rules .pane-slider { + border: solid 1px #738498; +} +#permissions-sliders ul#rules li h3 { + border: solid 1px #738498; +} +#permissions-sliders ul#rules li h3.pane-toggler-down a { + border: solid 0; +} +#permissions-sliders ul#rules .group-kind { + color: #2c2c2c; +} +#permissions-sliders ul#rules table.group-rules { + border: solid 1px #738498; +} +#permissions-sliders ul#rules table.group-rules td { + border-right: solid 1px #738498; + border-bottom: solid 1px #738498; +} +#permissions-sliders ul#rules table.group-rules th { + background: #e5d9c3; + border-right: solid 1px #738498; + border-bottom: solid 1px #738498; + color: #2c2c2c; +} +ul#rules table.aclmodify-table { + border: solid 1px #738498; +} +ul#rules table.group-rules td label { + border: solid 0 #738498; +} +#permissions-sliders ul#rules .mypanel { + border: solid 0 #738498; +} +#permissions-sliders ul#rules table.group-rules td { + background: #ffffff; +} +#permissions-sliders span.level { + color: #738498; + background-image: none; +} +.check-0, +table.adminlist tbody td.check-0 { + background-color: #ffffcf; +} +.check-a, +table.adminlist tbody td.check-a { + background-color: #cfffda; +} +.check-d, +table.adminlist tbody td.check-d { + background-color: #ffcfcf; +} +#system-message dd ul { + color: #2c2c2c; +} +#system-message dd.error ul { + color: #2c2c2c; +} +#system-message dd.message ul { + color: #2c2c2c; +} +#system-message dd.notice ul { + color: #2c2c2c; +} +#menu { + color: #2c2c2c; +} +#menu ul.dropdown-menu { + background-color: #b1c4db; + background-image: -moz-linear-gradient(top,#a5bbd4,#c3d2e5); + background-image: -webkit-gradient(linear,0 0,0 100%,from(#a5bbd4),to(#c3d2e5)); + background-image: -webkit-linear-gradient(top,#a5bbd4,#c3d2e5); + background-image: -o-linear-gradient(top,#a5bbd4,#c3d2e5); + background-image: linear-gradient(to bottom,#a5bbd4,#c3d2e5); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffa5bbd4', endColorstr='#ffc3d2e5', GradientType=0); + color: #2c2c2c; +} +#menu ul.dropdown-menu li.dropdown-submenu { + background: url(../images/j_arrow.png) no-repeat right 50%; +} +#menu ul.dropdown-menu li.divider { + margin-bottom: 0; + border-bottom: 1px dotted #738498; +} +#menu a { + color: #054993; + background-repeat: no-repeat; + background-position: left 50%; +} +#menu li { + border-right: 1px solid #738498; + background-color: transparent; +} +#menu li a:hover, +#menu li a:focus { + background-color: #e5d9c3; +} +#menu li.disabled a:hover, +#menu li.disabled a:focus, +#menu li.disabled a { + color: #738498; + background-color: #b1c4db; + background-image: -moz-linear-gradient(top,#a5bbd4,#c3d2e5); + background-image: -webkit-gradient(linear,0 0,0 100%,from(#a5bbd4),to(#c3d2e5)); + background-image: -webkit-linear-gradient(top,#a5bbd4,#c3d2e5); + background-image: -o-linear-gradient(top,#a5bbd4,#c3d2e5); + background-image: linear-gradient(to bottom,#a5bbd4,#c3d2e5); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffa5bbd4', endColorstr='#ffc3d2e5', GradientType=0); +} +#menu li ul { + border: 1px solid #738498; +} +#menu li li { + background-color: transparent; +} +#menu li.sfhover a { + background-color: #e5d9c3; +} +#menu li.sfhover li a { + background-color: transparent; +} +#menu li.sfhover li.sfhover a, +#menu li li a:focus { + background-color: #e5d9c3; +} +#menu li.sfhover li.sfhover li a { + background-color: transparent; +} +#menu li.sfhover li.sfhover li.sfhover a, +#menu li li li a:focus { + background-color: #e5d9c3; +} +#menu li li a:focus, +#menu li li li a:focus { + background-color: #e5d9c3; +} +#menu li li li a:focus { + background-color: #e5d9c3; +} +#submenu { + border-bottom: 1px solid #738498; +} +#submenu li, +#submenu span.nolink { + background-color: #b1c4db; + background-image: -moz-linear-gradient(top,#a5bbd4,#c3d2e5); + background-image: -webkit-gradient(linear,0 0,0 100%,from(#a5bbd4),to(#c3d2e5)); + background-image: -webkit-linear-gradient(top,#a5bbd4,#c3d2e5); + background-image: -o-linear-gradient(top,#a5bbd4,#c3d2e5); + background-image: linear-gradient(to bottom,#a5bbd4,#c3d2e5); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffa5bbd4', endColorstr='#ffc3d2e5', GradientType=0); + border: 1px solid #738498; + color: #054993; +} +#submenu li:hover, +#submenu li:focus { + background: #e5d9c3; +} +#submenu li.active, +#submenu span.nolink.active { + background: #ffffff; + border-bottom: 1px solid #ffffff; +} +#submenu li.active a, +#submenu span.nolink.active { + color: #000; +} +.element-invisible { + margin: 0; + padding: 0; +} +div.CodeMirror-wrapping { + border: 1px solid #738498; +} +table.adminform tr.row0 { + background-color: #ffffff; +} +ul.alternating > li:nth-child(odd) { + background-color: #ffffff; +} +ul.alternating > li:nth-child(even) { + background-color: #c3d2e5; +} +ol.alternating > li:nth-child(odd) { + background-color: #ffffff; +} +ol.alternating > li:nth-child(even) { + background-color: #c3d2e5; +} +#installer-database, +#installer-discover, +#installer-update, +#installer-warnings { + border-top: 1px solid #738498; +} +#installer-database p.warning { + background: transparent url(../images/admin/icon-16-deny.png) center left no-repeat; +} +#installer-database p.nowarning { + background: transparent url(../images/admin/icon-16-allow.png) center left no-repeat; +} +.input-append, +.input-prepend { + font-size: 1.2em; +} diff --git a/Sites/pages/administrator/templates/hathor/css/colour_blue_rtl.css b/Sites/pages/administrator/templates/hathor/css/colour_blue_rtl.css new file mode 100644 index 00000000..31282e47 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/css/colour_blue_rtl.css @@ -0,0 +1,374 @@ +@charset "UTF-8"; + +/** + * @package Joomla.Administrator + * @subpackage templates.hathor + * @copyright Copyright (C) 2005 - 2020 Open Source Matters, Inc. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + * @since 1.6 + * + * RTL CSS file for the color standard + */ + +/** + * Overall Styles + */ +#header { + background: #ffffff url(../images/j_logo.png) no-repeat top right; +} + +#element-box { + border-left: 1px solid #738498; + border-right: 1px solid #738498; +} + + +/** + * Various Styles + */ + +div.checkin-tick { + background: url(../images/admin/tick.png) 20px 50% no-repeat; +} + +/** + * Subheader, toolbar, page title + */ + +div.toolbar-box { + border-left: 1px solid #738498; + border-right: 1px solid #738498; +} + +div.toolbar-list li.divider { + border-left: 1px dotted #e5d9c3; + border-right: none; +} + +div.toolbar-list a:hover { + border-right: 1px solid #e5d9c3; + border-left: 1px solid #738498; +} + +/** + * Pane Slider pane Toggler styles + */ +.pane-toggler span { + background: transparent url(../images/j_arrow_left.png) right 50% no-repeat; +} + +.pane-toggler-down span { + background: transparent url(../images/j_arrow_down.png) right 50% no-repeat; +} + +/** + * Cpanel Settings + */ + +#cpanel div.icon a:hover, +#cpanel div.icon a:focus { + border-right: 1px solid #e5d9c3; + border-left: 1px solid #738498; +} + +fieldset#filter-bar { + border-left: none; + border-right: none; +} + +/** + * Admintable Styles + */ + +table.admintable td.key,table.admintable td.paramlist_key { + border-left: 1px solid #738498; + border-right: none; +} + +table.paramlist td.paramlist_description { + border-left: 1px solid #738498; + border-right: none; +} + +/** + * Admin Form Styles + */ +table.adminform tr { + border-left: 1px solid #738498; + border-right: none; +} + +/** + * Adminlist Table layout + */ + +table.adminlist.modal { + border-right: 1px solid #738498; + border-left: 1px solid #738498; +} + +/* Table row styles */ + +table.adminlist tbody tr td, +table.adminlist tbody tr th { + border-left: 1px solid #738498; + border-right: none; +} + +table.adminlist tbody tr td:last-child { + border-left: none; +} + +/** + * Saving order icon styling in admin tables + */ +a.saveorder { + background: url(../images/admin/filesave.png) no-repeat; +} + +a.saveorder.inactive { + background-position: 0 -16px; +} + +/** + * Button styling + */ + +/* Button 1 Type */ + + /* Use this if you add images to the buttons such as directional arrows */ + +.button1 a { + /* add padding if you are using the directional images */ + /* padding: 0 6px 0 30px; */ +} + + /* Button 2 Type */ + +.button2-right .prev { + background-image: url(../images/j_button2_prev.png); + background-position: right center; +} + +.button2-right.off .prev { + background: url(../images/j_button2_prev_off.png) no-repeat; +} + +.button2-right .start { + background-image: url(../images/j_button2_first.png); + background-position: right center; +} + +.button2-left .next { + background-image: url(../images/j_button2_next.png); + background-position: left center; +} + +.button2-left.off .next { /* @TODO check the x position */ + background: url(../images/j_button2_next_off.png) 100% 0 no-repeat; +} + +.button2-left .end { + background-image: url(../images/j_arrow_left.png); + background-position: left center; +} + +.button2-left.off .end { /* @TODO check the x position */ + background: url(../images/j_button2_last_off.png) 100% 0 no-repeat; +} + +.button2-left .image { + background: url(../images/j_button2_image.png) 100% 0 no-repeat; +} + +.button2-left .readmore { + background: url(../images/j_button2_readmore.png) 100% 0 no-repeat; +} + +.button2-left .pagebreak { + background: url(../images/j_button2_pagebreak.png) 100% 0 no-repeat; +} + +/** + * Tooltips + */ + +/** + * System Standard Messages + */ +#system-message dd.message ul { + background: #C3D2E5 url(../images/notice-info.png) 99.5% center no-repeat; +} + +/** + * System Error Messages + */ +#system-message dd.error ul { + background: #E6C0C0 url(../images/notice-alert.png) 99.5% top no-repeat; +} + +/** + * System Notice Messages + */ +#system-message dd.notice ul { + background: #EFE7B8 url(../images/notice-note.png) 99%.5 top no-repeat; +} + +/** + * JGrid styles + */ + +/** + * Menu Icons + * These icons are used on the Administrator menu + * The classes are constructed dynamically when the menu is generated + */ + + +/** + * Toolbar icons + * These icons are used for the toolbar buttons + * The classes are constructed dynamically when the toolbar is created + */ + +/** + * Quick Icons + * Also knows as Header Icons + * These are used for the Quick Icons on the Control Panel + * The same classes are also assigned the Component Title + */ + +/** + * General styles + */ + +.helpFrame { + border-right: 0 solid #738498; + border-left: none; + border-top: none; +} + +/* -- ACL STYLES relocated from com_users/media/grid.css ----------- */ + +/* -- ACL PANEL STYLES ----------- */ + + +/* All Tabs */ + +table.aclsummary-table td.col2, +table.aclsummary-table th.col2, +table.aclsummary-table td.col3, +table.aclsummary-table th.col3, +table.aclsummary-table td.col4, +table.aclsummary-table th.col4, +table.aclsummary-table td.col5, +table.aclsummary-table th.col5, +table.aclsummary-table td.col6, +table.aclsummary-table th.col6, +table.aclmodify-table td.col2, +table.aclmodify-table th.col2 { + border-right: 1px solid #738498; + border-left: none; +} + +/* Icons */ + +ul.acllegend li.acl-allowed { + background:url(../images/admin/icon-16-allow.png) no-repeat right; +} +ul.acllegend li.acl-denied { + background:url(../images/admin/icon-16-deny.png) no-repeat right; +} + +table#acl-config th.acl-groups { + border-left: 1px solid #738498; +} + +table#acl-config th.acl-groups { + text-align: right; +} + +.acl-action { + margin: auto 0; +} + +/* Icons */ + +span.icon-16-unset { + background: url(../images/admin/icon-16-denyinactive.png) no-repeat right; +} + +span.icon-16-allowed { + background: url(../images/admin/icon-16-allow.png) no-repeat right; +} + +span.icon-16-denied { + background: url(../images/admin/icon-16-deny.png) no-repeat right; +} + +span.icon-16-locked { + background: url(../images/admin/checked_out.png) no-repeat right; +} + +/** +* Mod_rewrite Warning +*/ +#jform_sef_rewrite-lbl { + background: url(../images/admin/icon-16-notice-note.png) left top no-repeat; +} + +/** +* Modal S-Box overrides +*/ + +#sbox-window { + text-align: right; +} + +/** +* Permission Rules +*/ + +#permissions-sliders ul#rules table.group-rules td +{ + border-left: solid 1px #738498; + border-right: solid 0 #738498; +} + +#permissions-sliders ul#rules table.group-rules th +{ + border-left: solid 1px #738498; + border-right: solid 0 #738498; +} + +/** + * Menu Styling + */ + +#menu ul li.node { + background-image: url(../images/j_arrow_left.png); + background-repeat: no-repeat; + background-position: left 50%; +} + +#menu a { + background-position: right 50%; +} + +#menu li { + border-left: 1px solid #738498; + border-right: 0 solid #738498; +} + +#menu li li li a:focus { + border-right: 1px solid #fafafa; +} + +/* Installer Database */ +#installer-database p.warning { + background-position: center right; +} + +#installer-database p.nowarning { + background-position: center right; +} diff --git a/Sites/pages/administrator/templates/hathor/css/colour_brown.css b/Sites/pages/administrator/templates/hathor/css/colour_brown.css new file mode 100644 index 00000000..01749071 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/css/colour_brown.css @@ -0,0 +1,1802 @@ +.clearfix { + *zoom: 1; +} +.clearfix:before, +.clearfix:after { + display: table; + content: ""; + line-height: 0; +} +.clearfix:after { + clear: both; +} +.hide-text { + font: 0/0 a; + color: transparent; + text-shadow: none; + background-color: transparent; + border: 0; +} +.input-block-level { + display: block; + width: 100%; + min-height: 25px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +#form-login .btn { + display: inline-block; + *display: inline; + *zoom: 1; + padding: 4px 14px; + margin-bottom: 0; + font-size: 13px; + line-height: 15px; + *line-height: 15px; + text-align: center; + vertical-align: middle; + cursor: pointer; + color: #333333; + text-shadow: 0 1px 1px rgba(255,255,255,0.75); + background-color: #f5f5f5; + background-image: -moz-linear-gradient(top,#ffffff,#e6e6e6); + background-image: -webkit-gradient(linear,0 0,0 100%,from(#ffffff),to(#e6e6e6)); + background-image: -webkit-linear-gradient(top,#ffffff,#e6e6e6); + background-image: -o-linear-gradient(top,#ffffff,#e6e6e6); + background-image: linear-gradient(to bottom,#ffffff,#e6e6e6); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe5e5e5', GradientType=0); + border-color: #e6e6e6 #e6e6e6 #bfbfbf; + *background-color: #e6e6e6; + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + border: 1px solid #bbb; + *border: 0; + border-bottom-color: #a2a2a2; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + *margin-left: .3em; + -webkit-box-shadow: inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); + -moz-box-shadow: inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); + box-shadow: inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); +} +#form-login .btn:hover, +#form-login .btn:focus, +#form-login .btn:active, +#form-login .btn.active, +#form-login .btn.disabled, +#form-login .btn[disabled] { + color: #333333; + background-color: #e6e6e6; + *background-color: #d9d9d9; +} +#form-login .btn:active, +#form-login .btn.active { + background-color: #cccccc \9; +} +#form-login .btn:first-child { + *margin-left: 0; +} +#form-login .btn:hover { + color: #333333; + text-decoration: none; + background-color: #e6e6e6; + *background-color: #d9d9d9; + background-position: 0 -15px; + -webkit-transition: background-position .1s linear; + -moz-transition: background-position .1s linear; + -o-transition: background-position .1s linear; + transition: background-position .1s linear; +} +#form-login .btn:focus { + outline: thin dotted #333; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +#form-login .btn.active, +#form-login .btn:active { + background-color: #e6e6e6; + background-color: #d9d9d9 \9; + background-image: none; + outline: 0; + -webkit-box-shadow: inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05); + -moz-box-shadow: inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05); + box-shadow: inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05); +} +#form-login .btn.disabled, +#form-login .btn[disabled] { + cursor: default; + background-color: #e6e6e6; + background-image: none; + opacity: 0.65; + filter: alpha(opacity=65); + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; +} +.btn-large { + padding: 9px 14px; + font-size: 15px; + line-height: normal; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; +} +.btn-large [class^="icon-"] { + margin-top: 2px; +} +.input-append input[class*="span"], +.input-append .uneditable-input[class*="span"], +.input-prepend input[class*="span"], +.input-prepend .uneditable-input[class*="span"], +.row-fluid input[class*="span"], +.row-fluid select[class*="span"], +.row-fluid textarea[class*="span"], +.row-fluid .uneditable-input[class*="span"], +.row-fluid .input-prepend [class*="span"], +.row-fluid .input-append [class*="span"] { + display: inline-block; +} +.input-append, +.input-prepend { + margin-bottom: 5px; + font-size: 0; + white-space: nowrap; +} +.input-append input, +.input-append select, +.input-append .uneditable-input, +.input-prepend input, +.input-prepend select, +.input-prepend .uneditable-input { + position: relative; + margin-bottom: 0; + *margin-left: 0; + font-size: 13px; + vertical-align: top; + -webkit-border-radius: 0 3px 3px 0; + -moz-border-radius: 0 3px 3px 0; + border-radius: 0 3px 3px 0; +} +.input-append input:focus, +.input-append select:focus, +.input-append .uneditable-input:focus, +.input-prepend input:focus, +.input-prepend select:focus, +.input-prepend .uneditable-input:focus { + z-index: 2; +} +.input-append .add-on, +.input-prepend .add-on { + display: inline-block; + width: auto; + height: 15px; + min-width: 16px; + padding: 4px 5px; + font-size: 13px; + font-weight: normal; + line-height: 15px; + text-align: center; + text-shadow: 0 1px 0 #ffffff; + background-color: #eeeeee; + border: 1px solid #ccc; +} +.input-append .add-on, +.input-append .btn, +.input-prepend .add-on, +.input-prepend .btn { + margin-left: -1px; + vertical-align: top; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.input-append .active, +.input-prepend .active { + background-color: #a9dba9; + border-color: #46a546; +} +.input-prepend .add-on, +.input-prepend .btn { + margin-right: -1px; +} +.input-prepend .add-on:first-child, +.input-prepend .btn:first-child { + -webkit-border-radius: 3px 0 0 3px; + -moz-border-radius: 3px 0 0 3px; + border-radius: 3px 0 0 3px; +} +.input-append input, +.input-append select, +.input-append .uneditable-input { + -webkit-border-radius: 3px 0 0 3px; + -moz-border-radius: 3px 0 0 3px; + border-radius: 3px 0 0 3px; +} +.input-append .add-on:last-child, +.input-append .btn:last-child { + -webkit-border-radius: 0 3px 3px 0; + -moz-border-radius: 0 3px 3px 0; + border-radius: 0 3px 3px 0; +} +.input-prepend.input-append input, +.input-prepend.input-append select, +.input-prepend.input-append .uneditable-input { + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.input-prepend.input-append .add-on:first-child, +.input-prepend.input-append .btn:first-child { + margin-right: -1px; + -webkit-border-radius: 3px 0 0 3px; + -moz-border-radius: 3px 0 0 3px; + border-radius: 3px 0 0 3px; +} +.input-prepend.input-append .add-on:last-child, +.input-prepend.input-append .btn:last-child { + margin-left: -1px; + -webkit-border-radius: 0 3px 3px 0; + -moz-border-radius: 0 3px 3px 0; + border-radius: 0 3px 3px 0; +} +.form-search .input-append .search-query, +.form-search .input-prepend .search-query { + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.form-search .input-append .search-query { + -webkit-border-radius: 14px 0 0 14px; + -moz-border-radius: 14px 0 0 14px; + border-radius: 14px 0 0 14px; +} +.form-search .input-append .btn { + -webkit-border-radius: 0 14px 14px 0; + -moz-border-radius: 0 14px 14px 0; + border-radius: 0 14px 14px 0; +} +.form-search .input-prepend .search-query { + -webkit-border-radius: 0 14px 14px 0; + -moz-border-radius: 0 14px 14px 0; + border-radius: 0 14px 14px 0; +} +.form-search .input-prepend .btn { + -webkit-border-radius: 14px 0 0 14px; + -moz-border-radius: 14px 0 0 14px; + border-radius: 14px 0 0 14px; +} +.form-search input, +.form-search textarea, +.form-search select, +.form-search .help-inline, +.form-search .uneditable-input, +.form-search .input-prepend, +.form-search .input-append, +.form-inline input, +.form-inline textarea, +.form-inline select, +.form-inline .help-inline, +.form-inline .uneditable-input, +.form-inline .input-prepend, +.form-inline .input-append, +.form-horizontal input, +.form-horizontal textarea, +.form-horizontal select, +.form-horizontal .help-inline, +.form-horizontal .uneditable-input, +.form-horizontal .input-prepend, +.form-horizontal .input-append { + display: inline-block; + *display: inline; + *zoom: 1; + margin-bottom: 0; + vertical-align: middle; +} +.form-search .hide, +.form-inline .hide, +.form-horizontal .hide { + display: none; +} +.form-search .input-append, +.form-inline .input-append, +.form-search .input-prepend, +.form-inline .input-prepend { + margin-bottom: 0; +} +.element-invisible { + position: absolute; + padding: 0 !important; + margin: 0 !important; + border: 0; + height: 1px; + width: 1px !important; + overflow: hidden; +} +#form-login select, +#form-login input[type="text"], +#form-login input[type="password"] { + display: inline-block; + padding: 4px 6px; + margin-bottom: 9px; + font-size: 13px; + line-height: 15px; + color: #555555; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + width: 175px; +} +.subform-repeatable-wrapper div.btn-toolbar { + float: none; +} +.subform-repeatable-wrapper .text-right { + text-align: right; +} +.subform-repeatable-wrapper .ui-sortable-helper { + background: #ffffff; +} +.subform-repeatable-wrapper tr.ui-sortable-helper { + display: table; +} +.subform-repeatable-wrapper .subform-repeatable-group { + clear: both; +} +.label, +.badge { + display: inline-block; + padding: 2px 4px; + font-size: 10.998px; + font-weight: bold; + line-height: 14px; + color: #ffffff; + vertical-align: baseline; + white-space: nowrap; + text-shadow: 0 -1px 0 rgba(0,0,0,0.25); + background-color: #999999; +} +.label { + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} +.badge { + padding-left: 9px; + padding-right: 9px; + -webkit-border-radius: 9px; + -moz-border-radius: 9px; + border-radius: 9px; +} +.label:empty, +.badge:empty { + display: none; +} +a.label:hover, +a.label:focus, +a.badge:hover, +a.badge:focus { + color: #ffffff; + text-decoration: none; + cursor: pointer; +} +.label-important, +.badge-important { + background-color: #a20000; +} +.label-important[href], +.badge-important[href] { + background-color: #6f0000; +} +.label-warning, +.badge-warning { + background-color: #f89406; +} +.label-warning[href], +.badge-warning[href] { + background-color: #c67605; +} +.label-success, +.badge-success { + background-color: #005800; +} +.label-success[href], +.badge-success[href] { + background-color: #002500; +} +.label-info, +.badge-info { + background-color: #3a87ad; +} +.label-info[href], +.badge-info[href] { + background-color: #2d6987; +} +.label-inverse, +.badge-inverse { + background-color: #333333; +} +.label-inverse[href], +.badge-inverse[href] { + background-color: #1a1a1a; +} +.btn .label, +.btn .badge { + position: relative; + top: -1px; +} +.btn-mini .label, +.btn-mini .badge { + top: 0; +} +body { + background-color: #ffffff; + color: #2c2c2c; +} +h1 { + color: #2c2c2c; +} +a:link { + color: #054993; +} +a:visited { + color: #054993; +} +#header { + background: #ffffff url(../images/j_logo.png) no-repeat; +} +#header h1.title { + color: #2c2c2c; +} +#nav { + background-color: #d5c1b2; + background-image: -moz-linear-gradient(top,#d5c1b2,#d5c1b2); + background-image: -webkit-gradient(linear,0 0,0 100%,from(#d5c1b2),to(#d5c1b2)); + background-image: -webkit-linear-gradient(top,#d5c1b2,#d5c1b2); + background-image: -o-linear-gradient(top,#d5c1b2,#d5c1b2); + background-image: linear-gradient(to bottom,#d5c1b2,#d5c1b2); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd5c1b2', endColorstr='#ffd5c1b2', GradientType=0); + border: 1px solid #000000; +} +#content { + background: #ffffff; +} +#no-submenu { + border-bottom: 1px solid #000000; +} +#element-box { + background: #ffffff; + border-right: 1px solid #000000; + border-bottom: 1px solid #000000; + border-left: 1px solid #000000; +} +#element-box.login { + border-top: 1px solid #000000; +} +.enabled, +.success, +.allow, +span.writable { + color: #005800; +} +.disabled, +p.error, +.warning, +.deny, +span.unwritable { + color: #a20000; +} +.nowarning { + color: #2c2c2c; +} +.none, +.protected { + color: #000000; +} +span.note { + background: #ffffff; + color: #2c2c2c; +} +div.checkin-tick { + background: url(../images/admin/tick.png) 20px 50% no-repeat; +} +.ol-foreground { + background-color: #d5c1b2; +} +.ol-background { + background-color: #005800; +} +.ol-textfont { + color: #2c2c2c; +} +.ol-captionfont { + color: #ffffff; +} +.ol-captionfont a { + color: #054993; +} +div.subheader .padding { + background: #ffffff; +} +.pagetitle h2 { + color: #2c2c2c; +} +div.configuration { + color: #2c2c2c; + background-image: url(../images/menu/icon-16-config.png); + background-repeat: no-repeat; +} +div.toolbar-box { + border-right: 1px solid #000000; + border-bottom: 1px solid #000000; + border-left: 1px solid #000000; + background: #ffffff; +} +div.toolbar-list li { + color: #2c2c2c; +} +div.toolbar-list li.divider { + border-right: 1px dotted #e5d9c3; +} +div.toolbar-list a { + border-left: 1px solid #e5d9c3; + border-top: 1px solid #e5d9c3; + border-right: 1px solid #000000; + border-bottom: 1px solid #000000; + background: #d5c1b2; +} +div.toolbar-list a:hover { + border-left: 1px solid #868778; + border-top: 1px solid #868778; + border-right: 1px solid #f6f7db; + border-bottom: 1px solid #f6f7db; + background: #e5d9c3; + color: #054993; +} +div.btn-toolbar { + margin-left: 5px; + padding-top: 3px; +} +div.btn-toolbar li.divider { + border-right: 1px dotted #e5d9c3; +} +div.btn-toolbar div.btn-group button { + border-left: 1px solid #e5d9c3; + border-top: 1px solid #e5d9c3; + border-right: 1px solid #000000; + border-bottom: 1px solid #000000; + background-color: #d5c1b2; + background-image: -moz-linear-gradient(top,#d5c1b2,#d5c1b2); + background-image: -webkit-gradient(linear,0 0,0 100%,from(#d5c1b2),to(#d5c1b2)); + background-image: -webkit-linear-gradient(top,#d5c1b2,#d5c1b2); + background-image: -o-linear-gradient(top,#d5c1b2,#d5c1b2); + background-image: linear-gradient(to bottom,#d5c1b2,#d5c1b2); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd5c1b2', endColorstr='#ffd5c1b2', GradientType=0); + padding: 5px 4px 5px 4px; +} +div.btn-toolbar div.btn-group button:hover { + border-left: 1px solid #868778; + border-top: 1px solid #868778; + border-right: 1px solid #f6f7db; + border-bottom: 1px solid #f6f7db; + background: #e5d9c3; + color: #054993; + cursor: pointer; +} +div.btn-toolbar a { + border-left: 1px solid #e5d9c3; + border-top: 1px solid #e5d9c3; + border-right: 1px solid #000000; + border-bottom: 1px solid #000000; + background-color: #d5c1b2; + background-image: -moz-linear-gradient(top,#d5c1b2,#d5c1b2); + background-image: -webkit-gradient(linear,0 0,0 100%,from(#d5c1b2),to(#d5c1b2)); + background-image: -webkit-linear-gradient(top,#d5c1b2,#d5c1b2); + background-image: -o-linear-gradient(top,#d5c1b2,#d5c1b2); + background-image: linear-gradient(to bottom,#d5c1b2,#d5c1b2); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd5c1b2', endColorstr='#ffd5c1b2', GradientType=0); + padding: 6px 5px; + text-align: center; + white-space: nowrap; + font-size: 1.2em; + text-decoration: none; +} +div.btn-toolbar a:hover { + border-left: 1px solid #868778; + border-top: 1px solid #868778; + border-right: 1px solid #f6f7db; + border-bottom: 1px solid #f6f7db; + background: #e5d9c3; + color: #054993; + cursor: pointer; +} +div.btn-toolbar div.btn-group button.inactive { + background: #d5c1b2; +} +.pane-sliders .title { + color: #2c2c2c; +} +.pane-sliders .panel { + border: 1px solid #000000; +} +.pane-sliders .panel h3 { + background-color: #d5c1b2; + background-image: -moz-linear-gradient(top,#d5c1b2,#d5c1b2); + background-image: -webkit-gradient(linear,0 0,0 100%,from(#d5c1b2),to(#d5c1b2)); + background-image: -webkit-linear-gradient(top,#d5c1b2,#d5c1b2); + background-image: -o-linear-gradient(top,#d5c1b2,#d5c1b2); + background-image: linear-gradient(to bottom,#d5c1b2,#d5c1b2); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd5c1b2', endColorstr='#ffd5c1b2', GradientType=0); + color: #054993; +} +.pane-sliders .panel h3:hover { + background: #e5d9c3; +} +.pane-sliders .panel h3:hover a { + text-decoration: none; +} +.pane-sliders .adminlist { + border: 0 none; +} +.pane-sliders .adminlist td { + border: 0 none; +} +.pane-toggler span { + background: transparent url(../images/j_arrow.png) 5px 50% no-repeat; +} +.pane-toggler-down span { + background: transparent url(../images/j_arrow_down.png) 5px 50% no-repeat; +} +.pane-toggler-down { + border-bottom: 1px solid #000000; +} +dl.tabs dt { + border: 1px solid #000000; + background-color: #d5c1b2; + background-image: -moz-linear-gradient(top,#d5c1b2,#d5c1b2); + background-image: -webkit-gradient(linear,0 0,0 100%,from(#d5c1b2),to(#d5c1b2)); + background-image: -webkit-linear-gradient(top,#d5c1b2,#d5c1b2); + background-image: -o-linear-gradient(top,#d5c1b2,#d5c1b2); + background-image: linear-gradient(to bottom,#d5c1b2,#d5c1b2); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd5c1b2', endColorstr='#ffd5c1b2', GradientType=0); + color: #054993; +} +dl.tabs dt:hover { + background: #e5d9c3; +} +dl.tabs dt.open { + background: #ffffff; + border-bottom: 1px solid #ffffff; + color: #2c2c2c; +} +dl.tabs dt.open a:visited { + color: #2c2c2c; +} +dl.tabs dt a:hover { + text-decoration: none; +} +dl.tabs dt a:focus { + text-decoration: underline; +} +div.current { + border: 1px solid #000000; + background: #ffffff; +} +div.current fieldset { + border: none 0; +} +div.current fieldset.adminform { + border: 1px solid #000000; +} +#login-page .pagetitle h2 { + background: transparent; +} +#login-page #header { + border-bottom: 1px solid #000000; +} +#login-page #lock { + background: url(../images/j_login_lock.png) 50% 0 no-repeat; +} +#login-page #element-box.login { + background-color: #d5c1b2; + background-image: -moz-linear-gradient(top,#d5c1b2,#d5c1b2); + background-image: -webkit-gradient(linear,0 0,0 100%,from(#d5c1b2),to(#d5c1b2)); + background-image: -webkit-linear-gradient(top,#d5c1b2,#d5c1b2); + background-image: -o-linear-gradient(top,#d5c1b2,#d5c1b2); + background-image: linear-gradient(to bottom,#d5c1b2,#d5c1b2); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd5c1b2', endColorstr='#ffd5c1b2', GradientType=0); +} +#form-login { + background: #ffffff; + border: 1px solid #000000; +} +#form-login label { + color: #2c2c2c; +} +#form-login div.button1 a { + color: #054993; +} +#cpanel div.icon a, +.cpanel div.icon a { + color: #054993; + border-left: 1px solid #e5d9c3; + border-top: 1px solid #e5d9c3; + border-right: 1px solid #000000; + border-bottom: 1px solid #000000; + background-color: #d5c1b2; + background-image: -moz-linear-gradient(top,#d5c1b2,#d5c1b2); + background-image: -webkit-gradient(linear,0 0,0 100%,from(#d5c1b2),to(#d5c1b2)); + background-image: -webkit-linear-gradient(top,#d5c1b2,#d5c1b2); + background-image: -o-linear-gradient(top,#d5c1b2,#d5c1b2); + background-image: linear-gradient(to bottom,#d5c1b2,#d5c1b2); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd5c1b2', endColorstr='#ffd5c1b2', GradientType=0); +} +#cpanel div.icon a:hover, +#cpanel div.icon a:focus, +.cpanel div.icon a:hover, +.cpanel div.icon a:focus { + border-left: 1px solid #868778; + border-top: 1px solid #868778; + border-right: 1px solid #f6f7db; + border-bottom: 1px solid #f6f7db; + color: #054993; + background: #e5d9c3; +} +fieldset { + border: 1px #000000 solid; +} +legend { + color: #2c2c2c; +} +fieldset ul.checklist input:focus { + outline: thin dotted #2c2c2c; +} +fieldset#filter-bar { + border-top: 0 solid #000000; + border-right: 0 solid #000000; + border-bottom: 1px solid #000000; + border-left: 0 solid #000000; +} +fieldset#filter-bar ol, +fieldset#filter-bar ul { + border: 0; +} +fieldset#filter-bar ol li fieldset, +fieldset#filter-bar ul li fieldset { + border: 0; +} +.invalid { + color: #a20000; +} +input.invalid { + border: 1px solid #a20000; +} +input.readonly, +span.faux-input { + border: 0; +} +input.required { + background-color: #e5f0fa; +} +input.disabled { + background-color: #eeeeee; +} +input, +select, +span.faux-input { + background-color: #ffffff; + border: 1px solid #000000; +} +input[type="button"], +input[type="submit"], +input[type="reset"] { + color: #054993; + background-color: #d5c1b2; + background-image: -moz-linear-gradient(top,#d5c1b2,#d5c1b2); + background-image: -webkit-gradient(linear,0 0,0 100%,from(#d5c1b2),to(#d5c1b2)); + background-image: -webkit-linear-gradient(top,#d5c1b2,#d5c1b2); + background-image: -o-linear-gradient(top,#d5c1b2,#d5c1b2); + background-image: linear-gradient(to bottom,#d5c1b2,#d5c1b2); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd5c1b2', endColorstr='#ffd5c1b2', GradientType=0); +} +input[type="button"]:hover, +input[type="button"]:focus, +input[type="submit"]:hover, +input[type="submit"]:focus, +input[type="reset"]:hover, +input[type="reset"]:focus { + background: #e5d9c3; +} +textarea { + background-color: #ffffff; + border: 1px solid #000000; +} +input:focus, +select:focus, +textarea:focus, +option:focus, +input:hover, +select:hover, +textarea:hover, +option:hover { + background-color: #e5d9c3; + color: #054993; +} +.paramrules { + background: #d5c1b2; +} +span.gi { + color: #000000; +} +table.admintable td.key, +table.admintable td.paramlist_key { + background-color: #d5c1b2; + color: #2c2c2c; + border-bottom: 1px solid #000000; + border-right: 1px solid #000000; +} +table.paramlist td.paramlist_description { + background-color: #d5c1b2; + color: #2c2c2c; + border-bottom: 1px solid #000000; + border-right: 1px solid #000000; +} +fieldset.adminform { + border: 1px solid #000000; +} +table.adminform { + background-color: #ffffff; +} +table.adminform tr.row0 { + background-color: #ffffff; +} +table.adminform tr.row1 { + background-color: #e5d9c3; +} +table.adminform th { + color: #2c2c2c; + background: #ffffff; +} +table.adminform tr { + border-bottom: 1px solid #000000; + border-right: 1px solid #000000; +} +table.adminlist { + border-spacing: 1px; + background-color: #ffffff; + color: #2c2c2c; +} +table.adminlist.modal { + border-top: 1px solid #000000; + border-right: 1px solid #000000; + border-left: 1px solid #000000; +} +table.adminlist a { + color: #054993; +} +table.adminlist thead th { + background: #ffffff; + color: #2c2c2c; + border-bottom: 1px solid #000000; +} +table.adminlist tbody tr { + background: #ffffff; +} +table.adminlist tbody tr.row1 { + background: #ffffff; +} +table.adminlist tbody tr.row1:last-child td, +table.adminlist tbody tr.row1:last-child th { + border-bottom: 1px solid #000000; +} +table.adminlist tbody tr.row0:hover td, +table.adminlist tbody tr.row1:hover td, +table.adminlist tbody tr.row0:hover th, +table.adminlist tbody tr.row1:hover th, +table.adminlist tbody tr.row0:focus td, +table.adminlist tbody tr.row1:focus td, +table.adminlist tbody tr.row0:focus th, +table.adminlist tbody tr.row1:focus th { + background-color: #e5d9c3; +} +table.adminlist tbody tr td, +table.adminlist tbody tr th { + border-right: 1px solid #000000; +} +table.adminlist tbody tr td:last-child { + border-right: none; +} +table.adminlist tbody tr.row0:last-child td, +table.adminlist tbody tr.row0:last-child th { + border-bottom: 1px solid #000000; +} +table.adminlist tbody tr.row0 td, +table.adminlist tbody tr.row0 th { + background-color: #d5c1b2; + background-image: -moz-linear-gradient(top,#d5c1b2,#d5c1b2); + background-image: -webkit-gradient(linear,0 0,0 100%,from(#d5c1b2),to(#d5c1b2)); + background-image: -webkit-linear-gradient(top,#d5c1b2,#d5c1b2); + background-image: -o-linear-gradient(top,#d5c1b2,#d5c1b2); + background-image: linear-gradient(to bottom,#d5c1b2,#d5c1b2); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd5c1b2', endColorstr='#ffd5c1b2', GradientType=0); +} +table.adminlist { + border-bottom: 0 solid #000000; +} +table.adminlist tfoot tr { + color: #2c2c2c; +} +table.adminlist tfoot td, +table.adminlist tfoot th { + background-color: #ffffff; + border-top: 1px solid #000000; +} +table.adminlist tr td.btns a { + border: 1px solid #000000; + background-color: #d5c1b2; + background-image: -moz-linear-gradient(top,#d5c1b2,#d5c1b2); + background-image: -webkit-gradient(linear,0 0,0 100%,from(#d5c1b2),to(#d5c1b2)); + background-image: -webkit-linear-gradient(top,#d5c1b2,#d5c1b2); + background-image: -o-linear-gradient(top,#d5c1b2,#d5c1b2); + background-image: linear-gradient(to bottom,#d5c1b2,#d5c1b2); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd5c1b2', endColorstr='#ffd5c1b2', GradientType=0); + color: #054993; +} +table.adminlist tr td.btns a:hover, +table.adminlist tr td.btns a:active, +table.adminlist tr td.btns a:focus { + background-color: #ffffff; +} +a.saveorder { + background: url(../images/admin/filesave.png) no-repeat; +} +a.saveorder.inactive { + background-position: 0 -16px; +} +fieldset.batch { + background: #ffffff; +} +button { + color: #054993; + border: 1px solid #000000; + background-color: #d5c1b2; + background-image: -moz-linear-gradient(top,#d5c1b2,#d5c1b2); + background-image: -webkit-gradient(linear,0 0,0 100%,from(#d5c1b2),to(#d5c1b2)); + background-image: -webkit-linear-gradient(top,#d5c1b2,#d5c1b2); + background-image: -o-linear-gradient(top,#d5c1b2,#d5c1b2); + background-image: linear-gradient(to bottom,#d5c1b2,#d5c1b2); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd5c1b2', endColorstr='#ffd5c1b2', GradientType=0); +} +button:hover, +button:focus { + background: #e5d9c3; +} +.invalid { + color: #ff0000; +} +.button1 { + border: 1px solid #000000; + color: #054993; + background-color: #d5c1b2; + background-image: -moz-linear-gradient(top,#d5c1b2,#d5c1b2); + background-image: -webkit-gradient(linear,0 0,0 100%,from(#d5c1b2),to(#d5c1b2)); + background-image: -webkit-linear-gradient(top,#d5c1b2,#d5c1b2); + background-image: -o-linear-gradient(top,#d5c1b2,#d5c1b2); + background-image: linear-gradient(to bottom,#d5c1b2,#d5c1b2); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd5c1b2', endColorstr='#ffd5c1b2', GradientType=0); +} +.button1 a { + color: #054993; +} +.button1 a:hover, +.button1 a:focus { + background: #e5d9c3; +} +.button2-left, +.button2-right { + border: 1px solid #000000; + background-color: #d5c1b2; + background-image: -moz-linear-gradient(top,#d5c1b2,#d5c1b2); + background-image: -webkit-gradient(linear,0 0,0 100%,from(#d5c1b2),to(#d5c1b2)); + background-image: -webkit-linear-gradient(top,#d5c1b2,#d5c1b2); + background-image: -o-linear-gradient(top,#d5c1b2,#d5c1b2); + background-image: linear-gradient(to bottom,#d5c1b2,#d5c1b2); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd5c1b2', endColorstr='#ffd5c1b2', GradientType=0); +} +.button2-left a, +.button2-right a, +.button2-left span, +.button2-right span { + color: #054993; +} +.button2-left span, +.button2-right span { + color: #999999; +} +.page span, +.blank span { + color: #054993; +} +.button2-left a:hover, +.button2-right a:hover, +.button2-left a:focus, +.button2-right a:focus { + background: #e5d9c3; +} +.pagination .page span { + color: #999999; +} +.tip { + background: #000000; + border: 1px solid #FFFFFF; +} +.tip-title { + background: url(../images/selector-arrow-std.png) no-repeat; +} +a img.calendar { + background: url(../images/calendar.png) no-repeat; +} +.jgrid span.publish { + background-image: url(../images/admin/tick.png); +} +.jgrid span.unpublish { + background-image: url(../images/admin/publish_x.png); +} +.jgrid span.archive { + background-image: url(../images/menu/icon-16-archive.png); +} +.jgrid span.trash { + background-image: url(../images/menu/icon-16-trash.png); +} +.jgrid span.default { + background-image: url(../images/menu/icon-16-default.png); +} +.jgrid span.notdefault { + background-image: url(../images/menu/icon-16-notdefault.png); +} +.jgrid span.checkedout { + background-image: url(../images/admin/checked_out.png); +} +.jgrid span.downarrow { + background-image: url(../images/admin/downarrow.png); +} +.jgrid span.downarrow_disabled { + background-image: url(../images/admin/downarrow0.png); +} +.jgrid span.uparrow { + background-image: url(../images/admin/uparrow.png); +} +.jgrid span.uparrow_disabled { + background-image: url(../images/admin/uparrow0.png); +} +.jgrid span.published { + background-image: url(../images/admin/publish_g.png); +} +.jgrid span.expired { + background-image: url(../images/admin/publish_r.png); +} +.jgrid span.pending { + background-image: url(../images/admin/publish_y.png); +} +.jgrid span.warning { + background-image: url(../images/admin/publish_y.png); +} +.icon-32-send { + background-image: url(../images/toolbar/icon-32-send.png); +} +.icon-32-delete { + background-image: url(../images/toolbar/icon-32-delete.png); +} +.icon-32-help { + background-image: url(../images/toolbar/icon-32-help.png); +} +.icon-32-cancel { + background-image: url(../images/toolbar/icon-32-cancel.png); +} +.icon-32-checkin { + background-image: url(../images/toolbar/icon-32-checkin.png); +} +.icon-32-options { + background-image: url(../images/toolbar/icon-32-config.png); +} +.icon-32-apply { + background-image: url(../images/toolbar/icon-32-apply.png); +} +.icon-32-back { + background-image: url(../images/toolbar/icon-32-back.png); +} +.icon-32-forward { + background-image: url(../images/toolbar/icon-32-forward.png); +} +.icon-32-save { + background-image: url(../images/toolbar/icon-32-save.png); +} +.icon-32-edit { + background-image: url(../images/toolbar/icon-32-edit.png); +} +.icon-32-copy { + background-image: url(../images/toolbar/icon-32-copy.png); +} +.icon-32-move { + background-image: url(../images/toolbar/icon-32-move.png); +} +.icon-32-new { + background-image: url(../images/toolbar/icon-32-new.png); +} +.icon-32-upload { + background-image: url(../images/toolbar/icon-32-upload.png); +} +.icon-32-assign { + background-image: url(../images/toolbar/icon-32-publish.png); +} +.icon-32-html { + background-image: url(../images/toolbar/icon-32-html.png); +} +.icon-32-css { + background-image: url(../images/toolbar/icon-32-css.png); +} +.icon-32-menus { + background-image: url(../images/toolbar/icon-32-menu.png); +} +.icon-32-publish { + background-image: url(../images/toolbar/icon-32-publish.png); +} +.icon-32-unblock { + background-image: url(../images/toolbar/icon-32-unblock.png); +} +.icon-32-unpublish { + background-image: url(../images/toolbar/icon-32-unpublish.png); +} +.icon-32-restore { + background-image: url(../images/toolbar/icon-32-revert.png); +} +.icon-32-trash { + background-image: url(../images/toolbar/icon-32-trash.png); +} +.icon-32-archive { + background-image: url(../images/toolbar/icon-32-archive.png); +} +.icon-32-unarchive { + background-image: url(../images/toolbar/icon-32-unarchive.png); +} +.icon-32-preview { + background-image: url(../images/toolbar/icon-32-preview.png); +} +.icon-32-default { + background-image: url(../images/toolbar/icon-32-default.png); +} +.icon-32-refresh { + background-image: url(../images/toolbar/icon-32-refresh.png); +} +.icon-32-save-new { + background-image: url(../images/toolbar/icon-32-save-new.png); +} +.icon-32-save-copy { + background-image: url(../images/toolbar/icon-32-save-copy.png); +} +.icon-32-error { + background-image: url(../images/toolbar/icon-32-error.png); +} +.icon-32-new-style { + background-image: url(../images/toolbar/icon-32-new-style.png); +} +.icon-32-delete-style { + background-image: url(../images/toolbar/icon-32-delete-style.png); +} +.icon-32-purge { + background-image: url(../images/toolbar/icon-32-purge.png); +} +.icon-32-remove { + background-image: url(../images/toolbar/icon-32-remove.png); +} +.icon-32-featured { + background-image: url(../images/toolbar/icon-32-featured.png); +} +.icon-32-unfeatured { + background-image: url(../images/toolbar/icon-32-featured.png); + background-position: 0% 100%; +} +.icon-32-export { + background-image: url(../images/toolbar/icon-32-export.png); +} +.icon-32-stats { + background-image: url(../images/toolbar/icon-32-stats.png); +} +.icon-32-print { + background-image: url(../images/toolbar/icon-32-print.png); +} +.icon-32-batch { + background-image: url(../images/toolbar/icon-32-batch.png); +} +.icon-32-envelope { + background-image: url(../images/toolbar/icon-32-messaging.png); +} +.icon-32-download { + background-image: url(../images/toolbar/icon-32-export.png); +} +.icon-32-bars { + background-image: url(../images/toolbar/icon-32-stats.png); +} +.icon-48-categories { + background-image: url(../images/header/icon-48-category.png); +} +.icon-48-category-edit { + background-image: url(../images/header/icon-48-category.png); +} +.icon-48-category-add { + background-image: url(../images/header/icon-48-category-add.png); +} +.icon-48-generic { + background-image: url(../images/header/icon-48-generic.png); +} +.icon-48-banners { + background-image: url(../images/header/icon-48-banner.png); +} +.icon-48-banners-categories { + background-image: url(../images/header/icon-48-banner-categories.png); +} +.icon-48-banners-category-edit { + background-image: url(../images/header/icon-48-banner-categories.png); +} +.icon-48-banners-category-add { + background-image: url(../images/header/icon-48-category-add.png); +} +.icon-48-banners-clients { + background-image: url(../images/header/icon-48-banner-client.png); +} +.icon-48-banners-tracks { + background-image: url(../images/header/icon-48-banner-tracks.png); +} +.icon-48-checkin { + background-image: url(../images/header/icon-48-checkin.png); +} +.icon-48-clear { + background-image: url(../images/header/icon-48-clear.png); +} +.icon-48-contact { + background-image: url(../images/header/icon-48-contacts.png); +} +.icon-48-contact-categories { + background-image: url(../images/header/icon-48-contacts-categories.png); +} +.icon-48-contact-category-edit { + background-image: url(../images/header/icon-48-contacts-categories.png); +} +.icon-48-contact-category-add { + background-image: url(../images/header/icon-48-category-add.png); +} +.icon-48-purge { + background-image: url(../images/header/icon-48-purge.png); +} +.icon-48-cpanel { + background-image: url(../images/header/icon-48-cpanel.png); +} +.icon-48-config { + background-image: url(../images/header/icon-48-config.png); +} +.icon-48-groups { + background-image: url(../images/header/icon-48-groups.png); +} +.icon-48-groups-add { + background-image: url(../images/header/icon-48-groups-add.png); +} +.icon-48-levels { + background-image: url(../images/header/icon-48-levels.png); +} +.icon-48-levels-add { + background-image: url(../images/header/icon-48-levels-add.png); +} +.icon-48-module { + background-image: url(../images/header/icon-48-module.png); +} +.icon-48-menu { + background-image: url(../images/header/icon-48-menu.png); +} +.icon-48-menu-add { + background-image: url(../images/header/icon-48-menu-add.png); +} +.icon-48-menumgr { + background-image: url(../images/header/icon-48-menumgr.png); +} +.icon-48-trash { + background-image: url(../images/header/icon-48-trash.png); +} +.icon-48-user { + background-image: url(../images/header/icon-48-user.png); +} +.icon-48-user-add { + background-image: url(../images/header/icon-48-user-add.png); +} +.icon-48-user-edit { + background-image: url(../images/header/icon-48-user-edit.png); +} +.icon-48-user-profile { + background-image: url(../images/header/icon-48-user-profile.png); +} +.icon-48-inbox { + background-image: url(../images/header/icon-48-inbox.png); +} +.icon-48-new-privatemessage { + background-image: url(../images/header/icon-48-new-privatemessage.png); +} +.icon-48-msgconfig { + background-image: url(../images/header/icon-48-message_config.png); +} +.icon-48-langmanager { + background-image: url(../images/header/icon-48-language.png); +} +.icon-48-mediamanager { + background-image: url(../images/header/icon-48-media.png); +} +.icon-48-plugin { + background-image: url(../images/header/icon-48-plugin.png); +} +.icon-48-help_header { + background-image: url(../images/header/icon-48-help_header.png); +} +.icon-48-impressions { + background-image: url(../images/header/icon-48-stats.png); +} +.icon-48-browser { + background-image: url(../images/header/icon-48-stats.png); +} +.icon-48-searchtext { + background-image: url(../images/header/icon-48-stats.png); +} +.icon-48-thememanager { + background-image: url(../images/header/icon-48-themes.png); +} +.icon-48-writemess { + background-image: url(../images/header/icon-48-writemess.png); +} +.icon-48-featured { + background-image: url(../images/header/icon-48-featured.png); +} +.icon-48-sections { + background-image: url(../images/header/icon-48-section.png); +} +.icon-48-article-add { + background-image: url(../images/header/icon-48-article-add.png); +} +.icon-48-article-edit { + background-image: url(../images/header/icon-48-article-edit.png); +} +.icon-48-article { + background-image: url(../images/header/icon-48-article.png); +} +.icon-48-content-categories { + background-image: url(../images/header/icon-48-category.png); +} +.icon-48-content-category-edit { + background-image: url(../images/header/icon-48-category.png); +} +.icon-48-content-category-add { + background-image: url(../images/header/icon-48-category-add.png); +} +.icon-48-install { + background-image: url(../images/header/icon-48-extension.png); +} +.icon-48-dbbackup { + background-image: url(../images/header/icon-48-backup.png); +} +.icon-48-dbrestore { + background-image: url(../images/header/icon-48-dbrestore.png); +} +.icon-48-dbquery { + background-image: url(../images/header/icon-48-query.png); +} +.icon-48-systeminfo { + background-image: url(../images/header/icon-48-info.png); +} +.icon-48-massmail { + background-image: url(../images/header/icon-48-massmail.png); +} +.icon-48-redirect { + background-image: url(../images/header/icon-48-redirect.png); +} +.icon-48-search { + background-image: url(../images/header/icon-48-search.png); +} +.icon-48-finder { + background-image: url(../images/header/icon-48-search.png); +} +.icon-48-newsfeeds { + background-image: url(../images/header/icon-48-newsfeeds.png); +} +.icon-48-newsfeeds-categories { + background-image: url(../images/header/icon-48-newsfeeds-cat.png); +} +.icon-48-newsfeeds-category-edit { + background-image: url(../images/header/icon-48-newsfeeds-cat.png); +} +.icon-48-newsfeeds-category-add { + background-image: url(../images/header/icon-48-category-add.png); +} +.icon-48-weblinks { + background-image: url(../images/header/icon-48-links.png); +} +.icon-48-weblinks-categories { + background-image: url(../images/header/icon-48-links-cat.png); +} +.icon-48-weblinks-category-edit { + background-image: url(../images/header/icon-48-links-cat.png); +} +.icon-48-weblinks-category-add { + background-image: url(../images/header/icon-48-category-add.png); +} +.icon-48-tags { + background-image: url(../images/header/icon-48-tags.png); +} +.icon-48-assoc { + background-image: url(../images/header/icon-48-assoc.png); +} +.icon-48-puzzle { + background-image: url(../images/header/icon-48-puzzle.png); +} +div.message { + border: 1px solid #000000; + color: #2c2c2c; +} +.helpFrame { + border-left: 0 solid #000000; + border-right: none; + border-top: none; + border-bottom: none; +} +.outline { + border: 1px solid #000000; + background: #ffffff; +} +dl.menu_type dt { + border-bottom: 1px solid #000000; +} +ul#new-modules-list { + border-top: 1px solid #000000; +} +#skiplinkholder a, +#skiplinkholder a:link, +#skiplinkholder a:visited { + color: #ffffff; + background: #054993; + border-bottom: solid #336 2px; +} +fieldset.panelform { + border: none 0; +} +a.move_up { + background-image: url('../images/admin/uparrow.png'); +} +span.move_up { + background-image: url('../images/admin/uparrow0.png'); +} +a.move_down { + background-image: url('../images/admin/downarrow.png'); +} +span.move_down { + background-image: url('../images/admin/downarrow0.png'); +} +a.grid_false { + background-image: url('../images/admin/publish_x.png'); +} +a.grid_true { + background-image: url('../images/admin/tick.png'); +} +a.grid_trash { + background-image: url('../images/admin/icon-16-trash.png'); +} +tr.row1 { + background-color: #d5c1b2; +} +table.aclsummary-table td.col2, +table.aclsummary-table th.col2, +table.aclsummary-table td.col3, +table.aclsummary-table th.col3, +table.aclsummary-table td.col4, +table.aclsummary-table th.col4, +table.aclsummary-table td.col5, +table.aclsummary-table th.col5, +table.aclsummary-table td.col6, +table.aclsummary-table th.col6, +table.aclmodify-table td.col2, +table.aclmodify-table th.col2 { + border-left: 1px solid #000000; +} +span.icon-16-unset { + background: url(../images/admin/icon-16-denyinactive.png) no-repeat; +} +span.icon-16-allowed { + background: url(../images/admin/icon-16-allow.png) no-repeat; +} +span.icon-16-denied { + background: url(../images/admin/icon-16-deny.png) no-repeat; +} +span.icon-16-locked { + background: url(../images/admin/checked_out.png) 0 0 no-repeat; +} +label.icon-16-allow { + background: url(../images/admin/icon-16-allow.png) no-repeat; +} +label.icon-16-deny { + background: url(../images/admin/icon-16-deny.png) no-repeat; +} +a.icon-16-allow { + background: url(../images/admin/icon-16-allow.png) no-repeat; +} +a.icon-16-deny { + background: url(../images/admin/icon-16-deny.png) no-repeat; +} +a.icon-16-allowinactive { + background: url(../images/admin/icon-16-allowinactive.png) no-repeat; +} +a.icon-16-denyinactive { + background: url(../images/admin/icon-16-denyinactive.png) no-repeat; +} +ul.acllegend li.acl-allowed { + background: url(../images/admin/icon-16-allow.png) no-repeat left; +} +ul.acllegend li.acl-denied { + background: url(../images/admin/icon-16-deny.png) no-repeat left; +} +li.acl-editgroups, +li.acl-resetbtn { + background-color: #d5c1b2; + border: 1px solid #000000; +} +li.acl-editgroups a, +li.acl-resetbtn a { + color: #054993; +} +li.acl-editgroups:hover, +li.acl-resetbtn:hover, +li.acl-editgroups:focus, +li.acl-resetbtn:focus { + background-color: #e5d9c3; +} +table#acl-config { + border: 1px solid #000000; +} +table#acl-config th, +table#acl-config td { + background: #d5c1b2; + border-bottom: 1px solid #000000; +} +table#acl-config th.acl-groups { + border-right: 1px solid #000000; +} +#jform_sef_rewrite-lbl { + background: url(../images/admin/icon-16-notice-note.png) right top no-repeat; +} +#permissions-sliders .tip { + background: #ffffff; + border: 1px solid #000000; +} +#permissions-sliders ul#rules, +#permissions-sliders ul#rules ul { + border: solid 0 #000000; + background: #ffffff; +} +ul#rules li .pane-sliders .panel h3.title { + border: solid 0 #000000; +} +#permissions-sliders ul#rules .pane-slider { + border: solid 1px #000000; +} +#permissions-sliders ul#rules li h3 { + border: solid 1px #000000; +} +#permissions-sliders ul#rules li h3.pane-toggler-down a { + border: solid 0; +} +#permissions-sliders ul#rules .group-kind { + color: #2c2c2c; +} +#permissions-sliders ul#rules table.group-rules { + border: solid 1px #000000; +} +#permissions-sliders ul#rules table.group-rules td { + border-right: solid 1px #000000; + border-bottom: solid 1px #000000; +} +#permissions-sliders ul#rules table.group-rules th { + background: #e5d9c3; + border-right: solid 1px #000000; + border-bottom: solid 1px #000000; + color: #2c2c2c; +} +ul#rules table.aclmodify-table { + border: solid 1px #000000; +} +ul#rules table.group-rules td label { + border: solid 0 #000000; +} +#permissions-sliders ul#rules .mypanel { + border: solid 0 #000000; +} +#permissions-sliders ul#rules table.group-rules td { + background: #ffffff; +} +#permissions-sliders span.level { + color: #000000; + background-image: none; +} +.check-0, +table.adminlist tbody td.check-0 { + background-color: #ffffcf; +} +.check-a, +table.adminlist tbody td.check-a { + background-color: #cfffda; +} +.check-d, +table.adminlist tbody td.check-d { + background-color: #ffcfcf; +} +#system-message dd ul { + color: #2c2c2c; +} +#system-message dd.error ul { + color: #2c2c2c; +} +#system-message dd.message ul { + color: #2c2c2c; +} +#system-message dd.notice ul { + color: #2c2c2c; +} +#menu { + color: #2c2c2c; +} +#menu ul.dropdown-menu { + background-color: #d5c1b2; + background-image: -moz-linear-gradient(top,#d5c1b2,#d5c1b2); + background-image: -webkit-gradient(linear,0 0,0 100%,from(#d5c1b2),to(#d5c1b2)); + background-image: -webkit-linear-gradient(top,#d5c1b2,#d5c1b2); + background-image: -o-linear-gradient(top,#d5c1b2,#d5c1b2); + background-image: linear-gradient(to bottom,#d5c1b2,#d5c1b2); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd5c1b2', endColorstr='#ffd5c1b2', GradientType=0); + color: #2c2c2c; +} +#menu ul.dropdown-menu li.dropdown-submenu { + background: url(../images/j_arrow.png) no-repeat right 50%; +} +#menu ul.dropdown-menu li.divider { + margin-bottom: 0; + border-bottom: 1px dotted #000000; +} +#menu a { + color: #054993; + background-repeat: no-repeat; + background-position: left 50%; +} +#menu li { + border-right: 1px solid #000000; + background-color: transparent; +} +#menu li a:hover, +#menu li a:focus { + background-color: #e5d9c3; +} +#menu li.disabled a:hover, +#menu li.disabled a:focus, +#menu li.disabled a { + color: #000000; + background-color: #d5c1b2; + background-image: -moz-linear-gradient(top,#d5c1b2,#d5c1b2); + background-image: -webkit-gradient(linear,0 0,0 100%,from(#d5c1b2),to(#d5c1b2)); + background-image: -webkit-linear-gradient(top,#d5c1b2,#d5c1b2); + background-image: -o-linear-gradient(top,#d5c1b2,#d5c1b2); + background-image: linear-gradient(to bottom,#d5c1b2,#d5c1b2); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd5c1b2', endColorstr='#ffd5c1b2', GradientType=0); +} +#menu li ul { + border: 1px solid #000000; +} +#menu li li { + background-color: transparent; +} +#menu li.sfhover a { + background-color: #e5d9c3; +} +#menu li.sfhover li a { + background-color: transparent; +} +#menu li.sfhover li.sfhover a, +#menu li li a:focus { + background-color: #e5d9c3; +} +#menu li.sfhover li.sfhover li a { + background-color: transparent; +} +#menu li.sfhover li.sfhover li.sfhover a, +#menu li li li a:focus { + background-color: #e5d9c3; +} +#menu li li a:focus, +#menu li li li a:focus { + background-color: #e5d9c3; +} +#menu li li li a:focus { + background-color: #e5d9c3; +} +#submenu { + border-bottom: 1px solid #000000; +} +#submenu li, +#submenu span.nolink { + background-color: #d5c1b2; + background-image: -moz-linear-gradient(top,#d5c1b2,#d5c1b2); + background-image: -webkit-gradient(linear,0 0,0 100%,from(#d5c1b2),to(#d5c1b2)); + background-image: -webkit-linear-gradient(top,#d5c1b2,#d5c1b2); + background-image: -o-linear-gradient(top,#d5c1b2,#d5c1b2); + background-image: linear-gradient(to bottom,#d5c1b2,#d5c1b2); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd5c1b2', endColorstr='#ffd5c1b2', GradientType=0); + border: 1px solid #000000; + color: #054993; +} +#submenu li:hover, +#submenu li:focus { + background: #e5d9c3; +} +#submenu li.active, +#submenu span.nolink.active { + background: #ffffff; + border-bottom: 1px solid #ffffff; +} +#submenu li.active a, +#submenu span.nolink.active { + color: #000; +} +.element-invisible { + margin: 0; + padding: 0; +} +div.CodeMirror-wrapping { + border: 1px solid #000000; +} +table.adminform tr.row0 { + background-color: #ffffff; +} +ul.alternating > li:nth-child(odd) { + background-color: #ffffff; +} +ul.alternating > li:nth-child(even) { + background-color: #d5c1b2; +} +ol.alternating > li:nth-child(odd) { + background-color: #ffffff; +} +ol.alternating > li:nth-child(even) { + background-color: #d5c1b2; +} +#installer-database, +#installer-discover, +#installer-update, +#installer-warnings { + border-top: 1px solid #000000; +} +#installer-database p.warning { + background: transparent url(../images/admin/icon-16-deny.png) center left no-repeat; +} +#installer-database p.nowarning { + background: transparent url(../images/admin/icon-16-allow.png) center left no-repeat; +} +.input-append, +.input-prepend { + font-size: 1.2em; +} diff --git a/Sites/pages/administrator/templates/hathor/css/colour_brown_rtl.css b/Sites/pages/administrator/templates/hathor/css/colour_brown_rtl.css new file mode 100644 index 00000000..bfa662e5 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/css/colour_brown_rtl.css @@ -0,0 +1,316 @@ +@charset "UTF-8"; + +/** + * @package Joomla.Administrator + * @subpackage templates.hathor + * @copyright Copyright (C) 2005 - 2020 Open Source Matters, Inc. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + * @since 1.6 + * + * RTL CSS file for the color standard + */ + +/** + * Overall Styles + */ +#header { + background: #ffffff url(../images/j_logo.png) no-repeat top right; +} + +/** + * Various Styles + */ +div.checkin-tick { + background: url(../images/admin/tick.png) 20px 50% no-repeat; +} + +/** + * Pane Slider pane Toggler styles + */ +.pane-toggler span { + background: transparent url(../images/j_arrow_left.png) right 50% no-repeat; +} + +.pane-toggler-down span { + background: transparent url(../images/j_arrow_down.png) right 50% no-repeat; +} + +/** + * Cpanel Settings + */ +fieldset#filter-bar { + border-left: none; + border-right: none; +} + +/** + * Admintable Styles + */ + +table.admintable td.key,table.admintable td.paramlist_key { + border-left: 1px solid #e9e9e9; + border-right: none; +} + +table.paramlist td.paramlist_description { + border-left: 1px solid #e9e9e9; + border-right: none; +} + +/** + * Admin Form Styles + */ +table.adminform tr { + border-left: 1px solid #000000; + border-right: none; +} + +/** + * Adminlist Table layout + */ + +table.adminlist.modal { + border-right: 1px solid #000000; + border-left: 1px solid #000000; +} + + /* Table row styles */ +table.adminlist tbody tr td:last-child { + border-left: none; +} + +/** + * Saving order icon styling in admin tables + */ +a.saveorder { + background: url(../images/admin/filesave.png) no-repeat; +} + +a.saveorder.inactive { + background-position: 0 -16px; +} + +/** + * Button styling + */ + +/* Button 1 Type */ + + /* Use this if you add images to the buttons such as directional arrows */ + +.button1 a { + /* add padding if you are using the directional images */ + /* padding: 0 6px 0 30px; */ +} + + /* Button 2 Type */ + +.button2-right .prev { + background-image: url(../images/j_button2_prev.png); + background-position: right center; +} + +.button2-right.off .prev { + background: url(../images/j_button2_prev_off.png) no-repeat; +} + +.button2-right .start { + background-image: url(../images/j_button2_first.png); + background-position: right center; +} + +.button2-left .next { + background-image: url(../images/j_button2_next.png); + background-position: left center; +} + +.button2-left.off .next { /* @TODO check the x position */ + background: url(../images/j_button2_next_off.png) 100% 0 no-repeat; +} + +.button2-left .end { + background-image: url(../images/j_arrow_left.png); + background-position: left center; +} + +.button2-left.off .end { /* @TODO check the x position */ + background: url(../images/j_button2_last_off.png) 100% 0 no-repeat; +} + +.button2-left .image { + background: url(../images/j_button2_image.png) 100% 0 no-repeat; +} + +.button2-left .readmore { + background: url(../images/j_button2_readmore.png) 100% 0 no-repeat; +} + +.button2-left .pagebreak { + background: url(../images/j_button2_pagebreak.png) 100% 0 no-repeat; +} + +/** + * Tooltips + */ + + +/** + * System Standard Messages + */ +#system-message dd.message ul { + background: #C3D2E5 url(../images/notice-info.png) 99.5% center no-repeat; +} + +/** + * System Error Messages + */ +#system-message dd.error ul { + background: #E6C0C0 url(../images/notice-alert.png) 99.5% top no-repeat; +} + +/** + * System Notice Messages + */ +#system-message dd.notice ul { + background: #EFE7B8 url(../images/notice-note.png) 99%.5 top no-repeat; +} + +/** + * JGrid styles + */ + +/** + * Menu Icons + * These icons are used on the Administrator menu + * The classes are constructed dynamically when the menu is generated + */ + + +/** + * Toolbar icons + * These icons are used for the toolbar buttons + * The classes are constructed dynamically when the toolbar is created + */ + +/** + * Quick Icons + * Also knows as Header Icons + * These are used for the Quick Icons on the Control Panel + * The same classes are also assigned the Component Title + */ + +/** + * General styles + */ + +.helpFrame { + border-right: 0 solid #222; + border-left: none; + border-top: none; +} + +/* -- ACL STYLES relocated from com_users/media/grid.css ----------- */ + +/* -- ACL PANEL STYLES ----------- */ + + +/* All Tabs */ + +table.aclsummary-table td.col2, +table.aclsummary-table th.col2, +table.aclsummary-table td.col3, +table.aclsummary-table th.col3, +table.aclsummary-table td.col4, +table.aclsummary-table th.col4, +table.aclsummary-table td.col5, +table.aclsummary-table th.col5, +table.aclsummary-table td.col6, +table.aclsummary-table th.col6, +table.aclmodify-table td.col2, +table.aclmodify-table th.col2 { + border-right: 1px solid #cbcbcb; + border-left: none; +} + +/* Icons */ + +ul.acllegend li.acl-allowed { + background: url(../images/admin/icon-16-allow.png) no-repeat right; +} +ul.acllegend li.acl-denied { + background: url(../images/admin/icon-16-deny.png) no-repeat right; +} + +table#acl-config th.acl-groups { + border-left: 1px solid #000000; +} + +table#acl-config th.acl-groups { + text-align: right; +} + +.acl-action { + margin: auto 0; +} + +/* Icons */ + +span.icon-16-unset { + background: url(../images/admin/icon-16-denyinactive.png) no-repeat right; +} + +span.icon-16-allowed { + background: url(../images/admin/icon-16-allow.png) no-repeat right; +} + +span.icon-16-denied { + background: url(../images/admin/icon-16-deny.png) no-repeat right; +} + +span.icon-16-locked { + background: url(../images/admin/checked_out.png) no-repeat right; +} + +/** +* Mod_rewrite Warning +*/ +#jform_sef_rewrite-lbl { + background: url(../images/admin/icon-16-notice-note.png) left top no-repeat; +} + +/** +* Permission Rules +*/ + +#permissions-sliders ul#rules table.group-rules td { + border-left: solid 1px #000000; + border-right: solid 0 #000000; +} + +#permissions-sliders ul#rules table.group-rules th { + border-left: solid 1px #000000; + border-right: solid 0 #000000; +} + +/** + * Menu Styling + */ + +#menu ul li.node { + background-image: url(../images/j_arrow_left.png); + background-repeat: no-repeat; + background-position: left 50%; +} + +#menu a { + background-position: right 50%; +} + +/* Installer Database */ +#installer-database p.warning { + background-position: center right; +} + +#installer-database p.nowarning { + background-position: center right; +} diff --git a/Sites/pages/administrator/templates/hathor/css/colour_highcontrast.css b/Sites/pages/administrator/templates/hathor/css/colour_highcontrast.css new file mode 100644 index 00000000..cb6ba3c6 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/css/colour_highcontrast.css @@ -0,0 +1,2155 @@ +@charset "UTF-8"; + +/** + * @package Joomla.Administrator + * @subpackage templates.hathor + * @copyright Copyright (C) 2005 - 2020 Open Source Matters, Inc. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + * @since 1.6 + * + * Changes to use high contrast colors + */ + +/** + * Main Colors + * #163365 Text background/border + * #1c4181 Alternative text background 1/border + * #1b3f7c Alternative text background 2/border + * #fcff20 Text + * #ffffff Highlighted Text + * #10254a Main hover color/border + * #000000 Highlight/shadow border + * #a20000 Invalid Alert Color + * #00f800 Success Alert Color + * #feffbf Disabled Menu/Protected + * + * MENU: + * + * Standard Link + * #1b3f7c Link Background + * #ffffff Text + * #10254a Border + * + * Pressed Link + * #163365 Text background + * #ffffff Highlighted Text + * #000000 Left & Top Border + * #1b3f7c Right & Bottom Border + * + * Background behind the links + * #163365 Background + * #122b56 Border + * + * Inactive (Disabled) + * #cccccc Text + * + * SUBMENU + * #163365 Active Tab Background + * #fcff20 Active Tab Text color + * #10254a Hover background + * #10254a Border + * #1b3f7c "off" Tab Background + * #ffffff "off" Tab Text color + * + * #1c4181 Color behind the tabs + */ + +/** + * General styles + */ +body { + background-color: #1c4181; + color: #fcff20; +} + +div#sbox-content { + background-color: #1c4181; + color: #fcff20; +} + +h1 { + color: #163365; +} + +a:link { + color: #ffffff; +} + +a:visited { + color: #ffffff; +} + +a:hover,a:focus { + text-decoration: underline; + color: #fcff20; +} + +/** + * Overall Styles + */ +#header { + background: #ffffff url(../images/j_logo.png) no-repeat; +} + +#header h1.title { + color: #163365; +} + +#footer { + background: #163365; + border: 1px solid #1b3f7c; +} + +#nav { + background: #163365; + border: 1px solid #1b3f7c; +} + +#content { + background: #1c4181; +} + +#no-submenu { + border-bottom: 1px solid #1b3f7c; +} + +#element-box { + background: #163365; + border-right: 1px solid #1b3f7c; + border-bottom: 1px solid #1b3f7c; + border-left: 1px solid #1b3f7c; +} + +#element-box.login { + border-top: 1px solid #1b3f7c; +} + +/** + * Status layout + */ +#module-status a, #module-status span { + color: #163365; +} + +#module-status .preview { + background: url(../images/menu/icon-16-media.png) 3px 3px no-repeat; +} + +#module-status .viewsite { + background: url(../images/menu/icon-16-viewsite.png) 3px 3px no-repeat; +} + +#module-status .unread-messages,#module-status .no-unread-messages { + background: url(../images/menu/icon-16-messages.png) 3px 3px no-repeat; +} + +#module-status .loggedin-users { + background: url(../images/menu/icon-16-user.png) 3px 3px no-repeat; +} + +#module-status .backloggedin-users { + background: url(../images/menu/icon-16-back-user.png) 3px 3px no-repeat; +} + +#module-status .multilanguage { + background: url(../images/menu/icon-16-language.png) 3px 3px no-repeat; +} + +#module-status .logout { + background: url(../images/menu/icon-16-logout.png) 3px 3px no-repeat; +} + +/** + * Various Styles + */ +.enabled, +.success , +.allow, +span.writable { + color: #00f800; +} + +.disabled, +p.error, +.warning, +.deny, +span.unwritable { + color: #a20000; +} + +.nowarning { + color: #fcff20; +} + +.none,.protected { + color: #feffbf; +} + +span.note { + background: #163365; + color: #fcff20; +} + +div.checkin-tick { + background: url(../images/admin/tick.png) 20px 50% no-repeat; +} + +/** + * Overlib + */ +.ol-foreground { + background-color: #fcff20; +} + +.ol-background { + background-color: #1b3f7c; +} + +.ol-textfont { + color: #163365; +} + +.ol-captionfont { + color: #ffffff; +} + +.ol-captionfont a { + color: #1b3f7c; +} + +/** + * Subheader, toolbar, page title + */ +.pagetitle h2 { + color: #fcff20; +} + +div.configuration { + color: #fcff20; + background-image: url(../images/menu/icon-16-config.png); + background-repeat: no-repeat; +} + +div.toolbar-box { + border-right: 1px solid #10254a; + border-bottom: 1px solid #10254a; + border-left: 1px solid #10254a; + background: #163365; +} + +div.toolbar-list li { + color: #fcff20; +} + +div.toolbar-list li.divider { + border-right:1px dotted #1b3f7c; +} + +div.toolbar-list a { + border: 1px solid #10254a; + color: #fcff20; + background: #1b3f7c; +} + +div.toolbar-list a:hover { + border-left: 1px solid #000000; + border-top: 1px solid #000000; + border-right: 1px solid #1b3f7c; + border-bottom: 1px solid #1b3f7c; + background: #163365; + color: #ffffff; +} + +/** + * Pane Slider pane Toggler styles + */ +.pane-sliders .title { + color: #fcff20; + border: 1px solid #10254a; +} + +.pane-sliders .panel { + border: 1px solid #1b3f7c; +} + +.pane-sliders .panel h3 { + background: #1c4181; + color: #fcff20; +} + +.pane-sliders .content { + background: #163365; +} + +.pane-sliders .adminlist { + border: 0 none; +} + +.pane-sliders .adminlist td { + border: 0 none; +} + +.pane-toggler span { + background: transparent url(../images/j_arrow.png) 5px 50% no-repeat; +} + +.pane-toggler-down span { + background: transparent url(../images/j_arrow_down.png) 5px 50% + no-repeat; +} + +.pane-toggler-down { + border-bottom: 1px solid #1b3f7c; +} + +/** + * Tabs + */ +dl.tabs dt { + border: 1px solid #10254a; + background: #1c4181; + color: #fcff20; +} + +dl.tabs dt.open { + background: #163365; + border-bottom: 1px solid #163365; + color: #fcff20; +} + +dl.tabs dt.open a:visited { + color: #fcff20; +} + +div.current { + border: 1px solid #10254a; + background: #163365; +} + +div.current dd { + padding: 0; + margin: 0; +} + +div#menu-assignment h3 { + border-bottom: 1px solid #fcff20; +} + +/** + * Login Settings + */ +#login-page .pagetitle h2 { + background-color: transparent; + /* background-color: #1c4181; */ + color: #fcff20; +} + +#login-page #header { + border-bottom: 1px solid #1b3f7c; +} + +#login-page #content { + background: #1c4181; +} + +#login-page #lock { + background: url(../images/j_login_lock.png) 50% 0 no-repeat; +} + +#login-page #element-box.login { + background: #163365; + border: 1px solid #10254a; +} + +#form-login { + border: 1px solid #10254a; + background: #1c4181; +} + +#form-login label { + color: #fcff20; +} + +#form-login div.button1 a { + color: #fcff20; + background-color: #1b3f7c; + border: 1px solid #10254a; +} + +#form-login div.button1 a:hover,#form-login div.button1 a:focus { + text-decoration: none; + background-color: #163365; + border-top: 1px solid #000000; + border-right: 1px solid #1b3f7c; + border-bottom: 1px solid #1b3f7c; + border-left: 1px solid #000000; + color: #fcff20; +} + +/** + * Cpanel Settings + */ +.cpanel-page div#element-box { + background: #163365; + border: 1px solid #10254a; +} + +#cpanel div.icon a, .cpanel div.icon a { + border: 1px solid #10254a; + background: #1b3f7c; + color: #fcff20; +} + +#cpanel div.icon a:hover, +#cpanel div.icon a:focus, +.cpanel div.icon a:hover, +.cpanel div.icon a:focus { + border-left: 1px solid #000000; + border-top: 1px solid #000000; + border-right: 1px solid #1b3f7c; + border-bottom: 1px solid #1b3f7c; + background: #163365; + color: #ffffff; +} + +/** + * Form Styles + */ +fieldset { + border: 3px dotted #1b3f7c; +} + +legend { + color: #fcff20; +} + +fieldset ul.checklist input:focus { + outline: thin dotted #333333; +} + +fieldset#filter-bar { + border-bottom: 1px solid #1b3f7c; +} + +fieldset#filter-bar ol, fieldset#filter-bar ul { + border: 0; +} + +fieldset#filter-bar ol li fieldset, fieldset#filter-bar ul li fieldset { + border: 0; +} + +input,span.faux-input, select,option { + color: #fcff20; + background-color: #163365; + border: 1px solid #1b3f7c; +} + +/* Note: these visual cues should be augmented by aria */ +.invalid { + color: #a20000; + background-color: #ffffff; +} + +/* must be augmented by aria at the same time if changed dynamically by js + aria-invalid=true or aria-invalid=false */ +input.invalid { + border: 1px solid #a20000; +} + +input.required { + background-color: #fcff20; + color: #163365; + border: 1px solid #1b3f7c; +} + +input.disabled { + background-color: #eeeeee; +} + +/* Inputs used as buttons */ +input[type="button"], +input[type="submit"], +input[type="reset"] { + background-color: #1b3f7c; + border: 1px solid #10254a; + color: #fcff20; +} + +input[type="button"]:hover, input[type="button"]:focus, +input[type="submit"]:hover, input[type="submit"]:focus, +input[type="reset"]:hover, input[type="reset"]:focus { + background-color: #163365; + border-top: 1px solid #000000; + border-right: 1px solid #1b3f7c; + border-bottom: 1px solid #1b3f7c; + border-left: 1px solid #000000; + color: #fcff20; +} + +textarea { + color: #fcff20; + background-color: #163365; + border: 1px solid #1b3f7c; +} + +input:focus, select:focus, textarea:focus, option:focus, +input:hover, select:hover, textarea:hover, option:hover + { + background-color: #10254a; + color: #fcff20; +} + +/** + * Option or Parameter styles + */ +.paramrules { + background: #1b3f7c; +} + +span.gi { + color: #ffffff; +} + + +/** + * Admintable Styles + */ +table.admintable td.key,table.admintable td.paramlist_key { + background-color: #1c4181; + color: #fcff20; + border-bottom: 1px solid #10254a; + border-right: 1px solid #10254a; +} + +table.paramlist td.paramlist_description { + background-color: #1c4181; + color: #fcff20; + border-bottom: 1px solid #10254a; + border-right: 1px solid #10254a; +} + +/** + * Admin Form Styles + */ +fieldset.adminform { + border: 1px solid #1b3f7c; +} + + /* Table styles are for use with tabular data */ +table.adminform { + background-color: #163365; +} + +table.adminform tr.row0 { + background-color: #163365; +} + +table.adminform tr.row1 { + background-color: #10254a; +} + +table.adminform th { + color: #fcff20; + background: #163365; +} + +table.adminform tr { + border-bottom: 1px solid #1b3f7c; + border-right: 1px solid #1b3f7c; +} + +/** + * Adminlist Table layout + */ +table.adminlist { + background-color: #163365; + color: #fcff20; +} + +table.adminlist a { + color: #ffffff; +} + +table.adminlist thead th { + background: #163365; + color: #fcff20; +} + +/* Table row styles */ +table.adminlist tbody tr { + background: #163365; +} + +table.adminlist tbody tr.row1 { + background: #163365; +} + +table.adminlist tbody tr.row1 td, +table.adminlist tbody tr.row1 th { + border-bottom: 1px solid #1b3f7c; +} + +table.adminlist tbody tr.row0:hover td, +table.adminlist tbody tr.row1:hover td, +table.adminlist tbody tr.row0:hover th, +table.adminlist tbody tr.row1:hover th, +table.adminlist tbody tr.row0:focus td, +table.adminlist tbody tr.row1:focus td, +table.adminlist tbody tr.row0:focus th, +table.adminlist tbody tr.row1:focus th { + background-color: #10254a; +} + +table.adminlist tbody tr td, +table.adminlist tbody tr th { + border-right: 1px solid #1b3f7c; +} + +table.adminlist tbody tr td:last-child { + border-right: none; +} + +table.adminlist tbody tr.row0:last-child td, +table.adminlist tbody tr.row0:last-child th { + border-bottom: 1px solid #1b3f7c; +} + +table.adminlist tbody tr.row0 td, +table.adminlist tbody tr.row0 th { + background: #1c4181; +} + +table.adminlist tfoot tr { + color: #fcff20; +} + +/* Table td/th styles */ +table.adminlist tfoot td,table.adminlist tfoot th { + background-color: #163365; + border-top: 1px solid #1b3f7c; +} + +/** + * Adminlist buttons + */ +table.adminlist tr td.btns a { + background-color: #1b3f7c; + border: 1px solid #10254a; + color: #fcff20; +} + +table.adminlist tr td.btns a:hover, table.adminlist tr td.btns a:active, table.adminlist tr td.btns a:focus { + background-color: #163365; + border-top: 1px solid #000000; + border-right: 1px solid #1b3f7c; + border-bottom: 1px solid #1b3f7c; + border-left: 1px solid #000000; + color: #fcff20; +} + +/** + * Saving order icon styling in admin tables + */ +a.saveorder { + background: url(../images/admin/filesave.png) no-repeat; +} + +a.saveorder.inactive { + background-position: 0 -16px; +} + +/** + * Saving order icon styling in admin tables + */ +fieldset.batch { + background: #1c4181; +} + + +/** + * Button styling + */ +button { + color: #fcff20; + background-color: #1b3f7c; + border: 1px solid #10254a; +} + +button:hover, button:focus { + background-color: #163365; + border-top: 1px solid #000000; + border-right: 1px solid #1b3f7c; + border-bottom: 1px solid #1b3f7c; + border-left: 1px solid #000000; + color: #fcff20; +} + +/* Button 1 Type */ +.button1 { + border: none; + background: #1b3f7c; +} + + /* Use this if you add images to the buttons such as directional arrows */ +.button1 .next { + /* background: transparent url(../images/j_button1_next.png) 100% 0 no-repeat; */ +} + +.button1 a { + border: 1px solid #10254a; + color: #fcff20; +} + +.button1 a:hover,.button1 a:focus { + text-decoration: none; + background-color: #163365; + border-top: 1px solid #000000; + border-right: 1px solid #1b3f7c; + border-bottom: 1px solid #1b3f7c; + border-left: 1px solid #000000; + color: #fcff20; +} + +/* Button 2 Type */ +.button2-left,.button2-right { + border: none; + background: #1b3f7c; +} + +.button2-left a,.button2-right a,.button2-left span,.button2-right span + { + color: #fcff20; + border: 1px solid #10254a; +} + +/* these are inactive buttons */ +.button2-left span,.button2-right span { + color: #cccccc; + border: 1px solid #10254a; +} + +.page span,.blank span { + color: #fcff20; + border: 1px solid #10254a; +} + +.button2-left a:hover,.button2-right a:hover,.button2-left a:focus,.button2-right a:focus + { + text-decoration: none; + background-color: #163365; + border-top: 1px solid #000000; + border-right: 1px solid #1b3f7c; + border-bottom: 1px solid #1b3f7c; + border-left: 1px solid #000000; + color: #fcff20; +} + +/** + * Pagination styles + */ + + /* Grey out the current page number */ +.pagination .page span { + color: #cccccc; +} + +/** + * Tooltips + */ +.tip { + background: #000000; + border: 1px solid #FFFFFF; +} + +.tip-title { + background: url(../images/selector-arrow-std.png) no-repeat; +} + +/** + * Calendar + */ +a img.calendar { + background: url(../images/calendar.png) no-repeat; +} + +/** + * JGrid styles + */ +.jgrid span.publish { + background-image: url(../images/admin/tick.png); +} + +.jgrid span.unpublish { + background-image: url(../images/admin/publish_x.png); +} + +.jgrid span.archive { + background-image: url(../images/menu/icon-16-archive.png); +} + +.jgrid span.trash { + background-image: url(../images/menu/icon-16-trash.png); +} + +.jgrid span.default { + background-image: url(../images/menu/icon-16-default.png); +} + +.jgrid span.notdefault { + background-image: url(../images/menu/icon-16-notdefault.png); +} + +.jgrid span.checkedout { + background-image: url(../images/admin/checked_out.png); +} + +.jgrid span.downarrow { + background-image: url(../images/admin/downarrow.png); +} + +.jgrid span.downarrow_disabled { + background-image: url(../images/admin/downarrow0.png); +} + +.jgrid span.uparrow { + background-image: url(../images/admin/uparrow.png); +} + +.jgrid span.uparrow_disabled { + background-image: url(../images/admin/uparrow0.png); +} + +.jgrid span.published { + background-image: url(../images/admin/publish_g.png); +} + +.jgrid span.expired { + background-image: url(../images/admin/publish_r.png); +} + +.jgrid span.pending { + background-image: url(../images/admin/publish_y.png); +} + +.jgrid span.warning { + background-image: url(../images/admin/publish_y.png); +} + +/** + * Menu Icons + * These icons are used on the Administrator menu + * The classes are constructed dynamically when the menu is generated + */ +.icon-16-archive { + background-image: url(../images/menu/icon-16-archive.png); +} + +.icon-16-article { + background-image: url(../images/menu/icon-16-article.png); +} + +.icon-16-banners { + background-image: url(../images/menu/icon-16-banner.png); +} + +.icon-16-banners-clients { + background-image: url(../images/menu/icon-16-banner-client.png); +} + +.icon-16-banners-tracks { + background-image: url(../images/menu/icon-16-banner-tracks.png); +} + +.icon-16-banners-cat { + background-image: url(../images/menu/icon-16-banner-categories.png); +} + +.icon-16-category { + background-image: url(../images/menu/icon-16-category.png); +} + +.icon-16-checkin { + background-image: url(../images/menu/icon-16-checkin.png); +} + +.icon-16-clear { + background-image: url(../images/menu/icon-16-clear.png); +} + +.icon-16-component { + background-image: url(../images/menu/icon-16-component.png); +} + +.icon-16-config { + background-image: url(../images/menu/icon-16-config.png); +} + +.icon-16-contact { + background-image: url(../images/menu/icon-16-contacts.png); +} + +.icon-16-contact-cat { + background-image: url(../images/menu/icon-16-contacts-categories.png); +} + +.icon-16-content { + background-image: url(../images/menu/icon-16-content.png); +} + +.icon-16-cpanel { + background-image: url(../images/menu/icon-16-cpanel.png); +} + +.icon-16-default { + background-image: url(../images/menu/icon-16-default.png); +} + +.icon-16-featured { + background-image: url(../images/menu/icon-16-featured.png); +} + +.icon-16-groups { + background-image: url(../images/menu/icon-16-groups.png); +} + +.icon-16-help { + background-image: url(../images/menu/icon-16-help.png); +} + +.icon-16-help-this { + background-image: url(../images/menu/icon-16-help-this.png); +} + +.icon-16-help-forum { + background-image: url(../images/menu/icon-16-help-forum.png); +} + +.icon-16-help-docs { + background-image: url(../images/menu/icon-16-help-docs.png); +} + +.icon-16-help-jed { + background-image: url(../images/menu/icon-16-help-jed.png); +} + +.icon-16-help-jrd { + background-image: url(../images/menu/icon-16-help-jrd.png); +} + +.icon-16-help-community { + background-image: url(../images/menu/icon-16-help-community.png); +} + +.icon-16-help-security { + background-image: url(../images/menu/icon-16-help-security.png); +} + +.icon-16-help-dev { + background-image: url(../images/menu/icon-16-help-dev.png); +} + +.icon-16-help-shop { + background-image: url(../images/menu/icon-16-help-shop.png); +} + +.icon-16-info { + background-image: url(../images/menu/icon-16-info.png); +} + +.icon-16-install { + background-image: url(../images/menu/icon-16-install.png); +} + +.icon-16-joomlaupdate { + background-image: url(../images/menu/icon-16-install.png); +} + +.icon-16-language { + background-image: url(../images/menu/icon-16-language.png); +} + +.icon-16-levels { + background-image: url(../images/menu/icon-16-levels.png); +} + +.icon-16-logout { + background-image: url(../images/menu/icon-16-logout.png); +} + +.icon-16-maintenance { + background-image: url(../images/menu/icon-16-maintenance.png); +} + +.icon-16-massmail { + background-image: url(../images/menu/icon-16-massmail.png); +} + +.icon-16-media { + background-image: url(../images/menu/icon-16-media.png); +} + +.icon-16-menu { + background-image: url(../images/menu/icon-16-menu.png); +} + +.icon-16-menumgr { + background-image: url(../images/menu/icon-16-menumgr.png); +} + +.icon-16-messages { + background-image: url(../images/menu/icon-16-messaging.png); +} + +.icon-16-messages-add { + background-image: url(../images/menu/icon-16-new-privatemessage.png); +} + +.icon-16-messages-read { + background-image: url(../images/menu/icon-16-messages.png); +} + +.icon-16-module { + background-image: url(../images/menu/icon-16-module.png); +} + +/* .icon-16-new { background-image: url(../images/menu/icon-16-new.png); } */ +.icon-16-newarticle { + background-image: url(../images/menu/icon-16-newarticle.png); +} + +.icon-16-newcategory { + background-image: url(../images/menu/icon-16-newcategory.png); +} + +.icon-16-newgroup { + background-image: url(../images/menu/icon-16-newgroup.png); +} + +.icon-16-newlevel { + background-image: url(../images/menu/icon-16-newlevel.png); +} + +.icon-16-newuser { + background-image: url(../images/menu/icon-16-newuser.png); +} + +.icon-16-plugin { + background-image: url(../images/menu/icon-16-plugin.png); +} + +.icon-16-profile { + background-image: url(../images/menu/icon-16-user.png); +} + +.icon-16-purge { + background-image: url(../images/menu/icon-16-purge.png); +} + +.icon-16-readmess { + background-image: url(../images/menu/icon-16-readmess.png); +} + +.icon-16-section { + background-image: url(../images/menu/icon-16-section.png); +} + +.icon-16-static { + background-image: url(../images/menu/icon-16-static.png); +} + +.icon-16-stats { + background-image: url(../images/menu/icon-16-stats.png); +} + +.icon-16-themes { + background-image: url(../images/menu/icon-16-themes.png); +} + +.icon-16-trash { + background-image: url(../images/menu/icon-16-trash.png); +} + +.icon-16-user { + background-image: url(../images/menu/icon-16-user.png); +} + +.icon-16-user-note { + background-image: url(../images/menu/icon-16-user-note.png); +} + +.icon-16-delete { + background-image: url(../images/menu/icon-16-delete.png); +} + +.icon-16-help-trans { + background-image: url(../images/menu/icon-16-help-trans.png); +} + +.icon-16-newsfeeds { + background-image: url(../images/menu/icon-16-newsfeeds.png); +} + +.icon-16-newsfeeds-cat { + background-image: url(../images/menu/icon-16-newsfeeds-cat.png); +} + +.icon-16-redirect { + background-image: url(../images/menu/icon-16-redirect.png); +} + +.icon-16-search { + background-image: url(../images/menu/icon-16-search.png); +} + +.icon-16-finder { + background-image: url(../images/menu/icon-16-search.png); +} + +.icon-16-weblinks { + background-image: url(../images/menu/icon-16-links.png); +} + +.icon-16-weblinks-cat { + background-image: url(../images/menu/icon-16-links-cat.png); +} + +/** + * Toolbar icons + * These icons are used for the toolbar buttons + * The classes are constructed dynamically when the toolbar is created + */ +.icon-32-send { + background-image: url(../images/toolbar/icon-32-send.png); +} + +.icon-32-delete { + background-image: url(../images/toolbar/icon-32-delete.png); +} + +.icon-32-help { + background-image: url(../images/toolbar/icon-32-help.png); +} + +.icon-32-cancel { + background-image: url(../images/toolbar/icon-32-cancel.png); +} + +.icon-32-checkin { + background-image: url(../images/toolbar/icon-32-checkin.png); +} + +.icon-32-options{ + background-image: url(../images/toolbar/icon-32-config.png); +} + +.icon-32-apply { + background-image: url(../images/toolbar/icon-32-apply.png); +} + +.icon-32-back { + background-image: url(../images/toolbar/icon-32-back.png); +} + +.icon-32-forward { + background-image: url(../images/toolbar/icon-32-forward.png); +} + +.icon-32-save { + background-image: url(../images/toolbar/icon-32-save.png); +} + +.icon-32-edit { + background-image: url(../images/toolbar/icon-32-edit.png); +} + +.icon-32-copy { + background-image: url(../images/toolbar/icon-32-copy.png); +} + +.icon-32-move { + background-image: url(../images/toolbar/icon-32-move.png); +} + +.icon-32-new { + background-image: url(../images/toolbar/icon-32-new.png); +} + +.icon-32-upload { + background-image: url(../images/toolbar/icon-32-upload.png); +} + +.icon-32-assign { + background-image: url(../images/toolbar/icon-32-publish.png); +} + +.icon-32-html { + background-image: url(../images/toolbar/icon-32-html.png); +} + +.icon-32-css { + background-image: url(../images/toolbar/icon-32-css.png); +} + +.icon-32-menus { + background-image: url(../images/toolbar/icon-32-menu.png); +} + +.icon-32-publish { + background-image: url(../images/toolbar/icon-32-publish.png); +} + +.icon-32-unblock { + background-image: url(../images/toolbar/icon-32-unblock.png); +} + +.icon-32-unpublish { + background-image: url(../images/toolbar/icon-32-unpublish.png); +} + +.icon-32-restore { + background-image: url(../images/toolbar/icon-32-revert.png); +} + +.icon-32-trash { + background-image: url(../images/toolbar/icon-32-trash.png); +} + +.icon-32-archive { + background-image: url(../images/toolbar/icon-32-archive.png); +} + +.icon-32-unarchive { + background-image: url(../images/toolbar/icon-32-unarchive.png); +} + +.icon-32-preview { + background-image: url(../images/toolbar/icon-32-preview.png); +} + +.icon-32-default { + background-image: url(../images/toolbar/icon-32-default.png); +} + +.icon-32-refresh { + background-image: url(../images/toolbar/icon-32-refresh.png); +} + +.icon-32-save-new { + background-image: url(../images/toolbar/icon-32-save-new.png); +} + +.icon-32-save-copy { + background-image: url(../images/toolbar/icon-32-save-copy.png); +} + +.icon-32-error { + background-image: url(../images/toolbar/icon-32-error.png); +} + +.icon-32-new-style { + background-image: url(../images/toolbar/icon-32-new-style.png); +} + +.icon-32-delete-style { + background-image: url(../images/toolbar/icon-32-delete-style.png); +} + +.icon-32-purge { + background-image: url(../images/toolbar/icon-32-purge.png); +} + +.icon-32-remove { + background-image: url(../images/toolbar/icon-32-remove.png); +} + +.icon-32-featured { + background-image: url(../images/toolbar/icon-32-featured.png); +} + +.icon-32-unfeatured { + background-image: url(../images/toolbar/icon-32-featured.png); + background-position: 0% 100%; +} + +.icon-32-export { + background-image: url(../images/toolbar/icon-32-export.png); +} + +.icon-32-stats { + background-image: url(../images/toolbar/icon-32-stats.png); +} + +.icon-32-print { + background-image: url(../images/toolbar/icon-32-print.png); +} + +.icon-32-batch { + background-image: url(../images/toolbar/icon-32-batch.png); +} + +.icon-32-envelope { + background-image: url(../images/toolbar/icon-32-messaging.png); +} +.icon-32-download { + background-image: url(../images/toolbar/icon-32-export.png); +} + +.icon-32-bars { + background-image: url(../images/toolbar/icon-32-stats.png); +} + +/** + * Quick Icons + * Also knows as Header Icons + * These are used for the Quick Icons on the Control Panel + * The same classes are also assigned the Component Title + */ +.icon-48-categories { + background-image: url(../images/header/icon-48-category.png); +} + +.icon-48-category-edit { + background-image: url(../images/header/icon-48-category.png); +} + +.icon-48-category-add { + background-image: url(../images/header/icon-48-category-add.png); +} + +.icon-48-generic { + background-image: url(../images/header/icon-48-generic.png); +} + +.icon-48-banners { + background-image: url(../images/header/icon-48-banner.png); +} + +.icon-48-banners-categories { + background-image: url(../images/header/icon-48-banner-categories.png); +} + +.icon-48-banners-category-edit { + background-image: url(../images/header/icon-48-banner-categories.png); +} + +.icon-48-banners-category-add { + background-image: url(../images/header/icon-48-category-add.png); +} + +.icon-48-banners-clients { + background-image: url(../images/header/icon-48-banner-client.png); +} + +.icon-48-banners-tracks { + background-image: url(../images/header/icon-48-banner-tracks.png); +} + +.icon-48-checkin { + background-image: url(../images/header/icon-48-checkin.png); +} + +.icon-48-clear { + background-image: url(../images/header/icon-48-clear.png); +} + +.icon-48-contact { + background-image: url(../images/header/icon-48-contacts.png); +} + +.icon-48-contact-categories { + background-image: url(../images/header/icon-48-contacts-categories.png); +} + +.icon-48-contact-category-edit { + background-image: url(../images/header/icon-48-contacts-categories.png); +} + +.icon-48-contact-category-add { + background-image: url(../images/header/icon-48-category-add.png); +} + +.icon-48-purge { + background-image: url(../images/header/icon-48-purge.png); +} + +.icon-48-cpanel { + background-image: url(../images/header/icon-48-cpanel.png); +} + +.icon-48-config { + background-image: url(../images/header/icon-48-config.png); +} + +.icon-48-groups { + background-image: url(../images/header/icon-48-groups.png); +} + +.icon-48-groups-add { + background-image: url(../images/header/icon-48-groups-add.png); +} + +.icon-48-levels { + background-image: url(../images/header/icon-48-levels.png); +} + +.icon-48-levels-add { + background-image: url(../images/header/icon-48-levels-add.png); +} + +.icon-48-module { + background-image: url(../images/header/icon-48-module.png); +} + +.icon-48-menu { + background-image: url(../images/header/icon-48-menu.png); +} + +.icon-48-menu-add { + background-image: url(../images/header/icon-48-menu-add.png); +} + +.icon-48-menumgr { + background-image: url(../images/header/icon-48-menumgr.png); +} + +.icon-48-trash { + background-image: url(../images/header/icon-48-trash.png); +} + +.icon-48-user { + background-image: url(../images/header/icon-48-user.png); +} + +.icon-48-user-add { + background-image: url(../images/header/icon-48-user-add.png); +} + +.icon-48-user-edit { + background-image: url(../images/header/icon-48-user-edit.png); +} + +.icon-48-user-profile { + background-image: url(../images/header/icon-48-user-profile.png); +} + +.icon-48-inbox { + background-image: url(../images/header/icon-48-inbox.png); +} + +.icon-48-new-privatemessage { + background-image: url(../images/header/icon-48-new-privatemessage.png); +} + +.icon-48-msgconfig { + background-image: url(../images/header/icon-48-message_config.png); +} + +.icon-48-langmanager { + background-image: url(../images/header/icon-48-language.png); +} + +.icon-48-mediamanager { + background-image: url(../images/header/icon-48-media.png); +} + +.icon-48-plugin { + background-image: url(../images/header/icon-48-plugin.png); +} + +.icon-48-help_header { + background-image: url(../images/header/icon-48-help_header.png); +} + +.icon-48-impressions { + background-image: url(../images/header/icon-48-stats.png); +} + +.icon-48-browser { + background-image: url(../images/header/icon-48-stats.png); +} + +.icon-48-searchtext { + background-image: url(../images/header/icon-48-stats.png); +} + +.icon-48-thememanager { + background-image: url(../images/header/icon-48-themes.png); +} + +.icon-48-assoc { + background-image: url(../images/header/icon-48-assoc.png); +} + +.icon-48-writemess { + background-image: url(../images/header/icon-48-writemess.png); +} + +.icon-48-featured { + background-image: url(../images/header/icon-48-featured.png); +} + +.icon-48-sections { + background-image: url(../images/header/icon-48-section.png); +} + +.icon-48-article-add { + background-image: url(../images/header/icon-48-article-add.png); +} + +.icon-48-article-edit { + background-image: url(../images/header/icon-48-article-edit.png); +} + +.icon-48-article { + background-image: url(../images/header/icon-48-article.png); +} + +.icon-48-content-categories { + background-image: url(../images/header/icon-48-category.png); +} + +.icon-48-content-category-edit { + background-image: url(../images/header/icon-48-category.png); +} + +.icon-48-content-category-add { + background-image: url(../images/header/icon-48-category-add.png); +} + +.icon-48-install { + background-image: url(../images/header/icon-48-extension.png); +} + +.icon-48-dbbackup { + background-image: url(../images/header/icon-48-backup.png); +} + +.icon-48-dbrestore { + background-image: url(../images/header/icon-48-dbrestore.png); +} + +.icon-48-dbquery { + background-image: url(../images/header/icon-48-query.png); +} + +.icon-48-systeminfo { + background-image: url(../images/header/icon-48-info.png); +} + +.icon-48-massmail { + background-image: url(../images/header/icon-48-massmail.png); +} + +.icon-48-redirect { + background-image: url(../images/header/icon-48-redirect.png); +} + +.icon-48-search { + background-image: url(../images/header/icon-48-search.png); +} + +.icon-48-finder { + background-image: url(../images/header/icon-48-search.png); +} + +.icon-48-newsfeeds { + background-image: url(../images/header/icon-48-newsfeeds.png); +} + +.icon-48-newsfeeds-categories { + background-image: url(../images/header/icon-48-newsfeeds-cat.png); +} + +.icon-48-newsfeeds-category-edit { + background-image: url(../images/header/icon-48-newsfeeds-cat.png); +} + +.icon-48-newsfeeds-category-add { + background-image: url(../images/header/icon-48-category-add.png); +} + +.icon-48-weblinks { + background-image: url(../images/header/icon-48-links.png); +} + +.icon-48-weblinks-categories { + background-image: url(../images/header/icon-48-links-cat.png); +} + +.icon-48-weblinks-category-edit { + background-image: url(../images/header/icon-48-links-cat.png); +} + +.icon-48-weblinks-category-add { + background-image: url(../images/header/icon-48-category-add.png); +} + +.icon-48-tags { + background-image: url(../images/header/icon-48-tags.png); +} + +/** + * General styles + */ +div.message { + border: 1px solid #1b3f7c; + color: #333; +} + +.helpFrame { + border-left: 0 solid #1b3f7c; + border-right: none; + border-top: none; + border-bottom: none; +} + +/** + * Override mootree.css styles + * media/system/css/mootree.css + */ +.mooTree_selected { + background-color: #10254a; +} + +/** + * Modal Styles + */ +dl.menu_type dt { + border-bottom: 1px solid #1b3f7c; +} + +ul#new-modules-list { + border-top: 1px solid #1b3f7c; +} + +/** + * Override mediamanager.css styles + * administrator/components/com_media/assets/mediamanager.css + */ +#folderview input#folderpath { + width: 65%; + color: #fcff20; + background-color: #163365; + border: 1px solid #1b3f7c; +} + +.upload-queue .queue-loader { + background-color: #fcff20; + color: #163365; + border: 1px inset #fcff20; +} + +.upload-queue .queue-subloader { + background-color: #1b3f7c; + color: #fcff20; +} + +/** + * User Accessibility + */ + + /* Skip to Content Visual Styling */ +#skiplinkholder a, #skiplinkholder a:link, #skiplinkholder a:visited { + color: #163365; + background: #fcff20; +} + +/** + * Admin Form Styles + */ +fieldset.panelform { + border: none 0; +} + +/** + * ACL STYLES relocated from com_users/media/grid.css + */ +a.move_up { + background-image: url('../images/admin/uparrow.png'); +} + +span.move_up { + background-image: url('../images/admin/uparrow0.png'); +} + +a.move_down { + background-image: url('../images/admin/downarrow.png'); +} + +span.move_down { + background-image: url('../images/admin/downarrow0.png'); +} + +a.grid_false { + background-image: url('../images/admin/publish_x.png'); +} + +a.grid_true { + background-image: url('../images/admin/tick.png'); +} + +a.grid_trash { + background-image: url('../images/admin/icon-16-trash.png'); +} + +/** + * ACL PANEL STYLES + */ + +/* All Tabs */ + +tr.row1 { + background-color: #1c4181; +} + +/* Summary Tab */ +table.aclsummary-table td.col2, +table.aclsummary-table th.col2, +table.aclsummary-table td.col3, +table.aclsummary-table th.col3, +table.aclsummary-table td.col4, +table.aclsummary-table th.col4, +table.aclsummary-table td.col5, +table.aclsummary-table th.col5, +table.aclsummary-table td.col6, +table.aclsummary-table th.col6, +table.aclmodify-table td.col2, +table.aclmodify-table th.col2 { + border-left: 1px solid #cbcbcb; +} + +/* Icons */ + +span.icon-16-unset { + background: url(../images/admin/icon-16-denyinactive.png) no-repeat; +} + +span.icon-16-allowed { + background: url(../images/admin/icon-16-allow.png) no-repeat; +} + +span.icon-16-denied { + background: url(../images/admin/icon-16-deny.png) no-repeat; +} + +span.icon-16-locked { + background: url(../images/admin/checked_out.png) 0 0 no-repeat; +} + +label.icon-16-allow { + background: url(../images/admin/icon-16-allow.png) no-repeat; +} + +label.icon-16-deny { + background: url(../images/admin/icon-16-deny.png) no-repeat; +} +a.icon-16-allow { + background: url(../images/admin/icon-16-allow.png) no-repeat ; +} +a.icon-16-deny { + background: url(../images/admin/icon-16-deny.png) no-repeat ; +} +a.icon-16-allowinactive { + background: url(../images/admin/icon-16-allowinactive.png) no-repeat ; +} +a.icon-16-denyinactive { + background: url(../images/admin/icon-16-denyinactive.png) no-repeat ; +} + +/* ACL footer/legend */ + +ul.acllegend li.acl-allowed { + background: url(../images/admin/icon-16-allow.png) no-repeat left; +} + +ul.acllegend li.acl-denied { + background: url(../images/admin/icon-16-deny.png) no-repeat left; +} + +li.acl-editgroups, +li.acl-resetbtn { + background-color: #1b3f7c; + border: 1px solid #10254a; +} + +li.acl-editgroups a, +li.acl-resetbtn a { + color: #fcff20 +} + +li.acl-editgroups:hover, +li.acl-resetbtn:hover, +li.acl-editgroups:focus, +li.acl-resetbtn:focus { + background-color: #163365; + border-top: 1px solid #000000; + border-right: 1px solid #1b3f7c; + border-bottom: 1px solid #1b3f7c; + border-left: 1px solid #000000; + color: #fcff20; +} + +/* ACL Config --------- */ +table#acl-config { + border: 1px solid #10254a; + background: #1c4181; +} + +table#acl-config th, +table#acl-config td { + background: #1c4181; + border-bottom: 1px solid #10254a; + border-top: none; + border-left: none; + border-right: none; +} + +table#acl-config th.acl-groups { + border-right: 1px solid #10254a; +} + +/** +* Mod_rewrite Warning +*/ +#jform_sef_rewrite-lbl { + background: url(../images/admin/icon-16-notice-note.png) right top no-repeat; +} + +/** +* Options modal- config +*/ + +/* * +* Permission Rules +*/ + +#permissions-sliders ul#rules, +#permissions-sliders ul#rules ul { + border:solid 0 #1b3f7c; + background:#163365; +} + +ul#rules li .pane-sliders .panel h3.title { + border:solid 0 #1b3f7c; +} + +#permissions-sliders ul#rules .pane-slider { + border:solid 1px #1b3f7c; +} + +#permissions-sliders ul#rules li h3 { + background:#1c4181; + border: 1px solid #1b3f7c; +} + +#permissions-sliders ul#rules li h3.pane-toggler-down a { + border:solid 0; +} + +#permissions-sliders ul#rules .group-kind { + color:#fcff20; +} + +#permissions-sliders ul#rules table.group-rules td { + border-right:solid 1px #1b3f7c; + border-bottom:solid 1px #1b3f7c; +} + +#permissions-sliders ul#rules table.group-rules th { + background: #10254a; + border-right:solid 1px #1b3f7c; + border-bottom:solid 1px #1b3f7c; + color:#fcff20; +} + +ul#rules table.aclmodify-table { + border:solid 1px #fcff20; +} + +ul#rules table.group-rules td label { + border:solid 0 #1b3f7c; +} + +#permissions-sliders ul#rules .mypanel { + border:solid 0 #1b3f7c; +} + +#permissions-sliders ul#rules table.group-rules td { + background: #163365; +} + +#permissions-sliders span.level { + color:#ffffff; + background-image:none; +} + +/* + * Debug styles + */ +.check-0, +table.adminlist tbody td.check-0, +table.adminlist tbody tr:hover td.check-0 { + background-color: #FFFFCF; + color: #163365; +} + +.check-a, +table.adminlist tbody td.check-a, +table.adminlist tbody tr:hover td.check-a { + background-color: #CFFFDA; + color: #163365; +} + +.check-d, +table.adminlist tbody td.check-d, +table.adminlist tbody tr:hover td.check-d { + background-color: #FFCFCF; + color: #163365; +} + +/** + * System Messages + */ + +#system-message dd ul { + color: #fcff20; + border-top: 3px solid #84A7DB; + border-bottom: 3px solid #84A7DB; +} + +#system-message dd.error ul { + color: #fcff20; + background: #1c4181 url(../images/notice-alert.png) 4px top no-repeat; + border-top: 3px solid #a20000; + border-bottom: 3px solid #a20000; +} + +#system-message dd.message ul { + color: #fcff20; + background: #10254a url(../images/notice-info.png) 4px center no-repeat; + border-top: 3px solid #EFE7B8; + border-bottom: 3px solid #EFE7B8; +} + +#system-message dd.notice ul { + color: #fcff20; + background: #10254a url(../images/notice-note.png) 4px top no-repeat; + border-top: 3px solid #F0DC7E; + border-bottom: 3px solid #F0DC7E; +} + +/** CSS file for Accessible Admin Menu + * based on Matt Carrolls' son of suckerfish + * with javascript by Bill Tomczak + */ + + /* Note: set up the font-size on the id and used 100% on the elements. + If ul/li/a are different ems, then the shifting back via non-js keyboard + doesn't work properly */ + +/** + * Menu Styling + */ +#menu { /* this is on the main ul */ + color: #ffffff; +} + +#menu ul { /* all lists */ + background-color: #163365; + color: #ffffff; +} + +#menu ul li.node { + background: #163365 url(../images/j_arrow.png) no-repeat right 50%; +} + +#menu a { + color: #ffffff; + background-repeat: no-repeat; + background-position: left 50%; + background-color: #1b3f7c; +} + +#menu li { /* all list items */ + background-color: #163365; + border-right: 1px solid #000000; +} + +#menu li a { + border: 1px solid #10254a; +} + +#menu li li a { + border: 1px solid #10254a; +} + +#menu li a:hover, +#menu li a:active, +#menu li a:focus { + background-color: #163365; + border-top: 1px solid #000000; + border-right: 1px solid #1b3f7c; + border-bottom: 1px solid #1b3f7c; + border-left: 1px solid #000000; + color: #ffffff; +} + +#menu li.disabled a:hover, +#menu li.disabled a:focus, +#menu li.disabled a { + color: #feffbf; + background-color: #1b3f7c; + border-top: 1px solid #163365; + border-right: 1px solid #10254a; + border-bottom: 1px solid #163365; + border-left: 1px solid #10254a; +} + +#menu li ul { /* second-level lists */ + border-top: 1px solid #10254a; + border-bottom: 2px solid #10254a; +} + +#menu li li { /* second-level row */ + background-color: #163365; +} + +#menu li:hover ul,#menu li.sfhover ul { + /* lists nested under hovered list items */ + margin-left: 0; + border-left: 1px solid #122b56; + border-right: 1px solid #122b56; +} + +#menu li li:hover ul,#menu li li.sfhover ul { + border-left: 1px solid #122b56; + border-right: 1px solid #122b56; +} + +/** + * Styling parents + */ + + /* 1 level - sfhover */ +#menu li.sfhover a { + background-color: #163365; + border-top: 1px solid #000000; + border-right: 1px solid #1b3f7c; + border-bottom: 1px solid #1b3f7c; + border-left: 1px solid #000000; + color: #fcff20; +} + + /* 2 level - normal */ +#menu li.sfhover li a { /* background-color: #f0f0f0; */ + background-color: #1b3f7c; + border: 1px solid #10254a; + color: #ffffff; +} + + /* 2 level - hover */ +#menu li.sfhover li.sfhover a,#menu li li a:focus { + background-color: #163365; + border-top: 1px solid #000000; + border-right: 1px solid #1b3f7c; + border-bottom: 1px solid #1b3f7c; + border-left: 1px solid #000000; + color: #fcff20; +} + + /* 3 level - normal */ +#menu li.sfhover li.sfhover li a { + background-color: #1b3f7c; + border: 1px solid #10254a; + color: #ffffff; +} + + /* 3 level - hover */ +#menu li.sfhover li.sfhover li.sfhover a { + background-color: #163365; + border-top: 1px solid #000000; + border-right: 1px solid #1b3f7c; + border-bottom: 1px solid #1b3f7c; + border-left: 1px solid #000000; + color: #fcff20; +} + +/* bring back the focus elements into view */ +#menu li li a:focus, #menu li li li a:focus { + background-color: #163365; + border-top: 1px solid #000000; + border-right: 1px solid #1b3f7c; + border-bottom: 1px solid #1b3f7c; + border-left: 1px solid #000000; + color: #ffffff; +} + +#menu li li li a:focus { + background-color: #163365; + border-top: 1px solid #000000; + border-right: 1px solid #1b3f7c; + border-bottom: 1px solid #1b3f7c; + border-left: 1px solid #000000; + color: #ffffff; +} + +/** + * Submenu styling + */ +#submenu { + border-bottom: 1px solid #10254a; + /* border-bottom plus padding-bottom is the technique */ + /* This is the background befind the tabs */ + background: #1c4181; +} + +#submenu a, #submenu span.nolink { + background: #1b3f7c; + border: 1px solid #10254a; + color: #ffffff; +} + +#submenu a:hover, #submenu a:focus { + background-color: #10254a; +} + +#submenu a.active, #submenu span.nolink.active { + background: #163365; + border-bottom: 1px solid #163365; + color: #fcff20; +} + +/** + * Webkit fixes + **/ +input:-webkit-autofill { + background-color: #163365 !important; +} + +/* -- Codemirror Editor ----------- */ +div.editor-border, div.CodeMirror-wrapping { + border: 1px solid #163365; + background-color: #ffffff; +} + +/* User Notes */ +div.unotes h1 { + background-color: #ffffff; +} +ul.alternating > li:nth-child(odd) { background-color: #163365; } +ul.alternating > li:nth-child(even) { background-color: #10254a; } +ol.alternating > li:nth-child(odd) { background-color: #163365; } +ol.alternating > li:nth-child(even) { background-color: #10254a;} + +/* Installer Database */ +#installer-database, #installer-discover, #installer-update, #installer-warnings { + border-top: 1px solid #1b3f7c; +} +#installer-database p.warning { + background: transparent url(../images/admin/icon-16-deny.png) center left no-repeat; +} + +#installer-database p.nowarning { + background: transparent url(../images/admin/icon-16-allow.png) center left no-repeat; +} diff --git a/Sites/pages/administrator/templates/hathor/css/colour_highcontrast_rtl.css b/Sites/pages/administrator/templates/hathor/css/colour_highcontrast_rtl.css new file mode 100644 index 00000000..fa01d0ba --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/css/colour_highcontrast_rtl.css @@ -0,0 +1,422 @@ +@charset "UTF-8"; + +/** + * @package Joomla.Administrator + * @subpackage templates.hathor + * @copyright Copyright (C) 2005 - 2020 Open Source Matters, Inc. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + * @since 1.6 + * + * RTL CSS file for the color standard + */ + +/** + * Overall Styles + */ +#header { + background: #ffffff url(../images/j_logo.png) no-repeat top right; +} + +#element-box { + border-left: 1px solid #1b3f7c; + border-right: 1px solid #1b3f7c; +} + +/** + * Various Styles + */ + +div.checkin-tick { + background: url(../images/admin/tick.png) 20px 50% no-repeat; +} + +/** + * Subheader, toolbar, page title + */ + +div.toolbar-box { + border-left: 1px solid #10254a; + border-right: 1px solid #10254a; +} + +div.toolbar-list li.divider { + border-left:1px dotted #1b3f7c; + border-right:none; +} + +div.toolbar-list a:hover { + border-right: 1px solid #000000; + border-left: 1px solid #1b3f7c; +} + +/** + * Pane Slider pane Toggler styles + */ +.pane-toggler span { + background: transparent url(../images/j_arrow_left.png) right 50% no-repeat; +} + +.pane-toggler-down span { + background: transparent url(../images/j_arrow_down.png) right 50% no-repeat; +} + +/** + * Cpanel Settings + */ + +#cpanel div.icon a:hover, +#cpanel div.icon a:focus { + border-right: 1px solid #000000; + border-left: 1px solid #1b3f7c; +} + + +fieldset#filter-bar { + border-left: none; + border-right: none; +} + +/** + * Admintable Styles + */ + +table.admintable td.key,table.admintable td.paramlist_key { + border-left: 1px solid #10254a; + border-right: none; +} + +table.paramlist td.paramlist_description { + border-left: 1px solid #10254a; + border-right: none; +} + +/** + * Admin Form Styles + */ +table.adminform tr { + border-left: 1px solid #1b3f7c; + border-right: none; +} + +/** + * Adminlist Table layout + */ + +table.adminlist.modal { + border-right: 1px solid #1b3f7c; + border-left: 1px solid #1b3f7c; +} + + + /* Table row styles */ + +table.adminlist tbody tr td, +table.adminlist tbody tr th { + border-left: 1px solid #1b3f7c; + border-right: none; +} + +table.adminlist tbody tr td:last-child { + border-left: none; +} + +/** + * Saving order icon styling in admin tables + */ +a.saveorder { + background: url(../images/admin/filesave.png) no-repeat; +} + +a.saveorder.inactive { + background-position: 0 -16px; +} + +/** + * Button styling + */ + +/* Button 1 Type */ + + /* Use this if you add images to the buttons such as directional arrows */ + +.button1 a { + /* add padding if you are using the directional images */ + /* padding: 0 6px 0 30px; */ +} + + /* Button 2 Type */ + +.button2-right .prev { + background-image: url(../images/j_button2_prev.png); + background-position: right center; +} + +.button2-right.off .prev { + background: url(../images/j_button2_prev_off.png) no-repeat; +} + +.button2-right .start { + background-image: url(../images/j_button2_first.png); + background-position: right center; +} + +.button2-left .next { + background-image: url(../images/j_button2_next.png); + background-position: left center; +} + +.button2-left.off .next { /* @TODO check the x position */ + background: url(../images/j_button2_next_off.png) 100% 0 no-repeat; +} + +.button2-left .end { + background-image: url(../images/j_arrow_left.png); + background-position: left center; +} + +.button2-left.off .end { /* @TODO check the x position */ + background: url(../images/j_button2_last_off.png) 100% 0 no-repeat; +} + +.button2-left .image { + background: url(../images/j_button2_image.png) 100% 0 no-repeat; +} + +.button2-left .readmore { + background: url(../images/j_button2_readmore.png) 100% 0 no-repeat; +} + +.button2-left .pagebreak { + background: url(../images/j_button2_pagebreak.png) 100% 0 no-repeat; +} + +/** + * Tooltips + */ + + +/** + * System Standard Messages + */ +#system-message dd.message ul { + background: #10254a url(../images/notice-info.png) 99.5% center no-repeat; +} + +/** + * System Error Messages + */ +#system-message dd.error ul { + background: #1c4181 url(../images/notice-alert.png) 99.5% top no-repeat; +} + +/** + * System Notice Messages + */ +#system-message dd.notice ul { + background: #10254a url(../images/notice-note.png) 99%.5 top no-repeat; +} + +/** + * JGrid styles + */ + +/** + * Menu Icons + * These icons are used on the Administrator menu + * The classes are constructed dynamically when the menu is generated + */ + + +/** + * Toolbar icons + * These icons are used for the toolbar buttons + * The classes are constructed dynamically when the toolbar is created + */ + +/** + * Quick Icons + * Also knows as Header Icons + * These are used for the Quick Icons on the Control Panel + * The same classes are also assigned the Component Title + */ + +/** + * General styles + */ + +.helpFrame { + border-right: 0 solid #1b3f7c; + border-left: none; + border-top: none; +} + +/* -- ACL STYLES relocated from com_users/media/grid.css ----------- */ + +/* -- ACL PANEL STYLES ----------- */ + + +/* All Tabs */ + +table.aclsummary-table td.col2, +table.aclsummary-table th.col2, +table.aclsummary-table td.col3, +table.aclsummary-table th.col3, +table.aclsummary-table td.col4, +table.aclsummary-table th.col4, +table.aclsummary-table td.col5, +table.aclsummary-table th.col5, +table.aclmodify-table td.col2, +table.aclmodify-table th.col2 { + border-right: 1px solid #cbcbcb; + border-left: none; +} + +/* Icons */ + +ul.acllegend li.acl-allowed { + background:url(../images/admin/icon-16-allow.png) no-repeat right; +} +ul.acllegend li.acl-denied { + background:url(../images/admin/icon-16-deny.png) no-repeat right; +} + +table#acl-config th.acl-groups { + border-left: 1px solid #c7c8b2; +} + +table#acl-config th.acl-groups { + text-align: right; +} + +.acl-action { + margin: auto 0; +} + +/* Icons */ + +span.icon-16-unset { + background: url(../images/admin/icon-16-denyinactive.png) no-repeat right; +} + +span.icon-16-allowed { + background: url(../images/admin/icon-16-allow.png) no-repeat right; +} + +span.icon-16-denied { + background: url(../images/admin/icon-16-deny.png) no-repeat right; +} + +span.icon-16-locked { + background: url(../images/admin/checked_out.png) no-repeat right; +} + +/** +* Mod_rewrite Warning +*/ +#jform_sef_rewrite-lbl { + background: url(../images/admin/icon-16-notice-note.png) left top no-repeat; +} + +/** +* Modal S-Box overrides +*/ + +#sbox-window { + text-align:right; +} + +/* * +* Permission Rules +*/ + +#permissions-sliders ul#rules table.group-rules td { + border-left:solid 1px #1b3f7c; + border-right:solid 0 #1b3f7c; +} + +#permissions-sliders ul#rules table.group-rules th { + border-left:solid 1px #1b3f7c; + border-right:solid 0 #1b3f7c; +} + +/** + * Menu Styling + */ + +#menu ul li.node { + background-image: url(../images/j_arrow_left.png); + background-repeat: no-repeat; + background-position: left 50%; +} + +#menu a { + background-position: right 50%; +} + +#menu li { + border-left: 1px solid #000000; +} + +#menu li a:hover, #menu li a:active, #menu li a:focus { + border-left: 1px solid #1b3f7c; + border-right: 1px solid #000000; +} + +#menu li.disabled a:hover,#menu li.disabled a:focus,#menu li.disabled a + { + border-right: 1px solid #10254a; + border-left: 1px solid #10254a; +} + +#menu li:hover ul,#menu li.sfhover ul { + /* lists nested under hovered list items */ + border-right: 1px solid #122b56; + border-left: 1px solid #122b56; +} + +#menu li li:hover ul,#menu li li.sfhover ul { + border-right: 1px solid #122b56; + border-left: 1px solid #122b56; +} + +/** + * Styling parents + */ + + /* 1 level - sfhover */ +#menu li.sfhover a { + border-left: 1px solid #1b3f7c; + border-right: 1px solid #000000; +} + + /* 2 level - hover */ +#menu li.sfhover li.sfhover a,#menu li li a:focus { + border-left: 1px solid #1b3f7c; + border-right: 1px solid #000000; +} + + /* 3 level - hover */ +#menu li.sfhover li.sfhover li.sfhover a,#menu li li li a:focus { + border-left: 1px solid #1b3f7c; + border-right: 1px solid #000000; +} + +/* bring back the focus elements into view */ +#menu li li a:focus { + border-left: 1px solid #1b3f7c; + border-right: 1px solid #000000; +} + +#menu li li li a:focus { + border-left: 1px solid #1b3f7c; + border-right: 1px solid #000000; +} + +/* Installer Database */ +#installer-database p.warning { + background-position: center right; +} + +#installer-database p.nowarning { + background-position: center right; +} diff --git a/Sites/pages/administrator/templates/hathor/css/colour_standard.css b/Sites/pages/administrator/templates/hathor/css/colour_standard.css new file mode 100644 index 00000000..f011a28c --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/css/colour_standard.css @@ -0,0 +1,1802 @@ +.clearfix { + *zoom: 1; +} +.clearfix:before, +.clearfix:after { + display: table; + content: ""; + line-height: 0; +} +.clearfix:after { + clear: both; +} +.hide-text { + font: 0/0 a; + color: transparent; + text-shadow: none; + background-color: transparent; + border: 0; +} +.input-block-level { + display: block; + width: 100%; + min-height: 25px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +#form-login .btn { + display: inline-block; + *display: inline; + *zoom: 1; + padding: 4px 14px; + margin-bottom: 0; + font-size: 13px; + line-height: 15px; + *line-height: 15px; + text-align: center; + vertical-align: middle; + cursor: pointer; + color: #333333; + text-shadow: 0 1px 1px rgba(255,255,255,0.75); + background-color: #f5f5f5; + background-image: -moz-linear-gradient(top,#ffffff,#e6e6e6); + background-image: -webkit-gradient(linear,0 0,0 100%,from(#ffffff),to(#e6e6e6)); + background-image: -webkit-linear-gradient(top,#ffffff,#e6e6e6); + background-image: -o-linear-gradient(top,#ffffff,#e6e6e6); + background-image: linear-gradient(to bottom,#ffffff,#e6e6e6); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe5e5e5', GradientType=0); + border-color: #e6e6e6 #e6e6e6 #bfbfbf; + *background-color: #e6e6e6; + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + border: 1px solid #bbb; + *border: 0; + border-bottom-color: #a2a2a2; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + *margin-left: .3em; + -webkit-box-shadow: inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); + -moz-box-shadow: inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); + box-shadow: inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); +} +#form-login .btn:hover, +#form-login .btn:focus, +#form-login .btn:active, +#form-login .btn.active, +#form-login .btn.disabled, +#form-login .btn[disabled] { + color: #333333; + background-color: #e6e6e6; + *background-color: #d9d9d9; +} +#form-login .btn:active, +#form-login .btn.active { + background-color: #cccccc \9; +} +#form-login .btn:first-child { + *margin-left: 0; +} +#form-login .btn:hover { + color: #333333; + text-decoration: none; + background-color: #e6e6e6; + *background-color: #d9d9d9; + background-position: 0 -15px; + -webkit-transition: background-position .1s linear; + -moz-transition: background-position .1s linear; + -o-transition: background-position .1s linear; + transition: background-position .1s linear; +} +#form-login .btn:focus { + outline: thin dotted #333; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +#form-login .btn.active, +#form-login .btn:active { + background-color: #e6e6e6; + background-color: #d9d9d9 \9; + background-image: none; + outline: 0; + -webkit-box-shadow: inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05); + -moz-box-shadow: inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05); + box-shadow: inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05); +} +#form-login .btn.disabled, +#form-login .btn[disabled] { + cursor: default; + background-color: #e6e6e6; + background-image: none; + opacity: 0.65; + filter: alpha(opacity=65); + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; +} +.btn-large { + padding: 9px 14px; + font-size: 15px; + line-height: normal; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; +} +.btn-large [class^="icon-"] { + margin-top: 2px; +} +.input-append input[class*="span"], +.input-append .uneditable-input[class*="span"], +.input-prepend input[class*="span"], +.input-prepend .uneditable-input[class*="span"], +.row-fluid input[class*="span"], +.row-fluid select[class*="span"], +.row-fluid textarea[class*="span"], +.row-fluid .uneditable-input[class*="span"], +.row-fluid .input-prepend [class*="span"], +.row-fluid .input-append [class*="span"] { + display: inline-block; +} +.input-append, +.input-prepend { + margin-bottom: 5px; + font-size: 0; + white-space: nowrap; +} +.input-append input, +.input-append select, +.input-append .uneditable-input, +.input-prepend input, +.input-prepend select, +.input-prepend .uneditable-input { + position: relative; + margin-bottom: 0; + *margin-left: 0; + font-size: 13px; + vertical-align: top; + -webkit-border-radius: 0 3px 3px 0; + -moz-border-radius: 0 3px 3px 0; + border-radius: 0 3px 3px 0; +} +.input-append input:focus, +.input-append select:focus, +.input-append .uneditable-input:focus, +.input-prepend input:focus, +.input-prepend select:focus, +.input-prepend .uneditable-input:focus { + z-index: 2; +} +.input-append .add-on, +.input-prepend .add-on { + display: inline-block; + width: auto; + height: 15px; + min-width: 16px; + padding: 4px 5px; + font-size: 13px; + font-weight: normal; + line-height: 15px; + text-align: center; + text-shadow: 0 1px 0 #ffffff; + background-color: #eeeeee; + border: 1px solid #ccc; +} +.input-append .add-on, +.input-append .btn, +.input-prepend .add-on, +.input-prepend .btn { + margin-left: -1px; + vertical-align: top; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.input-append .active, +.input-prepend .active { + background-color: #a9dba9; + border-color: #46a546; +} +.input-prepend .add-on, +.input-prepend .btn { + margin-right: -1px; +} +.input-prepend .add-on:first-child, +.input-prepend .btn:first-child { + -webkit-border-radius: 3px 0 0 3px; + -moz-border-radius: 3px 0 0 3px; + border-radius: 3px 0 0 3px; +} +.input-append input, +.input-append select, +.input-append .uneditable-input { + -webkit-border-radius: 3px 0 0 3px; + -moz-border-radius: 3px 0 0 3px; + border-radius: 3px 0 0 3px; +} +.input-append .add-on:last-child, +.input-append .btn:last-child { + -webkit-border-radius: 0 3px 3px 0; + -moz-border-radius: 0 3px 3px 0; + border-radius: 0 3px 3px 0; +} +.input-prepend.input-append input, +.input-prepend.input-append select, +.input-prepend.input-append .uneditable-input { + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.input-prepend.input-append .add-on:first-child, +.input-prepend.input-append .btn:first-child { + margin-right: -1px; + -webkit-border-radius: 3px 0 0 3px; + -moz-border-radius: 3px 0 0 3px; + border-radius: 3px 0 0 3px; +} +.input-prepend.input-append .add-on:last-child, +.input-prepend.input-append .btn:last-child { + margin-left: -1px; + -webkit-border-radius: 0 3px 3px 0; + -moz-border-radius: 0 3px 3px 0; + border-radius: 0 3px 3px 0; +} +.form-search .input-append .search-query, +.form-search .input-prepend .search-query { + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.form-search .input-append .search-query { + -webkit-border-radius: 14px 0 0 14px; + -moz-border-radius: 14px 0 0 14px; + border-radius: 14px 0 0 14px; +} +.form-search .input-append .btn { + -webkit-border-radius: 0 14px 14px 0; + -moz-border-radius: 0 14px 14px 0; + border-radius: 0 14px 14px 0; +} +.form-search .input-prepend .search-query { + -webkit-border-radius: 0 14px 14px 0; + -moz-border-radius: 0 14px 14px 0; + border-radius: 0 14px 14px 0; +} +.form-search .input-prepend .btn { + -webkit-border-radius: 14px 0 0 14px; + -moz-border-radius: 14px 0 0 14px; + border-radius: 14px 0 0 14px; +} +.form-search input, +.form-search textarea, +.form-search select, +.form-search .help-inline, +.form-search .uneditable-input, +.form-search .input-prepend, +.form-search .input-append, +.form-inline input, +.form-inline textarea, +.form-inline select, +.form-inline .help-inline, +.form-inline .uneditable-input, +.form-inline .input-prepend, +.form-inline .input-append, +.form-horizontal input, +.form-horizontal textarea, +.form-horizontal select, +.form-horizontal .help-inline, +.form-horizontal .uneditable-input, +.form-horizontal .input-prepend, +.form-horizontal .input-append { + display: inline-block; + *display: inline; + *zoom: 1; + margin-bottom: 0; + vertical-align: middle; +} +.form-search .hide, +.form-inline .hide, +.form-horizontal .hide { + display: none; +} +.form-search .input-append, +.form-inline .input-append, +.form-search .input-prepend, +.form-inline .input-prepend { + margin-bottom: 0; +} +.element-invisible { + position: absolute; + padding: 0 !important; + margin: 0 !important; + border: 0; + height: 1px; + width: 1px !important; + overflow: hidden; +} +#form-login select, +#form-login input[type="text"], +#form-login input[type="password"] { + display: inline-block; + padding: 4px 6px; + margin-bottom: 9px; + font-size: 13px; + line-height: 15px; + color: #555555; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + width: 175px; +} +.subform-repeatable-wrapper div.btn-toolbar { + float: none; +} +.subform-repeatable-wrapper .text-right { + text-align: right; +} +.subform-repeatable-wrapper .ui-sortable-helper { + background: #ffffff; +} +.subform-repeatable-wrapper tr.ui-sortable-helper { + display: table; +} +.subform-repeatable-wrapper .subform-repeatable-group { + clear: both; +} +.label, +.badge { + display: inline-block; + padding: 2px 4px; + font-size: 10.998px; + font-weight: bold; + line-height: 14px; + color: #ffffff; + vertical-align: baseline; + white-space: nowrap; + text-shadow: 0 -1px 0 rgba(0,0,0,0.25); + background-color: #999999; +} +.label { + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} +.badge { + padding-left: 9px; + padding-right: 9px; + -webkit-border-radius: 9px; + -moz-border-radius: 9px; + border-radius: 9px; +} +.label:empty, +.badge:empty { + display: none; +} +a.label:hover, +a.label:focus, +a.badge:hover, +a.badge:focus { + color: #ffffff; + text-decoration: none; + cursor: pointer; +} +.label-important, +.badge-important { + background-color: #a20000; +} +.label-important[href], +.badge-important[href] { + background-color: #6f0000; +} +.label-warning, +.badge-warning { + background-color: #f89406; +} +.label-warning[href], +.badge-warning[href] { + background-color: #c67605; +} +.label-success, +.badge-success { + background-color: #005800; +} +.label-success[href], +.badge-success[href] { + background-color: #002500; +} +.label-info, +.badge-info { + background-color: #3a87ad; +} +.label-info[href], +.badge-info[href] { + background-color: #2d6987; +} +.label-inverse, +.badge-inverse { + background-color: #333333; +} +.label-inverse[href], +.badge-inverse[href] { + background-color: #1a1a1a; +} +.btn .label, +.btn .badge { + position: relative; + top: -1px; +} +.btn-mini .label, +.btn-mini .badge { + top: 0; +} +body { + background-color: #ffffff; + color: #2c2c2c; +} +h1 { + color: #2c2c2c; +} +a:link { + color: #054993; +} +a:visited { + color: #054993; +} +#header { + background: #ffffff url(../images/j_logo.png) no-repeat; +} +#header h1.title { + color: #2c2c2c; +} +#nav { + background-color: #f9fade; + background-image: -moz-linear-gradient(top,#f9fade,#f9fade); + background-image: -webkit-gradient(linear,0 0,0 100%,from(#f9fade),to(#f9fade)); + background-image: -webkit-linear-gradient(top,#f9fade,#f9fade); + background-image: -o-linear-gradient(top,#f9fade,#f9fade); + background-image: linear-gradient(to bottom,#f9fade,#f9fade); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff9fade', endColorstr='#fff9fade', GradientType=0); + border: 1px solid #c7c8b2; +} +#content { + background: #ffffff; +} +#no-submenu { + border-bottom: 1px solid #c7c8b2; +} +#element-box { + background: #ffffff; + border-right: 1px solid #c7c8b2; + border-bottom: 1px solid #c7c8b2; + border-left: 1px solid #c7c8b2; +} +#element-box.login { + border-top: 1px solid #c7c8b2; +} +.enabled, +.success, +.allow, +span.writable { + color: #005800; +} +.disabled, +p.error, +.warning, +.deny, +span.unwritable { + color: #a20000; +} +.nowarning { + color: #2c2c2c; +} +.none, +.protected { + color: #c7c8b2; +} +span.note { + background: #ffffff; + color: #2c2c2c; +} +div.checkin-tick { + background: url(../images/admin/tick.png) 20px 50% no-repeat; +} +.ol-foreground { + background-color: #f9fade; +} +.ol-background { + background-color: #005800; +} +.ol-textfont { + color: #2c2c2c; +} +.ol-captionfont { + color: #ffffff; +} +.ol-captionfont a { + color: #054993; +} +div.subheader .padding { + background: #ffffff; +} +.pagetitle h2 { + color: #2c2c2c; +} +div.configuration { + color: #2c2c2c; + background-image: url(../images/menu/icon-16-config.png); + background-repeat: no-repeat; +} +div.toolbar-box { + border-right: 1px solid #c7c8b2; + border-bottom: 1px solid #c7c8b2; + border-left: 1px solid #c7c8b2; + background: #ffffff; +} +div.toolbar-list li { + color: #2c2c2c; +} +div.toolbar-list li.divider { + border-right: 1px dotted #e5d9c3; +} +div.toolbar-list a { + border-left: 1px solid #e5d9c3; + border-top: 1px solid #e5d9c3; + border-right: 1px solid #c7c8b2; + border-bottom: 1px solid #c7c8b2; + background: #f9fade; +} +div.toolbar-list a:hover { + border-left: 1px solid #868778; + border-top: 1px solid #868778; + border-right: 1px solid #f6f7db; + border-bottom: 1px solid #f6f7db; + background: #e5d9c3; + color: #054993; +} +div.btn-toolbar { + margin-left: 5px; + padding-top: 3px; +} +div.btn-toolbar li.divider { + border-right: 1px dotted #e5d9c3; +} +div.btn-toolbar div.btn-group button { + border-left: 1px solid #e5d9c3; + border-top: 1px solid #e5d9c3; + border-right: 1px solid #c7c8b2; + border-bottom: 1px solid #c7c8b2; + background-color: #f9fade; + background-image: -moz-linear-gradient(top,#f9fade,#f9fade); + background-image: -webkit-gradient(linear,0 0,0 100%,from(#f9fade),to(#f9fade)); + background-image: -webkit-linear-gradient(top,#f9fade,#f9fade); + background-image: -o-linear-gradient(top,#f9fade,#f9fade); + background-image: linear-gradient(to bottom,#f9fade,#f9fade); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff9fade', endColorstr='#fff9fade', GradientType=0); + padding: 5px 4px 5px 4px; +} +div.btn-toolbar div.btn-group button:hover { + border-left: 1px solid #868778; + border-top: 1px solid #868778; + border-right: 1px solid #f6f7db; + border-bottom: 1px solid #f6f7db; + background: #e5d9c3; + color: #054993; + cursor: pointer; +} +div.btn-toolbar a { + border-left: 1px solid #e5d9c3; + border-top: 1px solid #e5d9c3; + border-right: 1px solid #c7c8b2; + border-bottom: 1px solid #c7c8b2; + background-color: #f9fade; + background-image: -moz-linear-gradient(top,#f9fade,#f9fade); + background-image: -webkit-gradient(linear,0 0,0 100%,from(#f9fade),to(#f9fade)); + background-image: -webkit-linear-gradient(top,#f9fade,#f9fade); + background-image: -o-linear-gradient(top,#f9fade,#f9fade); + background-image: linear-gradient(to bottom,#f9fade,#f9fade); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff9fade', endColorstr='#fff9fade', GradientType=0); + padding: 6px 5px; + text-align: center; + white-space: nowrap; + font-size: 1.2em; + text-decoration: none; +} +div.btn-toolbar a:hover { + border-left: 1px solid #868778; + border-top: 1px solid #868778; + border-right: 1px solid #f6f7db; + border-bottom: 1px solid #f6f7db; + background: #e5d9c3; + color: #054993; + cursor: pointer; +} +div.btn-toolbar div.btn-group button.inactive { + background: #f9fade; +} +.pane-sliders .title { + color: #2c2c2c; +} +.pane-sliders .panel { + border: 1px solid #c7c8b2; +} +.pane-sliders .panel h3 { + background-color: #f9fade; + background-image: -moz-linear-gradient(top,#f9fade,#f9fade); + background-image: -webkit-gradient(linear,0 0,0 100%,from(#f9fade),to(#f9fade)); + background-image: -webkit-linear-gradient(top,#f9fade,#f9fade); + background-image: -o-linear-gradient(top,#f9fade,#f9fade); + background-image: linear-gradient(to bottom,#f9fade,#f9fade); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff9fade', endColorstr='#fff9fade', GradientType=0); + color: #054993; +} +.pane-sliders .panel h3:hover { + background: #e5d9c3; +} +.pane-sliders .panel h3:hover a { + text-decoration: none; +} +.pane-sliders .adminlist { + border: 0 none; +} +.pane-sliders .adminlist td { + border: 0 none; +} +.pane-toggler span { + background: transparent url(../images/j_arrow.png) 5px 50% no-repeat; +} +.pane-toggler-down span { + background: transparent url(../images/j_arrow_down.png) 5px 50% no-repeat; +} +.pane-toggler-down { + border-bottom: 1px solid #c7c8b2; +} +dl.tabs dt { + border: 1px solid #c7c8b2; + background-color: #f9fade; + background-image: -moz-linear-gradient(top,#f9fade,#f9fade); + background-image: -webkit-gradient(linear,0 0,0 100%,from(#f9fade),to(#f9fade)); + background-image: -webkit-linear-gradient(top,#f9fade,#f9fade); + background-image: -o-linear-gradient(top,#f9fade,#f9fade); + background-image: linear-gradient(to bottom,#f9fade,#f9fade); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff9fade', endColorstr='#fff9fade', GradientType=0); + color: #054993; +} +dl.tabs dt:hover { + background: #e5d9c3; +} +dl.tabs dt.open { + background: #ffffff; + border-bottom: 1px solid #ffffff; + color: #2c2c2c; +} +dl.tabs dt.open a:visited { + color: #2c2c2c; +} +dl.tabs dt a:hover { + text-decoration: none; +} +dl.tabs dt a:focus { + text-decoration: underline; +} +div.current { + border: 1px solid #c7c8b2; + background: #ffffff; +} +div.current fieldset { + border: none 0; +} +div.current fieldset.adminform { + border: 1px solid #c7c8b2; +} +#login-page .pagetitle h2 { + background: transparent; +} +#login-page #header { + border-bottom: 1px solid #c7c8b2; +} +#login-page #lock { + background: url(../images/j_login_lock.png) 50% 0 no-repeat; +} +#login-page #element-box.login { + background-color: #f9fade; + background-image: -moz-linear-gradient(top,#f9fade,#f9fade); + background-image: -webkit-gradient(linear,0 0,0 100%,from(#f9fade),to(#f9fade)); + background-image: -webkit-linear-gradient(top,#f9fade,#f9fade); + background-image: -o-linear-gradient(top,#f9fade,#f9fade); + background-image: linear-gradient(to bottom,#f9fade,#f9fade); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff9fade', endColorstr='#fff9fade', GradientType=0); +} +#form-login { + background: #ffffff; + border: 1px solid #c7c8b2; +} +#form-login label { + color: #2c2c2c; +} +#form-login div.button1 a { + color: #054993; +} +#cpanel div.icon a, +.cpanel div.icon a { + color: #054993; + border-left: 1px solid #e5d9c3; + border-top: 1px solid #e5d9c3; + border-right: 1px solid #c7c8b2; + border-bottom: 1px solid #c7c8b2; + background-color: #f9fade; + background-image: -moz-linear-gradient(top,#f9fade,#f9fade); + background-image: -webkit-gradient(linear,0 0,0 100%,from(#f9fade),to(#f9fade)); + background-image: -webkit-linear-gradient(top,#f9fade,#f9fade); + background-image: -o-linear-gradient(top,#f9fade,#f9fade); + background-image: linear-gradient(to bottom,#f9fade,#f9fade); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff9fade', endColorstr='#fff9fade', GradientType=0); +} +#cpanel div.icon a:hover, +#cpanel div.icon a:focus, +.cpanel div.icon a:hover, +.cpanel div.icon a:focus { + border-left: 1px solid #868778; + border-top: 1px solid #868778; + border-right: 1px solid #f6f7db; + border-bottom: 1px solid #f6f7db; + color: #054993; + background: #e5d9c3; +} +fieldset { + border: 1px #c7c8b2 solid; +} +legend { + color: #2c2c2c; +} +fieldset ul.checklist input:focus { + outline: thin dotted #2c2c2c; +} +fieldset#filter-bar { + border-top: 0 solid #c7c8b2; + border-right: 0 solid #c7c8b2; + border-bottom: 1px solid #c7c8b2; + border-left: 0 solid #c7c8b2; +} +fieldset#filter-bar ol, +fieldset#filter-bar ul { + border: 0; +} +fieldset#filter-bar ol li fieldset, +fieldset#filter-bar ul li fieldset { + border: 0; +} +.invalid { + color: #a20000; +} +input.invalid { + border: 1px solid #a20000; +} +input.readonly, +span.faux-input { + border: 0; +} +input.required { + background-color: #e5f0fa; +} +input.disabled { + background-color: #eeeeee; +} +input, +select, +span.faux-input { + background-color: #ffffff; + border: 1px solid #c7c8b2; +} +input[type="button"], +input[type="submit"], +input[type="reset"] { + color: #054993; + background-color: #f9fade; + background-image: -moz-linear-gradient(top,#f9fade,#f9fade); + background-image: -webkit-gradient(linear,0 0,0 100%,from(#f9fade),to(#f9fade)); + background-image: -webkit-linear-gradient(top,#f9fade,#f9fade); + background-image: -o-linear-gradient(top,#f9fade,#f9fade); + background-image: linear-gradient(to bottom,#f9fade,#f9fade); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff9fade', endColorstr='#fff9fade', GradientType=0); +} +input[type="button"]:hover, +input[type="button"]:focus, +input[type="submit"]:hover, +input[type="submit"]:focus, +input[type="reset"]:hover, +input[type="reset"]:focus { + background: #e5d9c3; +} +textarea { + background-color: #ffffff; + border: 1px solid #c7c8b2; +} +input:focus, +select:focus, +textarea:focus, +option:focus, +input:hover, +select:hover, +textarea:hover, +option:hover { + background-color: #e5d9c3; + color: #054993; +} +.paramrules { + background: #f9fade; +} +span.gi { + color: #c7c8b2; +} +table.admintable td.key, +table.admintable td.paramlist_key { + background-color: #f9fade; + color: #2c2c2c; + border-bottom: 1px solid #c7c8b2; + border-right: 1px solid #c7c8b2; +} +table.paramlist td.paramlist_description { + background-color: #f9fade; + color: #2c2c2c; + border-bottom: 1px solid #c7c8b2; + border-right: 1px solid #c7c8b2; +} +fieldset.adminform { + border: 1px solid #c7c8b2; +} +table.adminform { + background-color: #ffffff; +} +table.adminform tr.row0 { + background-color: #ffffff; +} +table.adminform tr.row1 { + background-color: #e5d9c3; +} +table.adminform th { + color: #2c2c2c; + background: #ffffff; +} +table.adminform tr { + border-bottom: 1px solid #c7c8b2; + border-right: 1px solid #c7c8b2; +} +table.adminlist { + border-spacing: 1px; + background-color: #ffffff; + color: #2c2c2c; +} +table.adminlist.modal { + border-top: 1px solid #c7c8b2; + border-right: 1px solid #c7c8b2; + border-left: 1px solid #c7c8b2; +} +table.adminlist a { + color: #054993; +} +table.adminlist thead th { + background: #ffffff; + color: #2c2c2c; + border-bottom: 1px solid #c7c8b2; +} +table.adminlist tbody tr { + background: #ffffff; +} +table.adminlist tbody tr.row1 { + background: #ffffff; +} +table.adminlist tbody tr.row1:last-child td, +table.adminlist tbody tr.row1:last-child th { + border-bottom: 1px solid #c7c8b2; +} +table.adminlist tbody tr.row0:hover td, +table.adminlist tbody tr.row1:hover td, +table.adminlist tbody tr.row0:hover th, +table.adminlist tbody tr.row1:hover th, +table.adminlist tbody tr.row0:focus td, +table.adminlist tbody tr.row1:focus td, +table.adminlist tbody tr.row0:focus th, +table.adminlist tbody tr.row1:focus th { + background-color: #e5d9c3; +} +table.adminlist tbody tr td, +table.adminlist tbody tr th { + border-right: 1px solid #c7c8b2; +} +table.adminlist tbody tr td:last-child { + border-right: none; +} +table.adminlist tbody tr.row0:last-child td, +table.adminlist tbody tr.row0:last-child th { + border-bottom: 1px solid #c7c8b2; +} +table.adminlist tbody tr.row0 td, +table.adminlist tbody tr.row0 th { + background-color: #f9fade; + background-image: -moz-linear-gradient(top,#f9fade,#f9fade); + background-image: -webkit-gradient(linear,0 0,0 100%,from(#f9fade),to(#f9fade)); + background-image: -webkit-linear-gradient(top,#f9fade,#f9fade); + background-image: -o-linear-gradient(top,#f9fade,#f9fade); + background-image: linear-gradient(to bottom,#f9fade,#f9fade); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff9fade', endColorstr='#fff9fade', GradientType=0); +} +table.adminlist { + border-bottom: 0 solid #c7c8b2; +} +table.adminlist tfoot tr { + color: #2c2c2c; +} +table.adminlist tfoot td, +table.adminlist tfoot th { + background-color: #ffffff; + border-top: 1px solid #c7c8b2; +} +table.adminlist tr td.btns a { + border: 1px solid #c7c8b2; + background-color: #f9fade; + background-image: -moz-linear-gradient(top,#f9fade,#f9fade); + background-image: -webkit-gradient(linear,0 0,0 100%,from(#f9fade),to(#f9fade)); + background-image: -webkit-linear-gradient(top,#f9fade,#f9fade); + background-image: -o-linear-gradient(top,#f9fade,#f9fade); + background-image: linear-gradient(to bottom,#f9fade,#f9fade); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff9fade', endColorstr='#fff9fade', GradientType=0); + color: #054993; +} +table.adminlist tr td.btns a:hover, +table.adminlist tr td.btns a:active, +table.adminlist tr td.btns a:focus { + background-color: #ffffff; +} +a.saveorder { + background: url(../images/admin/filesave.png) no-repeat; +} +a.saveorder.inactive { + background-position: 0 -16px; +} +fieldset.batch { + background: #ffffff; +} +button { + color: #054993; + border: 1px solid #c7c8b2; + background-color: #f9fade; + background-image: -moz-linear-gradient(top,#f9fade,#f9fade); + background-image: -webkit-gradient(linear,0 0,0 100%,from(#f9fade),to(#f9fade)); + background-image: -webkit-linear-gradient(top,#f9fade,#f9fade); + background-image: -o-linear-gradient(top,#f9fade,#f9fade); + background-image: linear-gradient(to bottom,#f9fade,#f9fade); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff9fade', endColorstr='#fff9fade', GradientType=0); +} +button:hover, +button:focus { + background: #e5d9c3; +} +.invalid { + color: #ff0000; +} +.button1 { + border: 1px solid #c7c8b2; + color: #054993; + background-color: #f9fade; + background-image: -moz-linear-gradient(top,#f9fade,#f9fade); + background-image: -webkit-gradient(linear,0 0,0 100%,from(#f9fade),to(#f9fade)); + background-image: -webkit-linear-gradient(top,#f9fade,#f9fade); + background-image: -o-linear-gradient(top,#f9fade,#f9fade); + background-image: linear-gradient(to bottom,#f9fade,#f9fade); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff9fade', endColorstr='#fff9fade', GradientType=0); +} +.button1 a { + color: #054993; +} +.button1 a:hover, +.button1 a:focus { + background: #e5d9c3; +} +.button2-left, +.button2-right { + border: 1px solid #c7c8b2; + background-color: #f9fade; + background-image: -moz-linear-gradient(top,#f9fade,#f9fade); + background-image: -webkit-gradient(linear,0 0,0 100%,from(#f9fade),to(#f9fade)); + background-image: -webkit-linear-gradient(top,#f9fade,#f9fade); + background-image: -o-linear-gradient(top,#f9fade,#f9fade); + background-image: linear-gradient(to bottom,#f9fade,#f9fade); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff9fade', endColorstr='#fff9fade', GradientType=0); +} +.button2-left a, +.button2-right a, +.button2-left span, +.button2-right span { + color: #054993; +} +.button2-left span, +.button2-right span { + color: #999999; +} +.page span, +.blank span { + color: #054993; +} +.button2-left a:hover, +.button2-right a:hover, +.button2-left a:focus, +.button2-right a:focus { + background: #e5d9c3; +} +.pagination .page span { + color: #999999; +} +.tip { + background: #000000; + border: 1px solid #FFFFFF; +} +.tip-title { + background: url(../images/selector-arrow-std.png) no-repeat; +} +a img.calendar { + background: url(../images/calendar.png) no-repeat; +} +.jgrid span.publish { + background-image: url(../images/admin/tick.png); +} +.jgrid span.unpublish { + background-image: url(../images/admin/publish_x.png); +} +.jgrid span.archive { + background-image: url(../images/menu/icon-16-archive.png); +} +.jgrid span.trash { + background-image: url(../images/menu/icon-16-trash.png); +} +.jgrid span.default { + background-image: url(../images/menu/icon-16-default.png); +} +.jgrid span.notdefault { + background-image: url(../images/menu/icon-16-notdefault.png); +} +.jgrid span.checkedout { + background-image: url(../images/admin/checked_out.png); +} +.jgrid span.downarrow { + background-image: url(../images/admin/downarrow.png); +} +.jgrid span.downarrow_disabled { + background-image: url(../images/admin/downarrow0.png); +} +.jgrid span.uparrow { + background-image: url(../images/admin/uparrow.png); +} +.jgrid span.uparrow_disabled { + background-image: url(../images/admin/uparrow0.png); +} +.jgrid span.published { + background-image: url(../images/admin/publish_g.png); +} +.jgrid span.expired { + background-image: url(../images/admin/publish_r.png); +} +.jgrid span.pending { + background-image: url(../images/admin/publish_y.png); +} +.jgrid span.warning { + background-image: url(../images/admin/publish_y.png); +} +.icon-32-send { + background-image: url(../images/toolbar/icon-32-send.png); +} +.icon-32-delete { + background-image: url(../images/toolbar/icon-32-delete.png); +} +.icon-32-help { + background-image: url(../images/toolbar/icon-32-help.png); +} +.icon-32-cancel { + background-image: url(../images/toolbar/icon-32-cancel.png); +} +.icon-32-checkin { + background-image: url(../images/toolbar/icon-32-checkin.png); +} +.icon-32-options { + background-image: url(../images/toolbar/icon-32-config.png); +} +.icon-32-apply { + background-image: url(../images/toolbar/icon-32-apply.png); +} +.icon-32-back { + background-image: url(../images/toolbar/icon-32-back.png); +} +.icon-32-forward { + background-image: url(../images/toolbar/icon-32-forward.png); +} +.icon-32-save { + background-image: url(../images/toolbar/icon-32-save.png); +} +.icon-32-edit { + background-image: url(../images/toolbar/icon-32-edit.png); +} +.icon-32-copy { + background-image: url(../images/toolbar/icon-32-copy.png); +} +.icon-32-move { + background-image: url(../images/toolbar/icon-32-move.png); +} +.icon-32-new { + background-image: url(../images/toolbar/icon-32-new.png); +} +.icon-32-upload { + background-image: url(../images/toolbar/icon-32-upload.png); +} +.icon-32-assign { + background-image: url(../images/toolbar/icon-32-publish.png); +} +.icon-32-html { + background-image: url(../images/toolbar/icon-32-html.png); +} +.icon-32-css { + background-image: url(../images/toolbar/icon-32-css.png); +} +.icon-32-menus { + background-image: url(../images/toolbar/icon-32-menu.png); +} +.icon-32-publish { + background-image: url(../images/toolbar/icon-32-publish.png); +} +.icon-32-unblock { + background-image: url(../images/toolbar/icon-32-unblock.png); +} +.icon-32-unpublish { + background-image: url(../images/toolbar/icon-32-unpublish.png); +} +.icon-32-restore { + background-image: url(../images/toolbar/icon-32-revert.png); +} +.icon-32-trash { + background-image: url(../images/toolbar/icon-32-trash.png); +} +.icon-32-archive { + background-image: url(../images/toolbar/icon-32-archive.png); +} +.icon-32-unarchive { + background-image: url(../images/toolbar/icon-32-unarchive.png); +} +.icon-32-preview { + background-image: url(../images/toolbar/icon-32-preview.png); +} +.icon-32-default { + background-image: url(../images/toolbar/icon-32-default.png); +} +.icon-32-refresh { + background-image: url(../images/toolbar/icon-32-refresh.png); +} +.icon-32-save-new { + background-image: url(../images/toolbar/icon-32-save-new.png); +} +.icon-32-save-copy { + background-image: url(../images/toolbar/icon-32-save-copy.png); +} +.icon-32-error { + background-image: url(../images/toolbar/icon-32-error.png); +} +.icon-32-new-style { + background-image: url(../images/toolbar/icon-32-new-style.png); +} +.icon-32-delete-style { + background-image: url(../images/toolbar/icon-32-delete-style.png); +} +.icon-32-purge { + background-image: url(../images/toolbar/icon-32-purge.png); +} +.icon-32-remove { + background-image: url(../images/toolbar/icon-32-remove.png); +} +.icon-32-featured { + background-image: url(../images/toolbar/icon-32-featured.png); +} +.icon-32-unfeatured { + background-image: url(../images/toolbar/icon-32-featured.png); + background-position: 0% 100%; +} +.icon-32-export { + background-image: url(../images/toolbar/icon-32-export.png); +} +.icon-32-stats { + background-image: url(../images/toolbar/icon-32-stats.png); +} +.icon-32-print { + background-image: url(../images/toolbar/icon-32-print.png); +} +.icon-32-batch { + background-image: url(../images/toolbar/icon-32-batch.png); +} +.icon-32-envelope { + background-image: url(../images/toolbar/icon-32-messaging.png); +} +.icon-32-download { + background-image: url(../images/toolbar/icon-32-export.png); +} +.icon-32-bars { + background-image: url(../images/toolbar/icon-32-stats.png); +} +.icon-48-categories { + background-image: url(../images/header/icon-48-category.png); +} +.icon-48-category-edit { + background-image: url(../images/header/icon-48-category.png); +} +.icon-48-category-add { + background-image: url(../images/header/icon-48-category-add.png); +} +.icon-48-generic { + background-image: url(../images/header/icon-48-generic.png); +} +.icon-48-banners { + background-image: url(../images/header/icon-48-banner.png); +} +.icon-48-banners-categories { + background-image: url(../images/header/icon-48-banner-categories.png); +} +.icon-48-banners-category-edit { + background-image: url(../images/header/icon-48-banner-categories.png); +} +.icon-48-banners-category-add { + background-image: url(../images/header/icon-48-category-add.png); +} +.icon-48-banners-clients { + background-image: url(../images/header/icon-48-banner-client.png); +} +.icon-48-banners-tracks { + background-image: url(../images/header/icon-48-banner-tracks.png); +} +.icon-48-checkin { + background-image: url(../images/header/icon-48-checkin.png); +} +.icon-48-clear { + background-image: url(../images/header/icon-48-clear.png); +} +.icon-48-contact { + background-image: url(../images/header/icon-48-contacts.png); +} +.icon-48-contact-categories { + background-image: url(../images/header/icon-48-contacts-categories.png); +} +.icon-48-contact-category-edit { + background-image: url(../images/header/icon-48-contacts-categories.png); +} +.icon-48-contact-category-add { + background-image: url(../images/header/icon-48-category-add.png); +} +.icon-48-purge { + background-image: url(../images/header/icon-48-purge.png); +} +.icon-48-cpanel { + background-image: url(../images/header/icon-48-cpanel.png); +} +.icon-48-config { + background-image: url(../images/header/icon-48-config.png); +} +.icon-48-groups { + background-image: url(../images/header/icon-48-groups.png); +} +.icon-48-groups-add { + background-image: url(../images/header/icon-48-groups-add.png); +} +.icon-48-levels { + background-image: url(../images/header/icon-48-levels.png); +} +.icon-48-levels-add { + background-image: url(../images/header/icon-48-levels-add.png); +} +.icon-48-module { + background-image: url(../images/header/icon-48-module.png); +} +.icon-48-menu { + background-image: url(../images/header/icon-48-menu.png); +} +.icon-48-menu-add { + background-image: url(../images/header/icon-48-menu-add.png); +} +.icon-48-menumgr { + background-image: url(../images/header/icon-48-menumgr.png); +} +.icon-48-trash { + background-image: url(../images/header/icon-48-trash.png); +} +.icon-48-user { + background-image: url(../images/header/icon-48-user.png); +} +.icon-48-user-add { + background-image: url(../images/header/icon-48-user-add.png); +} +.icon-48-user-edit { + background-image: url(../images/header/icon-48-user-edit.png); +} +.icon-48-user-profile { + background-image: url(../images/header/icon-48-user-profile.png); +} +.icon-48-inbox { + background-image: url(../images/header/icon-48-inbox.png); +} +.icon-48-new-privatemessage { + background-image: url(../images/header/icon-48-new-privatemessage.png); +} +.icon-48-msgconfig { + background-image: url(../images/header/icon-48-message_config.png); +} +.icon-48-langmanager { + background-image: url(../images/header/icon-48-language.png); +} +.icon-48-mediamanager { + background-image: url(../images/header/icon-48-media.png); +} +.icon-48-plugin { + background-image: url(../images/header/icon-48-plugin.png); +} +.icon-48-help_header { + background-image: url(../images/header/icon-48-help_header.png); +} +.icon-48-impressions { + background-image: url(../images/header/icon-48-stats.png); +} +.icon-48-browser { + background-image: url(../images/header/icon-48-stats.png); +} +.icon-48-searchtext { + background-image: url(../images/header/icon-48-stats.png); +} +.icon-48-thememanager { + background-image: url(../images/header/icon-48-themes.png); +} +.icon-48-writemess { + background-image: url(../images/header/icon-48-writemess.png); +} +.icon-48-featured { + background-image: url(../images/header/icon-48-featured.png); +} +.icon-48-sections { + background-image: url(../images/header/icon-48-section.png); +} +.icon-48-article-add { + background-image: url(../images/header/icon-48-article-add.png); +} +.icon-48-article-edit { + background-image: url(../images/header/icon-48-article-edit.png); +} +.icon-48-article { + background-image: url(../images/header/icon-48-article.png); +} +.icon-48-content-categories { + background-image: url(../images/header/icon-48-category.png); +} +.icon-48-content-category-edit { + background-image: url(../images/header/icon-48-category.png); +} +.icon-48-content-category-add { + background-image: url(../images/header/icon-48-category-add.png); +} +.icon-48-install { + background-image: url(../images/header/icon-48-extension.png); +} +.icon-48-dbbackup { + background-image: url(../images/header/icon-48-backup.png); +} +.icon-48-dbrestore { + background-image: url(../images/header/icon-48-dbrestore.png); +} +.icon-48-dbquery { + background-image: url(../images/header/icon-48-query.png); +} +.icon-48-systeminfo { + background-image: url(../images/header/icon-48-info.png); +} +.icon-48-massmail { + background-image: url(../images/header/icon-48-massmail.png); +} +.icon-48-redirect { + background-image: url(../images/header/icon-48-redirect.png); +} +.icon-48-search { + background-image: url(../images/header/icon-48-search.png); +} +.icon-48-finder { + background-image: url(../images/header/icon-48-search.png); +} +.icon-48-newsfeeds { + background-image: url(../images/header/icon-48-newsfeeds.png); +} +.icon-48-newsfeeds-categories { + background-image: url(../images/header/icon-48-newsfeeds-cat.png); +} +.icon-48-newsfeeds-category-edit { + background-image: url(../images/header/icon-48-newsfeeds-cat.png); +} +.icon-48-newsfeeds-category-add { + background-image: url(../images/header/icon-48-category-add.png); +} +.icon-48-weblinks { + background-image: url(../images/header/icon-48-links.png); +} +.icon-48-weblinks-categories { + background-image: url(../images/header/icon-48-links-cat.png); +} +.icon-48-weblinks-category-edit { + background-image: url(../images/header/icon-48-links-cat.png); +} +.icon-48-weblinks-category-add { + background-image: url(../images/header/icon-48-category-add.png); +} +.icon-48-tags { + background-image: url(../images/header/icon-48-tags.png); +} +.icon-48-assoc { + background-image: url(../images/header/icon-48-assoc.png); +} +.icon-48-puzzle { + background-image: url(../images/header/icon-48-puzzle.png); +} +div.message { + border: 1px solid #c7c8b2; + color: #2c2c2c; +} +.helpFrame { + border-left: 0 solid #c7c8b2; + border-right: none; + border-top: none; + border-bottom: none; +} +.outline { + border: 1px solid #c7c8b2; + background: #ffffff; +} +dl.menu_type dt { + border-bottom: 1px solid #c7c8b2; +} +ul#new-modules-list { + border-top: 1px solid #c7c8b2; +} +#skiplinkholder a, +#skiplinkholder a:link, +#skiplinkholder a:visited { + color: #ffffff; + background: #054993; + border-bottom: solid #336 2px; +} +fieldset.panelform { + border: none 0; +} +a.move_up { + background-image: url('../images/admin/uparrow.png'); +} +span.move_up { + background-image: url('../images/admin/uparrow0.png'); +} +a.move_down { + background-image: url('../images/admin/downarrow.png'); +} +span.move_down { + background-image: url('../images/admin/downarrow0.png'); +} +a.grid_false { + background-image: url('../images/admin/publish_x.png'); +} +a.grid_true { + background-image: url('../images/admin/tick.png'); +} +a.grid_trash { + background-image: url('../images/admin/icon-16-trash.png'); +} +tr.row1 { + background-color: #f9fade; +} +table.aclsummary-table td.col2, +table.aclsummary-table th.col2, +table.aclsummary-table td.col3, +table.aclsummary-table th.col3, +table.aclsummary-table td.col4, +table.aclsummary-table th.col4, +table.aclsummary-table td.col5, +table.aclsummary-table th.col5, +table.aclsummary-table td.col6, +table.aclsummary-table th.col6, +table.aclmodify-table td.col2, +table.aclmodify-table th.col2 { + border-left: 1px solid #c7c8b2; +} +span.icon-16-unset { + background: url(../images/admin/icon-16-denyinactive.png) no-repeat; +} +span.icon-16-allowed { + background: url(../images/admin/icon-16-allow.png) no-repeat; +} +span.icon-16-denied { + background: url(../images/admin/icon-16-deny.png) no-repeat; +} +span.icon-16-locked { + background: url(../images/admin/checked_out.png) 0 0 no-repeat; +} +label.icon-16-allow { + background: url(../images/admin/icon-16-allow.png) no-repeat; +} +label.icon-16-deny { + background: url(../images/admin/icon-16-deny.png) no-repeat; +} +a.icon-16-allow { + background: url(../images/admin/icon-16-allow.png) no-repeat; +} +a.icon-16-deny { + background: url(../images/admin/icon-16-deny.png) no-repeat; +} +a.icon-16-allowinactive { + background: url(../images/admin/icon-16-allowinactive.png) no-repeat; +} +a.icon-16-denyinactive { + background: url(../images/admin/icon-16-denyinactive.png) no-repeat; +} +ul.acllegend li.acl-allowed { + background: url(../images/admin/icon-16-allow.png) no-repeat left; +} +ul.acllegend li.acl-denied { + background: url(../images/admin/icon-16-deny.png) no-repeat left; +} +li.acl-editgroups, +li.acl-resetbtn { + background-color: #f9fade; + border: 1px solid #c7c8b2; +} +li.acl-editgroups a, +li.acl-resetbtn a { + color: #054993; +} +li.acl-editgroups:hover, +li.acl-resetbtn:hover, +li.acl-editgroups:focus, +li.acl-resetbtn:focus { + background-color: #e5d9c3; +} +table#acl-config { + border: 1px solid #c7c8b2; +} +table#acl-config th, +table#acl-config td { + background: #f9fade; + border-bottom: 1px solid #c7c8b2; +} +table#acl-config th.acl-groups { + border-right: 1px solid #c7c8b2; +} +#jform_sef_rewrite-lbl { + background: url(../images/admin/icon-16-notice-note.png) right top no-repeat; +} +#permissions-sliders .tip { + background: #ffffff; + border: 1px solid #c7c8b2; +} +#permissions-sliders ul#rules, +#permissions-sliders ul#rules ul { + border: solid 0 #c7c8b2; + background: #ffffff; +} +ul#rules li .pane-sliders .panel h3.title { + border: solid 0 #c7c8b2; +} +#permissions-sliders ul#rules .pane-slider { + border: solid 1px #c7c8b2; +} +#permissions-sliders ul#rules li h3 { + border: solid 1px #c7c8b2; +} +#permissions-sliders ul#rules li h3.pane-toggler-down a { + border: solid 0; +} +#permissions-sliders ul#rules .group-kind { + color: #2c2c2c; +} +#permissions-sliders ul#rules table.group-rules { + border: solid 1px #c7c8b2; +} +#permissions-sliders ul#rules table.group-rules td { + border-right: solid 1px #c7c8b2; + border-bottom: solid 1px #c7c8b2; +} +#permissions-sliders ul#rules table.group-rules th { + background: #e5d9c3; + border-right: solid 1px #c7c8b2; + border-bottom: solid 1px #c7c8b2; + color: #2c2c2c; +} +ul#rules table.aclmodify-table { + border: solid 1px #c7c8b2; +} +ul#rules table.group-rules td label { + border: solid 0 #c7c8b2; +} +#permissions-sliders ul#rules .mypanel { + border: solid 0 #c7c8b2; +} +#permissions-sliders ul#rules table.group-rules td { + background: #ffffff; +} +#permissions-sliders span.level { + color: #c7c8b2; + background-image: none; +} +.check-0, +table.adminlist tbody td.check-0 { + background-color: #ffffcf; +} +.check-a, +table.adminlist tbody td.check-a { + background-color: #cfffda; +} +.check-d, +table.adminlist tbody td.check-d { + background-color: #ffcfcf; +} +#system-message dd ul { + color: #2c2c2c; +} +#system-message dd.error ul { + color: #2c2c2c; +} +#system-message dd.message ul { + color: #2c2c2c; +} +#system-message dd.notice ul { + color: #2c2c2c; +} +#menu { + color: #2c2c2c; +} +#menu ul.dropdown-menu { + background-color: #f9fade; + background-image: -moz-linear-gradient(top,#f9fade,#f9fade); + background-image: -webkit-gradient(linear,0 0,0 100%,from(#f9fade),to(#f9fade)); + background-image: -webkit-linear-gradient(top,#f9fade,#f9fade); + background-image: -o-linear-gradient(top,#f9fade,#f9fade); + background-image: linear-gradient(to bottom,#f9fade,#f9fade); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff9fade', endColorstr='#fff9fade', GradientType=0); + color: #2c2c2c; +} +#menu ul.dropdown-menu li.dropdown-submenu { + background: url(../images/j_arrow.png) no-repeat right 50%; +} +#menu ul.dropdown-menu li.divider { + margin-bottom: 0; + border-bottom: 1px dotted #c7c8b2; +} +#menu a { + color: #054993; + background-repeat: no-repeat; + background-position: left 50%; +} +#menu li { + border-right: 1px solid #c7c8b2; + background-color: transparent; +} +#menu li a:hover, +#menu li a:focus { + background-color: #e5d9c3; +} +#menu li.disabled a:hover, +#menu li.disabled a:focus, +#menu li.disabled a { + color: #c7c8b2; + background-color: #f9fade; + background-image: -moz-linear-gradient(top,#f9fade,#f9fade); + background-image: -webkit-gradient(linear,0 0,0 100%,from(#f9fade),to(#f9fade)); + background-image: -webkit-linear-gradient(top,#f9fade,#f9fade); + background-image: -o-linear-gradient(top,#f9fade,#f9fade); + background-image: linear-gradient(to bottom,#f9fade,#f9fade); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff9fade', endColorstr='#fff9fade', GradientType=0); +} +#menu li ul { + border: 1px solid #c7c8b2; +} +#menu li li { + background-color: transparent; +} +#menu li.sfhover a { + background-color: #e5d9c3; +} +#menu li.sfhover li a { + background-color: transparent; +} +#menu li.sfhover li.sfhover a, +#menu li li a:focus { + background-color: #e5d9c3; +} +#menu li.sfhover li.sfhover li a { + background-color: transparent; +} +#menu li.sfhover li.sfhover li.sfhover a, +#menu li li li a:focus { + background-color: #e5d9c3; +} +#menu li li a:focus, +#menu li li li a:focus { + background-color: #e5d9c3; +} +#menu li li li a:focus { + background-color: #e5d9c3; +} +#submenu { + border-bottom: 1px solid #c7c8b2; +} +#submenu li, +#submenu span.nolink { + background-color: #f9fade; + background-image: -moz-linear-gradient(top,#f9fade,#f9fade); + background-image: -webkit-gradient(linear,0 0,0 100%,from(#f9fade),to(#f9fade)); + background-image: -webkit-linear-gradient(top,#f9fade,#f9fade); + background-image: -o-linear-gradient(top,#f9fade,#f9fade); + background-image: linear-gradient(to bottom,#f9fade,#f9fade); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff9fade', endColorstr='#fff9fade', GradientType=0); + border: 1px solid #c7c8b2; + color: #054993; +} +#submenu li:hover, +#submenu li:focus { + background: #e5d9c3; +} +#submenu li.active, +#submenu span.nolink.active { + background: #ffffff; + border-bottom: 1px solid #ffffff; +} +#submenu li.active a, +#submenu span.nolink.active { + color: #000; +} +.element-invisible { + margin: 0; + padding: 0; +} +div.CodeMirror-wrapping { + border: 1px solid #c7c8b2; +} +table.adminform tr.row0 { + background-color: #ffffff; +} +ul.alternating > li:nth-child(odd) { + background-color: #ffffff; +} +ul.alternating > li:nth-child(even) { + background-color: #f9fade; +} +ol.alternating > li:nth-child(odd) { + background-color: #ffffff; +} +ol.alternating > li:nth-child(even) { + background-color: #f9fade; +} +#installer-database, +#installer-discover, +#installer-update, +#installer-warnings { + border-top: 1px solid #c7c8b2; +} +#installer-database p.warning { + background: transparent url(../images/admin/icon-16-deny.png) center left no-repeat; +} +#installer-database p.nowarning { + background: transparent url(../images/admin/icon-16-allow.png) center left no-repeat; +} +.input-append, +.input-prepend { + font-size: 1.2em; +} diff --git a/Sites/pages/administrator/templates/hathor/css/colour_standard_rtl.css b/Sites/pages/administrator/templates/hathor/css/colour_standard_rtl.css new file mode 100644 index 00000000..0f639936 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/css/colour_standard_rtl.css @@ -0,0 +1,370 @@ +@charset "UTF-8"; + +/** + * @package Joomla.Administrator + * @subpackage templates.hathor + * @copyright Copyright (C) 2005 - 2020 Open Source Matters, Inc. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + * @since 1.6 + * + * RTL CSS file for the color standard + */ + +/** + * Overall Styles + */ +#header { + background: #ffffff url(../images/j_logo.png) no-repeat top right; +} + +#element-box { + border-left: 1px solid #c7c8b2; + border-right: 1px solid #c7c8b2; +} + +/** + * Various Styles + */ + +div.checkin-tick { + background: url(../images/admin/tick.png) 20px 50% no-repeat; +} + +/** + * Subheader, toolbar, page title + */ +div.toolbar-box { + border-left: 1px solid #c7c8b2; + border-right: 1px solid #c7c8b2; +} + +div.toolbar-list li.divider { + border-left:1px dotted #e3e4ca; + border-right:none; +} + +div.toolbar-list a:hover { + border-right: 1px solid #e3e4ca; + border-left: 1px solid #c7c8b2; +} + +/** + * Pane Slider pane Toggler styles + */ +.pane-toggler span { + background: transparent url(../images/j_arrow_left.png) right 50% no-repeat; +} + +.pane-toggler-down span { + background: transparent url(../images/j_arrow_down.png) right 50% + no-repeat; +} + +/** + * Cpanel Settings + */ +#cpanel div.icon a:hover, +#cpanel div.icon a:focus { + border-right: 1px solid #e3e4ca; + border-left: 1px solid #c7c8b2; +} + +fieldset#filter-bar { + border-left: none; + border-right: none; +} + +/** + * Admintable Styles + */ +table.admintable td.key,table.admintable td.paramlist_key { + border-left: 1px solid #c7c8b2; + border-right: none; +} + +table.paramlist td.paramlist_description { + border-left: 1px solid #c7c8b2; + border-right: none; +} + +/** + * Admin Form Styles + */ +table.adminform tr { + border-left: 1px solid #c7c8b2; + border-right: none; +} + +/** + * Adminlist Table layout + */ + +table.adminlist.modal { + border-right: 1px solid #c7c8b2; + border-left: 1px solid #c7c8b2; +} + + +/* Table row styles */ + +table.adminlist tbody tr td, +table.adminlist tbody tr th { + border-left: 1px solid #c7c8b2; + border-right: none; +} + +table.adminlist tbody tr td:last-child { + border-left: none; +} + +/** + * Saving order icon styling in admin tables + */ +a.saveorder { + background: url(../images/admin/filesave.png) no-repeat; +} + +a.saveorder.inactive { + background-position: 0 -16px; +} + +/** + * Button styling + */ + +/* Button 1 Type */ + + /* Use this if you add images to the buttons such as directional arrows */ + +.button1 a { + /* add padding if you are using the directional images */ + /* padding: 0 6px 0 30px; */ +} + + /* Button 2 Type */ + +.button2-right .prev { + background-image: url(../images/j_button2_prev.png); + background-position: right center; +} + +.button2-right.off .prev { + background: url(../images/j_button2_prev_off.png) no-repeat; +} + +.button2-right .start { + background-image: url(../images/j_button2_first.png); + background-position: right center; +} + +.button2-left .next { + background-image: url(../images/j_button2_next.png); + background-position: left center; +} + +.button2-left.off .next { /* @TODO check the x position */ + background: url(../images/j_button2_next_off.png) 100% 0 no-repeat; +} + +.button2-left .end { + background-image: url(../images/j_arrow_left.png); + background-position: left center; +} + +.button2-left.off .end { /* @TODO check the x position */ + background: url(../images/j_button2_last_off.png) 100% 0 no-repeat; +} + +.button2-left .image { + background: url(../images/j_button2_image.png) 100% 0 no-repeat; +} + +.button2-left .readmore { + background: url(../images/j_button2_readmore.png) 100% 0 no-repeat; +} + +.button2-left .pagebreak { + background: url(../images/j_button2_pagebreak.png) 100% 0 no-repeat; +} + +/** + * Tooltips + */ + +/** + * System Standard Messages + */ +#system-message dd.message ul { + background: #C3D2E5 url(../images/notice-info.png) 99.5% center no-repeat; +} + +/** + * System Error Messages + */ +#system-message dd.error ul { + background: #E6C0C0 url(../images/notice-alert.png) 99.5% top no-repeat; +} + +/** + * System Notice Messages + */ +#system-message dd.notice ul { + background: #EFE7B8 url(../images/notice-note.png) 99%.5 top no-repeat; +} + +/** + * JGrid styles + */ + +/** + * Menu Icons + * These icons are used on the Administrator menu + * The classes are constructed dynamically when the menu is generated + */ + + +/** + * Toolbar icons + * These icons are used for the toolbar buttons + * The classes are constructed dynamically when the toolbar is created + */ + +/** + * Quick Icons + * Also knows as Header Icons + * These are used for the Quick Icons on the Control Panel + * The same classes are also assigned the Component Title + */ + +/** + * General styles + */ + +.helpFrame { + border-right: 0 solid #c7c8b2; + border-left: none; + border-top: none; +} + +/* -- ACL STYLES relocated from com_users/media/grid.css ----------- */ + +/* -- ACL PANEL STYLES ----------- */ + + +/* All Tabs */ + +table.aclsummary-table td.col2, +table.aclsummary-table th.col2, +table.aclsummary-table td.col3, +table.aclsummary-table th.col3, +table.aclsummary-table td.col4, +table.aclsummary-table th.col4, +table.aclsummary-table td.col5, +table.aclsummary-table th.col5, +table.aclsummary-table td.col6, +table.aclsummary-table th.col6, +table.aclmodify-table td.col2, +table.aclmodify-table th.col2 { + border-right: 1px solid #c7c8b2; + border-left: none; +} + +/* Icons */ + +ul.acllegend li.acl-allowed { + background:url(../images/admin/icon-16-allow.png) no-repeat right; +} +ul.acllegend li.acl-denied { + background:url(../images/admin/icon-16-deny.png) no-repeat right; +} + +table#acl-config th.acl-groups { + border-left: 1px solid #c7c8b2; +} + +table#acl-config th.acl-groups { + text-align: right; +} + +.acl-action { + margin: auto 0; +} + +/* Icons */ + +span.icon-16-unset { + background: url(../images/admin/icon-16-denyinactive.png) no-repeat right; +} + +span.icon-16-allowed { + background: url(../images/admin/icon-16-allow.png) no-repeat right; +} + +span.icon-16-denied { + background: url(../images/admin/icon-16-deny.png) no-repeat right; +} + +span.icon-16-locked { + background: url(../images/admin/checked_out.png) no-repeat right; +} + +/** +* Mod_rewrite Warning +*/ +#jform_sef_rewrite-lbl { + background: url(../images/admin/icon-16-notice-note.png) left top no-repeat; +} + +/** +* Modal S-Box overrides +*/ + +#sbox-window { + text-align: right; +} + +/** +* Permission Rules +*/ + +#permissions-sliders ul#rules table.group-rules td { + border-left: solid 1px #c7c8b2; + border-right: solid 0 #c7c8b2; +} + +#permissions-sliders ul#rules table.group-rules th { + border-left: solid 1px #c7c8b2; + border-right: solid 0 #c7c8b2; +} + +/** + * Menu Styling + */ + +#menu ul li.node { + background-image: url(../images/j_arrow_left.png); + background-repeat: no-repeat; + background-position: left 50%; +} + +#menu a { + background-position: right 50%; +} + +#menu li { + border-left: 1px solid #c7c8b2; + border-right: 0 solid #c7c8b2; +} + +#menu li li li a:focus { + border-right: 1px solid #fafafa; +} + +/* Installer Database */ +#installer-database p.warning { + background-position: center right; +} + +#installer-database p.nowarning { + background-position: center right; +} diff --git a/Sites/pages/administrator/templates/hathor/css/error.css b/Sites/pages/administrator/templates/hathor/css/error.css new file mode 100644 index 00000000..6cb0d69e --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/css/error.css @@ -0,0 +1,74 @@ +/** + * @copyright Copyright (C) 2005 - 2020 Open Source Matters, Inc. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +.outline { + border: 1px solid #cccccc; + background: #ffffff; + padding: 2px; +} + +body { + height: 100%; + padding: 0; + font-family: Arial, Helvetica, Sans Serif; + font-size: 11px; + color: #2c2c2c; + background: #ffffff; + width: 80%; + min-width: 400px; + margin: 15px auto; +} + +div { + background-color: #f9fade; + padding: 8px; + border: solid 1px #c7c8b2; + margin-top: 13px; + margin-bottom: 25px; +} + +.frame { + background-color: #f9fade; + padding: 8px; + border: solid 1px #c7c8b2; + margin-top: 13px; + margin-bottom: 25px; +} + +.table { + border-collapse: collapse; + margin-top: 13px; +} + +a { + border: 1px solid #c7c8b2; + -moz-border-radius: 3px; + -webkit-border-radius: 3px; + border-radius: 3px; + background-color: #ffffff; + color: #2c2c2c; + padding: 3px 20px; + text-decoration: none; +} + +a:hover, a:focus, a:active { + background-color: #e3e4ca; + text-decoration: none; +} + +td { + padding: 3px; + padding-left: 5px; + padding-right: 5px; + border: solid 1px #c7c8b2; + font-size: 10px; +} + +.type { + background-color: #cc0000; + color: #ffffff; + font-weight: bold; + padding: 3px; +} diff --git a/Sites/pages/administrator/templates/hathor/css/ie7.css b/Sites/pages/administrator/templates/hathor/css/ie7.css new file mode 100644 index 00000000..b0f9af42 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/css/ie7.css @@ -0,0 +1,121 @@ +@charset "UTF-8"; + +/** + * @package Joomla.Administrator + * @subpackage templates.hathor + * @copyright Copyright (C) 2005 - 2020 Open Source Matters, Inc. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + * @since 1.6 + * + * CSS file for IE7 + */ + +/** + * Special Styles for Internet Explorer 7 + */ + +input { + border-width: expression(this.type == "radio" ? '0px' : this.type == "checkbox" ? '0px' : '1px'); +} + +div.toolbar-box { + height: 65px; +} + +div.toolbar-list span { + margin: 0; + position: relative +} + +div.toolbar-list a { + position: relative; +} + +div#subheader { + height: 2em; +} + +#login-page .pagetitle h2 { + margin: 0px; + padding: 0px; +} + +*:first-child+html .clearfix { + min-height: 1px; +} + +.menu-links li, +.menu-links li label { + height: 2em; +} + +div.article-edit, +div.category-edit { + zoom: 1; +} + +div.pane-sliders, +div.panel, +div.pane-slider, +div.rules-section, +div.mypanel, +div.containerpg, +div.pagination, +div.upload-queue { + zoom: 1; +} + +div.width-20 fieldset.adminform, +div.width-30 fieldset.adminform, +div.width-35 fieldset.adminform, +div.width-40 fieldset.adminform, +div.width-45 fieldset.adminform, +div.width-50 fieldset.adminform, +div.width-55 fieldset.adminform, +div.width-60 fieldset.adminform, +div.width-65 fieldset.adminform, +div.width-70 fieldset.adminform, +div.width-80 fieldset.adminform, +div.width-100 fieldset.adminform { + zoom: 1; + margin-bottom:10px; +} + +div.toggle-editor { + margin-top: -5px; + margin-bottom: 5px; +} + +table.adminlist { + border-bottom-width: 1px; +} + +div.current dd { + width: 100%; + position: relative; +} + +#permissions-sliders ul#rules table.group-rules caption span { + height: 0; + overflow: hidden; + position: absolute; + padding:0; + margin:0; +} + +div.current ul.menu-links { + zoom: 1; + width: 25%; + margin: 0; + padding:0; + list-style-position: inside; +} + +div#position-icon.pane-sliders div.pane-down div.icon-wrapper { + margin: 0; +} + +fieldset.panelform fieldset.checkboxes.impunlimited { + float: none; + width: 170px; +} diff --git a/Sites/pages/administrator/templates/hathor/css/ie8.css b/Sites/pages/administrator/templates/hathor/css/ie8.css new file mode 100644 index 00000000..98cb58ec --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/css/ie8.css @@ -0,0 +1,21 @@ +@charset "UTF-8"; + +/** + * @package Joomla.Administrator + * @subpackage templates.hathor + * @copyright Copyright (C) 2005 - 2020 Open Source Matters, Inc. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + * @since 1.6 + * + * CSS file for IE8 + */ + +/** + * Special Styles for Internet Explorer 8 + */ + +/* Accessibility: css in template.css for slider keyboard + * has to be reversed here or the mouse does not work for ie */ +.pane-toggler + div.pane-slider { + /*display: block;*/ +} diff --git a/Sites/pages/administrator/templates/hathor/css/template.css b/Sites/pages/administrator/templates/hathor/css/template.css new file mode 100644 index 00000000..8bd16f12 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/css/template.css @@ -0,0 +1,3949 @@ +.clearfix { + *zoom: 1; +} +.clearfix:before, +.clearfix:after { + display: table; + content: ""; + line-height: 0; +} +.clearfix:after { + clear: both; +} +.hide-text { + font: 0/0 a; + color: transparent; + text-shadow: none; + background-color: transparent; + border: 0; +} +.input-block-level { + display: block; + width: 100%; + min-height: 25px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +.fade { + opacity: 0; + -webkit-transition: opacity .15s linear; + -moz-transition: opacity .15s linear; + -o-transition: opacity .15s linear; + transition: opacity .15s linear; +} +.fade.in { + opacity: 1; +} +.collapse { + position: relative; + height: 0; + overflow: hidden; + -webkit-transition: height .35s ease; + -moz-transition: height .35s ease; + -o-transition: height .35s ease; + transition: height .35s ease; +} +.collapse.in { + height: auto; +} +.modal-open .dropdown-menu { + z-index: 2050; +} +.modal-open .dropdown.open { + *z-index: 2050; +} +.modal-open .popover { + z-index: 2110; +} +.modal-open .tooltip { + z-index: 2080; +} +.modal-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1040; + background-color: #000000; +} +.modal-backdrop.fade { + opacity: 0; +} +.modal-backdrop, +.modal-backdrop.fade.in { + opacity: 0.8; + filter: alpha(opacity=80); +} +div.modal { + position: fixed; + top: 50%; + left: 50%; + z-index: 1050; + overflow: auto; + width: 80%; + margin: -250px 0 0 -40%; + background-color: #ffffff; + border: 1px solid #999; + border: 1px solid rgba(0,0,0,0.3); + *border: 1px solid #999; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; + -webkit-box-shadow: 0 3px 7px rgba(0,0,0,0.3); + -moz-box-shadow: 0 3px 7px rgba(0,0,0,0.3); + box-shadow: 0 3px 7px rgba(0,0,0,0.3); + -webkit-background-clip: padding-box; + -moz-background-clip: padding-box; + background-clip: padding-box; +} +div.modal.fade { + -webkit-transition: opacity .3s linear, top .3s ease-out; + -moz-transition: opacity .3s linear, top .3s ease-out; + -o-transition: opacity .3s linear, top .3s ease-out; + transition: opacity .3s linear, top .3s ease-out; + top: -25%; +} +div.modal.fade.in { + top: 50%; +} +.modal-header { + padding: 9px 15px; + border-bottom: 1px solid #eee; +} +.modal-header .close { + float: right; + margin-top: 2px; +} +.modal-body { + overflow-y: auto; + max-height: 400px; + padding: 15px; +} +.modal-form { + margin-bottom: 0; +} +.modal-footer { + padding: 14px 15px 15px; + margin-bottom: 0; + text-align: right; + background-color: #f5f5f5; + border-top: 1px solid #ddd; + -webkit-border-radius: 0 0 6px 6px; + -moz-border-radius: 0 0 6px 6px; + border-radius: 0 0 6px 6px; + -webkit-box-shadow: inset 0 1px 0 #ffffff; + -moz-box-shadow: inset 0 1px 0 #ffffff; + box-shadow: inset 0 1px 0 #ffffff; + *zoom: 1; +} +.modal-footer:before, +.modal-footer:after { + display: table; + content: ""; + line-height: 0; +} +.modal-footer:after { + clear: both; +} +.modal-footer .btn + .btn { + margin-left: 5px; + margin-bottom: 0; +} +.modal-footer .btn-group .btn + .btn { + margin-left: -1px; +} +body.modal-open { + overflow: hidden; + -ms-overflow-style: none; +} +.modal-buttons { + padding: 15px 0px; +} +.modal-buttons button { + font-size: 1.2em; + line-height: 1.6em; +} +.popover { + position: absolute; + top: 0; + left: 0; + z-index: 1060; + display: none; + max-width: 276px; + padding: 1px; + text-align: left; + background-color: #ffffff; + -webkit-background-clip: padding-box; + -moz-background-clip: padding; + background-clip: padding-box; + border: 1px solid #ccc; + border: 1px solid rgba(0,0,0,0.2); + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; + -webkit-box-shadow: 0 5px 10px rgba(0,0,0,0.2); + -moz-box-shadow: 0 5px 10px rgba(0,0,0,0.2); + box-shadow: 0 5px 10px rgba(0,0,0,0.2); + white-space: normal; +} +.popover.top { + margin-top: -10px; +} +.popover.right { + margin-left: 10px; +} +.popover.bottom { + margin-top: 10px; +} +.popover.left { + margin-left: -10px; +} +.popover-title { + margin: 0; + padding: 8px 14px; + font-size: 14px; + font-weight: normal; + line-height: 18px; + background-color: #f7f7f7; + border-bottom: 1px solid #ebebeb; + -webkit-border-radius: 5px 5px 0 0; + -moz-border-radius: 5px 5px 0 0; + border-radius: 5px 5px 0 0; +} +.popover-title:empty { + display: none; +} +.popover-content { + padding: 9px 14px; +} +.popover .arrow, +.popover .arrow:after { + position: absolute; + display: block; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; +} +.popover .arrow { + border-width: 11px; +} +.popover .arrow:after { + border-width: 10px; + content: ""; +} +.popover.top .arrow { + left: 50%; + margin-left: -11px; + border-bottom-width: 0; + border-top-color: #999; + border-top-color: rgba(0,0,0,0.25); + bottom: -11px; +} +.popover.top .arrow:after { + bottom: 1px; + margin-left: -10px; + border-bottom-width: 0; + border-top-color: #ffffff; +} +.popover.right .arrow { + top: 50%; + left: -11px; + margin-top: -11px; + border-left-width: 0; + border-right-color: #999; + border-right-color: rgba(0,0,0,0.25); +} +.popover.right .arrow:after { + left: 1px; + bottom: -10px; + border-left-width: 0; + border-right-color: #ffffff; +} +.popover.bottom .arrow { + left: 50%; + margin-left: -11px; + border-top-width: 0; + border-bottom-color: #999; + border-bottom-color: rgba(0,0,0,0.25); + top: -11px; +} +.popover.bottom .arrow:after { + top: 1px; + margin-left: -10px; + border-top-width: 0; + border-bottom-color: #ffffff; +} +.popover.left .arrow { + top: 50%; + right: -11px; + margin-top: -11px; + border-right-width: 0; + border-left-color: #999; + border-left-color: rgba(0,0,0,0.25); +} +.popover.left .arrow:after { + right: 1px; + border-right-width: 0; + border-left-color: #ffffff; + bottom: -10px; +} +@font-face { + font-family: 'IcoMoon'; + src: url('../../../../media/jui/fonts/IcoMoon.eot'); + src: url('../../../../media/jui/fonts/IcoMoon.eot?#iefix') format('embedded-opentype'), url('../../../../media/jui/fonts/IcoMoon.woff') format('woff'), url('../../../../media/jui/fonts/IcoMoon.ttf') format('truetype'), url('../../../../media/jui/fonts/IcoMoon.svg#IcoMoon') format('svg'); + font-weight: normal; + font-style: normal; +} +[data-icon]:before { + font-family: 'IcoMoon'; + content: attr(data-icon); + speak: none; +} +[class^="icon-"], +[class*=" icon-"] { + display: inline-block; + width: 14px; + height: 14px; + margin-right: .25em; + line-height: 14px; +} +[class^="icon-"]:before, +[class*=" icon-"]:before { + font-family: 'IcoMoon'; + font-style: normal; + speak: none; +} +[class^="icon-"].disabled, +[class*=" icon-"].disabled { + font-weight: normal; +} +.icon-joomla:before { + content: "\e200"; +} +.icon-chevron-up:before, +.icon-uparrow:before, +.icon-arrow-up:before { + content: "\e005"; +} +.icon-chevron-right:before, +.icon-rightarrow:before, +.icon-arrow-right:before { + content: "\e006"; +} +.icon-chevron-down:before, +.icon-downarrow:before, +.icon-arrow-down:before { + content: "\e007"; +} +.icon-chevron-left:before, +.icon-leftarrow:before, +.icon-arrow-left:before { + content: "\e008"; +} +.icon-arrow-first:before { + content: "\e003"; +} +.icon-arrow-last:before { + content: "\e004"; +} +.icon-arrow-up-2:before { + content: "\e009"; +} +.icon-arrow-right-2:before { + content: "\e00a"; +} +.icon-arrow-down-2:before { + content: "\e00b"; +} +.icon-arrow-left-2:before { + content: "\e00c"; +} +.icon-arrow-up-3:before { + content: "\e00f"; +} +.icon-arrow-right-3:before { + content: "\e010"; +} +.icon-arrow-down-3:before { + content: "\e011"; +} +.icon-arrow-left-3:before { + content: "\e012"; +} +.icon-menu-2:before { + content: "\e00e"; +} +.icon-arrow-up-4:before { + content: "\e201"; +} +.icon-arrow-right-4:before { + content: "\e202"; +} +.icon-arrow-down-4:before { + content: "\e203"; +} +.icon-arrow-left-4:before { + content: "\e204"; +} +.icon-share:before, +.icon-redo:before { + content: "\27"; +} +.icon-undo:before { + content: "\28"; +} +.icon-forward-2:before { + content: "\e205"; +} +.icon-backward-2:before, +.icon-reply:before { + content: "\e206"; +} +.icon-unblock:before, +.icon-refresh:before, +.icon-redo-2:before { + content: "\6c"; +} +.icon-undo-2:before { + content: "\e207"; +} +.icon-move:before { + content: "\7a"; +} +.icon-expand:before { + content: "\66"; +} +.icon-contract:before { + content: "\67"; +} +.icon-expand-2:before { + content: "\68"; +} +.icon-contract-2:before { + content: "\69"; +} +.icon-play:before { + content: "\e208"; +} +.icon-pause:before { + content: "\e209"; +} +.icon-stop:before { + content: "\e210"; +} +.icon-previous:before, +.icon-backward:before { + content: "\7c"; +} +.icon-next:before, +.icon-forward:before { + content: "\7b"; +} +.icon-first:before { + content: "\7d"; +} +.icon-last:before { + content: "\e000"; +} +.icon-play-circle:before { + content: "\e00d"; +} +.icon-pause-circle:before { + content: "\e211"; +} +.icon-stop-circle:before { + content: "\e212"; +} +.icon-backward-circle:before { + content: "\e213"; +} +.icon-forward-circle:before { + content: "\e214"; +} +.icon-loop:before { + content: "\e001"; +} +.icon-shuffle:before { + content: "\e002"; +} +.icon-search:before { + content: "\53"; +} +.icon-zoom-in:before { + content: "\64"; +} +.icon-zoom-out:before { + content: "\65"; +} +.icon-apply:before, +.icon-edit:before, +.icon-pencil:before { + content: "\2b"; +} +.icon-pencil-2:before { + content: "\2c"; +} +.icon-brush:before { + content: "\3b"; +} +.icon-save-new:before, +.icon-plus-2:before { + content: "\5d"; +} +.icon-minus-sign:before, +.icon-minus-2:before { + content: "\5e"; +} +.icon-delete:before, +.icon-remove:before, +.icon-cancel-2:before { + content: "\49"; +} +.icon-publish:before, +.icon-save:before, +.icon-ok:before, +.icon-checkmark:before { + content: "\47"; +} +.icon-new:before, +.icon-plus:before { + content: "\2a"; +} +.icon-plus-circle:before { + content: "\e215"; +} +.icon-minus:before, +.icon-not-ok:before { + content: "\4b"; +} +.icon-ban-circle:before, +.icon-minus-circle:before { + content: "\e216"; +} +.icon-unpublish:before, +.icon-cancel:before { + content: "\4a"; +} +.icon-cancel-circle:before { + content: "\e217"; +} +.icon-checkmark-2:before { + content: "\e218"; +} +.icon-checkmark-circle:before { + content: "\e219"; +} +.icon-info:before { + content: "\e220"; +} +.icon-info-2:before, +.icon-info-circle:before { + content: "\e221"; +} +.icon-question:before, +.icon-question-sign:before, +.icon-help:before { + content: "\45"; +} +.icon-question-2:before, +.icon-question-circle:before { + content: "\e222"; +} +.icon-notification:before { + content: "\e223"; +} +.icon-notification-2:before, +.icon-notification-circle:before { + content: "\e224"; +} +.icon-pending:before, +.icon-warning:before { + content: "\48"; +} +.icon-warning-2:before, +.icon-warning-circle:before { + content: "\e225"; +} +.icon-checkbox-unchecked:before { + content: "\3d"; +} +.icon-checkin:before, +.icon-checkbox:before, +.icon-checkbox-checked:before { + content: "\3e"; +} +.icon-checkbox-partial:before { + content: "\3f"; +} +.icon-square:before { + content: "\e226"; +} +.icon-radio-unchecked:before { + content: "\e227"; +} +.icon-radio-checked:before, +.icon-generic:before { + content: "\e228"; +} +.icon-circle:before { + content: "\e229"; +} +.icon-signup:before { + content: "\e230"; +} +.icon-grid:before, +.icon-grid-view:before { + content: "\58"; +} +.icon-grid-2:before, +.icon-grid-view-2:before { + content: "\59"; +} +.icon-menu:before { + content: "\5a"; +} +.icon-list:before, +.icon-list-view:before { + content: "\31"; +} +.icon-list-2:before { + content: "\e231"; +} +.icon-menu-3:before { + content: "\e232"; +} +.icon-folder-open:before, +.icon-folder:before { + content: "\2d"; +} +.icon-folder-close:before, +.icon-folder-2:before { + content: "\2e"; +} +.icon-folder-plus:before { + content: "\e234"; +} +.icon-folder-minus:before { + content: "\e235"; +} +.icon-folder-3:before { + content: "\e236"; +} +.icon-folder-plus-2:before { + content: "\e237"; +} +.icon-folder-remove:before { + content: "\e238"; +} +.icon-file:before { + content: "\e016"; +} +.icon-file-2:before { + content: "\e239"; +} +.icon-file-add:before, +.icon-file-plus:before { + content: "\29"; +} +.icon-file-minus:before { + content: "\e017"; +} +.icon-file-check:before { + content: "\e240"; +} +.icon-file-remove:before { + content: "\e241"; +} +.icon-save-copy:before, +.icon-copy:before { + content: "\e018"; +} +.icon-stack:before { + content: "\e242"; +} +.icon-tree:before { + content: "\e243"; +} +.icon-tree-2:before { + content: "\e244"; +} +.icon-paragraph-left:before { + content: "\e246"; +} +.icon-paragraph-center:before { + content: "\e247"; +} +.icon-paragraph-right:before { + content: "\e248"; +} +.icon-paragraph-justify:before { + content: "\e249"; +} +.icon-screen:before { + content: "\e01c"; +} +.icon-tablet:before { + content: "\e01d"; +} +.icon-mobile:before { + content: "\e01e"; +} +.icon-box-add:before { + content: "\51"; +} +.icon-box-remove:before { + content: "\52"; +} +.icon-download:before { + content: "\e021"; +} +.icon-upload:before { + content: "\e022"; +} +.icon-home:before { + content: "\21"; +} +.icon-home-2:before { + content: "\e250"; +} +.icon-out-2:before, +.icon-new-tab:before { + content: "\e024"; +} +.icon-out-3:before, +.icon-new-tab-2:before { + content: "\e251"; +} +.icon-link:before { + content: "\e252"; +} +.icon-picture:before, +.icon-image:before { + content: "\2f"; +} +.icon-pictures:before, +.icon-images:before { + content: "\30"; +} +.icon-palette:before, +.icon-color-palette:before { + content: "\e014"; +} +.icon-camera:before { + content: "\55"; +} +.icon-camera-2:before, +.icon-video:before { + content: "\e015"; +} +.icon-play-2:before, +.icon-video-2:before, +.icon-youtube:before { + content: "\56"; +} +.icon-music:before { + content: "\57"; +} +.icon-user:before { + content: "\22"; +} +.icon-users:before { + content: "\e01f"; +} +.icon-vcard:before { + content: "\6d"; +} +.icon-address:before { + content: "\70"; +} +.icon-share-alt:before, +.icon-out:before { + content: "\26"; +} +.icon-enter:before { + content: "\e257"; +} +.icon-exit:before { + content: "\e258"; +} +.icon-comment:before, +.icon-comments:before { + content: "\24"; +} +.icon-comments-2:before { + content: "\25"; +} +.icon-quote:before, +.icon-quotes-left:before { + content: "\60"; +} +.icon-quote-2:before, +.icon-quotes-right:before { + content: "\61"; +} +.icon-quote-3:before, +.icon-bubble-quote:before { + content: "\e259"; +} +.icon-phone:before { + content: "\e260"; +} +.icon-phone-2:before { + content: "\e261"; +} +.icon-envelope:before, +.icon-mail:before { + content: "\4d"; +} +.icon-envelope-opened:before, +.icon-mail-2:before { + content: "\4e"; +} +.icon-unarchive:before, +.icon-drawer:before { + content: "\4f"; +} +.icon-archive:before, +.icon-drawer-2:before { + content: "\50"; +} +.icon-briefcase:before { + content: "\e020"; +} +.icon-tag:before { + content: "\e262"; +} +.icon-tag-2:before { + content: "\e263"; +} +.icon-tags:before { + content: "\e264"; +} +.icon-tags-2:before { + content: "\e265"; +} +.icon-options:before, +.icon-cog:before { + content: "\38"; +} +.icon-cogs:before { + content: "\37"; +} +.icon-screwdriver:before, +.icon-tools:before { + content: "\36"; +} +.icon-wrench:before { + content: "\3a"; +} +.icon-equalizer:before { + content: "\39"; +} +.icon-dashboard:before { + content: "\78"; +} +.icon-switch:before { + content: "\e266"; +} +.icon-filter:before { + content: "\54"; +} +.icon-purge:before, +.icon-trash:before { + content: "\4c"; +} +.icon-checkedout:before, +.icon-lock:before, +.icon-locked:before { + content: "\23"; +} +.icon-unlock:before { + content: "\e267"; +} +.icon-key:before { + content: "\5f"; +} +.icon-support:before { + content: "\46"; +} +.icon-database:before { + content: "\62"; +} +.icon-scissors:before { + content: "\e268"; +} +.icon-health:before { + content: "\6a"; +} +.icon-wand:before { + content: "\6b"; +} +.icon-eye-open:before, +.icon-eye:before { + content: "\3c"; +} +.icon-eye-close:before, +.icon-eye-blocked:before, +.icon-eye-2:before { + content: "\e269"; +} +.icon-clock:before { + content: "\6e"; +} +.icon-compass:before { + content: "\6f"; +} +.icon-broadcast:before, +.icon-connection:before, +.icon-wifi:before { + content: "\e01b"; +} +.icon-book:before { + content: "\e271"; +} +.icon-lightning:before, +.icon-flash:before { + content: "\79"; +} +.icon-print:before, +.icon-printer:before { + content: "\e013"; +} +.icon-feed:before { + content: "\71"; +} +.icon-calendar:before { + content: "\43"; +} +.icon-calendar-2:before { + content: "\44"; +} +.icon-calendar-3:before { + content: "\e273"; +} +.icon-pie:before { + content: "\77"; +} +.icon-bars:before { + content: "\76"; +} +.icon-chart:before { + content: "\75"; +} +.icon-power-cord:before { + content: "\32"; +} +.icon-cube:before { + content: "\33"; +} +.icon-puzzle:before { + content: "\34"; +} +.icon-attachment:before, +.icon-paperclip:before, +.icon-flag-2:before { + content: "\72"; +} +.icon-lamp:before { + content: "\74"; +} +.icon-pin:before, +.icon-pushpin:before { + content: "\73"; +} +.icon-location:before { + content: "\63"; +} +.icon-shield:before { + content: "\e274"; +} +.icon-flag:before { + content: "\35"; +} +.icon-flag-3:before { + content: "\e275"; +} +.icon-bookmark:before { + content: "\e023"; +} +.icon-bookmark-2:before { + content: "\e276"; +} +.icon-heart:before { + content: "\e277"; +} +.icon-heart-2:before { + content: "\e278"; +} +.icon-thumbs-up:before { + content: "\5b"; +} +.icon-thumbs-down:before { + content: "\5c"; +} +.icon-unfeatured:before, +.icon-asterisk:before, +.icon-star-empty:before { + content: "\40"; +} +.icon-star-2:before { + content: "\41"; +} +.icon-featured:before, +.icon-default:before, +.icon-star:before { + content: "\42"; +} +.icon-smiley:before, +.icon-smiley-happy:before { + content: "\e279"; +} +.icon-smiley-2:before, +.icon-smiley-happy-2:before { + content: "\e280"; +} +.icon-smiley-sad:before { + content: "\e281"; +} +.icon-smiley-sad-2:before { + content: "\e282"; +} +.icon-smiley-neutral:before { + content: "\e283"; +} +.icon-smiley-neutral-2:before { + content: "\e284"; +} +.icon-cart:before { + content: "\e019"; +} +.icon-basket:before { + content: "\e01a"; +} +.icon-credit:before { + content: "\e286"; +} +.icon-credit-2:before { + content: "\e287"; +} +.icon-expired:before { + content: "\4b"; +} +html, +body, +div, +span, +applet, +object, +iframe, +h1, +h2, +h3, +h4, +h5, +h6, +p, +blockquote, +pre, +a, +abbr, +acronym, +address, +big, +cite, +code, +del, +dfn, +em, +font, +img, +ins, +kbd, +q, +s, +samp, +small, +strike, +strong, +sub, +sup, +tt, +var, +b, +u, +i, +center, +dl, +dt, +dd, +ol, +ul, +li, +fieldset, +form, +label, +legend, +table, +caption, +tbody, +tfoot, +thead, +tr, +th, +td { + margin: 0; + padding: 0; + border: 0; + font-size: 100%; + background: transparent; +} +blockquote, +q { + quotes: none; +} +blockquote:before, +blockquote:after, +q:before, +q:after { + content: ''; + content: none; +} +del { + text-decoration: line-through; +} +html { + overflow-y: scroll; + height: 100%; +} +body { + margin: 0; + padding: 0; + font-size: 62.5%; + line-height: 1.5em; + height: 100%; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} +body, +td, +th, +span, +a { + font-family: Arial, Helvetica, sans-serif; +} +html, +body { + height: 100%; +} +a, +img { + padding: 0; + margin: 0; +} +img { + border: 0 none; +} +form { + margin: 0; + padding: 0; +} +ul { + padding: 0; + margin: 0; +} +h1 { + margin: 0; + padding-bottom: 8px; + font-size: 1.4em; + font-weight: bold; + line-height: 2em; +} +h2 { + padding-top: .83em; + padding-bottom: .83em; +} +h3 { + font-size: 1.4em; +} +a:link { + color: #054993; + text-decoration: none; +} +a:visited { + color: #054993; + text-decoration: none; +} +a:hover { + text-decoration: underline; +} +a:focus { + text-decoration: underline; +} +iframe { + border: 0; +} +.enabled { + color: #005800; + font-weight: bold; +} +.disabled { + color: #a20000; + font-weight: bold; +} +p.error { + color: #a20000; + font-weight: bold; +} +.warning { + color: #a20000; + font-weight: bold; +} +.nowarning { + color: #2c2c2c; + font-weight: bold; +} +.success { + color: #005800; + font-weight: bold; +} +.allow { + color: #005800; +} +span.writable { + color: #005800; +} +.deny { + color: #a20000; +} +span.unwritable { + color: #a20000; +} +.none { + color: #aaaaaa; +} +.pointer { + cursor: pointer; +} +.nowrap { + white-space: nowrap; +} +p.nowarning, +p.warning { + margin: 10px; +} +#minwidth, +#minwidth-body { + min-width: 980px; +} +#containerwrap { + position: relative; +} +#header { + position: relative; +} +#header h1.title { + font-size: 1.5em; + font-weight: normal; + line-height: 25px; + margin: 0; + padding: 0 0 0 120px; +} +#footer { + padding: 10px 20px; +} +#footer .copyright { + margin: 0 0 0 0; + text-align: center; +} +#footer p { + font-size: 1.2em; +} +#nav .no-nav { + line-height: 2em; +} +#content { + margin: 5px 20px 20px 20px; +} +.cpanel-page div#element-box { + padding: 15px; +} +#module-status { + float: right; + position: relative; + top: -48px; +} +#module-status div.btn-group { + display: block; + float: left; + padding: 4px 10px 0 10px; + font-size: 1.2em; +} +#module-status div.divider { + display: none; +} +#module-status .unread-messages a { + font-weight: bold; +} +.title-ua { + position: relative; + width: 60%; +} +.enabled, +.disabled, +p.error, +.warning, +.nowarning, +.success { + font-weight: bold; +} +.pointer { + cursor: pointer; +} +.nowrap { + white-space: nowrap; +} +span.note { + display: block; + padding: 5px; +} +div.checkin-tick { + text-indent: -9999px; +} +.ol-textfont { + font-family: Arial, Helvetica, sans-serif; + font-size: 1.2em; +} +.ol-captionfont { + font-family: Arial, Helvetica, sans-serif; + font-size: 1.2em; + font-weight: bold; +} +.ol-captionfont a { + text-decoration: none; +} +div.subheader .padding { + padding: 0; +} +div.pagetitle { + padding: 0 0 5px 5px; + margin: 0; + background-repeat: no-repeat; + background-position: left 50%; + line-height: 54px; + width: 100%; + margin-top: -20px; + height: 60px; +} +.tabs-left > .nav-tabs { + float: left; + margin-right: 19px; + border-right: 1px solid #DDD; +} +tabs-below > .nav-tabs, +.tabs-right > .nav-tabs, +.tabs-left > .nav-tabs { + border-bottom: 0; +} +.tab-content { + overflow: visible; +} +.tabs-left .tab-content { + overflow: auto; +} +.nav-tabs > li > span { + display: block; + margin-right: 2px; + padding-right: 12px; + padding-left: 12px; + padding-top: 8px; + padding-bottom: 8px; + line-height: 18px; + border: 1px solid transparent; + -webkit-border-radius: 4px 4px 0 0; + -moz-border-radius: 4px 4px 0 0; + border-radius: 4px 4px 0 0; +} +.btn-micro { + padding: 1px 4px; + font-size: 10px; + line-height: 8px; +} +.tip-wrap { + max-width: 200px; + padding: 3px 8px; + color: #ffffff; + text-align: center; + text-decoration: none; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + z-index: 100; +} +.pagetitle h2 { + padding: 0 0 0 50px; + font-size: 1.3em; + font-weight: bold; + line-height: 48px; + font-style: italic; +} +div.configuration { + font-size: 1.2em; + font-weight: bold; + line-height: 2em; + padding-left: 30px; + margin-left: 10px; +} +div.toolbar-box h3 { + height: 0; + overflow: hidden; + position: absolute; + padding: 0; + margin: 0; +} +.btn-toolbar { + margin-bottom: 3px; + margin-top: 14px; +} +div.btn-toolbar, +div.toolbar-list { + float: left; + text-align: left; + padding: 0; +} +div.toolbar-list li { + padding: 5px 1px 5px 4px; + text-align: center; + height: 52px; + list-style: none; + float: left; +} +div.toolbar-list li.spacer { + width: 10px; +} +div.toolbar-list li.divider { + width: 10px; + margin-right: 10px; +} +div.toolbar-list span { + float: none; + width: 32px; + height: 32px; + margin: 0 auto; + display: block; +} +div.toolbar-list a { + display: block; + float: left; + white-space: nowrap; + padding: 1px 5px; + cursor: pointer; + font-weight: bold; +} +div.btn-toolbar div.btn-group button { + display: block; + float: left; + white-space: nowrap; + padding: 1px 5px; + cursor: pointer; + text-align: center; +} +div.btn-toolbar button:hover, +div.btn-toolbar button:focus, +div.toolbar-list a:hover, +div.toolbar-list a:focus { + text-decoration: none; +} +td#mm_pane { + width: 90%; +} +input#mm_subject { + width: 200px; +} +textarea#mm_message { + width: 100%; +} +textarea { + resize: both; +} +textarea.vert { + resize: vertical; +} +textarea.noResize { + resize: none; +} +.pane-sliders { + margin: 0; + position: relative; +} +.pane-sliders .title { + margin: 0; + padding: 2px; + cursor: pointer; +} +.pane-sliders .panel { + margin-bottom: 3px; +} +.pane-sliders .adminlist td { + border: 0 none; +} +h3.pane-toggler-down a:focus, +h3.pane-toggler a:focus { + outline: none; +} +.pane-toggler span { + padding-left: 20px; +} +.pane-toggler-down span { + padding-left: 20px; +} +.pane-slider.pane-hide { + display: none; +} +div#position-icon.pane-sliders div.pane-down div.quickicon-wrapper { + margin: 5px 0 5px 0; +} +div#position-icon.pane-sliders div.pane-down .quickicon-wrapper .icon { + padding: 5px 0 5px 10px; + margin: 0; +} +dl.tabs { + float: left; + margin: 10px 0 -1px 0; + z-index: 50; +} +dl.tabs dt { + float: left; + padding: 4px 10px; + margin-left: 3px; +} +dl.tabs dt.open { + z-index: 100; +} +div.current { + clear: both; + padding: 10px 10px; +} +div.current dd { + padding: 0; + margin: 0; +} +dl#content-pane.tabs { + margin: 1px 0 0 0; +} +div.current label, +div.current span.faux-label { + display: block; + min-width: 150px; + float: left; + clear: left; + margin-top: 8px; +} +div.current fieldset.radio { + float: left; +} +div.current fieldset.radio input { + clear: none; + min-width: 15px; + float: left; + margin: 3px 0 0 2px; +} +div.current fieldset.radio label { + clear: none; + min-width: 45px; + float: left; + margin: 3px 0 0 2px; +} +div.current fieldset.checkboxes { + float: left; + clear: right; +} +div.current fieldset.checkboxes input { + clear: left; + min-width: 15px; + float: left; + margin: 3px 0 0 2px; +} +div.current fieldset.checkboxes label { + clear: right; + min-width: 45px; + margin: 3px 0 0 2px; +} +div.current input, +div.current span.faux-input, +div.current textarea, +div.current select { + clear: none; + float: left; + margin: 3px 0 0 2px; +} +div.current select { + margin-bottom: 15px; +} +div.current table#acl-config th.acl-groups { + text-align: left; +} +div.current table#filter-config th.acl-groups { + text-align: left; +} +div.current table#filter-config select { + margin-bottom: 0; +} +div#menu-assignment { + clear: left; +} +div#menu-assignment ul.menu-links { + float: left; + width: 49%; +} +div#menu-assignment ul.menu-links label { + clear: none; + float: left; + margin: 3px 0 0 2px; +} +div#menu-assignment ul.menu-links input { + clear: left; + float: left; +} +button.jform-rightbtn { + float: right; + margin-right: 0; +} +p.tab-description { + font-size: 1.091em; + margin-left: 0; + margin-top: 5px; +} +#login-page input, +#login-page select { + float: right; + clear: none; +} +#login-page .login { + margin: 0 auto; + width: 575px; + margin-bottom: 100px; +} +#login-page .pagetitle h2 { + margin: -70px 0 30px 0; + font-size: 2em; + padding: 0; +} +#login-page p { + margin: 0; + padding: 0; + margin-bottom: 1em; + font-size: 1.2em; +} +#login-page #header { + margin-bottom: 100px; +} +#login-page .login-inst { + float: left; + width: 35%; +} +#login-page .login-box { + float: right; + width: 63%; +} +#login-page #lock { + width: 150px; + height: 137px; +} +#login-page #element-box.login { + padding: 20px; + -moz-border-radius: 3px; + -webkit-border-radius: 3px; + border-radius: 3px; +} +#login-page .button { + text-align: right; +} +#login-page .login-text { + text-align: left; + width: 40%; + float: left; +} +#form-login { + float: left; + padding: 1.1em; + -moz-border-radius: 3px; + -webkit-border-radius: 3px; + border-radius: 3px; +} +#form-login fieldset { + border: none; +} +#form-login label { + display: block; + float: left; + clear: left; + width: 100px; + text-align: right; + padding: 4px; + color: #2c2c2c; + font-weight: bold; + font-size: 1.4em; + margin-bottom: 15px; +} +#form-login div.button1 div.next { + float: left; +} +#form-login div.button1 a { + height: 2.2em; + line-height: 2.2em; + font-size: 1.5em; + cursor: default; + padding: 0 15px 0 15px; +} +.login-submit { + border: 0; + padding: 0; + margin: 0; + width: 0; + height: 0; +} +#cpanel div.icon, +.cpanel div.icon { + text-align: center; + margin-right: 5px; + float: left; + margin-bottom: 5px; +} +#cpanel div.icon a, +.cpanel div.icon a { + display: block; + float: left; + height: auto; + min-height: 97px; + width: 108px; + color: #2c2c2c; + vertical-align: middle; + text-decoration: none; + font-weight: bold; +} +#cpanel img, +.cpanel img { + padding: 10px; + margin: 0 auto; +} +#cpanel span, +.cpanel span { + display: block; + text-align: center; + padding: 0 0 5px; +} +div.cpanel-icons { + width: 54%; + float: left; +} +div.cpanel-component { + width: 45%; + float: right; +} +div.col { + float: left; +} +div.options-section.col { + float: right; +} +div.col1 { + float: left; + width: 45%; +} +div.col2 { + float: right; + width: 45%; +} +div.width-1 { + width: 1%; +} +div.width-3 { + width: 3%; +} +div.width-5 { + width: 5%; +} +div.width-10 { + width: 10%; +} +div.width-20 { + width: 20%; +} +div.width-30 { + width: 30%; +} +div.width-35 { + width: 35%; +} +div.width-40 { + width: 40%; +} +div.width-45 { + width: 45%; +} +div.width-50 { + width: 50%; +} +div.width-55 { + width: 55%; +} +div.width-60 { + width: 60%; +} +div.width-65 { + width: 65%; +} +div.width-70 { + width: 70%; +} +div.width-80 { + width: 80%; +} +div.width-100 { + width: 100%; +} +.clrlft { + clear: left; +} +.clrrt { + clear: right; +} +.fltlft { + float: left; +} +.fltrt { + float: right; +} +.fltnone { + float: none; +} +div.main-section { + width: 60%; +} +div.options-section { + width: 38%; + margin: 10px 10px 10px 0; +} +div.width-40.fltrt { + width: 38%; + margin: 10px 10px 10px 0; +} +div.rules-section { + width: 98%; + margin: 10px; +} +fieldset { + margin: 2px 10px 2px 10px; + padding: 5px; + text-align: left; +} +legend { + font-size: 1.3em; + font-weight: bold; + padding-bottom: 5px; +} +fieldset p { + margin: 10px 0; + font-size: 1.2em; +} +fieldset ol, +ol#property-values, +fieldset ul, +ul#property-values { + margin: 0; + padding: 0; +} +fieldset li, +ol#property-values li, +ul#property-values li { + list-style: none; + margin: 0; + padding: 5px; +} +fieldset.adminform fieldset.radio, +fieldset.panelform fieldset.radio, +fieldset.adminform-legacy fieldset.radio { + border: 0; + float: left; + padding: 0; + margin: 0 0 5px 0; + clear: right; +} +fieldset.adminform fieldset.radio label, +fieldset.panelform fieldset.radio label, +fieldset.adminform fieldset.radio span.faux-label, +fieldset.panelform fieldset.radio span.faux-label { + min-width: 40px; + float: left; + clear: none; +} +fieldset.adminform fieldset.checkboxes, +fieldset.panelform fieldset.checkboxes, +fieldset.adminform-legacy fieldset.checkboxes { + border: 0; + float: left; + padding: 0; + margin: 0 0 5px 0; + clear: right; +} +fieldset.adminform fieldset.checkboxes input[type="checkbox"], +fieldset.panelform fieldset.checkboxes input[type="checkbox"] { + float: left; + clear: left; +} +fieldset.adminform fieldset.checkboxes label, +fieldset.panelform fieldset.checkboxes label, +fieldset.adminform fieldset.checkboxes span.faux-label, +fieldset.panelform fieldset.checkboxes span.faux-label { + clear: right; +} +div.current span.spacer > span.before, +fieldset.adminform span.spacer > span.before, +fieldset.panelform span.spacer > span.before { + clear: both; + overflow: hidden; + height: 0; + display: block; +} +fieldset.panelform-legacy label, +fieldset.adminform-legacy label, +fieldset.panelform-legacy span.faux-label, +fieldset.adminform-legacy span.faux-label { + min-width: 150px; + float: left; +} +fieldset.adminform .input-prepend, +fieldset.adminform .input-append, +fieldset.panelform .input-prepend, +fieldset.panelform .input-append { + float: left; +} +fieldset.adminform .adminformlist .btn.modal, +fieldset.adminform .input-prepend > *, +fieldset.adminform .input-append > *, +fieldset.panelform .adminformlist .btn.modal, +fieldset.panelform .input-prepend > *, +fieldset.panelform .input-append > * { + float: none; + vertical-align: middle; +} +fieldset.panelform-legacy label.radiobtn-jno, +fieldset.panelform-legacy label.radiobtn-jyes, +fieldset.panelform-legacy label.radiobtn-show, +fieldset.panelform-legacy label.radiobtn-hide, +fieldset.panelform-legacy label.radiobtn-off, +fieldset.panelform-legacy label.radiobtn-on { + min-width: 40px !important; + clear: none !important; +} +#jform_plugdesc-lbl, +#jform_description-lbl { + font-weight: bold; + clear: both; + margin-top: 15px; +} +p.jform_desc { + clear: left; +} +div#jform_ordering { + font-size: 1.091em; + margin-top: 3px; +} +fieldset ul.checklist { + margin-left: 27px; +} +fieldset ul.checklist input, +fieldset ul.checklist label { + float: none; +} +fieldset ul.checklist input:focus { + outline: thin dotted #333333; +} +fieldset#filter-bar { + margin: 0; + padding: 5px 10px 5px 10px; + float: left; + width: 98%; +} +fieldset#filter-bar ol, +fieldset#filter-bar ul { + list-style: none; + margin: 0; + padding: 5px 0 0; +} +fieldset#filter-bar ol li, +fieldset#filter-bar ul li { + float: left; + padding: 0 5px 0 0; +} +fieldset#filter-bar ol li fieldset, +fieldset#filter-bar ul li fieldset { + margin: 0; + padding: 0; +} +fieldset#filter-bar .filter-search { + float: left; + padding-bottom: 3px; +} +fieldset#filter-bar .filter-select { + float: right; +} +fieldset#filter-bar input#search { + width: 10em; +} +.invalid { + font-weight: bold; +} +input.readonly, +span.faux-input { + border: 0; +} +.star { + color: #cc0000; + font-size: 1.2em; +} +input, +select, +span.faux-input { + font-size: 1.2em; + -moz-border-radius: 3px; + -webkit-border-radius: 3px; + border-radius: 3px; +} +span.readonly { + float: left; + font-size: 1.2em; + line-height: 2em; +} +div.readonly { + font-size: 1.2em; + line-height: 2em; +} +div.extdescript { + margin-left: 10px; +} +input[type="button"], +input[type="submit"], +input[type="reset"] { + font-family: Arial, Helvetica, sans-serif; + padding: 1px 6px; + font-size: 1.2em; + line-height: 1.5em; +} +textarea { + font-size: 1.4em; + -moz-border-radius: 3px; + -webkit-border-radius: 3px; + border-radius: 3px; +} +input.button { + cursor: pointer; +} +label { + font-weight: bold; + font-size: 1.1em; +} +span.faux-label { + font-weight: bold; + font-size: 1.1em; +} +label.selectlabel { + position: absolute; + left: -1000em; +} +.paramrules { + padding: 10px; +} +span.gi { + font-weight: bold; + margin-right: 5px; +} +span.gtr { + visibility: hidden; + margin-right: 5px; +} +table.admintable td { + padding: 3px; + font-size: 1em; +} +table.admintable td.key, +table.admintable td.paramlist_key { + text-align: right; + width: 140px; + font-weight: bold; + font-size: 1em; +} +table.admintable td.key label, +table.admintable td.paramlist_key label { + font-size: 1em; +} +table.admintable td.paramlist_value label { + font-size: 1em; +} +table.admintable input, +table.admintable span.faux-input, +table.admintable select { + font-size: 1em; +} +table.paramlist td.paramlist_description { + text-align: left; + width: 170px; + font-weight: normal; +} +table.admintable td.key.vtop { + vertical-align: top; +} +fieldset.adminform { + margin: 0 10px 10px 10px; + overflow: hidden; +} +.adminformlist .btn.modal { + float: left; + margin-top: 7px; +} +ul.adminformlist, +ul.adminformlist li, +dl.adminformlist, +dl.adminformlist li { + margin: 0; + padding: 0; + list-style: none; +} +ul.adminformlist pre { + font-size: 1.3em; +} +ul.adminformlist .button2-left, +ul.adminformlist .button2-left { + margin-top: 5px; +} +table.adminform { + width: 100%; + border-collapse: collapse; + margin: 8px 0 10px 0; + margin-bottom: 15px; +} +table.adminform.nospace { + margin-bottom: 0; +} +table.adminform th { + font-size: 1.4em; + padding: 6px 2px 4px 4px; + text-align: left; + height: 25px; +} +table.adminform td { + padding: 3px; + text-align: left; +} +table.adminform td#filter-bar { + text-align: left; +} +table.adminform td.helpMenu { + text-align: right; +} +table.adminform tr { + padding-left: 10px; + padding-right: 10px; +} +td.center, +th.center { + text-align: center; +} +th.width-1 { + width: 1%; +} +th.width-3 { + width: 3%; +} +th.width-5 { + width: 5%; +} +th.width-10 { + width: 10%; +} +th.width-12 { + width: 12%; +} +th.width-15 { + width: 15%; +} +th.width-20 { + width: 20%; +} +th.width-25 { + width: 25%; +} +th.width-30 { + width: 30%; +} +th.width-40 { + width: 40%; +} +th.row-number-col { + width: 3%; +} +th.checkmark-col { + width: 1%; +} +th.state-col { + width: 5%; +} +th.ordering-col { + width: 10%; +} +th.ordering-col a { + display: block; + float: left; + margin-left: 3px; +} +th.ordering-col a img { + margin-left: 4px; + margin-right: 4px; +} +.categories th.ordering-col input, +.categories td.order input { + font-size: 1em; +} +th.category-col { + width: 5%; +} +th.access-col { + width: 10%; +} +.categories th.access-col { + width: 5%; +} +th.hits-col { + width: 5%; +} +th.id-col { + width: 3%; +} +th.featured-col { + width: 5%; +} +th.created-by-col { + width: 15%; +} +th.date-col { + width: 5%; +} +th.language-col { + width: 5%; +} +th.home-col { + width: 5%; +} +table.adminlist { + width: 100%; + float: left; +} +table.adminlist td, +table.adminlist th { + padding: 4px; + font-size: 1.2em; +} +table.adminlist thead th { + text-align: center; +} +table.adminlist thead a:hover { + text-decoration: none; +} +table.adminlist thead th img { + vertical-align: middle; +} +table.adminlist tbody th { + font-weight: bold; +} +table.adminlist tr { + padding-left: 30px; + padding-right: 30px; +} +table.adminlist tbody tr { + text-align: left; +} +table.adminlist tbody tr td, +table.adminlist tbody tr th { + height: 25px; +} +table.adminlist tfoot tr { + text-align: center; +} +table.adminlist tfoot td, +table.adminlist tfoot th { + text-align: center; +} +table.adminlist td.order { + text-align: center; + white-space: nowrap; +} +table.adminlist td.order span { + float: left; + width: 20px; + text-align: center; +} +table.adminlist td.order input { + text-align: center; + width: 3em; + font-size: 100%; +} +#media-tree_tree ul { + list-style: none outside none; + margin: 0 10px; +} +table.adminlist td.indent-4 { + padding-left: 4px; +} +table.adminlist td.indent-19 { + padding-left: 19px; +} +table.adminlist td.indent-34 { + padding-left: 34px; +} +table.adminlist td.indent-49 { + padding-left: 49px; +} +table.adminlist td.indent-64 { + padding-left: 64px; +} +table.adminlist td.indent-79 { + padding-left: 79px; +} +table.adminlist td.indent-94 { + padding-left: 94px; +} +table.adminlist td.indent-109 { + padding-left: 109px; +} +table.adminlist td.indent-124 { + padding-left: 124px; +} +table.adminlist td.indent-139 { + padding-left: 139px; +} +table.adminlist tr td.btns a { + -moz-border-radius: 3px; + -webkit-border-radius: 3px; + border-radius: 3px; + padding: 3px 20px; +} +table.adminlist tr td.btns a:hover, +table.adminlist tr td.btns a:active, +table.adminlist tr td.btns a:focus { + text-decoration: none; +} +table.adminlist td li { + list-style: inside; +} +ul#new-modules-list { + margin-left: 50px; + font-size: 1.4em; + line-height: 1.5em; +} +.clr { + clear: both; + overflow: hidden; + height: 0; +} +.clearfix:after { + content: "."; + display: block; + height: 0; + clear: both; + visibility: hidden; +} +.menu-module-list { + list-style-position: inside; + padding-left: 10px; + margin-left: 5px; +} +.container { + clear: both; + text-decoration: none; +} +* html .container { + display: inline-block; +} +table.noshow { + width: 100%; + border-collapse: collapse; + padding: 0; + margin: 0; +} +table.noshow tr { + vertical-align: top; +} +table.noshow fieldset { + margin: 15px 7px 7px 7px; +} +a.saveorder { + width: 16px; + height: 16px; + display: block; + overflow: hidden; + float: right; + margin-right: 8px; +} +#editor-xtd-buttons { + padding: 5px; +} +button { + font-family: Arial, Helvetica, sans-serif; + -moz-border-radius: 3px; + -webkit-border-radius: 3px; + border-radius: 3px; + margin-right: 3px; + margin-left: 3px; +} +.invalid { + font-weight: bold; +} +.button1, +.button1 div { + height: 1%; + float: right; +} +.button1 { + white-space: nowrap; + -moz-border-radius: 3px; + -webkit-border-radius: 3px; + border-radius: 3px; +} +.button1 a { + display: block; + height: 2.2em; + float: left; + line-height: 2.2em; + font-size: 1.2em; + font-weight: bold; + cursor: default; + padding: 0 6px 0 6px; +} +.button1 a:hover, +.button1 a:focus { + text-decoration: none; +} +.button2-left, +.button2-right { + float: left; + line-height: 1.5em; + font-size: 1.2em; + -moz-border-radius: 3px; + -webkit-border-radius: 3px; + border-radius: 3px; +} +.button2-left.smallsub, +.button2-right.smallsub { + line-height: 1.2em; + font-size: .9em; +} +.button2-left a, +.button2-right a, +.button2-left span, +.button2-right span { + display: block; + float: left; + cursor: default; +} +.button2-left span, +.button2-right span { + cursor: default; +} +.button2-left .page a, +.button2-right .page a, +.button2-left .page span, +.button2-right .page span, +.button2-left .blank a, +.button2-right .blank a, +.button2-left .blank span, +.button2-right .blank span { + padding: 0 6px; +} +.page span, +.blank span { + font-weight: bold; +} +.button2-left a:hover, +.button2-right a:hover, +.button2-left a:focus, +.button2-right a:focus { + text-decoration: none; +} +.button2-left a, +.button2-left span { + padding: 0 24px 0 6px; +} +.button2-right a, +.button2-right span { + padding: 0 6px 0 24px; +} +.button2-left { + float: left; + margin-left: 5px; +} +.button2-right { + float: left; + margin-left: 5px; +} +div.containerpg { + position: relative; + left: 50%; + float: left; + clear: left; +} +div.pagination { + position: relative; + left: -50%; + margin: 0 auto; + padding: .5em; +} +.pagination div.limit { + float: left; + margin: 0 10px; + font-size: 1.2em; + height: 1.8em; + line-height: 1.8em; +} +.pagination div.limit label { + font-size: 100%; + height: 1.8em; + line-height: 1.8em; +} +.pagination div.limit select { + font-size: 100%; +} +.pagination button { + font-size: 100%; + height: 2.0em; + line-height: 1.8em; + margin-right: 20px; +} +div.pagination .button2-right, +div.pagination .button2-left { + font-size: 1.2em; + height: 1.6em; + line-height: 1.6em; +} +table.adminlist .pagination { + display: table; + padding: 0; + margin: 0 auto; + font-size: .8em; +} +table.adminlist .pagination button { + font-size: 1.2em; + height: 1.6em; + line-height: 1.5em; + margin-right: 20px; +} +div.toggle-editor { + margin-top: 9px; +} +.tip { + float: left; + padding: 5px; + max-width: 400px; + z-index: 50; +} +.tip-title { + padding: 0; + margin: 0; + font-size: 120%; + margin-top: -15px; + padding-top: 15px; + padding-bottom: 5px; +} +.tip-text { + font-size: 100%; + text-align: left; + margin: 0; +} +a img.calendar { + width: 16px; + height: 16px; + margin-left: 3px; + cursor: pointer; + vertical-align: middle; +} +a.jgrid:hover { + text-decoration: none; +} +.jgrid span.state { + display: inline-block; + height: 16px; + width: 16px; +} +.jgrid span.text { + display: none; +} +div.message { + text-align: center; + font-family: Arial, Helvetica, sans-serif; + font-size: 1.2em; + padding: 3px; + margin-bottom: 10px; + font-weight: bold; +} +.helpIndex { + border: 0; + width: 100%; + height: 100%; + padding: 0; + overflow: auto; +} +.helpFrame { + width: 100%; + height: 800px; + padding: 0 5px 0 10px; +} +#treecellhelp { + width: 25%; + display: block; + position: relative; + float: left; + margin: 0; + padding: 2px; + overflow: hidden; +} +#datacellhelp { + width: 73%; + display: block; + float: left; + margin: 0; + padding: 2px 0 0 0; +} +.outline { + padding: 2px; +} +h2.modal-title { + margin-left: 15px; + margin-bottom: 0; + margin-top: 5px; + font-size: 1.8em; + padding-bottom: .5em; +} +ul.menu_types { + padding: 0 0 0 15px; + width: 95%; + margin: 0; +} +ul.menu_types li, +dl.menu_type dd ul li { + width: 240px; + list-style: none; + display: block; + float: left; + margin-right: 10px; +} +ul.menu_types li { + width: 47%; +} +dl.menu_type { + width: 240px; + margin: 0; + padding: 0; +} +dl.menu_type dt { + font-weight: bold; + font-size: 1.5em; + float: left; + margin: 13px 0 5px 0; + width: 240px; +} +dl.menu_type dd { + clear: left; + margin: 0; +} +dl.menu_type dd a { + font-size: 1.2em; +} +dl.menu_type dd ul li { + margin: 0; +} +ul#new-modules-list { + padding: 5px 0 0 15px; + width: 95%; + margin: 0; + list-style: none; +} +ul#new-modules-list li { + list-style: none; + display: block; + float: left; + margin: 0 20px 0 0; + width: 47%; +} +ul#new-modules-list li a { + font-size: 1em; + line-height: 1.5em; +} +body.contentpane #filter-bar { + font-size: 80%; +} +body.contentpane input, +body.contentpane select { + font-size: 120%; +} +#filter-bar input, +#filter-bar select, +#filter-bar button { + font-size: 110%; +} +#skiplinkholder a, +#skiplinkholder a:link, +#skiplinkholder a:visited { + display: block; + width: 99%; + position: absolute; + top: 0; + left: -200%; + z-index: 2; +} +#skiplinkholder a:focus, +#skiplinkholder a:active { + left: 0; + top: 0; + z-index: 100; +} +#skiplinkholder p { + margin: 0; +} +#skiptargetholder { + position: absolute; + left: -200%; +} +#skiplinkholder a, +#skiplinkholder a:link, +#skiplinkholder a:visited { + text-decoration: underline; + padding: 5px; + font-size: 1.3em; + font-weight: bold; + padding-left: 20px; + padding-right: 20px; +} +.body-overlayed a, +.body-overlayed input, +.body-overlayed button { + visibility: hidden; +} +.body-overlayed #sbox-window a, +.body-overlayed #sbox-window input, +.body-overlayed #sbox-window button { + visibility: visible; +} +.element-hidden, +.hide { + display: none; +} +.hidebtn { + border: 0 !important; + padding: 0 !important; + margin: 0; + width: 0; + height: 0; +} +.element-invisible, +.hidelabeltxt { + height: 0; + overflow: hidden; + position: absolute; + padding: 0; + margin: 0; +} +legend.element-invisible { + position: absolute !important; + margin: 0; + padding: 0; + border: 0; + margin-left: -10000px; + font-size: 1px; + height: 0; +} +fieldset.panelform { + overflow: hidden; + clear: both; +} +fieldset.adminform label, +fieldset.panelform label, +fieldset.adminform span.faux-label, +fieldset.panelform span.faux-label { + line-height: 2em; + clear: left; + min-width: 12em; + float: left; + margin-left: 10px; + margin-right: 5px; +} +fieldset.adminform.long label, +fieldset.panelform.long label, +fieldset.adminform.long span.faux-label, +fieldset.panelform.long span.faux-label { + min-width: 18em; +} +fieldset.adminform fieldset.radio label, +fieldset.panelform fieldset.radio label, +fieldset.adminform fieldset.radio span.faux-label, +fieldset.panelform fieldset.radio span.faux-label { + margin-left: 0; +} +fieldset.adminform input, +fieldset.adminform span.faux-input, +fieldset.adminform textarea, +fieldset.adminform select, +fieldset.adminform img, +fieldset.adminform button, +fieldset.panelform input, +fieldset.panelform span.faux-input, +fieldset.panelform textarea, +fieldset.panelform select, +fieldset.panelform img, +fieldset.panelform button { + float: left; + margin: 5px 5px 5px 0; + width: auto; +} +fieldset.batch { + margin: 20px 10px 10px 10px; + padding: 10px; +} +fieldset.batch label { + margin: 5px; + min-width: 40px; +} +fieldset.batch button { + margin: 3px; +} +fieldset#batch-choose-action { + clear: left; + border: 0 none; +} +fieldset.batch label { + float: left; + clear: none; +} +fieldset label#batch-choose-action-lbl { + clear: left; + margin-top: 15px; +} +label#batch-language-lbl, +label#batch-user-lbl { + clear: left; + margin-right: 10px; + margin-top: 15px; +} +select#batch-language-id, +select#batch-user-id { + margin-top: 15px; +} +select#batch-category-id, +select#batch-position-id, +select#batch-menu-id { + margin-right: 30px; +} +fieldset.batch select, +fieldset.batch input, +fieldset.batch img, +fieldset.batch button { + float: left; +} +label#batch-access-lbl, +label#batch-client-lbl { + margin-right: 10px; +} +div#jform_ordering { + font-size: 1.091em; + margin-top: 3px; +} +#jform_impmade, +#jform_clicks { + width: 30px; +} +fieldset.panelform label#jform-imp { + min-width: 3em; + font-size: 1.091em; +} +fieldset.adminform input#jform_clickurl { + width: 20em; +} +a.move_up { + display: inline-block; + height: 16px; + text-indent: -1000em; + width: 16px; +} +span.move_up { + display: inline-block; + height: 16px; + width: 16px; +} +a.move_down { + display: inline-block; + height: 16px; + text-indent: -1000em; + width: 16px; +} +span.move_down { + display: inline-block; + height: 16px; + width: 16px; +} +a.grid_false { + display: inline-block; + height: 16px; + text-indent: -1000em; + width: 16px; +} +a.grid_true { + display: inline-block; + height: 16px; + text-indent: -1000em; + width: 16px; +} +a.grid_trash { + display: inline-block; + height: 16px; + text-indent: -1000em; + width: 16px; +} +div.acl-options { + width: 100%; +} +table.aclsummary-table, +table.aclmodify-table { + border-collapse: collapse; + width: 100%; + font-size: 1.091em; +} +td.col1 { + font-size: 1.091em; + text-align: left; + padding: 4px; +} +table.aclsummary-table caption, +table.aclmodify-table caption { + display: none; +} +table.aclsummary-table th.col1 { + width: 25%; +} +table.aclsummary-table th.col2, +table.aclsummary-table th.col3, +table.aclsummary-table th.col4, +table.aclsummary-table th.col5, +table.aclsummary-table th.col6 { + width: 15%; + vertical-align: bottom; + text-align: center; +} +span.icon-16-unset, +span.icon-16-allowed, +span.icon-16-denied, +span.icon-16-locked { + padding-left: 18px; +} +label.icon-16-allow, +label.icon-16-deny, +a.icon-16-allow, +a.icon-16-deny, +a.icon-16-allowinactive, +a.icon-16-denyinactive { + display: block; + height: 16px; + width: 16px; + margin: 0 auto; +} +label.icon-16-allow { + text-indent: -9999em; + position: relative; + left: 40%; +} +label.icon-16-deny { + text-indent: -9999em; + position: relative; + left: 40%; +} +table.aclmodify-table th.col2, +table.aclmodify-table th.col3, +table.aclmodify-table th.col4 { + width: 20%; + vertical-align: bottom; + text-align: center; +} +table.aclmodify-table select { + margin: 1px; +} +table.aclsummary-table td label, +table.aclmodify-table td label { + min-width: 20px; +} +ul.acllegend { + list-style: none; + font-size: 1.091em; + padding-bottom: 10px; +} +ul.acllegend li { + display: block; + float: left; + padding-right: 20px; + margin: 15px 0 15px 10px; +} +ul.acllegend li.acl-allowed { + padding-left: 20px; + padding-right: 10px; +} +ul.acllegend li.acl-denied { + padding-left: 20px; + padding-right: 20px; +} +ul.acllegend li.acl-editgroups { + padding-right: 10px; +} +ul.acllegend li.acl-resetbtn { + padding-right: 0; +} +li.acl-editgroups, +li.acl-resetbtn { + display: block; + float: left; + -moz-border-radius: 3px; + -webkit-border-radius: 3px; + border-radius: 3px; +} +li.acl-editgroups a, +li.acl-resetbtn a { + padding: 6px; + cursor: default; +} +li.acl-editgroups a:hover, +li.acl-resetbtn a:hover, +li.acl-editgroups a:focus, +li.acl-resetbtn a:focus { + text-decoration: none; + cursor: default; +} +li.acl-editgroups:hover, +li.acl-resetbtn:hover, +li.acl-editgroups:focus, +li.acl-resetbtn:focus { + text-decoration: none; + cursor: default; +} +table#acl-config { + width: 100%; + margin-top: 15px; +} +table#acl-config th, +table#acl-config td { + height: 2em; + background: #f9fade; + text-align: center; + vertical-align: middle; +} +table#acl-config th.acl-groups { + padding-left: 8px; + font-weight: bold; + text-align: left; +} +table#acl-config th.acl-groups span.gi { + margin-right: 2px; +} +table#acl-config td { + width: 9em; +} +table#acl-config td select { + float: none; +} +.acl-action { + font-size: 1.091em; + margin: auto 0; +} +.acl-groups { + font-size: 1.091em; + font-weight: normal; +} +label#jform_rules-lbl { + float: none; + white-space: nowrap; + display: none; + visibility: hidden; +} +label#jform_filters-lbl { + float: none; + white-space: nowrap; + display: none; + visibility: hidden; +} +ul.config-option-list, +ul.config-option-list li { + margin: 0; + padding: 0; + list-style: none; +} +ul.config-option-list fieldset { + margin: 0; + padding-left: 0; + padding-right: 0; +} +#permissions-sliders { + margin-top: 15px; +} +#permissions-sliders ul#rules, +#permissions-sliders ul#rules ul { + margin: 0 !important; + padding: 0 !important; + list-style-type: none; +} +#permissions-sliders ul#rules li { + margin: 0; + padding: 0; +} +#permissions-sliders ul#rules table.group-rules { + border-collapse: collapse; + margin: 5px; + width: 100%; +} +#permissions-sliders ul#rules table.group-rules td { + padding: 4px; + vertical-align: middle; + text-align: left; + overflow: hidden; +} +#permissions-sliders ul#rules table.group-rules th { + font-size: 1.2em; + overflow: hidden; + font-weight: bold; +} +#permissions-sliders .panel { + margin-bottom: 3px; + margin-left: 0; + border: 0; +} +#permissions-sliders p.rule-desc { + font-size: 1.1em; +} +#permissions-sliders div.rule-notes { + font-size: 1.1em; +} +ul#rules table.group-rules td label { + margin: 0 !important; + line-height: 1.1em; +} +ul#rules table.group-rules td span { + font-size: 1.1em; + padding-bottom: 4px; +} +ul#rules table.group-rules td span span { + font-size: 100%; +} +table.group-rules td select { + margin: 0 !important; +} +#permissions-sliders ul#rules .mypanel { + padding: 0; + line-height: 1.3em; +} +#permissions-sliders .mypanel table.group-rules caption { + font-size: 1.3em; +} +#permissions-sliders ul#rules { + padding: 5px; +} +#permissions-sliders ul#rules table.group-rules th { + text-align: left; + padding: 4px; +} +#permissions-sliders ul#rules table.group-rules td label { + min-width: 1em; +} +#permissions-sliders .pane-toggler span { + padding-left: 20px; +} +#permissions-sliders .pane-toggler-down span { + padding-left: 20px; +} +#permissions-sliders .pane-toggler-down span.level, +#permissions-sliders .pane-toggler span.level { + padding: 0; +} +.swatch { + text-align: center; + padding: 0 15px 0 15px; +} +dl.tabs dt h3 { + padding: 0; + font-size: 100%; +} +ul.helpmenu li { + float: right; + margin: 10px; + padding: 0; + list-style-type: none; + font-weight: bold; +} +#menu { + position: relative; + z-index: 100; + padding: 0; + margin: 0; + width: 100%; + list-style: none; + font-size: 1.2em; + font-weight: bold; +} +#menu ul { + padding: 0; + margin: 0; + list-style: none; + font-size: 100%; +} +#menu ul li.separator { + margin-bottom: 1em; +} +#menu a { + padding: 0.35em 2.5em 0.35em 2em; + vertical-align: middle; + display: block; + text-decoration: none; + font-size: 100%; +} +#menu li { + float: left; + font-size: 100%; +} +#menu li a { + white-space: nowrap; +} +#menu li li a { + margin-bottom: 1px; + margin-top: 1px; + width: 10em; +} +#menu li.disabled a:hover, +#menu li.disabled a:focus, +#menu li.disabled a { + cursor: default; +} +#menu li ul { + position: absolute; + width: 16em; + margin-left: -1000em; +} +#menu li li { + border: none; + width: 16em; +} +#menu li ul ul { + margin: -2.3em 0 0 -1000em; +} +#menu li:hover ul ul, +#menu li.sfhover ul ul { + margin-left: -1000em; +} +#menu li:hover ul, +#menu li.sfhover ul { + margin-left: 0; +} +#menu li li:hover ul, +#menu li li.sfhover ul { + margin-left: 16em; +} +[class^="menu-"], +[class*=" menu-"] { + background-position: 3px 50% !important; +} +.menu-archive { + background-image: url(../images/menu/icon-16-archive.png); +} +.menu-article { + background-image: url(../images/menu/icon-16-article.png); +} +.menu-associations { + background-image: url(../images/menu/icon-16-assoc.png); +} +.menu-banners { + background-image: url(../images/menu/icon-16-banner.png); +} +.menu-banners-clients { + background-image: url(../images/menu/icon-16-banner-client.png); +} +.menu-banners-tracks { + background-image: url(../images/menu/icon-16-banner-tracks.png); +} +.menu-banners-cat { + background-image: url(../images/menu/icon-16-banner-categories.png); +} +.menu-category { + background-image: url(../images/menu/icon-16-category.png); +} +.menu-checkin { + background-image: url(../images/menu/icon-16-checkin.png); +} +.menu-clear { + background-image: url(../images/menu/icon-16-clear.png); +} +.menu-component { + background-image: url(../images/menu/icon-16-component.png); +} +.menu-config { + background-image: url(../images/menu/icon-16-config.png); +} +.menu-contact { + background-image: url(../images/menu/icon-16-contacts.png); +} +.menu-contact-cat { + background-image: url(../images/menu/icon-16-contacts-categories.png); +} +.menu-content { + background-image: url(../images/menu/icon-16-content.png); +} +.menu-cpanel { + background-image: url(../images/menu/icon-16-cpanel.png); +} +.menu-default { + background-image: url(../images/menu/icon-16-default.png); +} +.menu-featured { + background-image: url(../images/menu/icon-16-featured.png); +} +.menu-fields { + background-image: url(../images/menu/icon-16-puzzle.png); +} +.menu-groups { + background-image: url(../images/menu/icon-16-groups.png); +} +.menu-help { + background-image: url(../images/menu/icon-16-help.png); +} +.menu-help-this { + background-image: url(../images/menu/icon-16-help-this.png); +} +.menu-help-forum { + background-image: url(../images/menu/icon-16-help-forum.png); +} +.menu-help-docs { + background-image: url(../images/menu/icon-16-help-docs.png); +} +.menu-help-jed { + background-image: url(../images/menu/icon-16-help-jed.png); +} +.menu-help-jrd { + background-image: url(../images/menu/icon-16-help-jrd.png); +} +.menu-help-community { + background-image: url(../images/menu/icon-16-help-community.png); +} +.menu-help-security { + background-image: url(../images/menu/icon-16-help-security.png); +} +.menu-help-dev { + background-image: url(../images/menu/icon-16-help-dev.png); +} +.menu-help-shop { + background-image: url(../images/menu/icon-16-help-shop.png); +} +.menu-info { + background-image: url(../images/menu/icon-16-info.png); +} +.menu-install { + background-image: url(../images/menu/icon-16-install.png); +} +.menu-joomlaupdate { + background-image: url(../images/menu/icon-16-install.png); +} +.menu-language { + background-image: url(../images/menu/icon-16-language.png); +} +.menu-levels { + background-image: url(../images/menu/icon-16-levels.png); +} +.menu-logout { + background-image: url(../images/menu/icon-16-logout.png); +} +.menu-maintenance { + background-image: url(../images/menu/icon-16-maintenance.png); +} +.menu-massmail { + background-image: url(../images/menu/icon-16-massmail.png); +} +.menu-media { + background-image: url(../images/menu/icon-16-media.png); +} +.menu-menu { + background-image: url(../images/menu/icon-16-menu.png); +} +.menu-menumgr { + background-image: url(../images/menu/icon-16-menumgr.png); +} +.menu-messages { + background-image: url(../images/menu/icon-16-messaging.png); +} +.menu-messages-add { + background-image: url(../images/menu/icon-16-new-privatemessage.png); +} +.menu-messages-read { + background-image: url(../images/menu/icon-16-messages.png); +} +.menu-module { + background-image: url(../images/menu/icon-16-module.png); +} +.menu-newarticle { + background-image: url(../images/menu/icon-16-newarticle.png); +} +.menu-newcategory { + background-image: url(../images/menu/icon-16-newcategory.png); +} +.menu-newgroup { + background-image: url(../images/menu/icon-16-newgroup.png); +} +.menu-newlevel { + background-image: url(../images/menu/icon-16-newlevel.png); +} +.menu-newuser { + background-image: url(../images/menu/icon-16-newuser.png); +} +.menu-plugin { + background-image: url(../images/menu/icon-16-plugin.png); +} +.menu-profile { + background-image: url(../images/menu/icon-16-user.png); +} +.menu-purge { + background-image: url(../images/menu/icon-16-purge.png); +} +.menu-readmess { + background-image: url(../images/menu/icon-16-readmess.png); +} +.menu-section { + background-image: url(../images/menu/icon-16-section.png); +} +.menu-static { + background-image: url(../images/menu/icon-16-static.png); +} +.menu-stats { + background-image: url(../images/menu/icon-16-stats.png); +} +.menu-themes { + background-image: url(../images/menu/icon-16-themes.png); +} +.menu-trash { + background-image: url(../images/menu/icon-16-trash.png); +} +.menu-user { + background-image: url(../images/menu/icon-16-user.png); +} +.menu-user-note { + background-image: url(../images/menu/icon-16-user-note.png); +} +.menu-delete { + background-image: url(../images/menu/icon-16-delete.png); +} +.menu-help-trans { + background-image: url(../images/menu/icon-16-help-trans.png); +} +.menu-newsfeeds { + background-image: url(../images/menu/icon-16-newsfeeds.png); +} +.menu-newsfeeds-cat { + background-image: url(../images/menu/icon-16-newsfeeds-cat.png); +} +.menu-redirect { + background-image: url(../images/menu/icon-16-redirect.png); +} +.menu-search { + background-image: url(../images/menu/icon-16-search.png); +} +.menu-finder { + background-image: url(../images/menu/icon-16-search.png); +} +.menu-weblinks { + background-image: url(../images/menu/icon-16-links.png); +} +.menu-weblinks-cat { + background-image: url(../images/menu/icon-16-links-cat.png); +} +.menu-tags { + background-image: url(../images/menu/icon-16-tags.png); +} +.menu-postinstall { + background-image: url(../images/menu/icon-16-generic.png); +} +.icon-32-cog { + background-image: url(../images/toolbar/icon-32-cog.png); +} +#menu li a:focus+ul { + margin-left: 0; +} +#menu li li a:focus+ul { + margin-left: 1016em; +} +#menu li li a:focus { + margin-left: 1000em; + width: 10em; +} +#menu li li li a:focus { + margin-left: 2016em; + width: 10em; +} +#menu li:hover a:focus, +#menu li.sfhover a.sffocus { + margin-left: 0; +} +#menu li li:hover a:focus+ul, +#menu li li.sfhover a.sffocus+ul { + margin-left: 16em; +} +#sidebar { + float: left; + margin: 15px 5px; +} +#submenu { + list-style: none; + padding: 0; + margin: 0; + padding-bottom: 2.5em; + line-height: 2em; +} +#submenu ul, +#submenu li { + display: inline; + list-style-type: none; + margin: 0; + padding: 0; +} +#submenu li, +#submenu span.nolink { + float: left; + font-weight: bold; + margin-right: 8px; + padding: 2px 10px 2px 10px; + text-decoration: none; + cursor: pointer; + -moz-border-radius-topright: 3px; + -moz-border-radius-topleft: 3px; + -webkit-border-top-right-radius: 3px; + -webkit-border-top-left-radius: 3px; + border-top-right-radius: 3px; + border-top-left-radius: 3px; +} +#submenu span.nolink { + color: #999; +} +#submenu li.active, +#submenu span.nolink.active { + cursor: default; +} +#submenu li.active a, +#submenu span.nolink.active, +#submenu li a:hover, +#submenu li a:focus { + text-decoration: none; +} +.red { + font-weight: bold; + color: #c00; +} +.pre_message { + font-size: 1.3em; +} +span.update-badge { + background-image: -moz-linear-gradient(center bottom,#FF0000 41%,#FC7E7E 79%); + background-image: -webkit-gradient(linear,left bottom,left top,color-stop(0.41,#ff0000),color-stop(0.79,#fc7e7e)); + border: 2px solid white; + border-radius: 1.5em 1.5em 1.5em 1.5em; + color: white; + display: block; + float: left; + font-size: 1.2em; + font-weight: bold; + height: 1.2em; + left: 60px; + min-width: 1em; + padding: 0 0.1em 0; + position: relative; + top: -88px; +} +.unotes ul, +.unotes ol { + list-style: none; + list-style-position: inside; + padding-left: 0; + padding-right: 0; +} +.unotes div.utitle { + padding: 10px; + float: left; + font-size: 1.2em; + line-height: 1.2em; +} +.unotes h4 { + margin-top: 0; + margin-bottom: 0; + font-size: 1.3em; +} +.unotes .ubody { + padding-left: 10px; + padding-right: 10px; + font-size: 1.2em; + line-height: 1.5em; +} +.unotes p { + padding-bottom: 10px; +} +div#database-sliders { + margin: 10px; +} +fieldset.uploadform { + margin-top: 10px; + margin-bottom: 10px; + min-height: 200px; +} +#installer-database, +#installer-discover, +#installer-update, +#installer-warnings { + margin-top: 10px; +} +#installer-database #sidebar { + float: none; +} +#installer-database p.warning { + padding-left: 20px; +} +#installer-database p.nowarning { + padding-left: 20px; +} +.joomlaupdate_spinner { + float: left; + margin-right: 15px; +} +.btn-group { + position: relative; + display: inline-block; +} +.btn-group + .btn-group { + margin-left: 5px; +} +.btn-group > .btn { + position: relative; + float: left; + margin-left: -1px; +} +.icon-48-cpanel { + height: 50px; + width: 50%; +} +.well { + min-height: 20px; + padding: 19px; + margin-bottom: 20px; + background-color: #f5f5f5; + border: 1px solid #eee; + border: 1px solid rgba(0,0,0,0.05); + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,0.05); + -moz-box-shadow: inset 0 1px 1px rgba(0,0,0,0.05); + box-shadow: inset 0 1px 1px rgba(0,0,0,0.05); +} +.well blockquote { + border-color: #ddd; + border-color: rgba(0,0,0,0.15); +} +.well-large { + padding: 24px; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} +.well-small { + padding: 9px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} +.list-striped, +.row-striped { + list-style: none; + line-height: 18px; + text-align: left; + vertical-align: middle; + border-top: 1px solid #dddddd; + margin-left: 0; + font-size: 1.2em; + padding: 9px; +} +.list-striped li, +.list-striped dd, +.row-striped .row, +.row-striped .row-fluid { + border-bottom: 1px solid #dddddd; + padding: 8px; +} +.list-striped li:nth-child(odd), +.list-striped dd:nth-child(odd), +.row-striped .row:nth-child(odd), +.row-striped .row-fluid:nth-child(odd) { + background-color: #f9f9f9; +} +.list-striped li:hover, +.list-striped dd:hover, +.row-striped .row:hover, +.row-striped .row-fluid:hover { + background-color: #f5f5f5; +} +.row-striped .row-fluid { + width: 100%; + box-sizing: border-box; +} +.row-striped .row-fluid [class*="span"] { + min-height: 10px; +} +.alert { + padding: 8px 35px 8px 14px; + margin-bottom: 18px; + text-shadow: 0 1px 0 rgba(255,255,255,0.5); + background-color: #fcf8e3; + border: 1px solid #fbeed5; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + color: #c09853; + font-size: 120%; +} +.alert-heading { + color: inherit; +} +.alert .close { + position: relative; + right: -30px; + top: -5px; + line-height: 18px; + float: right; + font-size: 20px; + font-weight: bold; +} +.alert-success { + background-color: #dff0d8; + border-color: #d6e9c6; + color: #468847; +} +.alert-danger, +.alert-error { + background-color: #f2dede; + border-color: #eed3d7; + color: #b94a48; +} +.alert-info { + background-color: #d9edf7; + border-color: #bce8f1; + color: #3a87ad; +} +.alert-block { + padding-top: 14px; + padding-bottom: 14px; +} +.alert-block > p, +.alert-block > ul { + margin-bottom: 0; +} +.alert-block p + p { + margin-top: 5px; +} +.btn-group > .btn:hover, +.btn-group > .btn:focus, +.btn-group > .btn:active, +.btn-group > .btn.active { + z-index: 2; +} +.btn-group > .btn { + position: relative; + float: left; + margin-left: -1px; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +table { + max-width: 100%; + background-color: transparent; + border-collapse: collapse; + border-spacing: 0; +} +.table { + width: 100%; + margin-bottom: 18px; +} +.tab-content > .tab-pane, +.pill-content > .pill-pane { + display: none; +} +.tab-content > .active, +.pill-content > .active { + display: block; +} +.tabs-below > .nav-tabs { + border-top: 1px solid #ddd; +} +#status .btn-toolbar, +#status p { + margin: 0px; +} +.navbar .btn-group { + margin: 0; + padding: 5px 5px 6px; +} +.media .btn { + margin: 10px 20px; +} +.thumbnails > li { + list-style: none outside none; + float: left; + margin-bottom: 18px; + margin-left: 20px; +} +#mediamanager-form { + margin: 10px; +} +.is-tagbox { + float: left; +} +.item-associations { + margin: 0; +} +.item-associations li { + list-style: none; + display: inline-block; + margin: 0 0 3px 0; +} +.item-associations li a, +table.adminlist .item-associations li a { + color: #ffffff; +} +.hidden { + display: none; + visibility: hidden; +} +.tooltip { + position: absolute; + z-index: 1030; + display: block; + visibility: visible; + font-size: 11px; + line-height: 1.4; + opacity: 0; + filter: alpha(opacity=0); +} +.tooltip.in { + opacity: 0.8; + filter: alpha(opacity=80); +} +.tooltip.top { + margin-top: -3px; + padding: 5px 0; +} +.tooltip.right { + margin-left: 3px; + padding: 0 5px; +} +.tooltip.bottom { + margin-top: 3px; + padding: 5px 0; +} +.tooltip.left { + margin-left: -3px; + padding: 0 5px; +} +.tooltip-inner { + max-width: 200px; + padding: 8px; + color: #ffffff; + text-align: center; + text-decoration: none; + background-color: #000000; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} +.tooltip-arrow { + position: absolute; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; +} +.tooltip.top .tooltip-arrow { + bottom: 0; + left: 50%; + margin-left: -5px; + border-width: 5px 5px 0; + border-top-color: #000000; +} +.tooltip.right .tooltip-arrow { + top: 50%; + left: 0; + margin-top: -5px; + border-width: 5px 5px 5px 0; + border-right-color: #000000; +} +.tooltip.left .tooltip-arrow { + top: 50%; + right: 0; + margin-top: -5px; + border-width: 5px 0 5px 5px; + border-left-color: #000000; +} +.tooltip.bottom .tooltip-arrow { + top: 0; + left: 50%; + margin-left: -5px; + border-width: 0 5px 5px; + border-bottom-color: #000000; +} +.tooltip { + max-width: 400px; +} +.tooltip-inner { + max-width: none; + text-align: left; + text-shadow: none; +} +th .tooltip-inner { + font-weight: normal; +} +.tooltip.hasimage { + opacity: 1; +} +fieldset.panelform .tooltip img { + float: none; + margin: 0; +} +div.toggle-editor { + float: right; +} +.text-left { + text-align: left; +} +.text-right { + text-align: right; +} +.text-center { + text-align: center; +} +.module-edit { + display: inline-block; +} +.break-word { + word-break: break-all; + word-wrap: break-word; +} +.muted { + color: #999; +} +.popover-content { + min-height: 33px; +} diff --git a/Sites/pages/administrator/templates/hathor/css/template_rtl.css b/Sites/pages/administrator/templates/hathor/css/template_rtl.css new file mode 100644 index 00000000..d126ff0b --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/css/template_rtl.css @@ -0,0 +1,1325 @@ +@charset "UTF-8"; + +/** + * @package Joomla.Administrator + * @subpackage templates.hathor + * @copyright Copyright (C) 2005 - 2020 Open Source Matters, Inc. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + * @since 1.6 + * + * RTL CSS file for the template + */ + +body { + direction: rtl; +} + +h1, h2, h3 { + text-align: right; +} + +/** + * CSS Reset + */ + +html, body, div, span, applet, object, iframe, +h1, h2, h3, h4, h5, h6, p, blockquote, pre, +a, abbr, acronym, address, big, cite, code, +del, dfn, em, font, img, ins, kbd, q, s, samp, +small, strike, strong, sub, sup, tt, var, +b, u, i, center, +dl, dt, dd, ol, ul, li, +fieldset, form, label, legend, +table, caption, tbody, tfoot, thead, tr, th, td { + background-position: transparent none repeat scroll top right; +} + +/* new styles */ + + + +/* end new styles */ + +/** + * Overall Styles + */ +#header h1.title { + padding: 0 120px 0 0; +} + +#footer { + padding: 10px 20px; +} + +#content { + margin: 5px 20px 20px 20px; +} + +.cpanel-page div#element-box { + padding: 15px; +} + +/** + * Status layout + */ +#module-status { + left: 0; + right: none; + float: left; +} + +#module-status > span { + float: right; + padding: 4px 22px 0 20px; +} + +/* background images moved to color css file */ + +/** + * Various Styles + */ + +div.checkin-tick { + text-indent: -9999px; +} + +/** + * Overlib + */ + +/** + * Subheader, toolbar, page title + */ + +div.pagetitle { + padding: 0 0 5px 0; + background-position: right 50%; + line-height: 54px; +} + +.pagetitle h2 { + padding: 0 50px 0 0; +} + +div.configuration { + padding-right: 30px; + margin-right: 10px; +} + +div.toolbar-list { + float: right; + text-align: left; +} + +div.toolbar-list li { + padding: 5px 4px 5px 1px; + float: right; +} + +div.toolbar-list li.divider { + margin-left: 10px; + margin-right: 0; +} + +div.toolbar-list span { + margin: 0 auto; +} + +div.toolbar-list a { + float: right; + padding: 1px 5px; +} + +/** + * Massmail component + */ + + +/** + * Pane Slider pane Toggler styles + */ +div.pane-sliders { + margin-left: 10px; +} + +.pane-toggler span { + padding-left: 0; + padding-right: 20px; +} + +.pane-toggler-down span { + padding-right: 20px; + padding-left: 0; +} + +div#position-icon.pane-sliders div.pane-down .icon-wrapper .icon { + padding: 5px 10px 5px 0; + margin: 0; +} + +/** + * Tabs + */ +dl.tabs { + float: right; + margin: 10px 0 -1px 0; +} + +dl.tabs dt { + float: right; + padding: 4px 10px; + margin-right: 3px; +} + +div.current { + padding: 10px 10px; +} + +/* New parameter styles (check rtl) */ + +dl#content-pane.tabs { + margin: 1px 0 0 0; +} + +div.current label, div.current span.faux-label { + float:right; + clear:right; +} + +div.current fieldset.radio { + float:right; +} + +div.current fieldset.radio input { + float:right; + margin: 3px 2px 0 0; +} + +div.current fieldset.radio label { + float:right; + margin: 3px 2px 0 0; +} + +div.current fieldset.checkboxes { + float:right; + clear:left; +} + +div.current fieldset.checkboxes input { + float:right; + clear:right; + margin: 3px 2px 0 0; +} + +div.current fieldset.checkboxes label { + clear:left; + margin: 3px 2px 0 0; +} + +div.current input, +div.current span.faux-input, +div.current textarea, +div.current select { + float:right; + margin: 3px 2px 0 0; +} + +div.current table#acl-config th.acl-groups { + text-align: right; +} + +div.current table#filter-config th.acl-groups { + text-align: right; +} + +/* -------- Menu Assignments ---------- */ +div#menu-assignment { + clear:right; +} + +div#menu-assignment ul.menu-links { + float:right; +} + +div#menu-assignment h3 { + clear:right; +} + +div#menu-assignment ul.menu-links li.menu-link label { + float: right; + margin: 3px 2px 0 0; +} +div#menu-assignment ul.menu-links li.menu-link input { + clear: right; + float: right; +} + +p.tab-description { + margin-right: 0; +} +/* end new parameter styles */ + +/** + * Login Settings + */ +#login-page input, #login-page select { + float: left; +} + +#login-page .login { + margin: 0 auto; +} + +#login-page .pagetitle h2 { + margin: -70px 0 30px 0; +} + +#login-page .login-inst { + float: right; +} + +#login-page .login-box { + float: left; +} + +#login-page .button { + text-align: left; +} + +#login-page .login-text { + text-align: right; + float: right; +} + +#form-login { + float: left; +} + +#form-login label { + float: right; + clear: right; + text-align: left; +} + +#form-login div.button1 div.next { + float: right; +} + +#form-login div.button1 a { + padding: 0 15px 0 15px; + /* padding: 0 6px 0 30px; use this if you use images */ +} + +/** + * Cpanel Settings + */ +.cpanel div.icon , +#cpanel div.icon { + margin-left: 5px; + float: right; +} + +.cpanel div.icon a , +#cpanel div.icon a { + float: right; +} + +.cpanel img , +#cpanel img { + padding: 10px 0; + margin: 0 auto; +} + +div.cpanel-icons { + float: right; +} + +div.cpanel-component { + float: left; +} + +/** + * Standard Layout Styles + */ +div.col { + float: right; +} + +div.options-section.col { + float: left; +} + +div.col1 { + float: right; +} + +div.col2 { + float: left; +} + + /* Avoid using the width divs. They are here for 3PD Extensions if needed + * Use the specific layout divs listed after. See also the th.width entries */ +.clrlft { clear: right; } +.clrrt { clear: left; } +.fltlft { float: right; } +.fltrt { float: left; } +.fltnone { float: none; } + + /* Layout Divs */ +div.options-section { + margin: 10px 0 10px 10px; +} + +/* for bluestork style html */ +div.width-40.fltrt { + margin: 10px 0 10px 10px; +} + +/** + * Form Styles + */ + +fieldset { + margin: 2px 10px 2px 10px; + text-align: right; +} + +fieldset p { + margin: 10px 0; +} + +/* new form fields (check rtl) */ + +fieldset.adminform fieldset.radio, +fieldset.panelform fieldset.radio, +fieldset.adminform-legacy fieldset.radio { + float:right; + margin: 0 0 5px 0; + clear:left; +} +fieldset.adminform fieldset.radio label, +fieldset.panelform fieldset.radio label, +fieldset.adminform fieldset.radio span.faux-label, +fieldset.panelform fieldset.radio span.faux-label { + float:right; +} + +fieldset.panelform-legacy label, +fieldset.adminform-legacy label, +fieldset.panelform-legacy span.faux-label, +fieldset.adminform-legacy span.faux-label { + float:right; + +} +/* JParameter classes on radio button labels */ + +p.jform_desc { + clear: right; +} + +fieldset ul.checklist { + margin-right: 27px; + margin-left: 0; +} + +fieldset#filter-bar { + margin: 0; + padding: 5px 10px 5px 10px; +} + +fieldset#filter-bar ol, fieldset#filter-bar ul { + padding: 5px 0 0; +} + +fieldset#filter-bar ol li, fieldset#filter-bar ul li { + float: right; + padding: 0 0 0 5px; +} + +fieldset#filter-bar .filter-search { + float: right; +} + +fieldset#filter-bar .filter-select { + float: left; +} + + + /* Note: these visual cues should be augmented by aria */ + + /* must be augmented by aria at the same time if changed dynamically by js + aria-invalid=true or aria-invalid=false */ + + + /* augmented by aria in template javascript */ + +span.readonly { + float: right; +} + +div.extdescript { + margin-right: 10px; +} + +input[type="button"] { + padding: 1px 6px; +} + +/** + * Option or Parameter styles + */ + + +/* end from alpha2 */ + +span.gi { + margin-left: 5px; +} + +/** + * Admintable Styles + */ + +table.admintable td.key,table.admintable td.paramlist_key { + text-align: left; +} + +table.paramlist td.paramlist_description { + text-align: right; +} + +/** + * Admin Form Styles + */ +fieldset.adminform { + margin: 0 10px 10px 10px; +} +fieldset.adminform .input-prepend, +fieldset.adminform .input-append, +fieldset.panelform .input-prepend, +fieldset.panelform .input-append { + float: right; +} +fieldset.adminform .adminformlist .btn.modal, +fieldset.adminform .input-prepend > *, +fieldset.adminform .input-append > *, +fieldset.panelform .adminformlist .btn.modal, +fieldset.panelform .input-prepend > *, +fieldset.panelform .input-append > * { + float: none; + vertical-align: middle; +} + + /* Table styles are for use with tabular data */ +table.adminform { + margin: 8px 0 10px 0; +} + + +table.adminform th { + padding: 6px 4px 4px 2px; + text-align: right; +} + +table.adminform td { + text-align: right; +} + +table.adminform td#filter-bar { + text-align: right; +} + +table.adminform td.helpMenu { + text-align: left; +} + +table.adminform tr { + padding-right: 10px; + padding-left: 10px; + border-left: 1px solid #c7c8b2; + border-right: none; +} + +/** + * Table formatting styles + */ + + /* Avoid using the width classes. They are here for 3PD Extensions if needed + * Use the specific layout table headers listed after. See also the div.width entries */ + + /* Table header layout classes */ + +th.ordering-col a { + float:right; + margin-right: 3px; +} + +th.ordering-col a img { + margin-right: 4px; + margin-left: 4px; +} + +/** + * Adminlist Table layout + */ +table.adminlist { + float: right; +} + /* Table row styles */ +table.adminlist tr { + padding-left: 30px; + padding-right: 30px; +} + +table.adminlist tbody tr { + text-align: right; +} + + /* Table td/th styles */ +table.adminlist td.order span { + float: right; +} + +/** + * Tree indentation & nesting - Up to 10 levels deep so don't go crazy : + */ +table.adminlist td.indent-4 { padding-right:4px; } +table.adminlist td.indent-19 { padding-right:19px; } +table.adminlist td.indent-34 { padding-right:34px; } +table.adminlist td.indent-49 { padding-right:49px; } +table.adminlist td.indent-64 { padding-right:64px; } +table.adminlist td.indent-79 { padding-right:79px; } +table.adminlist td.indent-94 { padding-right:94px; } +table.adminlist td.indent-109 { padding-right:109px; } +table.adminlist td.indent-124 { padding-right:124px; } +table.adminlist td.indent-139 { padding-right:139px; } + +/** + * Adminlist buttons + */ +table.adminlist tr td.btns a { + padding: 3px 20px; +} + +/** + * Modal Modules styles + */ +ul#new-modules-list { + margin-right: 50px; + margin-left: 0; +} + +/** + * Utility styles + */ + /* General Clearing Class */ +.menu-module-list { + padding-right: 10px; + margin-right: 5px; +} + + /* stu nicholls solution for centering divs */ + + /* table solution for global config */ + +table.noshow fieldset { + margin: 15px 7px 7px 7px; +} + +/** + * Saving order icon styling in admin tables + */ +a.saveorder { + float:left; + margin-left: 8px; +} + +/** + * Button styling + */ +#editor-xtd-buttons { + padding: 5px; +} + +/* Button 1 Type */ +.button1,.button1 div { + float: left; +} + + /* Use this if you add images to the buttons such as directional arrows */ + +.button1 a { + float: right; + padding: 0 6px 0 6px; +} + + /* Button 2 Type */ +.button2-left,.button2-right { + float: right; +} + +.button2-left a, +.button2-right a, +.button2-left span, +.button2-right span { + float: right; +} + + /* these are inactive buttons */ + +.button2-left .page a, +.button2-right .page a, +.button2-left .page span, +.button2-right .page span, +.button2-left .blank a, +.button2-right .blank a, +.button2-left .blank span, +.button2-right .blank span { + padding: 0 6px; +} + +.button2-left a,.button2-left span { + padding: 0 6px 0 24px; +} + +.button2-right a,.button2-right span { + padding: 0 24px 0 6px; +} + +.button2-left { + float: right; + margin-right: 5px; +} + +.button2-right { + float: right; + margin-right: 5px; +} + +/* background images moved to the color rtl css file */ + +/** + * Pagination styles + */ + + /* Normal pagination styles */ +div.containerpg { + position: relative; + right: 50%; + float: right; + clear: right; +} + +div.pagination { + right: -50%; + margin: 0 auto; +} + +.pagination a { + line-height: 1.6em; +} + +.pagination div.limit { + float: right; + margin: 0 10px; +} + + /* The Go submittal button */ +.pagination button { + margin-left: 20px; +} + + /* Style if pagination is part of the table (old style) */ +table.adminlist .pagination { + margin: 0 auto; +} + +table.adminlist .pagination button { + margin-left: 20px; +} + +/** + * Pagination styles + */ + + /* Normal pagination styles */ +div.containerpg { + right: 50%; + float: right; + clear: right; +} + +div.pagination { + right: -50%; + margin: 0 auto; +} + +.pagination div.limit { + float: right; + margin: 0 10px; +} + + /* The Go submittal button */ +.pagination button { + margin-left: 20px; +} + + + /* Grey out the current page number */ + + + /* Style if pagination is part of the table (old style) */ + +table.adminlist .pagination button { + margin-left: 20px; +} + +/** + * MCE Editor + */ +div.toggle-editor { + +} + +/** + * Tooltips + */ + +.tip-text { + text-align: right; +} + +/** + * Calendar + */ +a img.calendar { + margin-right: 3px; +} + +/** + * General styles + */ + +.helpFrame { + padding: 0 10px 0 5px; +} + +#treecellhelp { + float: right; +} + +#datacellhelp { + float: right; + padding: 2px 0 0 0; +} + +/* -- MODAL STYLES ----------- */ +div#sbox-window { + text-align: right; +} + +h2.modal-title { + margin: 5px 15px 0 0; +} + +ul.menu_types { + padding: 0 15px 0 0; +} +ul.menu_types li, +dl.menu_type dd ul li { + float:right; + margin-left: 10px; + margin-right: 0; +} + +dl.menu_type dt { + float:right; + margin: 13px 0 5px 0; +} +dl.menu_type dd { + clear:right; +} + +dl.menu_type dd ul li { + margin: 0; +} + +dl.menu_type dd ul { + margin: 0; +} + +ul#new-modules-list { + padding: 5px 15px 0 0; + margin: 0; +} +ul#new-modules-list li { + float:right; + margin: 0 0 0 20px; +} + +/** + * User Accessibility + */ + + /* Skip to Content Structural Styling */ +#skiplinkholder a, +#skiplinkholder a:link, +#skiplinkholder a:visited { + left: 0; + right: -200%; +} + +#skiplinkholder a:focus, #skiplinkholder a:active { + right: 0; + top: 0; +} + +#skiplinkholder p { + margin: 0; +} + +#skiptargetholder { + left: 0; + right: -200%; +} + + /* Skip to Content Visual Styling */ +#skiplinkholder a, #skiplinkholder a:link, #skiplinkholder a:visited { + padding-left: 20px; + padding-right: 20px; +} + + /* For elements that aren't to be seen by users unless the user does something + * like clicking on a header to see the collapsed section. */ + + /* For elements that aren't to be seen by visual users but do need to be read by screenreaders. + * Cannot be used for elements that can get focus such as links and form elements */ + + /* Firefox has issues styling legend so this is a universal fix + for making the legend invisible (i.e. visually it's not there, but screen readers see it */ + +legend.element-invisible { + /*margin: 0; + margin-right: -10000px; */ +} + +fieldset.adminform label, +fieldset.panelform label, +fieldset.adminform span.faux-label, +fieldset.panelform span.faux-label { + clear:right; + float:right; + margin-right: 10px; + margin-left: 5px; +} + +fieldset.adminform fieldset.radio label, +fieldset.panelform fieldset.radio label, +fieldset.adminform fieldset.radio span.faux-label, +fieldset.panelform fieldset.radio span.faux-label { + margin-right: 0; +} + +/* checkboxes */ +fieldset.adminform fieldset.checkboxes, +fieldset.panelform fieldset.checkboxes, +fieldset.adminform-legacy fieldset.checkboxes { + float:right; + margin: 0 0 5px 0; + clear:left; +} + +fieldset.adminform fieldset.checkboxes input[type="checkbox"], +fieldset.panelform fieldset.checkboxes input[type="checkbox"] { + float: right; + clear: right; +} + +fieldset.adminform fieldset.checkboxes label, +fieldset.panelform fieldset.checkboxes label, +fieldset.adminform fieldset.checkboxes span.faux-label, +fieldset.panelform fieldset.checkboxes span.faux-label { + clear: left; +} +/* end checkboxes */ + +fieldset.adminform input, fieldset.adminform span.faux-input, fieldset.adminform textarea, fieldset.adminform select, fieldset.adminform img, fieldset.adminform button, +fieldset.panelform input, fieldset.panelform span.faux-input, fieldset.panelform textarea, fieldset.panelform select, fieldset.panelform img, fieldset.panelform button { + float:right; + margin:5px 0 5px 5px; +} + +/* -------- Batch Section ---------- */ +fieldset#batch-choose-action { + clear:none; + clear: right; +} +fieldset.batch label { + float: right; + clear: none; +} +fieldset label#batch-choose-action-lbl { + clear: none; + clear: right; +} +label#batch-language-lbl, +label#batch-user-lbl { + clear: right; + margin-left: 10px; + margin-right: 0; + margin-top: 15px; +} +select#batch-language-id, +select#batch-user-id { + margin-top: 15px; +} +select#batch-category-id, +select#batch-menu-id, +select#batch-position-id +{ + margin-left: 30px; + margin-right: 0; +} +fieldset.batch select, fieldset.batch input, fieldset.batch img, fieldset.batch button { + float: right; +} +label#batch-access-lbl, +label#batch-client-lbl { + margin-right: 0; + margin-left: 10px; +} + +/* Banner edit */ + + +/* -- ACL STYLES relocated from com_users/media/grid.css ----------- */ + +/* -- ACL PANEL STYLES ----------- */ + + +/* All Tabs */ + +td.col1 { + text-align:right; +} + +/* Icons */ +label.icon-16-allow, +label.icon-16-deny, +a.icon-16-allow, +a.icon-16-deny, +a.icon-16-allowinactive, +a.icon-16-denyinactive { + margin: 0 auto; +} +label.icon-16-allow { + right: 40%; +} +label.icon-16-deny { + right: 40%; +} + +ul.acllegend li { + float: right; + padding-left: 20px; + margin: 15px 10px 15px 0; +} +ul.acllegend li.acl-allowed { + padding-right: 20px; + padding-left: 10px; +} +ul.acllegend li.acl-denied { + padding-right: 20px; + padding-left: 20px; +} +ul.acllegend li.acl-editgroups { + padding-left: 10px; +} +ul.acllegend li.acl-resetbtn { + padding-left: 0; +} + +li.acl-editgroups, +li.acl-resetbtn { + float: right; +} + +table#acl-config th.acl-groups { + padding-right: 8px; +} + +table#acl-config th.acl-groups { + text-align: right; +} + +.acl-action { + margin: auto 0; +} + +/* Icons */ +span.icon-16-unset, +span.icon-16-allowed, +span.icon-16-denied, +span.icon-16-locked { + padding-left: 0; + padding-right: 18px; +} + +/* * +* Permission Rules +*/ + +#permissions-sliders ul#rules, +#permissions-sliders ul#rules ul { + margin: 0 !important; + padding: 0 !important; +} + +#permissions-sliders ul#rules li { + margin: 0; + padding: 0; +} + +#permissions-sliders ul#rules table.group-rules td { + padding:4px; + vertical-align:middle; + text-align:right; +} + +#permissions-sliders .panel { + margin-bottom: 3px; + margin-right: 0; +} + +ul#rules table.group-rules td label { + margin: 0 !important; +} + +table.group-rules td select { + margin: 0 !important; +} + +#permissions-sliders ul#rules .mypanel { + padding: 0; +} + +#permissions-sliders ul#rules { + padding: 5px; +} + +#permissions-sliders ul#rules table.group-rules th { + text-align: right; + padding: 4px; +} + +#permissions-sliders .pane-toggler span { + padding-left: 0; + padding-right: 20px; +} + +#permissions-sliders .pane-toggler-down span { + padding-left: 0; + padding-right: 20px; +} + +/** + * Helpmenus + */ +ul.helpmenu li { + float: left; +} + +/** + * Menu Styling + */ +#menu a { + padding: 0.35em 2em 0.35em 2.5em; +} + +#menu li { + float: right; +} + +#menu li ul { /* second-level lists */ + margin-right: -1000em; + /* using right instead of display to hide menus because display: none isn't read by screen readers */ +} + +#menu li ul ul { /* third-and-above-level lists */ + margin: -2.3em -1000em 0 0; + /* top margin is equal to parent line height+bottom padding */ +} + +#menu li:hover ul ul,#menu li.sfhover ul ul { + margin-right: -1000em; +} + +#menu li:hover ul,#menu li.sfhover ul { + /* lists nested under hovered list items */ + margin-right: 0; +} + +#menu li li:hover ul,#menu li li.sfhover ul { + margin-right: 16em; +} + +/** + * Extra positioning rules for limited noscript keyboard accessibility + * need the backgrounds here to keep the background as the nav background + * since it is overlaying other content. + * Using margin-left instead of left so that can move back without javascript + * display downlevel ul + */ +#menu li a:focus+ul { + margin-right: 0; +} + +#menu li li a:focus+ul { + margin-right: 1016em; +} + +/* bring back the focus elements into view */ +#menu li li a:focus { + margin-right: 1000em; +} + +#menu li li li a:focus { + margin-right: 2016em; +} + +#menu li:hover a:focus,#menu li.sfhover a.sffocus { + margin-right: 0; +} + +#menu li li:hover a:focus+ul,#menu li li.sfhover a.sffocus+ul { + margin-right: 16em; +} + +/** + * Submenu styling + */ + + +#submenu a, #submenu span.nolink { + float: right; + margin-left: 8px; + padding: 2px 10px 2px 10px; + -moz-border-radius-topleft: 3px; + -moz-border-radius-topright: 3px; + -webkit-border-top-left-radius: 3px; + -webkit-border-top-right-radius: 3px; + border-top-left-radius: 3px; + border-top-right-radius: 3px; +} + +/* Installer Database */ +#installer-database p.warning { + padding-left: 0; + padding-right: 20px +} + +#installer-database #sidebar { + float: none +} + +#installer-database p.nowarning { + padding-left: 0; + padding-right: 20px +} + +p.nowarning { + float: none; + margin-left: 0; + margin-right: 15px; +} + +table.adminlist tfoot button { + float: right; +} + +/* Spinner */ +.joomlaupdate_spinner { + float: right; + margin-left: 15px; +} + +/* Various corrections */ +[class*="span"] { + float: none; + margin-left: 0; + margin-right: 0; +} + +#sidebar { + float:right; + margin: 15px 0; +} + +#submenu li, #submenu span.nolink { + float: right; +} + +div.btn-toolbar { + float: right; + text-align: right; +} + +.btn-group { + float: right; + margin-right: 10px; +} + +#module-status div.btn-group { + float: right; +} + +.nav-tabs > li, .nav-pills > li { + float: none; +} + +.tabs-left > .nav-tabs { + border-right: 0 solid #DDDDDD; + float: right; + margin-right: 19px; +} + +.list-striped, .row-striped { + text-align: right; +} + +.row-fluid [class*="span"] { + float: none; +} +.media .btn { + float: none; +} + +.media { + float:none; + margin: 10px 20px; +} + +.alert .close { + right: 5px; + float: left; +} + +.popover, +.tooltip-inner { + text-align: right; +} +div.toggle-editor { + float: left; +} +#editor-xtd-buttons .btn { + float: right; +} +div.toggle-editor { + margin-top: 14px; +} +.modal-footer button { + float: left; +} +#form-login { + float: right; +} \ No newline at end of file diff --git a/Sites/pages/administrator/templates/hathor/css/theme.css b/Sites/pages/administrator/templates/hathor/css/theme.css new file mode 100644 index 00000000..e7735d99 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/css/theme.css @@ -0,0 +1,297 @@ +@charset "UTF-8"; + +/** + * @package Joomla.Administrator + * @subpackage templates.hathor + * @copyright Copyright (C) 2005 - 2020 Open Source Matters, Inc. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + * @since 1.6 + */ + +/* ThemeOfficeMenu Style Sheet */ + +.ThemeOfficeMenu, +.ThemeOfficeSubMenuTable { + font-family: Arial, Verdana, sans-serif; + font-size: 13px; + padding: 0; + white-space: nowrap; + cursor: default; + height: 25px; +} + +.ThemeOfficeSubMenu { + position: absolute; + visibility: hidden; + /* + Netscape/Mozilla renders borders by increasing + their z-index. The following line is necessary + to cover any borders underneath + */ + z-index: 100; + border: 0; + padding: 0; + overflow: visible; + border: 1px solid #8C867B; + filter:progid:DXImageTransform.Microsoft.Shadow(color=#BDC3BD, Direction=135, Strength=4); +} + +.ThemeOfficeSubMenuTable { + overflow: visible; +} + +.ThemeOfficeMainItem, +.ThemeOfficeMainItemHover, +.ThemeOfficeMainItemActive, +.ThemeOfficeMenuItem, +.ThemeOfficeMenuItemHover, +.ThemeOfficeMenuItemActive { + border: 0; + cursor: default; + white-space: nowrap; +} + +.ThemeOfficeMainItem { + /*background-color: #EFEBDE;*/ +} + +.ThemeOfficeMainItemHover, +.ThemeOfficeMainItemActive { + background-color: #e7eddf; +} + +.ThemeOfficeMenuItem { + background-color: #F1F3F5; +} + +.ThemeOfficeMenuItemHover, +.ThemeOfficeMenuItemActive { + background-color: #e7eddf; +} + + +/* horizontal main menu */ + +.ThemeOfficeMainItem { + padding: 4px 1px 4px 1px; + border: 0; +} + +td.ThemeOfficeMainItemHover, +td.ThemeOfficeMainItemActive { + padding: 0; + border-right: 1px solid #6d9d2e; + border-left: 1px solid #6d9d2e; +} + +.ThemeOfficeMainFolderLeft, +.ThemeOfficeMainItemLeft, +.ThemeOfficeMainFolderText, +.ThemeOfficeMainItemText, +.ThemeOfficeMainFolderRight, +.ThemeOfficeMainItemRight { + background-color: inherit; +} + +/* vertical main menu sub components */ + +td.ThemeOfficeMainFolderLeft, +td.ThemeOfficeMainItemLeft { + padding-top: 2px; + padding-bottom: 2px; + padding-left: 0; + padding-right: 2px; + + border-top: 1px solid #6d9d2e; + border-bottom: 1px solid #6d9d2e; + border-left: 1px solid #6d9d2e; + + background-color: inherit; +} + +td.ThemeOfficeMainFolderText, +td.ThemeOfficeMainItemText { + padding-top: 2px; + padding-bottom: 2px; + padding-left: 5px; + padding-right: 5px; + + border-top: 1px solid #6d9d2e; + border-bottom: 1px solid #6d9d2e; + + background-color: inherit; + white-space: nowrap; +} + +td.ThemeOfficeMainFolderRight, +td.ThemeOfficeMainItemRight { + padding-top: 2px; + padding-bottom: 2px; + padding-left: 0; + padding-right: 0; + + border-top: 1px solid #6d9d2e; + border-bottom: 1px solid #6d9d2e; + border-right: 1px solid #6d9d2e; + + background-color: inherit; +} + +tr.ThemeOfficeMainItem td.ThemeOfficeMainFolderLeft, +tr.ThemeOfficeMainItem td.ThemeOfficeMainItemLeft { + padding-top: 3px; + padding-bottom: 3px; + padding-left: 1px; + padding-right: 2px; + white-space: nowrap; + border: 0; + background-color: inherit; +} + +tr.ThemeOfficeMainItem td.ThemeOfficeMainFolderText, +tr.ThemeOfficeMainItem td.ThemeOfficeMainItemText { + padding-top: 3px; + padding-bottom: 3px; + padding-left: 5px; + padding-right: 5px; + border: 0; + background-color: inherit; +} + +tr.ThemeOfficeMainItem td.ThemeOfficeMainItemRight, +tr.ThemeOfficeMainItem td.ThemeOfficeMainFolderRight { + padding-top: 3px; + padding-bottom: 3px; + padding-left: 0; + padding-right: 1px; + border: 0; + background-color: inherit; +} + +/* sub menu sub components */ + +.ThemeOfficeMenuFolderLeft, +.ThemeOfficeMenuItemLeft { + padding-top: 2px; + padding-bottom: 2px; + padding-left: 1px; + padding-right: 3px; + border-top: 1px solid #6d9d2e; + border-bottom: 1px solid #6d9d2e; + border-left: 1px solid #6d9d2e; + background-color: inherit; + white-space: nowrap; +} + +.ThemeOfficeMenuFolderText, +.ThemeOfficeMenuItemText { + padding-top: 2px; + padding-bottom: 2px; + padding-left: 5px; + padding-right: 5px; + + border-top: 1px solid #6d9d2e; + border-bottom: 1px solid #6d9d2e; + + background-color: inherit; + white-space: nowrap; +} + +.ThemeOfficeMenuFolderRight, +.ThemeOfficeMenuItemRight { + padding-top: 2px; + padding-bottom: 2px; + padding-left: 0; + padding-right: 0; + + border-top: 1px solid #6d9d2e; + border-bottom: 1px solid #6d9d2e; + border-right: 1px solid #6d9d2e; + background-color: inherit; + white-space: nowrap; +} + +.ThemeOfficeMenuItem .ThemeOfficeMenuFolderLeft, +.ThemeOfficeMenuItem .ThemeOfficeMenuItemLeft { + padding-top: 3px; + padding-bottom: 3px; + padding-left: 2px; + padding-right: 3px; + white-space: nowrap; + border: 0; + background-color: #DDE1E6; +} + +.ThemeOfficeMenuItem .ThemeOfficeMenuFolderText, +.ThemeOfficeMenuItem .ThemeOfficeMenuItemText { + padding-top: 3px; + padding-bottom: 3px; + padding-left: 5px; + padding-right: 5px; + border: 0; + background-color: inherit; +} + +.ThemeOfficeMenuItem .ThemeOfficeMenuFolderRight, +.ThemeOfficeMenuItem .ThemeOfficeMenuItemRight { + padding-top: 3px; + padding-bottom: 3px; + padding-left: 0; + padding-right: 1px; + border: 0; + background-color: inherit; +} + +/* menu splits */ + +.ThemeOfficeMenuSplit { + margin: 2px; + height: 1px; + overflow: hidden; + background-color: inherit; + border-top: 1px solid #C6C3BD; +} + +/* image shadow animation */ +/* + seq1: image for normal + seq2: image for hover and active + To use, in the icon field, input the following: + +*/ + +.ThemeOfficeMenuItem img.seq1 { + display: inline; +} + +.ThemeOfficeMenuItemHover seq2, +.ThemeOfficeMenuItemActive seq2 { + display: inline; +} + +.ThemeOfficeMenuItem .seq2, +.ThemeOfficeMenuItemHover .seq1, +.ThemeOfficeMenuItemActive .seq1 { + display: none; +} + +/* inactive settings */ +div.inactive td.ThemeOfficeMainItemHover, +div.inactive td.ThemeOfficeMainItemActive { + border-top: 0; + border-right: 1px solid #f1f3f5; + border-left: 1px solid #f1f3f5; +} + +div.inactive .ThemeOfficeMainItem { + color: #bbb; +} + +div.inactive span.ThemeOfficeMainItemText { + color: #aaa; +} + +div.inactive .ThemeOfficeMainItemHover, +div.inactive .ThemeOfficeMainItemActive { + background-color: #f1f3f5; +} \ No newline at end of file diff --git a/Sites/pages/administrator/templates/hathor/error.php b/Sites/pages/administrator/templates/hathor/error.php new file mode 100644 index 00000000..f1e8f689 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/error.php @@ -0,0 +1,75 @@ + + + + + + <?php echo $this->title; ?> <?php echo htmlspecialchars($this->error->getMessage(), ENT_QUOTES, 'UTF-8'); ?> + + get('debug_lang', '0') == '1' || $app->get('debug', '0') == '1') : ?> + + + + + direction == 'rtl') : ?> + + + + + +
      +

      + error->getCode(); ?> - +

      +
      +
      +

      + error->getMessage(), ENT_QUOTES, 'UTF-8'); ?> + debug) : ?> +
      error->getFile(), ENT_QUOTES, 'UTF-8');?>:error->getLine(); ?> + +

      +

      + debug) : ?> +
      + renderBacktrace(); ?> + + error->getPrevious()) : ?> + + _error here and in the loop as setError() assigns errors to this property and we need this for the backtrace to work correctly ?> + + setError($this->_error->getPrevious()); ?> + +

      +

      + _error->getMessage(), ENT_QUOTES, 'UTF-8'); ?> +
      _error->getFile(), ENT_QUOTES, 'UTF-8');?>:_error->getLine(); ?> +

      + renderBacktrace(); ?> + setError($this->_error->getPrevious()); ?> + + + setError($this->error); ?> + +
      + +
      +
      + + + diff --git a/Sites/pages/administrator/templates/hathor/favicon.ico b/Sites/pages/administrator/templates/hathor/favicon.ico new file mode 100644 index 00000000..1a4d7979 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/favicon.ico differ diff --git a/Sites/pages/administrator/templates/hathor/html/com_admin/help/default.php b/Sites/pages/administrator/templates/hathor/html/com_admin/help/default.php new file mode 100644 index 00000000..e23469b4 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_admin/help/default.php @@ -0,0 +1,49 @@ + +
      + +
      +
      +
      + + +
      +
        + toc as $k => $v):?> +
      • + + 'helpFrame'));?> +
      • + +
      +
      +
      +
      + +
      +
      + + + + +
      +
      +
      diff --git a/Sites/pages/administrator/templates/hathor/html/com_admin/profile/edit.php b/Sites/pages/administrator/templates/hathor/html/com_admin/profile/edit.php new file mode 100644 index 00000000..583ccc2c --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_admin/profile/edit.php @@ -0,0 +1,71 @@ +form->getFieldsets(); + +JFactory::getDocument()->addScriptDeclaration(" + Joomla.submitbutton = function(task) + { + if (task == 'profile.cancel' || document.formvalidator.isValid(document.getElementById('profile-form'))) + { + Joomla.submitform(task, document.getElementById('profile-form')); + } + } +"); +?> +
      +
      +
      + +
        + form->getFieldset('user_details') as $field) : ?> +
      • label; ?> + input; ?>
      • + +
      +
      +
      + +
      + name == 'user_details') : + continue; + endif; + echo JHtml::_('sliders.panel', JText::_($fieldset->label), $fieldset->name); + ?> +
      + label); ?> +
        + form->getFieldset($fieldset->name) as $field) : ?> + hidden) : ?> + input; ?> + +
      • label; ?> + input; ?>
      • + + +
      +
      + + + + + +
      +
      diff --git a/Sites/pages/administrator/templates/hathor/html/com_admin/sysinfo/default.php b/Sites/pages/administrator/templates/hathor/html/com_admin/sysinfo/default.php new file mode 100644 index 00000000..e31ce405 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_admin/sysinfo/default.php @@ -0,0 +1,62 @@ + + +
      +
      +
      +
      +
      + loadTemplate('system'); ?> +
      +
      +
      + +
      +
      +
      + loadTemplate('phpsettings'); ?> +
      +
      +
      + +
      +
      +
      + loadTemplate('config'); ?> +
      +
      +
      + +
      +
      +
      + loadTemplate('directory'); ?> +
      +
      +
      + +
      +
      +
      + loadTemplate('phpinfo'); ?> +
      +
      +
      +
      + +
      +
      diff --git a/Sites/pages/administrator/templates/hathor/html/com_admin/sysinfo/default_config.php b/Sites/pages/administrator/templates/hathor/html/com_admin/sysinfo/default_config.php new file mode 100644 index 00000000..5e1e1e4b --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_admin/sysinfo/default_config.php @@ -0,0 +1,43 @@ + +
      + + + + + + + + + + + + + + + config as $key => $value):?> + + + + + + +
      + + + +
       
      + + + +
      +
      diff --git a/Sites/pages/administrator/templates/hathor/html/com_admin/sysinfo/default_directory.php b/Sites/pages/administrator/templates/hathor/html/com_admin/sysinfo/default_directory.php new file mode 100644 index 00000000..8886345f --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_admin/sysinfo/default_directory.php @@ -0,0 +1,43 @@ + +
      + + + + + + + + + + + + + + + directory as $dir => $info) : ?> + + + + + + +
      + + + +
       
      + + + +
      +
      diff --git a/Sites/pages/administrator/templates/hathor/html/com_admin/sysinfo/default_navigation.php b/Sites/pages/administrator/templates/hathor/html/com_admin/sysinfo/default_navigation.php new file mode 100644 index 00000000..773bd49d --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_admin/sysinfo/default_navigation.php @@ -0,0 +1,41 @@ + + diff --git a/Sites/pages/administrator/templates/hathor/html/com_admin/sysinfo/default_phpsettings.php b/Sites/pages/administrator/templates/hathor/html/com_admin/sysinfo/default_phpsettings.php new file mode 100644 index 00000000..4e48c860 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_admin/sysinfo/default_phpsettings.php @@ -0,0 +1,162 @@ + +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
        +
      + + + php_settings['safe_mode']); ?> +
      + + + php_settings['open_basedir']); ?> +
      + + + php_settings['display_errors']); ?> +
      + + + php_settings['short_open_tag']); ?> +
      + + + php_settings['file_uploads']); ?> +
      + + + php_settings['magic_quotes_gpc']); ?> +
      + + + php_settings['register_globals']); ?> +
      + + + php_settings['output_buffering']); ?> +
      + + + php_settings['session.save_path']); ?> +
      + + + php_settings['session.auto_start']); ?> +
      + + + php_settings['xml']); ?> +
      + + + php_settings['zlib']); ?> +
      + + + php_settings['zip']); ?> +
      + + + php_settings['disable_functions']); ?> +
      + + + php_settings['mbstring']); ?> +
      + + + php_settings['iconv']); ?> +
      +
      diff --git a/Sites/pages/administrator/templates/hathor/html/com_admin/sysinfo/default_system.php b/Sites/pages/administrator/templates/hathor/html/com_admin/sysinfo/default_system.php new file mode 100644 index 00000000..ba315fc9 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_admin/sysinfo/default_system.php @@ -0,0 +1,106 @@ + +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + +
        +
      + + + info['php'];?> +
      + + + info['dbversion'];?> +
      + + + info['dbcollation'];?> +
      + + + info['phpversion'];?> +
      + + + info['server']); ?> +
      + + + info['sapi_name'];?> +
      + + + info['version'];?> +
      + + + info['platform'];?> +
      + + + info['useragent'];?> +
      +
      diff --git a/Sites/pages/administrator/templates/hathor/html/com_associations/associations/default.php b/Sites/pages/administrator/templates/hathor/html/com_associations/associations/default.php new file mode 100644 index 00000000..b88cc26a --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_associations/associations/default.php @@ -0,0 +1,178 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$canManageCheckin = JFactory::getUser()->authorise('core.manage', 'com_checkin'); +$colSpan = 5; + +$iconStates = array( + -2 => 'icon-trash', + 0 => 'icon-unpublish', + 1 => 'icon-publish', + 2 => 'icon-archive', +); + +JText::script('COM_ASSOCIATIONS_PURGE_CONFIRM_PROMPT'); + +JFactory::getDocument()->addScriptDeclaration(' + Joomla.submitbutton = function(pressbutton) + { + if (pressbutton == "associations.purge") + { + if (confirm(Joomla.JText._("COM_ASSOCIATIONS_PURGE_CONFIRM_PROMPT"))) + { + Joomla.submitform(pressbutton); + } + else + { + return false; + } + } + else + { + Joomla.submitform(pressbutton); + } + }; +'); +?> +
      +sidebar)) : ?> +
      + sidebar; ?> +
      +
      + +
      + + $this)); ?> + items)) : ?> +
      + +
      + + + + + typeSupports['state'])) : ?> + + + + + + + typeFields['menutype'])) : ?> + + + typeFields['access'])) : ?> + + + + + + + + + + + + items as $i => $item) : + $canCheckin = true; + $canEdit = AssociationsHelper::allowEdit($this->extensionName, $this->typeName, $item->id); + $canCheckin = $canManageCheckin || AssociationsHelper::canCheckinItem($this->extensionName, $this->typeName, $item->id); + $isCheckout = AssociationsHelper::isCheckoutItem($this->extensionName, $this->typeName, $item->id); + ?> + + typeSupports['state'])) : ?> + + + + + + + typeFields['menutype'])) : ?> + + + typeFields['access'])) : ?> + + + + + + +
      + + + + + + + + + + + + + + + +
      + pagination->getListFooter(); ?> +
      + + + level)) : ?> + $item->level)); ?> + + + editor, $item->checked_out_time, 'associations.', $canCheckin); ?> + + + + escape($item->title); ?> + + escape($item->title); ?> + + typeFields['alias'])) : ?> + + escape($item->alias)); ?> + + + typeFields['catid'])) : ?> +
      + escape($item->category_title); ?> +
      + +
      + + + extensionName, $this->typeName, (int) $item->id, $item->language, !$isCheckout, false); ?> + + extensionName, $this->typeName, (int) $item->id, $item->language, !$isCheckout, true); ?> + + escape($item->menutype_title); ?> + + escape($item->access_level); ?> + + id; ?> +
      + + + +
      + diff --git a/Sites/pages/administrator/templates/hathor/html/com_banners/banner/edit.php b/Sites/pages/administrator/templates/hathor/html/com_banners/banner/edit.php new file mode 100644 index 00000000..55e8dac4 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_banners/banner/edit.php @@ -0,0 +1,134 @@ +addScriptDeclaration(" + Joomla.submitbutton = function(task) + { + if (task == 'banner.cancel' || document.formvalidator.isValid(document.getElementById('banner-form'))) + { + Joomla.submitform(task, document.getElementById('banner-form')); + } + } +"); +?> + diff --git a/Sites/pages/administrator/templates/hathor/html/com_banners/banners/default.php b/Sites/pages/administrator/templates/hathor/html/com_banners/banners/default.php new file mode 100644 index 00000000..08e80352 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_banners/banners/default.php @@ -0,0 +1,235 @@ +get('id'); +$listOrder = $this->escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$canOrder = $user->authorise('core.edit.state', 'com_banners'); +$saveOrder = $listOrder == 'ordering'; +?> +
      +sidebar)) : ?> +
      + sidebar; ?> +
      +
      + +
      + +
      + + + +
      + + + + + + + + + + + + + +
      +
      +
      + + + + + + + + + + + + + + + + + + + + + + items as $i => $item) : + $ordering = ($listOrder == 'ordering'); + $item->cat_link = JRoute::_('index.php?option=com_categories&extension=com_banners&task=edit&type=other&cid[]=' . $item->catid); + $canCreate = $user->authorise('core.create', 'com_banners.category.' . $item->catid); + $canEdit = $user->authorise('core.edit', 'com_banners.category.' . $item->catid); + $canCheckin = $user->authorise('core.manage', 'com_checkin') || $item->checked_out == $userId || $item->checked_out == 0; + $canChange = $user->authorise('core.edit.state', 'com_banners.category.' . $item->catid) && $canCheckin; + ?> + + + + + + + + + + + + + + + + + +
      + + + + + + + + + + + + + + + items, 'filesave.png', 'banners.saveorder'); ?> + + + + + + + + + + + state->get('list.direction'), $this->state->get('list.ordering')); ?> + + +
      + id); ?> + + checked_out) : ?> + editor, $item->checked_out_time, 'banners.', $canCheckin); ?> + + + + escape($item->name); ?> + + escape($item->name); ?> + +

      + escape($item->alias));?>

      +
      + state, $i, 'banners.', $canChange, 'cb', $item->publish_up, $item->publish_down); ?> + + sticky, $i, $canChange);?> + + client_name;?> + + escape($item->category_title); ?> + + + + + pagination->orderUpIcon($i, @$this->items[$i - 1]->catid == $item->catid, 'banners.orderup', 'JLIB_HTML_MOVE_UP', $ordering); ?> + pagination->orderDownIcon($i, $this->pagination->total, @$this->items[$i + 1]->catid == $item->catid, 'banners.orderdown', 'JLIB_HTML_MOVE_DOWN', $ordering); ?> + + pagination->orderUpIcon($i, @$this->items[$i - 1]->catid == $item->catid, 'banners.orderdown', 'JLIB_HTML_MOVE_UP', $ordering); ?> + pagination->orderDownIcon($i, $this->pagination->total, @$this->items[$i + 1]->catid == $item->catid, 'banners.orderup', 'JLIB_HTML_MOVE_DOWN', $ordering); ?> + + + + class="text-area-order" title="name; ?> order" /> + + ordering; ?> + + + impmade, $item->imptotal ?: JText::_('COM_BANNERS_UNLIMITED'));?> + + clicks;?> - + impmade ? 100 * $item->clicks / $item->impmade : 0);?> + + metakey; ?> + + purchase_type < 0):?> + client_purchase_type > 0) ? JText::_('COM_BANNERS_FIELD_VALUE_'.$item->client_purchase_type) : JText::_('COM_BANNERS_FIELD_VALUE_'.$this->state->params->get('purchase_type')));?> + + purchase_type);?> + + + + + id; ?> +
      + + pagination->getListFooter(); ?> +
      + + + authorise('core.create', 'com_banners') + && $user->authorise('core.edit', 'com_banners') + && $user->authorise('core.edit.state', 'com_banners')) : ?> + JText::_('COM_BANNERS_BATCH_OPTIONS'), + 'footer' => $this->loadTemplate('batch_footer'), + ), + $this->loadTemplate('batch_body') + ); ?> + + + + + + + +
      + diff --git a/Sites/pages/administrator/templates/hathor/html/com_banners/client/edit.php b/Sites/pages/administrator/templates/hathor/html/com_banners/client/edit.php new file mode 100644 index 00000000..3660ed72 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_banners/client/edit.php @@ -0,0 +1,101 @@ +addScriptDeclaration(" + Joomla.submitbutton = function(task) + { + if (task == 'client.cancel' || document.formvalidator.isValid(document.getElementById('client-form'))) + { + Joomla.submitform(task, document.getElementById('client-form')); + } + } +"); +?> + +
      + +
      +
      + item->id) ? JText::_('COM_BANNERS_NEW_CLIENT') : JText::sprintf('COM_BANNERS_EDIT_CLIENT', $this->item->id); ?> +
        +
      • form->getLabel('name'); ?> + form->getInput('name'); ?>
      • + +
      • form->getLabel('contact'); ?> + form->getInput('contact'); ?>
      • + +
      • form->getLabel('email'); ?> + form->getInput('email'); ?>
      • + + canDo->get('core.edit.state')) : ?> +
      • form->getLabel('state'); ?> + form->getInput('state'); ?>
      • + + +
      • form->getLabel('purchase_type'); ?> + form->getInput('purchase_type'); ?>
      • + +
      • form->getLabel('track_impressions'); ?> + form->getInput('track_impressions'); ?>
      • + +
      • form->getLabel('track_clicks'); ?> + form->getInput('track_clicks'); ?>
      • + +
      • form->getLabel('id'); ?> + form->getInput('id'); ?>
      • +
      + +
      +
      + +
      + item->id, array('useCookie' => 1)); ?> + + +
      + +
        + form->getFieldset('metadata') as $field) : ?> +
      • + hidden) : ?> + label; ?> + + input; ?> +
      • + +
      +
      + + +
      + +
        + form->getFieldset('extra') as $field) : ?> +
      • hidden) : ?> + label; ?> + + input; ?>
      • + +
      +
      + + + + + +
      + +
      +
      diff --git a/Sites/pages/administrator/templates/hathor/html/com_banners/clients/default.php b/Sites/pages/administrator/templates/hathor/html/com_banners/clients/default.php new file mode 100644 index 00000000..fce45692 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_banners/clients/default.php @@ -0,0 +1,143 @@ +get('id'); +$listOrder = $this->escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +?> + +
      +sidebar)) : ?> +
      + sidebar; ?> +
      +
      + +
      + +
      + + + +
      + + + + +
      +
      +
      + + + + + + + + + + + + + + + + + items as $i => $item) : + $ordering = ($listOrder == 'ordering'); + $canCreate = $user->authorise('core.create', 'com_banners'); + $canEdit = $user->authorise('core.edit', 'com_banners'); + $canCheckin = $user->authorise('core.manage', 'com_checkin') || $item->checked_out == $user->get('id') || $item->checked_out == 0; + $canChange = $user->authorise('core.edit.state', 'com_banners') && $canCheckin; + ?> + + + + + + + + + + + + +
      + + + + + + + + + + + + + + + +
      + id); ?> + + checked_out) : ?> + editor, $item->checked_out_time, 'clients.', $canCheckin); ?> + + + + escape($item->name); ?> + + escape($item->name); ?> + + + contact;?> + + state, $i, 'clients.', $canChange);?> + + nbanners; ?> + + metakey; ?> + + purchase_type < 0):?> + state->params->get('purchase_type')));?> + + purchase_type);?> + + + id; ?> +
      + + pagination->getListFooter(); ?> + + + + + + +
      + diff --git a/Sites/pages/administrator/templates/hathor/html/com_banners/download/default.php b/Sites/pages/administrator/templates/hathor/html/com_banners/download/default.php new file mode 100644 index 00000000..9ee53fa8 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_banners/download/default.php @@ -0,0 +1,44 @@ + 'bottom')); +?> +
      +
      + +
      +
        + form->getFieldset() as $field) : ?> +
      • + form->getLabel($field->fieldname); ?> + form->getInput($field->fieldname); ?> +
      • + +
      +
      + + + +
      +
      diff --git a/Sites/pages/administrator/templates/hathor/html/com_banners/tracks/default.php b/Sites/pages/administrator/templates/hathor/html/com_banners/tracks/default.php new file mode 100644 index 00000000..261bef5d --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_banners/tracks/default.php @@ -0,0 +1,149 @@ +get('id'); +$listOrder = $this->escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +?> +
      +sidebar)) : ?> +
      + sidebar; ?> +
      +
      + +
      + + +
      + + + +
      + + + + + state->get('filter.category_id');?> + + + + + + +
      +
      + +
      + + + + + + + + + + + + + + + items as $i => $item) :?> + + + + + + + + + + +
      + + + + + + + + + + + +
      + banner_name;?> + + client_name;?> + + category_title;?> + + track_type == 1 ? JText::_('COM_BANNERS_IMPRESSION'): JText::_('COM_BANNERS_CLICK');?> + + count;?> + + track_date, JText::_('DATE_FORMAT_LC5'));?> +
      + + + JText::_('COM_BANNERS_TRACKS_DOWNLOAD'), + 'url' => JRoute::_('index.php?option=com_banners&view=download&tmpl=component'), + 'width' => '100%', + 'height' => '300px', + 'footer' => '' + . '', + ) + ); ?> + + pagination->getListFooter(); ?> + + + + + + +
      + diff --git a/Sites/pages/administrator/templates/hathor/html/com_cache/cache/default.php b/Sites/pages/administrator/templates/hathor/html/com_cache/cache/default.php new file mode 100644 index 00000000..d539ae81 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_cache/cache/default.php @@ -0,0 +1,91 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +?> + +
      +sidebar)) : ?> +
      + sidebar; ?> +
      +
      + +
      + +
      + +
      + + + + +
      +
      +
      + + + + + + + + + + + + data as $folder => $item) : ?> + + + + + + + + +
      + + + + + + + +
      + + + + group; ?> + + + count; ?> + + size*1024); ?> +
      + +pagination->getListFooter(); ?> + + + + + + + +
      + diff --git a/Sites/pages/administrator/templates/hathor/html/com_cache/purge/default.php b/Sites/pages/administrator/templates/hathor/html/com_cache/purge/default.php new file mode 100644 index 00000000..1b0b3f36 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_cache/purge/default.php @@ -0,0 +1,45 @@ + + +
      +sidebar)) : ?> +
      + sidebar; ?> +
      +
      + +
      + + + + + + + + + + + + +
      + +
      +

      +

      +
      + +
      + + +
      +
      + diff --git a/Sites/pages/administrator/templates/hathor/html/com_categories/categories/default.php b/Sites/pages/administrator/templates/hathor/html/com_categories/categories/default.php new file mode 100644 index 00000000..e5bd548d --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_categories/categories/default.php @@ -0,0 +1,259 @@ +get('id'); +$extension = $this->escape($this->state->get('filter.extension')); +$listOrder = $this->escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$ordering = ($listOrder == 'a.lft'); +$canOrder = $user->authorise('core.edit.state', $extension); +$saveOrder = ($listOrder == 'a.lft' && $listDirn == 'asc'); +$jinput = JFactory::getApplication()->input; +$component = $jinput->get('extension'); +?> + +
      +
      + sidebar)) : ?> +
      + sidebar; ?> +
      + +
      sidebar) ? ' class="span10"' : ''; ?>> +
      + + + +
      + + + + + + + + + + + + + + + + +
      +
      +
      + + + + + + + + + items[0]) && property_exists($this->items[0], 'count_published')) : ?> + + + items[0]) && property_exists($this->items[0], 'count_unpublished')) : ?> + + + items[0]) && property_exists($this->items[0], 'count_archived')) : ?> + + + items[0]) && property_exists($this->items[0], 'count_trashed')) : ?> + + + + assoc) : ?> + + + + + + + + + items as $i => $item) : ?> + id, $this->ordering[$item->parent_id]); + $canEdit = $user->authorise('core.edit', $extension . '.category.' . $item->id); + $canCheckin = $user->authorise('core.admin', 'com_checkin') || $item->checked_out == $userId || $item->checked_out == 0; + $canEditOwn = $user->authorise('core.edit.own', $extension . '.category.' . $item->id) && $item->created_user_id == $userId; + $canChange = $user->authorise('core.edit.state', $extension . '.category.' . $item->id) && $canCheckin; + ?> + + + + + + items[0]) && property_exists($this->items[0], 'count_published')) : ?> + + + items[0]) && property_exists($this->items[0], 'count_unpublished')) : ?> + + + items[0]) && property_exists($this->items[0], 'count_archived')) : ?> + + + items[0]) && property_exists($this->items[0], 'count_trashed')) : ?> + + + + assoc) : ?> + + + + + + + +
      + + + + + + + + + items, 'filesave.png', 'categories.saveorder'); ?> + + + + + + + + + + + + + + + state->get('list.direction'), $this->state->get('list.ordering')); ?> + + +
      + id); ?> + + |—', $item->level - 1) ?> + checked_out) : ?> + editor, $item->checked_out_time, 'categories.', $canCheckin); ?> + + + + escape($item->title); ?> + + escape($item->title); ?> + +

      + |—', $item->level - 1) ?> + note)) : ?> + escape($item->alias)); ?> + + escape($item->alias), $this->escape($item->note)); ?> +

      +
      + published, $i, 'categories.', $canChange); ?> + + + + pagination->orderUpIcon($i, isset($this->ordering[$item->parent_id][$orderkey - 1]), 'categories.orderup', 'JLIB_HTML_MOVE_UP', $ordering); ?> + pagination->orderDownIcon($i, $this->pagination->total, isset($this->ordering[$item->parent_id][$orderkey + 1]), 'categories.orderdown', 'JLIB_HTML_MOVE_DOWN', $ordering); ?> + + + class="text-area-order" title="title; ?> order" /> + + + + + + count_published; ?> + + + count_unpublished; ?> + + + count_archived; ?> + + + count_trashed; ?> + + escape($item->access_level); ?> + + association): ?> + id, $extension); ?> + + + + + + id; ?> +
      + + pagination->getListFooter(); ?> +
      + + + authorise('core.create', $extension) + && $user->authorise('core.edit', $extension) + && $user->authorise('core.edit.state', $extension)) : ?> + JText::_('COM_CATEGORIES_BATCH_OPTIONS'), + 'footer' => $this->loadTemplate('batch_footer'), + ), + $this->loadTemplate('batch_body') + ); ?> + + + + + + + + +
      +
      +
      diff --git a/Sites/pages/administrator/templates/hathor/html/com_categories/category/edit.php b/Sites/pages/administrator/templates/hathor/html/com_categories/category/edit.php new file mode 100644 index 00000000..5aba5e25 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_categories/category/edit.php @@ -0,0 +1,175 @@ +input; + +$saveHistory = $this->state->get('params')->get('save_history', 0); + +JHtml::_('behavior.keepalive'); +JHtml::_('behavior.formvalidator'); + +JFactory::getDocument()->addScriptDeclaration(" + Joomla.submitbutton = function(task) + { + if (task == 'category.cancel' || document.formvalidator.isValid(document.getElementById('item-form'))) { + " . $this->form->getField('description')->save() . " + Joomla.submitform(task, document.getElementById('item-form')); + } + } +"); +$assoc = JLanguageAssociations::isEnabled(); + +?> + +
      +
      +
      +
      + +
        +
      • + form->getLabel('title'); ?> + form->getInput('title'); ?> +
      • +
      • + form->getLabel('alias'); ?> + form->getInput('alias'); ?> +
      • +
      • + form->getLabel('extension'); ?> + form->getInput('extension'); ?> +
      • +
      • + form->getLabel('parent_id'); ?> + form->getInput('parent_id'); ?> +
      • +
      • + form->getLabel('published'); ?> + form->getInput('published'); ?> +
      • +
      • + form->getLabel('access'); ?> + form->getInput('access'); ?> +
      • + canDo->get('core.admin')) : ?> +
      • + + + +
      • + +
      • + form->getLabel('language'); ?> + form->getInput('language'); ?> +
      • + +
      • + checkTags) : ?> + form->getLabel('tags'); ?> +
        + form->getInput('tags'); ?> +
        + +
      • + +
      • form->getLabel('version_note'); ?> + form->getInput('version_note'); ?>
      • + +
      • + form->getLabel('id'); ?> + form->getInput('id'); ?> +
      • +
      • + form->getLabel('hits'); ?> + form->getInput('hits'); ?> +
      • +
      + +
      + form->getLabel('description'); ?> +
      + form->getInput('description'); ?> +
      +
      +
      + +
      + + item->id, array('useCookie' => 1)); ?> + loadTemplate('options'); ?> +
      + + +
      + + loadTemplate('metadata'); ?> +
      + + form->getFieldsets(); ?> + $fieldSet) : ?> + + label) ? $fieldSet->label : 'COM_CATEGORIES_' . $name . '_FIELDSET_LABEL'; + echo JHtml::_('sliders.panel', JText::_($label), $name . '-options'); + if (isset($fieldSet->description) && trim($fieldSet->description)) + { + echo '

      ' . $this->escape(JText::_($fieldSet->description)) . '

      '; + } + ?> +
      +
      +
        + form->getFieldset($name) as $field) : ?> +
      • + label; ?> + input; ?> +
      • + +
      +
      + + + + + + loadTemplate('associations'); ?> + + + +
      +
      + + canDo->get('core.admin')) : ?> +
      + + item->id, array('useCookie' => 1)); ?> + + +
      + + form->getLabel('rules'); ?> + form->getInput('rules'); ?> +
      + + +
      + +
      + + +
      +
      +
      +
      diff --git a/Sites/pages/administrator/templates/hathor/html/com_categories/category/edit_options.php b/Sites/pages/administrator/templates/hathor/html/com_categories/category/edit_options.php new file mode 100644 index 00000000..c64f75be --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_categories/category/edit_options.php @@ -0,0 +1,67 @@ + + + + +
      + +
        +
      • + form->getLabel('created_user_id'); ?> + form->getInput('created_user_id'); ?> +
      • + item->created_time) : ?> +
      • + form->getLabel('created_time'); ?> + form->getInput('created_time'); ?> +
      • + + item->modified_user_id) : ?> +
      • + form->getLabel('modified_user_id'); ?> + form->getInput('modified_user_id'); ?> +
      • +
      • + form->getLabel('modified_time'); ?> + form->getInput('modified_time'); ?> +
      • + +
      +
      + +form->getFieldsets('params'); ?> + $fieldSet) : ?> + label) ? $fieldSet->label : 'COM_CATEGORIES_' . $name . '_FIELDSET_LABEL'; + echo JHtml::_('sliders.panel', JText::_($label), $name . '-options'); + if (isset($fieldSet->description) && trim($fieldSet->description)) + { + echo '

      ' . $this->escape(JText::_($fieldSet->description)) . '

      '; + } + ?> +
      + +
        + form->getFieldset($name) as $field) : ?> +
      • + label; ?> + input; ?> +
      • + + +
      • + form->getLabel('note'); ?> + form->getInput('note'); ?> +
      • + +
      +
      + diff --git a/Sites/pages/administrator/templates/hathor/html/com_checkin/checkin/default.php b/Sites/pages/administrator/templates/hathor/html/com_checkin/checkin/default.php new file mode 100644 index 00000000..7a38ce35 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_checkin/checkin/default.php @@ -0,0 +1,65 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +?> +
      + sidebar)) : ?> +
      + sidebar; ?> +
      + +
      sidebar) ? ' class="span10"' : ''; ?>> +
      + +
      +
      + + + + + + + + + + + items as $table => $count): $i = 0; ?> + + + + + + + + + + + + +
      + +
      + pagination->getListFooter(); ?> +
      + + + + + +
      +
      diff --git a/Sites/pages/administrator/templates/hathor/html/com_config/application/default.php b/Sites/pages/administrator/templates/hathor/html/com_config/application/default.php new file mode 100644 index 00000000..4cfe6d17 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_config/application/default.php @@ -0,0 +1,84 @@ +document->setBuffer($this->loadTemplate('navigation'), 'modules', 'submenu'); + +JFactory::getDocument()->addScriptDeclaration(" + Joomla.submitbutton = function(task) + { + if (task == 'application.cancel' || document.formvalidator.isValid(document.getElementById('application-form'))) { + Joomla.submitform(task, document.getElementById('application-form')); + } + } +"); +?> + +
      + ftp) : ?> + loadTemplate('ftplogin'); ?> + +
      +
      +
      +
      + loadTemplate('site'); ?> + loadTemplate('metadata'); ?> +
      +
      + loadTemplate('seo'); ?> + loadTemplate('cookie'); ?> +
      +
      +
      +
      +
      +
      + loadTemplate('system'); ?> +
      +
      + loadTemplate('debug'); ?> + loadTemplate('cache'); ?> + loadTemplate('session'); ?> +
      +
      +
      +
      +
      +
      + loadTemplate('server'); ?> + loadTemplate('locale'); ?> + loadTemplate('ftp'); ?> +
      +
      + loadTemplate('database'); ?> + loadTemplate('mail'); ?> +
      +
      +
      +
      +
      + loadTemplate('permissions'); ?> +
      +
      +
      +
      + loadTemplate('filters'); ?> +
      +
      + + +
      +
      +
      diff --git a/Sites/pages/administrator/templates/hathor/html/com_config/application/default_cache.php b/Sites/pages/administrator/templates/hathor/html/com_config/application/default_cache.php new file mode 100644 index 00000000..2bc689f7 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_config/application/default_cache.php @@ -0,0 +1,26 @@ + +
      + +
      + +
        + form->getFieldset('cache') as $field): ?> +
      • + label; ?> + input; ?> +
      • + +
      + +
      +
      diff --git a/Sites/pages/administrator/templates/hathor/html/com_config/application/default_cookie.php b/Sites/pages/administrator/templates/hathor/html/com_config/application/default_cookie.php new file mode 100644 index 00000000..e6af63bd --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_config/application/default_cookie.php @@ -0,0 +1,26 @@ + + +
      + +
      + +
        + form->getFieldset('cookie') as $field): ?> +
      • + label; ?> + input; ?> +
      • + +
      +
      +
      diff --git a/Sites/pages/administrator/templates/hathor/html/com_config/application/default_database.php b/Sites/pages/administrator/templates/hathor/html/com_config/application/default_database.php new file mode 100644 index 00000000..b0cb638d --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_config/application/default_database.php @@ -0,0 +1,24 @@ + +
      +
      + +
        + form->getFieldset('database') as $field): ?> +
      • + label; ?> + input; ?> +
      • + +
      +
      +
      diff --git a/Sites/pages/administrator/templates/hathor/html/com_config/application/default_debug.php b/Sites/pages/administrator/templates/hathor/html/com_config/application/default_debug.php new file mode 100644 index 00000000..abe83d06 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_config/application/default_debug.php @@ -0,0 +1,24 @@ + +
      +
      + +
        + form->getFieldset('debug') as $field): ?> +
      • + label; ?> + input; ?> +
      • + +
      +
      +
      diff --git a/Sites/pages/administrator/templates/hathor/html/com_config/application/default_filters.php b/Sites/pages/administrator/templates/hathor/html/com_config/application/default_filters.php new file mode 100644 index 00000000..dc599687 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_config/application/default_filters.php @@ -0,0 +1,22 @@ + +
      +
      + +

      + form->getFieldset('filters') as $field) : ?> + label; ?> +
      + input; ?> + +
      +
      diff --git a/Sites/pages/administrator/templates/hathor/html/com_config/application/default_ftp.php b/Sites/pages/administrator/templates/hathor/html/com_config/application/default_ftp.php new file mode 100644 index 00000000..3b81d4ee --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_config/application/default_ftp.php @@ -0,0 +1,24 @@ + +
      +
      + +
        + form->getFieldset('ftp') as $field): ?> +
      • + label; ?> + input; ?> +
      • + +
      +
      +
      diff --git a/Sites/pages/administrator/templates/hathor/html/com_config/application/default_ftplogin.php b/Sites/pages/administrator/templates/hathor/html/com_config/application/default_ftplogin.php new file mode 100644 index 00000000..91758dbd --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_config/application/default_ftplogin.php @@ -0,0 +1,31 @@ + +
      +
      + + + + ftp instanceof Exception) : ?> +

      ftp->message); ?>

      + +
        +
      • + + +
      • +
      • + + +
      • +
      +
      +
      diff --git a/Sites/pages/administrator/templates/hathor/html/com_config/application/default_locale.php b/Sites/pages/administrator/templates/hathor/html/com_config/application/default_locale.php new file mode 100644 index 00000000..d314365a --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_config/application/default_locale.php @@ -0,0 +1,24 @@ + +
      +
      + +
        + form->getFieldset('locale') as $field): ?> +
      • + label; ?> + input; ?> +
      • + +
      +
      +
      diff --git a/Sites/pages/administrator/templates/hathor/html/com_config/application/default_mail.php b/Sites/pages/administrator/templates/hathor/html/com_config/application/default_mail.php new file mode 100644 index 00000000..3837a248 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_config/application/default_mail.php @@ -0,0 +1,34 @@ + 'auto', 'relative' => true)); + +JFactory::getDocument()->addScriptDeclaration(' + var sendtestmail_url = "' . addslashes(JUri::base()) . 'index.php?option=com_config&task=config.sendtestmail.application&format=json"; + '); +?> +
      +
      + +
        + form->getFieldset('mail') as $field): ?> +
      • + label; ?> + input; ?> +
      • + +
      + +
      +
      diff --git a/Sites/pages/administrator/templates/hathor/html/com_config/application/default_metadata.php b/Sites/pages/administrator/templates/hathor/html/com_config/application/default_metadata.php new file mode 100644 index 00000000..744c73a3 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_config/application/default_metadata.php @@ -0,0 +1,24 @@ + +
      +
      + +
        + form->getFieldset('metadata') as $field): ?> +
      • + label; ?> + input; ?> +
      • + +
      +
      +
      diff --git a/Sites/pages/administrator/templates/hathor/html/com_config/application/default_navigation.php b/Sites/pages/administrator/templates/hathor/html/com_config/application/default_navigation.php new file mode 100644 index 00000000..c01778a8 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_config/application/default_navigation.php @@ -0,0 +1,22 @@ + + diff --git a/Sites/pages/administrator/templates/hathor/html/com_config/application/default_permissions.php b/Sites/pages/administrator/templates/hathor/html/com_config/application/default_permissions.php new file mode 100644 index 00000000..70b08c10 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_config/application/default_permissions.php @@ -0,0 +1,21 @@ + +
      +
      + + form->getFieldset('permissions') as $field) : ?> + label; ?> +
      + input; ?> + +
      +
      diff --git a/Sites/pages/administrator/templates/hathor/html/com_config/application/default_seo.php b/Sites/pages/administrator/templates/hathor/html/com_config/application/default_seo.php new file mode 100644 index 00000000..5a90bb88 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_config/application/default_seo.php @@ -0,0 +1,24 @@ + +
      +
      + +
        + form->getFieldset('seo') as $field): ?> +
      • + label; ?> + input; ?> +
      • + +
      +
      +
      diff --git a/Sites/pages/administrator/templates/hathor/html/com_config/application/default_server.php b/Sites/pages/administrator/templates/hathor/html/com_config/application/default_server.php new file mode 100644 index 00000000..5162cce8 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_config/application/default_server.php @@ -0,0 +1,24 @@ + +
      +
      + +
        + form->getFieldset('server') as $field): ?> +
      • + label; ?> + input; ?> +
      • + +
      +
      +
      diff --git a/Sites/pages/administrator/templates/hathor/html/com_config/application/default_session.php b/Sites/pages/administrator/templates/hathor/html/com_config/application/default_session.php new file mode 100644 index 00000000..bf9f243d --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_config/application/default_session.php @@ -0,0 +1,24 @@ + +
      +
      + +
        + form->getFieldset('session') as $field): ?> +
      • + label; ?> + input; ?> +
      • + +
      +
      +
      diff --git a/Sites/pages/administrator/templates/hathor/html/com_config/application/default_site.php b/Sites/pages/administrator/templates/hathor/html/com_config/application/default_site.php new file mode 100644 index 00000000..3ae09012 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_config/application/default_site.php @@ -0,0 +1,24 @@ + +
      +
      + +
        + form->getFieldset('site') as $field): ?> +
      • + label; ?> + input; ?> +
      • + +
      +
      +
      diff --git a/Sites/pages/administrator/templates/hathor/html/com_config/application/default_system.php b/Sites/pages/administrator/templates/hathor/html/com_config/application/default_system.php new file mode 100644 index 00000000..a044fcc0 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_config/application/default_system.php @@ -0,0 +1,24 @@ + +
      +
      + +
        + form->getFieldset('system') as $field): ?> +
      • + label; ?> + input; ?> +
      • + +
      +
      +
      diff --git a/Sites/pages/administrator/templates/hathor/html/com_config/component/default.php b/Sites/pages/administrator/templates/hathor/html/com_config/component/default.php new file mode 100644 index 00000000..fd47925d --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_config/component/default.php @@ -0,0 +1,62 @@ +getTemplate(); + +JHtml::_('behavior.formvalidator'); +JHtml::_('bootstrap.framework'); + +JFactory::getDocument()->addScriptDeclaration(" + Joomla.submitbutton = function(task) + { + if (document.formvalidator.isValid(document.getElementById('component-form'))) { + Joomla.submitform(task, document.getElementById('component-form')); + } + } +"); +?> +
      + component->option . '_configuration', array('useCookie' => 1)); + $fieldSets = $this->form->getFieldsets(); + ?> + $fieldSet) : ?> + label) ? 'COM_CONFIG_' . $name . '_FIELDSET_LABEL' : $fieldSet->label; + echo JHtml::_('tabs.panel', JText::_($label), 'publishing-details'); + if (isset($fieldSet->description) && !empty($fieldSet->description)) + { + echo '

      ' . JText::_($fieldSet->description) . '

      '; + } + ?> +
        + form->getFieldset($name) as $field): ?> +
      • + hidden) : ?> + label; ?> + + input; ?> +
      • + +
      + +
      + + +
      + + + + + +
      +
      diff --git a/Sites/pages/administrator/templates/hathor/html/com_contact/contact/edit.php b/Sites/pages/administrator/templates/hathor/html/com_contact/contact/edit.php new file mode 100644 index 00000000..05a86d74 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_contact/contact/edit.php @@ -0,0 +1,212 @@ +input; + +$saveHistory = $this->state->get('params')->get('save_history', 0); + +$assoc = JLanguageAssociations::isEnabled(); + +JFactory::getDocument()->addScriptDeclaration(" + Joomla.submitbutton = function(task) + { + if (task == 'contact.cancel' || document.formvalidator.isValid(document.getElementById('contact-form'))) + { + " . $this->form->getField('misc')->save() . " + Joomla.submitform(task, document.getElementById('contact-form')); + } + } +"); +$fieldSets = $this->form->getFieldsets(); +?> +
      +
      +
      + item->id) ? JText::_('COM_CONTACT_NEW_CONTACT') : JText::sprintf('COM_CONTACT_EDIT_CONTACT', $this->item->id); ?> +
        +
      • form->getLabel('name'); ?> + form->getInput('name'); ?>
      • + +
      • form->getLabel('alias'); ?> + form->getInput('alias'); ?>
      • + +
      • form->getLabel('user_id'); ?> + form->getInput('user_id'); ?>
      • + +
      • form->getLabel('catid'); ?> + form->getInput('catid'); ?>
      • + +
      • form->getLabel('published'); ?> + form->getInput('published'); ?>
      • + +
      • form->getLabel('access'); ?> + form->getInput('access'); ?>
      • + +
      • form->getLabel('ordering'); ?> + form->getInput('ordering'); ?>
      • + +
      • form->getLabel('featured'); ?> + form->getInput('featured'); ?>
      • + +
      • form->getLabel('language'); ?> + form->getInput('language'); ?>
      • + + +
      • form->getLabel('tags'); ?> +
        + form->getInput('tags'); ?> +
        +
      • + + +
      • form->getLabel('version_note'); ?> + form->getInput('version_note'); ?>
      • + + +
      • form->getLabel('id'); ?> + form->getInput('id'); ?>
      • +
      +
      + form->getLabel('misc'); ?> +
      + form->getInput('misc'); ?> +
      +
      +
      + + + +
      + +
        + +
      • form->getLabel('created_by'); ?> + form->getInput('created_by'); ?>
      • + +
      • form->getLabel('created_by_alias'); ?> + form->getInput('created_by_alias'); ?>
      • + +
      • form->getLabel('created'); ?> + form->getInput('created'); ?>
      • + +
      • form->getLabel('publish_up'); ?> + form->getInput('publish_up'); ?>
      • + +
      • form->getLabel('publish_down'); ?> + form->getInput('publish_down'); ?>
      • + + item->modified_by) : ?> +
      • form->getLabel('modified_by'); ?> + form->getInput('modified_by'); ?>
      • + +
      • form->getLabel('modified'); ?> + form->getInput('modified'); ?>
      • + + +
      +
      + + +
      + +

      item->id) ? JText::_('COM_CONTACT_DETAILS') : JText::sprintf('COM_CONTACT_EDIT_DETAILS', $this->item->id); ?>

      + +
        +
      • form->getLabel('image'); ?> + form->getInput('image'); ?>
      • + +
      • form->getLabel('con_position'); ?> + form->getInput('con_position'); ?>
      • + +
      • form->getLabel('email_to'); ?> + form->getInput('email_to'); ?>
      • + +
      • form->getLabel('address'); ?> + form->getInput('address'); ?>
      • + +
      • form->getLabel('suburb'); ?> + form->getInput('suburb'); ?>
      • + +
      • form->getLabel('state'); ?> + form->getInput('state'); ?>
      • + +
      • form->getLabel('postcode'); ?> + form->getInput('postcode'); ?>
      • + +
      • form->getLabel('country'); ?> + form->getInput('country'); ?>
      • + +
      • form->getLabel('telephone'); ?> + form->getInput('telephone'); ?>
      • + +
      • form->getLabel('mobile'); ?> + form->getInput('mobile'); ?>
      • + +
      • form->getLabel('fax'); ?> + form->getInput('fax'); ?>
      • + +
      • form->getLabel('webpage'); ?> + form->getInput('webpage'); ?>
      • + +
      • form->getLabel('sortname1'); ?> + form->getInput('sortname1'); ?>
      • + +
      • form->getLabel('sortname2'); ?> + form->getInput('sortname2'); ?>
      • + +
      • form->getLabel('sortname3'); ?> + form->getInput('sortname3'); ?>
      • +
      +
      + + loadTemplate('params'); ?> + + $fieldSet) : ?> + + label), $name.'-options'); ?> + description) && trim($fieldSet->description)) : ?> +

      escape(JText::_($fieldSet->description));?>

      + +
      +
        + form->getFieldset($name) as $field) : ?> +
      • + label; ?> + input; ?> +
      • + +
      +
      + + + + +
      + + loadTemplate('metadata'); ?> +
      + + + + loadTemplate('associations'); ?> + + + + + +
      +
      diff --git a/Sites/pages/administrator/templates/hathor/html/com_contact/contact/edit_params.php b/Sites/pages/administrator/templates/hathor/html/com_contact/contact/edit_params.php new file mode 100644 index 00000000..a6af2840 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_contact/contact/edit_params.php @@ -0,0 +1,28 @@ +form->getFieldsets('params'); +foreach ($fieldSets as $name => $fieldSet) : + echo JHtml::_('sliders.panel', JText::_($fieldSet->label), $name.'-params'); + if (isset($fieldSet->description) && trim($fieldSet->description)) : + echo '

      '.$this->escape(JText::_($fieldSet->description)).'

      '; + endif; + ?> +
      + label); ?> +
        + form->getFieldset($name) as $field) : ?> +
      • label; ?> + input; ?>
      • + +
      +
      + diff --git a/Sites/pages/administrator/templates/hathor/html/com_contact/contacts/default.php b/Sites/pages/administrator/templates/hathor/html/com_contact/contacts/default.php new file mode 100644 index 00000000..39bec44c --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_contact/contacts/default.php @@ -0,0 +1,239 @@ +get('id'); +$listOrder = $this->escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$canOrder = $user->authorise('core.edit.state', 'com_contact'); +$saveOrder = $listOrder == 'a.ordering'; +$assoc = JLanguageAssociations::isEnabled(); +?> + +
      +sidebar)) : ?> +
      + sidebar; ?> +
      +
      + +
      + +
      + + +
      + + + + + + + + + + + + + + + + +
      +
      +
      + + + + + + + + + + + + + + + + + + + + + + items); + foreach ($this->items as $i => $item) : + $ordering = $listOrder == 'a.ordering'; + $canCreate = $user->authorise('core.create', 'com_contact.category.' . $item->catid); + $canEdit = $user->authorise('core.edit', 'com_contact.category.' . $item->catid); + $canCheckin = $user->authorise('core.manage', 'com_checkin') || $item->checked_out == $userId || $item->checked_out == 0; + $canEditOwn = $user->authorise('core.edit.own', 'com_contact.category.' . $item->catid) && $item->created_by == $userId; + $canChange = $user->authorise('core.edit.state', 'com_contact.category.' . $item->catid) && $canCheckin; + + $item->cat_link = JRoute::_('index.php?option=com_categories&extension=com_contact&task=edit&type=other&id='.$item->catid); + ?> + + + + + + + + + + + + + + + + + +
      + + + + + + + + + + + + + + + items, 'filesave.png', 'contacts.saveorder'); ?> + + + + + + + + + +
      + id); ?> + + checked_out) : ?> + editor, $item->checked_out_time, 'contacts.', $canCheckin); ?> + + + + escape($item->name); ?> + + escape($item->name); ?> + +

      + escape($item->alias));?>

      +
      + linked_user)) : ?> + linked_user;?> + + + published, $i, 'contacts.', $canChange, 'cb', $item->publish_up, $item->publish_down); ?> + + featured, $i, $canChange); ?> + + category_title; ?> + + + + + pagination->orderUpIcon($i, $item->catid == @$this->items[$i - 1]->catid, 'contacts.orderup', 'JLIB_HTML_MOVE_UP', $ordering); ?> + pagination->orderDownIcon($i, $this->pagination->total, $item->catid == @$this->items[$i + 1]->catid, 'contacts.orderdown', 'JLIB_HTML_MOVE_DOWN', $ordering); ?> + + pagination->orderUpIcon($i, $item->catid == @$this->items[$i - 1]->catid, 'contacts.orderdown', 'JLIB_HTML_MOVE_UP', $ordering); ?> + pagination->orderDownIcon($i, $this->pagination->total, $item->catid == @$this->items[$i + 1]->catid, 'contacts.orderup', 'JLIB_HTML_MOVE_DOWN', $ordering); ?> + + + + class="text-area-order" title="name; ?> order" /> + + ordering; ?> + + + access_level; ?> + + association) : ?> + id); ?> + + + + + id; ?> +
      + + + authorise('core.create', 'com_contact') + && $user->authorise('core.edit', 'com_contact') + && $user->authorise('core.edit.state', 'com_contact')) : ?> + JText::_('COM_CONTACT_BATCH_OPTIONS'), + 'footer' => $this->loadTemplate('batch_footer'), + ), + $this->loadTemplate('batch_body') + ); ?> + + + pagination->getListFooter(); ?> + + + + + + +
      + diff --git a/Sites/pages/administrator/templates/hathor/html/com_contact/contacts/modal.php b/Sites/pages/administrator/templates/hathor/html/com_contact/contacts/modal.php new file mode 100644 index 00000000..331a6622 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_contact/contacts/modal.php @@ -0,0 +1,134 @@ +input->get('forcedLanguage', '', 'cmd'); +$function = JFactory::getApplication()->input->getCmd('function', 'jSelectContact'); +$listOrder = $this->escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +?> +
      +
      + + + +
      + + + + + + + + + + + + + + + + + + +
      +
      +
      + + + + + + + + + + + + + + + items as $i => $item) : ?> + + + + + + + + + + + + + pagination->getListFooter(); ?> + + + + + + +
      diff --git a/Sites/pages/administrator/templates/hathor/html/com_content/article/edit.php b/Sites/pages/administrator/templates/hathor/html/com_content/article/edit.php new file mode 100644 index 00000000..1f3427f8 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_content/article/edit.php @@ -0,0 +1,277 @@ +state->get('params'); +$params = $params->toArray(); +$saveHistory = $this->state->get('params')->get('save_history', 0); + +// This checks if the config options have ever been saved. If they haven't they will fall back to the original settings. +$editoroptions = isset($params['show_publishing_options']); + +$input = JFactory::getApplication()->input; + +if (!$editoroptions): + $params['show_publishing_options'] = '1'; + $params['show_article_options'] = '1'; + $params['show_urls_images_backend'] = '0'; + $params['show_urls_images_frontend'] = '0'; +endif; + +// Check if the article uses configuration settings besides global. If so, use them. +if (!empty($this->item->attribs['show_publishing_options'])): + $params['show_publishing_options'] = $this->item->attribs['show_publishing_options']; +endif; +if (!empty($this->item->attribs['show_article_options'])): + $params['show_article_options'] = $this->item->attribs['show_article_options']; +endif; +if (!empty($this->item->attribs['show_urls_images_backend'])): + $params['show_urls_images_backend'] = $this->item->attribs['show_urls_images_backend']; +endif; + +$assoc = JLanguageAssociations::isEnabled(); + +JFactory::getDocument()->addScriptDeclaration(" + Joomla.submitbutton = function(task) + { + if (task == 'article.cancel' || document.formvalidator.isValid(document.getElementById('item-form'))) + { + " . $this->form->getField('articletext')->save() . " + Joomla.submitform(task, document.getElementById('item-form')); + } + } +"); +?> +
      + +
      +
      +
      + item->id) ? JText::_('COM_CONTENT_NEW_ARTICLE') : JText::sprintf('COM_CONTENT_EDIT_ARTICLE', $this->item->id); ?> +
        +
      • form->getLabel('title'); ?> + form->getInput('title'); ?>
      • + +
      • form->getLabel('alias'); ?> + form->getInput('alias'); ?>
      • + +
      • form->getLabel('catid'); ?> + form->getInput('catid'); ?>
      • + +
      • form->getLabel('state'); ?> + form->getInput('state'); ?>
      • + +
      • form->getLabel('access'); ?> + form->getInput('access'); ?>
      • + + canDo->get('core.admin')) : ?> +
      • + +
      • + + +
      • form->getLabel('featured'); ?> + form->getInput('featured'); ?>
      • + +
      • form->getLabel('language'); ?> + form->getInput('language'); ?>
      • + + +
      • form->getLabel('tags'); ?> +
        + form->getInput('tags'); ?> +
        +
      • + + +
      • form->getLabel('version_note'); ?> + form->getInput('version_note'); ?>
      • + + +
      • form->getLabel('id'); ?> + form->getInput('id'); ?>
      • + +
      + +
      + form->getLabel('articletext'); ?> +
      + form->getInput('articletext'); ?> +
      +
      +
      + +
      + item->id, array('useCookie' => 1)); ?> + + + +
      +
        +
      • form->getLabel('created_by'); ?> + form->getInput('created_by'); ?>
      • + +
      • form->getLabel('created_by_alias'); ?> + form->getInput('created_by_alias'); ?>
      • + +
      • form->getLabel('created'); ?> + form->getInput('created'); ?>
      • + +
      • form->getLabel('publish_up'); ?> + form->getInput('publish_up'); ?>
      • + +
      • form->getLabel('publish_down'); ?> + form->getInput('publish_down'); ?>
      • + + item->modified_by) : ?> +
      • form->getLabel('modified_by'); ?> + form->getInput('modified_by'); ?>
      • + +
      • form->getLabel('modified'); ?> + form->getInput('modified'); ?>
      • + + + item->version) : ?> +
      • form->getLabel('version'); ?> + form->getInput('version'); ?>
      • + + + item->hits) : ?> +
      • form->getLabel('hits'); ?> + form->getInput('hits'); ?>
      • + +
      +
      + + form->getFieldsets(); ?> + $fieldSet) : ?> + + label), $name.'-options'); ?> + description) && trim($fieldSet->description)) : ?> +

      escape(JText::_($fieldSet->description));?>

      + +
      +
        + form->getFieldset($name) as $field) : ?> +
      • label; ?> + input; ?>
      • + +
      +
      + + + + form->getFieldset('basic-limited') as $field) : ?> + input; ?> + + + + + +
      +
      + canDo->get('core.admin') ): ?> + +
      +
        + form->getFieldset('editorConfig') as $field) : ?> +
      • label; ?> + input; ?>
      • + +
      +
      + + + + + + +
      +
        +
      • + form->getLabel('images'); ?> + form->getInput('images'); ?>
      • + + form->getGroup('images') as $field) : ?> +
      • + hidden) : ?> + label; ?> + + input; ?> +
      • + + form->getGroup('urls') as $field) : ?> +
      • + hidden) : ?> + label; ?> + + input; ?> +
      • + +
      +
      + + +
      + + loadTemplate('metadata'); ?> +
      + + + + loadTemplate('associations'); ?> + + + +
      + +
      + canDo->get('core.admin')) : ?> +
      + item->id, array('useCookie' => 1)); ?> + + +
      + + form->getLabel('rules'); ?> + form->getInput('rules'); ?> +
      + + +
      + +
      + + + +
      +
      +
      +
      diff --git a/Sites/pages/administrator/templates/hathor/html/com_content/articles/default.php b/Sites/pages/administrator/templates/hathor/html/com_content/articles/default.php new file mode 100644 index 00000000..3244894c --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_content/articles/default.php @@ -0,0 +1,254 @@ +get('id'); +$listOrder = $this->escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$saveOrder = $listOrder == 'a.ordering'; +$assoc = JLanguageAssociations::isEnabled(); +$n = count($this->items); +?> + +
      +sidebar)) : ?> +
      + sidebar; ?> +
      +
      + +
      + +
      + + + +
      + + + + + + + + + + + + + + + + + + + + + + +
      +
      +
      + + + + + + + + + + + + + + + + + + + + + + + + items as $i => $item) : + $item->max_ordering = 0; //?? + $ordering = ($listOrder == 'a.ordering'); + $canCreate = $user->authorise('core.create', 'com_content.category.' . $item->catid); + $canEdit = $user->authorise('core.edit', 'com_content.article.' . $item->id); + $canCheckin = $user->authorise('core.manage', 'com_checkin') || $item->checked_out == $userId || $item->checked_out == 0; + $canEditOwn = $user->authorise('core.edit.own', 'com_content.article.' . $item->id) && $item->created_by == $userId; + $canChange = $user->authorise('core.edit.state', 'com_content.article.' . $item->id) && $canCheckin; + ?> + + + + + + + + + + + + + + + + + + + +
      + + + + + + + + + + + + + items, 'filesave.png', 'articles.saveorder'); ?> + + + + + + + + + + + + + + + +
      + id); ?> + + checked_out) : ?> + editor, $item->checked_out_time, 'articles.', $canCheckin); ?> + + + + escape($item->title); ?> + + escape($item->title); ?> + +

      + escape($item->alias)); ?>

      +
      + state, $i, 'articles.', $canChange, 'cb', $item->publish_up, $item->publish_down); ?> + + featured, $i, $canChange); ?> + + escape($item->category_title); ?> + + + + + pagination->orderUpIcon($i, $item->catid == @$this->items[$i - 1]->catid, 'articles.orderup', 'JLIB_HTML_MOVE_UP', $ordering); ?> + pagination->orderDownIcon($i, $this->pagination->total, $item->catid == @$this->items[$i + 1]->catid, 'articles.orderdown', 'JLIB_HTML_MOVE_DOWN', $ordering); ?> + + pagination->orderUpIcon($i, $item->catid == @$this->items[$i - 1]->catid, 'articles.orderdown', 'JLIB_HTML_MOVE_UP', $ordering); ?> + pagination->orderDownIcon($i, $this->pagination->total, $item->catid == @$this->items[$i + 1]->catid, 'articles.orderup', 'JLIB_HTML_MOVE_DOWN', $ordering); ?> + + + + class="text-area-order" title="title; ?> order" /> + + ordering; ?> + + + escape($item->access_level); ?> + + association):?> + id); ?> + + + created_by_alias) : ?> + escape($item->author_name); ?> +

      escape($item->created_by_alias)); ?>

      + + escape($item->author_name); ?> + +
      + created, JText::_('DATE_FORMAT_LC4')); ?> + + hits; ?> + + + + id; ?> +
      + + + authorise('core.create', 'com_content') + && $user->authorise('core.edit', 'com_content') + && $user->authorise('core.edit.state', 'com_content')) : ?> + JText::_('COM_CONTENT_BATCH_OPTIONS'), + 'footer' => $this->loadTemplate('batch_footer'), + ), + $this->loadTemplate('batch_body') + ); ?> + + + pagination->getListFooter(); ?> + + + + + + +
      + diff --git a/Sites/pages/administrator/templates/hathor/html/com_content/articles/modal.php b/Sites/pages/administrator/templates/hathor/html/com_content/articles/modal.php new file mode 100644 index 00000000..946179e2 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_content/articles/modal.php @@ -0,0 +1,134 @@ +isClient('site')) +{ + JSession::checkToken('get') or die(JText::_('JINVALID_TOKEN')); +} + +JLoader::register('ContentHelperRoute', JPATH_ROOT . '/components/com_content/helpers/route.php'); + +JHtml::addIncludePath(JPATH_COMPONENT.'/helpers/html'); + +$function = $app->input->getCmd('function', 'jSelectArticle'); +$listOrder = $this->escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +?> +
      +
      + + + +
      + + + + + + + + + state->get('filter.forcedLanguage')) : ?> + + + + + + + + +
      +
      + + + + + + + + + + + + + + + items as $i => $item) : ?> + + + + + + + + + + + + +pagination->getListFooter(); ?> + + + + + + +
      diff --git a/Sites/pages/administrator/templates/hathor/html/com_content/featured/default.php b/Sites/pages/administrator/templates/hathor/html/com_content/featured/default.php new file mode 100644 index 00000000..d47e1c34 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_content/featured/default.php @@ -0,0 +1,209 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$canOrder = $user->authorise('core.edit.state', 'com_content'); +$saveOrder = $listOrder == 'fp.ordering'; +$n = count($this->items); +?> + +
      +sidebar)) : ?> +
      + sidebar; ?> +
      +
      + +
      + +
      + + + +
      + + + + + + + + + + + + + + + + +
      +
      +
      + + + + + + + + + + + + + + + + + + + + items as $i => $item) : + $item->max_ordering = 0; //?? + $ordering = ($listOrder == 'fp.ordering'); + $assetId = 'com_content.article.' . $item->id; + $canCreate = $user->authorise('core.create', 'com_content.category.' . $item->catid); + $canEdit = $user->authorise('core.edit', 'com_content.article.' . $item->id); + $canCheckin = $user->authorise('core.manage', 'com_checkin') || $item->checked_out == $user->get('id')|| $item->checked_out == 0; + $canChange = $user->authorise('core.edit.state', 'com_content.article.' . $item->id) && $canCheckin; + ?> + + + + + + + + + + + + + + + +
      + + + + + + + + + + + items, 'filesave.png', 'featured.saveorder'); ?> + + + + + + + + + + + + + +
      + id); ?> + + checked_out) : ?> + editor, $item->checked_out_time, 'featured.', $canCheckin); ?> + + + + escape($item->title); ?> + + escape($item->title); ?> + +

      + escape($item->alias)); ?>

      +
      + state, $i, 'articles.', $canChange, 'cb', $item->publish_up, $item->publish_down); ?> + + escape($item->category_title); ?> + + + + + pagination->orderUpIcon($i, true, 'featured.orderup', 'JLIB_HTML_MOVE_UP', $ordering); ?> + pagination->orderDownIcon($i, $this->pagination->total, true, 'featured.orderdown', 'JLIB_HTML_MOVE_DOWN', $ordering); ?> + + pagination->orderUpIcon($i, true, 'featured.orderdown', 'JLIB_HTML_MOVE_UP', $ordering); ?> + pagination->orderDownIcon($i, $this->pagination->total, true, 'featured.orderup', 'JLIB_HTML_MOVE_DOWN', $ordering); ?> + + + + class="text-area-order" title="title; ?> order" /> + + ordering; ?> + + + escape($item->access_level); ?> + + created_by_alias) : ?> + escape($item->author_name); ?> +

      escape($item->created_by_alias)); ?>

      + + escape($item->author_name); ?> + +
      + created, JText::_('DATE_FORMAT_LC4')); ?> + + hits; ?> + + + + id; ?> +
      + +pagination->getListFooter(); ?> + + + + + + +
      + diff --git a/Sites/pages/administrator/templates/hathor/html/com_contenthistory/history/modal.php b/Sites/pages/administrator/templates/hathor/html/com_contenthistory/history/modal.php new file mode 100644 index 00000000..7ddbb7ad --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_contenthistory/history/modal.php @@ -0,0 +1,188 @@ + 'bottom')); +JHtml::_('behavior.multiselect'); +JHtml::_('jquery.framework'); + +$input = JFactory::getApplication()->input; +$field = $input->getCmd('field'); +$function = 'jSelectContenthistory_' . $field; +$listOrder = $this->escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$message = JText::_('COM_CONTENTHISTORY_BUTTON_SELECT_ONE', true); +$compareMessage = JText::_('COM_CONTENTHISTORY_BUTTON_SELECT_TWO', true); +JText::script('JLIB_HTML_PLEASE_MAKE_A_SELECTION_FROM_THE_LIST'); +$deleteMessage = "alert(Joomla.JText._('JLIB_HTML_PLEASE_MAKE_A_SELECTION_FROM_THE_LIST'));"; +$aliasArray = explode('.', $this->state->type_alias); +$option = (end($aliasArray) == 'category') ? 'com_categories&extension=' . implode('.', array_slice($aliasArray, 0, count($aliasArray) - 1)) : $aliasArray[0]; +$filter = JFilterInput::getInstance(); +$task = $filter->clean(end($aliasArray)) . '.loadhistory'; +$loadUrl = JRoute::_('index.php?option=' . $filter->clean($option) . '&task=' . $task); +$deleteUrl = JRoute::_('index.php?option=com_contenthistory&task=history.delete'); +$hash = $this->state->get('sha1_hash'); +$formUrl = 'index.php?option=com_contenthistory&view=history&layout=modal&tmpl=component&item_id=' . $this->state->get('item_id') . '&type_id=' + . $this->state->get('type_id') . '&type_alias=' . $this->state->get('type_alias') . '&' . JSession::getFormToken() . '=1'; + +JFactory::getDocument()->addScriptDeclaration(" + (function ($){ + $(document).ready(function (){ + $('#toolbar-load').click(function() { + var ids = $('input[id*=\'cb\']:checked'); + if (ids.length == 1) { + // Add version item id to URL + var url = $('#toolbar-load').attr('data-url') + '&version_id=' + ids[0].value; + $('#content-url').attr('data-url', url); + if (window.parent) { + window.parent.location = url; + } + } else { + alert('" . $message . "'); + } + }); + + $('#toolbar-preview').click(function() { + var windowSizeArray = ['width=800, height=600, resizable=yes, scrollbars=yes']; + var ids = $('input[id*=\'cb\']:checked'); + if (ids.length == 1) { + // Add version item id to URL + var url = $('#toolbar-preview').attr('data-url') + '&version_id=' + ids[0].value; + $('#content-url').attr('data-url', url); + if (window.parent) { + window.open(url, '', windowSizeArray); + return false; + } + } else { + alert('" . $message . "'); + } + }); + + $('#toolbar-compare').click(function() { + var windowSizeArray = ['width=1000, height=600, resizable=yes, scrollbars=yes']; + var ids = $('input[id*=\'cb\']:checked'); + if (ids.length == 2) { + // Add version item ids to URL + var url = $('#toolbar-compare').attr('data-url') + '&id1=' + ids[0].value + '&id2=' + ids[1].value; + $('#content-url').attr('data-url', url); + if (window.parent) { + window.open(url, '', windowSizeArray); + return false; + } + } else { + alert('" . $compareMessage . "'); + } + }); + }); + })(jQuery); + " +); + +?> + + + diff --git a/Sites/pages/administrator/templates/hathor/html/com_cpanel/cpanel/default.php b/Sites/pages/administrator/templates/hathor/html/com_cpanel/cpanel/default.php new file mode 100644 index 00000000..82d843dd --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_cpanel/cpanel/default.php @@ -0,0 +1,43 @@ + '1')); +if (JFactory::getUser()->authorise('core.manage', 'com_postinstall')) : + if ($this->postinstall_message_count): + echo JHtml::_('sliders.panel', JText::_('COM_CPANEL_MESSAGES_TITLE'), 'cpanel-panel-com-postinstall'); + ?> + + + +modules as $module) +{ + $output = JModuleHelper::renderModule($module); + echo JHtml::_('sliders.panel', $module->title, 'cpanel-panel-' . $module->name); + echo $output; +} + +echo JHtml::_('sliders.end'); diff --git a/Sites/pages/administrator/templates/hathor/html/com_fields/field/edit.php b/Sites/pages/administrator/templates/hathor/html/com_fields/field/edit.php new file mode 100644 index 00000000..356a1fa1 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_fields/field/edit.php @@ -0,0 +1,144 @@ + 0 )); + +$app = JFactory::getApplication(); +$input = $app->input; + +JFactory::getDocument()->addScriptDeclaration(' + Joomla.submitbutton = function(task) + { + if (task == "field.cancel" || document.formvalidator.isValid(document.getElementById("item-form"))) + { + Joomla.submitform(task, document.getElementById("item-form")); + } + }; + jQuery(document).ready(function() { + jQuery("#jform_title").data("dp-old-value", jQuery("#jform_title").val()); + jQuery("#jform_title").change(function(data, handler) { + if(jQuery("#jform_title").data("dp-old-value") == jQuery("#jform_label").val()) { + jQuery("#jform_label").val(jQuery("#jform_title").val()); + } + + jQuery("#jform_title").data("dp-old-value", jQuery("#jform_title").val()); + }); + }); +'); +?> +
      +
      +
      +
      +
        +
      • + form->getLabel('title'); ?> + form->getInput('title'); ?> +
      • +
      +
      +
      +
      +
        +
      • form->renderField('type'); ?>
      • +
      • form->renderField('name'); ?>
      • +
      • form->renderField('label'); ?>
      • +
      • form->renderField('description'); ?>
      • +
      • form->renderField('required'); ?>
      • +
      • form->renderField('default_value'); ?>
      • + + form->getFieldsets('fieldparams') as $name => $fieldSet) : ?> + form->getFieldset($name) as $field) : ?> +
      • renderField(); ?>
      • + + +
      +
      + +
      +
      + item->id, array('useCookie' => 1)); ?> + + set('fields', + array( + array( + 'published', + 'state', + 'enabled', + ), + 'group_id', + 'assigned_cat_ids', + 'access', + 'language', + 'note', + ) + ); ?> + + set('fields', null); ?> + + + set('ignore_fieldsets', array('fieldparams')); ?> + + + +
      + +
        + +
      • form->getLabel('created_user_id'); ?> + form->getInput('created_user_id'); ?>
      • + +
      • form->getLabel('created_time'); ?> + form->getInput('created_time'); ?>
      • + + item->modified_by) : ?> +
      • form->getLabel('modified_by'); ?> + form->getInput('modified_by'); ?>
      • + +
      • form->getLabel('modified_time'); ?> + form->getInput('modified_time'); ?>
      • + + +
      • form->getLabel('id'); ?> + form->getInput('id'); ?>
      • + +
      +
      + +
      +
      +
      + canDo->get('core.admin')) : ?> +
      + item->id, array('useCookie' => 1)); ?> + + +
      + + form->getLabel('rules'); ?> + form->getInput('rules'); ?> +
      + + +
      + + + form->getInput('context'); ?> + + +
      + +
      +
      diff --git a/Sites/pages/administrator/templates/hathor/html/com_fields/fields/default.php b/Sites/pages/administrator/templates/hathor/html/com_fields/fields/default.php new file mode 100644 index 00000000..a9d1d95c --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_fields/fields/default.php @@ -0,0 +1,173 @@ +get('id'); +$context = $this->escape($this->state->get('filter.context')); +$component = $this->state->get('filter.component'); +$listOrder = $this->escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$ordering = ($listOrder == 'a.ordering'); +$saveOrder = ($listOrder == 'a.ordering' && strtolower($listDirn) == 'asc'); + +// The category object of the component +$category = JCategories::getInstance(str_replace('com_', '', $component)); + +if ($saveOrder) +{ + $saveOrderingUrl = 'index.php?option=com_fields&task=fields.saveOrderAjax&tmpl=component'; + JHtml::_('sortablelist.sortable', 'fieldList', 'adminForm', strtolower($listDirn), $saveOrderingUrl, false, true); +} +?> + +
      +
      + sidebar; ?> +
      +
      +
      +
      + filterForm->getField('context')->input; ?> +
        +
      + $this)); ?> + items)) : ?> +
      + +
      + + + + + + + + + + + + + + + + + + + + + items as $i => $item) : ?> + + authorise('core.edit', $component . '.field.' . $item->id); ?> + authorise('core.admin', 'com_checkin') || $item->checked_out == $userId || $item->checked_out == 0; ?> + authorise('core.edit.own', $component . '.field.' . $item->id) && $item->created_user_id == $userId; ?> + authorise('core.edit.state', $component . '.field.' . $item->id) && $canCheckin; ?> + + + + + + + + + + + + +
      + + + + + + + + + + + + + + + +
      + pagination->getListFooter(); ?> +
      + id); ?> + + state, $i, 'fields.', $canChange); ?> + +
      + checked_out) : ?> + editor, $item->checked_out_time, 'fields.', $canCheckin); ?> + + + + escape($item->title); ?> + + escape($item->title); ?> + + + note)) : ?> + escape($item->name)); ?> + + escape($item->name), $this->escape($item->note)); ?> + + +
      + + + id); ?> + + + + + + +
      +
      +
      + escape($item->type); ?> + + escape($item->group_title); ?> + + escape($item->access_level); ?> + + + + id; ?> +
      + + authorise('core.create', $component) + && $user->authorise('core.edit', $component) + && $user->authorise('core.edit.state', $component)) : ?> + JText::_('COM_FIELDS_VIEW_FIELDS_BATCH_OPTIONS'), + 'footer' => $this->loadTemplate('batch_footer') + ), + $this->loadTemplate('batch_body') + ); ?> + + + + + +
      +
      diff --git a/Sites/pages/administrator/templates/hathor/html/com_fields/group/edit.php b/Sites/pages/administrator/templates/hathor/html/com_fields/group/edit.php new file mode 100644 index 00000000..61fc5cc7 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_fields/group/edit.php @@ -0,0 +1,126 @@ +input; + +JFactory::getDocument()->addScriptDeclaration(' + Joomla.submitbutton = function(task) + { + if (task == "group.cancel" || document.formvalidator.isValid(document.getElementById("item-form"))) + { + Joomla.submitform(task, document.getElementById("item-form")); + } + }; +'); +?> +
      +
      +
      +
      + +
        +
      • + form->getLabel('title'); ?> + form->getInput('title'); ?> +
      • +
      • + form->getLabel('description'); ?> + form->getInput('description'); ?> +
      • +
      • + form->getLabel('published'); ?> + form->getInput('published'); ?> +
      • +
      • + form->getLabel('access'); ?> + form->getInput('access'); ?> +
      • +
      • + form->getLabel('language'); ?> + form->getInput('language'); ?> +
      • +
      • + form->getLabel('note'); ?> + form->getInput('note'); ?> +
      • +
      +
      +
      +
      + +
      + item->id, array('useCookie' => 1)); ?> + +
      + +
        +
      • + form->getLabel('created_by'); ?> + form->getInput('created_by'); ?> +
      • + item->created) : ?> +
      • + form->getLabel('created'); ?> + form->getInput('created'); ?> +
      • + + item->modified_by) : ?> +
      • + form->getLabel('modified_by'); ?> + form->getInput('modified_by'); ?> +
      • +
      • + form->getLabel('modified'); ?> + form->getInput('modified'); ?> +
      • +
      • + form->getLabel('id'); ?> + form->getInput('id'); ?> +
      • + +
      +
      + +
      + + set('ignore_fieldsets', array('fieldparams')); ?> +
      +
      + + canDo->get('core.admin')) : ?> +
      + item->id, array('useCookie' => 1)); ?> + + +
      + + form->getLabel('rules'); ?> + form->getInput('rules'); ?> +
      + + +
      + + + form->getInput('context'); ?> + + +
      + +
      +
      \ No newline at end of file diff --git a/Sites/pages/administrator/templates/hathor/html/com_fields/groups/default.php b/Sites/pages/administrator/templates/hathor/html/com_fields/groups/default.php new file mode 100644 index 00000000..4b3ddbec --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_fields/groups/default.php @@ -0,0 +1,152 @@ +get('id'); + +$component = ''; +$parts = FieldsHelper::extract($this->state->get('filter.context')); + +if ($parts) +{ + $component = $this->escape($parts[0]); +} + +$listOrder = $this->escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$ordering = ($listOrder == 'a.ordering'); +$saveOrder = ($listOrder == 'a.ordering' && strtolower($listDirn) == 'asc'); + +if ($saveOrder) +{ + $saveOrderingUrl = 'index.php?option=com_fields&task=groups.saveOrderAjax&tmpl=component'; + JHtml::_('sortablelist.sortable', 'groupList', 'adminForm', strtolower($listDirn), $saveOrderingUrl, false, true); +} +?> + +
      +
      + sidebar; ?> +
      +
      +
      +
      + filterForm->getField('context')->input; ?> +
        +
      + $this)); ?> + items)) : ?> +
      + +
      + + + + + + + + + + + + + + + + + + + items as $i => $item) : ?> + + authorise('core.edit', $component . '.fieldgroup.' . $item->id); ?> + authorise('core.admin', 'com_checkin') || $item->checked_out == $userId || $item->checked_out == 0; ?> + authorise('core.edit.own', $component . '.fieldgroup.' . $item->id) && $item->created_by == $userId; ?> + authorise('core.edit.state', $component . '.fieldgroup.' . $item->id) && $canCheckin; ?> + + + + + + + + + + +
      + + + + + + + + + + + +
      + pagination->getListFooter(); ?> +
      + id); ?> + + state, $i, 'groups.', $canChange); ?> + +
      + checked_out) : ?> + editor, $item->checked_out_time, 'groups.', $canCheckin); ?> + + + + escape($item->title); ?> + + escape($item->title); ?> + + + note) : ?> + escape($item->note)); ?> + + +
      +
      + escape($item->access_level); ?> + + + + id; ?> +
      + + authorise('core.create', $component) + && $user->authorise('core.edit', $component) + && $user->authorise('core.edit.state', $component)) : ?> + JText::_('COM_FIELDS_VIEW_GROUPS_BATCH_OPTIONS'), + 'footer' => $this->loadTemplate('batch_footer') + ), + $this->loadTemplate('batch_body') + ); ?> + + + + + +
      +
      diff --git a/Sites/pages/administrator/templates/hathor/html/com_finder/filters/default.php b/Sites/pages/administrator/templates/hathor/html/com_finder/filters/default.php new file mode 100644 index 00000000..c5cffe2e --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_finder/filters/default.php @@ -0,0 +1,166 @@ +get('id'); +$listOrder = $this->escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); + +JText::script('COM_FINDER_INDEX_CONFIRM_DELETE_PROMPT'); + +JFactory::getDocument()->addScriptDeclaration(" +Joomla.submitbutton = function(pressbutton) +{ + if (pressbutton == 'filters.delete') + { + if (confirm(Joomla.JText._('COM_FINDER_INDEX_CONFIRM_DELETE_PROMPT'))) + { + Joomla.submitform(pressbutton); + } + else + { + return false; + } + } + Joomla.submitform(pressbutton); +} +"); +?> + +
      +sidebar)) : ?> +
      + sidebar; ?> +
      +
      + +
      + +
      + + + +
      + + + + +
      +
      +
      + + + + + + + + + + + + + + + + items) == 0) : ?> + + + + + + items as $i => $item) : + $canCreate = $user->authorise('core.create', 'com_finder'); + $canEdit = $user->authorise('core.edit', 'com_finder'); + $canCheckin = $user->authorise('core.manage', 'com_checkin') || $filter->checked_out == $user->get('id') || $filter->checked_out == 0; + $canChange = $user->authorise('core.edit.state', 'com_finder') && $canCheckin; + ?> + + + + + + + + + + + +
      + + + + + + + + + + + + + +
      + total == 0): + echo JText::_('COM_FINDER_NO_FILTERS'); + ?> + + + + +
      + filter_id); ?> + + checked_out) + { + echo JHtml::_('jgrid.checkedout', $i, $item->editor, $item->checked_out_time, 'filters.', $canCheckin); + } ?> + + + escape($item->title); ?> + escape($item->title); + } ?> + + state, $i, 'filters.', $canChange); ?> + + created_by_alias ?: $item->user_name; ?> + + created, JText::_('DATE_FORMAT_LC4')); ?> + + map_count; ?> + + filter_id; ?> +
      + + pagination->getListFooter(); ?> + + + + + + +
      + diff --git a/Sites/pages/administrator/templates/hathor/html/com_finder/index/default.php b/Sites/pages/administrator/templates/hathor/html/com_finder/index/default.php new file mode 100644 index 00000000..2e4576c6 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_finder/index/default.php @@ -0,0 +1,174 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$lang = JFactory::getLanguage(); + +JText::script('COM_FINDER_INDEX_CONFIRM_PURGE_PROMPT'); +JText::script('COM_FINDER_INDEX_CONFIRM_DELETE_PROMPT'); + +JFactory::getDocument()->addScriptDeclaration(" + Joomla.submitbutton = function(pressbutton) + { + if (pressbutton == 'index.purge') + { + if (confirm(Joomla.JText._('COM_FINDER_INDEX_CONFIRM_PURGE_PROMPT'))) + { + Joomla.submitform(pressbutton); + } + else + { + return false; + } + } + if (pressbutton == 'index.delete') + { + if (confirm(Joomla.JText._('COM_FINDER_INDEX_CONFIRM_DELETE_PROMPT'))) + { + Joomla.submitform(pressbutton); + } + else + { + return false; + } + } + + Joomla.submitform(pressbutton); + } +"); +?> +
      +sidebar)) : ?> +
      + sidebar; ?> +
      +
      + +
      + +
      + + + +
      + + + + + + + +
      +
      +
      + + + + + + + + + + + + + + + items) == 0) : ?> + + + + + authorise('core.manage', 'com_finder'); ?> + items as $i => $item) : ?> + + + + + + + + + + +
      + + + + + + + + + + + +
      + total == 0) + { + echo JText::_('COM_FINDER_INDEX_NO_DATA') . ' ' . JText::_('COM_FINDER_INDEX_TIP'); + } else { + echo JText::_('COM_FINDER_INDEX_NO_CONTENT'); + } + ?> +
      + link_id); ?> + + publish_start_date or (int) $item->publish_end_date or (int) $item->start_date or (int) $item->end_date) : ?> + + + escape($item->title); ?> + + published, $i, 'index.', $canChange, 'cb'); ?> + + t_title); + echo $lang->hasKey($key) ? JText::_($key) : $item->t_title; + ?> + + url) > 80) + { + echo substr($item->url, 0, 70) . '...'; + } else { + echo $item->url; + } + ?> + + indexdate, JText::_('DATE_FORMAT_LC4')); ?> +
      + + pagination->getListFooter(); ?> + + + + + + +
      + diff --git a/Sites/pages/administrator/templates/hathor/html/com_finder/maps/default.php b/Sites/pages/administrator/templates/hathor/html/com_finder/maps/default.php new file mode 100644 index 00000000..bc64dd20 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_finder/maps/default.php @@ -0,0 +1,141 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$lang = JFactory::getLanguage(); + +JText::script('COM_FINDER_MAPS_CONFIRM_DELETE_PROMPT'); + +JFactory::getDocument()->addScriptDeclaration(" + Joomla.submitbutton = function(pressbutton) + { + if (pressbutton == 'map.delete') + { + if (confirm(Joomla.JText._('COM_FINDER_MAPS_CONFIRM_DELETE_PROMPT'))) + { + Joomla.submitform(pressbutton); + } + else + { + return false; + } + } + Joomla.submitform(pressbutton); + } +"); +?> + +
      +sidebar)) : ?> +
      + sidebar; ?> +
      +
      + +
      + +
      + + + +
      + + + + + + + +
      +
      +
      + + + + + + + + + + + + + items) == 0) : ?> + + + + + authorise('core.manage', 'com_finder'); ?> + items as $i => $item) :?> + + + + + + + + +
      + + + + + + + +
      + +
      + id); ?> + + num_children === 0) : ?> + + + title); + $title = $lang->hasKey($key) ? JText::_($key) : $item->title; + echo $this->escape(($title == '*') ? JText::_('JALL_LANGUAGE') : $title); + ?> + + state, $i, 'maps.', $canChange, 'cb'); ?> + + num_children === 0) : ?> + num_nodes; ?> + +   + +
      + + pagination->getListFooter(); ?> + + + + + + +
      + diff --git a/Sites/pages/administrator/templates/hathor/html/com_installer/database/default.php b/Sites/pages/administrator/templates/hathor/html/com_installer/database/default.php new file mode 100644 index 00000000..6900428f --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_installer/database/default.php @@ -0,0 +1,79 @@ + +
      +
      +sidebar)) : ?> +
      + sidebar; ?> +
      +
      + +
      + +errorCount === 0) : ?> + 1)); ?> + + + 1)); ?> + + errorCount); ?> + +
      +
        + filterParams) : ?> +
      • + + + schemaVersion != $this->changeSet->getSchema()) : ?> +
      • schemaVersion, $this->changeSet->getSchema()); ?>
      • + + + updateVersion, JVERSION) != 0) : ?> +
      • updateVersion, JVERSION); ?>
      • + + + errors as $line => $error) : ?> + queryType; + $msgs = $error->msgElements; + $file = basename($error->file); + $msg0 = isset($msgs[0]) ? $msgs[0] : ' '; + $msg1 = isset($msgs[1]) ? $msgs[1] : ' '; + $msg2 = isset($msgs[2]) ? $msgs[2] : ' '; + $message = JText::sprintf($key, $file, $msg0, $msg1, $msg2); ?> +
      • + +
      +
      + + + +
      +
        +
      • schemaVersion); ?>
      • +
      • updateVersion); ?>
      • +
      • name); ?>
      • +
      • results['ok'])); ?>
      • +
      • results['skipped'])); ?>
      • +
      +
      + + +
      +
      + + + +
      +
      + +
      diff --git a/Sites/pages/administrator/templates/hathor/html/com_installer/default/default_ftp.php b/Sites/pages/administrator/templates/hathor/html/com_installer/default/default_ftp.php new file mode 100644 index 00000000..0ac8715c --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_installer/default/default_ftp.php @@ -0,0 +1,29 @@ + +
      + + + + + ftp instanceof Exception) : ?> +

      ftp->getMessage()); ?>

      + + +
        +
      • +
      • + +
      • +
      • +
      + +
      diff --git a/Sites/pages/administrator/templates/hathor/html/com_installer/discover/default.php b/Sites/pages/administrator/templates/hathor/html/com_installer/discover/default.php new file mode 100644 index 00000000..a6eaf8a5 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_installer/discover/default.php @@ -0,0 +1,91 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +?> + +
      +
      +sidebar)) : ?> +
      + sidebar; ?> +
      +
      + +
      + + showMessage) : ?> + loadTemplate('message'); ?> + + + ftp) : ?> + loadTemplate('ftp'); ?> + + + items)) : ?> + + + + + + + + + + + + + + + + + items as $i => $item) : ?> + + + + + + + + + + + + + +
      extension_id); ?>name; ?>type); ?>version != '' ? $item->version : ' '; ?>creationDate != '' ? $item->creationDate : ' '; ?>folder != '' ? $item->folder : JText::_('COM_INSTALLER_TYPE_NONAPPLICABLE'); ?>client; ?> + + author != '' ? $item->author : ' '; ?> + + extension_id ?>
      + pagination->getListFooter(); ?> + + +

      + +

      +

      + +

      + + + + + + + +
      + +
      diff --git a/Sites/pages/administrator/templates/hathor/html/com_installer/install/default.php b/Sites/pages/administrator/templates/hathor/html/com_installer/install/default.php new file mode 100644 index 00000000..7e979879 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_installer/install/default.php @@ -0,0 +1,15 @@ + +showMessage) : ?> +loadTemplate('message'); ?> + +loadTemplate('form'); ?> diff --git a/Sites/pages/administrator/templates/hathor/html/com_installer/install/default_form.php b/Sites/pages/administrator/templates/hathor/html/com_installer/install/default_form.php new file mode 100644 index 00000000..01662362 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_installer/install/default_form.php @@ -0,0 +1,160 @@ +addScriptDeclaration(" + Joomla.submitbutton = function() + { + var form = document.getElementById('adminForm'); + + // do field validation + if (form.install_package.value == ''){ + alert('" . JText::_('COM_INSTALLER_MSG_INSTALL_PLEASE_SELECT_A_PACKAGE', true) . "'); + } + else + { + form.installtype.value = 'upload'; + form.submit(); + } + }; + + Joomla.submitbutton3 = function() + { + var form = document.getElementById('adminForm'); + + // do field validation + if (form.install_directory.value == ''){ + alert('" . JText::_('COM_INSTALLER_MSG_INSTALL_PLEASE_SELECT_A_DIRECTORY', true) . "'); + } + else + { + JoomlaInstaller.showLoading(); + form.installtype.value = 'folder'; + form.submit(); + } + }; + + Joomla.submitbutton4 = function() + { + var form = document.getElementById('adminForm'); + + // do field validation + if (form.install_url.value == '' || form.install_url.value == 'http://' || form.install_url.value == 'https://'){ + alert('" . JText::_('COM_INSTALLER_MSG_INSTALL_ENTER_A_URL', true) . "'); + } + else + { + form.installtype.value = 'url'; + form.submit(); + } + }; + + Joomla.submitbuttonInstallWebInstaller = function() + { + var form = document.getElementById('adminForm'); + + form.install_url.value = 'https://appscdn.joomla.org/webapps/jedapps/webinstaller.xml'; + + Joomla.submitbutton4(); + }; + + // Add spindle-wheel for installations: + jQuery(document).ready(function($) { + var outerDiv = $(\"#installer-install\"); + + JoomlaInstaller.getLoadingOverlay() + .css(\"top\", outerDiv.position().top - $(window).scrollTop()) + .css(\"left\", \"0\") + .css(\"width\", \"100%\") + .css(\"height\", \"100%\") + .css(\"display\", \"none\") + .css(\"margin-top\", \"-10px\"); + }); + + var JoomlaInstaller = { + getLoadingOverlay: function () { + return jQuery(\"#loading\"); + }, + showLoading: function () { + this.getLoadingOverlay().css(\"display\", \"block\"); + }, + hideLoading: function () { + this.getLoadingOverlay().css(\"display\", \"none\"); + } + }; +"); + +JFactory::getDocument()->addStyleDeclaration( + ' + #loading { + background: rgba(255, 255, 255, .8) url(\'' . JHtml::_('image', 'jui/ajax-loader.gif', '', null, true, true) . '\') 50% 15% no-repeat; + position: fixed; + opacity: 0.8; + -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity = 80); + filter: alpha(opacity = 80); + overflow: hidden; + } + ' +); +?> +
      +
      + sidebar)) : ?> +
      + sidebar; ?> +
      +
      + +
      + + + showJedAndWebInstaller && !$this->showMessage) : ?> +
      + "> +

       

      + +
      + + + ftp) : ?> + loadTemplate('ftp'); ?> + +
      + + trigger('onInstallerViewBeforeFirstTab', array()); ?> + + + trigger('onInstallerAddInstallationTab', array()); ?> + +
      + +
      + + + trigger('onInstallerViewAfterLastTab', array()); ?> + + + + enqueueMessage(JText::_('COM_INSTALLER_NO_INSTALLATION_PLUGINS_FOUND'), 'warning'); ?> + + + + + + +
      +
      + +
      +
      diff --git a/Sites/pages/administrator/templates/hathor/html/com_installer/languages/default.php b/Sites/pages/administrator/templates/hathor/html/com_installer/languages/default.php new file mode 100644 index 00000000..8b2b1e20 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_installer/languages/default.php @@ -0,0 +1,113 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); + +$version = new JVersion; + +// Add spindle-wheel for language installation. +JFactory::getDocument()->addScriptDeclaration(' +jQuery(document).ready(function($) { + Joomla.loadingLayer("load"); + $("#adminForm").on("submit", function(e) { + if (document.getElementsByName("task")[0].value == "languages.install") + { + Joomla.loadingLayer("show"); + } + }); +}); +'); +?> +
      +
      + sidebar)) : ?> +
      + sidebar; ?> +
      +
      + +
      + + + items) || $this->escape($this->state->get('filter.search'))) : ?> + loadTemplate('filter'); ?> + + + + + + + + + + + + items as $i => $language) : + preg_match('#^pkg_([a-z]{2,3}-[A-Z]{2})$#', $language->element, $element); + $language->code = $element[1]; + ?> + + + + + + + + + +
      + + + + + + + +
      + installedLang[0][$language->code]) || isset($this->installedLang[1][$language->code])) ? 'REINSTALL' : 'INSTALL'; ?> + detailsurl . '\'; Joomla.submitbutton(\'install.install\');'; ?> + + + name; ?> + + + + version, 0, 3) != $minorVersion + || substr($language->version, 0, 5) != $version->getShortVersion()) : ?> +
      + +
      + version; ?> + + type)); ?> + + detailsurl; ?> +
      + pagination->getListFooter(); ?> + +
      + + + + + + + + + + +
      + +
      diff --git a/Sites/pages/administrator/templates/hathor/html/com_installer/languages/default_filter.php b/Sites/pages/administrator/templates/hathor/html/com_installer/languages/default_filter.php new file mode 100644 index 00000000..86611438 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_installer/languages/default_filter.php @@ -0,0 +1,21 @@ + +
      + + +
      +
      diff --git a/Sites/pages/administrator/templates/hathor/html/com_installer/manage/default.php b/Sites/pages/administrator/templates/hathor/html/com_installer/manage/default.php new file mode 100644 index 00000000..5c276efc --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_installer/manage/default.php @@ -0,0 +1,137 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +?> + +
      +
      +sidebar)) : ?> +
      + sidebar; ?> +
      +
      + +
      + + showMessage) : ?> + loadTemplate('message'); ?> + + + ftp) : ?> + loadTemplate('ftp'); ?> + + + loadTemplate('filter'); ?> + + items)) : ?> + + + + + + + + + + + + + + + + + + + items as $i => $item) : ?> + + + + + + + + + + + + + + + +
      + + + + + + + + + + + + + + + + + + + + + +
      + extension_id); ?> + + + name; ?> + + + client; ?> + + element) : ?> + X + + status, $i, $item->status < 2, 'cb'); ?> + + + type); ?> + + version != '' ? $item->version : ' '; ?> + + creationDate != '' ? $item->creationDate : ' '; ?> + + + author != '' ? $item->author : ' '; ?> + + + folder != '' ? $item->folder : JText::_('COM_INSTALLER_TYPE_NONAPPLICABLE'); ?> + + package_id ?: JText::_('COM_INSTALLER_TYPE_NONAPPLICABLE'); ?> + + extension_id ?> +
      + pagination->getListFooter(); ?> + + + + + + + +
      + +
      diff --git a/Sites/pages/administrator/templates/hathor/html/com_installer/manage/default_filter.php b/Sites/pages/administrator/templates/hathor/html/com_installer/manage/default_filter.php new file mode 100644 index 00000000..a1a27917 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_installer/manage/default_filter.php @@ -0,0 +1,60 @@ + +
      + + + +
      + + + + + + + + + + + + + + +
      + +
      +
      diff --git a/Sites/pages/administrator/templates/hathor/html/com_installer/update/default.php b/Sites/pages/administrator/templates/hathor/html/com_installer/update/default.php new file mode 100644 index 00000000..cebe20a9 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_installer/update/default.php @@ -0,0 +1,91 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +?> + +
      +
      +sidebar)) : ?> +
      + sidebar; ?> +
      +
      + +
      + + showMessage) : ?> + loadTemplate('message'); ?> + + + ftp) : ?> + loadTemplate('ftp'); ?> + + + items)) : ?> + + + + + + + + + + + + + + + + items as $i => $item) : ?> + client_id ? JText::_('JADMINISTRATOR') : JText::_('JSITE'); ?> + + + + + + + + + + + + +
      update_id); ?> + + name; ?> + + + extension_id ? JText::_('COM_INSTALLER_MSG_UPDATE_UPDATE') : JText::_('COM_INSTALLER_NEW_INSTALL') ?> + type) ?>version ?>folder != '' ? $item->folder : JText::_('COM_INSTALLER_TYPE_NONAPPLICABLE'); ?>detailsurl ?> + infourl)) : ?> +
      infourl;?> + +
      + pagination->getListFooter(); ?> + + +

      + + + + + + + +
      + +
      diff --git a/Sites/pages/administrator/templates/hathor/html/com_installer/warnings/default.php b/Sites/pages/administrator/templates/hathor/html/com_installer/warnings/default.php new file mode 100644 index 00000000..79f72a12 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_installer/warnings/default.php @@ -0,0 +1,49 @@ + +
      +
      +sidebar)) : ?> +
      + sidebar; ?> +
      +
      + +
      + +messages)) +{ + echo '

      ' . JText::_('COM_INSTALLER_MSG_WARNINGS_NONE') . '

      '; +} +else +{ + echo JHtml::_('sliders.start', 'warning-sliders', array('useCookie' => 1)); + foreach ($this->messages as $message) + { + echo JHtml::_('sliders.panel', $message['message'], str_replace(' ', '', $message['message'])); + echo '
      ' . $message['description'] . '
      '; + } + echo JHtml::_('sliders.panel', JText::_('COM_INSTALLER_MSG_WARNINGFURTHERINFO'), 'furtherinfo-pane'); + echo '
      ' . JText::_('COM_INSTALLER_MSG_WARNINGFURTHERINFODESC') . '
      '; + echo JHtml::_('sliders.end'); +} +?> +
      +
      + + +
      +
      + +
      diff --git a/Sites/pages/administrator/templates/hathor/html/com_joomlaupdate/default/default.php b/Sites/pages/administrator/templates/hathor/html/com_joomlaupdate/default/default.php new file mode 100644 index 00000000..ec95690b --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_joomlaupdate/default/default.php @@ -0,0 +1,79 @@ +addScriptDeclaration(" +jQuery(document).ready(function($) { + $('#extraction_method').change(function(e){ + extractionMethodHandler('#extraction_method', 'row_ftp'); + }); + $('#upload_method').change(function(e){ + extractionMethodHandler('#upload_method', 'upload_ftp'); + }); + + $('button.submit').on('click', function() { + $('div.download_message').show(); + }); +});"); +?> + +
      +
      + + showUploadAndUpdate) : ?> + + + + selfUpdate) : ?> + + enqueueMessage(JText::_('COM_JOOMLAUPDATE_VIEW_DEFAULT_INSTALL_SELF_UPDATE_FIRST'), 'error'); ?> + loadTemplate('updatemefirst'); ?> + + updateInfo['object']->downloadurl->_data) && $this->updateInfo['installed'] < $this->updateInfo['latest']) : ?> + + loadTemplate('nodownload'); ?> + updateInfo['hasUpdate']) : ?> + + loadTemplate('reinstall'); ?> + + + loadTemplate('update'); ?> + + + + + + + +
      + + + showUploadAndUpdate) : ?> + + loadTemplate('upload'); ?> + + + + +
      +
      diff --git a/Sites/pages/administrator/templates/hathor/html/com_languages/installed/default.php b/Sites/pages/administrator/templates/hathor/html/com_languages/installed/default.php new file mode 100644 index 00000000..74da9225 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_languages/installed/default.php @@ -0,0 +1,123 @@ +get('id'); +?> + +
      +sidebar)) : ?> +
      + sidebar; ?> +
      +
      + +
      + +
      + +
      + + + + +
      +
      + ftp) : ?> + loadTemplate('ftp');?> + + + + + + + + + + + + + + + + + + rows as $i => $row) : + $canCreate = $user->authorise('core.create', 'com_languages'); + $canEdit = $user->authorise('core.edit', 'com_languages'); + $canChange = $user->authorise('core.edit.state', 'com_languages'); + ?> + + + + + + + + + + + + +
      +   + + + + + + + + + + + + + + +
      + language);?> + + escape($row->name); ?> + + escape($row->language); ?> + + published, $i, 'installed.', !$row->published && $canChange);?> + + escape($row->version); ?> + + escape($row->creationDate); ?> + + escape($row->author); ?> + + escape($row->authorEmail)); ?> +
      + + pagination->getListFooter(); ?> + + + + +
      + diff --git a/Sites/pages/administrator/templates/hathor/html/com_languages/installed/default_ftp.php b/Sites/pages/administrator/templates/hathor/html/com_languages/installed/default_ftp.php new file mode 100644 index 00000000..a89c2765 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_languages/installed/default_ftp.php @@ -0,0 +1,29 @@ + +
      + + + + + +

      message); ?>

      + + +
      + + +
      +
      + + +
      +
      diff --git a/Sites/pages/administrator/templates/hathor/html/com_languages/languages/default.php b/Sites/pages/administrator/templates/hathor/html/com_languages/languages/default.php new file mode 100644 index 00000000..48f46ef6 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_languages/languages/default.php @@ -0,0 +1,180 @@ +get('id'); +$n = count($this->items); +$listOrder = $this->escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$canOrder = $user->authorise('core.edit.state', 'com_languages'); +$saveOrder = $listOrder == 'a.ordering'; +?> + +
      +sidebar)) : ?> +
      + sidebar; ?> +
      +
      + +
      + +
      + + + +
      + + + + +
      +
      + + + + + + + + + + + + + + + + + + + items as $i => $item) : + $ordering = ($listOrder == 'a.ordering'); + $canCreate = $user->authorise('core.create', 'com_languages'); + $canEdit = $user->authorise('core.edit', 'com_languages'); + $canChange = $user->authorise('core.edit.state', 'com_languages'); + ?> + + + + + + + + + + + + + + +
      + + + + + + + + + + + + + + + + + items, 'filesave.png', 'languages.saveorder'); ?> + + + + + +
      + lang_id); ?> + + + + + escape($item->title); ?> + + escape($item->title); ?> + + + + escape($item->title_native); ?> + + escape($item->lang_code); ?> + + escape($item->sef); ?> + + image) : ?> + image . '.gif', $item->image, null, true); ?> escape($item->image); ?> + + + + + published, $i, 'languages.', $canChange); ?> + + + + + pagination->orderUpIcon($i, true, 'languages.orderup', 'JLIB_HTML_MOVE_UP', $ordering); ?> + pagination->orderDownIcon($i, $this->pagination->total, true, 'languages.orderdown', 'JLIB_HTML_MOVE_DOWN', $ordering); ?> + + pagination->orderUpIcon($i, true, 'languages.orderdown', 'JLIB_HTML_MOVE_UP', $ordering); ?> + pagination->orderDownIcon($i, $this->pagination->total, true, 'languages.orderup', 'JLIB_HTML_MOVE_DOWN', $ordering); ?> + + + + class="text-area-order" /> + + ordering; ?> + + + home == '1') : ?> + + + + + + escape($item->lang_id); ?> +
      + + pagination->getListFooter(); ?> + +
      + + + + + +
      +
      + diff --git a/Sites/pages/administrator/templates/hathor/html/com_languages/overrides/default.php b/Sites/pages/administrator/templates/hathor/html/com_languages/overrides/default.php new file mode 100644 index 00000000..3edc7f81 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_languages/overrides/default.php @@ -0,0 +1,109 @@ +state->get('filter.client') == 'site' ? JText::_('JSITE') : JText::_('JADMINISTRATOR'); +$language = $this->state->get('filter.language'); +$listOrder = $this->escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +?> + +
      +sidebar)) : ?> +
      + sidebar; ?> +
      +
      + +
      + +
      + +
      + +
      +
      + +
      + + + + + + + + + + + + + + + + + + authorise('core.edit', 'com_languages'); + $i = 0; + foreach ($this->items as $key => $text) : ?> + + + + + + + + + +
      + + + + + + + + + +
      + pagination->getListFooter(); ?> +
      + + + + escape($key); ?> + + escape($key); ?> + + + escape($text); ?> + + + + +
      +
      + + + + + +
      +
      + diff --git a/Sites/pages/administrator/templates/hathor/html/com_menus/item/edit.php b/Sites/pages/administrator/templates/hathor/html/com_menus/item/edit.php new file mode 100644 index 00000000..4b052b0e --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_menus/item/edit.php @@ -0,0 +1,184 @@ +'); + option.text(val.title).val(val.id); + $('#jform_parent_id').append(option); + }); + $('#jform_parent_id').trigger('liszt:updated'); + }); + }); +}); +Joomla.submitbutton = function(task, type){ + if (task == 'item.setType' || task == 'item.setMenuType') + { + if (task == 'item.setType') + { + jQuery('#item-form input[name=\"jform[type]\"]').val(type); + jQuery('#fieldtype').val('type'); + } else { + jQuery('#item-form input[name=\"jform[menutype]\"]').val(type); + } + Joomla.submitform('item.setType', document.getElementById('item-form')); + } else if (task == 'item.cancel' || document.formvalidator.isValid(document.getElementById('item-form'))) + { + Joomla.submitform(task, document.getElementById('item-form')); + } + else + { + // special case for modal popups validation response + jQuery('#item-form .modal-value.invalid').each(function(){ + var field = jQuery(this), + idReversed = field.attr('id').split('').reverse().join(''), + separatorLocation = idReversed.indexOf('_'), + nameId = '#' + idReversed.substr(separatorLocation).split('').reverse().join('') + 'name'; + jQuery(nameId).addClass('invalid'); + }); + } +}; +"; +// Add the script to the document head. +JFactory::getDocument()->addScriptDeclaration($script); + +// In case of modal +$input = JFactory::getApplication()->input; +$isModal = $input->get('layout') == 'modal' ? true : false; +$layout = $isModal ? 'modal' : 'edit'; +$tmpl = $isModal || $input->get('tmpl', '', 'cmd') === 'component' ? '&tmpl=component' : ''; +$clientId = $this->state->get('item.client_id', 0); +?> + + diff --git a/Sites/pages/administrator/templates/hathor/html/com_menus/item/edit_options.php b/Sites/pages/administrator/templates/hathor/html/com_menus/item/edit_options.php new file mode 100644 index 00000000..fd831fab --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_menus/item/edit_options.php @@ -0,0 +1,70 @@ + +form->getFieldsets('request'); + + if (!empty($fieldSets)) + { + $fieldSet = array_shift($fieldSets); + $label = !empty($fieldSet->label) ? $fieldSet->label : 'COM_MENUS_'.$fieldSet->name.'_FIELDSET_LABEL'; + echo JHtml::_('sliders.panel', JText::_($label), 'request-options'); + if (isset($fieldSet->description) && trim($fieldSet->description)) : + echo '

      '.$this->escape(JText::_($fieldSet->description)).'

      '; + endif; + ?> +
      + + +
        + form->getFieldset('request') as $field) : ?> + hidden) : ?> +
      • + label; ?> + input; ?> +
      • + input; ?> + + +
      + +
      +form->getFieldsets('params'); + + foreach ($fieldSets as $name => $fieldSet) : + $label = !empty($fieldSet->label) ? $fieldSet->label : 'COM_MENUS_'.$name.'_FIELDSET_LABEL'; + echo JHtml::_('sliders.panel', JText::_($label), $name.'-options'); + if (isset($fieldSet->description) && trim($fieldSet->description)) : + echo '

      '.$this->escape(JText::_($fieldSet->description)).'

      '; + endif; + ?> +
      +
      + +
        + form->getFieldset($name) as $field) : ?> +
      • label; ?> + input; ?>
      • + +
      +
      + + + state->get('item.client_id') != 1) : ?> + + loadTemplate('associations'); ?> + diff --git a/Sites/pages/administrator/templates/hathor/html/com_menus/items/default.php b/Sites/pages/administrator/templates/hathor/html/com_menus/items/default.php new file mode 100644 index 00000000..ce40325e --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_menus/items/default.php @@ -0,0 +1,258 @@ +get('id'); +$listOrder = $this->escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$ordering = ($listOrder == 'a.lft'); +$canOrder = $user->authorise('core.edit.state', 'com_menus'); +$saveOrder = ($listOrder == 'a.lft' && $listDirn == 'asc'); +$menutypeid = (int) $this->state->get('menutypeid'); +$assoc = JLanguageAssociations::isEnabled() && $this->state->get('filter.client_id') == 0; +?> + + +
      +sidebar)) : ?> +
      + sidebar; ?> +
      +
      + +
      + +
      + + +
      + + + + + + + + + + + + + + + + +
      +
      +
      + + + + + + + + + + + state->get('filter.client_id') == 0): ?> + + + + + + + + + + + + items as $i => $item) : + $orderkey = array_search($item->id, $this->ordering[$item->parent_id]); + $canCreate = $user->authorise('core.create', 'com_menus.menu.' . $menutypeid); + $canEdit = $user->authorise('core.edit', 'com_menus.menu.' . $menutypeid); + $canCheckin = $user->authorise('core.manage', 'com_checkin') || $item->checked_out == $user->get('id')|| $item->checked_out == 0; + $canChange = $user->authorise('core.edit.state', 'com_menus.menu.' . $menutypeid) && $canCheckin; + ?> + + + + + + + + state->get('filter.client_id') == 0): ?> + + + + + + + + + + +
      + + + + + + + + + items, 'filesave.png', 'items.saveorder'); ?> + + + + + + + + + + + + + +
      + id); ?> + + |—', $item->level - 1) ?> + checked_out) : ?> + editor, $item->checked_out_time, 'items.', $canCheckin); ?> + + protected) : ?> + + escape($item->title); ?> + + escape($item->title); ?> + +

      + |—', $item->level - 1) ?> + type != 'url') : ?> + note)) : ?> + escape($item->alias)); ?> + + escape($item->alias), $this->escape($item->note)); ?> + + type == 'url' && $item->note) : ?> + escape($item->note)); ?> +

      +
      + published, $i, $canChange, 'cb'); ?> + + + + pagination->orderUpIcon($i, isset($this->ordering[$item->parent_id][$orderkey - 1]), 'items.orderup', 'JLIB_HTML_MOVE_UP', $ordering); ?> + pagination->orderDownIcon($i, $this->pagination->total, isset($this->ordering[$item->parent_id][$orderkey + 1]), 'items.orderdown', 'JLIB_HTML_MOVE_DOWN', $ordering); ?> + + + class="text-area-order" title="title; ?> order" /> + + + + + escape($item->access_level); ?> + + + escape($item->item_type); ?> + + type == 'component') : ?> + language == '*' || $item->home == '0'):?> + home, $i, 'items.', ($item->language != '*' || !$item->home) && $canChange && !$item->protected); ?> + + + language_image) : ?> + language_image . '.gif', $item->language_title, array('title' => JText::sprintf('COM_MENUS_GRID_UNSET_LANGUAGE', $item->language_title)), true); ?> + + language_sef; ?> + + + + language_image) : ?> + language_image . '.gif', $item->language_title, array('title' => $item->language_title), true); ?> + + language_sef; ?> + + + + + association):?> + id); ?> + + + + + + id; ?> +
      + + pagination->getListFooter(); ?> +
      + + + authorise('core.create', 'com_menus') || $user->authorise('core.edit', 'com_menus')) : ?> + JText::_('COM_MENUS_BATCH_OPTIONS'), + 'footer' => $this->loadTemplate('batch_footer'), + ), + $this->loadTemplate('batch_body') + ); ?> + + + + + + + +
      + diff --git a/Sites/pages/administrator/templates/hathor/html/com_menus/menu/edit.php b/Sites/pages/administrator/templates/hathor/html/com_menus/menu/edit.php new file mode 100644 index 00000000..39285442 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_menus/menu/edit.php @@ -0,0 +1,72 @@ +addScriptDeclaration(" + Joomla.submitbutton = function(task) + { + var form = document.getElementById('item-form'); + if (task == 'menu.cancel' || document.formvalidator.isValid(form)) + { + Joomla.submitform(task, form); + } + }; +"); +?> + + diff --git a/Sites/pages/administrator/templates/hathor/html/com_menus/menus/default.php b/Sites/pages/administrator/templates/hathor/html/com_menus/menus/default.php new file mode 100644 index 00000000..68fa2f9d --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_menus/menus/default.php @@ -0,0 +1,206 @@ +get('id'); +$listOrder = $this->escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$modMenuId = (int) $this->get('ModMenuId'); + +$script = array(); +$script[] = 'jQuery(document).ready(function() {'; + +foreach ($this->items as $item) : + if ($user->authorise('core.edit', 'com_menus')) : + $script[] = ' function jSelectPosition_' . $item->id . '(name) {'; + $script[] = ' document.getElementById("' . $item->id . '").value = name;'; + $script[] = ' jQuery(".modal").modal("hide");'; + $script[] = ' };'; + endif; +endforeach; + +$script[] = ' jQuery(".modal").on("hidden", function () {'; +$script[] = ' setTimeout(function(){'; +$script[] = ' window.parent.location.reload();'; +$script[] = ' },1000);'; +$script[] = ' });'; +$script[] = '});'; + +JFactory::getDocument()->addScriptDeclaration(implode("\n", $script)); +?> +
      +sidebar)) : ?> +
      + sidebar; ?> +
      +
      + +
      + +
      + + +
      +
      + + + + + + + + + + + + + + + + + + items as $i => $item) : + $canCreate = $user->authorise('core.create', 'com_menus'); + $canEdit = $user->authorise('core.edit', 'com_menus'); + $canChange = $user->authorise('core.edit.state', 'com_menus'); + $canManageItems = $user->authorise('core.manage', 'com_menus.menu.' . (int) $item->id); + ?> + + + + + + + + + + + +
      + + + + + + + + + +
      + + + + + +
      + id); ?> + + + + escape($item->title); ?> + + escape($item->title); ?> + +

      ( + + id).' title='.$this->escape($item->description).'">'. + $this->escape($item->menutype).''; ?>) + + escape($item->menutype)?>) + +

      +
      + + count_published; ?> + + + count_unpublished; ?> + + + count_trashed; ?> + + + modules[$item->menutype] as &$module) : ?> + + id.'&return='.$return.'&tmpl=component&layout=modal'); ?> + id . 'Modal', + array( + 'url' => $link, + 'title' => JText::_('COM_MENUS_EDIT_MODULE_SETTINGS'), + 'height' => '300px', + 'width' => '800px', + 'footer' => '' + . '', + ) + ); ?> + + + + menutype); ?> + + $link, + 'title' => JText::_('COM_MENUS_EDIT_MODULE_SETTINGS'), + 'height' => '500px', + 'width' => '800px', + 'footer' => '', + ) + ); ?> + + + id; ?> +
      + + pagination->getListFooter(); ?> + + + + + + +
      + diff --git a/Sites/pages/administrator/templates/hathor/html/com_menus/menutypes/default.php b/Sites/pages/administrator/templates/hathor/html/com_menus/menutypes/default.php new file mode 100644 index 00000000..375a8afd --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_menus/menutypes/default.php @@ -0,0 +1,53 @@ +input; +// Checking if loaded via index.php or component.php +$tmpl = ($input->getCmd('tmpl') != '') ? '1' : ''; + +JFactory::getDocument()->addScriptDeclaration( + ' + setmenutype = function(type) { + var tmpl = ' . json_encode($tmpl) . '; + if (tmpl) + { + window.parent.Joomla.submitbutton("item.setType", type); + window.parent.jQuery("#menuTypeModal").modal("hide"); + } + else + { + window.location="index.php?option=com_menus&view=item&task=item.setType&layout=edit&type=" + type; + } + }; + ' +); +?> + + + diff --git a/Sites/pages/administrator/templates/hathor/html/com_messages/message/edit.php b/Sites/pages/administrator/templates/hathor/html/com_messages/message/edit.php new file mode 100644 index 00000000..483db077 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_messages/message/edit.php @@ -0,0 +1,47 @@ +addScriptDeclaration(" + Joomla.submitbutton = function(task) + { + if (task == 'message.cancel' || document.formvalidator.isValid(document.getElementById('message-form'))) + { + Joomla.submitform(task, document.getElementById('message-form')); + } + } +"); +?> + +
      +
      +
        +
      • form->getLabel('user_id_to'); ?> + form->getInput('user_id_to'); ?>
      • + +
      • form->getLabel('subject'); ?> + form->getInput('subject'); ?>
      • +
      +
      +
      + form->getLabel('message'); ?> +
        +
      • form->getInput('message'); ?>
      • +
      +
      + + +
      diff --git a/Sites/pages/administrator/templates/hathor/html/com_messages/messages/default.php b/Sites/pages/administrator/templates/hathor/html/com_messages/messages/default.php new file mode 100644 index 00000000..edf21d94 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_messages/messages/default.php @@ -0,0 +1,110 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +?> + +
      +sidebar)) : ?> +
      + sidebar; ?> +
      +
      + +
      + +
      + + +
      + + + + + +
      +
      +
      + + + + + + + + + + + + + + items as $i => $item) : + $canChange = $user->authorise('core.edit.state', 'com_messages'); + ?> + + + + + + + + + +
      + + + + + + + + + +
      + message_id); ?> + + + escape($item->subject); ?> + + state, $i, $canChange); ?> + + user_from; ?> + + date_time, JText::_('DATE_FORMAT_LC2')); ?> +
      + + pagination->getListFooter(); ?> + + + + + + +
      + diff --git a/Sites/pages/administrator/templates/hathor/html/com_modules/module/edit.php b/Sites/pages/administrator/templates/hathor/html/com_modules/module/edit.php new file mode 100644 index 00000000..e30e70b3 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_modules/module/edit.php @@ -0,0 +1,141 @@ +item->module) || $this->item->module == 'custom' || $this->item->module == 'mod_custom'; + +$script = "Joomla.submitbutton = function(task) + { + if (task == 'module.cancel' || document.formvalidator.isValid(document.getElementById('module-form'))) {"; +if ($hasContent) +{ + $script .= $this->form->getField('content')->save(); +} +$script .= " Joomla.submitform(task, document.getElementById('module-form')); + if (self != top) + { + window.parent.jQuery('.modal').modal('hide'); + } + } + }"; + +JFactory::getDocument()->addScriptDeclaration($script); +?> +
      + +
      +
      +
      + +
        + +
      • form->getLabel('title'); ?> + form->getInput('title'); ?>
      • + +
      • form->getLabel('showtitle'); ?> + form->getInput('showtitle'); ?>
      • + +
      • form->getLabel('position'); ?> + form->getInput('custom_position'); ?> + + form->getInput('position'); ?>
      • + + item->xml->name != 'Login Form') : ?> +
      • form->getLabel('published'); ?> + form->getInput('published'); ?>
      • + + +
      • form->getLabel('access'); ?> + form->getInput('access'); ?>
      • + +
      • form->getLabel('ordering'); ?> + form->getInput('ordering'); ?>
      • + + item->xml->name != 'Login Form') : ?> +
      • form->getLabel('publish_up'); ?> + form->getInput('publish_up'); ?>
      • + +
      • form->getLabel('publish_down'); ?> + form->getInput('publish_down'); ?>
      • + + +
      • form->getLabel('language'); ?> + form->getInput('language'); ?>
      • + +
      • form->getLabel('note'); ?> + form->getInput('note'); ?>
      • + + item->id) : ?> +
      • form->getLabel('id'); ?> + form->getInput('id'); ?>
      • + + +
      • form->getLabel('module'); ?> + form->getInput('module'); ?> + item->xml) echo ($text = (string) $this->item->xml->name) ? JText::_($text) : $this->item->module;else echo JText::_(COM_MODULES_ERR_XML);?>
      • + +
      • form->getLabel('client_id'); ?> + + form->getInput('client_id'); ?>
      • +
      +
      + + item->xml) : ?> + item->xml->description)) : ?> + + + +
      +
      + +
      + + + + +
      +
      +
      + +
      + + loadTemplate('options'); ?> + +
      + + +
      +
      + +
        +
      • form->getLabel('content'); ?> +
        + form->getInput('content'); ?>
      • +
      +
      +
      + + + item->client_id == 0) :?> +
      + loadTemplate('assignment'); ?> +
      + + +
      + + +
      +
      +
      diff --git a/Sites/pages/administrator/templates/hathor/html/com_modules/module/edit_assignment.php b/Sites/pages/administrator/templates/hathor/html/com_modules/module/edit_assignment.php new file mode 100644 index 00000000..e734afea --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_modules/module/edit_assignment.php @@ -0,0 +1,128 @@ +addScriptDeclaration(" + window.addEvent('domready', function(){ + validate(); + document.getElements('select').addEvent('change', function(e){validate();}); + }); + function validate(){ + var value = document.id('jform_assignment').value; + var list = document.id('menu-assignment'); + if (value == '-' || value == '0'){ + $$('.jform-assignments-button').each(function(el) {el.setProperty('disabled', true); }); + list.getElements('input').each(function(el){ + el.setProperty('disabled', true); + if (value == '-'){ + el.setProperty('checked', false); + } else { + el.setProperty('checked', true); + } + }); + } else { + $$('.jform-assignments-button').each(function(el) {el.setProperty('disabled', false); }); + list.getElements('input').each(function(el){ + el.setProperty('disabled', false); + }); + } + } +"); +?> + +
      + + + +
      + + +
      + + + + + + + + + +
      + + +
      diff --git a/Sites/pages/administrator/templates/hathor/html/com_modules/module/edit_options.php b/Sites/pages/administrator/templates/hathor/html/com_modules/module/edit_options.php new file mode 100644 index 00000000..efa088a0 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_modules/module/edit_options.php @@ -0,0 +1,37 @@ +form->getFieldsets('params'); + + foreach ($fieldSets as $name => $fieldSet) : + $label = !empty($fieldSet->label) ? $fieldSet->label : 'COM_MODULES_'.$name.'_FIELDSET_LABEL'; + echo JHtml::_('sliders.panel', JText::_($label), $name.'-options'); + if (isset($fieldSet->description) && trim($fieldSet->description)) : + echo '

      '.$this->escape(JText::_($fieldSet->description)).'

      '; + endif; + ?> +
      + + +
        + form->getFieldset($name) as $field) : ?> + hidden) : ?> +
      • + label; ?> + input; ?> +
      • + input; ?> + + +
      + +
      + diff --git a/Sites/pages/administrator/templates/hathor/html/com_modules/modules/default.php b/Sites/pages/administrator/templates/hathor/html/com_modules/modules/default.php new file mode 100644 index 00000000..36624e5c --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_modules/modules/default.php @@ -0,0 +1,252 @@ +state->get('client_id') ? 'administrator' : 'site'; +$user = JFactory::getUser(); +$listOrder = $this->escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$canOrder = $user->authorise('core.edit.state', 'com_modules'); +$saveOrder = $listOrder == 'ordering'; +?> + +
      +sidebar)) : ?> +
      + sidebar; ?> +
      +
      + +
      + +
      + + + +
      + + + + + + + + + + + + + + + + + + + + +
      +
      +
      + + + + + + + + + + + + + + + + + + + items as $i => $item) : + $ordering = ($listOrder == 'ordering'); + $canCreate = $user->authorise('core.create', 'com_modules'); + $canEdit = $user->authorise('core.edit', 'com_modules'); + $canCheckin = $user->authorise('core.manage', 'com_checkin') || $item->checked_out == $user->get('id') || $item->checked_out == 0; + $canChange = $user->authorise('core.edit.state', 'com_modules') && $canCheckin; + ?> + + + + + + + + + + + + + + + +
      + + + + + + + + + + + items, 'filesave.png', 'modules.saveorder'); ?> + + + + + + + + + + + +
      + id); ?> + + checked_out) : ?> + editor, $item->checked_out_time, 'modules.', $canCheckin); ?> + + + + escape($item->title); ?> + + escape($item->title); ?> + + note)) : ?> +

      + escape($item->note)); ?>

      + +
      + + enabled > 0) : ?> + published, $i, $canChange, 'cb'); ?> + + + + + + position; ?> + + + + + pagination->orderUpIcon($i, @$this->items[$i - 1]->position == $item->position, 'modules.orderup', 'JLIB_HTML_MOVE_UP', $ordering); ?> + pagination->orderDownIcon($i, $this->pagination->total, @$this->items[$i + 1]->position == $item->position, 'modules.orderdown', 'JLIB_HTML_MOVE_DOWN', $ordering); ?> + + pagination->orderUpIcon($i, @$this->items[$i - 1]->position == $item->position, 'modules.orderdown', 'JLIB_HTML_MOVE_UP', $ordering); ?> + pagination->orderDownIcon($i, $this->pagination->total, @$this->items[$i + 1]->position == $item->position, 'modules.orderup', 'JLIB_HTML_MOVE_DOWN', $ordering); ?> + + + + class="text-area-order" title="title; ?> order" /> + + ordering; ?> + + + name; ?> + + pages; ?> + + escape($item->access_level); ?> + + language == ''):?> + + language == '*'):?> + + + language_title ? JHtml::_('image', 'mod_languages/' . $item->language_image . '.gif', $item->language_title, array('title' => $item->language_title), true) . ' ' . $this->escape($item->language_title) : JText::_('JUNDEFINED'); ?> + + + id; ?> +
      + + + authorise('core.create', 'com_modules') + && $user->authorise('core.edit', 'com_modules') + && $user->authorise('core.edit.state', 'com_modules')) : ?> + JText::_('COM_MODULES_BATCH_OPTIONS'), + 'footer' => $this->loadTemplate('batch_footer') + ), + $this->loadTemplate('batch_body') + ); ?> + + + pagination->getListFooter(); ?> + + + + + + +
      + + diff --git a/Sites/pages/administrator/templates/hathor/html/com_modules/positions/modal.php b/Sites/pages/administrator/templates/hathor/html/com_modules/positions/modal.php new file mode 100644 index 00000000..435bcc64 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_modules/positions/modal.php @@ -0,0 +1,111 @@ +input->getCmd('function', 'jSelectPosition'); +$lang = JFactory::getLanguage(); +$ordering = $this->escape($this->state->get('list.ordering')); +$direction = $this->escape($this->state->get('list.direction')); +$clientId = $this->state->get('client_id'); +$state = $this->state->get('filter.state'); +$template = $this->state->get('filter.template'); +$type = $this->state->get('filter.type'); +?> +
      +
      + + + +
      + + + + + + + + + + +
      +
      + + + + + + + + + + + items as $value => $templates) : ?> + + + + + + +
      + + + +
      + escape($value); ?> + + + +
        + $label):?> +
      • hasKey($label) ? JText::sprintf('COM_MODULES_MODULE_TEMPLATE_POSITION', JText::_($template), JText::_($label)) : JText::_($template);?>
      • + +
      +
      + +
      + + pagination->getListFooter(); ?> + +
      + + + + + +
      +
      diff --git a/Sites/pages/administrator/templates/hathor/html/com_newsfeeds/newsfeed/edit.php b/Sites/pages/administrator/templates/hathor/html/com_newsfeeds/newsfeed/edit.php new file mode 100644 index 00000000..c9b6a9d1 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_newsfeeds/newsfeed/edit.php @@ -0,0 +1,144 @@ +input; + +$saveHistory = $this->state->get('params')->get('save_history', 0); + +$assoc = JLanguageAssociations::isEnabled(); + +JFactory::getDocument()->addScriptDeclaration(" + Joomla.submitbutton = function(task) + { + if (task == 'newsfeed.cancel' || document.formvalidator.isValid(document.getElementById('newsfeed-form'))) + { + Joomla.submitform(task, document.getElementById('newsfeed-form')); + } + } +"); +?> + +
      +
      +
      + item->id) ? JText::_('COM_NEWSFEEDS_NEW_NEWSFEED') : JText::sprintf('COM_NEWSFEEDS_EDIT_NEWSFEED', $this->item->id); ?> +
        +
      • form->getLabel('name'); ?> + form->getInput('name'); ?>
      • + +
      • form->getLabel('alias'); ?> + form->getInput('alias'); ?>
      • + +
      • form->getLabel('link'); ?> + form->getInput('link'); ?>
      • + +
      • form->getLabel('catid'); ?> + form->getInput('catid'); ?>
      • + +
      • form->getLabel('published'); ?> + form->getInput('published'); ?>
      • + +
      • form->getLabel('access'); ?> + form->getInput('access'); ?>
      • + +
      • form->getLabel('ordering'); ?> + form->getInput('ordering'); ?>
      • + +
      • form->getLabel('language'); ?> + form->getInput('language'); ?>
      • + + +
      • form->getLabel('tags'); ?> +
        + form->getInput('tags'); ?> +
        +
      • + + +
      • form->getLabel('version_note'); ?> + form->getInput('version_note'); ?>
      • + + +
      • form->getLabel('id'); ?> + form->getInput('id'); ?>
      • +
      +
      +
      + +
      + item->id, array('useCookie' => 1)); ?> + + + +
      + +
        +
      • form->getLabel('created_by'); ?> + form->getInput('created_by'); ?>
      • + +
      • form->getLabel('created_by_alias'); ?> + form->getInput('created_by_alias'); ?>
      • + +
      • form->getLabel('created'); ?> + form->getInput('created'); ?>
      • + +
      • form->getLabel('publish_up'); ?> + form->getInput('publish_up'); ?>
      • + +
      • form->getLabel('publish_down'); ?> + form->getInput('publish_down'); ?>
      • + + item->modified_by) : ?> +
      • form->getLabel('modified_by'); ?> + form->getInput('modified_by'); ?>
      • + +
      • form->getLabel('modified'); ?> + form->getInput('modified'); ?>
      • + + +
      • form->getLabel('numarticles'); ?> + form->getInput('numarticles'); ?>
      • + +
      • form->getLabel('cache_time'); ?> + form->getInput('cache_time'); ?>
      • + +
      • form->getLabel('rtl'); ?> + form->getInput('rtl'); ?>
      • +
      +
      + + loadTemplate('params'); ?> + + +
      + + loadTemplate('metadata'); ?> +
      + + + + loadTemplate('associations'); ?> + + + + + +
      + +
      +
      diff --git a/Sites/pages/administrator/templates/hathor/html/com_newsfeeds/newsfeed/edit_params.php b/Sites/pages/administrator/templates/hathor/html/com_newsfeeds/newsfeed/edit_params.php new file mode 100644 index 00000000..36d76884 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_newsfeeds/newsfeed/edit_params.php @@ -0,0 +1,28 @@ +form->getFieldsets('params'); +foreach ($fieldSets as $name => $fieldSet) : + echo JHtml::_('sliders.panel', JText::_($fieldSet->label), $name.'-params'); + if (isset($fieldSet->description) && trim($fieldSet->description)) : + echo '

      '.$this->escape(JText::_($fieldSet->description)).'

      '; + endif; + ?> +
      + label); ?> +
        + form->getFieldset($name) as $field) : ?> +
      • label; ?> + input; ?>
      • + +
      +
      + diff --git a/Sites/pages/administrator/templates/hathor/html/com_newsfeeds/newsfeeds/default.php b/Sites/pages/administrator/templates/hathor/html/com_newsfeeds/newsfeeds/default.php new file mode 100644 index 00000000..6e8695b5 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_newsfeeds/newsfeeds/default.php @@ -0,0 +1,234 @@ +get('id'); +$listOrder = $this->escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$canOrder = $user->authorise('core.edit.state', 'com_newsfeeds'); +$saveOrder = $listOrder == 'a.ordering'; +$assoc = JLanguageAssociations::isEnabled(); +?> + +
      +sidebar)) : ?> +
      + sidebar; ?> +
      +
      + +
      + +
      + + + +
      + + + + + + + + + + + + + + + + +
      +
      +
      + + + + + + + + + + + + + + + + + + + + + + items as $i => $item) : + $ordering = ($listOrder == 'a.ordering'); + $canCreate = $user->authorise('core.create', 'com_newsfeeds.category.' . $item->catid); + $canEdit = $user->authorise('core.edit', 'com_newsfeeds.category.' . $item->catid); + $canCheckin = $user->authorise('core.manage', 'com_checkin') || $item->checked_out == $user->get('id') || $item->checked_out == 0; + $canChange = $user->authorise('core.edit.state', 'com_newsfeeds.category.' . $item->catid) && $canCheckin; + ?> + + + + + + + + + + + + + + + + + +
      + + + + + + + + + + + items, 'filesave.png', 'newsfeeds.saveorder'); ?> + + + + + + + + + + + + + +
      + id); ?> + + checked_out) : ?> + editor, $item->checked_out_time, 'newsfeeds.', $canCheckin); ?> + + + + escape($item->name); ?> + + escape($item->name); ?> + +

      + escape($item->alias)); ?>

      +
      + published, $i, 'newsfeeds.', $canChange, 'cb', $item->publish_up, $item->publish_down); ?> + + escape($item->category_title); ?> + + + + + pagination->orderUpIcon($i, $item->catid == @$this->items[$i - 1]->catid, 'newsfeeds.orderup', 'JLIB_HTML_MOVE_UP', $ordering); ?> + pagination->orderDownIcon($i, $this->pagination->total, $item->catid == @$this->items[$i + 1]->catid, 'newsfeeds.orderdown', 'JLIB_HTML_MOVE_DOWN', $ordering); ?> + + pagination->orderUpIcon($i, $item->catid == @$this->items[$i - 1]->catid, 'newsfeeds.orderdown', 'JLIB_HTML_MOVE_UP', $ordering); ?> + pagination->orderDownIcon($i, $this->pagination->total, $item->catid == @$this->items[$i + 1]->catid, 'newsfeeds.orderup', 'JLIB_HTML_MOVE_DOWN', $ordering); ?> + + + + class="text-area-order" title="name; ?> order" /> + + ordering; ?> + + + escape($item->access_level); ?> + + numarticles; ?> + + cache_time; ?> + + association) : ?> + id); ?> + + + + + id; ?> +
      + + + authorise('core.create', 'com_newsfeeds') + && $user->authorise('core.edit', 'com_newsfeeds') + && $user->authorise('core.edit.state', 'com_newsfeeds')) : ?> + JText::_('COM_NEWSFEEDS_BATCH_OPTIONS'), + 'footer' => $this->loadTemplate('batch_footer'), + ), + $this->loadTemplate('batch_body') + ); ?> + + + pagination->getListFooter(); ?> + + + + + + +
      + diff --git a/Sites/pages/administrator/templates/hathor/html/com_newsfeeds/newsfeeds/modal.php b/Sites/pages/administrator/templates/hathor/html/com_newsfeeds/newsfeeds/modal.php new file mode 100644 index 00000000..bdeddad6 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_newsfeeds/newsfeeds/modal.php @@ -0,0 +1,127 @@ +input->get('forcedLanguage', '', 'cmd'); + +$function = JFactory::getApplication()->input->getCmd('function', 'jSelectNewsfeed'); +$listOrder = $this->escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +?> +
      +
      + + + +
      + + + + + + + + + + + + + + + + + + +
      +
      + + + + + + + + + + + + + + items as $i => $item) : ?> + + + + + + + + + + + + pagination->getListFooter(); ?> + + + + + + + +
      diff --git a/Sites/pages/administrator/templates/hathor/html/com_plugins/plugin/edit.php b/Sites/pages/administrator/templates/hathor/html/com_plugins/plugin/edit.php new file mode 100644 index 00000000..a9978a7a --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_plugins/plugin/edit.php @@ -0,0 +1,90 @@ +addScriptDeclaration(" + Joomla.submitbutton = function(task) + { + if (task == 'plugin.cancel' || document.formvalidator.isValid(document.getElementById('style-form'))) + { + Joomla.submitform(task, document.getElementById('style-form')); + } + } +"); +?> + +
      +
      +
      + +
        + +
      • form->getLabel('name'); ?> + form->getInput('name'); ?> + item->name);?>
      • + +
      • form->getLabel('enabled'); ?> + form->getInput('enabled'); ?>
      • + +
      • form->getLabel('access'); ?> + form->getInput('access'); ?>
      • + +
      • form->getLabel('ordering'); ?> + form->getInput('ordering'); ?>
      • + +
      • form->getLabel('folder'); ?> + form->getInput('folder'); ?>
      • + +
      • form->getLabel('element'); ?> + form->getInput('element'); ?>
      • + + item->extension_id) : ?> +
      • form->getLabel('extension_id'); ?> + form->getInput('extension_id'); ?>
      • + +
      + + item->xml) : ?> + item->xml->description)) : ?> + + +
      +
      + +
      + + + + + + +
      +
      + +
      + item->extension_id); ?> + + loadTemplate('options'); ?> + +
      + + + + +
      + +
      +
      diff --git a/Sites/pages/administrator/templates/hathor/html/com_plugins/plugin/edit_options.php b/Sites/pages/administrator/templates/hathor/html/com_plugins/plugin/edit_options.php new file mode 100644 index 00000000..b09f5e92 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_plugins/plugin/edit_options.php @@ -0,0 +1,37 @@ +form->getFieldsets('params'); + +foreach ($fieldSets as $name => $fieldSet) : + $label = !empty($fieldSet->label) ? $fieldSet->label : 'COM_PLUGINS_'.$name.'_FIELDSET_LABEL'; + echo JHtml::_('sliders.panel', JText::_($label), $name.'-options'); + if (isset($fieldSet->description) && trim($fieldSet->description)) : + echo '

      '.$this->escape(JText::_($fieldSet->description)).'

      '; + endif; + ?> +
      + + +
        + form->getFieldset($name) as $field) : ?> + hidden) : ?> +
      • + label; ?> + input; ?> +
      • + input; ?> + + +
      + +
      + diff --git a/Sites/pages/administrator/templates/hathor/html/com_plugins/plugins/default.php b/Sites/pages/administrator/templates/hathor/html/com_plugins/plugins/default.php new file mode 100644 index 00000000..ef3c3727 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_plugins/plugins/default.php @@ -0,0 +1,173 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$canOrder = $user->authorise('core.edit.state', 'com_plugins'); +$saveOrder = $listOrder == 'ordering'; +?> +
      +sidebar)) : ?> +
      + sidebar; ?> +
      +
      + +
      + +
      + + + +
      + + + + + + + + + +
      +
      +
      + + + + + + + + + + + + + + + + + + items as $i => $item) : + $ordering = ($listOrder == 'ordering'); + $canEdit = $user->authorise('core.edit', 'com_plugins'); + $canCheckin = $user->authorise('core.manage', 'com_checkin') || $item->checked_out == $user->get('id') || $item->checked_out == 0; + $canChange = $user->authorise('core.edit.state', 'com_plugins') && $canCheckin; + ?> + + + + + + + + + + + + + +
      + + + + + + + + + items, 'filesave.png', 'plugins.saveorder'); ?> + + + + + + + + + +
      + extension_id); ?> + + checked_out) : ?> + editor, $item->checked_out_time, 'plugins.', $canCheckin); ?> + + + + name; ?> + + name; ?> + + + enabled, $i, 'plugins.', $canChange); ?> + + + + + pagination->orderUpIcon($i, @$this->items[$i - 1]->folder == $item->folder, 'plugins.orderup', 'JLIB_HTML_MOVE_UP', $ordering); ?> + pagination->orderDownIcon($i, $this->pagination->total, @$this->items[$i + 1]->folder == $item->folder, 'plugins.orderdown', 'JLIB_HTML_MOVE_DOWN', $ordering); ?> + + pagination->orderUpIcon($i, @$this->items[$i - 1]->folder == $item->folder, 'plugins.orderdown', 'JLIB_HTML_MOVE_UP', $ordering); ?> + pagination->orderDownIcon($i, $this->pagination->total, @$this->items[$i + 1]->folder == $item->folder, 'plugins.orderup', 'JLIB_HTML_MOVE_DOWN', $ordering); ?> + + + + class="text-area-order" title="name; ?> order" /> + + ordering; ?> + + + escape($item->folder); ?> + + escape($item->element); ?> + + escape($item->access_level); ?> + + extension_id; ?> +
      + + pagination->getListFooter(); ?> + + + + + + +
      + diff --git a/Sites/pages/administrator/templates/hathor/html/com_postinstall/messages/default.php b/Sites/pages/administrator/templates/hathor/html/com_postinstall/messages/default.php new file mode 100644 index 00000000..84307524 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_postinstall/messages/default.php @@ -0,0 +1,85 @@ +loadRenderer('module'); +$options = array('style' => 'raw'); +$mod = JModuleHelper::getModule('mod_feed'); +$param = array( + 'rssurl' => 'https://www.joomla.org/announcements/release-news.feed?type=rss', + 'rsstitle' => 0, + 'rssdesc' => 0, + 'rssimage' => 1, + 'rssitems' => 5, + 'rssitemdesc' => 1, + 'word_count' => 200, + 'cache' => 0, + 'moduleclass_sfx' => ' list-striped' +); +$params = array('params' => json_encode($param)); +?> + +items)): ?> +

      +

      +
      + +
      +eid == 700): ?> +
      +
      +

      + render($mod, $params, $options); ?> +
      + + +eid == 700): + echo JHtml::_('sliders.start', 'panel-sliders', array('useCookie' => '1')); + echo JHtml::_('sliders.panel', JText::_('COM_POSTINSTALL_LBL_MESSAGES'), 'postinstall-panel-messages'); + else: +?> +

      + + items as $item): ?> +
      + title_key) ?> +

      + version_introduced) ?> +

      +

      description_key) ?>

      + +
      + type !== 'message'): ?> + + + authorise('core.edit.state', 'com_postinstall')) : ?> + + +
      +
      + +eid == 700): + echo JHtml::_('sliders.panel', JText::_('COM_POSTINSTALL_LBL_RELEASENEWS'), 'postinstall-panel-releasenotes'); +?> + render($mod, $params, $options); ?> + + diff --git a/Sites/pages/administrator/templates/hathor/html/com_redirect/links/default.php b/Sites/pages/administrator/templates/hathor/html/com_redirect/links/default.php new file mode 100644 index 00000000..1d11ca2c --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_redirect/links/default.php @@ -0,0 +1,169 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +?> + +
      +sidebar)) : ?> +
      + sidebar; ?> +
      +
      + +
      + +
      + + + +
      + + + + +
      +
      +
      + + + + + + + + + + + + + + + + + items as $i => $item) : + $canCreate = $user->authorise('core.create', 'com_redirect'); + $canEdit = $user->authorise('core.edit', 'com_redirect'); + $canChange = $user->authorise('core.edit.state', 'com_redirect'); + ?> + + + + + + + + + + + + +
      + + + + + + + + + + + + + + + +
      + id); ?> + + + + escape(str_replace(JUri::root(), '', rawurldecode($item->old_url))); ?> + + escape(str_replace(JUri::root(), '', rawurldecode($item->old_url))); ?> + + + escape(rawurldecode($item->new_url)); ?> + + escape($item->referer); ?> + + created_date, JText::_('DATE_FORMAT_LC4')); ?> + + hits; ?> + + published, $i); ?> + + id; ?> +
      + + + authorise('core.create', 'com_redirect') + && $user->authorise('core.edit', 'com_redirect') + && $user->authorise('core.edit.state', 'com_redirect')) : ?> + JText::_('COM_REDIRECT_BATCH_OPTIONS'), + 'footer' => $this->loadTemplate('batch_footer'), + ), + $this->loadTemplate('batch_body') + ); ?> + + + pagination->getListFooter(); ?> + +
      + + items)) : ?> + loadTemplate('addform'); ?> + + + + + + + +
      + diff --git a/Sites/pages/administrator/templates/hathor/html/com_search/searches/default.php b/Sites/pages/administrator/templates/hathor/html/com_search/searches/default.php new file mode 100644 index 00000000..90f51a2a --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_search/searches/default.php @@ -0,0 +1,78 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +?> + +
      +
      + + + + +
      +
      + + + + + + + + + + + + items as $i => $item) : ?> + + + + + + + +
      + + + + + +
      + escape($item->search_term); ?> + + hits; ?> + + state->get('show_results')) : ?> + returns; ?> + + + +
      + + pagination->getListFooter(); ?> + + + + + + +
      diff --git a/Sites/pages/administrator/templates/hathor/html/com_tags/tag/edit.php b/Sites/pages/administrator/templates/hathor/html/com_tags/tag/edit.php new file mode 100644 index 00000000..e2cf55bf --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_tags/tag/edit.php @@ -0,0 +1,124 @@ +state->get('params')->get('save_history', 0); + +JHtml::_('behavior.formvalidator'); + +JFactory::getDocument()->addScriptDeclaration(" + Joomla.submitbutton = function(task) + { + if (task == 'tag.cancel' || document.formvalidator.isValid(document.getElementById('tag-form'))) + { + " . $this->form->getField('description')->save() . " + Joomla.submitform(task, document.getElementById('tag-form')); + } + } +"); +?> + + + diff --git a/Sites/pages/administrator/templates/hathor/html/com_tags/tag/edit_metadata.php b/Sites/pages/administrator/templates/hathor/html/com_tags/tag/edit_metadata.php new file mode 100644 index 00000000..6e2933fe --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_tags/tag/edit_metadata.php @@ -0,0 +1,38 @@ +form->getFieldsets('metadata'); +foreach ($fieldSets as $name => $fieldSet) : + echo JHtml::_('sliders.panel', JText::_($fieldSet->label), $name.'-options'); + if (isset($fieldSet->description) && trim($fieldSet->description)) : + echo '

      '.$this->escape(JText::_($fieldSet->description)).'

      '; + endif; + ?> +
      + label); ?> +
        + +
      • form->getLabel('metadesc'); ?> + form->getInput('metadesc'); ?>
      • + +
      • form->getLabel('metakey'); ?> + form->getInput('metakey'); ?>
      • + +
      • form->getLabel('xreference'); ?> + form->getInput('xreference'); ?>
      • + + form->getFieldset($name) as $field) : ?> +
      • label; ?> + input; ?>
      • + +
      +
      + diff --git a/Sites/pages/administrator/templates/hathor/html/com_tags/tag/edit_options.php b/Sites/pages/administrator/templates/hathor/html/com_tags/tag/edit_options.php new file mode 100644 index 00000000..a4954a6b --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_tags/tag/edit_options.php @@ -0,0 +1,62 @@ +description) && trim($fieldSet->description)) : + echo '

      '.$this->escape(JText::_($fieldSet->description)).'

      '; +endif; +?> +
      + label); ?> +
        +
      • form->getLabel('created_user_id'); ?> + form->getInput('created_user_id'); ?>
      • + +
      • form->getLabel('created_by_alias'); ?> + form->getInput('created_by_alias'); ?>
      • + +
      • form->getLabel('created_time'); ?> + form->getInput('created_time'); ?>
      • + +
      • form->getLabel('publish_up'); ?> + form->getInput('publish_up'); ?>
      • + +
      • form->getLabel('publish_down'); ?> + form->getInput('publish_down'); ?>
      • + +
      • form->getLabel('modified_user_id'); ?> + form->getInput('modified_user_id'); ?>
      • + +
      • form->getLabel('modified_time'); ?> + form->getInput('modified_time'); ?>
      • +
      • form->getLabel('version'); ?> + form->getInput('version'); ?>
      • + + +
      +
      + +form->getFieldsets('params'); + foreach ($fieldSets as $name => $fieldSet) : + echo JHtml::_('sliders.panel', JText::_($fieldSet->label), $name.'-params'); + if (isset($fieldSet->description) && trim($fieldSet->description)) : + echo '

      '.$this->escape(JText::_($fieldSet->description)).'

      '; + endif; + ?> +
      + label); ?> +
        + form->getFieldset($name) as $field) : ?> +
      • label; ?> + input; ?>
      • + +
      +
      + diff --git a/Sites/pages/administrator/templates/hathor/html/com_tags/tags/default.php b/Sites/pages/administrator/templates/hathor/html/com_tags/tags/default.php new file mode 100644 index 00000000..f889f180 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_tags/tags/default.php @@ -0,0 +1,165 @@ +get('id'); +$listOrder = $this->escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$saveOrder = $listOrder == 'a.ordering'; +$n = count($this->items); +?> + +
      +sidebar)) : ?> +
      + sidebar; ?> +
      +
      + +
      + +
      + + + +
      + + + + + + + + + + + + + +
      +
      +
      + + + + + + + + + + + + + items as $i => $item) : + $item->max_ordering = 0; //?? + $canCreate = $user->authorise('core.create', 'com_tags'); + $canEdit = $user->authorise('core.edit', 'com_tags.tag.' . $item->id); + $canCheckin = $user->authorise('core.manage', 'com_checkin') || $item->checked_out_user_id == $userId || $item->checked_out_user_id == 0; + $canChange = $user->authorise('core.edit.state', 'com_tags.tag.' . $item->id) && $canCheckin; + ?> + + + + + + + + + + +
      + + + + + + + + + + + +
      + id); ?> + + level > 0): ?> + —', $item->level - 1) ?> + + + checked_out) : ?> + editor, $item->checked_out_time, 'tags.', $canCheckin); ?> + + + + escape($item->title); ?> + + escape($item->title); ?> + +

      + escape($item->alias)); ?>

      +
      + published, $i, 'tags.', $canChange, 'cb'); ?> + + escape($item->access_title); ?> + + + + id; ?> +
      + + + authorise('core.create', 'com_tags') + && $user->authorise('core.edit', 'com_tags') + && $user->authorise('core.edit.state', 'com_tags')) : ?> + JText::_('COM_TAGS_BATCH_OPTIONS'), + 'footer' => $this->loadTemplate('batch_footer'), + ), + $this->loadTemplate('batch_body') + ); ?> + + + pagination->getListFooter(); ?> + + + + + + +
      + diff --git a/Sites/pages/administrator/templates/hathor/html/com_templates/style/edit.php b/Sites/pages/administrator/templates/hathor/html/com_templates/style/edit.php new file mode 100644 index 00000000..c84965f2 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_templates/style/edit.php @@ -0,0 +1,87 @@ +addScriptDeclaration(" + Joomla.submitbutton = function(task) + { + if (task == 'style.cancel' || document.formvalidator.isValid(document.getElementById('style-form'))) + { + Joomla.submitform(task, document.getElementById('style-form')); + } + } +"); +?> + +
      +
      +
      + +
        +
      • form->getLabel('title'); ?> + form->getInput('title'); ?>
      • + +
      • form->getLabel('template'); ?> + form->getInput('template'); ?> + form->getLabel('client_id'); ?> + form->getInput('client_id'); ?> +
      • + +
      • form->getLabel('home'); ?> + form->getInput('home'); ?>
      • + + item->id) : ?> +
      • form->getLabel('id'); ?> + item->id; ?>
      • + +
      +
      + item->xml) : ?> + item->xml->description)) : ?> + + + + +

      + +
      +
      + + +
      + +
      + item->id); ?> + + loadTemplate('options'); ?> + +
      + + +
      + authorise('core.edit', 'com_menu') && $this->item->client_id == 0):?> + canDo->get('core.edit.state')) : ?> +
      + loadTemplate('assignment'); ?> +
      + + + +
      +
      diff --git a/Sites/pages/administrator/templates/hathor/html/com_templates/style/edit_assignment.php b/Sites/pages/administrator/templates/hathor/html/com_templates/style/edit_assignment.php new file mode 100644 index 00000000..4973df71 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_templates/style/edit_assignment.php @@ -0,0 +1,48 @@ + +
      + + + + +
      + +
      diff --git a/Sites/pages/administrator/templates/hathor/html/com_templates/style/edit_options.php b/Sites/pages/administrator/templates/hathor/html/com_templates/style/edit_options.php new file mode 100644 index 00000000..3b6e84ff --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_templates/style/edit_options.php @@ -0,0 +1,33 @@ +form->getFieldsets('params'); + + foreach ($fieldSets as $name => $fieldSet) : + $label = !empty($fieldSet->label) ? $fieldSet->label : 'COM_TEMPLATES_'.$name.'_FIELDSET_LABEL'; + echo JHtml::_('sliders.panel', JText::_($label), $name.'-options'); + if (isset($fieldSet->description) && trim($fieldSet->description)) : + echo '

      '.$this->escape(JText::_($fieldSet->description)).'

      '; + endif; + ?> +
      +
        + form->getFieldset($name) as $field) : ?> +
      • + hidden) : ?> + label; ?> + + input; ?> +
      • + +
      +
      + diff --git a/Sites/pages/administrator/templates/hathor/html/com_templates/styles/default.php b/Sites/pages/administrator/templates/hathor/html/com_templates/styles/default.php new file mode 100644 index 00000000..fee4f1e2 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_templates/styles/default.php @@ -0,0 +1,162 @@ + 'auto', 'relative' => true)); + +$user = JFactory::getUser(); +$listOrder = $this->escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +?> + +
      +sidebar)) : ?> +
      + sidebar; ?> +
      +
      + +
      + +
      + + + +
      + + + + + + + +
      +
      +
      + + + + + + + + + + + + + + + + items as $i => $item) : + $canCreate = $user->authorise('core.create', 'com_templates'); + $canEdit = $user->authorise('core.edit', 'com_templates'); + $canChange = $user->authorise('core.edit.state', 'com_templates'); + ?> + + + + + + + + + + + +
      +   + + + + + + + + + + + + +
      + id); ?> + + preview && $item->client_id == '0') : ?> + + client_id == '1') : ?> + + + + + + + escape($item->title);?> + + escape($item->title);?> + + + client_id == 0 ? JText::_('JSITE') : JText::_('JADMINISTRATOR'); ?> + + + + home == '0' || $item->home == '1'):?> + home != '0', $i, 'styles.', $canChange && $item->home != '1');?> + + + image) : ?> + image . '.gif', $item->language_title, array('title' => JText::sprintf('COM_TEMPLATES_GRID_UNSET_LANGUAGE', $item->language_title)), true);?> + + language_sef; ?> + + + + image . '.gif', $item->language_title, array('title' => $item->language_title), true); ?> + image) : ?> + image . '.gif', $item->language_title, array('title' => $item->language_title), true); ?> + + language_sef; ?> + + + + assigned > 0) : ?> + assigned), array('title' => JText::plural('COM_TEMPLATES_ASSIGNED', $item->assigned)), true); ?> + +   + + + id; ?> +
      + + pagination->getListFooter(); ?> + + + + + + +
      + diff --git a/Sites/pages/administrator/templates/hathor/html/com_templates/template/default.php b/Sites/pages/administrator/templates/hathor/html/com_templates/template/default.php new file mode 100644 index 00000000..90343298 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_templates/template/default.php @@ -0,0 +1,512 @@ +input; +if ($this->type == 'image') +{ + JHtml::_('script', 'system/jquery.Jcrop.min.js', array('version' => 'auto', 'relative' => true)); + JHtml::_('stylesheet', 'system/jquery.Jcrop.min.css', array('version' => 'auto', 'relative' => true)); +} +JFactory::getDocument()->addScriptDeclaration(" +jQuery(document).ready(function($){ + // Hide all the folder when the page loads + $('.folder ul, .component-folder ul').hide(); + // Display the tree after loading + $('.directory-tree').removeClass('directory-tree'); + // Show all the lists in the path of an open file + $('.show > ul').show(); + // Stop the default action of anchor tag on a click event + $('.folder-url, .component-folder-url').click(function(event){ + event.preventDefault(); + }); + // Prevent the click event from proliferating + $('.file, .component-file-url').bind('click',function(e){ + e.stopPropagation(); + }); + // Toggle the child indented list on a click event + $('.folder, .component-folder').bind('click',function(e){ + $(this).children('ul').toggle(); + e.stopPropagation(); + }); + // New file tree + $('#fileModal .folder-url').bind('click',function(e){ + $('.folder-url').removeClass('selected'); + e.stopPropagation(); + $('#fileModal input.address').val($(this).attr('data-id')); + $(this).addClass('selected'); + }); + // Folder manager tree + $('#folderModal .folder-url').bind('click',function(e){ + $('.folder-url').removeClass('selected'); + e.stopPropagation(); + $('#folderModal input.address').val($(this).attr('data-id')); + $(this).addClass('selected'); + }); +});"); +if ($this->type == 'image') +{ + JFactory::getDocument()->addScriptDeclaration(" + jQuery(document).ready(function() { + var jcrop_api; + // Configuration for image cropping + $('#image-crop').Jcrop({ + onChange: showCoords, + onSelect: showCoords, + onRelease: clearCoords, + trueSize: " . $this->image['width'] . "," . $this->image['height'] . "] + },function(){ + jcrop_api = this; + }); + // Function for calculating the crop coordinates + function showCoords(c) + { + $('#x').val(c.x); + $('#y').val(c.y); + $('#w').val(c.w); + $('#h').val(c.h); + }; + // Function for clearing the coordinates + function clearCoords() + { + $('#adminForm input').val(''); + }; + });"); +} +JFactory::getDocument()->addStyleDeclaration(' + /* Styles for modals */ + .selected{ + background: #08c; + color: #fff; + } + .selected:hover{ + background: #08c !important; + color: #fff; + } + .modal-body .column { + width: 50%; float: left; + } + #deleteFolder{ + margin: 0; + } + #image-crop{ + max-width: 100% !important; + width: auto; + height: auto; + } + .directory-tree{ + display: none; + } + .tree-holder{ + overflow-x: auto; + } +'); +if ($this->type == 'font') +{ + JFactory::getDocument()->addStyleDeclaration( + "/* Styles for font preview */ + @font-face + { + font-family: previewFont; + src: url('" . $this->font['address'] . "') + } + .font-preview{ + font-family: previewFont !important; + }" + ); +} +?> +
      + + type != 'home'): ?> + + + + + + + type != 'home'): ?> +
      + + +
      + + + type == 'home'): ?> +
      + + +
      +

      +

      +

      + + + +

      +
      +
      + + type == 'file'): ?> +
      +
      + +

      +
      +
      + form->getInput('source'); ?> +
      + + + + + form->getInput('extension_id'); ?> + form->getInput('filename'); ?> +
      +
      + + type == 'image'): ?> +
      +
      + + + + + + +
      + + type == 'archive'): ?> + +
      +
      + +
      + + + +
      + + type == 'font'): ?> +
      +
      +
      + +

      H1

      Quickly gaze at Joomla! views from HTML, CSS, JavaScript and XML

      +

      H2

      Quickly gaze at Joomla! views from HTML, CSS, JavaScript and XML

      +

      H3

      Quickly gaze at Joomla! views from HTML, CSS, JavaScript and XML

      +

      H4

      Quickly gaze at Joomla! views from HTML, CSS, JavaScript and XML

      +

      H5

      Quickly gaze at Joomla! views from HTML, CSS, JavaScript and XML
      +

      H6

      Quickly gaze at Joomla! views from HTML, CSS, JavaScript and XML
      +

      Bold

      Quickly gaze at Joomla! views from HTML, CSS, JavaScript and XML +

      Italics

      Quickly gaze at Joomla! views from HTML, CSS, JavaScript and XML +

      Unordered List

      +
        +
      • Item
      • +
      • Item
      • +
      • Item
        +
          +
        • Item
        • +
        • Item
        • +
        • Item
          +
            +
          • Item
          • +
          • Item
          • +
          • Item
          • +
          +
        • +
        +
      • +
      +

      Ordered List

      +
        +
      1. Item
      2. +
      3. Item
      4. +
      5. Item
        +
          +
        • Item
        • +
        • Item
        • +
        • Item
          +
            +
          • Item
          • +
          • Item
          • +
          • Item
          • +
          +
        • +
        +
      6. +
      + + +
      +
      +
      + + +
      + + + loadTemplate('description');?> +
      + +
      +
      + +
      + + type != 'home'): ?> +
      + + type == 'file'): ?> +

      source->filename, $this->template->element); ?>

      + + type == 'image'): ?> +

      image['path'], $this->template->element); ?>

      + + type == 'font'): ?> +

      font['rel_path'], $this->template->element); ?>

      + +
      + + +
      + + + loadTemplate('tree');?> +
      + + 1)); ?> + +
      +
      + + + +
      + +
      + type != 'home'): ?> + +
      +
      + + + +
      + +
      + + +
      + +
      + +
      + +
      + +
      + +
      + +
      diff --git a/Sites/pages/administrator/templates/hathor/html/com_templates/template/default_description.php b/Sites/pages/administrator/templates/hathor/html/com_templates/template/default_description.php new file mode 100644 index 00000000..54a739b6 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_templates/template/default_description.php @@ -0,0 +1,20 @@ + + +
      + template->element, $this->template->client_id); ?> + template->element, $this->template->client_id); ?> +
      +

      template->element); ?>

      +template->client_id); ?> +

      template->xmldata = TemplatesHelper::parseXMLTemplateFile($client->path, $this->template->element);?>

      +

      template->xmldata->description); ?>

      \ No newline at end of file diff --git a/Sites/pages/administrator/templates/hathor/html/com_templates/template/default_folders.php b/Sites/pages/administrator/templates/hathor/html/com_templates/template/default_folders.php new file mode 100644 index 00000000..8acdf769 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_templates/template/default_folders.php @@ -0,0 +1,25 @@ +files, SORT_STRING); +?> + + diff --git a/Sites/pages/administrator/templates/hathor/html/com_templates/template/default_tree.php b/Sites/pages/administrator/templates/hathor/html/com_templates/template/default_tree.php new file mode 100644 index 00000000..b7d0a7ad --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_templates/template/default_tree.php @@ -0,0 +1,64 @@ +files, SORT_STRING); +?> + + diff --git a/Sites/pages/administrator/templates/hathor/html/com_templates/templates/default.php b/Sites/pages/administrator/templates/hathor/html/com_templates/templates/default.php new file mode 100644 index 00000000..db5bbb6e --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_templates/templates/default.php @@ -0,0 +1,136 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +?> + +
      +sidebar)) : ?> +
      + sidebar; ?> +
      +
      + +
      + +
      + + +
      + + + + +
      +
      +
      + + + + + + + + + + + + + + + items as $i => $item) : ?> + + + + + + + + element, $item->client_id); ?> + + + +
      +   + + + + + + + + + + +
      + element, $item->client_id); ?> + + + name); ?> +

      + preview && $item->client_id == '0') : ?> + + + client_id == '1') : ?> + + + + + +

      +
      + client_id == 0 ? JText::_('JSITE') : JText::_('JADMINISTRATOR'); ?> + + escape($item->xmldata->get('version')); ?> + + escape($item->xmldata->get('creationDate')); ?> + + xmldata->get('author')) : ?> +

      escape($author); ?>

      + + — + + xmldata->get('authorEmail')) : ?> +

      escape($email); ?>

      + + xmldata->get('authorUrl')) : ?> +

      + escape($url); ?>

      + +
      + + pagination->getListFooter(); ?> + + + + + + +
      + diff --git a/Sites/pages/administrator/templates/hathor/html/com_users/debuggroup/default.php b/Sites/pages/administrator/templates/hathor/html/com_users/debuggroup/default.php new file mode 100644 index 00000000..821759f5 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_users/debuggroup/default.php @@ -0,0 +1,152 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +?> + +
      +sidebar)) : ?> +
      + sidebar; ?> +
      +
      + +
      + +
      + + + +
      + + + + + + + + + + +
      + +
      +
      + +
      + + + + +
      + + + + + + + actions as $key => $action) : ?> + + + + + + + + + items as $i => $item) : ?> + + + + actions as $action) : ?> + checks[$name]; + if ($check === true) : + $class = 'check-a'; + $text = '✓'; + elseif ($check === false) : + $class = 'check-d'; + $text = '✗'; + elseif ($check === null) : + $class = 'check-0'; + $text = '-'; + else : + $class = ''; + $text = ' '; + endif; + ?> + + + + + + + +
      + + + + + + + + + +
      + escape($item->title); ?> + + |—', $item->level) ?> + escape($item->name); ?> + + + + lft; ?> + - rgt; ?> + + id; ?> +
      + + pagination->getListFooter(); ?> + +
      + + + + + +
      +
      + diff --git a/Sites/pages/administrator/templates/hathor/html/com_users/debuguser/default.php b/Sites/pages/administrator/templates/hathor/html/com_users/debuguser/default.php new file mode 100644 index 00000000..4d1af0ec --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_users/debuguser/default.php @@ -0,0 +1,152 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +?> + +
      +sidebar)) : ?> +
      + sidebar; ?> +
      +
      + +
      + +
      + + + +
      + + + + + + + + + + +
      + +
      +
      + +
      + + + + +
      + + + + + + + actions as $key => $action) : ?> + + + + + + + + + items as $i => $item) : ?> + + + + actions as $action) : ?> + checks[$name]; + if ($check === true) : + $class = 'check-a'; + $text = '✓'; + elseif ($check === false) : + $class = 'check-d'; + $text = '✗'; + elseif ($check === null) : + $class = 'check-0'; + $text = '-'; + else : + $class = ''; + $text = ' '; + endif; + ?> + + + + + + + +
      + + + + + + + + + +
      + escape($item->title); ?> + + |—', $item->level) ?> + escape($item->name); ?> + + + + lft; ?> + - rgt; ?> + + id; ?> +
      + + pagination->getListFooter(); ?> + +
      + + + + + +
      +
      + diff --git a/Sites/pages/administrator/templates/hathor/html/com_users/groups/default.php b/Sites/pages/administrator/templates/hathor/html/com_users/groups/default.php new file mode 100644 index 00000000..22ea82e5 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_users/groups/default.php @@ -0,0 +1,139 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); + +JText::script('COM_USERS_GROUPS_CONFIRM_DELETE'); + +$groupsWithUsers = array(); + +foreach ($this->items as $i => $item) +{ + if ($item->user_count > 0) + { + $groupsWithUsers[] = $i; + } +} +JFactory::getDocument()->addScriptDeclaration(' + Joomla.submitbutton = function(task) { + if (task == "groups.delete") { + var f = document.adminForm; + var cb = ""; + var groupsWithUsers = [' . implode(',', $groupsWithUsers) . ']; + for (index = 0; index < groupsWithUsers.length; ++index) { + cb = f["cb" + groupsWithUsers[index]]; + if (cb && cb.checked) { + if (confirm(Joomla.JText._("COM_USERS_GROUPS_CONFIRM_DELETE"))) { + Joomla.submitform(task); + } + return; + } + } + } + Joomla.submitform(task); + }; +'); +?> +
      +sidebar)) : ?> +
      + sidebar; ?> +
      +
      + +
      + +
      + + +
      +
      + + + + + + + + + + + + + items as $i => $item) : + $canCreate = $user->authorise('core.create', 'com_users'); + $canEdit = $user->authorise('core.edit', 'com_users'); + // If this group is super admin and this user is not super admin, $canEdit is false + if (!$user->authorise('core.admin') && JAccess::checkGroup($item->id, 'core.admin')) + { + $canEdit = false; + } + $canChange = $user->authorise('core.edit.state', 'com_users'); + ?> + + + + + + + + +
      + + + + + + + +
      + + id); ?> + + + |—', $item->level) ?> + + + escape($item->title); ?> + + escape($item->title); ?> + + + + + + user_count ?: ''; ?> + + id; ?> +
      + + pagination->getListFooter(); ?> + + + + + + +
      + diff --git a/Sites/pages/administrator/templates/hathor/html/com_users/levels/default.php b/Sites/pages/administrator/templates/hathor/html/com_users/levels/default.php new file mode 100644 index 00000000..38432c52 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_users/levels/default.php @@ -0,0 +1,123 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$canOrder = $user->authorise('core.edit.state', 'com_users'); +$saveOrder = $listOrder == 'a.ordering'; +?> + +
      +sidebar)) : ?> +
      + sidebar; ?> +
      +
      + +
      + +
      + + +
      +
      + + + + + + + + + + + + + + items as $i => $item) : + $ordering = ($listOrder == 'a.ordering'); + $canCreate = $user->authorise('core.create', 'com_users'); + $canEdit = $user->authorise('core.edit', 'com_users'); + $canChange = $user->authorise('core.edit.state', 'com_users'); + ?> + + + + + + + + + +
      + + + + + + + items, 'filesave.png', 'levels.saveorder'); ?> + + + + +   +
      + id); ?> + + + + escape($item->title); ?> + + escape($item->title); ?> + + + + + + pagination->orderUpIcon($i, true, 'levels.orderup', 'JLIB_HTML_MOVE_UP', $ordering); ?> + pagination->orderDownIcon($i, $this->pagination->total, true, 'levels.orderdown', 'JLIB_HTML_MOVE_DOWN', $ordering); ?> + + pagination->orderUpIcon($i, true, 'levels.orderdown', 'JLIB_HTML_MOVE_UP', $ordering); ?> + pagination->orderDownIcon($i, $this->pagination->total, true, 'levels.orderup', 'JLIB_HTML_MOVE_DOWN', $ordering); ?> + + + + class="text-area-order" title="title; ?> order" /> + + ordering; ?> + + + id; ?> + +   +
      + + pagination->getListFooter(); ?> + + + + + + +
      + diff --git a/Sites/pages/administrator/templates/hathor/html/com_users/note/edit.php b/Sites/pages/administrator/templates/hathor/html/com_users/note/edit.php new file mode 100644 index 00000000..3c7e4ec7 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_users/note/edit.php @@ -0,0 +1,67 @@ +addScriptDeclaration(' +jQuery(document).ready(function() { + Joomla.submitbutton = function(task) + { + if (task == "note.cancel" || document.formvalidator.isValid(document.getElementById("note-form"))) + { + ' . $this->form->getField('body')->save() . ' + Joomla.submitform(task, document.getElementById("note-form")); + } + } +});'); +?> +
      +
      +
      + item->id) ? JText::_('COM_USERS_NEW_NOTE') : JText::sprintf('COM_USERS_EDIT_NOTE', $this->item->id); ?> +
        +
      • + form->getLabel('subject'); ?> + form->getInput('subject'); ?> +
      • +
      • +
        + form->getLabel('user_id'); ?> + form->getInput('user_id'); ?> +
      • +
      • + form->getLabel('catid'); ?> + form->getInput('catid'); ?> +
      • +
      • + form->getLabel('state'); ?> + form->getInput('state'); ?> +
      • +
      • + form->getLabel('review_time'); ?> + form->getInput('review_time'); ?> +
      • +
      • + form->getLabel('version_note'); ?> + form->getInput('version_note'); ?> +
      • +
      +
      + form->getLabel('body'); ?> +
      +
      + form->getInput('body'); ?> +
      + + + +
      + diff --git a/Sites/pages/administrator/templates/hathor/html/com_users/notes/default.php b/Sites/pages/administrator/templates/hathor/html/com_users/notes/default.php new file mode 100644 index 00000000..1cf79627 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_users/notes/default.php @@ -0,0 +1,152 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$canEdit = $user->authorise('core.edit', 'com_users'); +?> +
      +sidebar)) : ?> +
      + sidebar; ?> +
      +
      + +
      + +
      + + + +
      + + + + + + + + + +
      +
      + + + + + + + + + + + + + + + items as $i => $item) : ?> + authorise('core.edit.state', 'com_users'); ?> + + + + + + + + + + + +
      + + + + + + + + + + + + + +
      + id); ?> + + checked_out) : ?> + editor, $item->checked_out_time); ?> + + + + escape($item->user_name); ?> + + escape($item->user_name); ?> + + + subject) : ?> + escape($item->subject); ?> + + + + + catid && $item->cparams->get('image')) : ?> + cparams->get('image')); ?> + + escape($item->category_title); ?> + + state, $i, 'notes.', $canChange, 'cb', $item->publish_up, $item->publish_down); ?> + + review_time !== JFactory::getDbo()->getNullDate()) : ?> + review_time, JText::_('DATE_FORMAT_LC4')); ?> + + + + + id; ?> +
      + + pagination->getListFooter(); ?> + +
      + + + + + +
      +
      + diff --git a/Sites/pages/administrator/templates/hathor/html/com_users/user/edit.php b/Sites/pages/administrator/templates/hathor/html/com_users/user/edit.php new file mode 100644 index 00000000..a31cd4a8 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_users/user/edit.php @@ -0,0 +1,139 @@ +form->getFieldsets(); + +JFactory::getDocument()->addScriptDeclaration(" + Joomla.submitbutton = function(task) + { + if (task == 'user.cancel' || document.formvalidator.isValid(document.getElementById('user-form'))) + { + Joomla.submitform(task, document.getElementById('user-form')); + } + } + + Joomla.twoFactorMethodChange = function(e) + { + var selectedPane = 'com_users_twofactor_' + jQuery('#jform_twofactor_method').val(); + + jQuery.each(jQuery('#com_users_twofactor_forms_container>div'), function(i, el) { + if (el.id != selectedPane) + { + jQuery('#' + el.id).hide(0); + } + else + { + jQuery('#' + el.id).show(0); + } + }); + } +"); +?> + +
      +
      +
      + +
        + form->getFieldset('user_details') as $field) : ?> +
      • label; ?> + input; ?>
      • + +
      +
      +
      +
      + 1)); ?> + grouplist) : ?> + +
      + + loadTemplate('groups'); ?> +
      + + name == 'user_details') : + continue; + endif; + echo JHtml::_('sliders.panel', JText::_($fieldset->label), $fieldset->name); + ?> +
      +
        + form->getFieldset($fieldset->name) as $field) : ?> + hidden) : ?> + input; ?> + +
      • label; ?> + input; ?>
      • + + +
      +
      + + + tfaform) && $this->item->id): ?> + +
      +
      + +
      +
      + 'Joomla.twoFactorMethodChange()'), 'value', 'text', $this->otpConfig->method, 'jform_twofactor_method', false) ?> +
      +
      +
      + tfaform as $form): ?> + otpConfig->method ? 'display: block' : 'display: none'; ?> +
      + +
      + +
      + +
      + + + +
      + +
      + otpConfig->otep)): ?> +
      + +
      + + otpConfig->otep as $otep): ?> + + --- + + +
      + +
      + + + + + + +
      +
      diff --git a/Sites/pages/administrator/templates/hathor/html/com_users/users/default.php b/Sites/pages/administrator/templates/hathor/html/com_users/users/default.php new file mode 100644 index 00000000..7b51f83a --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_users/users/default.php @@ -0,0 +1,234 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$loggeduser = JFactory::getUser(); +?> + +
      +sidebar)) : ?> +
      + sidebar; ?> +
      +
      + +
      + +
      + + + +
      + + + + + + + + + + + + + + + + + + +
      +
      +
      + + + + + + + + + + + + + + + + + + + items as $i => $item) : + $canEdit = $this->canDo->get('core.edit'); + $canChange = $loggeduser->authorise('core.edit.state', 'com_users'); + + // If this group is super admin and this user is not super admin, $canEdit is false + if ((!$loggeduser->authorise('core.admin')) && JAccess::check($item->id, 'core.admin')) + { + $canEdit = false; + $canChange = false; + } + ?> + + + + + + + + + + + + + + +
      + + + + + + + + + + + + + + + + + + + +
      + + id); ?> + + +
      + note_count, $item->id); ?> + note_count, $item->id); ?> + id); ?> + requireReset == '1') : ?> + + + note_count, $item->id); ?> +
      + + + escape($item->name); ?> + + escape($item->name); ?> + + + + +
      + escape($item->username); ?> + + + id != $item->id) : ?> + block, 'users.unblock', 'users.block'); ?> + + block, 'users.block', null); ?> + + + block ? 'JNO' : 'JYES'); ?> + + + activation, 'users.activate', null); ?> + + group_names, "\n") > 1) : ?> + + + group_names); ?> + + + escape($item->email); ?> + + lastvisitDate != $this->db->getNullDate()) : ?> + lastvisitDate, JText::_('DATE_FORMAT_LC6')); ?> + + + + + registerDate, JText::_('DATE_FORMAT_LC6')); ?> + + id; ?> +
      + + + authorise('core.create', 'com_users') + && $loggeduser->authorise('core.edit', 'com_users') + && $loggeduser->authorise('core.edit.state', 'com_users')) : ?> + JText::_('COM_USERS_BATCH_OPTIONS'), + 'footer' => $this->loadTemplate('batch_footer'), + ), + $this->loadTemplate('batch_body') + ); ?> + + + pagination->getListFooter(); ?> +
      + + + + + +
      +
      + diff --git a/Sites/pages/administrator/templates/hathor/html/com_users/users/modal.php b/Sites/pages/administrator/templates/hathor/html/com_users/users/modal.php new file mode 100644 index 00000000..c72ceb2d --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_users/users/modal.php @@ -0,0 +1,87 @@ +input; +$field = $input->getCmd('field'); +$function = 'jSelectUser_'.$field; +$listOrder = $this->escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +?> +
      +
      + + + +
      + + state->get('filter.group_id')); ?> + + +
      +
      + + + + + + + + + + + + items as $item) : ?> + + + + + + + + + + pagination->getListFooter(); ?> + + + + + + +
      diff --git a/Sites/pages/administrator/templates/hathor/html/com_weblinks/weblink/edit.php b/Sites/pages/administrator/templates/hathor/html/com_weblinks/weblink/edit.php new file mode 100644 index 00000000..b0000f12 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_weblinks/weblink/edit.php @@ -0,0 +1,139 @@ +state->get('params')->get('save_history', 0); + +JHtml::_('behavior.formvalidator'); + +JFactory::getDocument()->addScriptDeclaration(" + Joomla.submitbutton = function(task) + { + if (task == 'weblink.cancel' || document.formvalidator.isValid(document.id('weblink-form'))) + { + " . $this->form->getField('description')->save() . " + Joomla.submitform(task, document.getElementById('weblink-form')); + } + } +"); +?> + diff --git a/Sites/pages/administrator/templates/hathor/html/com_weblinks/weblink/edit_params.php b/Sites/pages/administrator/templates/hathor/html/com_weblinks/weblink/edit_params.php new file mode 100644 index 00000000..b542760d --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_weblinks/weblink/edit_params.php @@ -0,0 +1,28 @@ +form->getFieldsets('params'); +foreach ($fieldSets as $name => $fieldSet) : + echo JHtml::_('sliders.panel', JText::_($fieldSet->label), $name.'-params'); + if (isset($fieldSet->description) && trim($fieldSet->description)) : + echo '

      '.$this->escape(JText::_($fieldSet->description)).'

      '; + endif; + ?> +
      + label); ?> +
        + form->getFieldset($name) as $field) : ?> +
      • label; ?> + input; ?>
      • + +
      +
      + diff --git a/Sites/pages/administrator/templates/hathor/html/com_weblinks/weblinks/default.php b/Sites/pages/administrator/templates/hathor/html/com_weblinks/weblinks/default.php new file mode 100644 index 00000000..58bb363b --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/com_weblinks/weblinks/default.php @@ -0,0 +1,204 @@ +get('id'); +$listOrder = $this->escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$canOrder = $user->authorise('core.edit.state', 'com_weblinks'); +$saveOrder = $listOrder == 'a.ordering'; +?> + +
      +sidebar)) : ?> +
      + sidebar; ?> +
      +
      + +
      + +
      + + + +
      + + + + + + + + + + + + + + + + +
      +
      +
      + + + + + + + + + + + + + + + + + + items as $i => $item) : + $ordering = ($listOrder == 'a.ordering'); + $item->cat_link = JRoute::_('index.php?option=com_categories&extension=com_weblinks&task=edit&type=other&cid[]=' . $item->catid); + $canCreate = $user->authorise('core.create', 'com_weblinks.category.' . $item->catid); + $canEdit = $user->authorise('core.edit', 'com_weblinks.category.' . $item->catid); + $canCheckin = $user->authorise('core.manage', 'com_checkin') || $item->checked_out == $user->get('id') || $item->checked_out == 0; + $canChange = $user->authorise('core.edit.state', 'com_weblinks.category.' . $item->catid) && $canCheckin; + ?> + + + + + + + + + + + + + +
      + + + + + + + + + + + items, 'filesave.png', 'weblinks.saveorder'); ?> + + + + + + + + + +
      + id); ?> + + checked_out) : ?> + editor, $item->checked_out_time, 'weblinks.', $canCheckin); ?> + + + + escape($item->title); ?> + + escape($item->title); ?> + +

      + escape($item->alias)); ?>

      +
      + state, $i, 'weblinks.', $canChange, 'cb', $item->publish_up, $item->publish_down); ?> + + escape($item->category_title); ?> + + + + + pagination->orderUpIcon($i, $item->catid == @$this->items[$i - 1]->catid, 'weblinks.orderup', 'JLIB_HTML_MOVE_UP', $ordering); ?> + pagination->orderDownIcon($i, $this->pagination->total, $item->catid == @$this->items[$i + 1]->catid, 'weblinks.orderdown', 'JLIB_HTML_MOVE_DOWN', $ordering); ?> + + pagination->orderUpIcon($i, $item->catid == @$this->items[$i - 1]->catid, 'weblinks.orderdown', 'JLIB_HTML_MOVE_UP', $ordering); ?> + pagination->orderDownIcon($i, $this->pagination->total, $item->catid == @$this->items[$i + 1]->catid, 'weblinks.orderup', 'JLIB_HTML_MOVE_DOWN', $ordering); ?> + + + + class="text-area-order" title="title; ?> order" /> + + ordering; ?> + + + escape($item->access_level); ?> + + hits; ?> + + + + id; ?> +
      + +pagination->getListFooter(); ?> +
      + + + loadTemplate('batch'); ?> + + + + + + +
      + diff --git a/Sites/pages/administrator/templates/hathor/html/layouts/com_media/toolbar/deletemedia.php b/Sites/pages/administrator/templates/hathor/html/layouts/com_media/toolbar/deletemedia.php new file mode 100644 index 00000000..9ae950f0 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/layouts/com_media/toolbar/deletemedia.php @@ -0,0 +1,16 @@ + + diff --git a/Sites/pages/administrator/templates/hathor/html/layouts/com_media/toolbar/newfolder.php b/Sites/pages/administrator/templates/hathor/html/layouts/com_media/toolbar/newfolder.php new file mode 100644 index 00000000..8d95f292 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/layouts/com_media/toolbar/newfolder.php @@ -0,0 +1,16 @@ + + diff --git a/Sites/pages/administrator/templates/hathor/html/layouts/com_media/toolbar/uploadmedia.php b/Sites/pages/administrator/templates/hathor/html/layouts/com_media/toolbar/uploadmedia.php new file mode 100644 index 00000000..74ec178e --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/layouts/com_media/toolbar/uploadmedia.php @@ -0,0 +1,16 @@ + + diff --git a/Sites/pages/administrator/templates/hathor/html/layouts/com_messages/toolbar/mysettings.php b/Sites/pages/administrator/templates/hathor/html/layouts/com_messages/toolbar/mysettings.php new file mode 100644 index 00000000..2279c75d --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/layouts/com_messages/toolbar/mysettings.php @@ -0,0 +1,16 @@ + + + + diff --git a/Sites/pages/administrator/templates/hathor/html/layouts/com_modules/toolbar/cancelselect.php b/Sites/pages/administrator/templates/hathor/html/layouts/com_modules/toolbar/cancelselect.php new file mode 100644 index 00000000..af4b39a2 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/layouts/com_modules/toolbar/cancelselect.php @@ -0,0 +1,16 @@ + + + + diff --git a/Sites/pages/administrator/templates/hathor/html/layouts/com_modules/toolbar/newmodule.php b/Sites/pages/administrator/templates/hathor/html/layouts/com_modules/toolbar/newmodule.php new file mode 100644 index 00000000..6d6db69b --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/layouts/com_modules/toolbar/newmodule.php @@ -0,0 +1,17 @@ + + + + + diff --git a/Sites/pages/administrator/templates/hathor/html/layouts/joomla/edit/details.php b/Sites/pages/administrator/templates/hathor/html/layouts/joomla/edit/details.php new file mode 100644 index 00000000..d46a7b92 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/layouts/joomla/edit/details.php @@ -0,0 +1,104 @@ +get('form')->getValue('title'); +$published = $displayData->get('form')->getValue('published'); +$saveHistory = $displayData->get('state')->get('params')->get('save_history', 0); +?> +
      +

      +
      +
      + +
      +
      + get('form')->getValue('name'); ?> +
      +
      + +
      +
      + get('form')->getValue('title'); ?> +
      +
      + + + +
      +
      + get('form')->getLabel('published'); ?> +
      +
      + get('form')->getInput('published'); ?> +
      +
      + +
      +
      + get('form')->getLabel('state'); ?> +
      +
      + get('form')->getInput('state'); ?> +
      +
      + + +
      +
      + get('form')->getLabel('access'); ?> +
      +
      + get('form')->getInput('access'); ?> +
      +
      +
      +
      + get('form')->getLabel('featured'); ?> +
      +
      + get('form')->getInput('featured'); ?> +
      +
      + +
      +
      + get('form')->getLabel('language'); ?> +
      +
      + get('form')->getInput('language'); ?> +
      +
      + + + +
      + get('form')->getFieldset('jmetadata') as $field) : ?> + name == 'jform[metadata][tags][]') :?> +
      +
      label; ?>
      +
      input; ?>
      +
      + + +
      + +
      +
      + get('form')->getLabel('version_note'); ?> +
      +
      + get('form')->getInput('version_note'); ?> +
      +
      + +
      +
      diff --git a/Sites/pages/administrator/templates/hathor/html/layouts/joomla/edit/fieldset.php b/Sites/pages/administrator/templates/hathor/html/layouts/joomla/edit/fieldset.php new file mode 100644 index 00000000..0e6eff63 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/layouts/joomla/edit/fieldset.php @@ -0,0 +1,67 @@ +getForm(); + +$name = $displayData->get('fieldset'); +$fieldSet = $form->getFieldset($name); + +if (empty($fieldSet)) +{ + return; +} + +$ignoreFields = $displayData->get('ignore_fields') ? : array(); +$extraFields = $displayData->get('extra_fields') ? : array(); + +if ($displayData->get('show_options', 1)) +{ + if (isset($extraFields[$name])) + { + foreach ($extraFields[$name] as $f) + { + if (in_array($f, $ignoreFields)) + { + continue; + } + if ($form->getField($f)) + { + $fieldSet[] = $form->getField($f); + } + } + } + + $html = array(); + $html[] = '
      '; + $html[] = '
        '; + + foreach ($fieldSet as $field) + { + $html[] = '
      • ' . $field->label . $field->input . '
      • '; + } + $html[] = '
      '; + $html[] = '
      '; + + echo implode('', $html); +} +else +{ + $html = array(); + $html[] = '
      '; + foreach ($fieldSet as $field) + { + $html[] = $field->input; + } + $html[] = '
      '; + + echo implode('', $html); +} diff --git a/Sites/pages/administrator/templates/hathor/html/layouts/joomla/edit/global.php b/Sites/pages/administrator/templates/hathor/html/layouts/joomla/edit/global.php new file mode 100644 index 00000000..226a8d66 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/layouts/joomla/edit/global.php @@ -0,0 +1,68 @@ +getForm(); +$input = $app->input; +$component = $input->getCmd('option', 'com_content'); + +if ($component === 'com_categories') +{ + $extension = $input->getCmd('extension', 'com_content'); + $parts = explode('.', $extension); + $component = $parts[0]; +} + +$saveHistory = JComponentHelper::getParams($component)->get('save_history', 0); + +$fields = $displayData->get('fields') ?: array( + array('parent', 'parent_id'), + array('published', 'state', 'enabled'), + array('category', 'catid'), + 'featured', + 'sticky', + 'access', + 'language', + 'tags', + 'note', + 'version_note', +); + +$hiddenFields = $displayData->get('hidden_fields') ?: array(); + +if (!$saveHistory) +{ + $hiddenFields[] = 'version_note'; +} + +$html = array(); +$html[] = '
      '; + +foreach ($fields as $field) +{ + foreach ((array) $field as $f) + { + if ($form->getField($f)) + { + if (in_array($f, $hiddenFields)) + { + $form->setFieldAttribute($f, 'type', 'hidden'); + } + + $html[] = $form->renderField($f); + break; + } + } +} + +$html[] = '
      '; + +echo implode('', $html); diff --git a/Sites/pages/administrator/templates/hathor/html/layouts/joomla/edit/metadata.php b/Sites/pages/administrator/templates/hathor/html/layouts/joomla/edit/metadata.php new file mode 100644 index 00000000..bf10e7c6 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/layouts/joomla/edit/metadata.php @@ -0,0 +1,48 @@ +get('form'); +?> +
      +
      + getLabel('metadesc'); ?> +
      + getInput('metadesc'); ?> +
      +
      +
      + getLabel('metakey'); ?> +
      + getInput('metakey'); ?> +
      +
      + getLabel('xreference')):?> +
      + getLabel('xreference'); ?> +
      + getInput('xreference'); ?> +
      +
      + + getGroup('metadata') as $field) : ?> + name != 'jform[metadata][tags][]') :?> +
      + hidden) : ?> + label; ?> + +
      + input; ?> +
      +
      + + +
      diff --git a/Sites/pages/administrator/templates/hathor/html/layouts/joomla/edit/params.php b/Sites/pages/administrator/templates/hathor/html/layouts/joomla/edit/params.php new file mode 100644 index 00000000..19a62e6e --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/layouts/joomla/edit/params.php @@ -0,0 +1,97 @@ +getForm(); +$fieldSets = $form->getFieldsets(); + +if (empty($fieldSets)) +{ + return; +} + +$ignoreFieldsets = $displayData->get('ignore_fieldsets') ?: array(); +$ignoreFields = $displayData->get('ignore_fields') ?: array(); +$extraFields = $displayData->get('extra_fields') ?: array(); +$tabName = $displayData->get('tab_name') ?: 'myTab'; + +if (!empty($displayData->hiddenFieldsets)) +{ + // These are required to preserve data on save when fields are not displayed. + $hiddenFieldsets = $displayData->hiddenFieldsets ?: array(); +} + +if (!empty($displayData->configFieldsets)) +{ + // These are required to configure showing and hiding fields in the editor. + $configFieldsets = $displayData->configFieldsets ?: array(); +} + +if ($displayData->get('show_options', 1)) +{ + foreach ($fieldSets as $name => $fieldSet) + { + // Ensure any fieldsets we don't want to show are skipped (including repeating formfield fieldsets) + if ((isset($fieldSet->repeat) && $fieldSet->repeat == true) + || in_array($name, $ignoreFieldsets) + || (!empty($configFieldsets) && in_array($name, $configFieldsets)) + || (!empty($hiddenFieldsets) && in_array($name, $hiddenFieldsets)) + ) + { + continue; + } + + if (!empty($fieldSet->label)) + { + $label = JText::_($fieldSet->label); + } + else + { + $label = strtoupper('JGLOBAL_FIELDSET_' . $name); + if (JText::_($label) === $label) + { + $label = strtoupper($app->input->get('option') . '_' . $name . '_FIELDSET_LABEL'); + } + $label = JText::_($label); + } + + if (isset($fieldSet->description) && trim($fieldSet->description)) + { + echo '

      ' . $this->escape(JText::_($fieldSet->description)) . '

      '; + } + + $displayData->fieldset = $name; + echo JLayoutHelper::render('joomla.edit.fieldset', $displayData); + } +} +else +{ + $html = array(); + $html[] = '
      '; + foreach ($fieldSets as $name => $fieldSet) + { + if (in_array($name, $ignoreFieldsets)) + { + continue; + } + + if (in_array($name, $hiddenFieldsets)) + { + foreach ($form->getFieldset($name) as $field) + { + $html[] = $field->input; + } + } + } + $html[] = '
      '; + + echo implode('', $html); +} diff --git a/Sites/pages/administrator/templates/hathor/html/layouts/joomla/quickicons/icon.php b/Sites/pages/administrator/templates/hathor/html/layouts/joomla/quickicons/icon.php new file mode 100644 index 00000000..ff53a276 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/layouts/joomla/quickicons/icon.php @@ -0,0 +1,26 @@ +escape($displayData['title']) . '"'); +$text = empty($displayData['text']) ? '' : ('' . $displayData['text'] . '') + +?> +
      > + +
      diff --git a/Sites/pages/administrator/templates/hathor/html/layouts/joomla/sidebars/submenu.php b/Sites/pages/administrator/templates/hathor/html/layouts/joomla/sidebars/submenu.php new file mode 100644 index 00000000..14489696 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/layouts/joomla/sidebars/submenu.php @@ -0,0 +1,37 @@ + + diff --git a/Sites/pages/administrator/templates/hathor/html/layouts/joomla/toolbar/base.php b/Sites/pages/administrator/templates/hathor/html/layouts/joomla/toolbar/base.php new file mode 100644 index 00000000..f84da7b2 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/layouts/joomla/toolbar/base.php @@ -0,0 +1,15 @@ + + +
    • > + +
    • diff --git a/Sites/pages/administrator/templates/hathor/html/layouts/joomla/toolbar/batch.php b/Sites/pages/administrator/templates/hathor/html/layouts/joomla/toolbar/batch.php new file mode 100644 index 00000000..0131fe46 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/layouts/joomla/toolbar/batch.php @@ -0,0 +1,18 @@ + + diff --git a/Sites/pages/administrator/templates/hathor/html/layouts/joomla/toolbar/confirm.php b/Sites/pages/administrator/templates/hathor/html/layouts/joomla/toolbar/confirm.php new file mode 100644 index 00000000..c2938a30 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/layouts/joomla/toolbar/confirm.php @@ -0,0 +1,21 @@ + + + + + + diff --git a/Sites/pages/administrator/templates/hathor/html/layouts/joomla/toolbar/containerclose.php b/Sites/pages/administrator/templates/hathor/html/layouts/joomla/toolbar/containerclose.php new file mode 100644 index 00000000..c3c9aa26 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/layouts/joomla/toolbar/containerclose.php @@ -0,0 +1,15 @@ + + + +
      +
      diff --git a/Sites/pages/administrator/templates/hathor/html/layouts/joomla/toolbar/containeropen.php b/Sites/pages/administrator/templates/hathor/html/layouts/joomla/toolbar/containeropen.php new file mode 100644 index 00000000..fb1b7b7c --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/layouts/joomla/toolbar/containeropen.php @@ -0,0 +1,14 @@ + + +
      +
        diff --git a/Sites/pages/administrator/templates/hathor/html/layouts/joomla/toolbar/help.php b/Sites/pages/administrator/templates/hathor/html/layouts/joomla/toolbar/help.php new file mode 100644 index 00000000..cb34a3e4 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/layouts/joomla/toolbar/help.php @@ -0,0 +1,20 @@ + + + + + + diff --git a/Sites/pages/administrator/templates/hathor/html/layouts/joomla/toolbar/iconclass.php b/Sites/pages/administrator/templates/hathor/html/layouts/joomla/toolbar/iconclass.php new file mode 100644 index 00000000..6111c3f3 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/layouts/joomla/toolbar/iconclass.php @@ -0,0 +1,12 @@ + +icon-32- diff --git a/Sites/pages/administrator/templates/hathor/html/layouts/joomla/toolbar/link.php b/Sites/pages/administrator/templates/hathor/html/layouts/joomla/toolbar/link.php new file mode 100644 index 00000000..802ae412 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/layouts/joomla/toolbar/link.php @@ -0,0 +1,21 @@ + + + + + + diff --git a/Sites/pages/administrator/templates/hathor/html/layouts/joomla/toolbar/modal.php b/Sites/pages/administrator/templates/hathor/html/layouts/joomla/toolbar/modal.php new file mode 100644 index 00000000..324c50c8 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/layouts/joomla/toolbar/modal.php @@ -0,0 +1,22 @@ + + + + + diff --git a/Sites/pages/administrator/templates/hathor/html/layouts/joomla/toolbar/popup.php b/Sites/pages/administrator/templates/hathor/html/layouts/joomla/toolbar/popup.php new file mode 100644 index 00000000..062775a8 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/layouts/joomla/toolbar/popup.php @@ -0,0 +1,21 @@ + + + + + + diff --git a/Sites/pages/administrator/templates/hathor/html/layouts/joomla/toolbar/separator.php b/Sites/pages/administrator/templates/hathor/html/layouts/joomla/toolbar/separator.php new file mode 100644 index 00000000..a760078f --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/layouts/joomla/toolbar/separator.php @@ -0,0 +1,16 @@ + +
      • >
      • diff --git a/Sites/pages/administrator/templates/hathor/html/layouts/joomla/toolbar/slider.php b/Sites/pages/administrator/templates/hathor/html/layouts/joomla/toolbar/slider.php new file mode 100644 index 00000000..02efb3ef --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/layouts/joomla/toolbar/slider.php @@ -0,0 +1,22 @@ + + +> + + + diff --git a/Sites/pages/administrator/templates/hathor/html/layouts/joomla/toolbar/standard.php b/Sites/pages/administrator/templates/hathor/html/layouts/joomla/toolbar/standard.php new file mode 100644 index 00000000..8d36c85d --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/layouts/joomla/toolbar/standard.php @@ -0,0 +1,22 @@ + + + + + + diff --git a/Sites/pages/administrator/templates/hathor/html/layouts/joomla/toolbar/title.php b/Sites/pages/administrator/templates/hathor/html/layouts/joomla/toolbar/title.php new file mode 100644 index 00000000..ec03abf2 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/layouts/joomla/toolbar/title.php @@ -0,0 +1,30 @@ + $icon) + { + $icons[$i] = 'icon-48-' . preg_replace('#\.[^.]*$#', '', $icon); + } + $class .= ' ' . htmlspecialchars(implode(' ', $icons), ENT_COMPAT, 'UTF-8'); +} +?> +
        +

        + +

        +
        diff --git a/Sites/pages/administrator/templates/hathor/html/layouts/joomla/toolbar/versions.php b/Sites/pages/administrator/templates/hathor/html/layouts/joomla/toolbar/versions.php new file mode 100644 index 00000000..d43a2f30 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/layouts/joomla/toolbar/versions.php @@ -0,0 +1,19 @@ + + + + diff --git a/Sites/pages/administrator/templates/hathor/html/layouts/plugins/user/profile/fields/dob.php b/Sites/pages/administrator/templates/hathor/html/layouts/plugins/user/profile/fields/dob.php new file mode 100644 index 00000000..566df464 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/layouts/plugins/user/profile/fields/dob.php @@ -0,0 +1,18 @@ + +
        diff --git a/Sites/pages/administrator/templates/hathor/html/mod_login/default.php b/Sites/pages/administrator/templates/hathor/html/mod_login/default.php new file mode 100644 index 00000000..3d3f5ffa --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/mod_login/default.php @@ -0,0 +1,55 @@ + +
        +
        + + + + + + + 1): ?> +
        +
        + + +
        +
        + + + + + + +
        + +
        +
        + +
        +
        + +
        + + + + + +
        +
        diff --git a/Sites/pages/administrator/templates/hathor/html/mod_quickicon/default.php b/Sites/pages/administrator/templates/hathor/html/mod_quickicon/default.php new file mode 100644 index 00000000..100041ef --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/mod_quickicon/default.php @@ -0,0 +1,18 @@ + + +
        + +
        + diff --git a/Sites/pages/administrator/templates/hathor/html/modules.php b/Sites/pages/administrator/templates/hathor/html/modules.php new file mode 100644 index 00000000..b84174f4 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/modules.php @@ -0,0 +1,48 @@ + + * + * This gives template designers ultimate control over how modules are rendered. + * + * NOTICE: All chrome wrapping methods should be named: modChrome_{STYLE} and take the same + * two arguments. + */ + +/* + * Module chrome for rendering the module in a submenu + */ +function modChrome_xhtmlid($module, &$params, &$attribs) +{ + if ($module->content) + { + ?> +
        + + content; ?> +
        + +
        + +
        + diff --git a/Sites/pages/administrator/templates/hathor/html/pagination.php b/Sites/pages/administrator/templates/hathor/html/pagination.php new file mode 100644 index 00000000..606f103f --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/html/pagination.php @@ -0,0 +1,153 @@ +base : integer + * $item->prefix : string + * $item->link : string + * $item->text : string + * + * pagination_item_inactive + * Input variable $item is an object with fields: + * $item->base : integer + * $item->prefix : string + * $item->link : string + * $item->text : string + * + * This gives template designers ultimate control over how pagination is rendered. + * + * NOTE: If you override pagination_item_active OR pagination_item_inactive you MUST override them both + */ + +function pagination_list_footer($list) +{ + /** + * Fix javascript jump menu + * + * Remove the onchange=Joomla.submitform from the select tag + * Add in a button with onclick instead + */ + $fixlimit = $list['limitfield']; + $fixlimit = preg_replace('/onchange="Joomla.submitform\(\);"/', '', $fixlimit); + + $html = '
        '; + + return $html; +} + +function pagination_list_render($list) +{ + $html = null; + + if ($list['start']['active']) + { + $html .= '
        '. $list['start']['data']. '
        '; + } else { + $html .= '
        '. $list['start']['data']. '
        '; + } + if ($list['previous']['active']) + { + $html .= '
        '; + } else { + $html .= '
        '; + } + + $html .= '
        '; + foreach ($list['pages'] as $page) + { + $html .= $page['data']; + } + $html .= '
        '; + + if ($list['next']['active']) + { + $html .= '
        '; + } else { + $html .= '
        '; + } + if ($list['end']['active']) + { + $html .= '
        '. $list['end']['data']. '
        '; + } else { + $html .= '
        '. $list['end']['data']. '
        '; + } + + return $html; +} + +function pagination_item_active(&$item) +{ + if ($item->base > 0) + { + return ''.$item->text. ''; + } + else + { + return ''.$item->text. ''; + } +} + +function pagination_item_inactive(&$item) +{ + if ($item->active) + { + $class = 'class="active"'; + } + else + { + $class = ''; + } + return '' . $item->text . ''; +} diff --git a/Sites/pages/administrator/templates/hathor/images/admin/blank.png b/Sites/pages/administrator/templates/hathor/images/admin/blank.png new file mode 100644 index 00000000..1797bf90 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/admin/blank.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/admin/checked_out.png b/Sites/pages/administrator/templates/hathor/images/admin/checked_out.png new file mode 100644 index 00000000..6ad8f25a Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/admin/checked_out.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/admin/collapseall.png b/Sites/pages/administrator/templates/hathor/images/admin/collapseall.png new file mode 100644 index 00000000..3d50db82 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/admin/collapseall.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/admin/disabled.png b/Sites/pages/administrator/templates/hathor/images/admin/disabled.png new file mode 100644 index 00000000..5218081b Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/admin/disabled.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/admin/downarrow-1.png b/Sites/pages/administrator/templates/hathor/images/admin/downarrow-1.png new file mode 100644 index 00000000..c94074e5 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/admin/downarrow-1.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/admin/downarrow.png b/Sites/pages/administrator/templates/hathor/images/admin/downarrow.png new file mode 100644 index 00000000..a27a7585 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/admin/downarrow.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/admin/downarrow0.png b/Sites/pages/administrator/templates/hathor/images/admin/downarrow0.png new file mode 100644 index 00000000..bd9f310e Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/admin/downarrow0.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/admin/expandall.png b/Sites/pages/administrator/templates/hathor/images/admin/expandall.png new file mode 100644 index 00000000..233cb735 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/admin/expandall.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/admin/featured.png b/Sites/pages/administrator/templates/hathor/images/admin/featured.png new file mode 100644 index 00000000..a3e2c159 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/admin/featured.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/admin/filesave.png b/Sites/pages/administrator/templates/hathor/images/admin/filesave.png new file mode 100644 index 00000000..65a45b55 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/admin/filesave.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/admin/filter_16.png b/Sites/pages/administrator/templates/hathor/images/admin/filter_16.png new file mode 100644 index 00000000..cbc62b7d Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/admin/filter_16.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/admin/icon-16-allow.png b/Sites/pages/administrator/templates/hathor/images/admin/icon-16-allow.png new file mode 100644 index 00000000..d28a18b2 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/admin/icon-16-allow.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/admin/icon-16-allowinactive.png b/Sites/pages/administrator/templates/hathor/images/admin/icon-16-allowinactive.png new file mode 100644 index 00000000..d20e059d Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/admin/icon-16-allowinactive.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/admin/icon-16-deny.png b/Sites/pages/administrator/templates/hathor/images/admin/icon-16-deny.png new file mode 100644 index 00000000..a5b37aa2 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/admin/icon-16-deny.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/admin/icon-16-denyinactive.png b/Sites/pages/administrator/templates/hathor/images/admin/icon-16-denyinactive.png new file mode 100644 index 00000000..0dc1b43e Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/admin/icon-16-denyinactive.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/admin/icon-16-links.png b/Sites/pages/administrator/templates/hathor/images/admin/icon-16-links.png new file mode 100644 index 00000000..52b4cb43 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/admin/icon-16-links.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/admin/icon-16-notice-note.png b/Sites/pages/administrator/templates/hathor/images/admin/icon-16-notice-note.png new file mode 100644 index 00000000..a207d70a Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/admin/icon-16-notice-note.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/admin/icon-16-protected.png b/Sites/pages/administrator/templates/hathor/images/admin/icon-16-protected.png new file mode 100644 index 00000000..b72ad935 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/admin/icon-16-protected.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/admin/menu_divider.png b/Sites/pages/administrator/templates/hathor/images/admin/menu_divider.png new file mode 100644 index 00000000..174df4cd Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/admin/menu_divider.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/admin/note_add_16.png b/Sites/pages/administrator/templates/hathor/images/admin/note_add_16.png new file mode 100644 index 00000000..68e7ee66 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/admin/note_add_16.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/admin/publish_g.png b/Sites/pages/administrator/templates/hathor/images/admin/publish_g.png new file mode 100644 index 00000000..d3794988 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/admin/publish_g.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/admin/publish_r.png b/Sites/pages/administrator/templates/hathor/images/admin/publish_r.png new file mode 100644 index 00000000..1405a790 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/admin/publish_r.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/admin/publish_x.png b/Sites/pages/administrator/templates/hathor/images/admin/publish_x.png new file mode 100644 index 00000000..87190439 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/admin/publish_x.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/admin/publish_y.png b/Sites/pages/administrator/templates/hathor/images/admin/publish_y.png new file mode 100644 index 00000000..4652e87c Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/admin/publish_y.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/admin/sort_asc.png b/Sites/pages/administrator/templates/hathor/images/admin/sort_asc.png new file mode 100644 index 00000000..1204f31f Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/admin/sort_asc.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/admin/sort_desc.png b/Sites/pages/administrator/templates/hathor/images/admin/sort_desc.png new file mode 100644 index 00000000..c0ca72e6 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/admin/sort_desc.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/admin/tick.png b/Sites/pages/administrator/templates/hathor/images/admin/tick.png new file mode 100644 index 00000000..2b11164d Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/admin/tick.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/admin/trash.png b/Sites/pages/administrator/templates/hathor/images/admin/trash.png new file mode 100644 index 00000000..b2d671a4 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/admin/trash.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/admin/uparrow-1.png b/Sites/pages/administrator/templates/hathor/images/admin/uparrow-1.png new file mode 100644 index 00000000..20175936 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/admin/uparrow-1.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/admin/uparrow.png b/Sites/pages/administrator/templates/hathor/images/admin/uparrow.png new file mode 100644 index 00000000..def39656 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/admin/uparrow.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/admin/uparrow0.png b/Sites/pages/administrator/templates/hathor/images/admin/uparrow0.png new file mode 100644 index 00000000..60602b83 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/admin/uparrow0.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/arrow.png b/Sites/pages/administrator/templates/hathor/images/arrow.png new file mode 100644 index 00000000..7fe1a536 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/arrow.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/bg-menu.gif b/Sites/pages/administrator/templates/hathor/images/bg-menu.gif new file mode 100644 index 00000000..f36c5872 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/bg-menu.gif differ diff --git a/Sites/pages/administrator/templates/hathor/images/calendar.png b/Sites/pages/administrator/templates/hathor/images/calendar.png new file mode 100644 index 00000000..586bc28e Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/calendar.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-alert.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-alert.png new file mode 100644 index 00000000..297b5826 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-alert.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-apply.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-apply.png new file mode 100644 index 00000000..179c2017 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-apply.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-archive.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-archive.png new file mode 100644 index 00000000..87bbe302 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-archive.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-article-add.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-article-add.png new file mode 100644 index 00000000..b9249fd4 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-article-add.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-article-edit.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-article-edit.png new file mode 100644 index 00000000..2d271335 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-article-edit.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-article.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-article.png new file mode 100644 index 00000000..0f629c9a Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-article.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-assoc.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-assoc.png new file mode 100644 index 00000000..4444f875 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-assoc.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-banner-categories.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-banner-categories.png new file mode 100644 index 00000000..bf588204 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-banner-categories.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-banner-client.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-banner-client.png new file mode 100644 index 00000000..9a5df676 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-banner-client.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-banner-tracks.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-banner-tracks.png new file mode 100644 index 00000000..9be1442b Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-banner-tracks.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-banner.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-banner.png new file mode 100644 index 00000000..3e36c154 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-banner.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-calendar.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-calendar.png new file mode 100644 index 00000000..151a52bf Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-calendar.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-category-add.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-category-add.png new file mode 100644 index 00000000..5ee7740a Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-category-add.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-category.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-category.png new file mode 100644 index 00000000..354f1853 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-category.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-checkin.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-checkin.png new file mode 100644 index 00000000..6ab4cdda Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-checkin.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-clear.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-clear.png new file mode 100644 index 00000000..76dee7ce Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-clear.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-component.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-component.png new file mode 100644 index 00000000..c4179a6e Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-component.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-config.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-config.png new file mode 100644 index 00000000..1b895fcb Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-config.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-contacts-categories.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-contacts-categories.png new file mode 100644 index 00000000..73a689b5 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-contacts-categories.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-contacts.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-contacts.png new file mode 100644 index 00000000..d2128a1c Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-contacts.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-content.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-content.png new file mode 100644 index 00000000..363020bc Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-content.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-cpanel.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-cpanel.png new file mode 100644 index 00000000..8fa510d2 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-cpanel.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-default.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-default.png new file mode 100644 index 00000000..de1b8053 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-default.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-deny.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-deny.png new file mode 100644 index 00000000..291da192 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-deny.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-download.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-download.png new file mode 100644 index 00000000..bbd5d917 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-download.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-edit.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-edit.png new file mode 100644 index 00000000..e24a733c Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-edit.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-extension.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-extension.png new file mode 100644 index 00000000..b26131d1 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-extension.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-featured.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-featured.png new file mode 100644 index 00000000..acfe49a7 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-featured.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-frontpage.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-frontpage.png new file mode 100644 index 00000000..285b65e4 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-frontpage.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-generic.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-generic.png new file mode 100644 index 00000000..c50f01e9 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-generic.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-groups-add.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-groups-add.png new file mode 100644 index 00000000..411fd886 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-groups-add.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-groups.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-groups.png new file mode 100644 index 00000000..21d52f24 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-groups.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-help-forum.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-help-forum.png new file mode 100644 index 00000000..62133d7e Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-help-forum.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-help-this.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-help-this.png new file mode 100644 index 00000000..b1845f5c Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-help-this.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-help_header.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-help_header.png new file mode 100644 index 00000000..559b654b Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-help_header.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-inbox.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-inbox.png new file mode 100644 index 00000000..29f41298 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-inbox.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-info.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-info.png new file mode 100644 index 00000000..0d8641d0 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-info.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-install.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-install.png new file mode 100644 index 00000000..5747c4d7 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-install.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-jupdate-updatefound.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-jupdate-updatefound.png new file mode 100644 index 00000000..288ab8bd Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-jupdate-updatefound.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-jupdate-uptodate.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-jupdate-uptodate.png new file mode 100644 index 00000000..924b1dbc Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-jupdate-uptodate.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-language.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-language.png new file mode 100644 index 00000000..902d11c2 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-language.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-levels-add.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-levels-add.png new file mode 100644 index 00000000..e5458d5a Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-levels-add.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-levels.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-levels.png new file mode 100644 index 00000000..3a87ad0f Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-levels.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-links-cat.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-links-cat.png new file mode 100644 index 00000000..7b20b257 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-links-cat.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-links.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-links.png new file mode 100644 index 00000000..b534e8a3 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-links.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-massmail.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-massmail.png new file mode 100644 index 00000000..c0c8fcd1 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-massmail.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-media.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-media.png new file mode 100644 index 00000000..4fbb51cd Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-media.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-menu-add.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-menu-add.png new file mode 100644 index 00000000..5c901aa8 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-menu-add.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-menu.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-menu.png new file mode 100644 index 00000000..26194944 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-menu.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-menumgr.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-menumgr.png new file mode 100644 index 00000000..58146f31 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-menumgr.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-module.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-module.png new file mode 100644 index 00000000..0a8e444e Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-module.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-move.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-move.png new file mode 100644 index 00000000..70772a39 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-move.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-new-privatemessage.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-new-privatemessage.png new file mode 100644 index 00000000..7bab1e70 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-new-privatemessage.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-newcategory.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-newcategory.png new file mode 100644 index 00000000..5797c9ce Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-newcategory.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-newsfeeds-cat.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-newsfeeds-cat.png new file mode 100644 index 00000000..886b5765 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-newsfeeds-cat.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-newsfeeds.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-newsfeeds.png new file mode 100644 index 00000000..f1bd76d0 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-newsfeeds.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-notice.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-notice.png new file mode 100644 index 00000000..16e1b96e Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-notice.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-plugin.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-plugin.png new file mode 100644 index 00000000..d127b6cd Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-plugin.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-preview.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-preview.png new file mode 100644 index 00000000..40dd10be Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-preview.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-print.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-print.png new file mode 100644 index 00000000..37e11dee Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-print.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-purge.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-purge.png new file mode 100644 index 00000000..97346a97 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-purge.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-puzzle.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-puzzle.png new file mode 100644 index 00000000..f0019d8d Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-puzzle.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-read-privatemessage.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-read-privatemessage.png new file mode 100644 index 00000000..cd255df8 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-read-privatemessage.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-readmess.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-readmess.png new file mode 100644 index 00000000..208b7934 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-readmess.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-redirect.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-redirect.png new file mode 100644 index 00000000..580a555a Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-redirect.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-revert.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-revert.png new file mode 100644 index 00000000..9bf2944a Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-revert.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-search.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-search.png new file mode 100644 index 00000000..79004021 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-search.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-section.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-section.png new file mode 100644 index 00000000..e6e0195d Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-section.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-send.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-send.png new file mode 100644 index 00000000..7ca3994a Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-send.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-static.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-static.png new file mode 100644 index 00000000..363020bc Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-static.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-stats.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-stats.png new file mode 100644 index 00000000..64659fde Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-stats.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-tags.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-tags.png new file mode 100644 index 00000000..9ba2124d Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-tags.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-themes.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-themes.png new file mode 100644 index 00000000..7e31c86f Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-themes.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-trash.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-trash.png new file mode 100644 index 00000000..1a388bbe Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-trash.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-unarchive.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-unarchive.png new file mode 100644 index 00000000..6e3b0581 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-unarchive.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-upload.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-upload.png new file mode 100644 index 00000000..7d76ece3 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-upload.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-user-add.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-user-add.png new file mode 100644 index 00000000..ab2112e4 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-user-add.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-user-edit.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-user-edit.png new file mode 100644 index 00000000..ab2112e4 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-user-edit.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-user-profile.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-user-profile.png new file mode 100644 index 00000000..0d8641d0 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-user-profile.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-user.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-user.png new file mode 100644 index 00000000..cc6e43a6 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-user.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-48-writemess.png b/Sites/pages/administrator/templates/hathor/images/header/icon-48-writemess.png new file mode 100644 index 00000000..827d99a0 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-48-writemess.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/header/icon-messaging.png b/Sites/pages/administrator/templates/hathor/images/header/icon-messaging.png new file mode 100644 index 00000000..46a377b2 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/header/icon-messaging.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/j_arrow.png b/Sites/pages/administrator/templates/hathor/images/j_arrow.png new file mode 100644 index 00000000..772bb4d9 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/j_arrow.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/j_arrow_down.png b/Sites/pages/administrator/templates/hathor/images/j_arrow_down.png new file mode 100644 index 00000000..5e733411 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/j_arrow_down.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/j_arrow_left.png b/Sites/pages/administrator/templates/hathor/images/j_arrow_left.png new file mode 100644 index 00000000..bee0eb1c Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/j_arrow_left.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/j_arrow_right.png b/Sites/pages/administrator/templates/hathor/images/j_arrow_right.png new file mode 100644 index 00000000..ed65eeda Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/j_arrow_right.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/j_login_lock.png b/Sites/pages/administrator/templates/hathor/images/j_login_lock.png new file mode 100644 index 00000000..b14c49b7 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/j_login_lock.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/j_logo.png b/Sites/pages/administrator/templates/hathor/images/j_logo.png new file mode 100644 index 00000000..3b1f5dfe Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/j_logo.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/logo.png b/Sites/pages/administrator/templates/hathor/images/logo.png new file mode 100644 index 00000000..00d02200 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/logo.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-alert.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-alert.png new file mode 100644 index 00000000..c1e0ed45 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-alert.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-apply.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-apply.png new file mode 100644 index 00000000..415fe205 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-apply.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-archive.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-archive.png new file mode 100644 index 00000000..1a948a56 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-archive.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-article.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-article.png new file mode 100644 index 00000000..c3a39d4a Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-article.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-assoc.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-assoc.png new file mode 100644 index 00000000..f0f8c5a3 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-assoc.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-back-user.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-back-user.png new file mode 100644 index 00000000..61ae0e0a Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-back-user.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-banner-categories.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-banner-categories.png new file mode 100644 index 00000000..8ce715f7 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-banner-categories.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-banner-client.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-banner-client.png new file mode 100644 index 00000000..9e071732 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-banner-client.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-banner-tracks.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-banner-tracks.png new file mode 100644 index 00000000..7f7f1218 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-banner-tracks.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-banner.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-banner.png new file mode 100644 index 00000000..2b030c9c Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-banner.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-calendar.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-calendar.png new file mode 100644 index 00000000..e2de0b7e Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-calendar.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-category.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-category.png new file mode 100644 index 00000000..f0c7a4f8 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-category.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-checkin.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-checkin.png new file mode 100644 index 00000000..2b11164d Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-checkin.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-clear.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-clear.png new file mode 100644 index 00000000..b609ada0 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-clear.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-component.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-component.png new file mode 100644 index 00000000..051a57b2 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-component.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-config.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-config.png new file mode 100644 index 00000000..c4edc5e3 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-config.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-contacts-categories.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-contacts-categories.png new file mode 100644 index 00000000..05fee276 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-contacts-categories.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-contacts.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-contacts.png new file mode 100644 index 00000000..24a8e8ee Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-contacts.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-content.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-content.png new file mode 100644 index 00000000..073aefa1 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-content.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-cpanel.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-cpanel.png new file mode 100644 index 00000000..c6d7761a Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-cpanel.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-default.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-default.png new file mode 100644 index 00000000..ab7702f9 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-default.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-delete.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-delete.png new file mode 100644 index 00000000..a93bed32 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-delete.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-deny.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-deny.png new file mode 100644 index 00000000..58d44076 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-deny.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-download.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-download.png new file mode 100644 index 00000000..396357c7 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-download.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-edit.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-edit.png new file mode 100644 index 00000000..936fe76c Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-edit.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-featured.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-featured.png new file mode 100644 index 00000000..dfd4e1de Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-featured.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-frontpage.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-frontpage.png new file mode 100644 index 00000000..675de06a Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-frontpage.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-generic.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-generic.png new file mode 100644 index 00000000..fa1099cb Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-generic.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-groups.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-groups.png new file mode 100644 index 00000000..28c67dcc Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-groups.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-help-community.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-help-community.png new file mode 100644 index 00000000..7b39c5fc Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-help-community.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-help-dev.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-help-dev.png new file mode 100644 index 00000000..3187674a Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-help-dev.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-help-docs.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-help-docs.png new file mode 100644 index 00000000..e8f6f4e4 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-help-docs.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-help-forum.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-help-forum.png new file mode 100644 index 00000000..bc0d3837 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-help-forum.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-help-jed.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-help-jed.png new file mode 100644 index 00000000..498a01ac Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-help-jed.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-help-jrd.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-help-jrd.png new file mode 100644 index 00000000..79a9d30d Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-help-jrd.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-help-security.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-help-security.png new file mode 100644 index 00000000..0050ca5d Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-help-security.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-help-shop.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-help-shop.png new file mode 100644 index 00000000..e24dc8a5 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-help-shop.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-help-this.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-help-this.png new file mode 100644 index 00000000..c90eac90 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-help-this.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-help-trans.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-help-trans.png new file mode 100644 index 00000000..1f2264c1 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-help-trans.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-help.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-help.png new file mode 100644 index 00000000..8c3a8ab9 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-help.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-inbox.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-inbox.png new file mode 100644 index 00000000..f808d62d Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-inbox.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-info.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-info.png new file mode 100644 index 00000000..3080bfdf Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-info.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-install.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-install.png new file mode 100644 index 00000000..f393945a Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-install.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-language.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-language.png new file mode 100644 index 00000000..76d33640 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-language.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-levels.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-levels.png new file mode 100644 index 00000000..f5a808f8 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-levels.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-links-cat.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-links-cat.png new file mode 100644 index 00000000..bc2a50ba Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-links-cat.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-links.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-links.png new file mode 100644 index 00000000..52b4cb43 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-links.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-logout.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-logout.png new file mode 100644 index 00000000..aab064a4 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-logout.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-maintenance.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-maintenance.png new file mode 100644 index 00000000..642c5552 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-maintenance.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-massmail.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-massmail.png new file mode 100644 index 00000000..d460e1ad Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-massmail.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-media.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-media.png new file mode 100644 index 00000000..ffb9498e Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-media.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-menu.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-menu.png new file mode 100644 index 00000000..c6a0ee42 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-menu.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-menumgr.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-menumgr.png new file mode 100644 index 00000000..88a2d1b3 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-menumgr.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-messages.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-messages.png new file mode 100644 index 00000000..56fc7804 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-messages.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-messaging.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-messaging.png new file mode 100644 index 00000000..33ffed14 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-messaging.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-module.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-module.png new file mode 100644 index 00000000..55ba9dbd Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-module.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-move.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-move.png new file mode 100644 index 00000000..6d709fcc Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-move.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-new-privatemessage.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-new-privatemessage.png new file mode 100644 index 00000000..f8f1ea8f Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-new-privatemessage.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-new.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-new.png new file mode 100644 index 00000000..8c4b8ba6 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-new.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-newarticle.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-newarticle.png new file mode 100644 index 00000000..c78257d1 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-newarticle.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-newcategory.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-newcategory.png new file mode 100644 index 00000000..fd4318c6 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-newcategory.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-newgroup.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-newgroup.png new file mode 100644 index 00000000..cb5b82cf Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-newgroup.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-newlevel.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-newlevel.png new file mode 100644 index 00000000..4ff0fb9a Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-newlevel.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-newsfeeds-cat.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-newsfeeds-cat.png new file mode 100644 index 00000000..55ebb428 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-newsfeeds-cat.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-newsfeeds.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-newsfeeds.png new file mode 100644 index 00000000..6639ec84 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-newsfeeds.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-newuser.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-newuser.png new file mode 100644 index 00000000..25d4cfd2 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-newuser.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-nopreview.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-nopreview.png new file mode 100644 index 00000000..cc79db62 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-nopreview.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-notdefault.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-notdefault.png new file mode 100644 index 00000000..8e5ced86 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-notdefault.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-notice.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-notice.png new file mode 100644 index 00000000..59f8b365 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-notice.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-plugin.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-plugin.png new file mode 100644 index 00000000..852c87dd Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-plugin.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-preview.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-preview.png new file mode 100644 index 00000000..e532f7d7 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-preview.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-print.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-print.png new file mode 100644 index 00000000..a1b9f315 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-print.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-purge.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-purge.png new file mode 100644 index 00000000..3aa8a5e2 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-purge.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-puzzle.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-puzzle.png new file mode 100644 index 00000000..fcc02d53 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-puzzle.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-read-privatemessage.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-read-privatemessage.png new file mode 100644 index 00000000..ee2f4403 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-read-privatemessage.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-readmess.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-readmess.png new file mode 100644 index 00000000..4c5f3046 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-readmess.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-redirect.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-redirect.png new file mode 100644 index 00000000..3a30b15b Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-redirect.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-revert.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-revert.png new file mode 100644 index 00000000..0b6c71f3 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-revert.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-search.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-search.png new file mode 100644 index 00000000..04cf3852 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-search.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-send.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-send.png new file mode 100644 index 00000000..188add67 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-send.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-stats.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-stats.png new file mode 100644 index 00000000..f0c4c045 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-stats.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-tags.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-tags.png new file mode 100644 index 00000000..94411880 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-tags.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-themes.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-themes.png new file mode 100644 index 00000000..2f20de7b Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-themes.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-trash.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-trash.png new file mode 100644 index 00000000..9c100938 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-trash.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-unarticle.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-unarticle.png new file mode 100644 index 00000000..793ea003 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-unarticle.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-upload.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-upload.png new file mode 100644 index 00000000..41549c52 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-upload.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-user-dd.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-user-dd.png new file mode 100644 index 00000000..a7ab2464 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-user-dd.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-user-note.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-user-note.png new file mode 100644 index 00000000..d634a59c Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-user-note.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-user.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-user.png new file mode 100644 index 00000000..51f4ba51 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-user.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-viewsite.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-viewsite.png new file mode 100644 index 00000000..121997e5 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-viewsite.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/menu/icon-16-writemess.png b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-writemess.png new file mode 100644 index 00000000..f24cfb3d Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/menu/icon-16-writemess.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/mini_icon.png b/Sites/pages/administrator/templates/hathor/images/mini_icon.png new file mode 100644 index 00000000..91a2a59d Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/mini_icon.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/notice-alert.png b/Sites/pages/administrator/templates/hathor/images/notice-alert.png new file mode 100644 index 00000000..d21ae834 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/notice-alert.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/notice-info.png b/Sites/pages/administrator/templates/hathor/images/notice-info.png new file mode 100644 index 00000000..939933a5 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/notice-info.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/notice-note.png b/Sites/pages/administrator/templates/hathor/images/notice-note.png new file mode 100644 index 00000000..aa4d3aac Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/notice-note.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/required.png b/Sites/pages/administrator/templates/hathor/images/required.png new file mode 100644 index 00000000..3cb1bc12 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/required.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/selector-arrow-hc.png b/Sites/pages/administrator/templates/hathor/images/selector-arrow-hc.png new file mode 100644 index 00000000..a613f31e Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/selector-arrow-hc.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/selector-arrow-rtl.png b/Sites/pages/administrator/templates/hathor/images/selector-arrow-rtl.png new file mode 100644 index 00000000..9f721c50 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/selector-arrow-rtl.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/selector-arrow-std.png b/Sites/pages/administrator/templates/hathor/images/selector-arrow-std.png new file mode 100644 index 00000000..15e3d8fe Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/selector-arrow-std.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/selector-arrow.png b/Sites/pages/administrator/templates/hathor/images/selector-arrow.png new file mode 100644 index 00000000..9e7687e5 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/selector-arrow.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/system/calendar.png b/Sites/pages/administrator/templates/hathor/images/system/calendar.png new file mode 100644 index 00000000..586bc28e Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/system/calendar.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/system/selector-arrow.png b/Sites/pages/administrator/templates/hathor/images/system/selector-arrow.png new file mode 100644 index 00000000..9e7687e5 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/system/selector-arrow.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-adduser.png b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-adduser.png new file mode 100644 index 00000000..a34c2455 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-adduser.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-alert.png b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-alert.png new file mode 100644 index 00000000..c4bd24ec Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-alert.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-apply.png b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-apply.png new file mode 100644 index 00000000..423fcacb Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-apply.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-archive.png b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-archive.png new file mode 100644 index 00000000..13a72777 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-archive.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-article-add.png b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-article-add.png new file mode 100644 index 00000000..0778bd98 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-article-add.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-article.png b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-article.png new file mode 100644 index 00000000..bf16fa6a Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-article.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-back.png b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-back.png new file mode 100644 index 00000000..7b8d35a0 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-back.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-banner-categories.png b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-banner-categories.png new file mode 100644 index 00000000..732c0110 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-banner-categories.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-banner-client.png b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-banner-client.png new file mode 100644 index 00000000..5ad4ea22 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-banner-client.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-banner-tracks.png b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-banner-tracks.png new file mode 100644 index 00000000..d39c1ebe Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-banner-tracks.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-banner.png b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-banner.png new file mode 100644 index 00000000..e51c03e0 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-banner.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-batch.png b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-batch.png new file mode 100644 index 00000000..b3cd07e4 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-batch.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-calendar.png b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-calendar.png new file mode 100644 index 00000000..5a72d6ee Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-calendar.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-cancel.png b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-cancel.png new file mode 100644 index 00000000..b143e100 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-cancel.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-checkin.png b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-checkin.png new file mode 100644 index 00000000..04e4e5b3 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-checkin.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-cog.png b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-cog.png new file mode 100644 index 00000000..abbff360 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-cog.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-component.png b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-component.png new file mode 100644 index 00000000..7ffc421a Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-component.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-config.png b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-config.png new file mode 100644 index 00000000..53de9648 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-config.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-contacts-categories.png b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-contacts-categories.png new file mode 100644 index 00000000..7ea47e95 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-contacts-categories.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-contacts.png b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-contacts.png new file mode 100644 index 00000000..2b7abca4 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-contacts.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-copy.png b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-copy.png new file mode 100644 index 00000000..dc036ec8 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-copy.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-css.png b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-css.png new file mode 100644 index 00000000..1b75813b Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-css.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-default.png b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-default.png new file mode 100644 index 00000000..90c8aa95 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-default.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-delete-style.png b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-delete-style.png new file mode 100644 index 00000000..247ead53 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-delete-style.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-delete.png b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-delete.png new file mode 100644 index 00000000..4d05ecdb Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-delete.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-deny.png b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-deny.png new file mode 100644 index 00000000..4ac081c6 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-deny.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-download.png b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-download.png new file mode 100644 index 00000000..d09df782 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-download.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-edit.png b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-edit.png new file mode 100644 index 00000000..344b3e79 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-edit.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-error.png b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-error.png new file mode 100644 index 00000000..0cc0aaa7 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-error.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-export.png b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-export.png new file mode 100644 index 00000000..d9d59835 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-export.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-extension.png b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-extension.png new file mode 100644 index 00000000..8a45ae77 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-extension.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-featured.png b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-featured.png new file mode 100644 index 00000000..1662afae Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-featured.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-forward.png b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-forward.png new file mode 100644 index 00000000..c3ac95d3 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-forward.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-help.png b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-help.png new file mode 100644 index 00000000..fbf408cd Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-help.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-html.png b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-html.png new file mode 100644 index 00000000..1570f323 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-html.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-inbox.png b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-inbox.png new file mode 100644 index 00000000..490d275c Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-inbox.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-info.png b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-info.png new file mode 100644 index 00000000..0f6c8ca9 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-info.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-links.png b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-links.png new file mode 100644 index 00000000..bd867afc Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-links.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-lock.png b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-lock.png new file mode 100644 index 00000000..a9180af8 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-lock.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-menu.png b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-menu.png new file mode 100644 index 00000000..bc0b5fd4 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-menu.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-messaging.png b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-messaging.png new file mode 100644 index 00000000..ee6080cd Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-messaging.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-messanging.png b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-messanging.png new file mode 100644 index 00000000..ee6080cd Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-messanging.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-module.png b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-module.png new file mode 100644 index 00000000..eb218067 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-module.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-move.png b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-move.png new file mode 100644 index 00000000..2ef3a189 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-move.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-new-privatemessage.png b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-new-privatemessage.png new file mode 100644 index 00000000..5546a316 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-new-privatemessage.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-new-style.png b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-new-style.png new file mode 100644 index 00000000..cf23704f Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-new-style.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-new.png b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-new.png new file mode 100644 index 00000000..a4e1b78a Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-new.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-notice.png b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-notice.png new file mode 100644 index 00000000..cb6db185 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-notice.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-preview.png b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-preview.png new file mode 100644 index 00000000..eefa6a51 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-preview.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-print.png b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-print.png new file mode 100644 index 00000000..8ed65a33 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-print.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-publish.png b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-publish.png new file mode 100644 index 00000000..3bd38264 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-publish.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-purge.png b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-purge.png new file mode 100644 index 00000000..c87eebd0 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-purge.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-read-privatemessage.png b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-read-privatemessage.png new file mode 100644 index 00000000..eb40ead2 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-read-privatemessage.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-refresh.png b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-refresh.png new file mode 100644 index 00000000..e974d56f Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-refresh.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-remove.png b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-remove.png new file mode 100644 index 00000000..65ffdb3e Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-remove.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-revert.png b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-revert.png new file mode 100644 index 00000000..60b13969 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-revert.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-save-copy.png b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-save-copy.png new file mode 100644 index 00000000..3885723b Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-save-copy.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-save-new.png b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-save-new.png new file mode 100644 index 00000000..e5a115a2 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-save-new.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-save.png b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-save.png new file mode 100644 index 00000000..399dec5c Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-save.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-search.png b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-search.png new file mode 100644 index 00000000..a3be36a3 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-search.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-send.png b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-send.png new file mode 100644 index 00000000..51ae4145 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-send.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-stats.png b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-stats.png new file mode 100644 index 00000000..b3eb1ebe Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-stats.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-trash.png b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-trash.png new file mode 100644 index 00000000..89efa4ac Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-trash.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-unarchive.png b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-unarchive.png new file mode 100644 index 00000000..32b95072 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-unarchive.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-unblock.png b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-unblock.png new file mode 100644 index 00000000..eccc84a4 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-unblock.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-unpublish.png b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-unpublish.png new file mode 100644 index 00000000..1cf06556 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-unpublish.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-upload.png b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-upload.png new file mode 100644 index 00000000..e41e613b Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-upload.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-user-add.png b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-user-add.png new file mode 100644 index 00000000..8bbf9d81 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-user-add.png differ diff --git a/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-xml.png b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-xml.png new file mode 100644 index 00000000..95831db9 Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/images/toolbar/icon-32-xml.png differ diff --git a/Sites/pages/administrator/templates/hathor/index.php b/Sites/pages/administrator/templates/hathor/index.php new file mode 100644 index 00000000..696d6a2e --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/index.php @@ -0,0 +1,179 @@ +setHtml5(true); + +// jQuery needed by template.js +JHtml::_('jquery.framework'); + +// Add template js +JHtml::_('script', 'template.js', array('version' => 'auto', 'relative' => true)); + +// Add html5 shiv +JHtml::_('script', 'jui/html5.js', array('version' => 'auto', 'relative' => true, 'conditional' => 'lt IE 9')); + +// Load optional RTL Bootstrap CSS +JHtml::_('bootstrap.loadCss', false, $this->direction); + +// Load system style CSS +JHtml::_('stylesheet', 'templates/system/css/system.css', array('version' => 'auto')); + +// Load template CSS +JHtml::_('stylesheet', 'template.css', array('version' => 'auto', 'relative' => true)); + +// Load additional CSS styles for colors +if (!$this->params->get('colourChoice')) +{ + $colour = 'standard'; +} +else +{ + $colour = htmlspecialchars($this->params->get('colourChoice')); +} + +JHtml::_('stylesheet', 'colour_' . $colour . '.css', array('version' => 'auto', 'relative' => true)); + +// Load additional CSS styles for rtl sites +if ($this->direction === 'rtl') +{ + JHtml::_('stylesheet', 'template_rtl.css', array('version' => 'auto', 'relative' => true)); + JHtml::_('stylesheet', 'colour_' . $colour . '_rtl.css', array('version' => 'auto', 'relative' => true)); +} + +// Load additional CSS styles for bold Text +if ($this->params->get('boldText')) +{ + JHtml::_('stylesheet', 'boldtext.css', array('version' => 'auto', 'relative' => true)); +} + +// Load specific language related CSS +JHtml::_('stylesheet', 'administrator/language/' . $lang->getTag() . '/' . $lang->getTag() . '.css', array('version' => 'auto')); + +// Load custom.css +JHtml::_('stylesheet', 'custom.css', array('version' => 'auto', 'relative' => true)); + +// IE specific +JHtml::_('stylesheet', 'ie8.css', array('version' => 'auto', 'relative' => true, 'conditional' => 'IE 8')); +JHtml::_('stylesheet', 'ie7.css', array('version' => 'auto', 'relative' => true, 'conditional' => 'IE 7')); + +// Logo file +if ($this->params->get('logoFile')) +{ + $logo = JUri::root() . $this->params->get('logoFile'); +} +else +{ + $logo = $this->baseurl . '/templates/' . $this->template . '/images/logo.png'; +} + +$this->addScriptDeclaration(" + (function($){ + $(document).ready(function () { + // Patches to fix some wrong render of chosen fields + $('.chzn-container, .chzn-drop, .chzn-choices .search-field input').each(function (index) { + $(this).css({ + 'width': 'auto' + }); + }); + }); + })(jQuery); +"); +?> + + + + + + + +
        + + + + + +
        + +
        + +
        + + + + + +
        + input->getInt('hidemainmenu')) : ?> +

        + + + +
        + +
        + +
        + +
        +
        + +
        +
        +

        + + +
        +
        + +
        +
        +
        +
        + + + + diff --git a/Sites/pages/administrator/templates/hathor/js/template.js b/Sites/pages/administrator/templates/hathor/js/template.js new file mode 100644 index 00000000..b6c366e8 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/js/template.js @@ -0,0 +1,124 @@ +/** + * @package Hathor + * @copyright Copyright (C) 2005 - 2020 Open Source Matters, Inc. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +/** + * Functions + */ + +/** + * Change the skip nav target to work with webkit browsers (Safari/Chrome) and + * Opera + */ +function setSkip() { + var $ = jQuery.noConflict(); + var browser = $.browser; + if (browser.chrome || browser.safari || browser.opera) { + var $target = $('#skiptarget'); + $target.attr('href',"#skiptarget"); + $target.text("Start of main content"); + $target.attr("tabindex", "0"); + $('#skiplink').on("click", function(){ + $('#skiptarget').focus(); + }); + } +} + +/** + * Set the Aria Role based on the id + * + * @param id + * @param rolevalue + * @return + */ +function setRoleAttribute(id, rolevalue) { + if (jQuery('#' + id).length) { + jQuery('#'+ id).attr("role", rolevalue); + } +} + +/** + * Set the WAI-ARIA Roles Specify the html id then aria role + * + * @return + */ +function setAriaRoleElementsById() { + setRoleAttribute("header", "banner"); + setRoleAttribute("element-box", "main"); + setRoleAttribute("footer", "contentinfo"); + setRoleAttribute("nav", "navigation"); + setRoleAttribute("submenu", "navigation"); + setRoleAttribute("system-message", "alert"); +} + +/** + * This sets the given Aria Property state to true for the given element + * + * @param el + * The element (tag.class) + * @param prop + * The property to set to true + * @return + */ +function setPropertyAttribute(el, prop) { + if (jQuery(el).length) { + jQuery(el).attr(prop, "true"); + } +} + +/** + * Set the WAI-ARIA Properties Specify the tag.class then the aria property to + * set to true If classes are changed on the fly (i.e. aria-invalid) they need + * to be changed there instead of here. + * + * @return + */ +function setAriaProperties() { + setPropertyAttribute("input.required", "aria-required"); + setPropertyAttribute("textarea.required", "aria-required"); + setPropertyAttribute("input.readonly", "aria-readonly"); + setPropertyAttribute("input.invalid", "aria-invalid"); + setPropertyAttribute("textarea.invalid", "aria-invalid"); +} + + +/** + * Process file + */ + +/** from accessible suckerfish menu by Matt Carroll, + * mootooled by Bill Tomczak + */ + +jQuery(function($){ + var $menu = $('#menu'); + if ($menu.length && !$menu.hasClass('disabled')) { + $menu.find('li').each(function(){ + $(this).on('mouseenter', function(){ + $(this).addClass('sfhover'); + }); + $(this).on('mouseleave', function() { + $(this).removeClass('sfhover'); + }); + }); + + $menu.find('a').each(function() { + $(this).on('focus', function() { + $(this).addClass('sffocus'); + $(this).closest('li').addClass('sfhover'); + }); + $(this).on('blur', function() { + $(this).removeClass('sffocus'); + $(this).closest('li').removeClass('sfhover'); + }); + }); + } +}); + +jQuery(function() { + setSkip(); + setAriaRoleElementsById(); + setAriaProperties(); +}); \ No newline at end of file diff --git a/Sites/pages/administrator/templates/hathor/language/en-GB/en-GB.tpl_hathor.ini b/Sites/pages/administrator/templates/hathor/language/en-GB/en-GB.tpl_hathor.ini new file mode 100644 index 00000000..d3dfa155 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/language/en-GB/en-GB.tpl_hathor.ini @@ -0,0 +1,29 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +HATHOR="Hathor Administrator template" +TPL_HATHOR_ALTERNATE_MENU_DESC="Use the alternative menu which integrates mouse and keyboard. JavaScript Required. The regular menu for Hathor is accessible with or without Javascript, but leaves the mouse and keyboard independent." +TPL_HATHOR_ALTERNATE_MENU_LABEL="Alternative Menu" +TPL_HATHOR_BOLD_TEXT_DESC="Use bold text." +TPL_HATHOR_BOLD_TEXT_LABEL="Bold Text" +TPL_HATHOR_CHECKMARK_ALL="Checkmark All" +TPL_HATHOR_COLOUR_CHOICE_BLUE="Blue" +TPL_HATHOR_COLOUR_CHOICE_DESC="Select the colour palette to use with the template. You can use this option to select a high contrast version or use it to create custom branding." +TPL_HATHOR_COLOUR_CHOICE_LABEL="Select Colour" +TPL_HATHOR_COLOUR_CHOICE_STANDARD="Standard" +TPL_HATHOR_COLOUR_CHOICE_HIGH_CONTRAST="High Contrast" +TPL_HATHOR_COLOUR_CHOICE_BROWN="Brown" +TPL_HATHOR_COM_MENUS_MENU="Menu" +TPL_HATHOR_COM_MODULES_CUSTOM_POSITION_LABEL="Select" +TPL_HATHOR_CPANEL_LINK_TEXT="Return to Control Panel" +TPL_HATHOR_GO="Go" +TPL_HATHOR_LOGO_DESC="Select or upload a custom logo for the administrator template." +TPL_HATHOR_LOGO_LABEL="Logo" +TPL_HATHOR_MAIN_MENU="Main Menu" +TPL_HATHOR_SHOW_SITE_NAME_DESC="Show the site name in the template header." +TPL_HATHOR_SHOW_SITE_NAME_LABEL="Show Site Name" +TPL_HATHOR_SKIP_TO_MAIN_CONTENT="Skip to Main Content" +TPL_HATHOR_SUB_MENU="Sub Menu" +TPL_HATHOR_XML_DESCRIPTION="Hathor is an accessible Administrator template for Joomla! The Colour CSS files can also be used for custom colour branding." diff --git a/Sites/pages/administrator/templates/hathor/language/en-GB/en-GB.tpl_hathor.sys.ini b/Sites/pages/administrator/templates/hathor/language/en-GB/en-GB.tpl_hathor.sys.ini new file mode 100644 index 00000000..b8b32fcc --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/language/en-GB/en-GB.tpl_hathor.sys.ini @@ -0,0 +1,19 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +HATHOR="Hathor Administrator template" +TPL_HATHOR_POSITION_CP_SHELL="Unused" +TPL_HATHOR_POSITION_CPANEL="Control Panel" +TPL_HATHOR_POSITION_DEBUG="Debug" +TPL_HATHOR_POSITION_FOOTER="Footer" +TPL_HATHOR_POSITION_ICON="Quick Icons" +TPL_HATHOR_POSITION_LOGIN="Login" +TPL_HATHOR_POSITION_MENU="Menu" +TPL_HATHOR_POSITION_POSTINSTALL="Postinstall" +TPL_HATHOR_POSITION_STATUS="Status" +TPL_HATHOR_POSITION_SUBMENU="Submenu" +TPL_HATHOR_POSITION_TITLE="Title" +TPL_HATHOR_POSITION_TOOLBAR="Toolbar" +TPL_HATHOR_XML_DESCRIPTION="Hathor is an accessible Administrator template for Joomla! The Colour CSS files can also be used for custom colour branding." diff --git a/Sites/pages/administrator/templates/hathor/less/buttons.less b/Sites/pages/administrator/templates/hathor/less/buttons.less new file mode 100644 index 00000000..550f8053 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/less/buttons.less @@ -0,0 +1,82 @@ +// +// Buttons +// This is a custom version of Bootstrap's buttons.less file suited for Hathor's needs +// -------------------------------------------------- + + +// Base styles +// -------------------------------------------------- + +// Core +#form-login .btn { + display: inline-block; + .ie7-inline-block(); + padding: 4px 14px; + margin-bottom: 0; // For input.btn + font-size: @baseFontSize; + line-height: @baseLineHeight; + *line-height: @baseLineHeight; + text-align: center; + vertical-align: middle; + cursor: pointer; + .buttonBackground(@btnBackground, @btnBackgroundHighlight, @grayDark, 0 1px 1px rgba(255,255,255,.75)); + border: 1px solid @btnBorder; + *border: 0; // Remove the border to prevent IE7's black border on input:focus + border-bottom-color: darken(@btnBorder, 10%); + .border-radius(4px); + .ie7-restore-left-whitespace(); // Give IE7 some love + .box-shadow(~"inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05)"); + + // Hover state + &:hover { + color: @grayDark; + text-decoration: none; + background-color: darken(@white, 10%); + *background-color: darken(@white, 15%); /* Buttons in IE7 don't get borders, so darken on hover */ + background-position: 0 -15px; + + // transition is only when going to hover, otherwise the background + // behind the gradient (there for IE<=9 fallback) gets mismatched + .transition(background-position .1s linear); + } + + // Focus state for keyboard and accessibility + &:focus { + .tab-focus(); + } + + // Active state + &.active, + &:active { + background-color: darken(@white, 10%); + background-color: darken(@white, 15%) e("\9"); + background-image: none; + outline: 0; + .box-shadow(~"inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05)"); + } + + // Disabled state + &.disabled, + &[disabled] { + cursor: default; + background-color: darken(@white, 10%); + background-image: none; + .opacity(65); + .box-shadow(none); + } + +} + +// Button Sizes +// -------------------------------------------------- + +// Large +.btn-large { + padding: 9px 14px; + font-size: @baseFontSize + 2px; + line-height: normal; + .border-radius(5px); +} +.btn-large [class^="icon-"] { + margin-top: 2px; +} diff --git a/Sites/pages/administrator/templates/hathor/less/colour_baseline.less b/Sites/pages/administrator/templates/hathor/less/colour_baseline.less new file mode 100644 index 00000000..530da155 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/less/colour_baseline.less @@ -0,0 +1,1779 @@ +// colour_baseline.less +// +// Baseline CSS for the Hathor colours. +// Compilers should include this in their colour's imports, but not directly +// compile using this file. +// ----------------------------------------------------- + +// Core variables and mixins +@import "../../../../media/jui/less/mixins.less"; + +// Bootstrap Buttons +// Using override for Hathor to target specific instances only +@import "buttons.less"; + +// Bootstrap Forms +// Using override for Hathor since we're not pulling in all Bootstrap form styles +@import "forms.less"; + +// Bootstrap Labels and Badges +@import "../../../../media/jui/less/labels-badges.less"; + +/* + * General styles + */ +body { + background-color: @bodyBackground; + color: @textColor; +} + +h1 { + color: @textColor; +} + +a:link { + color: @linkColor; +} + +a:visited { + color: @linkColor; +} + +/* + * Overall Styles + */ +#header { + background: @bodyBackground url(../images/j_logo.png) no-repeat; +} + +#header h1.title { + color: @textColor; +} + +#nav { + #gradient > .vertical(@gradientTop, @gradientBottom); + border: 1px solid @mainBorder; +} + +#content { + background: @bodyBackground; +} + +#no-submenu { + border-bottom: 1px solid @mainBorder; +} + +#element-box { + background: @bodyBackground; + border-right: 1px solid @mainBorder; + border-bottom: 1px solid @mainBorder; + border-left: 1px solid @mainBorder; +} + +#element-box.login { + border-top: 1px solid @mainBorder; +} + +/* + * Various Styles + */ +.enabled, +.success, +.allow, +span.writable { + color: @successText; +} + +.disabled, +p.error, +.warning, +.deny, +span.unwritable { + color: @errorText; +} + +.nowarning { + color: @textColor; +} + +.none, +.protected { + color: @mainBorder; +} + +span.note { + background: @bodyBackground; + color: @textColor; +} + +div.checkin-tick { + background: url(../images/admin/tick.png) 20px 50% no-repeat; +} + +/* + * Overlib + */ +.ol-foreground { + background-color: @altBackground; +} + +.ol-background { + background-color: @successText; +} + +.ol-textfont { + color: @textColor; +} + +.ol-captionfont { + color: @bodyBackground; +} + +.ol-captionfont a { + color: @linkColor; +} + +/* + * Subheader, toolbar, page title + */ +div.subheader .padding { + background: @bodyBackground; +} + +.pagetitle h2 { + color: @textColor; +} + +div.configuration { + color: @textColor; + background-image: url(../images/menu/icon-16-config.png); + background-repeat: no-repeat; +} + +div.toolbar-box { + border-right: 1px solid @mainBorder; + border-bottom: 1px solid @mainBorder; + border-left: 1px solid @mainBorder; + background: @bodyBackground; +} + +div.toolbar-list li { + color: @textColor; +} + +div.toolbar-list li.divider { + border-right: 1px dotted @hoverBackground; +} + +div.toolbar-list a { + border-left: 1px solid @hoverBackground; + border-top: 1px solid @hoverBackground; + border-right: 1px solid @mainBorder; + border-bottom: 1px solid @mainBorder; + background: @altBackground; +} + +div.toolbar-list a:hover { + border-left: 1px solid @nwBorder; + border-top: 1px solid @nwBorder; + border-right: 1px solid @seBorder; + border-bottom: 1px solid @seBorder; + background: @hoverBackground; + color: @toolbarColor; +} + +div.btn-toolbar { + margin-left: 5px; + padding-top: 3px; +} + +div.btn-toolbar li.divider { + border-right: 1px dotted @hoverBackground; +} + +div.btn-toolbar div.btn-group button { + border-left: 1px solid @hoverBackground; + border-top: 1px solid @hoverBackground; + border-right: 1px solid @mainBorder; + border-bottom: 1px solid @mainBorder; + #gradient > .vertical(@gradientTop, @gradientBottom); + padding: 5px 4px 5px 4px; +} + +div.btn-toolbar div.btn-group button:hover { + border-left: 1px solid @nwBorder; + border-top: 1px solid @nwBorder; + border-right: 1px solid @seBorder; + border-bottom: 1px solid @seBorder; + background: @hoverBackground; + color: @toolbarColor; + cursor: pointer; +} + +div.btn-toolbar a { + border-left: 1px solid @hoverBackground; + border-top: 1px solid @hoverBackground; + border-right: 1px solid @mainBorder; + border-bottom: 1px solid @mainBorder; + #gradient > .vertical(@gradientTop, @gradientBottom); + padding: 6px 5px; + text-align: center; + white-space: nowrap; + font-size: 1.2em; + text-decoration: none; +} + +div.btn-toolbar a:hover { + border-left: 1px solid @nwBorder; + border-top: 1px solid @nwBorder; + border-right: 1px solid @seBorder; + border-bottom: 1px solid @seBorder; + background: @hoverBackground; + color: @toolbarColor; + cursor: pointer; +} + +div.btn-toolbar div.btn-group button.inactive { + background: @altBackground; +} + +/* + * Pane Slider pane Toggler styles + */ +.pane-sliders .title { + color: @textColor; +} + +.pane-sliders .panel { + border: 1px solid @mainBorder; +} + +.pane-sliders .panel h3 { + #gradient > .vertical(@gradientTop, @gradientBottom); + color: @linkColor; +} + +.pane-sliders .panel h3:hover { + background: @hoverBackground; +} + +.pane-sliders .panel h3:hover a { + text-decoration: none; +} + +.pane-sliders .adminlist { + border: 0 none; +} + +.pane-sliders .adminlist td { + border: 0 none; +} + +.pane-toggler span { + background: transparent url(../images/j_arrow.png) 5px 50% no-repeat; +} + +.pane-toggler-down span { + background: transparent url(../images/j_arrow_down.png) 5px 50% no-repeat; +} + +.pane-toggler-down { + border-bottom: 1px solid @mainBorder; +} + +/* + * Tabs + */ +dl.tabs dt { + border: 1px solid @mainBorder; + #gradient > .vertical(@gradientTop, @gradientBottom); + color: @linkColor; +} + +dl.tabs dt:hover { + background: @hoverBackground; +} + +dl.tabs dt.open { + background: @bodyBackground; + border-bottom: 1px solid @bodyBackground; + color: @textColor; +} + +dl.tabs dt.open a:visited { + color: @textColor; +} + +dl.tabs dt a:hover { + text-decoration: none; +} + +dl.tabs dt a:focus { + text-decoration: underline; +} + +div.current { + border: 1px solid @mainBorder; + background: @bodyBackground; +} + +/* + * New parameter styles + */ +div.current fieldset { + border: none 0; +} + +div.current fieldset.adminform { + border: 1px solid @mainBorder; +} + +/* + * Login Settings + */ +#login-page .pagetitle h2 { + background: transparent; +} + +#login-page #header { + border-bottom: 1px solid @mainBorder; +} + +#login-page #lock { + background: url(../images/j_login_lock.png) 50% 0 no-repeat; +} + +#login-page #element-box.login { + #gradient > .vertical(@gradientTop, @gradientBottom); +} + +#form-login { + background: @bodyBackground; + border: 1px solid @mainBorder; +} + +#form-login label { + color: @textColor; +} + +#form-login div.button1 a { + color: @linkColor; +} + +/* + * Cpanel Settings + */ +#cpanel div.icon a, .cpanel div.icon a { + color: @linkColor; + border-left: 1px solid @hoverBackground; + border-top: 1px solid @hoverBackground; + border-right: 1px solid @mainBorder; + border-bottom: 1px solid @mainBorder; + #gradient > .vertical(@gradientTop, @gradientBottom); +} + +#cpanel div.icon a:hover, +#cpanel div.icon a:focus, +.cpanel div.icon a:hover, +.cpanel div.icon a:focus { + border-left: 1px solid @nwBorder; + border-top: 1px solid @nwBorder; + border-right: 1px solid @seBorder; + border-bottom: 1px solid @seBorder; + color: @linkColor; + background: @hoverBackground; +} + +/* + * Form Styles + */ +fieldset { + border: 1px @mainBorder solid; +} + +legend { + color: @textColor; +} + +fieldset ul.checklist input:focus { + outline: thin dotted @textColor; +} + +fieldset#filter-bar { + border-top: 0 solid @mainBorder; + border-right: 0 solid @mainBorder; + border-bottom: 1px solid @mainBorder; + border-left: 0 solid @mainBorder; +} + +fieldset#filter-bar ol, fieldset#filter-bar ul { + border: 0; +} + +fieldset#filter-bar ol li fieldset, fieldset#filter-bar ul li fieldset { + border: 0; +} + +/* Note: these visual cues should be augmented by aria */ +.invalid { + color: @errorText; +} + +/* must be augmented by aria at the same time if changed dynamically by js +aria-invalid=true or aria-invalid=false */ +input.invalid { + border: 1px solid @errorText; +} + +/* augmented by aria in template javascript */ +input.readonly, span.faux-input { + border: 0; +} + +input.required { + background-color: @inputBackground; +} + +input.disabled { + background-color: @disabledBackground; +} + +input, select, span.faux-input { + background-color: @bodyBackground; + border: 1px solid @mainBorder; +} + +/* Inputs used as buttons */ +input[type="button"], input[type="submit"], input[type="reset"] { + color: @linkColor; + #gradient > .vertical(@gradientTop, @gradientBottom); +} + +input[type="button"]:hover, input[type="button"]:focus, +input[type="submit"]:hover, input[type="submit"]:focus, +input[type="reset"]:hover, input[type="reset"]:focus { + background: @hoverBackground; +} + +textarea { + background-color: @bodyBackground; + border: 1px solid @mainBorder; +} + +input:focus, select:focus, textarea:focus, option:focus, +input:hover, select:hover, textarea:hover, option:hover { + background-color: @hoverBackground; + color: @linkColor; +} + +/* + * Option or Parameter styles + */ +.paramrules { + background: @altBackground; +} + +span.gi { + color: @mainBorder; +} + +/* + * Admintable Styles + */ +table.admintable td.key, table.admintable td.paramlist_key { + background-color: @altBackground; + color: @textColor; + border-bottom: 1px solid @mainBorder; + border-right: 1px solid @mainBorder; +} + +table.paramlist td.paramlist_description { + background-color: @altBackground; + color: @textColor; + border-bottom: 1px solid @mainBorder; + border-right: 1px solid @mainBorder; +} + +/* + * Admin Form Styles + */ +fieldset.adminform { + border: 1px solid @mainBorder; +} + +/* + * Table styles are for use with tabular data + */ +table.adminform { + background-color: @bodyBackground; +} + +table.adminform tr.row0 { + background-color: @bodyBackground; +} + +table.adminform tr.row1 { + background-color: @hoverBackground; +} + +table.adminform th { + color: @textColor; + background: @bodyBackground; +} + +table.adminform tr { + border-bottom: 1px solid @mainBorder; + border-right: 1px solid @mainBorder; +} + +/* + * Adminlist Table layout + */ +table.adminlist { + border-spacing: 1px; + background-color: @bodyBackground; + color: @textColor; +} + +table.adminlist.modal { + border-top: 1px solid @mainBorder; + border-right: 1px solid @mainBorder; + border-left: 1px solid @mainBorder; +} + +table.adminlist a { + color: @linkColor; +} + +table.adminlist thead th { + background: @bodyBackground; + color: @textColor; + border-bottom: 1px solid @mainBorder; +} + +/* + * Table row styles + */ +table.adminlist tbody tr { + background: @bodyBackground; +} + +table.adminlist tbody tr.row1 { + background: @bodyBackground; +} + +table.adminlist tbody tr.row1:last-child td, +table.adminlist tbody tr.row1:last-child th { + border-bottom: 1px solid @mainBorder; +} + +table.adminlist tbody tr.row0:hover td, +table.adminlist tbody tr.row1:hover td, +table.adminlist tbody tr.row0:hover th, +table.adminlist tbody tr.row1:hover th, +table.adminlist tbody tr.row0:focus td, +table.adminlist tbody tr.row1:focus td, +table.adminlist tbody tr.row0:focus th, +table.adminlist tbody tr.row1:focus th { + background-color: @hoverBackground; +} + +table.adminlist tbody tr td, +table.adminlist tbody tr th { + border-right: 1px solid @mainBorder; +} + +table.adminlist tbody tr td:last-child { + border-right: none; +} + +table.adminlist tbody tr.row0:last-child td, +table.adminlist tbody tr.row0:last-child th { + border-bottom: 1px solid @mainBorder; +} + +table.adminlist tbody tr.row0 td, +table.adminlist tbody tr.row0 th { + #gradient > .vertical(@gradientTop, @gradientBottom); +} + +table.adminlist { + border-bottom: 0 solid @mainBorder; +} + +table.adminlist tfoot tr { + color: @textColor; +} + +/* + * Table td/th styles + */ +table.adminlist tfoot td, +table.adminlist tfoot th { + background-color: @bodyBackground; + border-top: 1px solid @mainBorder; +} + +/* + * Adminlist buttons + */ +table.adminlist tr td.btns a { + border: 1px solid @mainBorder; + #gradient > .vertical(@gradientTop, @gradientBottom); + color: @linkColor; +} + +table.adminlist tr td.btns a:hover, +table.adminlist tr td.btns a:active, +table.adminlist tr td.btns a:focus { + background-color: @bodyBackground; +} + +/* + * Saving order icon styling in admin tables + */ +a.saveorder { + background: url(../images/admin/filesave.png) no-repeat; +} + +a.saveorder.inactive { + background-position: 0 -16px; +} + +/* + * Saving order icon styling in admin tables + */ +fieldset.batch { + background: @bodyBackground; +} + +/** + * Button styling + */ +button { + color: @toolbarColor; + border: 1px solid @mainBorder; + #gradient > .vertical(@gradientTop, @gradientBottom); +} + +button:hover, +button:focus { + background: @hoverBackground; +} + +.invalid { + color: #ff0000; +} + +/* Button 1 Type */ +.button1 { + border: 1px solid @mainBorder; + color: @linkColor; + #gradient > .vertical(@gradientTop, @gradientBottom); +} + +/* Use this if you add images to the buttons such as directional arrows */ +.button1 a { + color: @linkColor; +/* add padding if you are using the directional images */ +/* padding: 0 30px 0 6px; */ +} + +.button1 a:hover, +.button1 a:focus { + background: @hoverBackground; +} + +/* Button 2 Type */ +.button2-left, +.button2-right { + border: 1px solid @mainBorder; + #gradient > .vertical(@gradientTop, @gradientBottom); +} + +.button2-left a, +.button2-right a, +.button2-left span, +.button2-right span { + color: @linkColor; +} + +/* these are inactive buttons */ +.button2-left span, +.button2-right span { + color: #999999; +} + +.page span, +.blank span { + color: @linkColor; +} + +.button2-left a:hover, +.button2-right a:hover, +.button2-left a:focus, +.button2-right a:focus { + background: @hoverBackground; +} + +/** + * Pagination styles + */ + +/* Grey out the current page number */ +.pagination .page span { + color: #999999; +} + +/** + * Tooltips + */ +.tip { + background: #000000; + border: 1px solid #FFFFFF; +} + +.tip-title { + background: url(../images/selector-arrow-std.png) no-repeat; +} + +/** + * Calendar + */ +a img.calendar { + background: url(../images/calendar.png) no-repeat; +} + +/** + * JGrid styles + */ +.jgrid span.publish { + background-image: url(../images/admin/tick.png); +} + +.jgrid span.unpublish { + background-image: url(../images/admin/publish_x.png); +} + +.jgrid span.archive { + background-image: url(../images/menu/icon-16-archive.png); +} + +.jgrid span.trash { + background-image: url(../images/menu/icon-16-trash.png); +} + +.jgrid span.default { + background-image: url(../images/menu/icon-16-default.png); +} + +.jgrid span.notdefault { + background-image: url(../images/menu/icon-16-notdefault.png); +} + +.jgrid span.checkedout { + background-image: url(../images/admin/checked_out.png); +} + +.jgrid span.downarrow { + background-image: url(../images/admin/downarrow.png); +} + +.jgrid span.downarrow_disabled { + background-image: url(../images/admin/downarrow0.png); +} + +.jgrid span.uparrow { + background-image: url(../images/admin/uparrow.png); +} + +.jgrid span.uparrow_disabled { + background-image: url(../images/admin/uparrow0.png); +} + +.jgrid span.published { + background-image: url(../images/admin/publish_g.png); +} + +.jgrid span.expired { + background-image: url(../images/admin/publish_r.png); +} + +.jgrid span.pending { + background-image: url(../images/admin/publish_y.png); +} + +.jgrid span.warning { + background-image: url(../images/admin/publish_y.png); +} + +/** + * Toolbar icons + * These icons are used for the toolbar buttons + * The classes are constructed dynamically when the toolbar is created + */ +.icon-32-send { + background-image: url(../images/toolbar/icon-32-send.png); +} + +.icon-32-delete { + background-image: url(../images/toolbar/icon-32-delete.png); +} + +.icon-32-help { + background-image: url(../images/toolbar/icon-32-help.png); +} + +.icon-32-cancel { + background-image: url(../images/toolbar/icon-32-cancel.png); +} + +.icon-32-checkin { + background-image: url(../images/toolbar/icon-32-checkin.png); +} + +.icon-32-options { + background-image: url(../images/toolbar/icon-32-config.png); +} + +.icon-32-apply { + background-image: url(../images/toolbar/icon-32-apply.png); +} + +.icon-32-back { + background-image: url(../images/toolbar/icon-32-back.png); +} + +.icon-32-forward { + background-image: url(../images/toolbar/icon-32-forward.png); +} + +.icon-32-save { + background-image: url(../images/toolbar/icon-32-save.png); +} + +.icon-32-edit { + background-image: url(../images/toolbar/icon-32-edit.png); +} + +.icon-32-copy { + background-image: url(../images/toolbar/icon-32-copy.png); +} + +.icon-32-move { + background-image: url(../images/toolbar/icon-32-move.png); +} + +.icon-32-new { + background-image: url(../images/toolbar/icon-32-new.png); +} + +.icon-32-upload { + background-image: url(../images/toolbar/icon-32-upload.png); +} + +.icon-32-assign { + background-image: url(../images/toolbar/icon-32-publish.png); +} + +.icon-32-html { + background-image: url(../images/toolbar/icon-32-html.png); +} + +.icon-32-css { + background-image: url(../images/toolbar/icon-32-css.png); +} + +.icon-32-menus { + background-image: url(../images/toolbar/icon-32-menu.png); +} + +.icon-32-publish { + background-image: url(../images/toolbar/icon-32-publish.png); +} + +.icon-32-unblock { + background-image: url(../images/toolbar/icon-32-unblock.png); +} + +.icon-32-unpublish { + background-image: url(../images/toolbar/icon-32-unpublish.png); +} + +.icon-32-restore { + background-image: url(../images/toolbar/icon-32-revert.png); +} + +.icon-32-trash { + background-image: url(../images/toolbar/icon-32-trash.png); +} + +.icon-32-archive { + background-image: url(../images/toolbar/icon-32-archive.png); +} + +.icon-32-unarchive { + background-image: url(../images/toolbar/icon-32-unarchive.png); +} + +.icon-32-preview { + background-image: url(../images/toolbar/icon-32-preview.png); +} + +.icon-32-default { + background-image: url(../images/toolbar/icon-32-default.png); +} + +.icon-32-refresh { + background-image: url(../images/toolbar/icon-32-refresh.png); +} + +.icon-32-save-new { + background-image: url(../images/toolbar/icon-32-save-new.png); +} + +.icon-32-save-copy { + background-image: url(../images/toolbar/icon-32-save-copy.png); +} + +.icon-32-error { + background-image: url(../images/toolbar/icon-32-error.png); +} + +.icon-32-new-style { + background-image: url(../images/toolbar/icon-32-new-style.png); +} + +.icon-32-delete-style { + background-image: url(../images/toolbar/icon-32-delete-style.png); +} + +.icon-32-purge { + background-image: url(../images/toolbar/icon-32-purge.png); +} + +.icon-32-remove { + background-image: url(../images/toolbar/icon-32-remove.png); +} + +.icon-32-featured { + background-image: url(../images/toolbar/icon-32-featured.png); +} + +.icon-32-unfeatured { + background-image: url(../images/toolbar/icon-32-featured.png); + background-position: 0% 100%; +} + +.icon-32-export { + background-image: url(../images/toolbar/icon-32-export.png); +} + +.icon-32-stats { + background-image: url(../images/toolbar/icon-32-stats.png); +} + +.icon-32-print { + background-image: url(../images/toolbar/icon-32-print.png); +} + +.icon-32-batch { + background-image: url(../images/toolbar/icon-32-batch.png); +} + +.icon-32-envelope { + background-image: url(../images/toolbar/icon-32-messaging.png); +} + +.icon-32-download { + background-image: url(../images/toolbar/icon-32-export.png); +} + +.icon-32-bars { + background-image: url(../images/toolbar/icon-32-stats.png); +} + +/** + * Quick Icons + * Also knows as Header Icons + * These are used for the Quick Icons on the Control Panel + * The same classes are also assigned the Component Title + */ +.icon-48-categories { + background-image: url(../images/header/icon-48-category.png); +} + +.icon-48-category-edit { + background-image: url(../images/header/icon-48-category.png); +} + +.icon-48-category-add { + background-image: url(../images/header/icon-48-category-add.png); +} + +.icon-48-generic { + background-image: url(../images/header/icon-48-generic.png); +} + +.icon-48-banners { + background-image: url(../images/header/icon-48-banner.png); +} + +.icon-48-banners-categories { + background-image: url(../images/header/icon-48-banner-categories.png); +} + +.icon-48-banners-category-edit { + background-image: url(../images/header/icon-48-banner-categories.png); +} + +.icon-48-banners-category-add { + background-image: url(../images/header/icon-48-category-add.png); +} + +.icon-48-banners-clients { + background-image: url(../images/header/icon-48-banner-client.png); +} + +.icon-48-banners-tracks { + background-image: url(../images/header/icon-48-banner-tracks.png); +} + +.icon-48-checkin { + background-image: url(../images/header/icon-48-checkin.png); +} + +.icon-48-clear { + background-image: url(../images/header/icon-48-clear.png); +} + +.icon-48-contact { + background-image: url(../images/header/icon-48-contacts.png); +} + +.icon-48-contact-categories { + background-image: url(../images/header/icon-48-contacts-categories.png); +} + +.icon-48-contact-category-edit { + background-image: url(../images/header/icon-48-contacts-categories.png); +} + +.icon-48-contact-category-add { + background-image: url(../images/header/icon-48-category-add.png); +} + +.icon-48-purge { + background-image: url(../images/header/icon-48-purge.png); +} + +.icon-48-cpanel { + background-image: url(../images/header/icon-48-cpanel.png); +} + +.icon-48-config { + background-image: url(../images/header/icon-48-config.png); +} + +.icon-48-groups { + background-image: url(../images/header/icon-48-groups.png); +} + +.icon-48-groups-add { + background-image: url(../images/header/icon-48-groups-add.png); +} + +.icon-48-levels { + background-image: url(../images/header/icon-48-levels.png); +} + +.icon-48-levels-add { + background-image: url(../images/header/icon-48-levels-add.png); +} + +.icon-48-module { + background-image: url(../images/header/icon-48-module.png); +} + +.icon-48-menu { + background-image: url(../images/header/icon-48-menu.png); +} + +.icon-48-menu-add { + background-image: url(../images/header/icon-48-menu-add.png); +} + +.icon-48-menumgr { + background-image: url(../images/header/icon-48-menumgr.png); +} + +.icon-48-trash { + background-image: url(../images/header/icon-48-trash.png); +} + +.icon-48-user { + background-image: url(../images/header/icon-48-user.png); +} + +.icon-48-user-add { + background-image: url(../images/header/icon-48-user-add.png); +} + +.icon-48-user-edit { + background-image: url(../images/header/icon-48-user-edit.png); +} + +.icon-48-user-profile { + background-image: url(../images/header/icon-48-user-profile.png); +} + +.icon-48-inbox { + background-image: url(../images/header/icon-48-inbox.png); +} + +.icon-48-new-privatemessage { + background-image: url(../images/header/icon-48-new-privatemessage.png); +} + +.icon-48-msgconfig { + background-image: url(../images/header/icon-48-message_config.png); +} + +.icon-48-langmanager { + background-image: url(../images/header/icon-48-language.png); +} + +.icon-48-mediamanager { + background-image: url(../images/header/icon-48-media.png); +} + +.icon-48-plugin { + background-image: url(../images/header/icon-48-plugin.png); +} + +.icon-48-help_header { + background-image: url(../images/header/icon-48-help_header.png); +} + +.icon-48-impressions { + background-image: url(../images/header/icon-48-stats.png); +} + +.icon-48-browser { + background-image: url(../images/header/icon-48-stats.png); +} + +.icon-48-searchtext { + background-image: url(../images/header/icon-48-stats.png); +} + +.icon-48-thememanager { + background-image: url(../images/header/icon-48-themes.png); +} + +.icon-48-writemess { + background-image: url(../images/header/icon-48-writemess.png); +} + +.icon-48-featured { + background-image: url(../images/header/icon-48-featured.png); +} + +.icon-48-sections { + background-image: url(../images/header/icon-48-section.png); +} + +.icon-48-article-add { + background-image: url(../images/header/icon-48-article-add.png); +} + +.icon-48-article-edit { + background-image: url(../images/header/icon-48-article-edit.png); +} + +.icon-48-article { + background-image: url(../images/header/icon-48-article.png); +} + +.icon-48-content-categories { + background-image: url(../images/header/icon-48-category.png); +} + +.icon-48-content-category-edit { + background-image: url(../images/header/icon-48-category.png); +} + +.icon-48-content-category-add { + background-image: url(../images/header/icon-48-category-add.png); +} + +.icon-48-install { + background-image: url(../images/header/icon-48-extension.png); +} + +.icon-48-dbbackup { + background-image: url(../images/header/icon-48-backup.png); +} + +.icon-48-dbrestore { + background-image: url(../images/header/icon-48-dbrestore.png); +} + +.icon-48-dbquery { + background-image: url(../images/header/icon-48-query.png); +} + +.icon-48-systeminfo { + background-image: url(../images/header/icon-48-info.png); +} + +.icon-48-massmail { + background-image: url(../images/header/icon-48-massmail.png); +} + +.icon-48-redirect { + background-image: url(../images/header/icon-48-redirect.png); +} + +.icon-48-search { + background-image: url(../images/header/icon-48-search.png); +} + +.icon-48-finder { + background-image: url(../images/header/icon-48-search.png); +} + +.icon-48-newsfeeds { + background-image: url(../images/header/icon-48-newsfeeds.png); +} + +.icon-48-newsfeeds-categories { + background-image: url(../images/header/icon-48-newsfeeds-cat.png); +} + +.icon-48-newsfeeds-category-edit { + background-image: url(../images/header/icon-48-newsfeeds-cat.png); +} + +.icon-48-newsfeeds-category-add { + background-image: url(../images/header/icon-48-category-add.png); +} + +.icon-48-weblinks { + background-image: url(../images/header/icon-48-links.png); +} + +.icon-48-weblinks-categories { + background-image: url(../images/header/icon-48-links-cat.png); +} + +.icon-48-weblinks-category-edit { + background-image: url(../images/header/icon-48-links-cat.png); +} + +.icon-48-weblinks-category-add { + background-image: url(../images/header/icon-48-category-add.png); +} + +.icon-48-tags { + background-image: url(../images/header/icon-48-tags.png); +} + +.icon-48-assoc { + background-image: url(../images/header/icon-48-assoc.png); +} + +.icon-48-puzzle { + background-image: url(../images/header/icon-48-puzzle.png); +} + +/** + * General styles + */ +div.message { + border: 1px solid @mainBorder; + color: @textColor; +} + +.helpFrame { + border-left: 0 solid @mainBorder; + border-right: none; + border-top: none; + border-bottom: none; +} + +.outline { + border: 1px solid @mainBorder; + background: @bodyBackground; +} + +/** + * Modal Styles + */ +dl.menu_type dt { + border-bottom: 1px solid @mainBorder; +} + +ul#new-modules-list { + border-top: 1px solid @mainBorder; +} + +/** + * User Accessibility + */ + +/* Skip to Content Visual Styling */ +#skiplinkholder a, #skiplinkholder a:link, #skiplinkholder a:visited { + color: @bodyBackground; + background: @linkColor; + border-bottom: solid #336 2px; +} + +/** + * Admin Form Styles + */ +fieldset.panelform { + border: none 0; +} + +/** + * ACL STYLES relocated from com_users/media/grid.css + */ +a.move_up { + background-image: url('../images/admin/uparrow.png'); +} + +span.move_up { + background-image: url('../images/admin/uparrow0.png'); +} + +a.move_down { + background-image: url('../images/admin/downarrow.png'); +} + +span.move_down { + background-image: url('../images/admin/downarrow0.png'); +} + +a.grid_false { + background-image: url('../images/admin/publish_x.png'); +} + +a.grid_true { + background-image: url('../images/admin/tick.png'); +} + +a.grid_trash { + background-image: url('../images/admin/icon-16-trash.png'); +} + +/** + * ACL PANEL STYLES + */ + +/* All Tabs */ + +tr.row1 { + background-color: @altBackground; +} + +/* Summary Tab */ +table.aclsummary-table td.col2, +table.aclsummary-table th.col2, +table.aclsummary-table td.col3, +table.aclsummary-table th.col3, +table.aclsummary-table td.col4, +table.aclsummary-table th.col4, +table.aclsummary-table td.col5, +table.aclsummary-table th.col5, +table.aclsummary-table td.col6, +table.aclsummary-table th.col6, +table.aclmodify-table td.col2, +table.aclmodify-table th.col2 { + border-left: 1px solid @mainBorder; +} + +/* Icons */ + +span.icon-16-unset { + background: url(../images/admin/icon-16-denyinactive.png) no-repeat; +} + +span.icon-16-allowed { + background: url(../images/admin/icon-16-allow.png) no-repeat; +} + +span.icon-16-denied { + background: url(../images/admin/icon-16-deny.png) no-repeat; +} + +span.icon-16-locked { + background: url(../images/admin/checked_out.png) 0 0 no-repeat; +} + +label.icon-16-allow { + background: url(../images/admin/icon-16-allow.png) no-repeat; +} + +label.icon-16-deny { + background: url(../images/admin/icon-16-deny.png) no-repeat; +} + +a.icon-16-allow { + background: url(../images/admin/icon-16-allow.png) no-repeat; +} + +a.icon-16-deny { + background: url(../images/admin/icon-16-deny.png) no-repeat; +} + +a.icon-16-allowinactive { + background: url(../images/admin/icon-16-allowinactive.png) no-repeat; +} + +a.icon-16-denyinactive { + background: url(../images/admin/icon-16-denyinactive.png) no-repeat; +} + +/* ACL footer/legend */ + +ul.acllegend li.acl-allowed { + background: url(../images/admin/icon-16-allow.png) no-repeat left; +} + +ul.acllegend li.acl-denied { + background: url(../images/admin/icon-16-deny.png) no-repeat left; +} + +li.acl-editgroups, +li.acl-resetbtn { + background-color: @altBackground; + border: 1px solid @mainBorder; +} + +li.acl-editgroups a, +li.acl-resetbtn a { + color: @linkColor; +} + +li.acl-editgroups:hover, +li.acl-resetbtn:hover, +li.acl-editgroups:focus, +li.acl-resetbtn:focus { + background-color: @hoverBackground; +} + +/* ACL Config --------- */ +table#acl-config { + border: 1px solid @mainBorder; +} + +table#acl-config th, +table#acl-config td { + background: @altBackground; + border-bottom: 1px solid @mainBorder; +} + +table#acl-config th.acl-groups { + border-right: 1px solid @mainBorder; +} + +/** +* Mod_rewrite Warning +*/ +#jform_sef_rewrite-lbl { + background: url(../images/admin/icon-16-notice-note.png) right top no-repeat; +} + +/** +* Permission Rules +*/ + +#permissions-sliders .tip { + background: @bodyBackground; + border: 1px solid @mainBorder; +} + +#permissions-sliders ul#rules, +#permissions-sliders ul#rules ul { + border: solid 0 @mainBorder; + background: @bodyBackground; +} + +ul#rules li .pane-sliders .panel h3.title { + border: solid 0 @mainBorder; +} + +#permissions-sliders ul#rules .pane-slider { + border: solid 1px @mainBorder; +} + +#permissions-sliders ul#rules li h3 { + border: solid 1px @mainBorder; +} + +#permissions-sliders ul#rules li h3.pane-toggler-down a { + border: solid 0; +} + +#permissions-sliders ul#rules .group-kind { + color: @textColor; +} + +#permissions-sliders ul#rules table.group-rules { + border: solid 1px @mainBorder; +} + +#permissions-sliders ul#rules table.group-rules td { + border-right: solid 1px @mainBorder; + border-bottom: solid 1px @mainBorder; +} + +#permissions-sliders ul#rules table.group-rules th { + background: @hoverBackground; + border-right: solid 1px @mainBorder; + border-bottom: solid 1px @mainBorder; + color: @textColor; +} + +ul#rules table.aclmodify-table { + border: solid 1px @mainBorder; +} + +ul#rules table.group-rules td label { + border: solid 0 @mainBorder; +} + +#permissions-sliders ul#rules .mypanel { + border: solid 0 @mainBorder; +} + +#permissions-sliders ul#rules table.group-rules td { + background: @bodyBackground; +} + +#permissions-sliders span.level { + color: @mainBorder; + background-image: none; +} + +/* + * Debug styles + */ +.check-0, +table.adminlist tbody td.check-0 { + background-color: @permissionDefault; +} + +.check-a, +table.adminlist tbody td.check-a { + background-color: @permissionAllowed; +} + +.check-d, +table.adminlist tbody td.check-d { + background-color: @permissionDenied; +} + +/** + * System Messages + */ + +#system-message dd ul { + color: @textColor; +} + +#system-message dd.error ul { + color: @textColor; +} + +#system-message dd.message ul { + color: @textColor; +} + +#system-message dd.notice ul { + color: @textColor; +} + +/** CSS file for Accessible Admin Menu + * based on Matt Carrolls' son of suckerfish + * with javascript by Bill Tomczak + */ + +/* Note: set up the font-size on the id and used 100% on the elements. + If ul/li/a are different ems, then the shifting back via non-js keyboard + doesn't work properly */ + +/** + * Menu Styling + */ +#menu { +/* this is on the main ul */ + color: @textColor; +} + +#menu ul.dropdown-menu { +/* all lists */ + #gradient > .vertical(@gradientTop, @gradientBottom); + color: @textColor; +} + +#menu ul.dropdown-menu li.dropdown-submenu { + background: url(../images/j_arrow.png) no-repeat right 50%; +} + +#menu ul.dropdown-menu li.divider { + margin-bottom: 0; + border-bottom: 1px dotted @mainBorder; +} + +#menu a { + color: @toolbarColor; + background-repeat: no-repeat; + background-position: left 50%; +} + +#menu li { +/* all list items */ + border-right: 1px solid @mainBorder; + background-color: transparent; +} + +#menu li a:hover, #menu li a:focus { + background-color: @hoverBackground; +} + +#menu li.disabled a:hover, +#menu li.disabled a:focus, +#menu li.disabled a { + color: @mainBorder; + #gradient > .vertical(@gradientTop, @gradientBottom); +} + +#menu li ul { +/* second-level lists */ + border: 1px solid @mainBorder; +} + +#menu li li { +/* second-level row */ + background-color: transparent; +} + +/** + * Styling parents + */ + +/* 1 level - sfhover */ +#menu li.sfhover a { + background-color: @hoverBackground; +} + +/* 2 level - normal */ +#menu li.sfhover li a { + background-color: transparent; +} + +/* 2 level - hover */ +#menu li.sfhover li.sfhover a, #menu li li a:focus { + background-color: @hoverBackground; +} + +/* 3 level - normal */ +#menu li.sfhover li.sfhover li a { + background-color: transparent; +} + +/* 3 level - hover */ +#menu li.sfhover li.sfhover li.sfhover a, #menu li li li a:focus { + background-color: @hoverBackground; +} + +/* bring back the focus elements into view */ +#menu li li a:focus, #menu li li li a:focus { + background-color: @hoverBackground; +} + +#menu li li li a:focus { + background-color: @hoverBackground; +} + +/** + * Submenu styling + */ +#submenu { + border-bottom: 1px solid @mainBorder; +/* border-bottom plus padding-bottom is the technique */ +/* This is the background befind the tabs */ +/*background: @bodyBackground;*/ +} + +#submenu li, #submenu span.nolink { + #gradient > .vertical(@gradientTop, @gradientBottom); + border: 1px solid @mainBorder; + color: @linkColor; +} + +#submenu li:hover, #submenu li:focus { + background: @hoverBackground; +} + +#submenu li.active, #submenu span.nolink.active { + background: @bodyBackground; + border-bottom: 1px solid @bodyBackground; +} + +#submenu li.active a, +#submenu span.nolink.active { + color: #000; +} + +.element-invisible { + margin: 0; + padding: 0; +} + +/* -- Codemirror Editor ----------- */ +div.CodeMirror-wrapping { + border: 1px solid @mainBorder; +} + +/* User Notes */ +table.adminform tr.row0 { + background-color: @bodyBackground; +} + +ul.alternating > li:nth-child(odd) { + background-color: @bodyBackground; +} + +ul.alternating > li:nth-child(even) { + background-color: @altBackground; +} + +ol.alternating > li:nth-child(odd) { + background-color: @bodyBackground; +} + +ol.alternating > li:nth-child(even) { + background-color: @altBackground; +} + +/* Installer Database */ +#installer-database, #installer-discover, #installer-update, #installer-warnings { + border-top: 1px solid @mainBorder; +} + +#installer-database p.warning { + background: transparent url(../images/admin/icon-16-deny.png) center left no-repeat; +} + +#installer-database p.nowarning { + background: transparent url(../images/admin/icon-16-allow.png) center left no-repeat; +} + +/* Override default bootstrap font-size */ +.input-append, +.input-prepend { + font-size: 1.2em; +} diff --git a/Sites/pages/administrator/templates/hathor/less/colour_blue.less b/Sites/pages/administrator/templates/hathor/less/colour_blue.less new file mode 100644 index 00000000..2fca62c9 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/less/colour_blue.less @@ -0,0 +1,38 @@ +// colour_blue.less +// +// Less to compile Hathor in the blue colour scheme +// ----------------------------------------------------- + +/** + * #2c2c2c Text + * #054993 Links + * #ffffff Background, border, text + * #c3d2e5 Background alternate, button/icon/menu background + * #a5bbd4-c3d2e5 Gradient Background + * #e5f0fa Background (input required) + * #e5d9c3 Background Hover, Top/Left icon borders + * #738498 Main borders + * #868778 Top/Left hover borders + * #f6f7db Right/Bottom hover borders + * + * Special Use Colors: + * #a20000 Text Error, border invalid + * #cccccc Text (faded) + * #005800 Text (success) + * #eeeeee Background (input disabled) + * #ffffcf Background permissions debug + * #cfffda Background permissions debug + * #ffcfcf Background permissions debug + */ + +// Import the variables file first to get common variables loaded +@import "hathor_variables.less"; + +// Define variables unique to this colour scheme, as well as override variables already defined in the common file +@altBackground: #c3d2e5; +@gradientTop: #a5bbd4; +@gradientBottom: #c3d2e5; +@mainBorder: #738498; + +// Import the baseline to compile the CSS +@import "colour_baseline.less"; diff --git a/Sites/pages/administrator/templates/hathor/less/colour_brown.less b/Sites/pages/administrator/templates/hathor/less/colour_brown.less new file mode 100644 index 00000000..ffa96656 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/less/colour_brown.less @@ -0,0 +1,42 @@ +// colour_brown.less +// +// Less to compile Hathor in the brown colour scheme +// ----------------------------------------------------- + +/** + * #2c2c2c Text + * #054993 Links + * #ffffff Background, border, text + * #d5c1b2 Background alternate, button/icon/menu background + * #d5c1b2-d5c1b2 Gradient Background + * #e5f0fa Background (input required) + * #e1d3c8 Background Hover, Top/Left icon borders + * #000000 Main borders + * #000000 Top/Left hover borders + * #000000 Right/Bottom hover borders + * + * Special Use Colors: + * #a20000 Text Error, border invalid + * #cccccc Text (faded) + * #005800 Text (success) + * #eeeeee Background (input disabled) + * #ffffcf Background permissions debug + * #cfffda Background permissions debug + * #ffcfcf Background permissions debug + */ + +// Import the variables file first to get common variables loaded +@import "hathor_variables.less"; + +// Define variables unique to this colour scheme, as well as override variables already defined in the common file +@altBackground: #d5c1b2; +@gradientTop: #d5c1b2; +@gradientBottom: #d5c1b2; +@mainBorder: #000000; +@toolbarColor: #054993; +@hoverBackground: #e5d9c3; +@nwBorder: #868778; +@seBorder: #f6f7db; + +// Import the baseline to compile the CSS +@import "colour_baseline.less"; diff --git a/Sites/pages/administrator/templates/hathor/less/colour_standard.less b/Sites/pages/administrator/templates/hathor/less/colour_standard.less new file mode 100644 index 00000000..b7de935b --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/less/colour_standard.less @@ -0,0 +1,38 @@ +// colour_standard.less +// +// Less to compile Hathor in the default colour scheme +// ----------------------------------------------------- + +/** + * Main colors: + * #2c2c2c Text + * #054993 Links + * #ffffff Background, border, text + * #f9fade Background alternate, button/icon/menu background + * #e5f0fa Background (input required) + * #e3e4ca Background Hover, Right/Bottom icon borders + * #c7c8b2 Main borders + * #868778 Top/Left icon hover borders + * #f6f7db Right/Bottom icon hover borders + * + * Special Use Colors: + * #a20000 Text Error, border invalid + * #cccccc Text (faded) + * #005800 Text (success) + * #eeeeee Background (input disabled) + * #ffffcf Background‚ permissions debug + * #cfffda Background‚ permissions debug + * #ffcfcf Background‚ permissions debug + */ + +// Import the variables file first to get common variables loaded +@import "hathor_variables.less"; + +// Define variables unique to this colour scheme, as well as override variables already defined in the common file +@altBackground: #f9fade; +@gradientTop: #f9fade; +@gradientBottom: #f9fade; +@mainBorder: #c7c8b2; + +// Import the baseline to compile the CSS +@import "colour_baseline.less"; diff --git a/Sites/pages/administrator/templates/hathor/less/forms.less b/Sites/pages/administrator/templates/hathor/less/forms.less new file mode 100644 index 00000000..bf43faa9 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/less/forms.less @@ -0,0 +1,196 @@ +// +// Forms +// This is a custom version of Bootstrap's forms.less file suited for Hathor's needs +// -------------------------------------------------- + +// Ensure input-prepend/append never wraps +.input-append input[class*="span"], +.input-append .uneditable-input[class*="span"], +.input-prepend input[class*="span"], +.input-prepend .uneditable-input[class*="span"], +.row-fluid input[class*="span"], +.row-fluid select[class*="span"], +.row-fluid textarea[class*="span"], +.row-fluid .uneditable-input[class*="span"], +.row-fluid .input-prepend [class*="span"], +.row-fluid .input-append [class*="span"] { + display: inline-block; +} +// Allow us to put symbols and text within the input field for a cleaner look +.input-append, +.input-prepend { + margin-bottom: 5px; + font-size: 0; + white-space: nowrap; // Prevent span and input from separating + + input, + select, + .uneditable-input { + position: relative; // placed here by default so that on :focus we can place the input above the .add-on for full border and box-shadow goodness + margin-bottom: 0; // prevent bottom margin from screwing up alignment in stacked forms + *margin-left: 0; + font-size: @baseFontSize; + vertical-align: top; + .border-radius(0 @inputBorderRadius @inputBorderRadius 0); + // Make input on top when focused so blue border and shadow always show + &:focus { + z-index: 2; + } + } + .add-on { + display: inline-block; + width: auto; + height: @baseLineHeight; + min-width: 16px; + padding: 4px 5px; + font-size: @baseFontSize; + font-weight: normal; + line-height: @baseLineHeight; + text-align: center; + text-shadow: 0 1px 0 @white; + background-color: @grayLighter; + border: 1px solid #ccc; + } + .add-on, + .btn { + margin-left: -1px; + vertical-align: top; + .border-radius(0); + } + .active { + background-color: lighten(@green, 30); + border-color: @green; + } +} +.input-prepend { + .add-on, + .btn { + margin-right: -1px; + } + .add-on:first-child, + .btn:first-child { + .border-radius(@inputBorderRadius 0 0 @inputBorderRadius); + } +} +.input-append { + input, + select, + .uneditable-input { + .border-radius(@inputBorderRadius 0 0 @inputBorderRadius); + } + .add-on:last-child, + .btn:last-child { + .border-radius(0 @inputBorderRadius @inputBorderRadius 0); + } +} +// Remove all border-radius for inputs with both prepend and append +.input-prepend.input-append { + input, + select, + .uneditable-input { + .border-radius(0); + } + .add-on:first-child, + .btn:first-child { + margin-right: -1px; + .border-radius(@inputBorderRadius 0 0 @inputBorderRadius); + } + .add-on:last-child, + .btn:last-child { + margin-left: -1px; + .border-radius(0 @inputBorderRadius @inputBorderRadius 0); + } +} +/* Allow for input prepend/append in search forms */ +.form-search .input-append .search-query, +.form-search .input-prepend .search-query { + .border-radius(0); // Override due to specificity +} +.form-search .input-append .search-query { + .border-radius(14px 0 0 14px) +} +.form-search .input-append .btn { + .border-radius(0 14px 14px 0) +} +.form-search .input-prepend .search-query { + .border-radius(0 14px 14px 0) +} +.form-search .input-prepend .btn { + .border-radius(14px 0 0 14px) +} +.form-search, +.form-inline, +.form-horizontal { + input, + textarea, + select, + .help-inline, + .uneditable-input, + .input-prepend, + .input-append { + display: inline-block; + .ie7-inline-block(); + margin-bottom: 0; + vertical-align: middle; + } + // Re-hide hidden elements due to specifity + .hide { + display: none; + } +} +// Remove margin for input-prepend/-append +.form-search .input-append, +.form-inline .input-append, +.form-search .input-prepend, +.form-inline .input-prepend { + margin-bottom: 0; +} +/* Accessible Hidden Elements (good for hidden labels and such) */ +.element-invisible{ + position: absolute; + padding: 0 !important; + margin: 0 !important; + border: 0; + height: 1px; + width: 1px !important; + overflow: hidden; +} + +// Login form only +// Shared size and type resets +#form-login select, +#form-login input[type="text"], +#form-login input[type="password"] { + display: inline-block; + padding: 4px 6px; + margin-bottom: 9px; + font-size: @baseFontSize; + line-height: @baseLineHeight; + color: @gray; + .border-radius(@inputBorderRadius); + width: 175px; +} + +/* Field subform repeatable */ +.subform-repeatable-wrapper{ + + div.btn-toolbar{ + float: none; + } + + .text-right{ + text-align: right; + } + + .ui-sortable-helper{ + background: @white; + } + + tr.ui-sortable-helper{ + display: table; + } + + .subform-repeatable-group{ + clear: both; + } +} diff --git a/Sites/pages/administrator/templates/hathor/less/hathor_variables.less b/Sites/pages/administrator/templates/hathor/less/hathor_variables.less new file mode 100644 index 00000000..36bf2f54 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/less/hathor_variables.less @@ -0,0 +1,140 @@ +// hathor_variables.less +// +// Less file containing Bootstrap variables needed to compile its CSS +// ----------------------------------------------------- + +// Grays +// ------------------------- +@black: #000000; +@grayDarker: #222222; +@grayDark: #333333; +@gray: #555555; +@grayLight: #999999; +@grayLighter: #eeeeee; +@white: #ffffff; + +// Accent colors +// ------------------------- +@blue: #049cdb; +@blueDark: #0064cd; +@green: #46a546; +@red: #9d261d; +@yellow: #ffc40d; +@orange: #f89406; +@pink: #c3325f; +@purple: #7a43b6; + +// Scaffolding +// ------------------------- +@bodyBackground: @white; +@textColor: #2c2c2c; + +// Links +// ------------------------- +@linkColor: #054993; +@linkColorHover: darken(@linkColor, 15%); + +// Typography +// ------------------------- +@baseFontSize: 13px; +@baseLineHeight: 15px; + +@headingsFontFamily: inherit; // empty to use BS default, @baseFontFamily +@headingsFontWeight: bold; // instead of browser default, bold +@headingsColor: inherit; // empty to use BS default, @textColor + +// Component sizing +// ------------------------- +@baseBorderRadius: 4px; +@borderRadiusLarge: 6px; +@borderRadiusSmall: 3px; + +// Buttons +// ------------------------- +@btnBackground: @white; +@btnBackgroundHighlight: darken(@white, 10%); +@btnBorder: #bbb; + +@btnPrimaryBackground: @linkColor; +@btnPrimaryBackgroundHighlight: spin(@btnPrimaryBackground, 20%); + +@btnInfoBackground: #5bc0de; +@btnInfoBackgroundHighlight: #2f96b4; + +@btnSuccessBackground: #62c462; +@btnSuccessBackgroundHighlight: #51a351; + +@btnWarningBackground: lighten(@orange, 15%); +@btnWarningBackgroundHighlight: @orange; + +@btnDangerBackground: #ee5f5b; +@btnDangerBackgroundHighlight: #bd362f; + +@btnInverseBackground: #444; +@btnInverseBackgroundHighlight: @grayDarker; + +// Forms +// ------------------------- +@inputBackground: #e5f0fa; +@inputBorder: #ccc; +@inputBorderRadius: 3px; +@inputDisabledBackground: @grayLighter; +@formActionsBackground: #f5f5f5; +@inputHeight: @baseLineHeight + 10px; // base line-height + 8px vertical padding + 2px top/bottom border + +// Z-index master list +// ------------------------- +// Used for a bird's eye view of components dependent on the z-axis +// Try to avoid customizing these :) +@zindexDropdown: 1000; +@zindexTooltip: 1030; +@zindexFixedNavbar: 1030; +@zindexModalBackdrop: 1040; +@zindexModal: 1050; +@zindexPopover: 1060; + +// Form states and alerts +// ------------------------- +@warningText: #c09853; +@warningBackground: #fcf8e3; +@warningBorder: darken(spin(@warningBackground, -10), 3%); + +@errorText: #a20000; +@errorBackground: #f2dede; +@errorBorder: darken(spin(@errorBackground, -10), 3%); + +@successText: #005800; +@successBackground: #dff0d8; +@successBorder: darken(spin(@successBackground, -10), 5%); + +@infoText: #3a87ad; +@infoBackground: #d9edf7; +@infoBorder: darken(spin(@infoBackground, -10), 7%); + +// Tooltips and popovers +// ------------------------- +@tooltipColor: @white; +@tooltipBackground: @black; +@tooltipArrowWidth: 5px; +@tooltipArrowColor: @tooltipBackground; + +@popoverBackground: @white; +@popoverArrowWidth: 10px; +@popoverArrowColor: @white; +@popoverTitleBackground: darken(@popoverBackground, 3%); + +// Special enhancement for popovers +@popoverArrowOuterWidth: @popoverArrowWidth + 1; +@popoverArrowOuterColor: rgba(0,0,0,.25); + +// Variables unique to Hathor +// ------------------------- +@toolbarColor: @linkColor; +@hoverBackground: #e5d9c3; +@nwBorder: #868778; +@seBorder: #f6f7db; +@fadedText: #cccccc; +@disabledBackground: #eeeeee; +@permissionDefault: #ffffcf; +@permissionAllowed: #cfffda; +@permissionDenied: #ffcfcf; diff --git a/Sites/pages/administrator/templates/hathor/less/icomoon.less b/Sites/pages/administrator/templates/hathor/less/icomoon.less new file mode 100644 index 00000000..f2e9c3a5 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/less/icomoon.less @@ -0,0 +1,11 @@ +@font-face { + font-family: 'IcoMoon'; + src: url('../../../../media/jui/fonts/IcoMoon.eot'); + src: url('../../../../media/jui/fonts/IcoMoon.eot?#iefix') format('embedded-opentype'), + url('../../../../media/jui/fonts/IcoMoon.woff') format('woff'), + url('../../../../media/jui/fonts/IcoMoon.ttf') format('truetype'), + url('../../../../media/jui/fonts/IcoMoon.svg#IcoMoon') format('svg'); + font-weight: normal; + font-style: normal; +} +@import "../../../../media/jui/less/icomoon.less"; diff --git a/Sites/pages/administrator/templates/hathor/less/modals.less b/Sites/pages/administrator/templates/hathor/less/modals.less new file mode 100644 index 00000000..64f84116 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/less/modals.less @@ -0,0 +1,108 @@ +// MODALS +// ------ + +// Recalculate z-index where appropriate +.modal-open { + .dropdown-menu { z-index: @zindexDropdown + @zindexModal; } + .dropdown.open { *z-index: @zindexDropdown + @zindexModal; } + .popover { z-index: @zindexPopover + @zindexModal; } + .tooltip { z-index: @zindexTooltip + @zindexModal; } +} + +// Background +.modal-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: @zindexModalBackdrop; + background-color: @black; + // Fade for backdrop + &.fade { opacity: 0; } +} + +.modal-backdrop, +.modal-backdrop.fade.in { + .opacity(80); +} + +// Base modal +div.modal { + position: fixed; + top: 50%; + left: 50%; + z-index: @zindexModal; + overflow: auto; + width: 80%; + margin: -250px 0 0 -40%; + background-color: @white; + border: 1px solid #999; + border: 1px solid rgba(0,0,0,.3); + *border: 1px solid #999; /* IE6-7 */ + .border-radius(6px); + .box-shadow(0 3px 7px rgba(0,0,0,0.3)); + .background-clip(padding-box); + &.fade { + .transition(e('opacity .3s linear, top .3s ease-out')); + top: -25%; + } + &.fade.in { top: 50%; } +} +.modal-header { + padding: 9px 15px; + border-bottom: 1px solid #eee; + // Close icon + .close { + float: right; + margin-top: 2px; + } +} + +// Body (where all modal content resides) +.modal-body { + overflow-y: auto; + max-height: 400px; + padding: 15px; +} +// Remove bottom margin if need be +.modal-form { + margin-bottom: 0; +} + +// Footer (for actions) +.modal-footer { + padding: 14px 15px 15px; + margin-bottom: 0; + text-align: right; // right align buttons + background-color: #f5f5f5; + border-top: 1px solid #ddd; + .border-radius(0 0 6px 6px); + .box-shadow(inset 0 1px 0 @white); + .clearfix(); // clear it in case folks use .pull-* classes on buttons + + // Properly space out buttons + .btn + .btn { + margin-left: 5px; + margin-bottom: 0; // account for input[type="submit"] which gets the bottom margin like all other inputs + } + // but override that for button groups + .btn-group .btn + .btn { + margin-left: -1px; + } +} + +/* Prevent scrolling on the parent window of a modal */ +body.modal-open { + overflow: hidden; + -ms-overflow-style: none; +} + +/* Buttons bar in modal iframe */ +.modal-buttons { + padding: 15px 0px; +} +.modal-buttons button { + font-size: 1.2em; + line-height: 1.6em; +} diff --git a/Sites/pages/administrator/templates/hathor/less/template.less b/Sites/pages/administrator/templates/hathor/less/template.less new file mode 100644 index 00000000..4c5710af --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/less/template.less @@ -0,0 +1,3565 @@ +// Import the variables file first to get common variables loaded +@import "hathor_variables.less"; + +// Core variables and mixins +@import "../../../../media/jui/less/mixins.less"; + +// Bootstrap Component Animations +@import "../../../../media/jui/less/component-animations.less"; + +// Bootstrap Modals +@import "modals.less"; +//@import "../../../../media/jui/less/modals.joomla.less"; + +// Bootstrap Popovers +@import "../../../../media/jui/less/popovers.less"; + +// Icon Font +@import "icomoon.less"; + +/** + * CSS Reset + */ +html, body, div, span, applet, object, iframe, +h1, h2, h3, h4, h5, h6, p, blockquote, pre, +a, abbr, acronym, address, big, cite, code, +del, dfn, em, font, img, ins, kbd, q, s, samp, +small, strike, strong, sub, sup, tt, var, +b, u, i, center, +dl, dt, dd, ol, ul, li, +fieldset, form, label, legend, +table, caption, tbody, tfoot, thead, tr, th, td { + margin: 0; + padding: 0; + border: 0; + font-size: 100%; + background: transparent; +} + +blockquote, q { + quotes: none; +} + +blockquote:before, blockquote:after, +q:before, q:after { + content: ''; + content: none; +} + +del { + text-decoration: line-through; +} + +/** + * General styles + */ +html { + overflow-y: scroll; + height: 100%; +} + +body { + margin: 0; + padding: 0; + font-size: 62.5%; + line-height: 1.5em; + height: 100%; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +body, td, th, span, a { + font-family: Arial, Helvetica, sans-serif; +} + +html, body { + height: 100%; +} + +a, img { + padding: 0; + margin: 0; +} + +img { + border: 0 none; +} + +form { + margin: 0; + padding: 0; +} + +ul { + padding: 0; + margin: 0; +} + +h1 { + margin: 0; + padding-bottom: 8px; + font-size: 1.4em; + font-weight: bold; + line-height: 2em; +} + +h2 { + padding-top: .83em; + padding-bottom: .83em; +} + +h3 { + font-size: 1.4em; +} + +a:link { + color: #054993; + text-decoration: none; +} + +a:visited { + color: #054993; + text-decoration: none; +} + +a:hover { + text-decoration: underline; +} + +a:focus { + text-decoration: underline; +} + +iframe { + border: 0; +} + +/* new styles */ + +.enabled { + color: #005800; + font-weight: bold; +} + +.disabled { + color: #a20000; + font-weight: bold; +} + +p.error { + color: #a20000; + font-weight: bold; +} + +.warning { + color: #a20000; + font-weight: bold; +} + +.nowarning { + color: #2c2c2c; + font-weight: bold; +} + +.success { + color: #005800; + font-weight: bold; +} + +.allow { + color: #005800; +} + +span.writable { + color: #005800; +} + +.deny { + color: #a20000; +} + +span.unwritable { + color: #a20000; +} + +.none { + color: #aaaaaa; +} + +.pointer { + cursor: pointer; +} + +.nowrap { + white-space: nowrap; +} + +p.nowarning, p.warning { + margin: 10px; +} + +/* end new styles */ + +/** + * Overall Styles + */ +#minwidth, #minwidth-body { + min-width: 980px; +} + +#containerwrap { + position: relative; +} + +#header { + position: relative; +} + +#header h1.title { + font-size: 1.5em; + font-weight: normal; + line-height: 25px; + margin: 0; + padding: 0 0 0 120px; +} + +#footer { + padding: 10px 20px; +} + +#footer .copyright { + margin: 0 0 0 0; + text-align: center; +} + +#footer p { + font-size: 1.2em; +} + +#nav .no-nav { + line-height: 2em; +} + +#content { + margin: 5px 20px 20px 20px; +} + +.cpanel-page div#element-box { + padding: 15px; +} + +/** + * Status layout + */ +#module-status { + float: right; + position: relative; + top: -48px; +} + +#module-status div.btn-group { + display: block; + float: left; + padding: 4px 10px 0 10px; + font-size: 1.2em; +} + +#module-status div.divider { + display: none; +} + +#module-status .unread-messages a { + font-weight: bold; +} + +.title-ua { + position: relative; + width: 60%; +} + +/** + * Various Styles + */ +.enabled, +.disabled, +p.error, +.warning, +.nowarning, +.success { + font-weight: bold; +} + +.pointer { + cursor: pointer; +} + +.nowrap { + white-space: nowrap; +} + +span.note { + display: block; + padding: 5px; +} + +div.checkin-tick { + text-indent: -9999px; +} + +/** + * Overlib + */ +.ol-textfont { + font-family: Arial, Helvetica, sans-serif; + font-size: 1.2em; +} + +.ol-captionfont { + font-family: Arial, Helvetica, sans-serif; + font-size: 1.2em; + font-weight: bold; +} + +.ol-captionfont a { + text-decoration: none; +} + +/** + * Subheader, toolbar, page title + */ +div.subheader .padding { + padding: 0; +} + +div.pagetitle { + padding: 0 0 5px 5px; + margin: 0; + background-repeat: no-repeat; + background-position: left 50%; + line-height: 54px; + width: 100%; + margin-top: -20px; + height: 60px; +} + +.tabs-left > .nav-tabs { + float: left; + margin-right: 19px; + border-right: 1px solid #DDD; +} + +tabs-below > .nav-tabs, .tabs-right > .nav-tabs, .tabs-left > .nav-tabs { + border-bottom: 0; +} + +/* Tabbed Content */ +.tab-content { + overflow: visible; +} + +.tabs-left .tab-content { + overflow: auto; +} + +/* Non-linkable nav-tabs */ +.nav-tabs > li > span { + display: block; + margin-right: 2px; + padding-right: 12px; + padding-left: 12px; + padding-top: 8px; + padding-bottom: 8px; + line-height: 18px; + border: 1px solid transparent; + -webkit-border-radius: 4px 4px 0 0; + -moz-border-radius: 4px 4px 0 0; + border-radius: 4px 4px 0 0; +} + +/* Extended Joomla Button Classes */ +.btn-micro { + padding: 1px 4px; + font-size: 10px; + line-height: 8px; +} + +/* Joomla => Bootstrap Tooltip */ +.tip-wrap { + max-width: 200px; + padding: 3px 8px; + color: #ffffff; + text-align: center; + text-decoration: none; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + z-index: 100; +} + +.pagetitle h2 { + padding: 0 0 0 50px; + font-size: 1.3em; + font-weight: bold; + line-height: 48px; + font-style: italic; +} + +div.configuration { + font-size: 1.2em; + font-weight: bold; + line-height: 2em; + padding-left: 30px; + margin-left: 10px; +} + +div.toolbar-box h3 { + height: 0; + overflow: hidden; + position: absolute; + padding: 0; + margin: 0; +} + +.btn-toolbar { + margin-bottom: 3px; + margin-top: 14px; +} + +div.btn-toolbar, div.toolbar-list { + float: left; + text-align: left; + padding: 0; +} + +div.toolbar-list li { + padding: 5px 1px 5px 4px; + text-align: center; + height: 52px; + list-style: none; + float: left; +} + +div.toolbar-list li.spacer { + width: 10px; +} + +div.toolbar-list li.divider { + width: 10px; + margin-right: 10px; +} + +div.toolbar-list span { + float: none; + width: 32px; + height: 32px; + margin: 0 auto; + display: block; +} + +div.toolbar-list a { + display: block; + float: left; + white-space: nowrap; + padding: 1px 5px; + cursor: pointer; + font-weight: bold; +} + +div.btn-toolbar div.btn-group button { + display: block; + float: left; + white-space: nowrap; + padding: 1px 5px; + cursor: pointer; + text-align: center; +} + +div.btn-toolbar button:hover, div.btn-toolbar button:focus, div.toolbar-list a:hover, div.toolbar-list a:focus { + text-decoration: none; +} + +/** + * Massmail component + */ +td#mm_pane { + width: 90%; +} + +input#mm_subject { + width: 200px; +} + +textarea#mm_message { + width: 100%; +} +textarea { + resize:both; +} +textarea.vert { + resize:vertical; +} +textarea.noResize { + resize:none; +} + +/** + * Pane Slider pane Toggler styles + */ +.pane-sliders { + margin: 0; + position: relative; +} + +.pane-sliders .title { + margin: 0; + padding: 2px; + cursor: pointer; +} + +.pane-sliders .panel { + margin-bottom: 3px; +} + +.pane-sliders .adminlist td { + border: 0 none; +} + +h3.pane-toggler-down a:focus, +h3.pane-toggler a:focus { + outline: none; +} + +.pane-toggler span { + padding-left: 20px; +} + +.pane-toggler-down span { + padding-left: 20px; +} + +/* The following line hides the unseen panel (prevents the mouse from activating in IE, so overridden in the ie css files) */ +/*.pane-toggler + div.pane-slider {display: none;}*/ +.pane-slider.pane-hide { + display: none; +} + +div#position-icon.pane-sliders div.pane-down div.quickicon-wrapper { + margin: 5px 0 5px 0; +} + +div#position-icon.pane-sliders div.pane-down .quickicon-wrapper .icon { + padding: 5px 0 5px 10px; + margin: 0; +} + +/** + * Tabs + */ +dl.tabs { + float: left; + margin: 10px 0 -1px 0; + z-index: 50; +} + +dl.tabs dt { + float: left; + padding: 4px 10px; + margin-left: 3px; +} + +dl.tabs dt.open { + z-index: 100; +} + +div.current { + clear: both; + padding: 10px 10px; +} + +div.current dd { + padding: 0; + margin: 0; +} + +/* New parameter styles */ + +dl#content-pane.tabs { + margin: 1px 0 0 0; +} + +div.current label, div.current span.faux-label { + display: block; + min-width: 150px; + float: left; + clear: left; + margin-top: 8px; +} + +div.current fieldset.radio { + float: left; +} + +div.current fieldset.radio input { + clear: none; + min-width: 15px; + float: left; + margin: 3px 0 0 2px; +} + +div.current fieldset.radio label { + clear: none; + min-width: 45px; + float: left; + margin: 3px 0 0 2px; +} + +div.current fieldset.checkboxes { + float: left; + clear: right; +} + +div.current fieldset.checkboxes input { + clear: left; + min-width: 15px; + float: left; + margin: 3px 0 0 2px; +} + +div.current fieldset.checkboxes label { + clear: right; + min-width: 45px; + margin: 3px 0 0 2px; +} + +div.current input, +div.current span.faux-input, +div.current textarea, +div.current select { + clear: none; + float: left; + margin: 3px 0 0 2px; +} + +div.current select { + margin-bottom: 15px; +} + +div.current table#acl-config th.acl-groups { + text-align: left; +} + +div.current table#filter-config th.acl-groups { + text-align: left; +} + +div.current table#filter-config select { + margin-bottom: 0; +} + +/* -------- Menu Assigments ---------- */ +div#menu-assignment { + clear: left; +} + +div#menu-assignment ul.menu-links { + float: left; + width: 49%; +} + +div#menu-assignment ul.menu-links label { + clear: none; + float: left; + margin: 3px 0 0 2px; +} + +div#menu-assignment ul.menu-links input { + clear: left; + float: left; +} + +button.jform-rightbtn { + float: right; + margin-right: 0; +} + +p.tab-description { + font-size: 1.091em; + margin-left: 0; + margin-top: 5px; +} + +/* end new parameter styles */ + +/** + * Login Settings + */ +#login-page input, #login-page select { + float: right; + clear: none; +} + +#login-page .login { + margin: 0 auto; + width: 575px; + margin-bottom: 100px; +} + +#login-page .pagetitle h2 { + margin: -70px 0 30px 0; + font-size: 2em; + padding: 0; +} + +#login-page p { + margin: 0; + padding: 0; + margin-bottom: 1em; + font-size: 1.2em; +} + +#login-page #header { + margin-bottom: 100px; +} + +#login-page .login-inst { + float: left; + width: 35%; +} + +#login-page .login-box { + float: right; + width: 63%; +} + +#login-page #lock { + width: 150px; + height: 137px; +} + +#login-page #element-box.login { + padding: 20px; + -moz-border-radius: 3px; + -webkit-border-radius: 3px; + border-radius: 3px; +} + +#login-page .button { + text-align: right; +} + +#login-page .login-text { + text-align: left; + width: 40%; + float: left; +} + +#form-login { + float: left; + padding: 1.1em; + -moz-border-radius: 3px; + -webkit-border-radius: 3px; + border-radius: 3px; +} + +#form-login fieldset { + border: none; +} + +#form-login label { + display: block; + float: left; + clear: left; + width: 100px; + text-align: right; + padding: 4px; + color: #2c2c2c; + font-weight: bold; + font-size: 1.4em; + margin-bottom: 15px; +} + +#form-login div.button1 div.next { + float: left; +} + +#form-login div.button1 a { + height: 2.2em; + line-height: 2.2em; + font-size: 1.5em; + cursor: default; + padding: 0 15px 0 15px; +} + +.login-submit { + border: 0; + padding: 0; + margin: 0; + width: 0; + height: 0; +} + +/** + * Cpanel Settings + */ +#cpanel div.icon, .cpanel div.icon { + text-align: center; + margin-right: 5px; + float: left; + margin-bottom: 5px; +} + +#cpanel div.icon a, .cpanel div.icon a { + display: block; + float: left; + height: auto; + min-height: 97px; + width: 108px; + color: #2c2c2c; + vertical-align: middle; + text-decoration: none; + font-weight: bold; +} + +#cpanel img, .cpanel img { + padding: 10px; + margin: 0 auto; +} + +#cpanel span, .cpanel span { + display: block; + text-align: center; + padding: 0 0 5px; +} + +div.cpanel-icons { + width: 54%; + float: left; +} + +div.cpanel-component { + width: 45%; + float: right; +} + +/** + * Standard Layout Styles + */ + +div.col { + float: left; +} + +div.options-section.col { + float: right; +} + +div.col1 { + float: left; + width: 45%; +} + +div.col2 { + float: right; + width: 45%; +} + +/* Avoid using the width divs. They are here for 3PD Extensions if needed + * Use the specific layout divs listed after. See also the th.width entries */ +div.width-1 { + width: 1%; +} + +div.width-3 { + width: 3%; +} + +div.width-5 { + width: 5%; +} + +div.width-10 { + width: 10%; +} + +div.width-20 { + width: 20%; +} + +div.width-30 { + width: 30%; +} + +div.width-35 { + width: 35%; +} + +div.width-40 { + width: 40%; +} + +div.width-45 { + width: 45%; +} + +div.width-50 { + width: 50%; +} + +div.width-55 { + width: 55%; +} + +div.width-60 { + width: 60%; +} + +div.width-65 { + width: 65%; +} + +div.width-70 { + width: 70%; +} + +div.width-80 { + width: 80%; +} + +div.width-100 { + width: 100%; +} + +.clrlft { + clear: left; +} + +.clrrt { + clear: right; +} + +.fltlft { + float: left; +} + +.fltrt { + float: right; +} + +.fltnone { + float: none; +} + +/* Layout Divs */ +div.main-section { + width: 60%; +} + +div.options-section { + width: 38%; + margin: 10px 10px 10px 0; +} + +/* for bluestork style html */ +div.width-40.fltrt { + width: 38%; + margin: 10px 10px 10px 0; +} + +div.rules-section { + width: 98%; + margin: 10px; +} + +/** + * Form Styles + */ + +fieldset { + margin: 2px 10px 2px 10px; + padding: 5px; + text-align: left; +} + +legend { + font-size: 1.3em; + font-weight: bold; + padding-bottom: 5px; +} + +fieldset p { + margin: 10px 0; + font-size: 1.2em; +} + +fieldset ol, ol#property-values, fieldset ul, ul#property-values { + margin: 0; + padding: 0; +} + +fieldset li, ol#property-values li, ul#property-values li { + list-style: none; + margin: 0; + padding: 5px; +} + +fieldset.adminform fieldset.radio, +fieldset.panelform fieldset.radio, +fieldset.adminform-legacy fieldset.radio { + border: 0; + float: left; + padding: 0; + margin: 0 0 5px 0; + clear: right; +} + +fieldset.adminform fieldset.radio label, +fieldset.panelform fieldset.radio label, +fieldset.adminform fieldset.radio span.faux-label, +fieldset.panelform fieldset.radio span.faux-label { + min-width: 40px; + float: left; + clear: none; +} + +/* checkboxes */ +fieldset.adminform fieldset.checkboxes, +fieldset.panelform fieldset.checkboxes, +fieldset.adminform-legacy fieldset.checkboxes { + border: 0; + float: left; + padding: 0; + margin: 0 0 5px 0; + clear: right; +} + +fieldset.adminform fieldset.checkboxes input[type="checkbox"], +fieldset.panelform fieldset.checkboxes input[type="checkbox"] { + float: left; + clear: left; +} + +fieldset.adminform fieldset.checkboxes label, +fieldset.panelform fieldset.checkboxes label, +fieldset.adminform fieldset.checkboxes span.faux-label, +fieldset.panelform fieldset.checkboxes span.faux-label { + clear: right; +} + +/* end checkboxes */ + +/* spacer */ +div.current span.spacer > span.before, +fieldset.adminform span.spacer > span.before, +fieldset.panelform span.spacer > span.before { + clear: both; + overflow: hidden; + height: 0; + display: block; +} + +/* end spacer */ + +fieldset.panelform-legacy label, +fieldset.adminform-legacy label, +fieldset.panelform-legacy span.faux-label, +fieldset.adminform-legacy span.faux-label { + min-width: 150px; + float: left; + +} + + +fieldset.adminform, +fieldset.panelform { + .input-prepend, + .input-append { + float: left; + } + .adminformlist .btn.modal, + .input-prepend > *, + .input-append > * { + float: none; + vertical-align: middle; + } +} + +/* JParameter classes on radio button labels */ +fieldset.panelform-legacy label.radiobtn-jno, +fieldset.panelform-legacy label.radiobtn-jyes, +fieldset.panelform-legacy label.radiobtn-show, +fieldset.panelform-legacy label.radiobtn-hide, +fieldset.panelform-legacy label.radiobtn-off, +fieldset.panelform-legacy label.radiobtn-on { + min-width: 40px !important; + clear: none !important; +} + +#jform_plugdesc-lbl, +#jform_description-lbl { + font-weight: bold; + clear: both; + margin-top: 15px; +} + +p.jform_desc { + clear: left; +} + +div#jform_ordering { + font-size: 1.091em; + margin-top: 3px; +} + +fieldset ul.checklist { + margin-left: 27px; +} + +fieldset ul.checklist input, +fieldset ul.checklist label { + float: none; +} + +fieldset ul.checklist input:focus { + outline: thin dotted #333333; +} + +fieldset#filter-bar { + margin: 0; + padding: 5px 10px 5px 10px; + float: left; + width: 98% +} + +fieldset#filter-bar ol, fieldset#filter-bar ul { + list-style: none; + margin: 0; + padding: 5px 0 0; +} + +fieldset#filter-bar ol li, fieldset#filter-bar ul li { + float: left; + padding: 0 5px 0 0; +} + +fieldset#filter-bar ol li fieldset, fieldset#filter-bar ul li fieldset { + margin: 0; + padding: 0; +} + +fieldset#filter-bar .filter-search { + float: left; + padding-bottom: 3px; +} + +fieldset#filter-bar .filter-select { + float: right; +} + +fieldset#filter-bar input#search { + width: 10em; +} + +/* Note: these visual cues should be augmented by aria */ +.invalid { + font-weight: bold; +} + +/* augmented by aria in template javascript */ +input.readonly, span.faux-input { + border: 0; +} + +.star { + color: #cc0000; + font-size: 1.2em; +} + +input, select, span.faux-input { + font-size: 1.2em; + -moz-border-radius: 3px; + -webkit-border-radius: 3px; + border-radius: 3px; +} + +span.readonly { + float: left; + font-size: 1.2em; + line-height: 2em; +} + +div.readonly { + font-size: 1.2em; + line-height: 2em; +} + +div.extdescript { + margin-left: 10px; +} + +input[type="button"], +input[type="submit"], +input[type="reset"] { + font-family: Arial, Helvetica, sans-serif; + padding: 1px 6px; + font-size: 1.2em; + line-height: 1.5em; +} + +textarea { + font-size: 1.4em; + -moz-border-radius: 3px; + -webkit-border-radius: 3px; + border-radius: 3px; +} + +input.button { + cursor: pointer; +} + +label { + font-weight: bold; + font-size: 1.1em; +} + +span.faux-label { + font-weight: bold; + font-size: 1.1em; +} + +label.selectlabel { + position: absolute; + left: -1000em; +} + +/** + * Option or Parameter styles + */ + +.paramrules { + padding: 10px; +} + +span.gi { + font-weight: bold; + margin-right: 5px; +} + +span.gtr { + visibility: hidden; + margin-right: 5px; +} + +/** + * Admintable Styles + */ +table.admintable td { + padding: 3px; + font-size: 1em; +} + +table.admintable td.key, table.admintable td.paramlist_key { + text-align: right; + width: 140px; + font-weight: bold; + font-size: 1em; +} + +table.admintable td.key label, table.admintable td.paramlist_key label { + font-size: 1em; +} + +table.admintable td.paramlist_value label { + font-size: 1em; +} + +table.admintable input, table.admintable span.faux-input, table.admintable select { + font-size: 1em; +} + +table.paramlist td.paramlist_description { + text-align: left; + width: 170px; + font-weight: normal; +} + +table.admintable td.key.vtop { + vertical-align: top; +} + +/** + * Admin Form Styles + */ +fieldset.adminform { + margin: 0 10px 10px 10px; + overflow: hidden; +} + +.adminformlist .btn.modal{ + float: left; + margin-top: 7px; +} + +ul.adminformlist, +ul.adminformlist li, +dl.adminformlist, +dl.adminformlist li { + margin: 0; + padding: 0; + list-style: none; +} + +ul.adminformlist pre { + font-size: 1.3em; +} + +ul.adminformlist .button2-left, ul.adminformlist .button2-left { + margin-top: 5px; +} + +/* Table styles are for use with tabular data */ +table.adminform { + width: 100%; + border-collapse: collapse; + margin: 8px 0 10px 0; + margin-bottom: 15px; +} + +table.adminform.nospace { + margin-bottom: 0; +} + +table.adminform th { + font-size: 1.4em; + padding: 6px 2px 4px 4px; + text-align: left; + height: 25px; +} + +table.adminform td { + padding: 3px; + text-align: left; +} + +table.adminform td#filter-bar { + text-align: left; +} + +table.adminform td.helpMenu { + text-align: right; +} + +table.adminform tr { + padding-left: 10px; + padding-right: 10px; +} + +/** + * Table formating styles + */ +td.center, th.center { + text-align: center; +} + +/* Avoid using the width classes. They are here for 3PD Extensions if needed + * Use the specific layout table headers listed after. See also the div.width entries */ +th.width-1 { + width: 1%; +} + +th.width-3 { + width: 3%; +} + +th.width-5 { + width: 5%; +} + +th.width-10 { + width: 10%; +} + +th.width-12 { + width: 12%; +} + +th.width-15 { + width: 15%; +} + +th.width-20 { + width: 20%; +} + +th.width-25 { + width: 25%; +} + +th.width-30 { + width: 30%; +} + +th.width-40 { + width: 40%; +} + +/* Table header layout classes */ +th.row-number-col { + width: 3%; +} + +th.checkmark-col { + width: 1%; +} + +th.state-col { + width: 5%; +} + +th.ordering-col { + width: 10%; +} + +th.ordering-col a { + display: block; + float: left; + margin-left: 3px; +} + +th.ordering-col a img { + margin-left: 4px; + margin-right: 4px; +} + +.categories th.ordering-col input, .categories td.order input { + font-size: 1em; +} + +th.category-col { + width: 5%; +} + +th.access-col { + width: 10%; +} + +.categories th.access-col { + width: 5%; +} + +th.hits-col { + width: 5%; +} + +th.id-col { + width: 3%; +} + +th.featured-col { + width: 5%; +} + +th.created-by-col { + width: 15%; +} + +th.date-col { + width: 5%; +} + +th.language-col { + width: 5%; +} + +th.home-col { + width: 5%; +} + +/** + * Adminlist Table layout + */ +table.adminlist { + width: 100%; + float: left; +} + +table.adminlist td, table.adminlist th { + padding: 4px; + font-size: 1.2em; +} + +table.adminlist thead th { + text-align: center; +} + +table.adminlist thead a:hover { + text-decoration: none; +} + +table.adminlist thead th img { + vertical-align: middle; +} + +table.adminlist tbody th { + font-weight: bold; +} + +/* Table row styles */ +table.adminlist tr { + padding-left: 30px; + padding-right: 30px; +} + +table.adminlist tbody tr { + text-align: left; +} + +table.adminlist tbody tr td, +table.adminlist tbody tr th { + height: 25px; +} + +table.adminlist tfoot tr { + text-align: center; +} + +/* Table td/th styles */ +table.adminlist tfoot td, table.adminlist tfoot th { + text-align: center; +} + +table.adminlist td.order { + text-align: center; + white-space: nowrap; +} + +table.adminlist td.order span { + float: left; + width: 20px; + text-align: center; +} + +table.adminlist td.order input { + text-align: center; + width: 3em; + font-size: 100%; +} + +/** + * Tree indentation & nesting - Up to 10 levels deep so don't go crazy : + */ +#media-tree_tree ul { + list-style: none outside none; + margin: 0 10px; +} + +table.adminlist td.indent-4 { + padding-left: 4px; +} + +table.adminlist td.indent-19 { + padding-left: 19px; +} + +table.adminlist td.indent-34 { + padding-left: 34px; +} + +table.adminlist td.indent-49 { + padding-left: 49px; +} + +table.adminlist td.indent-64 { + padding-left: 64px; +} + +table.adminlist td.indent-79 { + padding-left: 79px; +} + +table.adminlist td.indent-94 { + padding-left: 94px; +} + +table.adminlist td.indent-109 { + padding-left: 109px; +} + +table.adminlist td.indent-124 { + padding-left: 124px; +} + +table.adminlist td.indent-139 { + padding-left: 139px; +} + +/** + * Adminlist buttons + */ +table.adminlist tr td.btns a { + -moz-border-radius: 3px; + -webkit-border-radius: 3px; + border-radius: 3px; + padding: 3px 20px; +} + +table.adminlist tr td.btns a:hover, table.adminlist tr td.btns a:active, table.adminlist tr td.btns a:focus { + text-decoration: none; +} + +/** + * Adminlist lists + */ +table.adminlist td li { + list-style: inside; +} + +/** + * Modal Modules styles + */ +ul#new-modules-list { + margin-left: 50px; + font-size: 1.4em; + line-height: 1.5em; +} + +/** + * Utility styles + */ +/* General Clearing Class */ +.clr { + clear: both; + overflow: hidden; + height: 0; +} + +.clearfix:after { + content: "."; + display: block; + height: 0; + clear: both; + visibility: hidden; +} + +.menu-module-list { + list-style-position: inside; + padding-left: 10px; + margin-left: 5px; +} + +/* stu nicholls solution for centering divs */ +.container { + clear: both; + text-decoration: none; +} + +* html .container { + display: inline-block; +} + +/* table solution for global config */ +table.noshow { + width: 100%; + border-collapse: collapse; + padding: 0; + margin: 0; +} + +table.noshow tr { + vertical-align: top; +} + +table.noshow fieldset { + margin: 15px 7px 7px 7px; +} + +/** + * Saving order icon styling in admin tables + */ +a.saveorder { + width: 16px; + height: 16px; + display: block; + overflow: hidden; + float: right; + margin-right: 8px; +} + +/** + * Button styling + */ +#editor-xtd-buttons { + padding: 5px; +} + +button { + font-family: Arial, Helvetica, sans-serif; + -moz-border-radius: 3px; + -webkit-border-radius: 3px; + border-radius: 3px; + margin-right: 3px; + margin-left: 3px; +} + +.invalid { + font-weight: bold; +} + +/* Button 1 Type */ +.button1, .button1 div { + height: 1%; + float: right; +} + +.button1 { + white-space: nowrap; + -moz-border-radius: 3px; + -webkit-border-radius: 3px; + border-radius: 3px; +} + +.button1 a { + display: block; + height: 2.2em; + float: left; + line-height: 2.2em; + font-size: 1.2em; + font-weight: bold; + cursor: default; + padding: 0 6px 0 6px; + /* add padding if you are using the directional images */ + /* padding: 0 30px 0 6px; */ +} + +.button1 a:hover, .button1 a:focus { + text-decoration: none; +} + +/* Button 2 Type */ +.button2-left, .button2-right { + float: left; + line-height: 1.5em; + font-size: 1.2em; + -moz-border-radius: 3px; + -webkit-border-radius: 3px; + border-radius: 3px; +} + +.button2-left.smallsub, .button2-right.smallsub { + line-height: 1.2em; + font-size: .9em; +} + +.button2-left a, .button2-right a, .button2-left span, .button2-right span { + display: block; + float: left; + cursor: default; +} + +/* these are inactive buttons */ +.button2-left span, .button2-right span { + cursor: default; +} + +.button2-left .page a, .button2-right .page a, +.button2-left .page span, .button2-right .page span, +.button2-left .blank a, .button2-right .blank a, +.button2-left .blank span, .button2-right .blank span { + padding: 0 6px; +} + +.page span, .blank span { + font-weight: bold; +} + +.button2-left a:hover, +.button2-right a:hover, +.button2-left a:focus, +.button2-right a:focus { + text-decoration: none; +} + +.button2-left a, .button2-left span { + padding: 0 24px 0 6px; +} + +.button2-right a, .button2-right span { + padding: 0 6px 0 24px; +} + +.button2-left { + float: left; + margin-left: 5px; +} + +.button2-right { + float: left; + margin-left: 5px; +} + +/** + * Pagination styles + */ + +/* Normal pagination styles */ +div.containerpg { + position: relative; + left: 50%; + float: left; + clear: left; +} + +div.pagination { + position: relative; + left: -50%; + margin: 0 auto; + padding: .5em; +} + +.pagination div.limit { + float: left; + margin: 0 10px; + font-size: 1.2em; + height: 1.8em; + line-height: 1.8em; +} + +.pagination div.limit label { + font-size: 100%; + height: 1.8em; + line-height: 1.8em; +} + +.pagination div.limit select { + font-size: 100%; +} + +/* The Go submittal button */ +.pagination button { + font-size: 100%; + height: 2.0em; + line-height: 1.8em; + margin-right: 20px; +} + +div.pagination .button2-right, div.pagination .button2-left { + font-size: 1.2em; + height: 1.6em; + line-height: 1.6em; +} + +/* Style if pagination is part of the table (old style) */ +table.adminlist .pagination { + display: table; + padding: 0; + margin: 0 auto; + font-size: .8em; +} + +table.adminlist .pagination button { + font-size: 1.2em; + height: 1.6em; + line-height: 1.5em; + margin-right: 20px; +} + +/** + * MCE Editor + */ +div.toggle-editor { + margin-top: 9px; +} + +/** + * Tooltips + */ +.tip { + float: left; + padding: 5px; + max-width: 400px; + z-index: 50; +} + +.tip-title { + padding: 0; + margin: 0; + font-size: 120%; + margin-top: -15px; + padding-top: 15px; + padding-bottom: 5px; +} + +.tip-text { + font-size: 100%; + text-align: left; + margin: 0; +} + +/** + * Calendar + */ +a img.calendar { + width: 16px; + height: 16px; + margin-left: 3px; + cursor: pointer; + vertical-align: middle; +} + +/** + * JGrid styles + */ +a.jgrid:hover { + text-decoration: none; +} + +.jgrid span.state { + display: inline-block; + height: 16px; + width: 16px; +} + +.jgrid span.text { + display: none; +} + +/** + * Icons + * The Background Icons for Menus, Toolbars, Quick Icons + * are now in the color css files + */ + +/** + * General styles + */ +div.message { + text-align: center; + font-family: Arial, Helvetica, sans-serif; + font-size: 1.2em; + padding: 3px; + margin-bottom: 10px; + font-weight: bold; +} + +.helpIndex { + border: 0; + width: 100%; + height: 100%; + padding: 0; + overflow: auto; +} + +.helpFrame { + width: 100%; + height: 800px; + padding: 0 5px 0 10px; +} + +#treecellhelp { + width: 25%; + display: block; + position: relative; + float: left; + margin: 0; + padding: 2px; + overflow: hidden; +} + +#datacellhelp { + width: 73%; + display: block; + float: left; + margin: 0; + padding: 2px 0 0 0; +} + +.outline { + padding: 2px; +} + +/** + * Modal Styles + */ + +h2.modal-title { + margin-left: 15px; + margin-bottom: 0; + margin-top: 5px; + font-size: 1.8em; + padding-bottom: .5em; +} + +ul.menu_types { + padding: 0 0 0 15px; + width: 95%; + margin: 0; +} + +ul.menu_types li, +dl.menu_type dd ul li { + width: 240px; + list-style: none; + display: block; + float: left; + margin-right: 10px; +} + +ul.menu_types li { + width: 47%; +} + +dl.menu_type { + width: 240px; + margin: 0; + padding: 0; +} + +dl.menu_type dt { + font-weight: bold; + font-size: 1.5em; + float: left; + margin: 13px 0 5px 0; + width: 240px; +} + +dl.menu_type dd { + clear: left; + margin: 0; +} + +dl.menu_type dd a { + font-size: 1.2em; +} + +dl.menu_type dd ul li { + margin: 0; +} + +ul#new-modules-list { + padding: 5px 0 0 15px; + width: 95%; + margin: 0; + list-style: none; +} + +ul#new-modules-list li { + list-style: none; + display: block; + float: left; + margin: 0 20px 0 0; + width: 47%; +} + +ul#new-modules-list li a { + font-size: 1em; + line-height: 1.5em; +} + +body.contentpane #filter-bar { + font-size: 80%; +} + +body.contentpane input, body.contentpane select { + font-size: 120%; +} + +#filter-bar input, #filter-bar select, #filter-bar button { + font-size: 110%; +} + +/** + * User Accessibility + */ + +/* Skip to Content Structural Styling */ +#skiplinkholder a, #skiplinkholder a:link, #skiplinkholder a:visited { + display: block; + width: 99%; + position: absolute; + top: 0; + left: -200%; + z-index: 2; +} + +#skiplinkholder a:focus, #skiplinkholder a:active { + left: 0; + top: 0; + z-index: 100; +} + +#skiplinkholder p { + margin: 0; +} + +#skiptargetholder { + position: absolute; + left: -200%; +} + +/* Skip to Content Visual Styling */ +#skiplinkholder a, #skiplinkholder a:link, #skiplinkholder a:visited { + text-decoration: underline; + padding: 5px; + font-size: 1.3em; + font-weight: bold; + padding-left: 20px; + padding-right: 20px; +} + +/* Hide overlayed controls so that keyboarders can get to the modal */ +.body-overlayed a, +.body-overlayed input, +.body-overlayed button { + visibility: hidden; +} + +.body-overlayed #sbox-window a, +.body-overlayed #sbox-window input, +.body-overlayed #sbox-window button { + visibility: visible; +} + +/** + * Admin Form Styles + */ + +/* For elements that aren't to be seen by users unless the user does something + * like clicking on a header to see the collapsed section. */ +.element-hidden, .hide { + display: none; +} + +.hidebtn { + border: 0 !important; + padding: 0 !important; + margin: 0; + width: 0; + height: 0; +} + +/* For elements that aren't to be seen by visual users but do need to be read by screenreaders. + * Cannot be used for elements that can get focus such as links and form elements */ +.element-invisible, .hidelabeltxt { + height: 0; + overflow: hidden; + position: absolute; + padding: 0; + margin: 0; +} + +/* Firefox has issues styling legend so this is a universal fix + for making the legend invisible (i.e. visually it's not there, but screen readers see it */ + +legend.element-invisible { + position: absolute !important; + margin: 0; + padding: 0; + border: 0; + margin-left: -10000px; + font-size: 1px; + height: 0; +} + +fieldset.panelform { + overflow: hidden; + clear: both; +} + +fieldset.adminform label, +fieldset.panelform label, +fieldset.adminform span.faux-label, +fieldset.panelform span.faux-label { + line-height: 2em; + clear: left; + min-width: 12em; + float: left; + margin-left: 10px; + margin-right: 5px; +} + +fieldset.adminform.long label, +fieldset.panelform.long label, +fieldset.adminform.long span.faux-label, +fieldset.panelform.long span.faux-label { + min-width: 18em; +} + +fieldset.adminform fieldset.radio label, +fieldset.panelform fieldset.radio label, +fieldset.adminform fieldset.radio span.faux-label, +fieldset.panelform fieldset.radio span.faux-label { + margin-left: 0; +} + +fieldset.adminform input, fieldset.adminform span.faux-input, fieldset.adminform textarea, fieldset.adminform select, fieldset.adminform img, fieldset.adminform button, +fieldset.panelform input, fieldset.panelform span.faux-input, fieldset.panelform textarea, fieldset.panelform select, fieldset.panelform img, fieldset.panelform button { + float: left; + margin: 5px 5px 5px 0; + width: auto; +} + +/* -------- Batch Section ---------- */ +fieldset.batch { + margin: 20px 10px 10px 10px; + padding: 10px; +} + +fieldset.batch label { + margin: 5px; + min-width: 40px; +} + +fieldset.batch button { + margin: 3px; +} + +fieldset#batch-choose-action { + clear: left; + border: 0 none; +} + +fieldset.batch label { + float: left; + clear: none; +} + +fieldset label#batch-choose-action-lbl { + clear: left; + margin-top: 15px; +} + +label#batch-language-lbl, +label#batch-user-lbl { + clear: left; + margin-right: 10px; + margin-top: 15px; +} + +select#batch-language-id, +select#batch-user-id { + margin-top: 15px; +} + +select#batch-category-id, +select#batch-position-id, +select#batch-menu-id { + margin-right: 30px; +} + +fieldset.batch select, fieldset.batch input, fieldset.batch img, fieldset.batch button { + float: left; +} + +label#batch-access-lbl, +label#batch-client-lbl { + margin-right: 10px; +} + +div#jform_ordering { + font-size: 1.091em; + margin-top: 3px; +} + +/* Banner edit */ +#jform_impmade, #jform_clicks { + width: 30px; +} + +fieldset.panelform label#jform-imp { + min-width: 3em; + font-size: 1.091em; +} + +fieldset.adminform input#jform_clickurl { + width: 20em; +} + +/** + * ACL STYLES relocated from com_users/media/grid.css + */ + +a.move_up { + display: inline-block; + height: 16px; + text-indent: -1000em; + width: 16px; +} + +span.move_up { + display: inline-block; + height: 16px; + width: 16px; +} + +a.move_down { + display: inline-block; + height: 16px; + text-indent: -1000em; + width: 16px; +} + +span.move_down { + display: inline-block; + height: 16px; + width: 16px; +} + +a.grid_false { + display: inline-block; + height: 16px; + text-indent: -1000em; + width: 16px; +} + +a.grid_true { + display: inline-block; + height: 16px; + text-indent: -1000em; + width: 16px; +} + +a.grid_trash { + display: inline-block; + height: 16px; + text-indent: -1000em; + width: 16px; +} + +/** + * ACL PANEL STYLES + */ +div.acl-options { + width: 100%; +} + +/* All Tabs */ +table.aclsummary-table, +table.aclmodify-table { + border-collapse: collapse; + width: 100%; + font-size: 1.091em; +} + +td.col1 { + font-size: 1.091em; + text-align: left; + padding: 4px; +} + +table.aclsummary-table caption, +table.aclmodify-table caption { + display: none; +} + +/* Summary Tab */ +table.aclsummary-table th.col1 { + width: 25%; +} + +table.aclsummary-table th.col2, +table.aclsummary-table th.col3, +table.aclsummary-table th.col4, +table.aclsummary-table th.col5, +table.aclsummary-table th.col6 { + width: 15%; + vertical-align: bottom; + text-align: center; +} + +/* Icons (background images moved to color css files */ +span.icon-16-unset, +span.icon-16-allowed, +span.icon-16-denied, +span.icon-16-locked { + padding-left: 18px; +} + +label.icon-16-allow, +label.icon-16-deny, +a.icon-16-allow, +a.icon-16-deny, +a.icon-16-allowinactive, +a.icon-16-denyinactive { + display: block; + height: 16px; + width: 16px; + margin: 0 auto; +} + +label.icon-16-allow { + text-indent: -9999em; + position: relative; + left: 40%; +} + +label.icon-16-deny { + text-indent: -9999em; + position: relative; + left: 40%; +} + +/* Create, Edit, Edit State & Delete Tabs */ +table.aclmodify-table th.col2, +table.aclmodify-table th.col3, +table.aclmodify-table th.col4 { + width: 20%; + vertical-align: bottom; + text-align: center; +} + +table.aclmodify-table select { + margin: 1px; +} + +table.aclsummary-table td label, +table.aclmodify-table td label { + min-width: 20px; +} + +/* ACL footer/legend */ +ul.acllegend { + list-style: none; + font-size: 1.091em; + padding-bottom: 10px; +} + +ul.acllegend li { + display: block; + float: left; + padding-right: 20px; + margin: 15px 0 15px 10px; +} + +ul.acllegend li.acl-allowed { + padding-left: 20px; + padding-right: 10px; +} + +ul.acllegend li.acl-denied { + padding-left: 20px; + padding-right: 20px; +} + +ul.acllegend li.acl-editgroups { + padding-right: 10px; +} + +ul.acllegend li.acl-resetbtn { + padding-right: 0; +} + +li.acl-editgroups, +li.acl-resetbtn { + display: block; + float: left; + -moz-border-radius: 3px; + -webkit-border-radius: 3px; + border-radius: 3px; +} + +li.acl-editgroups a, +li.acl-resetbtn a { + padding: 6px; + cursor: default; +} + +li.acl-editgroups a:hover, +li.acl-resetbtn a:hover, +li.acl-editgroups a:focus, +li.acl-resetbtn a:focus { + text-decoration: none; + cursor: default; +} + +li.acl-editgroups:hover, +li.acl-resetbtn:hover, +li.acl-editgroups:focus, +li.acl-resetbtn:focus { + text-decoration: none; + cursor: default; +} + +table#acl-config { + width: 100%; + margin-top: 15px; +} + +table#acl-config th, +table#acl-config td { + height: 2em; + background: #f9fade; + text-align: center; + vertical-align: middle; +} + +table#acl-config th.acl-groups { + padding-left: 8px; + font-weight: bold; + text-align: left; +} + +table#acl-config th.acl-groups span.gi { + margin-right: 2px; +} + +table#acl-config td { + width: 9em; +} + +table#acl-config td select { + float: none; +} + +.acl-action { + font-size: 1.091em; + margin: auto 0; +} + +.acl-groups { + font-size: 1.091em; + font-weight: normal; +} + +label#jform_rules-lbl { + float: none; + white-space: nowrap; + display: none; + visibility: hidden; +} + +label#jform_filters-lbl { + float: none; + white-space: nowrap; + display: none; + visibility: hidden; +} + +/** +* Options modal- config +*/ +ul.config-option-list, +ul.config-option-list li { + margin: 0; + padding: 0; + list-style: none; +} + +ul.config-option-list fieldset { + margin: 0; + padding-left: 0; + padding-right: 0; +} + +/* * +* Permission Rules +*/ +#permissions-sliders { + margin-top: 15px; +} + +#permissions-sliders ul#rules, +#permissions-sliders ul#rules ul { + margin: 0 !important; + padding: 0 !important; + list-style-type: none; +} + +#permissions-sliders ul#rules li { + margin: 0; + padding: 0; +} + +#permissions-sliders ul#rules table.group-rules { + border-collapse: collapse; + margin: 5px; + width: 100%; +} + +#permissions-sliders ul#rules table.group-rules td { + padding: 4px; + vertical-align: middle; + text-align: left; + overflow: hidden; +} + +#permissions-sliders ul#rules table.group-rules th { + font-size: 1.2em; + overflow: hidden; + font-weight: bold; +} + +#permissions-sliders .panel { + margin-bottom: 3px; + margin-left: 0; + border: 0; +} + +#permissions-sliders p.rule-desc { + font-size: 1.1em; +} + +#permissions-sliders div.rule-notes { + font-size: 1.1em; +} + +ul#rules table.group-rules td label { + margin: 0 !important; + line-height: 1.1em; +} + +ul#rules table.group-rules td span { + font-size: 1.1em; + padding-bottom: 4px; +} + +ul#rules table.group-rules td span span { + font-size: 100%; +} + +table.group-rules td select { + margin: 0 !important; +} + +#permissions-sliders ul#rules .mypanel { + padding: 0; + line-height: 1.3em; +} + +#permissions-sliders .mypanel table.group-rules caption { + font-size: 1.3em; +} + +#permissions-sliders ul#rules { + padding: 5px; +} + +#permissions-sliders ul#rules table.group-rules th { + text-align: left; + padding: 4px; +} + +#permissions-sliders ul#rules table.group-rules td label { + min-width: 1em; +} + +#permissions-sliders .pane-toggler span { + padding-left: 20px; +} + +#permissions-sliders .pane-toggler-down span { + padding-left: 20px; +} + +#permissions-sliders .pane-toggler-down span.level, +#permissions-sliders .pane-toggler span.level { + padding: 0; +} + +/* + * Debug styles + */ + +.swatch { + text-align: center; + padding: 0 15px 0 15px; +} + +/* Tab changes for accessibility */ +dl.tabs dt h3 { + padding: 0; + font-size: 100%; +} + +/** + * Helpmenus + */ +ul.helpmenu li { + float: right; + margin: 10px; + padding: 0; + list-style-type: none; + font-weight: bold; +} + +/* CSS file for Accessible Admin Menu + * based on Matt Carrolls' son of suckerfish + * with javascript by Bill Tomczak + */ + +/* Note: set up the font-size on the id and used 100% on the elements. + If ul/li/a are different ems, then the shifting back via non-js keyboard + doesn't work properly */ + +/** + * Menu Styling + */ +#menu { + /* this is on the main ul */ + position: relative; + z-index: 100; + padding: 0; + margin: 0; + width: 100%; + list-style: none; + font-size: 1.2em; + font-weight: bold; +} + +#menu ul { + /* all lists */ + padding: 0; + margin: 0; + list-style: none; + font-size: 100%; +} + +#menu ul li.separator { + margin-bottom: 1em; +} + +#menu a { + padding: 0.35em 2.5em 0.35em 2em; + vertical-align: middle; + display: block; + /* width: 10em; */ + text-decoration: none; + font-size: 100%; +} + +#menu li { + /* all list items */ + float: left; + /* width: 12em; width needed or else Opera goes nuts */ + font-size: 100%; +} + +#menu li a { + white-space: nowrap; +} + +#menu li li a { + margin-bottom: 1px; + margin-top: 1px; + width: 10em; +} + +#menu li.disabled a:hover, +#menu li.disabled a:focus, +#menu li.disabled a { + cursor: default; +} + +#menu li ul { + /* second-level lists */ + position: absolute; + width: 16em; + margin-left: -1000em; + /* using left instead of display to hide menus because display: none isn't read by screen readers */ +} + +#menu li li { + /* second-level row */ + border: none; + width: 16em; +} + +#menu li ul ul { + /* third-and-above-level lists */ + margin: -2.3em 0 0 -1000em; + /* top margin is equal to parent line height+bottom padding */ +} + +#menu li:hover ul ul, #menu li.sfhover ul ul { + margin-left: -1000em; +} + +#menu li:hover ul, #menu li.sfhover ul { + /* lists nested under hovered list items */ + margin-left: 0; +} + +#menu li li:hover ul, #menu li li.sfhover ul { + margin-left: 16em; +} + +/** + * Menu Icons + * These icons are used on the Administrator menu + * The classes are constructed dynamically when the menu is generated + */ +[class^="menu-"], +[class*=" menu-"] { + background-position: 3px 50% !important; +} +.menu-archive { + background-image: url(../images/menu/icon-16-archive.png); +} + +.menu-article { + background-image: url(../images/menu/icon-16-article.png); +} + +.menu-associations { + background-image: url(../images/menu/icon-16-assoc.png); +} + +.menu-banners { + background-image: url(../images/menu/icon-16-banner.png); +} + +.menu-banners-clients { + background-image: url(../images/menu/icon-16-banner-client.png); +} + +.menu-banners-tracks { + background-image: url(../images/menu/icon-16-banner-tracks.png); +} + +.menu-banners-cat { + background-image: url(../images/menu/icon-16-banner-categories.png); +} + +.menu-category { + background-image: url(../images/menu/icon-16-category.png); +} + +.menu-checkin { + background-image: url(../images/menu/icon-16-checkin.png); +} + +.menu-clear { + background-image: url(../images/menu/icon-16-clear.png); +} + +.menu-component { + background-image: url(../images/menu/icon-16-component.png); +} + +.menu-config { + background-image: url(../images/menu/icon-16-config.png); +} + +.menu-contact { + background-image: url(../images/menu/icon-16-contacts.png); +} + +.menu-contact-cat { + background-image: url(../images/menu/icon-16-contacts-categories.png); +} + +.menu-content { + background-image: url(../images/menu/icon-16-content.png); +} + +.menu-cpanel { + background-image: url(../images/menu/icon-16-cpanel.png); +} + +.menu-default { + background-image: url(../images/menu/icon-16-default.png); +} + +.menu-featured { + background-image: url(../images/menu/icon-16-featured.png); +} + +.menu-fields { + background-image: url(../images/menu/icon-16-puzzle.png); +} + +.menu-groups { + background-image: url(../images/menu/icon-16-groups.png); +} + +.menu-help { + background-image: url(../images/menu/icon-16-help.png); +} + +.menu-help-this { + background-image: url(../images/menu/icon-16-help-this.png); +} + +.menu-help-forum { + background-image: url(../images/menu/icon-16-help-forum.png); +} + +.menu-help-docs { + background-image: url(../images/menu/icon-16-help-docs.png); +} + +.menu-help-jed { + background-image: url(../images/menu/icon-16-help-jed.png); +} + +.menu-help-jrd { + background-image: url(../images/menu/icon-16-help-jrd.png); +} + +.menu-help-community { + background-image: url(../images/menu/icon-16-help-community.png); +} + +.menu-help-security { + background-image: url(../images/menu/icon-16-help-security.png); +} + +.menu-help-dev { + background-image: url(../images/menu/icon-16-help-dev.png); +} + +.menu-help-shop { + background-image: url(../images/menu/icon-16-help-shop.png); +} + +.menu-info { + background-image: url(../images/menu/icon-16-info.png); +} + +.menu-install { + background-image: url(../images/menu/icon-16-install.png); +} + +.menu-joomlaupdate { + background-image: url(../images/menu/icon-16-install.png); +} + +.menu-language { + background-image: url(../images/menu/icon-16-language.png); +} + +.menu-levels { + background-image: url(../images/menu/icon-16-levels.png); +} + +.menu-logout { + background-image: url(../images/menu/icon-16-logout.png); +} + +.menu-maintenance { + background-image: url(../images/menu/icon-16-maintenance.png); +} + +.menu-massmail { + background-image: url(../images/menu/icon-16-massmail.png); +} + +.menu-media { + background-image: url(../images/menu/icon-16-media.png); +} + +.menu-menu { + background-image: url(../images/menu/icon-16-menu.png); +} + +.menu-menumgr { + background-image: url(../images/menu/icon-16-menumgr.png); +} + +.menu-messages { + background-image: url(../images/menu/icon-16-messaging.png); +} + +.menu-messages-add { + background-image: url(../images/menu/icon-16-new-privatemessage.png); +} + +.menu-messages-read { + background-image: url(../images/menu/icon-16-messages.png); +} + +.menu-module { + background-image: url(../images/menu/icon-16-module.png); +} + +.menu-newarticle { + background-image: url(../images/menu/icon-16-newarticle.png); +} + +.menu-newcategory { + background-image: url(../images/menu/icon-16-newcategory.png); +} + +.menu-newgroup { + background-image: url(../images/menu/icon-16-newgroup.png); +} + +.menu-newlevel { + background-image: url(../images/menu/icon-16-newlevel.png); +} + +.menu-newuser { + background-image: url(../images/menu/icon-16-newuser.png); +} + +.menu-plugin { + background-image: url(../images/menu/icon-16-plugin.png); +} + +.menu-profile { + background-image: url(../images/menu/icon-16-user.png); +} + +.menu-purge { + background-image: url(../images/menu/icon-16-purge.png); +} + +.menu-readmess { + background-image: url(../images/menu/icon-16-readmess.png); +} + +.menu-section { + background-image: url(../images/menu/icon-16-section.png); +} + +.menu-static { + background-image: url(../images/menu/icon-16-static.png); +} + +.menu-stats { + background-image: url(../images/menu/icon-16-stats.png); +} + +.menu-themes { + background-image: url(../images/menu/icon-16-themes.png); +} + +.menu-trash { + background-image: url(../images/menu/icon-16-trash.png); +} + +.menu-user { + background-image: url(../images/menu/icon-16-user.png); +} + +.menu-user-note { + background-image: url(../images/menu/icon-16-user-note.png); +} + +.menu-delete { + background-image: url(../images/menu/icon-16-delete.png); +} + +.menu-help-trans { + background-image: url(../images/menu/icon-16-help-trans.png); +} + +.menu-newsfeeds { + background-image: url(../images/menu/icon-16-newsfeeds.png); +} + +.menu-newsfeeds-cat { + background-image: url(../images/menu/icon-16-newsfeeds-cat.png); +} + +.menu-redirect { + background-image: url(../images/menu/icon-16-redirect.png); +} + +.menu-search { + background-image: url(../images/menu/icon-16-search.png); +} + +.menu-finder { + background-image: url(../images/menu/icon-16-search.png); +} + +.menu-weblinks { + background-image: url(../images/menu/icon-16-links.png); +} + +.menu-weblinks-cat { + background-image: url(../images/menu/icon-16-links-cat.png); +} + +.menu-tags { + background-image: url(../images/menu/icon-16-tags.png); +} + +.menu-postinstall { + background-image: url(../images/menu/icon-16-generic.png); +} +.icon-32-cog { + background-image: url(../images/toolbar/icon-32-cog.png); +} + +/** + * Extra positioning rules for limited noscript keyboard accessibility + * need the backgrounds here to keep the background as the nav background + * since it is overlaying other content. + * Using margin-left instead of left so that can move back without javascript + * display downlevel ul + */ +#menu li a:focus+ul { + margin-left: 0; +} + +#menu li li a:focus+ul { + margin-left: 1016em; +} + +/* bring back the focus elements into view */ +#menu li li a:focus { + margin-left: 1000em; + width: 10em; +} + +#menu li li li a:focus { + margin-left: 2016em; + width: 10em; +} + +#menu li:hover a:focus, #menu li.sfhover a.sffocus { + margin-left: 0; +} + +#menu li li:hover a:focus+ul, #menu li li.sfhover a.sffocus+ul { + margin-left: 16em; +} + +/** + * Sidebar styling + */ +#sidebar { + float:left; + margin: 15px 5px; +} + +/** + * Submenu styling + */ +#submenu { + list-style: none; + padding: 0; + margin: 0; + /* border-bottom plus padding-bottom is the technique */ + padding-bottom: 2.5em; + line-height: 2em; +} + +#submenu ul, #submenu li { + display: inline; + list-style-type: none; + margin: 0; + padding: 0; +} + +#submenu li, #submenu span.nolink { + float: left; + font-weight: bold; + margin-right: 8px; + padding: 2px 10px 2px 10px; + text-decoration: none; + cursor: pointer; + -moz-border-radius-topright: 3px; + -moz-border-radius-topleft: 3px; + -webkit-border-top-right-radius: 3px; + -webkit-border-top-left-radius: 3px; + border-top-right-radius: 3px; + border-top-left-radius: 3px; +} + +#submenu span.nolink { + color: #999; +} + +#submenu li.active, #submenu span.nolink.active { + cursor: default; +} + +#submenu li.active a, #submenu span.nolink.active, #submenu li a:hover, #submenu li a:focus { + text-decoration: none; +} + +/* -- CUSTOM LANG STRINGS STYLES ----------- */ + +.red { + font-weight: bold; + color: #c00; +} + +/* -- OTHER STYLES ----------- */ + +.pre_message { + font-size: 1.3em; +} + +/* -- Update check badges -- */ +span.update-badge { + background-image: -moz-linear-gradient(center bottom, #FF0000 41%, #FC7E7E 79%); + background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0.41, rgb(255, 0, 0)), color-stop(0.79, rgb(252, 126, 126))); + border: 2px solid white; + border-radius: 1.5em 1.5em 1.5em 1.5em; + color: white; + display: block; + float: left; + font-size: 1.2em; + font-weight: bold; + height: 1.2em; + left: 60px; + min-width: 1em; + padding: 0 0.1em 0; + position: relative; + top: -88px; +} + +/* User Notes */ +.unotes ul, .unotes ol { + list-style: none; + list-style-position: inside; + padding-left: 0; + padding-right: 0; + +} + +.unotes div.utitle { + padding: 10px; + float: left; + font-size: 1.2em; + line-height: 1.2em; +} + +.unotes h4 { + margin-top: 0; + margin-bottom: 0; + font-size: 1.3em; +} + +.unotes .ubody { + padding-left: 10px; + padding-right: 10px; + font-size: 1.2em; + line-height: 1.5em; +} + +.unotes p { + padding-bottom: 10px; +} + +/* com-install styling */ +div#database-sliders { + margin: 10px; +} + +fieldset.uploadform { + margin-top: 10px; + margin-bottom: 10px; + min-height: 200px; +} + +/* Installer Database */ +#installer-database, #installer-discover, #installer-update, #installer-warnings { + margin-top: 10px; +} + +#installer-database #sidebar { + float: none +} + +#installer-database p.warning { + padding-left: 20px; +} + +#installer-database p.nowarning { + padding-left: 20px; +} + +/* Spinner */ +.joomlaupdate_spinner { + float: left; + margin-right: 15px; +} + +.btn-group { + position: relative; + display: inline-block; +} + +.btn-group + .btn-group { + margin-left: 5px; +} + +.btn-group > .btn { + position: relative; + float: left; + margin-left: -1px; +} + +.icon-48-cpanel { + height: 50px; + width: 50%; +} + +.well { + min-height: 20px; + padding: 19px; + margin-bottom: 20px; + background-color: #f5f5f5; + border: 1px solid #eee; + border: 1px solid rgba(0, 0, 0, 0.05); + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); +} + +.well blockquote { + border-color: #ddd; + border-color: rgba(0, 0, 0, 0.15); +} + +.well-large { + padding: 24px; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} + +.well-small { + padding: 9px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} + +/* Striped */ +.list-striped, +.row-striped { + list-style: none; + line-height: 18px; + text-align: left; + vertical-align: middle; + border-top: 1px solid #dddddd; + margin-left: 0; + font-size: 1.2em; + padding: 9px; +} + +.list-striped li, +.list-striped dd, +.row-striped .row, +.row-striped .row-fluid { + border-bottom: 1px solid #dddddd; + padding: 8px; +} + +.list-striped li:nth-child(odd), +.list-striped dd:nth-child(odd), +.row-striped .row:nth-child(odd), +.row-striped .row-fluid:nth-child(odd) { + background-color: #f9f9f9; +} + +.list-striped li:hover, +.list-striped dd:hover, +.row-striped .row:hover, +.row-striped .row-fluid:hover { + background-color: #f5f5f5; +} + +.row-striped .row-fluid { + width: 100%; + box-sizing: border-box; +} + +.row-striped .row-fluid [class*="span"] { + min-height: 10px; +} + +.alert { + padding: 8px 35px 8px 14px; + margin-bottom: 18px; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); + background-color: #fcf8e3; + border: 1px solid #fbeed5; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + color: #c09853; + font-size: 120%; +} + +.alert-heading { + color: inherit; +} + +.alert .close { + position: relative; + right: -30px; + top: -5px; + line-height: 18px; + float: right; + font-size: 20px; + font-weight: bold; +} + +.alert-success { + background-color: #dff0d8; + border-color: #d6e9c6; + color: #468847; +} + +.alert-danger, +.alert-error { + background-color: #f2dede; + border-color: #eed3d7; + color: #b94a48; +} + +.alert-info { + background-color: #d9edf7; + border-color: #bce8f1; + color: #3a87ad; +} + +.alert-block { + padding-top: 14px; + padding-bottom: 14px; +} + +.alert-block > p, +.alert-block > ul { + margin-bottom: 0; +} + +.alert-block p + p { + margin-top: 5px; +} + +.btn-group > .btn:hover, .btn-group > .btn:focus, .btn-group > .btn:active, .btn-group > .btn.active { + z-index: 2; +} + +.btn-group > .btn { + position: relative; + float: left; + margin-left: -1px; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +table { + max-width: 100%; + background-color: transparent; + border-collapse: collapse; + border-spacing: 0; +} + +.table { + width: 100%; + margin-bottom: 18px; +} + +.tab-content > .tab-pane, +.pill-content > .pill-pane { + display: none; +} + +.tab-content > .active, +.pill-content > .active { + display: block; +} + +.tabs-below > .nav-tabs { + border-top: 1px solid #ddd; +} + +#status .btn-toolbar, #status p { + margin: 0px; +} + +.navbar .btn-group { + margin: 0; + padding: 5px 5px 6px; +} + +/** + * Media + */ +.media .btn { + margin: 10px 20px; +} + +.thumbnails > li { + list-style: none outside none; + float: left; + margin-bottom: 18px; + margin-left: 20px; +} + +#mediamanager-form { + margin: 10px; +} +.is-tagbox { + float: left; +} + +/* Item associations */ +.item-associations { + margin: 0; +} +.item-associations li { + list-style: none; + display: inline-block; + margin: 0 0 3px 0; +} +.item-associations li a, +table.adminlist .item-associations li a { + color: #ffffff; +} + +.hidden { + display: none; + visibility: hidden; +} + +// Bootstrap Tooltips (need to load last, something is overriding these styles in the CSS, debug later ;-) ) +@import "../../../../media/jui/less/tooltip.less"; + +.tooltip { + max-width: 400px; +} +.tooltip-inner { + max-width: none; + text-align: left; + text-shadow: none; +} +th .tooltip-inner { + font-weight: normal; +} +.tooltip.hasimage { + opacity: 1; +} +fieldset.panelform .tooltip img { + float: none; + margin: 0; +} +//Toggle editor button +div.toggle-editor { + float: right; +} + +.text-left { + text-align: left; +} +.text-right { + text-align: right; +} +.text-center { + text-align: center; +} +.module-edit { + display: inline-block; +} +.break-word { + word-break: break-all; + word-wrap: break-word; +} +.muted { + color: #999; +} +/* Popover minimum height - overwrite bootstrap default */ +.popover-content { + min-height: 33px; +} \ No newline at end of file diff --git a/Sites/pages/administrator/templates/hathor/less/variables.less b/Sites/pages/administrator/templates/hathor/less/variables.less new file mode 100644 index 00000000..11e990a1 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/less/variables.less @@ -0,0 +1,216 @@ +// Variables.less +// Variables to customize the look and feel of Bootstrap +// ----------------------------------------------------- + + + +// GLOBAL VALUES +// -------------------------------------------------- + + +// Grays +// ------------------------- +@black: #000; +@grayDarker: #222; +@grayDark: #333; +@gray: #555; +@grayLight: #999; +@grayLighter: #eee; +@white: #fff; + + +// Accent colors +// ------------------------- +@blue: #049cdb; +@blueDark: #0064cd; +@green: #46a546; +@red: #9d261d; +@yellow: #ffc40d; +@orange: #f89406; +@pink: #c3325f; +@purple: #7a43b6; + + +// Scaffolding +// ------------------------- +@bodyBackground: @white; +@textColor: @grayDark; + + +// Links +// ------------------------- +@linkColor: #08c; +@linkColorHover: darken(@linkColor, 15%); + + +// Typography +// ------------------------- +@sansFontFamily: "Helvetica Neue", Helvetica, Arial, sans-serif; +@serifFontFamily: Georgia, "Times New Roman", Times, serif; +@monoFontFamily: Menlo, Monaco, Consolas, "Courier New", monospace; + +@baseFontSize: 13px; +@baseFontFamily: @sansFontFamily; +@baseLineHeight: 18px; +@altFontFamily: @serifFontFamily; + +@headingsFontFamily: inherit; // empty to use BS default, @baseFontFamily +@headingsFontWeight: bold; // instead of browser default, bold +@headingsColor: inherit; // empty to use BS default, @textColor + + +// Tables +// ------------------------- +@tableBackground: transparent; // overall background-color +@tableBackgroundAccent: #f9f9f9; // for striping +@tableBackgroundHover: #f5f5f5; // for hover +@tableBorder: #ddd; // table and cell border + + +// Buttons +// ------------------------- +@btnBackground: @white; +@btnBackgroundHighlight: darken(@white, 10%); +@btnBorder: #ccc; + +@btnPrimaryBackground: #2384d3; +@btnPrimaryBackgroundHighlight: #15497c; + +@btnInfoBackground: #5bc0de; +@btnInfoBackgroundHighlight: #2f96b4; + +@btnSuccessBackground: #62c462; +@btnSuccessBackgroundHighlight: #51a351; + +@btnWarningBackground: lighten(@orange, 15%); +@btnWarningBackgroundHighlight: @orange; + +@btnDangerBackground: #ee5f5b; +@btnDangerBackgroundHighlight: #bd362f; + +@btnInverseBackground: @gray; +@btnInverseBackgroundHighlight: @grayDarker; + + +// Forms +// ------------------------- +@inputBackground: @white; +@inputBorder: #ccc; +@inputBorderRadius: 3px; +@inputDisabledBackground: @grayLighter; +@formActionsBackground: #f5f5f5; + +// Dropdowns +// ------------------------- +@dropdownBackground: @white; +@dropdownBorder: rgba(0,0,0,.2); +@dropdownLinkColor: @grayDark; +@dropdownLinkColorHover: @white; +@dropdownLinkBackgroundHover: @linkColor; +@dropdownDividerTop: #e5e5e5; +@dropdownDividerBottom: @white; + + + +// COMPONENT VARIABLES +// -------------------------------------------------- + +// Z-index master list +// ------------------------- +// Used for a bird's eye view of components dependent on the z-axis +// Try to avoid customizing these :) +@zindexDropdown: 1000; +@zindexTooltip: 1020; +@zindexFixedNavbar: 1030; +@zindexModalBackdrop: 1040; +@zindexModal: 1050; +@zindexPopover: 1060; + +// Sprite icons path +// ------------------------- +@iconSpritePath: "../img/glyphicons-halflings.png"; +@iconWhiteSpritePath: "../img/glyphicons-halflings-white.png"; + + +// Input placeholder text color +// ------------------------- +@placeholderText: @grayLight; + + +// Hr border color +// ------------------------- +@hrBorder: @grayLighter; + + +// Navbar +// ------------------------- +@navbarHeight: 40px; +@navbarBackground: @grayDarker; +@navbarBackgroundHighlight: @grayDark; + +@navbarText: @grayLight; +@navbarLinkColor: @grayLight; +@navbarLinkColorHover: @white; +@navbarLinkColorActive: @navbarLinkColorHover; +@navbarLinkBackgroundHover: transparent; +@navbarLinkBackgroundActive: @navbarBackground; + +@navbarSearchBackground: lighten(@navbarBackground, 25%); +@navbarSearchBackgroundFocus: @white; +@navbarSearchBorder: darken(@navbarSearchBackground, 30%); +@navbarSearchPlaceholderColor: #ccc; +@navbarBrandColor: @navbarLinkColor; + + +// Hero unit +// ------------------------- +@heroUnitBackground: @grayLighter; +@heroUnitHeadingColor: inherit; +@heroUnitLeadColor: inherit; + + +// Form states and alerts +// ------------------------- +@warningText: #c09853; +@warningBackground: #fcf8e3; +@warningBorder: darken(spin(@warningBackground, -10), 3%); + +@errorText: #b94a48; +@errorBackground: #f2dede; +@errorBorder: darken(spin(@errorBackground, -10), 3%); + +@successText: #468847; +@successBackground: #dff0d8; +@successBorder: darken(spin(@successBackground, -10), 5%); + +@infoText: #3a87ad; +@infoBackground: #d9edf7; +@infoBorder: darken(spin(@infoBackground, -10), 7%); + + + +// GRID +// -------------------------------------------------- + +// Default 940px grid +// ------------------------- +@gridColumns: 12; +@gridColumnWidth: 60px; +@gridGutterWidth: 20px; +@gridRowWidth: (@gridColumns * @gridColumnWidth) + (@gridGutterWidth * (@gridColumns - 1)); + +// Fluid grid +// ------------------------- +@fluidGridColumnWidth: 6.382978723%; +@fluidGridGutterWidth: 2.127659574%; + + +// Login +// ------------------------- +@loginBackground: #142849; +@loginBackgroundHighlight: #165387; + +// Header +// ------------------------- +@headerBackground: #1a3867; +@headerBackgroundHighlight: #17568c; \ No newline at end of file diff --git a/Sites/pages/administrator/templates/hathor/login.php b/Sites/pages/administrator/templates/hathor/login.php new file mode 100644 index 00000000..04ee6de0 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/login.php @@ -0,0 +1,142 @@ +setScheme(((int) $app->get('force_ssl', 0) === 2) ? 'https' : 'http'); + +// Output as HTML5 +$this->setHtml5(true); + +// jQuery needed by template.js +JHtml::_('jquery.framework'); + +// Add template js +JHtml::_('script', 'template.js', array('version' => 'auto', 'relative' => true)); + +// Add html5 shiv +JHtml::_('script', 'jui/html5.js', array('version' => 'auto', 'relative' => true, 'conditional' => 'lt IE 9')); + +// Load optional RTL Bootstrap CSS +JHtml::_('bootstrap.loadCss', false, $this->direction); + +// Load system style CSS +JHtml::_('stylesheet', 'templates/system/css/system.css', array('version' => 'auto')); + +// Loadtemplate CSS +JHtml::_('stylesheet', 'template.css', array('version' => 'auto', 'relative' => true)); + +// Load additional CSS styles for colors +if (!$this->params->get('colourChoice')) +{ + $colour = 'standard'; +} +else +{ + $colour = htmlspecialchars($this->params->get('colourChoice'), ENT_COMPAT, 'UTF-8'); +} + +JHtml::_('stylesheet', 'colour_' . $colour . '.css', array('version' => 'auto', 'relative' => true)); + +// Load additional CSS styles for rtl sites +if ($this->direction === 'rtl') +{ + JHtml::_('stylesheet', 'template_rtl.css', array('version' => 'auto', 'relative' => true)); + JHtml::_('stylesheet', 'colour_' . $colour . '_rtl.css', array('version' => 'auto', 'relative' => true)); +} + +// Load additional CSS styles for bold Text +if ($this->params->get('boldText')) +{ + JHtml::_('stylesheet', 'boldtext.css', array('version' => 'auto', 'relative' => true)); +} + +// Load specific language related CSS +JHtml::_('stylesheet', 'administrator/language/' . $lang->getTag() . '/' . $lang->getTag() . '.css', array('version' => 'auto')); + +// Load custom.css +JHtml::_('stylesheet', 'custom.css', array('version' => 'auto', 'relative' => true)); + +// IE specific +JHtml::_('stylesheet', 'ie8.css', array('version' => 'auto', 'relative' => true, 'conditional' => 'IE 8')); +JHtml::_('stylesheet', 'ie7.css', array('version' => 'auto', 'relative' => true, 'conditional' => 'IE 7')); + +// Logo file +if ($this->params->get('logoFile')) +{ + $logo = JUri::root() . $this->params->get('logoFile'); +} +else +{ + $logo = $this->baseurl . '/templates/' . $this->template . '/images/logo.png'; +} +?> + + + + + + +
        + + + +
        + + + +
        +
        +
        + + + + diff --git a/Sites/pages/administrator/templates/hathor/postinstall/hathormessage.php b/Sites/pages/administrator/templates/hathor/postinstall/hathormessage.php new file mode 100644 index 00000000..40ac3e74 --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/postinstall/hathormessage.php @@ -0,0 +1,134 @@ +authorise('core.edit.state', 'com_templates')) + { + $query = $db->getQuery(true) + ->select('template') + ->from($db->quoteName('#__template_styles')) + ->where($db->quoteName('home') . ' = ' . $db->quote('1')) + ->where($db->quoteName('client_id') . ' = 1'); + + // Get the global setting about the default template + $globalTemplate = $db->setQuery($query)->loadResult(); + } + + // Get the current user admin style + $adminstyle = $user->getParam('admin_style'); + + if ($adminstyle) + { + $query = $db->getQuery(true) + ->select('template') + ->from($db->quoteName('#__template_styles')) + ->where($db->quoteName('id') . ' = ' . (int) $adminstyle) + ->where($db->quoteName('client_id') . ' = 1'); + + // Get the template name associated to the admin style + $template = $db->setquery($query)->loadResult(); + } + + if (($globalTemplate != 'hathor') && ($template != 'hathor')) + { + // Hathor is not default not global and not in the user so no message needed + return false; + } + + // Hathor is default please add the message + return true; +} + +/** + * Set the default backend template back to isis if you are allowed to do this + * This also sets the current user setting to isis if not done yet + * + * @return void + * + * @since 3.7 + */ +function hathormessage_postinstall_action() +{ + $db = JFactory::getDbo(); + $user = JFactory::getUser(); + + $query = $db->getQuery(true) + ->select(array('id', 'title')) + ->from($db->quoteName('#__template_styles')) + ->where($db->quoteName('template') . ' = "isis"') + ->where($db->quoteName('client_id') . ' = 1'); + + $isisStyleId = $db->setQuery($query)->loadColumn(); + $isisStyleName = $db->setQuery($query)->loadColumn(1); + $adminstyle = $user->getParam('admin_style'); + + // The user uses the system setting so no need to change that. + if ($adminstyle) + { + $query = $db->getQuery(true) + ->select('template') + ->from($db->quoteName('#__template_styles')) + ->where($db->quoteName('id') . ' = ' . (int) $adminstyle) + ->where($db->quoteName('client_id') . ' = 1'); + + $template = $db->setQuery($query)->loadResult(); + + // The current user uses hathor + if ($template == 'hathor') + { + $user->setParam('admin_style', $isisStyleId['0']); + $user->save(); + } + } + + // We can only do that if you have edit permissions in com_templates + if ($user->authorise('core.edit.state', 'com_templates')) + { + $query = $db->getQuery(true) + ->update($db->quoteName('#__template_styles')) + ->set($db->quoteName('home') . ' = ' . $db->quote('0')) + ->where($db->quoteName('template') . ' = "hathor"') + ->where($db->quoteName('client_id') . ' = 1'); + + // Execute + $db->setQuery($query)->execute(); + + $query = $db->getQuery(true) + ->update($db->quoteName('#__template_styles')) + ->set($db->quoteName('home') . ' = ' . $db->quote('1')) + ->where($db->quoteName('template') . ' = "isis"') + ->where($db->quoteName('client_id') . ' = 1') + ->where($db->quoteName('id') . ' = ' . $isisStyleId[0]); + + // Execute + $db->setQuery($query)->execute(); + } + + // The postinstall component load the language to late... so we need to make sure it is loaded here. + JFactory::getLanguage()->load('tpl_hathor', JPATH_ADMINISTRATOR, null, false, true); + + // Template was successfully changed to isis + JFactory::getApplication()->enqueueMessage(JText::sprintf('TPL_HATHOR_CHANGED_DEFAULT_TEMPLATE_TO_ISIS', $isisStyleName[0]), 'message'); +} diff --git a/Sites/pages/administrator/templates/hathor/templateDetails.xml b/Sites/pages/administrator/templates/hathor/templateDetails.xml new file mode 100644 index 00000000..67e27a2c --- /dev/null +++ b/Sites/pages/administrator/templates/hathor/templateDetails.xml @@ -0,0 +1,99 @@ + + + + hathor + May 2010 + Andrea Tarr + admin@joomla.org + Copyright (C) 2005 - 2020 Open Source Matters, Inc. All rights reserved. + GNU General Public License version 2 or later; see LICENSE.txt + 3.0.0 + TPL_HATHOR_XML_DESCRIPTION + + component.php + cpanel.php + error.php + favicon.ico + index.php + login.php + LICENSE.txt + templateDetails.xml + template_preview.png + template_thumbnail.png + css + html + images + js + language + + + + menu + submenu + toolbar + title + status + icon + cp_shell + cpanel + login + debug + footer + + + language/en-GB/en-GB.tpl_hathor.ini + language/en-GB/en-GB.tpl_hathor.sys.ini + + + +
        + + + + + + + + + + + + + + + + + + +
        +
        +
        +
        diff --git a/Sites/pages/administrator/templates/hathor/template_preview.png b/Sites/pages/administrator/templates/hathor/template_preview.png new file mode 100644 index 00000000..be57da7c Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/template_preview.png differ diff --git a/Sites/pages/administrator/templates/hathor/template_thumbnail.png b/Sites/pages/administrator/templates/hathor/template_thumbnail.png new file mode 100644 index 00000000..b9b2b49b Binary files /dev/null and b/Sites/pages/administrator/templates/hathor/template_thumbnail.png differ diff --git a/Sites/pages/administrator/templates/isis/component.php b/Sites/pages/administrator/templates/isis/component.php new file mode 100644 index 00000000..e78892ec --- /dev/null +++ b/Sites/pages/administrator/templates/isis/component.php @@ -0,0 +1,59 @@ +setHtml5(true); + +// Add JavaScript Frameworks +JHtml::_('bootstrap.framework'); + +// Add filter polyfill for IE8 +JHtml::_('behavior.polyfill', array('filter'), 'lte IE 9'); + +// Add template js +JHtml::_('script', 'template.js', array('version' => 'auto', 'relative' => true)); + +// Add html5 shiv +JHtml::_('script', 'jui/html5.js', array('version' => 'auto', 'relative' => true, 'conditional' => 'lt IE 9')); + +// Add Stylesheets +JHtml::_('stylesheet', 'template' . ($this->direction === 'rtl' ? '-rtl' : '') . '.css', array('version' => 'auto', 'relative' => true)); + +// Load optional RTL Bootstrap CSS +JHtml::_('bootstrap.loadCss', false, $this->direction); + +// Load specific language related CSS +JHtml::_('stylesheet', 'administrator/language/' . $lang->getTag() . '/' . $lang->getTag() . '.css', array('version' => 'auto')); + +// Load custom.css +JHtml::_('stylesheet', 'custom.css', array('version' => 'auto', 'relative' => true)); + +// Link color +if ($this->params->get('linkColor')) +{ + $this->addStyleDeclaration('a { color: ' . $this->params->get('linkColor') . '; }'); +} +?> + + + + + + + + + + diff --git a/Sites/pages/administrator/templates/isis/cpanel.php b/Sites/pages/administrator/templates/isis/cpanel.php new file mode 100644 index 00000000..c41c8ec7 --- /dev/null +++ b/Sites/pages/administrator/templates/isis/cpanel.php @@ -0,0 +1,12 @@ + li, +ol.inline > li { + display: inline-block; + *display: inline; + *zoom: 1; + padding-left: 5px; + padding-right: 5px; +} +dl { + margin-bottom: 18px; +} +dt, +dd { + line-height: 18px; +} +dt { + font-weight: bold; +} +dd { + margin-left: 9px; +} +.dl-horizontal { + *zoom: 1; +} +.dl-horizontal:before, +.dl-horizontal:after { + display: table; + content: ""; + line-height: 0; +} +.dl-horizontal:after { + clear: both; +} +.dl-horizontal dt { + float: left; + width: 160px; + clear: left; + text-align: right; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} +.dl-horizontal dd { + margin-left: 180px; +} +hr { + margin: 18px 0; + border: 0; + border-top: 1px solid #eee; + border-bottom: 1px solid #fff; +} +abbr[title], +abbr[data-original-title] { + cursor: help; + border-bottom: 1px dotted #999; +} +abbr.initialism { + font-size: 90%; + text-transform: uppercase; +} +blockquote { + padding: 0 0 0 15px; + margin: 0 0 18px; + border-left: 5px solid #eee; +} +blockquote p { + margin-bottom: 0; + font-size: 16.25px; + font-weight: 300; + line-height: 1.25; +} +blockquote small { + display: block; + line-height: 18px; + color: #999; +} +blockquote small:before { + content: '\2014 \00A0'; +} +blockquote.pull-right { + float: right; + padding-right: 15px; + padding-left: 0; + border-right: 5px solid #eee; + border-left: 0; +} +blockquote.pull-right p, +blockquote.pull-right small { + text-align: right; +} +blockquote.pull-right small:before { + content: ''; +} +blockquote.pull-right small:after { + content: '\00A0 \2014'; +} +q:before, +q:after, +blockquote:before, +blockquote:after { + content: ""; +} +address { + display: block; + margin-bottom: 18px; + font-style: normal; + line-height: 18px; +} +code, +pre { + padding: 0 3px 2px; + font-family: Monaco, Menlo, Consolas, "Courier New", monospace; + font-size: 11px; + color: #333; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} +code { + padding: 2px 4px; + color: #d14; + background-color: #f7f7f9; + border: 1px solid #e1e1e8; + white-space: nowrap; +} +pre { + display: block; + padding: 8.5px; + margin: 0 0 9px; + font-size: 12px; + line-height: 18px; + word-break: break-all; + word-wrap: break-word; + white-space: pre; + white-space: pre-wrap; + background-color: #f5f5f5; + border: 1px solid #ccc; + border: 1px solid rgba(0,0,0,0.15); + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} +pre.prettyprint { + margin-bottom: 18px; +} +pre code { + padding: 0; + color: inherit; + white-space: pre; + white-space: pre-wrap; + background-color: transparent; + border: 0; +} +.pre-scrollable { + max-height: 340px; + overflow-y: scroll; +} +form { + margin: 0 0 18px; +} +fieldset { + padding: 0; + margin: 0; + border: 0; +} +legend { + display: block; + width: 100%; + padding: 0; + margin-bottom: 18px; + font-size: 19.5px; + line-height: 36px; + color: #333; + border: 0; + border-bottom: 1px solid #e5e5e5; +} +legend small { + font-size: 13.5px; + color: #999; +} +label, +input, +button, +select, +textarea { + font-size: 13px; + font-weight: normal; + line-height: 18px; +} +input, +button, +select, +textarea { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; +} +label { + display: block; + margin-bottom: 5px; +} +select, +textarea, +input[type="text"], +input[type="password"], +input[type="datetime"], +input[type="datetime-local"], +input[type="date"], +input[type="month"], +input[type="time"], +input[type="week"], +input[type="number"], +input[type="email"], +input[type="url"], +input[type="search"], +input[type="tel"], +input[type="color"], +.uneditable-input { + display: inline-block; + height: 18px; + padding: 4px 6px; + margin-bottom: 9px; + font-size: 13px; + line-height: 18px; + color: #555; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + vertical-align: middle; +} +input, +textarea, +.uneditable-input { + width: 206px; +} +textarea { + height: auto; +} +textarea, +input[type="text"], +input[type="password"], +input[type="datetime"], +input[type="datetime-local"], +input[type="date"], +input[type="month"], +input[type="time"], +input[type="week"], +input[type="number"], +input[type="email"], +input[type="url"], +input[type="search"], +input[type="tel"], +input[type="color"], +.uneditable-input { + background-color: #fff; + border: 1px solid #ccc; + -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075); + -moz-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075); + box-shadow: inset 0 1px 1px rgba(0,0,0,0.075); + -webkit-transition: border linear .2s, box-shadow linear .2s; + -moz-transition: border linear .2s, box-shadow linear .2s; + -o-transition: border linear .2s, box-shadow linear .2s; + transition: border linear .2s, box-shadow linear .2s; +} +textarea:focus, +input[type="text"]:focus, +input[type="password"]:focus, +input[type="datetime"]:focus, +input[type="datetime-local"]:focus, +input[type="date"]:focus, +input[type="month"]:focus, +input[type="time"]:focus, +input[type="week"]:focus, +input[type="number"]:focus, +input[type="email"]:focus, +input[type="url"]:focus, +input[type="search"]:focus, +input[type="tel"]:focus, +input[type="color"]:focus, +.uneditable-input:focus { + border-color: rgba(82,168,236,0.8); + outline: 0; + outline: thin dotted \9; + -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6); + -moz-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6); + box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6); +} +input[type="radio"], +input[type="checkbox"] { + margin: 4px 0 0; + *margin-top: 0; + margin-top: 1px \9; + line-height: normal; +} +input[type="file"], +input[type="image"], +input[type="submit"], +input[type="reset"], +input[type="button"], +input[type="radio"], +input[type="checkbox"] { + width: auto; +} +select, +input[type="file"] { + height: 28px; + *margin-top: 4px; + line-height: 28px; +} +select { + width: 220px; + border: 1px solid #ccc; + background-color: #fff; +} +select[multiple], +select[size] { + height: auto; +} +select:focus, +input[type="file"]:focus, +input[type="radio"]:focus, +input[type="checkbox"]:focus { + outline: thin dotted #333; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +.uneditable-input, +.uneditable-textarea { + color: #999; + background-color: #fcfcfc; + border-color: #ccc; + -webkit-box-shadow: inset 0 1px 2px rgba(0,0,0,0.025); + -moz-box-shadow: inset 0 1px 2px rgba(0,0,0,0.025); + box-shadow: inset 0 1px 2px rgba(0,0,0,0.025); + cursor: not-allowed; +} +.uneditable-input { + overflow: hidden; + white-space: nowrap; +} +.uneditable-textarea { + width: auto; + height: auto; +} +input:-moz-placeholder, +textarea:-moz-placeholder { + color: #999; +} +input:-ms-input-placeholder, +textarea:-ms-input-placeholder { + color: #999; +} +input::-webkit-input-placeholder, +textarea::-webkit-input-placeholder { + color: #999; +} +.radio, +.checkbox { + min-height: 18px; + padding-left: 20px; +} +.radio input[type="radio"], +.checkbox input[type="checkbox"] { + float: left; + margin-left: -20px; +} +.controls > .radio:first-child, +.controls > .checkbox:first-child { + padding-top: 5px; +} +.radio.inline, +.checkbox.inline { + display: inline-block; + padding-top: 5px; + margin-bottom: 0; + vertical-align: middle; +} +.radio.inline + .radio.inline, +.checkbox.inline + .checkbox.inline { + margin-left: 10px; +} +.input-mini { + width: 60px; +} +.input-small { + width: 90px; +} +.input-medium { + width: 150px; +} +.input-large { + width: 210px; +} +.input-xlarge { + width: 270px; +} +.input-xxlarge { + width: 530px; +} +input[class*="span"], +select[class*="span"], +textarea[class*="span"], +.uneditable-input[class*="span"], +.row-fluid input[class*="span"], +.row-fluid select[class*="span"], +.row-fluid textarea[class*="span"], +.row-fluid .uneditable-input[class*="span"] { + float: none; + margin-left: 0; +} +.input-append input[class*="span"], +.input-append .uneditable-input[class*="span"], +.input-prepend input[class*="span"], +.input-prepend .uneditable-input[class*="span"], +.row-fluid input[class*="span"], +.row-fluid select[class*="span"], +.row-fluid textarea[class*="span"], +.row-fluid .uneditable-input[class*="span"], +.row-fluid .input-prepend [class*="span"], +.row-fluid .input-append [class*="span"] { + display: inline-block; +} +input, +textarea, +.uneditable-input { + margin-left: 0; +} +.controls-row [class*="span"] + [class*="span"] { + margin-left: 20px; +} +input.span12, +textarea.span12, +.uneditable-input.span12 { + width: 926px; +} +input.span11, +textarea.span11, +.uneditable-input.span11 { + width: 846px; +} +input.span10, +textarea.span10, +.uneditable-input.span10 { + width: 766px; +} +input.span9, +textarea.span9, +.uneditable-input.span9 { + width: 686px; +} +input.span8, +textarea.span8, +.uneditable-input.span8 { + width: 606px; +} +input.span7, +textarea.span7, +.uneditable-input.span7 { + width: 526px; +} +input.span6, +textarea.span6, +.uneditable-input.span6 { + width: 446px; +} +input.span5, +textarea.span5, +.uneditable-input.span5 { + width: 366px; +} +input.span4, +textarea.span4, +.uneditable-input.span4 { + width: 286px; +} +input.span3, +textarea.span3, +.uneditable-input.span3 { + width: 206px; +} +input.span2, +textarea.span2, +.uneditable-input.span2 { + width: 126px; +} +input.span1, +textarea.span1, +.uneditable-input.span1 { + width: 46px; +} +.controls-row { + *zoom: 1; +} +.controls-row:before, +.controls-row:after { + display: table; + content: ""; + line-height: 0; +} +.controls-row:after { + clear: both; +} +.controls-row [class*="span"], +.row-fluid .controls-row [class*="span"] { + float: left; +} +.controls-row .checkbox[class*="span"], +.controls-row .radio[class*="span"] { + padding-top: 5px; +} +input[disabled], +select[disabled], +textarea[disabled], +input[readonly], +select[readonly], +textarea[readonly] { + cursor: not-allowed; + background-color: #eee; +} +input[type="radio"][disabled], +input[type="checkbox"][disabled], +input[type="radio"][readonly], +input[type="checkbox"][readonly] { + background-color: transparent; +} +.control-group.warning .control-label, +.control-group.warning .help-block, +.control-group.warning .help-inline { + color: #8a6d3b; +} +.control-group.warning .checkbox, +.control-group.warning .radio, +.control-group.warning input, +.control-group.warning select, +.control-group.warning textarea { + color: #8a6d3b; +} +.control-group.warning input, +.control-group.warning select, +.control-group.warning textarea { + border-color: #8a6d3b; +} +.control-group.warning input:focus, +.control-group.warning select:focus, +.control-group.warning textarea:focus { + border-color: #66512c; +} +.control-group.warning .input-prepend .add-on, +.control-group.warning .input-append .add-on { + color: #8a6d3b; + background-color: #fcf8e3; + border-color: #8a6d3b; +} +.control-group.error .control-label, +.control-group.error .help-block, +.control-group.error .help-inline { + color: #a94442; +} +.control-group.error .checkbox, +.control-group.error .radio, +.control-group.error input, +.control-group.error select, +.control-group.error textarea { + color: #a94442; +} +.control-group.error input, +.control-group.error select, +.control-group.error textarea { + border-color: #a94442; +} +.control-group.error input:focus, +.control-group.error select:focus, +.control-group.error textarea:focus { + border-color: #843534; +} +.control-group.error .input-prepend .add-on, +.control-group.error .input-append .add-on { + color: #a94442; + background-color: #f2dede; + border-color: #a94442; +} +.control-group.success .control-label, +.control-group.success .help-block, +.control-group.success .help-inline { + color: #3c763d; +} +.control-group.success .checkbox, +.control-group.success .radio, +.control-group.success input, +.control-group.success select, +.control-group.success textarea { + color: #3c763d; +} +.control-group.success input, +.control-group.success select, +.control-group.success textarea { + border-color: #3c763d; +} +.control-group.success input:focus, +.control-group.success select:focus, +.control-group.success textarea:focus { + border-color: #2b542c; +} +.control-group.success .input-prepend .add-on, +.control-group.success .input-append .add-on { + color: #3c763d; + background-color: #dff0d8; + border-color: #3c763d; +} +.control-group.info .control-label, +.control-group.info .help-block, +.control-group.info .help-inline { + color: #31708f; +} +.control-group.info .checkbox, +.control-group.info .radio, +.control-group.info input, +.control-group.info select, +.control-group.info textarea { + color: #31708f; +} +.control-group.info input, +.control-group.info select, +.control-group.info textarea { + border-color: #31708f; +} +.control-group.info input:focus, +.control-group.info select:focus, +.control-group.info textarea:focus { + border-color: #245269; +} +.control-group.info .input-prepend .add-on, +.control-group.info .input-append .add-on { + color: #31708f; + background-color: #d9edf7; + border-color: #31708f; +} +input:focus:invalid, +textarea:focus:invalid, +select:focus:invalid { + color: #b94a48; + border-color: #ee5f5b; +} +input:focus:invalid:focus, +textarea:focus:invalid:focus, +select:focus:invalid:focus { + border-color: #e9322d; + -webkit-box-shadow: 0 0 6px #f8b9b7; + -moz-box-shadow: 0 0 6px #f8b9b7; + box-shadow: 0 0 6px #f8b9b7; +} +.form-actions { + padding: 17px 20px 18px; + margin-top: 18px; + margin-bottom: 18px; + background-color: #F0F0F0; + border-top: 1px solid #e5e5e5; + *zoom: 1; +} +.form-actions:before, +.form-actions:after { + display: table; + content: ""; + line-height: 0; +} +.form-actions:after { + clear: both; +} +.help-block, +.help-inline { + color: #595959; +} +.help-block { + display: block; + margin-bottom: 9px; +} +.help-inline { + display: inline-block; + *display: inline; + *zoom: 1; + vertical-align: middle; + padding-left: 5px; +} +.input-append, +.input-prepend { + display: inline-block; + margin-bottom: 9px; + vertical-align: middle; + font-size: 0; + white-space: nowrap; +} +.input-append input, +.input-append select, +.input-append .uneditable-input, +.input-append .dropdown-menu, +.input-append .popover, +.input-prepend input, +.input-prepend select, +.input-prepend .uneditable-input, +.input-prepend .dropdown-menu, +.input-prepend .popover { + font-size: 13px; +} +.input-append input, +.input-append select, +.input-append .uneditable-input, +.input-prepend input, +.input-prepend select, +.input-prepend .uneditable-input { + position: relative; + margin-bottom: 0; + *margin-left: 0; + vertical-align: top; + -webkit-border-radius: 0 3px 3px 0; + -moz-border-radius: 0 3px 3px 0; + border-radius: 0 3px 3px 0; +} +.input-append input:focus, +.input-append select:focus, +.input-append .uneditable-input:focus, +.input-prepend input:focus, +.input-prepend select:focus, +.input-prepend .uneditable-input:focus { + z-index: 2; +} +.input-append .add-on, +.input-prepend .add-on { + display: inline-block; + width: auto; + height: 18px; + min-width: 16px; + padding: 4px 5px; + font-size: 13px; + font-weight: normal; + line-height: 18px; + text-align: center; + text-shadow: 0 1px 0 #fff; + background-color: #eee; + border: 1px solid #ccc; +} +.input-append .add-on, +.input-append .btn, +.input-append .btn-group > .dropdown-toggle, +.input-prepend .add-on, +.input-prepend .btn, +.input-prepend .btn-group > .dropdown-toggle { + vertical-align: top; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.input-prepend .add-on, +.input-prepend .btn { + margin-right: -1px; +} +.input-prepend .add-on:first-child, +.input-prepend .btn:first-child { + -webkit-border-radius: 3px 0 0 3px; + -moz-border-radius: 3px 0 0 3px; + border-radius: 3px 0 0 3px; +} +.input-append input, +.input-append select, +.input-append .uneditable-input { + -webkit-border-radius: 3px 0 0 3px; + -moz-border-radius: 3px 0 0 3px; + border-radius: 3px 0 0 3px; +} +.input-append input + .btn-group .btn:last-child, +.input-append select + .btn-group .btn:last-child, +.input-append .uneditable-input + .btn-group .btn:last-child { + -webkit-border-radius: 0 3px 3px 0; + -moz-border-radius: 0 3px 3px 0; + border-radius: 0 3px 3px 0; +} +.input-append .add-on, +.input-append .btn, +.input-append .btn-group { + margin-left: -1px; +} +.input-append .add-on:last-child, +.input-append .btn:last-child, +.input-append .btn-group:last-child > .dropdown-toggle { + -webkit-border-radius: 0 3px 3px 0; + -moz-border-radius: 0 3px 3px 0; + border-radius: 0 3px 3px 0; +} +.input-prepend.input-append input, +.input-prepend.input-append select, +.input-prepend.input-append .uneditable-input { + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.input-prepend.input-append input + .btn-group .btn, +.input-prepend.input-append select + .btn-group .btn, +.input-prepend.input-append .uneditable-input + .btn-group .btn { + -webkit-border-radius: 0 3px 3px 0; + -moz-border-radius: 0 3px 3px 0; + border-radius: 0 3px 3px 0; +} +.input-prepend.input-append .add-on:first-child, +.input-prepend.input-append .btn:first-child { + margin-right: -1px; + -webkit-border-radius: 3px 0 0 3px; + -moz-border-radius: 3px 0 0 3px; + border-radius: 3px 0 0 3px; +} +.input-prepend.input-append .add-on:last-child, +.input-prepend.input-append .btn:last-child { + margin-left: -1px; + -webkit-border-radius: 0 3px 3px 0; + -moz-border-radius: 0 3px 3px 0; + border-radius: 0 3px 3px 0; +} +.input-prepend.input-append .btn-group:first-child { + margin-left: 0; +} +input.search-query { + padding-right: 14px; + padding-right: 4px \9; + padding-left: 14px; + padding-left: 4px \9; + margin-bottom: 0; + -webkit-border-radius: 15px; + -moz-border-radius: 15px; + border-radius: 15px; +} +.form-search .input-append .search-query, +.form-search .input-prepend .search-query { + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.form-search .input-append .search-query { + -webkit-border-radius: 14px 0 0 14px; + -moz-border-radius: 14px 0 0 14px; + border-radius: 14px 0 0 14px; +} +.form-search .input-append .btn { + -webkit-border-radius: 0 14px 14px 0; + -moz-border-radius: 0 14px 14px 0; + border-radius: 0 14px 14px 0; +} +.form-search .input-prepend .search-query { + -webkit-border-radius: 0 14px 14px 0; + -moz-border-radius: 0 14px 14px 0; + border-radius: 0 14px 14px 0; +} +.form-search .input-prepend .btn { + -webkit-border-radius: 14px 0 0 14px; + -moz-border-radius: 14px 0 0 14px; + border-radius: 14px 0 0 14px; +} +.js-stools-field-filter .input-prepend, +.js-stools-field-filter .input-append { + margin-bottom: 0; +} +.form-search input, +.form-search textarea, +.form-search select, +.form-search .help-inline, +.form-search .uneditable-input, +.form-search .input-prepend, +.form-search .input-append, +.form-inline input, +.form-inline textarea, +.form-inline select, +.form-inline .help-inline, +.form-inline .uneditable-input, +.form-inline .input-prepend, +.form-inline .input-append, +.form-horizontal input, +.form-horizontal textarea, +.form-horizontal select, +.form-horizontal .help-inline, +.form-horizontal .uneditable-input, +.form-horizontal .input-prepend, +.form-horizontal .input-append { + display: inline-block; + *display: inline; + *zoom: 1; + margin-bottom: 0; + vertical-align: middle; +} +.form-search .hide, +.form-inline .hide, +.form-horizontal .hide { + display: none; +} +.form-search label, +.form-inline label, +.form-search .btn-group, +.form-inline .btn-group { + display: inline-block; +} +.form-search .input-append, +.form-inline .input-append, +.form-search .input-prepend, +.form-inline .input-prepend { + margin-bottom: 0; +} +.form-search .radio, +.form-search .checkbox, +.form-inline .radio, +.form-inline .checkbox { + padding-left: 0; + margin-bottom: 0; + vertical-align: middle; +} +.form-search .radio input[type="radio"], +.form-search .checkbox input[type="checkbox"], +.form-inline .radio input[type="radio"], +.form-inline .checkbox input[type="checkbox"] { + float: left; + margin-right: 3px; + margin-left: 0; +} +.control-group { + margin-bottom: 9px; +} +legend + .control-group { + margin-top: 18px; + -webkit-margin-top-collapse: separate; +} +.form-horizontal .control-group { + margin-bottom: 18px; + *zoom: 1; +} +.form-horizontal .control-group:before, +.form-horizontal .control-group:after { + display: table; + content: ""; + line-height: 0; +} +.form-horizontal .control-group:after { + clear: both; +} +.form-horizontal .control-label { + float: left; + width: 160px; + padding-top: 5px; + text-align: right; +} +.form-horizontal .controls { + *display: inline-block; + *padding-left: 20px; + margin-left: 180px; + *margin-left: 0; +} +.form-horizontal .controls:first-child { + *padding-left: 180px; +} +.form-horizontal .help-block { + margin-bottom: 0; +} +.form-horizontal input + .help-block, +.form-horizontal select + .help-block, +.form-horizontal textarea + .help-block, +.form-horizontal .uneditable-input + .help-block, +.form-horizontal .input-prepend + .help-block, +.form-horizontal .input-append + .help-block { + margin-top: 9px; +} +.form-horizontal .form-actions { + padding-left: 180px; +} +.control-label .hasPopover, +.control-label .hasTooltip { + display: inline-block; +} +.subform-repeatable-wrapper .btn-group>.btn.button { + min-width: 0; +} +.subform-repeatable-wrapper .ui-sortable-helper { + background: #fff; +} +.subform-repeatable-wrapper tr.ui-sortable-helper { + display: table; +} +@media (min-width: 980px) and (max-width: 1215px) { + .float-cols .control-label { + float: none; + } + .float-cols .controls { + margin-left: 0; + } +} +table { + max-width: 100%; + background-color: transparent; + border-collapse: collapse; + border-spacing: 0; +} +.table { + width: 100%; + margin-bottom: 18px; +} +.table th, +.table td { + padding: 8px; + line-height: 18px; + text-align: left; + vertical-align: top; + border-top: 1px solid #ddd; +} +.table th { + font-weight: bold; +} +.table thead th { + vertical-align: bottom; +} +.table caption + thead tr:first-child th, +.table caption + thead tr:first-child td, +.table colgroup + thead tr:first-child th, +.table colgroup + thead tr:first-child td, +.table thead:first-child tr:first-child th, +.table thead:first-child tr:first-child td { + border-top: 0; +} +.table tbody + tbody { + border-top: 2px solid #ddd; +} +.table .table { + background-color: #fff; +} +.table-condensed th, +.table-condensed td { + padding: 4px 5px; +} +.table-bordered { + border: 1px solid #ddd; + border-collapse: separate; + *border-collapse: collapse; + border-left: 0; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} +.table-bordered th, +.table-bordered td { + border-left: 1px solid #ddd; +} +.table-bordered caption + thead tr:first-child th, +.table-bordered caption + tbody tr:first-child th, +.table-bordered caption + tbody tr:first-child td, +.table-bordered colgroup + thead tr:first-child th, +.table-bordered colgroup + tbody tr:first-child th, +.table-bordered colgroup + tbody tr:first-child td, +.table-bordered thead:first-child tr:first-child th, +.table-bordered tbody:first-child tr:first-child th, +.table-bordered tbody:first-child tr:first-child td { + border-top: 0; +} +.table-bordered thead:first-child tr:first-child > th:first-child, +.table-bordered tbody:first-child tr:first-child > td:first-child, +.table-bordered tbody:first-child tr:first-child > th:first-child { + -webkit-border-top-left-radius: 3px; + -moz-border-radius-topleft: 3px; + border-top-left-radius: 3px; +} +.table-bordered thead:first-child tr:first-child > th:last-child, +.table-bordered tbody:first-child tr:first-child > td:last-child, +.table-bordered tbody:first-child tr:first-child > th:last-child { + -webkit-border-top-right-radius: 3px; + -moz-border-radius-topright: 3px; + border-top-right-radius: 3px; +} +.table-bordered thead:last-child tr:last-child > th:first-child, +.table-bordered tbody:last-child tr:last-child > td:first-child, +.table-bordered tbody:last-child tr:last-child > th:first-child, +.table-bordered tfoot:last-child tr:last-child > td:first-child, +.table-bordered tfoot:last-child tr:last-child > th:first-child { + -webkit-border-bottom-left-radius: 3px; + -moz-border-radius-bottomleft: 3px; + border-bottom-left-radius: 3px; +} +.table-bordered thead:last-child tr:last-child > th:last-child, +.table-bordered tbody:last-child tr:last-child > td:last-child, +.table-bordered tbody:last-child tr:last-child > th:last-child, +.table-bordered tfoot:last-child tr:last-child > td:last-child, +.table-bordered tfoot:last-child tr:last-child > th:last-child { + -webkit-border-bottom-right-radius: 3px; + -moz-border-radius-bottomright: 3px; + border-bottom-right-radius: 3px; +} +.table-bordered tfoot + tbody:last-child tr:last-child td:first-child { + -webkit-border-bottom-left-radius: 0; + -moz-border-radius-bottomleft: 0; + border-bottom-left-radius: 0; +} +.table-bordered tfoot + tbody:last-child tr:last-child td:last-child { + -webkit-border-bottom-right-radius: 0; + -moz-border-radius-bottomright: 0; + border-bottom-right-radius: 0; +} +.table-bordered caption + thead tr:first-child th:first-child, +.table-bordered caption + tbody tr:first-child td:first-child, +.table-bordered colgroup + thead tr:first-child th:first-child, +.table-bordered colgroup + tbody tr:first-child td:first-child { + -webkit-border-top-left-radius: 3px; + -moz-border-radius-topleft: 3px; + border-top-left-radius: 3px; +} +.table-bordered caption + thead tr:first-child th:last-child, +.table-bordered caption + tbody tr:first-child td:last-child, +.table-bordered colgroup + thead tr:first-child th:last-child, +.table-bordered colgroup + tbody tr:first-child td:last-child { + -webkit-border-top-right-radius: 3px; + -moz-border-radius-topright: 3px; + border-top-right-radius: 3px; +} +.table-striped tbody > tr:nth-child(odd) > td, +.table-striped tbody > tr:nth-child(odd) > th { + background-color: #f9f9f9; +} +.table-hover tbody tr:hover > td, +.table-hover tbody tr:hover > th { + background-color: #F0F0F0; +} +table td[class*="span"], +table th[class*="span"], +.row-fluid table td[class*="span"], +.row-fluid table th[class*="span"] { + display: table-cell; + float: none; + margin-left: 0; +} +.table td.span1, +.table th.span1 { + float: none; + width: 44px; + margin-left: 0; +} +.table td.span2, +.table th.span2 { + float: none; + width: 124px; + margin-left: 0; +} +.table td.span3, +.table th.span3 { + float: none; + width: 204px; + margin-left: 0; +} +.table td.span4, +.table th.span4 { + float: none; + width: 284px; + margin-left: 0; +} +.table td.span5, +.table th.span5 { + float: none; + width: 364px; + margin-left: 0; +} +.table td.span6, +.table th.span6 { + float: none; + width: 444px; + margin-left: 0; +} +.table td.span7, +.table th.span7 { + float: none; + width: 524px; + margin-left: 0; +} +.table td.span8, +.table th.span8 { + float: none; + width: 604px; + margin-left: 0; +} +.table td.span9, +.table th.span9 { + float: none; + width: 684px; + margin-left: 0; +} +.table td.span10, +.table th.span10 { + float: none; + width: 764px; + margin-left: 0; +} +.table td.span11, +.table th.span11 { + float: none; + width: 844px; + margin-left: 0; +} +.table td.span12, +.table th.span12 { + float: none; + width: 924px; + margin-left: 0; +} +.table tbody tr.success > td { + background-color: #dff0d8; +} +.table tbody tr.error > td { + background-color: #f2dede; +} +.table tbody tr.warning > td { + background-color: #fcf8e3; +} +.table tbody tr.info > td { + background-color: #d9edf7; +} +.table-hover tbody tr.success:hover > td { + background-color: #d0e9c6; +} +.table-hover tbody tr.error:hover > td { + background-color: #ebcccc; +} +.table-hover tbody tr.warning:hover > td { + background-color: #faf2cc; +} +.table-hover tbody tr.info:hover > td { + background-color: #c4e3f3; +} +.table-noheader { + border-collapse: collapse; +} +.table-noheader thead { + display: none; +} +.dropup, +.dropdown { + position: relative; +} +.dropdown-toggle { + *margin-bottom: -3px; +} +.dropdown-toggle:active, +.open .dropdown-toggle { + outline: 0; +} +.caret { + display: inline-block; + width: 0; + height: 0; + vertical-align: top; + border-top: 4px solid #000; + border-right: 4px solid transparent; + border-left: 4px solid transparent; + content: ""; +} +.dropdown .caret { + margin-top: 8px; + margin-left: 2px; +} +.dropdown-menu { + position: absolute; + top: 100%; + left: 0; + z-index: 1000; + display: none; + float: left; + min-width: 160px; + padding: 5px 0; + margin: 2px 0 0; + list-style: none; + background-color: #fff; + border: 1px solid #ccc; + border: 1px solid rgba(0,0,0,0.2); + *border-right-width: 2px; + *border-bottom-width: 2px; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; + -webkit-box-shadow: 0 5px 10px rgba(0,0,0,0.2); + -moz-box-shadow: 0 5px 10px rgba(0,0,0,0.2); + box-shadow: 0 5px 10px rgba(0,0,0,0.2); + -webkit-background-clip: padding-box; + -moz-background-clip: padding; + background-clip: padding-box; +} +.dropdown-menu.pull-right { + right: 0; + left: auto; +} +.dropdown-menu .divider { + *width: 100%; + height: 1px; + margin: 8px 1px; + *margin: -5px 0 5px; + overflow: hidden; + background-color: #F0F0F0; + border-bottom: 1px solid #fff; +} +.dropdown-menu .menuitem-group { + margin: 4px 1px; + overflow: hidden; + border-top: 1px solid #eee; + border-bottom: 1px solid #eee; + background-color: #eee; + color: #555; + text-transform: capitalize; + font-size: 95%; + padding: 3px 20px; +} +.dropdown-menu > li > a { + display: block; + padding: 3px 20px; + clear: both; + font-weight: normal; + line-height: 18px; + color: #333; + white-space: nowrap; +} +.dropdown-menu > li > a:hover, +.dropdown-menu > li > a:focus, +.dropdown-submenu:hover > a, +.dropdown-submenu:focus > a { + text-decoration: none; + color: #fff; + background-color: #2d6ca2; + background-image: -moz-linear-gradient(top,#3071a9,#2a6496); + background-image: -webkit-gradient(linear,0 0,0 100%,from(#3071a9),to(#2a6496)); + background-image: -webkit-linear-gradient(top,#3071a9,#2a6496); + background-image: -o-linear-gradient(top,#3071a9,#2a6496); + background-image: linear-gradient(to bottom,#3071a9,#2a6496); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff2f70a9', endColorstr='#ff296395', GradientType=0); +} +.dropdown-menu > .active > a, +.dropdown-menu > .active > a:hover, +.dropdown-menu > .active > a:focus { + color: #333; + text-decoration: none; + outline: 0; + background-color: #2d6ca2; + background-image: -moz-linear-gradient(top,#3071a9,#2a6496); + background-image: -webkit-gradient(linear,0 0,0 100%,from(#3071a9),to(#2a6496)); + background-image: -webkit-linear-gradient(top,#3071a9,#2a6496); + background-image: -o-linear-gradient(top,#3071a9,#2a6496); + background-image: linear-gradient(to bottom,#3071a9,#2a6496); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff2f70a9', endColorstr='#ff296395', GradientType=0); +} +.dropdown-menu > .disabled > a, +.dropdown-menu > .disabled > a:hover, +.dropdown-menu > .disabled > a:focus { + color: #999; +} +.dropdown-menu > .disabled > a:hover, +.dropdown-menu > .disabled > a:focus { + text-decoration: none; + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + cursor: default; +} +.open { + *z-index: 1000; +} +.open > .dropdown-menu { + display: block; +} +.dropdown-backdrop { + position: fixed; + left: 0; + right: 0; + bottom: 0; + top: 0; + z-index: 990; +} +.pull-right > .dropdown-menu { + right: 0; + left: auto; +} +.dropup .caret, +.navbar-fixed-bottom .dropdown .caret { + border-top: 0; + border-bottom: 4px solid #000; + content: ""; +} +.dropup .dropdown-menu, +.navbar-fixed-bottom .dropdown .dropdown-menu { + top: auto; + bottom: 100%; + margin-bottom: 1px; +} +.dropdown-submenu { + position: relative; +} +.dropdown-submenu > .dropdown-menu { + top: 0; + left: 100%; + margin-top: -6px; + margin-left: -1px; + -webkit-border-radius: 6px 6px 6px 6px; + -moz-border-radius: 6px 6px 6px 6px; + border-radius: 6px 6px 6px 6px; +} +.dropdown-submenu:hover > .dropdown-menu { + display: block; +} +.dropup .dropdown-submenu > .dropdown-menu { + top: auto; + bottom: 0; + margin-top: 0; + margin-bottom: -2px; + -webkit-border-radius: 5px 5px 5px 0; + -moz-border-radius: 5px 5px 5px 0; + border-radius: 5px 5px 5px 0; +} +.dropdown-submenu > a:after { + display: block; + content: " "; + float: right; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; + border-width: 5px 0 5px 5px; + border-left-color: #cccccc; + margin-top: 5px; + margin-right: -10px; +} +.dropdown-submenu:hover > a:after { + border-left-color: #fff; +} +.dropdown-submenu.pull-left { + float: none; +} +.dropdown-submenu.pull-left > .dropdown-menu { + left: -100%; + margin-left: 10px; + -webkit-border-radius: 6px 0 6px 6px; + -moz-border-radius: 6px 0 6px 6px; + border-radius: 6px 0 6px 6px; +} +.dropdown .dropdown-menu .nav-header { + padding-left: 20px; + padding-right: 20px; +} +.typeahead { + z-index: 1051; + margin-top: 2px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} +.well { + min-height: 20px; + padding: 19px; + margin-bottom: 20px; + background-color: #F0F0F0; + border: 1px solid #F0F0F0; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} +.well blockquote { + border-color: #f0f0f0; + border-color: rgba(0,0,0,0.15); +} +.well-large { + padding: 24px; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} +.well-small { + padding: 9px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} +.fade { + opacity: 0; + -webkit-transition: opacity .15s linear; + -moz-transition: opacity .15s linear; + -o-transition: opacity .15s linear; + transition: opacity .15s linear; +} +.fade.in { + opacity: 1; +} +.collapse { + position: relative; + height: 0; + overflow: hidden; + -webkit-transition: height .35s ease; + -moz-transition: height .35s ease; + -o-transition: height .35s ease; + transition: height .35s ease; +} +.collapse.in { + height: auto; +} +.close { + float: right; + font-size: 20px; + font-weight: bold; + line-height: 18px; + color: #000; + text-shadow: 0 1px 0 #ffffff; + opacity: 0.2; + filter: alpha(opacity=20); +} +.close:hover, +.close:focus { + color: #000; + text-decoration: none; + cursor: pointer; + opacity: 0.4; + filter: alpha(opacity=40); +} +button.close { + padding: 3; + cursor: pointer; + background: transparent; + border: 0; + -webkit-appearance: none; +} +.alert-options { + float: right; + line-height: 18px; + color: #000; + text-shadow: 0 1px 0 #ffffff; + opacity: 0.2; + filter: alpha(opacity=20); +} +.alert-options:hover, +.alert-options:focus { + color: #000; + text-decoration: none; + cursor: pointer; + opacity: 0.4; + filter: alpha(opacity=40); +} +.btn { + display: inline-block; + *display: inline; + *zoom: 1; + padding: 4px 12px; + margin-bottom: 0; + font-size: 13px; + line-height: 18px; + text-align: center; + vertical-align: middle; + cursor: pointer; + background-color: #f3f3f3; + color: #333; + border: 1px solid #b3b3b3; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + box-shadow: 0 1px 2px rgba(0,0,0,0.05); +} +.btn:hover, +.btn:focus { + background-color: #e6e6e6; + text-decoration: none; + text-shadow: none; +} +.btn:focus { + outline: thin dotted #333; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +.btn.active, +.btn:active { + background-image: none; + outline: 0; +} +.btn.disabled, +.btn[disabled] { + cursor: default; + background-image: none; + opacity: 0.65; + filter: alpha(opacity=65); + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; +} +.btn-large { + padding: 11px 19px; + font-size: 16.25px; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} +.btn-large [class^="icon-"], +.btn-large [class*=" icon-"] { + margin-top: 4px; +} +.btn-small { + padding: 2px 10px; + font-size: 12px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} +.btn-small [class^="icon-"], +.btn-small [class*=" icon-"] { + margin-top: 0; +} +.btn-mini [class^="icon-"], +.btn-mini [class*=" icon-"] { + margin-top: -1px; +} +.btn-mini { + padding: 0 6px; + font-size: 9.75px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} +.btn-block { + display: block; + width: 100%; + padding-left: 0; + padding-right: 0; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +.btn-block + .btn-block { + margin-top: 5px; +} +input[type="submit"].btn-block, +input[type="reset"].btn-block, +input[type="button"].btn-block { + width: 100%; +} +.btn-primary, +.btn-warning, +.btn-danger, +.btn-success, +.btn-info, +.btn-inverse { + box-shadow: 0 1px 2px rgba(0,0,0,0.05); +} +.btn-primary { + border: 1px solid #15497c; + border: 1px solid rgba(0,0,0,0.2); + color: #fff; + background-color: #2384d3; +} +.btn-primary:hover, +.btn-primary:focus { + background-color: #185b91; + color: #fff; + text-decoration: none; +} +.btn-warning { + border: 1px solid #f89406; + border: 1px solid rgba(0,0,0,0.2); + color: #fff; + background-color: #f89406; +} +.btn-warning:hover, +.btn-warning:focus { + background-color: #ad6704; + color: #fff; + text-decoration: none; + text-shadow: none; +} +.btn-danger { + border: 1px solid #bd362f; + border: 1px solid rgba(0,0,0,0.2); + color: #fff; + background-color: #bd362f; +} +.btn-danger:hover, +.btn-danger:focus { + background-color: #802420; + color: #fff; + text-decoration: none; +} +.btn-success { + border: 1px solid #378137; + border: 1px solid rgba(0,0,0,0.2); + color: #fff; + background-color: #46a546; +} +.btn-success:hover, +.btn-success:focus { + background-color: #2f6f2f; + color: #fff; + text-decoration: none; +} +.btn-info { + border: 1px solid #2f96b4; + border: 1px solid rgba(0,0,0,0.2); + color: #fff; + background-color: #2f96b4; +} +.btn-info:hover, +.btn-info:focus { + background-color: #1f6377; + color: #fff; + text-decoration: none; +} +.btn-inverse { + border: 1px solid #444; + border: 1px solid rgba(0,0,0,0.2); + color: #fff; + background-color: #444; +} +.btn-inverse:hover, +.btn-inverse:focus { + background-color: #1e1e1e; + color: #fff; + text-decoration: none; +} +button.btn, +input[type="submit"].btn { + *padding-top: 3px; + *padding-bottom: 3px; +} +button.btn::-moz-focus-inner, +input[type="submit"].btn::-moz-focus-inner { + padding: 0; + border: 0; +} +button.btn.btn-large, +input[type="submit"].btn.btn-large { + *padding-top: 7px; + *padding-bottom: 7px; +} +button.btn.btn-small, +input[type="submit"].btn.btn-small { + *padding-top: 3px; + *padding-bottom: 3px; +} +button.btn.btn-mini, +input[type="submit"].btn.btn-mini { + *padding-top: 1px; + *padding-bottom: 1px; +} +.btn-link, +.btn-link:active, +.btn-link[disabled] { + background-color: transparent; + background-image: none; + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; +} +.btn-link { + border-color: transparent; + cursor: pointer; + color: #3071a9; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.btn-link:hover, +.btn-link:focus { + color: #1f496e; + text-decoration: underline; + background-color: transparent; +} +.btn-link[disabled]:hover, +.btn-link[disabled]:focus { + color: #333; + text-decoration: none; +} +.btn-group { + position: relative; + display: inline-block; + *display: inline; + *zoom: 1; + font-size: 0; + vertical-align: middle; + white-space: nowrap; + *margin-left: .3em; +} +.btn-group:first-child { + *margin-left: 0; +} +.btn-group .btn + .btn { + margin-left: -1px; +} +.btn-group + .btn-group { + margin-left: 5px; +} +.btn-toolbar { + font-size: 0; + margin-top: 9px; + margin-bottom: 9px; +} +.btn-toolbar > .btn + .btn, +.btn-toolbar > .btn-group + .btn, +.btn-toolbar > .btn + .btn-group { + margin-left: 5px; +} +.btn-group > .btn { + position: relative; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.btn-group > .btn-micro { + margin-left: -1px; +} +.btn-group > .btn, +.btn-group > .dropdown-menu, +.btn-group > .popover { + font-size: 13px; +} +.btn-group > .btn-mini { + font-size: 9.75px; +} +.btn-group > .btn-small { + font-size: 12px; +} +.btn-group > .btn-large { + font-size: 16.25px; +} +.btn-group > .btn:first-child { + margin-left: 0; + -webkit-border-top-left-radius: 3px; + -moz-border-radius-topleft: 3px; + border-top-left-radius: 3px; + -webkit-border-bottom-left-radius: 3px; + -moz-border-radius-bottomleft: 3px; + border-bottom-left-radius: 3px; +} +.btn-group > .btn:last-child, +.btn-group > .dropdown-toggle { + -webkit-border-top-right-radius: 3px; + -moz-border-radius-topright: 3px; + border-top-right-radius: 3px; + -webkit-border-bottom-right-radius: 3px; + -moz-border-radius-bottomright: 3px; + border-bottom-right-radius: 3px; +} +.btn-group > .btn.large:first-child { + margin-left: 0; + -webkit-border-top-left-radius: 6px; + -moz-border-radius-topleft: 6px; + border-top-left-radius: 6px; + -webkit-border-bottom-left-radius: 6px; + -moz-border-radius-bottomleft: 6px; + border-bottom-left-radius: 6px; +} +.btn-group > .btn.large:last-child, +.btn-group > .large.dropdown-toggle { + -webkit-border-top-right-radius: 6px; + -moz-border-radius-topright: 6px; + border-top-right-radius: 6px; + -webkit-border-bottom-right-radius: 6px; + -moz-border-radius-bottomright: 6px; + border-bottom-right-radius: 6px; +} +.btn-group > .btn:hover, +.btn-group > .btn:focus, +.btn-group > .btn:active, +.btn-group > .btn.active { + z-index: 2; +} +.btn-group .dropdown-toggle:active, +.btn-group.open .dropdown-toggle { + outline: 0; +} +.btn-group > .btn + .dropdown-toggle { + padding-left: 8px; + padding-right: 8px; + *padding-top: 5px; + *padding-bottom: 5px; +} +.btn-group > .btn-mini + .dropdown-toggle { + padding-left: 5px; + padding-right: 5px; + *padding-top: 2px; + *padding-bottom: 2px; +} +.btn-group > .btn-small + .dropdown-toggle { + *padding-top: 5px; + *padding-bottom: 4px; +} +.btn-group > .btn-large + .dropdown-toggle { + padding-left: 12px; + padding-right: 12px; + *padding-top: 7px; + *padding-bottom: 7px; +} +.btn-group.open .dropdown-toggle { + background-image: none; +} +.btn-group.open .btn.dropdown-toggle { + background-color: #e6e6e6; +} +.btn-group.open .btn-primary.dropdown-toggle { + background-color: #15497c; +} +.btn-group.open .btn-warning.dropdown-toggle { + background-color: #c67605; +} +.btn-group.open .btn-danger.dropdown-toggle { + background-color: #942a25; +} +.btn-group.open .btn-success.dropdown-toggle { + background-color: #378137; +} +.btn-group.open .btn-info.dropdown-toggle { + background-color: #24748c; +} +.btn-group.open .btn-inverse.dropdown-toggle { + background-color: #222; +} +.btn .caret { + margin-top: 8px; + margin-left: 0; +} +.btn-large .caret { + margin-top: 6px; +} +.btn-large .caret { + border-left-width: 5px; + border-right-width: 5px; + border-top-width: 5px; +} +.btn-mini .caret, +.btn-small .caret { + margin-top: 8px; +} +.dropup .btn-large .caret { + border-bottom-width: 5px; +} +.btn-primary .caret { + border-top-color: #1f496e; + border-bottom-color: #1f496e; +} +.btn-warning .caret, +.btn-danger .caret, +.btn-info .caret, +.btn-success .caret, +.btn-inverse .caret { + border-top-color: #fff; + border-bottom-color: #fff; +} +.btn-group-vertical { + display: inline-block; + *display: inline; + *zoom: 1; +} +.btn-group-vertical > .btn { + display: block; + float: none; + max-width: 100%; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.btn-group-vertical > .btn + .btn { + margin-left: 0; + margin-top: -1px; +} +.btn-group-vertical > .btn:first-child { + -webkit-border-radius: 3px 3px 0 0; + -moz-border-radius: 3px 3px 0 0; + border-radius: 3px 3px 0 0; +} +.btn-group-vertical > .btn:last-child { + -webkit-border-radius: 0 0 3px 3px; + -moz-border-radius: 0 0 3px 3px; + border-radius: 0 0 3px 3px; +} +.btn-group-vertical > .btn-large:first-child { + -webkit-border-radius: 6px 6px 0 0; + -moz-border-radius: 6px 6px 0 0; + border-radius: 6px 6px 0 0; +} +.btn-group-vertical > .btn-large:last-child { + -webkit-border-radius: 0 0 6px 6px; + -moz-border-radius: 0 0 6px 6px; + border-radius: 0 0 6px 6px; +} +.alert { + padding: 8px 35px 8px 14px; + margin-bottom: 18px; + text-shadow: 0 1px 0 rgba(255,255,255,0.5); + background-color: #fcf8e3; + border: 1px solid #faebcc; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} +.alert, +.alert h4 { + color: #8a6d3b; +} +.alert h4 { + margin: 0 0 .5em; +} +.alert .close { + position: relative; + top: -2px; + right: -21px; + line-height: 18px; + cursor: pointer; +} +.alert-success { + background-color: #dff0d8; + border-color: #d6e9c6; + color: #3c763d; +} +.alert-success h4 { + color: #3c763d; +} +.alert-danger, +.alert-error { + background-color: #f2dede; + border-color: #ebccd1; + color: #a94442; +} +.alert-danger h4, +.alert-error h4 { + color: #a94442; +} +.alert-info { + background-color: #d9edf7; + border-color: #bce8f1; + color: #31708f; +} +.alert-info h4 { + color: #31708f; +} +.alert-block { + padding-top: 14px; + padding-bottom: 14px; +} +.alert-block > p, +.alert-block > ul { + margin-bottom: 0; +} +.alert-block p + p { + margin-top: 5px; +} +.nav { + margin-left: 0; + margin-bottom: 18px; + list-style: none; +} +.nav > li > a { + display: block; +} +.nav > li > a:hover, +.nav > li > a:focus { + text-decoration: none; + background-color: #eee; +} +.nav > li > a > img { + max-width: none; +} +.nav > .pull-right { + float: right; +} +.nav-header { + display: block; + padding: 3px 15px; + font-size: 11px; + font-weight: bold; + line-height: 18px; + color: #999; + text-shadow: 0 1px 0 rgba(255,255,255,0.5); + text-transform: uppercase; +} +.nav li + .nav-header { + margin-top: 9px; +} +.nav-list { + padding-left: 15px; + padding-right: 15px; + margin-bottom: 0; +} +.nav-list > li > a, +.nav-list .nav-header { + margin-left: -15px; + margin-right: -15px; + text-shadow: 0 1px 0 rgba(255,255,255,0.5); +} +.nav-list > li > a { + padding: 3px 15px; +} +.nav-list > .active > a, +.nav-list > .active > a:hover, +.nav-list > .active > a:focus { + color: #fff; + text-shadow: 0 -1px 0 rgba(0,0,0,0.2); + background-color: #3071a9; +} +.nav-list [class^="icon-"], +.nav-list [class*=" icon-"] { + margin-right: 2px; +} +.nav-list .divider { + *width: 100%; + height: 1px; + margin: 8px 1px; + *margin: -5px 0 5px; + overflow: hidden; + background-color: #e5e5e5; + border-bottom: 1px solid #fff; +} +.nav-tabs, +.nav-pills { + *zoom: 1; +} +.nav-tabs:before, +.nav-tabs:after, +.nav-pills:before, +.nav-pills:after { + display: table; + content: ""; + line-height: 0; +} +.nav-tabs:after, +.nav-pills:after { + clear: both; +} +.nav-tabs > li, +.nav-pills > li { + float: left; +} +.nav-tabs > li > a, +.nav-pills > li > a { + padding-right: 12px; + padding-left: 12px; + margin-right: 2px; + line-height: 14px; +} +.nav-tabs { + border-bottom: 1px solid #ddd; +} +.nav-tabs > li { + margin-bottom: -1px; +} +.nav-tabs > li > a { + padding-top: 8px; + padding-bottom: 8px; + line-height: 18px; + border: 1px solid transparent; + -webkit-border-radius: 4px 4px 0 0; + -moz-border-radius: 4px 4px 0 0; + border-radius: 4px 4px 0 0; +} +.nav-tabs > li > a:hover, +.nav-tabs > li > a:focus { + border-color: #eee #eee #ddd; +} +.nav-tabs > .active > a, +.nav-tabs > .active > a:hover, +.nav-tabs > .active > a:focus { + color: #555; + background-color: #fff; + border: 1px solid #ddd; + border-bottom-color: transparent; + cursor: default; +} +.nav-pills > li > a { + padding-top: 8px; + padding-bottom: 8px; + margin-top: 2px; + margin-bottom: 2px; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; +} +.nav-pills > .active > a, +.nav-pills > .active > a:hover, +.nav-pills > .active > a:focus { + color: #fff; + background-color: #3071a9; +} +.nav-stacked > li { + float: none; +} +.nav-stacked > li > a { + margin-right: 0; +} +.nav-tabs.nav-stacked { + border-bottom: 0; +} +.nav-tabs.nav-stacked > li > a { + border: 1px solid #ddd; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.nav-tabs.nav-stacked > li:first-child > a { + -webkit-border-top-right-radius: 4px; + -moz-border-radius-topright: 4px; + border-top-right-radius: 4px; + -webkit-border-top-left-radius: 4px; + -moz-border-radius-topleft: 4px; + border-top-left-radius: 4px; +} +.nav-tabs.nav-stacked > li:last-child > a { + -webkit-border-bottom-right-radius: 4px; + -moz-border-radius-bottomright: 4px; + border-bottom-right-radius: 4px; + -webkit-border-bottom-left-radius: 4px; + -moz-border-radius-bottomleft: 4px; + border-bottom-left-radius: 4px; +} +.nav-tabs.nav-stacked > li > a:hover, +.nav-tabs.nav-stacked > li > a:focus { + border-color: #ddd; + z-index: 2; +} +.nav-pills.nav-stacked > li > a { + margin-bottom: 3px; +} +.nav-pills.nav-stacked > li:last-child > a { + margin-bottom: 1px; +} +.nav-tabs .dropdown-menu { + -webkit-border-radius: 0 0 6px 6px; + -moz-border-radius: 0 0 6px 6px; + border-radius: 0 0 6px 6px; +} +.nav-pills .dropdown-menu { + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} +.nav .dropdown-toggle .caret { + border-top-color: #3071a9; + border-bottom-color: #3071a9; + margin-top: 6px; +} +.nav .dropdown-toggle:hover .caret, +.nav .dropdown-toggle:focus .caret { + border-top-color: #1f496e; + border-bottom-color: #1f496e; +} +.nav-tabs .dropdown-toggle .caret { + margin-top: 8px; +} +.nav .active .dropdown-toggle .caret { + border-top-color: #fff; + border-bottom-color: #fff; +} +.nav-tabs .active .dropdown-toggle .caret { + border-top-color: #555; + border-bottom-color: #555; +} +.nav > .dropdown.active > a:hover, +.nav > .dropdown.active > a:focus { + cursor: pointer; +} +.nav-tabs .open .dropdown-toggle, +.nav-pills .open .dropdown-toggle, +.nav > li.dropdown.open.active > a:hover, +.nav > li.dropdown.open.active > a:focus { + color: #fff; + background-color: #999; + border-color: #999; +} +.nav li.dropdown.open .caret, +.nav li.dropdown.open.active .caret, +.nav li.dropdown.open a:hover .caret, +.nav li.dropdown.open a:focus .caret { + border-top-color: #fff; + border-bottom-color: #fff; + opacity: 1; + filter: alpha(opacity=100); +} +.tabs-stacked .open > a:hover, +.tabs-stacked .open > a:focus { + border-color: #999; +} +.tabbable { + *zoom: 1; +} +.tabbable:before, +.tabbable:after { + display: table; + content: ""; + line-height: 0; +} +.tabbable:after { + clear: both; +} +.tab-content { + overflow: auto; +} +.tabs-below > .nav-tabs, +.tabs-right > .nav-tabs, +.tabs-left > .nav-tabs { + border-bottom: 0; +} +.tab-content > .tab-pane, +.pill-content > .pill-pane { + display: none; +} +.tab-content > .active, +.pill-content > .active { + display: block; +} +.tabs-below > .nav-tabs { + border-top: 1px solid #ddd; +} +.tabs-below > .nav-tabs > li { + margin-top: -1px; + margin-bottom: 0; +} +.tabs-below > .nav-tabs > li > a { + -webkit-border-radius: 0 0 4px 4px; + -moz-border-radius: 0 0 4px 4px; + border-radius: 0 0 4px 4px; +} +.tabs-below > .nav-tabs > li > a:hover, +.tabs-below > .nav-tabs > li > a:focus { + border-bottom-color: transparent; + border-top-color: #ddd; +} +.tabs-below > .nav-tabs > .active > a, +.tabs-below > .nav-tabs > .active > a:hover, +.tabs-below > .nav-tabs > .active > a:focus { + border-color: transparent #ddd #ddd #ddd; +} +.tabs-left > .nav-tabs > li, +.tabs-right > .nav-tabs > li { + float: none; +} +.tabs-left > .nav-tabs > li > a, +.tabs-right > .nav-tabs > li > a { + min-width: 74px; + margin-right: 0; + margin-bottom: 3px; +} +.tabs-left > .nav-tabs { + float: left; + margin-right: 19px; + border-right: 1px solid #ddd; +} +.tabs-left > .nav-tabs > li > a { + margin-right: -1px; + -webkit-border-radius: 4px 0 0 4px; + -moz-border-radius: 4px 0 0 4px; + border-radius: 4px 0 0 4px; +} +.tabs-left > .nav-tabs > li > a:hover, +.tabs-left > .nav-tabs > li > a:focus { + border-color: #eee #ddd #eee #eee; +} +.tabs-left > .nav-tabs .active > a, +.tabs-left > .nav-tabs .active > a:hover, +.tabs-left > .nav-tabs .active > a:focus { + border-color: #ddd transparent #ddd #ddd; + *border-right-color: #fff; +} +.tabs-right > .nav-tabs { + float: right; + margin-left: 19px; + border-left: 1px solid #ddd; +} +.tabs-right > .nav-tabs > li > a { + margin-left: -1px; + -webkit-border-radius: 0 4px 4px 0; + -moz-border-radius: 0 4px 4px 0; + border-radius: 0 4px 4px 0; +} +.tabs-right > .nav-tabs > li > a:hover, +.tabs-right > .nav-tabs > li > a:focus { + border-color: #eee #eee #eee #ddd; +} +.tabs-right > .nav-tabs .active > a, +.tabs-right > .nav-tabs .active > a:hover, +.tabs-right > .nav-tabs .active > a:focus { + border-color: #ddd #ddd #ddd transparent; + *border-left-color: #fff; +} +.nav > .disabled > a { + color: #999; +} +.nav > .disabled > a:hover, +.nav > .disabled > a:focus { + text-decoration: none; + background-color: transparent; + cursor: default; +} +.navbar { + overflow: visible; + margin-bottom: 18px; + *position: relative; + *z-index: 2; +} +.navbar-inner { + min-height: 40px; + padding-left: 20px; + padding-right: 20px; + background-color: #fafafa; + background-image: -moz-linear-gradient(top,#ffffff,#f2f2f2); + background-image: -webkit-gradient(linear,0 0,0 100%,from(#ffffff),to(#f2f2f2)); + background-image: -webkit-linear-gradient(top,#ffffff,#f2f2f2); + background-image: -o-linear-gradient(top,#ffffff,#f2f2f2); + background-image: linear-gradient(to bottom,#ffffff,#f2f2f2); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff2f2f2', GradientType=0); + border: 1px solid #d4d4d4; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + -webkit-box-shadow: 0 1px 4px rgba(0,0,0,0.065); + -moz-box-shadow: 0 1px 4px rgba(0,0,0,0.065); + box-shadow: 0 1px 4px rgba(0,0,0,0.065); + *zoom: 1; +} +.navbar-inner:before, +.navbar-inner:after { + display: table; + content: ""; + line-height: 0; +} +.navbar-inner:after { + clear: both; +} +.navbar .container { + width: auto; +} +.nav-collapse.collapse { + height: auto; + overflow: visible; +} +.navbar .brand { + float: left; + display: block; + padding: 11px 20px 11px; + margin-left: -20px; + font-size: 20px; + font-weight: 200; + color: #555; + text-shadow: 0 1px 0 #ffffff; +} +.navbar .brand:hover, +.navbar .brand:focus { + text-decoration: none; +} +.navbar-text { + margin-bottom: 0; + line-height: 40px; + color: #555; +} +.navbar-link { + color: #555; +} +.navbar-link:hover, +.navbar-link:focus { + color: #333; +} +.navbar .divider-vertical { + height: 40px; + margin: 0 9px; + border-left: 1px solid #f2f2f2; + border-right: 1px solid #ffffff; +} +.navbar .btn, +.navbar .btn-group { + margin-top: 5px; +} +.navbar .btn-group .btn, +.navbar .input-prepend .btn, +.navbar .input-append .btn, +.navbar .input-prepend .btn-group, +.navbar .input-append .btn-group { + margin-top: 0; +} +.navbar-form { + margin-bottom: 0; + *zoom: 1; +} +.navbar-form:before, +.navbar-form:after { + display: table; + content: ""; + line-height: 0; +} +.navbar-form:after { + clear: both; +} +.navbar-form input, +.navbar-form select, +.navbar-form .radio, +.navbar-form .checkbox { + margin-top: 5px; +} +.navbar-form input, +.navbar-form select, +.navbar-form .btn { + display: inline-block; + margin-bottom: 0; +} +.navbar-form input[type="image"], +.navbar-form input[type="checkbox"], +.navbar-form input[type="radio"] { + margin-top: 3px; +} +.navbar-form .input-append, +.navbar-form .input-prepend { + margin-top: 5px; + white-space: nowrap; +} +.navbar-form .input-append input, +.navbar-form .input-prepend input { + margin-top: 0; +} +.navbar-search { + position: relative; + float: left; + margin-top: 5px; + margin-bottom: 0; +} +.navbar-search .search-query { + margin-bottom: 0; + padding: 4px 14px; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 13px; + font-weight: normal; + line-height: 1; + -webkit-border-radius: 15px; + -moz-border-radius: 15px; + border-radius: 15px; +} +.navbar-static-top { + position: static; + margin-bottom: 0; +} +.navbar-static-top .navbar-inner { + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.navbar-fixed-top, +.navbar-fixed-bottom { + position: fixed; + right: 0; + left: 0; + z-index: 1030; + margin-bottom: 0; +} +.navbar-fixed-top .navbar-inner, +.navbar-static-top .navbar-inner { + border-width: 0 0 1px; +} +.navbar-fixed-bottom .navbar-inner { + border-width: 1px 0 0; +} +.navbar-fixed-top .navbar-inner, +.navbar-fixed-bottom .navbar-inner { + padding-left: 0; + padding-right: 0; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.navbar-static-top .container, +.navbar-fixed-top .container, +.navbar-fixed-bottom .container { + width: 940px; +} +.navbar-fixed-top { + top: 0; +} +.navbar-fixed-top .navbar-inner, +.navbar-static-top .navbar-inner { + -webkit-box-shadow: 0 1px 10px rgba(0,0,0,.1); + -moz-box-shadow: 0 1px 10px rgba(0,0,0,.1); + box-shadow: 0 1px 10px rgba(0,0,0,.1); +} +.navbar-fixed-bottom { + bottom: 0; +} +.navbar-fixed-bottom .navbar-inner { + -webkit-box-shadow: 0 -1px 10px rgba(0,0,0,.1); + -moz-box-shadow: 0 -1px 10px rgba(0,0,0,.1); + box-shadow: 0 -1px 10px rgba(0,0,0,.1); +} +.navbar .nav { + position: relative; + left: 0; + display: block; + float: left; + margin: 0 10px 0 0; +} +.navbar .nav.pull-right { + float: right; + margin-right: 0; +} +.navbar .nav > li { + float: left; +} +.navbar .nav > li > a { + float: none; + padding: 11px 15px 11px; + color: #555; + text-decoration: none; + text-shadow: 0 1px 0 #ffffff; +} +.navbar .nav .dropdown-toggle .caret { + margin-top: 8px; +} +.navbar .nav > li > a:focus, +.navbar .nav > li > a:hover { + background-color: transparent; + color: #333; + text-decoration: none; +} +.navbar .nav > li > a:focus { + outline: 2px solid #5e9ed6; +} +.navbar .nav > .active > a, +.navbar .nav > .active > a:hover, +.navbar .nav > .active > a:focus { + color: #555; + text-decoration: none; + background-color: #e6e6e6; + -webkit-box-shadow: inset 0 3px 8px rgba(0,0,0,0.125); + -moz-box-shadow: inset 0 3px 8px rgba(0,0,0,0.125); + box-shadow: inset 0 3px 8px rgba(0,0,0,0.125); +} +.navbar .btn-navbar { + display: none; + float: right; + padding: 7px 10px; + margin-left: 5px; + margin-right: 5px; + background-color: #f2f2f2; + *background-color: #f2f2f2; + -webkit-box-shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.075); + -moz-box-shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.075); + box-shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.075); +} +.navbar .btn-navbar:hover, +.navbar .btn-navbar:focus, +.navbar .btn-navbar:active, +.navbar .btn-navbar.active, +.navbar .btn-navbar.disabled, +.navbar .btn-navbar[disabled] { + color: #fff; + background-color: #d9d9d9; + *background-color: #d9d9d9; +} +.navbar .btn-navbar:active, +.navbar .btn-navbar.active { + background-color: #f2f2f2; +} +.navbar .btn-navbar .icon-bar { + display: block; + width: 18px; + height: 2px; + background-color: #f5f5f5; + -webkit-border-radius: 1px; + -moz-border-radius: 1px; + border-radius: 1px; + -webkit-box-shadow: 0 1px 0 rgba(0,0,0,0.25); + -moz-box-shadow: 0 1px 0 rgba(0,0,0,0.25); + box-shadow: 0 1px 0 rgba(0,0,0,0.25); +} +.btn-navbar .icon-bar + .icon-bar { + margin-top: 3px; +} +.navbar .nav > li > .dropdown-menu:before { + content: ''; + display: inline-block; + border-left: 7px solid transparent; + border-right: 7px solid transparent; + border-bottom: 7px solid #ccc; + border-bottom-color: rgba(0,0,0,0.2); + position: absolute; + top: -7px; + left: 9px; +} +.navbar .nav > li > .dropdown-menu:after { + content: ''; + display: inline-block; + border-left: 6px solid transparent; + border-right: 6px solid transparent; + border-bottom: 6px solid #fff; + position: absolute; + top: -6px; + left: 10px; +} +.navbar-fixed-bottom .nav > li > .dropdown-menu:before { + border-top: 7px solid #ccc; + border-top-color: rgba(0,0,0,0.2); + border-bottom: 0; + bottom: -7px; + top: auto; +} +.navbar-fixed-bottom .nav > li > .dropdown-menu:after { + border-top: 6px solid #fff; + border-bottom: 0; + bottom: -6px; + top: auto; +} +.navbar .nav li.dropdown > a:hover .caret, +.navbar .nav li.dropdown > a:focus .caret { + border-top-color: #333; + border-bottom-color: #333; +} +.navbar .nav li.dropdown.open > .dropdown-toggle, +.navbar .nav li.dropdown.active > .dropdown-toggle, +.navbar .nav li.dropdown.open.active > .dropdown-toggle { + background-color: #e6e6e6; + color: #555; +} +.navbar .nav li.dropdown > .dropdown-toggle .caret { + border-top-color: #555; + border-bottom-color: #555; +} +.navbar .nav li.dropdown.open > .dropdown-toggle .caret, +.navbar .nav li.dropdown.active > .dropdown-toggle .caret, +.navbar .nav li.dropdown.open.active > .dropdown-toggle .caret { + border-top-color: #555; + border-bottom-color: #555; +} +.navbar .pull-right > li > .dropdown-menu, +.navbar .nav > li > .dropdown-menu.pull-right { + left: auto; + right: 0; +} +.navbar .pull-right > li > .dropdown-menu:before, +.navbar .nav > li > .dropdown-menu.pull-right:before { + left: auto; + right: 12px; +} +.navbar .pull-right > li > .dropdown-menu:after, +.navbar .nav > li > .dropdown-menu.pull-right:after { + left: auto; + right: 13px; +} +.navbar .pull-right > li > .dropdown-menu .dropdown-menu, +.navbar .nav > li > .dropdown-menu.pull-right .dropdown-menu { + left: auto; + right: 100%; + margin-left: 0; + margin-right: -1px; + -webkit-border-radius: 6px 0 6px 6px; + -moz-border-radius: 6px 0 6px 6px; + border-radius: 6px 0 6px 6px; +} +.navbar-inverse .navbar-inner { + background-color: #13294a; + background-image: -moz-linear-gradient(top,#152d53,#10223e); + background-image: -webkit-gradient(linear,0 0,0 100%,from(#152d53),to(#10223e)); + background-image: -webkit-linear-gradient(top,#152d53,#10223e); + background-image: -o-linear-gradient(top,#152d53,#10223e); + background-image: linear-gradient(to bottom,#152d53,#10223e); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff142c52', endColorstr='#ff0f213e', GradientType=0); + border-color: #0b172a; +} +.navbar-inverse .brand, +.navbar-inverse .nav > li > a { + color: #d9d9d9; + text-shadow: 0 -1px 0 rgba(0,0,0,0.25); +} +.navbar-inverse .brand:hover, +.navbar-inverse .brand:focus, +.navbar-inverse .nav > li > a:hover, +.navbar-inverse .nav > li > a:focus { + color: #fff; +} +.navbar-inverse .brand { + color: #d9d9d9; +} +.navbar-inverse .navbar-text { + color: #d9d9d9; +} +.navbar-inverse .nav > li > a:focus, +.navbar-inverse .nav > li > a:hover { + background-color: transparent; + color: #fff; +} +.navbar-inverse .nav .active > a, +.navbar-inverse .nav .active > a:hover, +.navbar-inverse .nav .active > a:focus { + color: #fff; + background-color: #10223e; +} +.navbar-inverse .navbar-link { + color: #d9d9d9; +} +.navbar-inverse .navbar-link:hover, +.navbar-inverse .navbar-link:focus { + color: #fff; +} +.navbar-inverse .divider-vertical { + border-left-color: #10223e; + border-right-color: #152d53; +} +.navbar-inverse .nav li.dropdown.open > .dropdown-toggle, +.navbar-inverse .nav li.dropdown.active > .dropdown-toggle, +.navbar-inverse .nav li.dropdown.open.active > .dropdown-toggle { + background-color: #10223e; + color: #fff; +} +.navbar-inverse .nav li.dropdown > a:hover .caret, +.navbar-inverse .nav li.dropdown > a:focus .caret { + border-top-color: #fff; + border-bottom-color: #fff; +} +.navbar-inverse .nav li.dropdown > .dropdown-toggle .caret { + border-top-color: #d9d9d9; + border-bottom-color: #d9d9d9; +} +.navbar-inverse .nav li.dropdown.open > .dropdown-toggle .caret, +.navbar-inverse .nav li.dropdown.active > .dropdown-toggle .caret, +.navbar-inverse .nav li.dropdown.open.active > .dropdown-toggle .caret { + border-top-color: #fff; + border-bottom-color: #fff; +} +.navbar-inverse .navbar-search .search-query { + color: #fff; + background-color: #2959a4; + border-color: #10223e; + -webkit-box-shadow: inset 0 1px 2px rgba(0,0,0,.1), 0 1px 0 rgba(255,255,255,.15); + -moz-box-shadow: inset 0 1px 2px rgba(0,0,0,.1), 0 1px 0 rgba(255,255,255,.15); + box-shadow: inset 0 1px 2px rgba(0,0,0,.1), 0 1px 0 rgba(255,255,255,.15); + -webkit-transition: none; + -moz-transition: none; + -o-transition: none; + transition: none; +} +.navbar-inverse .navbar-search .search-query:-moz-placeholder { + color: #ccc; +} +.navbar-inverse .navbar-search .search-query:-ms-input-placeholder { + color: #ccc; +} +.navbar-inverse .navbar-search .search-query::-webkit-input-placeholder { + color: #ccc; +} +.navbar-inverse .navbar-search .search-query:focus, +.navbar-inverse .navbar-search .search-query.focused { + padding: 5px 15px; + color: #333; + text-shadow: 0 1px 0 #fff; + background-color: #fff; + border: 0; + -webkit-box-shadow: 0 0 3px rgba(0,0,0,0.15); + -moz-box-shadow: 0 0 3px rgba(0,0,0,0.15); + box-shadow: 0 0 3px rgba(0,0,0,0.15); + outline: 0; +} +.navbar-inverse .btn-navbar { + background-color: #10223e; + *background-color: #10223e; +} +.navbar-inverse .btn-navbar:hover, +.navbar-inverse .btn-navbar:focus, +.navbar-inverse .btn-navbar:active, +.navbar-inverse .btn-navbar.active, +.navbar-inverse .btn-navbar.disabled, +.navbar-inverse .btn-navbar[disabled] { + color: #fff; + background-color: #050c16; + *background-color: #050c16; +} +.navbar-inverse .btn-navbar:active, +.navbar-inverse .btn-navbar.active { + background-color: #10223e; +} +.breadcrumb { + padding: 8px 15px; + margin: 0 0 18px; + list-style: none; + background-color: #f5f5f5; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} +.breadcrumb > li { + display: inline-block; + *display: inline; + *zoom: 1; + text-shadow: 0 1px 0 #fff; +} +.breadcrumb > li > .divider { + padding: 0 5px; + color: #ccc; +} +.breadcrumb > .active { + color: #999; +} +.pagination { + margin: 18px 0; +} +.pagination ul { + display: inline-block; + *display: inline; + *zoom: 1; + margin-left: 0; + margin-bottom: 0; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + -webkit-box-shadow: 0 1px 2px rgba(0,0,0,0.05); + -moz-box-shadow: 0 1px 2px rgba(0,0,0,0.05); + box-shadow: 0 1px 2px rgba(0,0,0,0.05); +} +.pagination ul > li { + display: inline; +} +.pagination ul > li > a, +.pagination ul > li > span { + float: left; + padding: 4px 12px; + line-height: 18px; + text-decoration: none; + background-color: #fff; + border: 1px solid #ddd; + border-left-width: 0; +} +.pagination ul > li > a:hover, +.pagination ul > li > a:focus, +.pagination ul > .active > a, +.pagination ul > .active > span { + background-color: #F0F0F0; +} +.pagination ul > .active > a, +.pagination ul > .active > span { + color: #999; + cursor: default; +} +.pagination ul > .disabled > span, +.pagination ul > .disabled > a, +.pagination ul > .disabled > a:hover, +.pagination ul > .disabled > a:focus { + color: #999; + background-color: transparent; + cursor: default; +} +.pagination ul > li:first-child > a, +.pagination ul > li:first-child > span { + border-left-width: 1px; + -webkit-border-top-left-radius: 3px; + -moz-border-radius-topleft: 3px; + border-top-left-radius: 3px; + -webkit-border-bottom-left-radius: 3px; + -moz-border-radius-bottomleft: 3px; + border-bottom-left-radius: 3px; +} +.pagination ul > li:last-child > a, +.pagination ul > li:last-child > span { + -webkit-border-top-right-radius: 3px; + -moz-border-radius-topright: 3px; + border-top-right-radius: 3px; + -webkit-border-bottom-right-radius: 3px; + -moz-border-radius-bottomright: 3px; + border-bottom-right-radius: 3px; +} +.pagination-centered { + text-align: center; +} +.pagination-right { + text-align: right; +} +.pagination-large ul > li > a, +.pagination-large ul > li > span { + padding: 11px 19px; + font-size: 16.25px; +} +.pagination-large ul > li:first-child > a, +.pagination-large ul > li:first-child > span { + -webkit-border-top-left-radius: 6px; + -moz-border-radius-topleft: 6px; + border-top-left-radius: 6px; + -webkit-border-bottom-left-radius: 6px; + -moz-border-radius-bottomleft: 6px; + border-bottom-left-radius: 6px; +} +.pagination-large ul > li:last-child > a, +.pagination-large ul > li:last-child > span { + -webkit-border-top-right-radius: 6px; + -moz-border-radius-topright: 6px; + border-top-right-radius: 6px; + -webkit-border-bottom-right-radius: 6px; + -moz-border-radius-bottomright: 6px; + border-bottom-right-radius: 6px; +} +.pagination-mini ul > li:first-child > a, +.pagination-mini ul > li:first-child > span, +.pagination-small ul > li:first-child > a, +.pagination-small ul > li:first-child > span { + -webkit-border-top-left-radius: 3px; + -moz-border-radius-topleft: 3px; + border-top-left-radius: 3px; + -webkit-border-bottom-left-radius: 3px; + -moz-border-radius-bottomleft: 3px; + border-bottom-left-radius: 3px; +} +.pagination-mini ul > li:last-child > a, +.pagination-mini ul > li:last-child > span, +.pagination-small ul > li:last-child > a, +.pagination-small ul > li:last-child > span { + -webkit-border-top-right-radius: 3px; + -moz-border-radius-topright: 3px; + border-top-right-radius: 3px; + -webkit-border-bottom-right-radius: 3px; + -moz-border-radius-bottomright: 3px; + border-bottom-right-radius: 3px; +} +.pagination-small ul > li > a, +.pagination-small ul > li > span { + padding: 2px 10px; + font-size: 12px; +} +.pagination-mini ul > li > a, +.pagination-mini ul > li > span { + padding: 0 6px; + font-size: 9.75px; +} +.pager { + margin: 18px 0; + list-style: none; + text-align: center; + *zoom: 1; +} +.pager:before, +.pager:after { + display: table; + content: ""; + line-height: 0; +} +.pager:after { + clear: both; +} +.pager li { + display: inline; +} +.pager li > a, +.pager li > span { + display: inline-block; + padding: 5px 14px; + background-color: #fff; + border: 1px solid #ddd; + -webkit-border-radius: 15px; + -moz-border-radius: 15px; + border-radius: 15px; +} +.pager li > a:hover, +.pager li > a:focus { + text-decoration: none; + background-color: #f5f5f5; +} +.pager .next > a, +.pager .next > span { + float: right; +} +.pager .previous > a, +.pager .previous > span { + float: left; +} +.pager .disabled > a, +.pager .disabled > a:hover, +.pager .disabled > a:focus, +.pager .disabled > span { + color: #999; + background-color: #fff; + cursor: default; +} +.modal-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1040; + background-color: #000; +} +.modal-backdrop.fade { + opacity: 0; +} +.modal-backdrop, +.modal-backdrop.fade.in { + opacity: 0.8; + filter: alpha(opacity=80); +} +.modal-header { + padding: 9px 15px; + border-bottom: 1px solid #eee; +} +.modal-header .close { + margin-top: 2px; +} +.modal-header h3 { + margin: 0; + line-height: 30px; +} +.modal-body { + width: 98%; + position: relative; + max-height: 400px; + padding: 1%; +} +.modal-body iframe { + width: 100%; + max-height: none; + border: 0 !important; +} +.modal-form { + margin-bottom: 0; +} +.modal-footer { + padding: 14px 15px 15px; + margin-bottom: 0; + text-align: right; + background-color: #f5f5f5; + border-top: 1px solid #ddd; + -webkit-border-radius: 0 0 6px 6px; + -moz-border-radius: 0 0 6px 6px; + border-radius: 0 0 6px 6px; + -webkit-box-shadow: inset 0 1px 0 #fff; + -moz-box-shadow: inset 0 1px 0 #fff; + box-shadow: inset 0 1px 0 #fff; + *zoom: 1; +} +.modal-footer:before, +.modal-footer:after { + display: table; + content: ""; + line-height: 0; +} +.modal-footer:after { + clear: both; +} +.modal-footer .btn + .btn { + margin-left: 5px; + margin-bottom: 0; +} +.modal-footer .btn-group .btn + .btn { + margin-left: -1px; +} +.modal-footer .btn-block + .btn-block { + margin-left: 0; +} +.tooltip { + position: absolute; + z-index: 1030; + display: block; + visibility: visible; + font-size: 11px; + line-height: 1.4; + opacity: 0; + filter: alpha(opacity=0); +} +.tooltip.in { + opacity: 0.8; + filter: alpha(opacity=80); +} +.tooltip.top { + margin-top: -3px; + padding: 5px 0; +} +.tooltip.right { + margin-left: 3px; + padding: 0 5px; +} +.tooltip.bottom { + margin-top: 3px; + padding: 5px 0; +} +.tooltip.left { + margin-left: -3px; + padding: 0 5px; +} +.tooltip-inner { + max-width: 200px; + padding: 8px; + color: #fff; + text-align: center; + text-decoration: none; + background-color: #000; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} +.tooltip-arrow { + position: absolute; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; +} +.tooltip.top .tooltip-arrow { + bottom: 0; + left: 50%; + margin-left: -5px; + border-width: 5px 5px 0; + border-top-color: #000; +} +.tooltip.right .tooltip-arrow { + top: 50%; + left: 0; + margin-top: -5px; + border-width: 5px 5px 5px 0; + border-right-color: #000; +} +.tooltip.left .tooltip-arrow { + top: 50%; + right: 0; + margin-top: -5px; + border-width: 5px 0 5px 5px; + border-left-color: #000; +} +.tooltip.bottom .tooltip-arrow { + top: 0; + left: 50%; + margin-left: -5px; + border-width: 0 5px 5px; + border-bottom-color: #000; +} +.popover { + position: absolute; + top: 0; + left: 0; + z-index: 1060; + display: none; + max-width: 276px; + padding: 1px; + text-align: left; + background-color: #fff; + -webkit-background-clip: padding-box; + -moz-background-clip: padding; + background-clip: padding-box; + border: 1px solid #ccc; + border: 1px solid rgba(0,0,0,0.2); + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; + -webkit-box-shadow: 0 5px 10px rgba(0,0,0,0.2); + -moz-box-shadow: 0 5px 10px rgba(0,0,0,0.2); + box-shadow: 0 5px 10px rgba(0,0,0,0.2); + white-space: normal; +} +.popover.top { + margin-top: -10px; +} +.popover.right { + margin-left: 10px; +} +.popover.bottom { + margin-top: 10px; +} +.popover.left { + margin-left: -10px; +} +.popover-title { + margin: 0; + padding: 8px 14px; + font-size: 14px; + font-weight: normal; + line-height: 18px; + background-color: #f7f7f7; + border-bottom: 1px solid #ebebeb; + -webkit-border-radius: 5px 5px 0 0; + -moz-border-radius: 5px 5px 0 0; + border-radius: 5px 5px 0 0; +} +.popover-title:empty { + display: none; +} +.popover-content { + padding: 9px 14px; +} +.popover .arrow, +.popover .arrow:after { + position: absolute; + display: block; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; +} +.popover .arrow { + border-width: 11px; +} +.popover .arrow:after { + border-width: 10px; + content: ""; +} +.popover.top .arrow { + left: 50%; + margin-left: -11px; + border-bottom-width: 0; + border-top-color: #999; + border-top-color: rgba(0,0,0,0.25); + bottom: -11px; +} +.popover.top .arrow:after { + bottom: 1px; + margin-left: -10px; + border-bottom-width: 0; + border-top-color: #fff; +} +.popover.right .arrow { + top: 50%; + left: -11px; + margin-top: -11px; + border-left-width: 0; + border-right-color: #999; + border-right-color: rgba(0,0,0,0.25); +} +.popover.right .arrow:after { + left: 1px; + bottom: -10px; + border-left-width: 0; + border-right-color: #fff; +} +.popover.bottom .arrow { + left: 50%; + margin-left: -11px; + border-top-width: 0; + border-bottom-color: #999; + border-bottom-color: rgba(0,0,0,0.25); + top: -11px; +} +.popover.bottom .arrow:after { + top: 1px; + margin-left: -10px; + border-top-width: 0; + border-bottom-color: #fff; +} +.popover.left .arrow { + top: 50%; + right: -11px; + margin-top: -11px; + border-right-width: 0; + border-left-color: #999; + border-left-color: rgba(0,0,0,0.25); +} +.popover.left .arrow:after { + right: 1px; + border-right-width: 0; + border-left-color: #fff; + bottom: -10px; +} +.thumbnails { + margin-left: -20px; + list-style: none; + *zoom: 1; +} +.thumbnails:before, +.thumbnails:after { + display: table; + content: ""; + line-height: 0; +} +.thumbnails:after { + clear: both; +} +.row-fluid .thumbnails { + margin-left: 0; +} +.thumbnails > li { + float: left; + margin-bottom: 18px; + margin-left: 20px; +} +.thumbnail { + display: block; + padding: 4px; + line-height: 18px; + border: 1px solid #ddd; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + -webkit-box-shadow: 0 1px 3px rgba(0,0,0,0.055); + -moz-box-shadow: 0 1px 3px rgba(0,0,0,0.055); + box-shadow: 0 1px 3px rgba(0,0,0,0.055); + -webkit-transition: all .2s ease-in-out; + -moz-transition: all .2s ease-in-out; + -o-transition: all .2s ease-in-out; + transition: all .2s ease-in-out; +} +a.thumbnail:hover, +a.thumbnail:focus { + border-color: #3071a9; + -webkit-box-shadow: 0 1px 4px rgba(0,105,214,0.25); + -moz-box-shadow: 0 1px 4px rgba(0,105,214,0.25); + box-shadow: 0 1px 4px rgba(0,105,214,0.25); +} +.thumbnail > img { + display: block; + max-width: 100%; + margin-left: auto; + margin-right: auto; +} +.thumbnail .caption { + padding: 9px; + color: #555; +} +.media, +.media-body { + overflow: hidden; + *overflow: visible; + zoom: 1; +} +.media, +.media .media { + margin-top: 15px; +} +.media:first-child { + margin-top: 0; +} +.media-object { + display: block; +} +.media-heading { + margin: 0 0 5px; +} +.media > .pull-left { + margin-right: 10px; +} +.media > .pull-right { + margin-left: 10px; +} +.media-list { + margin-left: 0; + list-style: none; +} +.label, +.badge { + display: inline-block; + padding: 2px 4px; + font-size: 10.998px; + font-weight: bold; + line-height: 14px; + color: #fff; + vertical-align: baseline; + white-space: nowrap; + text-shadow: 0 -1px 0 rgba(0,0,0,0.25); + background-color: #999; +} +.label { + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} +.badge { + padding-left: 9px; + padding-right: 9px; + -webkit-border-radius: 9px; + -moz-border-radius: 9px; + border-radius: 9px; +} +.label:empty, +.badge:empty { + display: none; +} +a.label:hover, +a.label:focus, +a.badge:hover, +a.badge:focus { + color: #fff; + text-decoration: none; + cursor: pointer; +} +.label-important, +.badge-important { + background-color: #a94442; +} +.label-important[href], +.badge-important[href] { + background-color: #843534; +} +.label-warning, +.badge-warning { + background-color: #f89406; +} +.label-warning[href], +.badge-warning[href] { + background-color: #c67605; +} +.label-success, +.badge-success { + background-color: #3c763d; +} +.label-success[href], +.badge-success[href] { + background-color: #2b542c; +} +.label-info, +.badge-info { + background-color: #31708f; +} +.label-info[href], +.badge-info[href] { + background-color: #245269; +} +.label-inverse, +.badge-inverse { + background-color: #333; +} +.label-inverse[href], +.badge-inverse[href] { + background-color: #1a1a1a; +} +.btn .label, +.btn .badge { + position: relative; + top: -1px; +} +.btn-mini .label, +.btn-mini .badge { + top: 0; +} +@-webkit-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +@-moz-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +@-ms-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +@-o-keyframes progress-bar-stripes { + from { + background-position: 0 0; + } + to { + background-position: 40px 0; + } +} +@keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +.progress { + overflow: hidden; + height: 18px; + margin-bottom: 18px; + background-color: #f7f7f7; + background-image: -moz-linear-gradient(top,#f5f5f5,#f9f9f9); + background-image: -webkit-gradient(linear,0 0,0 100%,from(#f5f5f5),to(#f9f9f9)); + background-image: -webkit-linear-gradient(top,#f5f5f5,#f9f9f9); + background-image: -o-linear-gradient(top,#f5f5f5,#f9f9f9); + background-image: linear-gradient(to bottom,#f5f5f5,#f9f9f9); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#fff9f9f9', GradientType=0); + -webkit-box-shadow: inset 0 1px 2px rgba(0,0,0,0.1); + -moz-box-shadow: inset 0 1px 2px rgba(0,0,0,0.1); + box-shadow: inset 0 1px 2px rgba(0,0,0,0.1); + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} +.progress .bar { + width: 0%; + height: 100%; + color: #fff; + float: left; + font-size: 12px; + text-align: center; + text-shadow: 0 -1px 0 rgba(0,0,0,0.25); + background-color: #0e90d2; + background-image: -moz-linear-gradient(top,#149bdf,#0480be); + background-image: -webkit-gradient(linear,0 0,0 100%,from(#149bdf),to(#0480be)); + background-image: -webkit-linear-gradient(top,#149bdf,#0480be); + background-image: -o-linear-gradient(top,#149bdf,#0480be); + background-image: linear-gradient(to bottom,#149bdf,#0480be); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff149bdf', endColorstr='#ff0480be', GradientType=0); + -webkit-box-shadow: inset 0 -1px 0 rgba(0,0,0,0.15); + -moz-box-shadow: inset 0 -1px 0 rgba(0,0,0,0.15); + box-shadow: inset 0 -1px 0 rgba(0,0,0,0.15); + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + -webkit-transition: width .6s ease; + -moz-transition: width .6s ease; + -o-transition: width .6s ease; + transition: width .6s ease; +} +.progress .bar + .bar { + -webkit-box-shadow: inset 1px 0 0 rgba(0,0,0,.15), inset 0 -1px 0 rgba(0,0,0,.15); + -moz-box-shadow: inset 1px 0 0 rgba(0,0,0,.15), inset 0 -1px 0 rgba(0,0,0,.15); + box-shadow: inset 1px 0 0 rgba(0,0,0,.15), inset 0 -1px 0 rgba(0,0,0,.15); +} +.progress-striped .bar { + background-color: #149bdf; + background-image: -webkit-gradient(linear,0 100%,100% 0,color-stop(.25,rgba(255,255,255,0.15)),color-stop(.25,transparent),color-stop(.5,transparent),color-stop(.5,rgba(255,255,255,0.15)),color-stop(.75,rgba(255,255,255,0.15)),color-stop(.75,transparent),to(transparent)); + background-image: -webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); + background-image: -moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); + background-image: -o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); + background-image: linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); + -webkit-background-size: 40px 40px; + -moz-background-size: 40px 40px; + -o-background-size: 40px 40px; + background-size: 40px 40px; +} +.progress.active .bar { + -webkit-animation: progress-bar-stripes 2s linear infinite; + -moz-animation: progress-bar-stripes 2s linear infinite; + -ms-animation: progress-bar-stripes 2s linear infinite; + -o-animation: progress-bar-stripes 2s linear infinite; + animation: progress-bar-stripes 2s linear infinite; +} +.progress-danger .bar, +.progress .bar-danger { + background-color: #dd514c; + background-image: -moz-linear-gradient(top,#ee5f5b,#c43c35); + background-image: -webkit-gradient(linear,0 0,0 100%,from(#ee5f5b),to(#c43c35)); + background-image: -webkit-linear-gradient(top,#ee5f5b,#c43c35); + background-image: -o-linear-gradient(top,#ee5f5b,#c43c35); + background-image: linear-gradient(to bottom,#ee5f5b,#c43c35); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b', endColorstr='#ffc43c35', GradientType=0); +} +.progress-danger.progress-striped .bar, +.progress-striped .bar-danger { + background-color: #ee5f5b; + background-image: -webkit-gradient(linear,0 100%,100% 0,color-stop(.25,rgba(255,255,255,0.15)),color-stop(.25,transparent),color-stop(.5,transparent),color-stop(.5,rgba(255,255,255,0.15)),color-stop(.75,rgba(255,255,255,0.15)),color-stop(.75,transparent),to(transparent)); + background-image: -webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); + background-image: -moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); + background-image: -o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); + background-image: linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); +} +.progress-success .bar, +.progress .bar-success { + background-color: #5eb95e; + background-image: -moz-linear-gradient(top,#62c462,#57a957); + background-image: -webkit-gradient(linear,0 0,0 100%,from(#62c462),to(#57a957)); + background-image: -webkit-linear-gradient(top,#62c462,#57a957); + background-image: -o-linear-gradient(top,#62c462,#57a957); + background-image: linear-gradient(to bottom,#62c462,#57a957); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462', endColorstr='#ff57a957', GradientType=0); +} +.progress-success.progress-striped .bar, +.progress-striped .bar-success { + background-color: #62c462; + background-image: -webkit-gradient(linear,0 100%,100% 0,color-stop(.25,rgba(255,255,255,0.15)),color-stop(.25,transparent),color-stop(.5,transparent),color-stop(.5,rgba(255,255,255,0.15)),color-stop(.75,rgba(255,255,255,0.15)),color-stop(.75,transparent),to(transparent)); + background-image: -webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); + background-image: -moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); + background-image: -o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); + background-image: linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); +} +.progress-info .bar, +.progress .bar-info { + background-color: #4bb1cf; + background-image: -moz-linear-gradient(top,#5bc0de,#339bb9); + background-image: -webkit-gradient(linear,0 0,0 100%,from(#5bc0de),to(#339bb9)); + background-image: -webkit-linear-gradient(top,#5bc0de,#339bb9); + background-image: -o-linear-gradient(top,#5bc0de,#339bb9); + background-image: linear-gradient(to bottom,#5bc0de,#339bb9); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff339bb9', GradientType=0); +} +.progress-info.progress-striped .bar, +.progress-striped .bar-info { + background-color: #5bc0de; + background-image: -webkit-gradient(linear,0 100%,100% 0,color-stop(.25,rgba(255,255,255,0.15)),color-stop(.25,transparent),color-stop(.5,transparent),color-stop(.5,rgba(255,255,255,0.15)),color-stop(.75,rgba(255,255,255,0.15)),color-stop(.75,transparent),to(transparent)); + background-image: -webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); + background-image: -moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); + background-image: -o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); + background-image: linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); +} +.progress-warning .bar, +.progress .bar-warning { + background-color: #faa732; + background-image: -moz-linear-gradient(top,#fbb450,#f89406); + background-image: -webkit-gradient(linear,0 0,0 100%,from(#fbb450),to(#f89406)); + background-image: -webkit-linear-gradient(top,#fbb450,#f89406); + background-image: -o-linear-gradient(top,#fbb450,#f89406); + background-image: linear-gradient(to bottom,#fbb450,#f89406); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffab44f', endColorstr='#fff89406', GradientType=0); +} +.progress-warning.progress-striped .bar, +.progress-striped .bar-warning { + background-color: #fbb450; + background-image: -webkit-gradient(linear,0 100%,100% 0,color-stop(.25,rgba(255,255,255,0.15)),color-stop(.25,transparent),color-stop(.5,transparent),color-stop(.5,rgba(255,255,255,0.15)),color-stop(.75,rgba(255,255,255,0.15)),color-stop(.75,transparent),to(transparent)); + background-image: -webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); + background-image: -moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); + background-image: -o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); + background-image: linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); +} +.accordion { + margin-bottom: 18px; +} +.accordion-group { + margin-bottom: 2px; + border: 1px solid #e5e5e5; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} +.accordion-heading { + border-bottom: 0; +} +.accordion-heading .accordion-toggle { + display: block; + padding: 8px 15px; +} +.accordion-toggle { + cursor: pointer; +} +.accordion-inner { + padding: 9px 15px; + border-top: 1px solid #e5e5e5; +} +.carousel { + position: relative; + margin-bottom: 18px; + line-height: 1; +} +.carousel-inner { + overflow: hidden; + width: 100%; + position: relative; +} +.carousel-inner > .item { + display: none; + position: relative; + -webkit-transition: .6s ease-in-out left; + -moz-transition: .6s ease-in-out left; + -o-transition: .6s ease-in-out left; + transition: .6s ease-in-out left; +} +.carousel-inner > .item > img, +.carousel-inner > .item > a > img { + display: block; + line-height: 1; +} +.carousel-inner > .active, +.carousel-inner > .next, +.carousel-inner > .prev { + display: block; +} +.carousel-inner > .active { + left: 0; +} +.carousel-inner > .next, +.carousel-inner > .prev { + position: absolute; + top: 0; + width: 100%; +} +.carousel-inner > .next { + left: 100%; +} +.carousel-inner > .prev { + left: -100%; +} +.carousel-inner > .next.left, +.carousel-inner > .prev.right { + left: 0; +} +.carousel-inner > .active.left { + left: -100%; +} +.carousel-inner > .active.right { + left: 100%; +} +.carousel-control { + position: absolute; + top: 40%; + left: 15px; + width: 40px; + height: 40px; + margin-top: -20px; + font-size: 60px; + font-weight: 100; + line-height: 30px; + color: #fff; + text-align: center; + background: #222; + border: 3px solid #fff; + -webkit-border-radius: 23px; + -moz-border-radius: 23px; + border-radius: 23px; + opacity: 0.5; + filter: alpha(opacity=50); +} +.carousel-control.right { + left: auto; + right: 15px; +} +.carousel-control:hover, +.carousel-control:focus { + color: #fff; + text-decoration: none; + opacity: 0.9; + filter: alpha(opacity=90); +} +.carousel-indicators { + position: absolute; + top: 15px; + right: 15px; + z-index: 5; + margin: 0; + list-style: none; +} +.carousel-indicators li { + display: block; + float: left; + width: 10px; + height: 10px; + margin-left: 5px; + text-indent: -999px; + background-color: #ccc; + background-color: rgba(255,255,255,0.25); + border-radius: 5px; +} +.carousel-indicators .active { + background-color: #fff; +} +.carousel-caption { + position: absolute; + left: 0; + right: 0; + bottom: 0; + padding: 15px; + background: #333; + background: rgba(0,0,0,0.75); +} +.carousel-caption h4, +.carousel-caption p { + color: #fff; + line-height: 18px; +} +.carousel-caption h4 { + margin: 0 0 5px; +} +.carousel-caption p { + margin-bottom: 0; +} +.hero-unit { + padding: 60px; + margin-bottom: 30px; + font-size: 18px; + font-weight: 200; + line-height: 27px; + color: inherit; + background-color: #eee; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} +.hero-unit h1 { + margin-bottom: 0; + font-size: 60px; + line-height: 1; + color: inherit; + letter-spacing: -1px; +} +.hero-unit li { + line-height: 27px; +} +.pull-right { + float: right; +} +.pull-left { + float: left; +} +.hide { + display: none; +} +.show { + display: block; +} +.invisible { + visibility: hidden; +} +.affix { + position: fixed; +} +@-ms-viewport { + width: device-width; +} +.hidden { + display: none; + visibility: hidden; +} +.visible-phone { + display: none !important; +} +.visible-tablet { + display: none !important; +} +.hidden-desktop { + display: none !important; +} +.visible-desktop { + display: inherit !important; +} +@media (min-width: 768px) and (max-width: 979px) { + .hidden-desktop { + display: inherit !important; + } + .visible-desktop { + display: none !important; + } + .visible-tablet { + display: inherit !important; + } + .hidden-tablet { + display: none !important; + } +} +@media (max-width: 767px) { + .hidden-desktop { + display: inherit !important; + } + .visible-desktop { + display: none !important; + } + .visible-phone { + display: inherit !important; + } + .hidden-phone { + display: none !important; + } +} +.visible-print { + display: none !important; +} +@media print { + .visible-print { + display: inherit !important; + } + .hidden-print { + display: none !important; + } +} +@media (max-width: 767px) { + body { + padding-left: 20px; + padding-right: 20px; + } + .navbar-fixed-top, + .navbar-fixed-bottom, + .navbar-static-top { + margin-left: -20px; + margin-right: -20px; + } + .container-fluid { + padding: 0; + } + .dl-horizontal dt { + float: none; + clear: none; + width: auto; + text-align: left; + } + .dl-horizontal dd { + margin-left: 0; + } + .dropdown-menu .menuitem-group { + background-color: #10223e; + color: #eee; + } + .container { + width: auto; + } + .row-fluid { + width: 100%; + } + .row, + .thumbnails { + margin-left: 0; + } + .thumbnails > li { + float: none; + margin-left: 0; + } + [class*="span"], + .uneditable-input[class*="span"], + .row-fluid [class*="span"] { + float: none; + display: block; + width: 100%; + margin-left: 0; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + } + .span12, + .row-fluid .span12 { + width: 100%; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + } + .row-fluid [class*="offset"]:first-child { + margin-left: 0; + } + .input-large, + .input-xlarge, + .input-xxlarge, + input[class*="span"], + select[class*="span"], + textarea[class*="span"], + .uneditable-input { + display: block; + width: 100%; + min-height: 28px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + } + .input-prepend input, + .input-append input, + .input-prepend input[class*="span"], + .input-append input[class*="span"] { + display: inline-block; + } + .controls-row [class*="span"] + [class*="span"] { + margin-left: 0; + } +} +@media (max-width: 480px) { + .nav-collapse { + -webkit-transform: translate3d(0,0,0); + } + .page-header h1 small { + display: block; + line-height: 18px; + } + input[type="checkbox"], + input[type="radio"] { + border: 1px solid #ccc; + } + .form-horizontal .control-label { + float: none; + width: auto; + padding-top: 0; + text-align: left; + } + .form-horizontal .controls { + margin-left: 0; + } + .form-horizontal .control-list { + padding-top: 0; + } + .form-horizontal .form-actions { + padding-left: 10px; + padding-right: 10px; + } + .tag-category input#filter-search, + .newsfeed-category input#filter-search { + width: auto; + margin-bottom: 9px; + } + .category-list input#filter-search { + width: auto; + } + .media .pull-left, + .media .pull-right { + float: none; + display: block; + margin-bottom: 10px; + } + .media-object { + margin-right: 0; + margin-left: 0; + } + .modal-header .close { + padding: 10px; + margin: -10px; + } + .carousel-caption { + position: static; + } +} +@media (min-width: 768px) and (max-width: 979px) { + .row { + margin-left: -20px; + *zoom: 1; + } + .row:before, + .row:after { + display: table; + content: ""; + line-height: 0; + } + .row:after { + clear: both; + } + [class*="span"] { + float: left; + min-height: 1px; + margin-left: 20px; + } + .container, + .navbar-static-top .container, + .navbar-fixed-top .container, + .navbar-fixed-bottom .container { + width: 724px; + } + .span12 { + width: 724px; + } + .span11 { + width: 662px; + } + .span10 { + width: 600px; + } + .span9 { + width: 538px; + } + .span8 { + width: 476px; + } + .span7 { + width: 414px; + } + .span6 { + width: 352px; + } + .span5 { + width: 290px; + } + .span4 { + width: 228px; + } + .span3 { + width: 166px; + } + .span2 { + width: 104px; + } + .span1 { + width: 42px; + } + .offset12 { + margin-left: 764px; + } + .offset11 { + margin-left: 702px; + } + .offset10 { + margin-left: 640px; + } + .offset9 { + margin-left: 578px; + } + .offset8 { + margin-left: 516px; + } + .offset7 { + margin-left: 454px; + } + .offset6 { + margin-left: 392px; + } + .offset5 { + margin-left: 330px; + } + .offset4 { + margin-left: 268px; + } + .offset3 { + margin-left: 206px; + } + .offset2 { + margin-left: 144px; + } + .offset1 { + margin-left: 82px; + } + .row-fluid { + width: 100%; + *zoom: 1; + } + .row-fluid:before, + .row-fluid:after { + display: table; + content: ""; + line-height: 0; + } + .row-fluid:after { + clear: both; + } + .row-fluid [class*="span"] { + display: block; + width: 100%; + min-height: 28px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + float: left; + margin-left: 2.76243094%; + *margin-left: 2.70923945%; + } + .row-fluid [class*="span"]:first-child { + margin-left: 0; + } + .row-fluid .controls-row [class*="span"] + [class*="span"] { + margin-left: 2.76243094%; + } + .row-fluid .span12 { + width: 100%; + *width: 99.94680851%; + } + .row-fluid .span11 { + width: 91.43646409%; + *width: 91.3832726%; + } + .row-fluid .span10 { + width: 82.87292818%; + *width: 82.81973669%; + } + .row-fluid .span9 { + width: 74.30939227%; + *width: 74.25620078%; + } + .row-fluid .span8 { + width: 65.74585635%; + *width: 65.69266486%; + } + .row-fluid .span7 { + width: 57.18232044%; + *width: 57.12912895%; + } + .row-fluid .span6 { + width: 48.61878453%; + *width: 48.56559304%; + } + .row-fluid .span5 { + width: 40.05524862%; + *width: 40.00205713%; + } + .row-fluid .span4 { + width: 31.49171271%; + *width: 31.43852122%; + } + .row-fluid .span3 { + width: 22.9281768%; + *width: 22.87498531%; + } + .row-fluid .span2 { + width: 14.36464088%; + *width: 14.31144939%; + } + .row-fluid .span1 { + width: 5.80110497%; + *width: 5.74791348%; + } + .row-fluid .offset12 { + margin-left: 105.52486188%; + *margin-left: 105.4184789%; + } + .row-fluid .offset12:first-child { + margin-left: 102.76243094%; + *margin-left: 102.65604796%; + } + .row-fluid .offset11 { + margin-left: 96.96132597%; + *margin-left: 96.85494299%; + } + .row-fluid .offset11:first-child { + margin-left: 94.19889503%; + *margin-left: 94.09251205%; + } + .row-fluid .offset10 { + margin-left: 88.39779006%; + *margin-left: 88.29140708%; + } + .row-fluid .offset10:first-child { + margin-left: 85.63535912%; + *margin-left: 85.52897614%; + } + .row-fluid .offset9 { + margin-left: 79.83425414%; + *margin-left: 79.72787116%; + } + .row-fluid .offset9:first-child { + margin-left: 77.0718232%; + *margin-left: 76.96544023%; + } + .row-fluid .offset8 { + margin-left: 71.27071823%; + *margin-left: 71.16433525%; + } + .row-fluid .offset8:first-child { + margin-left: 68.50828729%; + *margin-left: 68.40190431%; + } + .row-fluid .offset7 { + margin-left: 62.70718232%; + *margin-left: 62.60079934%; + } + .row-fluid .offset7:first-child { + margin-left: 59.94475138%; + *margin-left: 59.8383684%; + } + .row-fluid .offset6 { + margin-left: 54.14364641%; + *margin-left: 54.03726343%; + } + .row-fluid .offset6:first-child { + margin-left: 51.38121547%; + *margin-left: 51.27483249%; + } + .row-fluid .offset5 { + margin-left: 45.5801105%; + *margin-left: 45.47372752%; + } + .row-fluid .offset5:first-child { + margin-left: 42.81767956%; + *margin-left: 42.71129658%; + } + .row-fluid .offset4 { + margin-left: 37.01657459%; + *margin-left: 36.91019161%; + } + .row-fluid .offset4:first-child { + margin-left: 34.25414365%; + *margin-left: 34.14776067%; + } + .row-fluid .offset3 { + margin-left: 28.45303867%; + *margin-left: 28.3466557%; + } + .row-fluid .offset3:first-child { + margin-left: 25.69060773%; + *margin-left: 25.58422476%; + } + .row-fluid .offset2 { + margin-left: 19.88950276%; + *margin-left: 19.78311978%; + } + .row-fluid .offset2:first-child { + margin-left: 17.12707182%; + *margin-left: 17.02068884%; + } + .row-fluid .offset1 { + margin-left: 11.32596685%; + *margin-left: 11.21958387%; + } + .row-fluid .offset1:first-child { + margin-left: 8.56353591%; + *margin-left: 8.45715293%; + } + input, + textarea, + .uneditable-input { + margin-left: 0; + } + .controls-row [class*="span"] + [class*="span"] { + margin-left: 20px; + } + input.span12, + textarea.span12, + .uneditable-input.span12 { + width: 710px; + } + input.span11, + textarea.span11, + .uneditable-input.span11 { + width: 648px; + } + input.span10, + textarea.span10, + .uneditable-input.span10 { + width: 586px; + } + input.span9, + textarea.span9, + .uneditable-input.span9 { + width: 524px; + } + input.span8, + textarea.span8, + .uneditable-input.span8 { + width: 462px; + } + input.span7, + textarea.span7, + .uneditable-input.span7 { + width: 400px; + } + input.span6, + textarea.span6, + .uneditable-input.span6 { + width: 338px; + } + input.span5, + textarea.span5, + .uneditable-input.span5 { + width: 276px; + } + input.span4, + textarea.span4, + .uneditable-input.span4 { + width: 214px; + } + input.span3, + textarea.span3, + .uneditable-input.span3 { + width: 152px; + } + input.span2, + textarea.span2, + .uneditable-input.span2 { + width: 90px; + } + input.span1, + textarea.span1, + .uneditable-input.span1 { + width: 28px; + } +} +@media (min-width: 1200px) { + .row { + margin-left: -30px; + *zoom: 1; + } + .row:before, + .row:after { + display: table; + content: ""; + line-height: 0; + } + .row:after { + clear: both; + } + [class*="span"] { + float: left; + min-height: 1px; + margin-left: 30px; + } + .container, + .navbar-static-top .container, + .navbar-fixed-top .container, + .navbar-fixed-bottom .container { + width: 1170px; + } + .span12 { + width: 1170px; + } + .span11 { + width: 1070px; + } + .span10 { + width: 970px; + } + .span9 { + width: 870px; + } + .span8 { + width: 770px; + } + .span7 { + width: 670px; + } + .span6 { + width: 570px; + } + .span5 { + width: 470px; + } + .span4 { + width: 370px; + } + .span3 { + width: 270px; + } + .span2 { + width: 170px; + } + .span1 { + width: 70px; + } + .offset12 { + margin-left: 1230px; + } + .offset11 { + margin-left: 1130px; + } + .offset10 { + margin-left: 1030px; + } + .offset9 { + margin-left: 930px; + } + .offset8 { + margin-left: 830px; + } + .offset7 { + margin-left: 730px; + } + .offset6 { + margin-left: 630px; + } + .offset5 { + margin-left: 530px; + } + .offset4 { + margin-left: 430px; + } + .offset3 { + margin-left: 330px; + } + .offset2 { + margin-left: 230px; + } + .offset1 { + margin-left: 130px; + } + .row-fluid { + width: 100%; + *zoom: 1; + } + .row-fluid:before, + .row-fluid:after { + display: table; + content: ""; + line-height: 0; + } + .row-fluid:after { + clear: both; + } + .row-fluid [class*="span"] { + display: block; + width: 100%; + min-height: 28px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + float: left; + margin-left: 2.76243094%; + *margin-left: 2.70923945%; + } + .row-fluid [class*="span"]:first-child { + margin-left: 0; + } + .row-fluid .controls-row [class*="span"] + [class*="span"] { + margin-left: 2.76243094%; + } + .row-fluid .span12 { + width: 100%; + *width: 99.94680851%; + } + .row-fluid .span11 { + width: 91.43646409%; + *width: 91.3832726%; + } + .row-fluid .span10 { + width: 82.87292818%; + *width: 82.81973669%; + } + .row-fluid .span9 { + width: 74.30939227%; + *width: 74.25620078%; + } + .row-fluid .span8 { + width: 65.74585635%; + *width: 65.69266486%; + } + .row-fluid .span7 { + width: 57.18232044%; + *width: 57.12912895%; + } + .row-fluid .span6 { + width: 48.61878453%; + *width: 48.56559304%; + } + .row-fluid .span5 { + width: 40.05524862%; + *width: 40.00205713%; + } + .row-fluid .span4 { + width: 31.49171271%; + *width: 31.43852122%; + } + .row-fluid .span3 { + width: 22.9281768%; + *width: 22.87498531%; + } + .row-fluid .span2 { + width: 14.36464088%; + *width: 14.31144939%; + } + .row-fluid .span1 { + width: 5.80110497%; + *width: 5.74791348%; + } + .row-fluid .offset12 { + margin-left: 105.52486188%; + *margin-left: 105.4184789%; + } + .row-fluid .offset12:first-child { + margin-left: 102.76243094%; + *margin-left: 102.65604796%; + } + .row-fluid .offset11 { + margin-left: 96.96132597%; + *margin-left: 96.85494299%; + } + .row-fluid .offset11:first-child { + margin-left: 94.19889503%; + *margin-left: 94.09251205%; + } + .row-fluid .offset10 { + margin-left: 88.39779006%; + *margin-left: 88.29140708%; + } + .row-fluid .offset10:first-child { + margin-left: 85.63535912%; + *margin-left: 85.52897614%; + } + .row-fluid .offset9 { + margin-left: 79.83425414%; + *margin-left: 79.72787116%; + } + .row-fluid .offset9:first-child { + margin-left: 77.0718232%; + *margin-left: 76.96544023%; + } + .row-fluid .offset8 { + margin-left: 71.27071823%; + *margin-left: 71.16433525%; + } + .row-fluid .offset8:first-child { + margin-left: 68.50828729%; + *margin-left: 68.40190431%; + } + .row-fluid .offset7 { + margin-left: 62.70718232%; + *margin-left: 62.60079934%; + } + .row-fluid .offset7:first-child { + margin-left: 59.94475138%; + *margin-left: 59.8383684%; + } + .row-fluid .offset6 { + margin-left: 54.14364641%; + *margin-left: 54.03726343%; + } + .row-fluid .offset6:first-child { + margin-left: 51.38121547%; + *margin-left: 51.27483249%; + } + .row-fluid .offset5 { + margin-left: 45.5801105%; + *margin-left: 45.47372752%; + } + .row-fluid .offset5:first-child { + margin-left: 42.81767956%; + *margin-left: 42.71129658%; + } + .row-fluid .offset4 { + margin-left: 37.01657459%; + *margin-left: 36.91019161%; + } + .row-fluid .offset4:first-child { + margin-left: 34.25414365%; + *margin-left: 34.14776067%; + } + .row-fluid .offset3 { + margin-left: 28.45303867%; + *margin-left: 28.3466557%; + } + .row-fluid .offset3:first-child { + margin-left: 25.69060773%; + *margin-left: 25.58422476%; + } + .row-fluid .offset2 { + margin-left: 19.88950276%; + *margin-left: 19.78311978%; + } + .row-fluid .offset2:first-child { + margin-left: 17.12707182%; + *margin-left: 17.02068884%; + } + .row-fluid .offset1 { + margin-left: 11.32596685%; + *margin-left: 11.21958387%; + } + .row-fluid .offset1:first-child { + margin-left: 8.56353591%; + *margin-left: 8.45715293%; + } + input, + textarea, + .uneditable-input { + margin-left: 0; + } + .controls-row [class*="span"] + [class*="span"] { + margin-left: 30px; + } + input.span12, + textarea.span12, + .uneditable-input.span12 { + width: 1156px; + } + input.span11, + textarea.span11, + .uneditable-input.span11 { + width: 1056px; + } + input.span10, + textarea.span10, + .uneditable-input.span10 { + width: 956px; + } + input.span9, + textarea.span9, + .uneditable-input.span9 { + width: 856px; + } + input.span8, + textarea.span8, + .uneditable-input.span8 { + width: 756px; + } + input.span7, + textarea.span7, + .uneditable-input.span7 { + width: 656px; + } + input.span6, + textarea.span6, + .uneditable-input.span6 { + width: 556px; + } + input.span5, + textarea.span5, + .uneditable-input.span5 { + width: 456px; + } + input.span4, + textarea.span4, + .uneditable-input.span4 { + width: 356px; + } + input.span3, + textarea.span3, + .uneditable-input.span3 { + width: 256px; + } + input.span2, + textarea.span2, + .uneditable-input.span2 { + width: 156px; + } + input.span1, + textarea.span1, + .uneditable-input.span1 { + width: 56px; + } + .thumbnails { + margin-left: -30px; + } + .thumbnails > li { + margin-left: 30px; + } + .row-fluid .thumbnails { + margin-left: 0; + } +} +@media (max-width: 767px) { + body { + padding-top: 0; + } + .navbar-fixed-top, + .navbar-fixed-bottom { + position: static; + } + .navbar-fixed-top { + margin-bottom: 18px; + } + .navbar-fixed-bottom { + margin-top: 18px; + } + .navbar-fixed-top .navbar-inner, + .navbar-fixed-bottom .navbar-inner { + padding: 5px; + } + .navbar .container { + width: auto; + padding: 0; + } + .navbar .brand { + padding-left: 10px; + padding-right: 10px; + margin: 0 0 0 -5px; + } + .nav-collapse { + clear: both; + } + .nav-collapse .nav { + float: none; + margin: 0 0 9px; + } + .nav-collapse .nav > li { + float: none; + } + .nav-collapse .nav > li > a { + margin-bottom: 2px; + } + .nav-collapse .nav > .divider-vertical { + display: none; + } + .nav-collapse .nav .nav-header { + color: #555; + text-shadow: none; + } + .nav-collapse .nav > li > a, + .nav-collapse .dropdown-menu a { + padding: 9px 15px; + font-weight: bold; + color: #555; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + } + .nav-collapse .btn { + padding: 4px 10px 4px; + font-weight: normal; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + } + .nav-collapse .dropdown-menu li + li a { + margin-bottom: 2px; + } + .nav-collapse .nav > li > a:hover, + .nav-collapse .nav > li > a:focus, + .nav-collapse .dropdown-menu a:hover, + .nav-collapse .dropdown-menu a:focus { + background-color: #f2f2f2; + } + .navbar-inverse .nav-collapse .nav > li > a, + .navbar-inverse .nav-collapse .dropdown-menu a { + color: #d9d9d9; + } + .navbar-inverse .nav-collapse .nav > li > a:hover, + .navbar-inverse .nav-collapse .nav > li > a:focus, + .navbar-inverse .nav-collapse .dropdown-menu a:hover, + .navbar-inverse .nav-collapse .dropdown-menu a:focus { + background-color: #10223e; + } + .nav-collapse.in .btn-group { + margin-top: 5px; + padding: 0; + } + .nav-collapse .dropdown-menu { + position: static; + top: auto; + left: auto; + float: none; + display: none; + max-width: none; + margin: 0 15px; + padding: 0; + background-color: transparent; + border: none; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; + } + .nav-collapse .open > .dropdown-menu { + display: block; + } + .nav-collapse .dropdown-menu:before, + .nav-collapse .dropdown-menu:after { + display: none; + } + .nav-collapse .dropdown-menu .divider { + display: none; + } + .nav-collapse .nav > li > .dropdown-menu:before, + .nav-collapse .nav > li > .dropdown-menu:after { + display: none; + } + .nav-collapse .navbar-form, + .nav-collapse .navbar-search { + float: none; + padding: 9px 15px; + margin: 9px 0; + border-top: 1px solid #f2f2f2; + border-bottom: 1px solid #f2f2f2; + -webkit-box-shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1); + -moz-box-shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1); + box-shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1); + } + .navbar-inverse .nav-collapse .navbar-form, + .navbar-inverse .nav-collapse .navbar-search { + border-top-color: #10223e; + border-bottom-color: #10223e; + } + .navbar .nav-collapse .nav.pull-right { + float: none; + margin-left: 0; + } + .nav-collapse, + .nav-collapse.collapse { + overflow: hidden; + height: 0; + } + .navbar .btn-navbar { + display: block; + } + .navbar-static .navbar-inner { + padding-left: 10px; + padding-right: 10px; + } +} +@media (min-width: 768px) { + .nav-collapse.collapse { + height: auto !important; + overflow: visible !important; + } +} +.small { + font-size: 11px; +} +iframe, +svg { + max-width: 100%; +} +.nowrap { + white-space: nowrap; +} +.center, +.table td.center, +.table th.center { + text-align: center; +} +a.disabled, +a.disabled:hover { + color: #999999; + background-color: transparent; + cursor: default; + text-decoration: none; +} +.hero-unit { + text-align: center; +} +.hero-unit .lead { + margin-bottom: 18px; + font-size: 20px; + font-weight: 200; + line-height: 27px; +} +.btn .caret { + margin-bottom: 7px; +} +.btn.btn-micro .caret { + margin: 5px 0; +} +.blog-row-rule, +.blog-item-rule { + border: 0; +} +body.modal { + padding-top: 0; +} +.row-even, +.row-odd { + padding: 5px; + width: 99%; + border-bottom: 1px solid #ddd; +} +.row-odd { + background-color: transparent; +} +.row-even { + background-color: #f9f9f9; +} +.blog-row-rule, +.blog-item-rule { + border: 0; +} +.row-fluid .row-reveal { + visibility: hidden; +} +.row-fluid:hover .row-reveal { + visibility: visible; +} +.btn-wide { + width: 80%; +} +.nav-list > li.offset > a { + padding-left: 30px; + font-size: 12px; +} +.blog-row-rule, +.blog-item-rule { + border: 0; +} +.row-fluid .offset1 { + margin-left: 8.382978723%; +} +.row-fluid .offset2 { + margin-left: 16.89361702%; +} +.row-fluid .offset3 { + margin-left: 25.404255317%; +} +.row-fluid .offset4 { + margin-left: 33.914893614%; +} +.row-fluid .offset5 { + margin-left: 42.425531911%; +} +.row-fluid .offset6 { + margin-left: 50.93617020799999%; +} +.row-fluid .offset7 { + margin-left: 59.446808505%; +} +.row-fluid .offset8 { + margin-left: 67.95744680199999%; +} +.row-fluid .offset9 { + margin-left: 76.468085099%; +} +.row-fluid .offset10 { + margin-left: 84.97872339599999%; +} +.row-fluid .offset11 { + margin-left: 91.489361693%; +} +.navbar .nav > li > a.btn { + padding: 4px 10px; + line-height: 18px; +} +.nav-tabs.nav-dark { + border-bottom: 1px solid #333; + text-shadow: 1px 1px 1px #000; +} +.nav-tabs.nav-dark > li > a { + color: #F8F8F8; +} +.nav-tabs.nav-dark > li > a:hover { + border-color: #333 #333 #111; + background-color: #777777; +} +.nav-tabs.nav-dark > .active > a, +.nav-tabs.nav-dark > .active > a:hover { + color: #ffffff; + background-color: #555555; + border: 1px solid #222; + border-bottom-color: transparent; +} +.thumbnail.pull-left { + margin: 0 10px 10px 0; +} +.thumbnail.pull-right { + margin: 0 0 10px 10px; +} +.width-10 { + width: 10px; +} +.width-20 { + width: 20px; +} +.width-30 { + width: 30px; +} +.width-40 { + width: 40px; +} +.width-50 { + width: 50px; +} +.width-60 { + width: 60px; +} +.width-70 { + width: 70px; +} +.width-80 { + width: 80px; +} +.width-90 { + width: 90px; +} +.width-100 { + width: 100px; +} +.height-10 { + height: 10px; +} +.height-20 { + height: 20px; +} +.height-30 { + height: 30px; +} +.height-40 { + height: 40px; +} +.height-50 { + height: 50px; +} +.height-60 { + height: 60px; +} +.height-70 { + height: 70px; +} +.height-80 { + height: 80px; +} +.height-90 { + height: 90px; +} +.height-100 { + height: 100px; +} +hr.hr-condensed { + margin: 10px 0; +} +.list-striped, +.row-striped { + list-style: none; + line-height: 18px; + text-align: left; + vertical-align: middle; + border-top: 1px solid #ddd; + margin-left: 0; +} +.list-striped li, +.list-striped dd, +.row-striped .row, +.row-striped .row-fluid { + border-bottom: 1px solid #ddd; + padding: 8px; +} +.list-striped li:nth-child(odd), +.list-striped dd:nth-child(odd), +.row-striped .row:nth-child(odd), +.row-striped .row-fluid:nth-child(odd) { + background-color: #f9f9f9; +} +.list-striped li:hover, +.list-striped dd:hover, +.row-striped .row:hover, +.row-striped .row-fluid:hover { + background-color: #F0F0F0; +} +.row-striped .row-fluid { + width: 100%; + box-sizing: border-box; +} +.row-striped .row-fluid [class*="span"] { + min-height: 10px; +} +.row-striped .row-fluid [class*="span"] { + margin-left: 8px; +} +.row-striped .row-fluid [class*="span"]:first-child { + margin-left: 0; +} +.list-condensed li { + padding: 4px 5px; +} +.row-condensed .row, +.row-condensed .row-fluid { + padding: 4px 5px; +} +.list-bordered, +.row-bordered { + list-style: none; + line-height: 18px; + text-align: left; + vertical-align: middle; + margin-left: 0; + border: 1px solid #ddd; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} +.radio.btn-group input[type=radio] { + display: none; +} +.radio.btn-group > label { + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} +.radio.btn-group > label:first-of-type { + margin-left: 0; + -webkit-border-bottom-left-radius: 4px; + border-bottom-left-radius: 4px; + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-bottomleft: 4px; + -moz-border-radius-topleft: 4px; +} +fieldset.radio.btn-group { + padding-left: 0; +} +.iframe-bordered { + border: 1px solid #ddd; +} +.tab-content { + overflow: visible; +} +.tabs-left .tab-content { + overflow: auto; +} +.nav-tabs > li > span { + display: block; + margin-right: 2px; + padding-right: 12px; + padding-left: 12px; + padding-top: 8px; + padding-bottom: 8px; + line-height: 18px; + border: 1px solid transparent; + -webkit-border-radius: 4px 4px 0 0; + -moz-border-radius: 4px 4px 0 0; + border-radius: 4px 4px 0 0; +} +.btn-micro { + padding: 1px 4px; + font-size: 10px; + line-height: 8px; +} +.btn-group > .btn-micro { + font-size: 10px; +} +.tip-wrap { + max-width: 200px; + padding: 3px 8px; + color: #fff; + text-align: center; + text-decoration: none; + background-color: #000; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + z-index: 100; +} +.page-header { + margin: 2px 0px 10px 0px; + padding-bottom: 5px; +} +.input-prepend > .add-on, +.input-append > .add-on { + vertical-align: top; +} +.input-prepend .chzn-container-single .chzn-single { + -webkit-border-radius: 0 3px 3px 0; + -moz-border-radius: 0 3px 3px 0; + border-radius: 0 3px 3px 0; +} +.input-prepend .chzn-container-single .chzn-single-with-drop { + -webkit-border-radius: 0 3px 0 0; + -moz-border-radius: 0 3px 0 0; + border-radius: 0 3px 0 0; +} +.input-append .chzn-container-single .chzn-single { + -webkit-border-radius: 3px 0 0 3px; + -moz-border-radius: 3px 0 0 3px; + border-radius: 3px 0 0 3px; +} +.input-append .chzn-container-single .chzn-single-with-drop { + -webkit-border-radius: 3px 0 0 0; + -moz-border-radius: 3px 0 0 0; + border-radius: 3px 0 0 0; +} +.input-prepend.input-append .chzn-container-single .chzn-single, +.input-prepend.input-append .chzn-container-single .chzn-single-with-drop { + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.element-invisible { + position: absolute; + padding: 0; + margin: 0; + border: 0; + height: 1px; + width: 1px; + overflow: hidden; +} +.element-invisible:focus { + width: auto; + height: auto; + overflow: auto; + background: #eee; + color: #000; + padding: 1em; +} +.form-vertical .control-label { + float: none; + width: auto; + padding-right: 0; + padding-top: 0; + text-align: left; +} +.form-vertical .controls { + margin-left: 0; +} +.width-auto { + width: auto; +} +.btn-group .chzn-results { + white-space: normal; +} +.accordion-body.in:hover { + overflow: visible; +} +.invalid { + color: #9d261d; + font-weight: bold; +} +input.invalid { + border: 1px solid #9d261d; + background: #f2dede; +} +select.chzn-done.invalid + .chzn-container.chzn-container-single > a.chzn-single, +select.chzn-done.invalid + .chzn-container.chzn-container-multi > ul.chzn-choices { + border-color: #9d261d; + color: #9d261d; +} +.tooltip { + max-width: 400px; +} +.tooltip-inner { + max-width: none; + text-align: left; + text-shadow: none; +} +th .tooltip-inner { + font-weight: normal; +} +.tooltip.hasimage { + opacity: 1; +} +.tip-text { + text-align: left; +} +.btn-group > .btn + .dropdown-backdrop + .btn { + margin-left: -1px; +} +.btn-group > .btn + .dropdown-backdrop + .dropdown-toggle { + padding-left: 8px; + padding-right: 8px; + -webkit-box-shadow: inset 1px 0 0 rgba(255,255,255,.125), inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); + -moz-box-shadow: inset 1px 0 0 rgba(255,255,255,.125), inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); + box-shadow: inset 1px 0 0 rgba(255,255,255,.125), inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); + *padding-top: 5px; + *padding-bottom: 5px; +} +.btn-group > .btn-mini + .dropdown-backdrop + .dropdown-toggle { + padding-left: 5px; + padding-right: 5px; + *padding-top: 2px; + *padding-bottom: 2px; +} +.btn-group > .btn-small + .dropdown-backdrop + .dropdown-toggle { + *padding-top: 5px; + *padding-bottom: 4px; +} +.btn-group > .btn-large + .dropdown-backdrop + .dropdown-toggle { + padding-left: 12px; + padding-right: 12px; + *padding-top: 7px; + *padding-bottom: 7px; +} +.dropdown-menu { + text-align: left; +} +.alert-link { + font-weight: bold; +} +.alert .alert-link { + color: #66512c; +} +.alert-success .alert-link { + color: #2b542c; +} +.alert-danger .alert-link, +.alert-error .alert-link { + color: #843534; +} +.alert-info .alert-link { + color: #245269; +} +div.modal { + position: fixed; + top: 5%; + left: 50%; + z-index: 1050; + width: 80%; + margin-left: -40%; + background-color: #fff; + border: 1px solid #999; + border: 1px solid rgba(0,0,0,0.3); + *border: 1px solid #999; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; + -webkit-box-shadow: 0 3px 7px rgba(0,0,0,0.3); + -moz-box-shadow: 0 3px 7px rgba(0,0,0,0.3); + box-shadow: 0 3px 7px rgba(0,0,0,0.3); + -webkit-background-clip: padding-box; + -moz-background-clip: padding-box; + background-clip: padding-box; + outline: none; +} +div.modal.fade { + -webkit-transition: opacity .3s linear, top .3s ease-out; + -moz-transition: opacity .3s linear, top .3s ease-out; + -o-transition: opacity .3s linear, top .3s ease-out; + transition: opacity .3s linear, top .3s ease-out; + top: -25%; +} +div.modal.fade.in { + top: 5%; +} +.modal-batch { + overflow-y: visible; +} +.modal-body[class^="jviewport-height"], +.modal-body[class*="jviewport-height"] { + max-height: none; +} +.jviewport-height10 { + height: 10vh; +} +.jviewport-height20 { + height: 20vh; +} +.jviewport-height30 { + height: 30vh; +} +.jviewport-height40 { + height: 40vh; +} +.jviewport-height50 { + height: 50vh; +} +.jviewport-height60 { + height: 60vh; +} +.jviewport-height70 { + height: 70vh; +} +.jviewport-height80 { + height: 80vh; +} +.jviewport-height90 { + height: 90vh; +} +.jviewport-height100 { + height: 100vh; +} +div.modal.jviewport-width10 { + width: 10vw; + margin-left: -5vw; +} +div.modal.jviewport-width20 { + width: 20vw; + margin-left: -10vw; +} +div.modal.jviewport-width30 { + width: 30vw; + margin-left: -15vw; +} +div.modal.jviewport-width40 { + width: 40vw; + margin-left: -20vw; +} +div.modal.jviewport-width50 { + width: 50vw; + margin-left: -25vw; +} +div.modal.jviewport-width60 { + width: 60vw; + margin-left: -30vw; +} +div.modal.jviewport-width70 { + width: 70vw; + margin-left: -35vw; +} +div.modal.jviewport-width80 { + width: 80vw; + margin-left: -40vw; +} +div.modal.jviewport-width90 { + width: 90vw; + margin-left: -45vw; +} +div.modal.jviewport-width100 { + width: 100vw; + margin-left: -50vw; +} +@media (max-width: 767px) { + div.modal { + position: fixed; + top: 20px; + left: 20px; + right: 20px; + width: auto; + margin: 0; + } + div.modal.fade { + top: -100px; + } + div.modal.fade.in { + top: 20px; + } + div.modal[class*="jviewport-width"] { + width: auto; + margin: 0; + } +} +@media (max-width: 480px) { + div.modal { + top: 10px; + left: 10px; + right: 10px; + } +} +@font-face { + font-family: 'IcoMoon'; + src: url('../../../../media/jui/fonts/IcoMoon.eot'); + src: url('../../../../media/jui/fonts/IcoMoon.eot?#iefix') format('embedded-opentype'), url('../../../../media/jui/fonts/IcoMoon.woff') format('woff'), url('../../../../media/jui/fonts/IcoMoon.ttf') format('truetype'), url('../../../../media/jui/fonts/IcoMoon.svg#IcoMoon') format('svg'); + font-weight: normal; + font-style: normal; +} +[data-icon]:before { + font-family: 'IcoMoon'; + content: attr(data-icon); + speak: none; +} +[class^="icon-"], +[class*=" icon-"] { + display: inline-block; + width: 14px; + height: 14px; + margin-right: .25em; + line-height: 14px; +} +[class^="icon-"]:before, +[class*=" icon-"]:before { + font-family: 'IcoMoon'; + font-style: normal; + speak: none; +} +[class^="icon-"].disabled, +[class*=" icon-"].disabled { + font-weight: normal; +} +.icon-joomla:before { + content: "\e200"; +} +.icon-chevron-up:before, +.icon-uparrow:before, +.icon-arrow-up:before { + content: "\e005"; +} +.icon-chevron-right:before, +.icon-rightarrow:before, +.icon-arrow-right:before { + content: "\e006"; +} +.icon-chevron-down:before, +.icon-downarrow:before, +.icon-arrow-down:before { + content: "\e007"; +} +.icon-chevron-left:before, +.icon-leftarrow:before, +.icon-arrow-left:before { + content: "\e008"; +} +.icon-arrow-first:before { + content: "\e003"; +} +.icon-arrow-last:before { + content: "\e004"; +} +.icon-arrow-up-2:before { + content: "\e009"; +} +.icon-arrow-right-2:before { + content: "\e00a"; +} +.icon-arrow-down-2:before { + content: "\e00b"; +} +.icon-arrow-left-2:before { + content: "\e00c"; +} +.icon-arrow-up-3:before { + content: "\e00f"; +} +.icon-arrow-right-3:before { + content: "\e010"; +} +.icon-arrow-down-3:before { + content: "\e011"; +} +.icon-arrow-left-3:before { + content: "\e012"; +} +.icon-menu-2:before { + content: "\e00e"; +} +.icon-arrow-up-4:before { + content: "\e201"; +} +.icon-arrow-right-4:before { + content: "\e202"; +} +.icon-arrow-down-4:before { + content: "\e203"; +} +.icon-arrow-left-4:before { + content: "\e204"; +} +.icon-share:before, +.icon-redo:before { + content: "\27"; +} +.icon-undo:before { + content: "\28"; +} +.icon-forward-2:before { + content: "\e205"; +} +.icon-backward-2:before, +.icon-reply:before { + content: "\e206"; +} +.icon-unblock:before, +.icon-refresh:before, +.icon-redo-2:before { + content: "\6c"; +} +.icon-undo-2:before { + content: "\e207"; +} +.icon-move:before { + content: "\7a"; +} +.icon-expand:before { + content: "\66"; +} +.icon-contract:before { + content: "\67"; +} +.icon-expand-2:before { + content: "\68"; +} +.icon-contract-2:before { + content: "\69"; +} +.icon-play:before { + content: "\e208"; +} +.icon-pause:before { + content: "\e209"; +} +.icon-stop:before { + content: "\e210"; +} +.icon-previous:before, +.icon-backward:before { + content: "\7c"; +} +.icon-next:before, +.icon-forward:before { + content: "\7b"; +} +.icon-first:before { + content: "\7d"; +} +.icon-last:before { + content: "\e000"; +} +.icon-play-circle:before { + content: "\e00d"; +} +.icon-pause-circle:before { + content: "\e211"; +} +.icon-stop-circle:before { + content: "\e212"; +} +.icon-backward-circle:before { + content: "\e213"; +} +.icon-forward-circle:before { + content: "\e214"; +} +.icon-loop:before { + content: "\e001"; +} +.icon-shuffle:before { + content: "\e002"; +} +.icon-search:before { + content: "\53"; +} +.icon-zoom-in:before { + content: "\64"; +} +.icon-zoom-out:before { + content: "\65"; +} +.icon-apply:before, +.icon-edit:before, +.icon-pencil:before { + content: "\2b"; +} +.icon-pencil-2:before { + content: "\2c"; +} +.icon-brush:before { + content: "\3b"; +} +.icon-save-new:before, +.icon-plus-2:before { + content: "\5d"; +} +.icon-minus-sign:before, +.icon-minus-2:before { + content: "\5e"; +} +.icon-delete:before, +.icon-remove:before, +.icon-cancel-2:before { + content: "\49"; +} +.icon-publish:before, +.icon-save:before, +.icon-ok:before, +.icon-checkmark:before { + content: "\47"; +} +.icon-new:before, +.icon-plus:before { + content: "\2a"; +} +.icon-plus-circle:before { + content: "\e215"; +} +.icon-minus:before, +.icon-not-ok:before { + content: "\4b"; +} +.icon-ban-circle:before, +.icon-minus-circle:before { + content: "\e216"; +} +.icon-unpublish:before, +.icon-cancel:before { + content: "\4a"; +} +.icon-cancel-circle:before { + content: "\e217"; +} +.icon-checkmark-2:before { + content: "\e218"; +} +.icon-checkmark-circle:before { + content: "\e219"; +} +.icon-info:before { + content: "\e220"; +} +.icon-info-2:before, +.icon-info-circle:before { + content: "\e221"; +} +.icon-question:before, +.icon-question-sign:before, +.icon-help:before { + content: "\45"; +} +.icon-question-2:before, +.icon-question-circle:before { + content: "\e222"; +} +.icon-notification:before { + content: "\e223"; +} +.icon-notification-2:before, +.icon-notification-circle:before { + content: "\e224"; +} +.icon-pending:before, +.icon-warning:before { + content: "\48"; +} +.icon-warning-2:before, +.icon-warning-circle:before { + content: "\e225"; +} +.icon-checkbox-unchecked:before { + content: "\3d"; +} +.icon-checkin:before, +.icon-checkbox:before, +.icon-checkbox-checked:before { + content: "\3e"; +} +.icon-checkbox-partial:before { + content: "\3f"; +} +.icon-square:before { + content: "\e226"; +} +.icon-radio-unchecked:before { + content: "\e227"; +} +.icon-radio-checked:before, +.icon-generic:before { + content: "\e228"; +} +.icon-circle:before { + content: "\e229"; +} +.icon-signup:before { + content: "\e230"; +} +.icon-grid:before, +.icon-grid-view:before { + content: "\58"; +} +.icon-grid-2:before, +.icon-grid-view-2:before { + content: "\59"; +} +.icon-menu:before { + content: "\5a"; +} +.icon-list:before, +.icon-list-view:before { + content: "\31"; +} +.icon-list-2:before { + content: "\e231"; +} +.icon-menu-3:before { + content: "\e232"; +} +.icon-folder-open:before, +.icon-folder:before { + content: "\2d"; +} +.icon-folder-close:before, +.icon-folder-2:before { + content: "\2e"; +} +.icon-folder-plus:before { + content: "\e234"; +} +.icon-folder-minus:before { + content: "\e235"; +} +.icon-folder-3:before { + content: "\e236"; +} +.icon-folder-plus-2:before { + content: "\e237"; +} +.icon-folder-remove:before { + content: "\e238"; +} +.icon-file:before { + content: "\e016"; +} +.icon-file-2:before { + content: "\e239"; +} +.icon-file-add:before, +.icon-file-plus:before { + content: "\29"; +} +.icon-file-minus:before { + content: "\e017"; +} +.icon-file-check:before { + content: "\e240"; +} +.icon-file-remove:before { + content: "\e241"; +} +.icon-save-copy:before, +.icon-copy:before { + content: "\e018"; +} +.icon-stack:before { + content: "\e242"; +} +.icon-tree:before { + content: "\e243"; +} +.icon-tree-2:before { + content: "\e244"; +} +.icon-paragraph-left:before { + content: "\e246"; +} +.icon-paragraph-center:before { + content: "\e247"; +} +.icon-paragraph-right:before { + content: "\e248"; +} +.icon-paragraph-justify:before { + content: "\e249"; +} +.icon-screen:before { + content: "\e01c"; +} +.icon-tablet:before { + content: "\e01d"; +} +.icon-mobile:before { + content: "\e01e"; +} +.icon-box-add:before { + content: "\51"; +} +.icon-box-remove:before { + content: "\52"; +} +.icon-download:before { + content: "\e021"; +} +.icon-upload:before { + content: "\e022"; +} +.icon-home:before { + content: "\21"; +} +.icon-home-2:before { + content: "\e250"; +} +.icon-out-2:before, +.icon-new-tab:before { + content: "\e024"; +} +.icon-out-3:before, +.icon-new-tab-2:before { + content: "\e251"; +} +.icon-link:before { + content: "\e252"; +} +.icon-picture:before, +.icon-image:before { + content: "\2f"; +} +.icon-pictures:before, +.icon-images:before { + content: "\30"; +} +.icon-palette:before, +.icon-color-palette:before { + content: "\e014"; +} +.icon-camera:before { + content: "\55"; +} +.icon-camera-2:before, +.icon-video:before { + content: "\e015"; +} +.icon-play-2:before, +.icon-video-2:before, +.icon-youtube:before { + content: "\56"; +} +.icon-music:before { + content: "\57"; +} +.icon-user:before { + content: "\22"; +} +.icon-users:before { + content: "\e01f"; +} +.icon-vcard:before { + content: "\6d"; +} +.icon-address:before { + content: "\70"; +} +.icon-share-alt:before, +.icon-out:before { + content: "\26"; +} +.icon-enter:before { + content: "\e257"; +} +.icon-exit:before { + content: "\e258"; +} +.icon-comment:before, +.icon-comments:before { + content: "\24"; +} +.icon-comments-2:before { + content: "\25"; +} +.icon-quote:before, +.icon-quotes-left:before { + content: "\60"; +} +.icon-quote-2:before, +.icon-quotes-right:before { + content: "\61"; +} +.icon-quote-3:before, +.icon-bubble-quote:before { + content: "\e259"; +} +.icon-phone:before { + content: "\e260"; +} +.icon-phone-2:before { + content: "\e261"; +} +.icon-envelope:before, +.icon-mail:before { + content: "\4d"; +} +.icon-envelope-opened:before, +.icon-mail-2:before { + content: "\4e"; +} +.icon-unarchive:before, +.icon-drawer:before { + content: "\4f"; +} +.icon-archive:before, +.icon-drawer-2:before { + content: "\50"; +} +.icon-briefcase:before { + content: "\e020"; +} +.icon-tag:before { + content: "\e262"; +} +.icon-tag-2:before { + content: "\e263"; +} +.icon-tags:before { + content: "\e264"; +} +.icon-tags-2:before { + content: "\e265"; +} +.icon-options:before, +.icon-cog:before { + content: "\38"; +} +.icon-cogs:before { + content: "\37"; +} +.icon-screwdriver:before, +.icon-tools:before { + content: "\36"; +} +.icon-wrench:before { + content: "\3a"; +} +.icon-equalizer:before { + content: "\39"; +} +.icon-dashboard:before { + content: "\78"; +} +.icon-switch:before { + content: "\e266"; +} +.icon-filter:before { + content: "\54"; +} +.icon-purge:before, +.icon-trash:before { + content: "\4c"; +} +.icon-checkedout:before, +.icon-lock:before, +.icon-locked:before { + content: "\23"; +} +.icon-unlock:before { + content: "\e267"; +} +.icon-key:before { + content: "\5f"; +} +.icon-support:before { + content: "\46"; +} +.icon-database:before { + content: "\62"; +} +.icon-scissors:before { + content: "\e268"; +} +.icon-health:before { + content: "\6a"; +} +.icon-wand:before { + content: "\6b"; +} +.icon-eye-open:before, +.icon-eye:before { + content: "\3c"; +} +.icon-eye-close:before, +.icon-eye-blocked:before, +.icon-eye-2:before { + content: "\e269"; +} +.icon-clock:before { + content: "\6e"; +} +.icon-compass:before { + content: "\6f"; +} +.icon-broadcast:before, +.icon-connection:before, +.icon-wifi:before { + content: "\e01b"; +} +.icon-book:before { + content: "\e271"; +} +.icon-lightning:before, +.icon-flash:before { + content: "\79"; +} +.icon-print:before, +.icon-printer:before { + content: "\e013"; +} +.icon-feed:before { + content: "\71"; +} +.icon-calendar:before { + content: "\43"; +} +.icon-calendar-2:before { + content: "\44"; +} +.icon-calendar-3:before { + content: "\e273"; +} +.icon-pie:before { + content: "\77"; +} +.icon-bars:before { + content: "\76"; +} +.icon-chart:before { + content: "\75"; +} +.icon-power-cord:before { + content: "\32"; +} +.icon-cube:before { + content: "\33"; +} +.icon-puzzle:before { + content: "\34"; +} +.icon-attachment:before, +.icon-paperclip:before, +.icon-flag-2:before { + content: "\72"; +} +.icon-lamp:before { + content: "\74"; +} +.icon-pin:before, +.icon-pushpin:before { + content: "\73"; +} +.icon-location:before { + content: "\63"; +} +.icon-shield:before { + content: "\e274"; +} +.icon-flag:before { + content: "\35"; +} +.icon-flag-3:before { + content: "\e275"; +} +.icon-bookmark:before { + content: "\e023"; +} +.icon-bookmark-2:before { + content: "\e276"; +} +.icon-heart:before { + content: "\e277"; +} +.icon-heart-2:before { + content: "\e278"; +} +.icon-thumbs-up:before { + content: "\5b"; +} +.icon-thumbs-down:before { + content: "\5c"; +} +.icon-unfeatured:before, +.icon-asterisk:before, +.icon-star-empty:before { + content: "\40"; +} +.icon-star-2:before { + content: "\41"; +} +.icon-featured:before, +.icon-default:before, +.icon-star:before { + content: "\42"; +} +.icon-smiley:before, +.icon-smiley-happy:before { + content: "\e279"; +} +.icon-smiley-2:before, +.icon-smiley-happy-2:before { + content: "\e280"; +} +.icon-smiley-sad:before { + content: "\e281"; +} +.icon-smiley-sad-2:before { + content: "\e282"; +} +.icon-smiley-neutral:before { + content: "\e283"; +} +.icon-smiley-neutral-2:before { + content: "\e284"; +} +.icon-cart:before { + content: "\e019"; +} +.icon-basket:before { + content: "\e01a"; +} +.icon-credit:before { + content: "\e286"; +} +.icon-credit-2:before { + content: "\e287"; +} +.icon-expired:before { + content: "\4b"; +} +.icon-edit:before { + color: #24748c; +} +.icon-publish:before, +.icon-save:before, +.icon-ok:before, +.icon-save-new:before, +.icon-save-copy:before, +.btn-toolbar .icon-copy:before { + color: #378137; +} +.icon-unpublish:before, +.icon-not-ok:before, +.icon-eye-close:before, +.icon-ban-circle:before, +.icon-minus-sign:before, +.btn-toolbar .icon-cancel:before { + color: #942a25; +} +.icon-featured:before, +.icon-default:before, +.icon-expired:before, +.icon-pending:before { + color: #c67605; +} +.icon-back:before { + content: "\e008"; +} +html { + height: 100%; +} +body { + height: 100%; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + box-sizing: border-box; +} +a:hover, +a:active, +a:focus { + outline: none; +} +.small { + font-size: 11px; +} +.row-even .small, +.row-odd .small, +.row-even .small a, +.row-odd .small a { + color: #888; +} +.content-title { + font-size: 24px; + font-weight: normal; + line-height: 26px; + margin-top: 0; +} +.well .page-header { + margin: -10px 0 18px 0; + padding-bottom: 5px; +} +.well .module-title.nav-header { + padding: 0 0 7px; + margin: 0; + font-size: 13px; +} +.well .row-even p, +.well .row-odd p { + margin-bottom: 0; +} +h1, +h2, +h3, +h4, +h5, +h6 { + margin: 12px 0; +} +h1 { + font-size: 26px; + line-height: 28px; +} +h2 { + font-size: 22px; + line-height: 24px; +} +h3 { + font-size: 18px; + line-height: 20px; +} +h4 { + font-size: 14px; + line-height: 16px; +} +h5 { + font-size: 13px; + line-height: 15px; +} +h6 { + font-size: 12px; + line-height: 14px; +} +.truncate { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} +.chzn-container .chzn-drop { + border-radius: 0 0 3px 3px; +} +.control-group .chzn-container { + max-width: 100%; +} +.control-group .chzn-container .chzn-choices li.search-field, +.control-group .chzn-container .chzn-choices li.search-field input { + width: 100% !important; +} +.chzn-container-single .chzn-single { + background-color: #fff; + background-clip: inherit; + background-image: none; + border: 1px solid #ccc; + border: 1px solid rgba(0,0,0,0.2); + border-radius: 3px; + box-shadow: 0 1px 0 rgba(255,255,255,0.2) inset, 0 1px 2px rgba(0,0,0,0.05); + height: auto; + line-height: 26px; +} +.chzn-container-single .chzn-single div { + background-color: #f3f3f3; + border-left: 1px solid #ccc; + bottom: 0; + height: auto; + text-align: center; + width: 28px; +} +.chzn-container-single .chzn-single div b { + background-image: none; + display: inline-block; +} +.chzn-container-single .chzn-single div b:after { + content: '\E011'; + font-family: IcoMoon; +} +.chzn-container-single .chzn-single abbr { + background: none; + right: 36px; + top: 0; +} +.chzn-container-single .chzn-single abbr:before { + font-family: IcoMoon; + content: '\0049'; + font-size: 10px; + line-height: 26px; +} +.chzn-container-single .chzn-single abbr:hover { + color: #000; +} +.chzn-container-single .chzn-search:after { + content: '\0053'; + font-family: IcoMoon; + position: relative; + right: 20px; + top: 2px; +} +.chzn-container-single .chzn-search input[type="text"] { + background: none; + border-radius: 3px; + border: 1px solid #ccc; + box-shadow: none; + height: 25px; +} +.chzn-container-single .chzn-search input[type="text"]:focus { + border-color: #3071A9; +} +.chzn-container-single .chzn-drop { + background-clip: padding-box; + border-color: #3071A9; + border-radius: 0 0 3px 3px; +} +.chzn-container-active .chzn-single { + color: #3071A9; +} +.chzn-container-active.chzn-with-drop .chzn-single { + background-image: none; + border: 1px solid #3071A9; + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; +} +.chzn-container-active.chzn-with-drop .chzn-single div { + background-color: #f3f3f3; + border-bottom: 1px solid #ccc; + border-bottom-left-radius: 3px; + border-left: 1px solid #ccc; +} +.chzn-container-active.chzn-with-drop .chzn-single div b:after { + content: '\E00F'; + font-family: IcoMoon; +} +.chzn-container-active.chzn-container-multi .chzn-choices { + border: 1px solid #3071A9; + box-shadow: none; +} +.chzn-container .chzn-results { + background-color: #fff; + border-radius: 0 0 3px 3px; + margin: 0; + padding: 0; +} +.chzn-container .chzn-results li.highlighted { + background-color: #3071A9; + background-image: none; +} +.chzn-color[rel="value_"] div { + background-color: #f3f3f3; + border-left: 1px solid #ccc; +} +.chzn-color-state.chzn-single div, +.chzn-color.chzn-single[rel="value_0"] div, +.chzn-color.chzn-single[rel="value_1"] div, +.chzn-color-state.chzn-single[rel="value_-1"] div, +.chzn-color-state.chzn-single[rel="value_-2"] div, +.chzn-color.chzn-single[rel="value_hide"] div, +.chzn-color.chzn-single[rel="value_show_no_link"] div, +.chzn-color.chzn-single[rel="value_show_with_link"] div { + background-color: transparent !important; + border: none !important; +} +.chzn-container-active .chzn-choices { + border: 1px solid #3071A9; +} +.chzn-container-multi .chzn-choices { + background-image: none; + border-radius: 3px; + border: 1px solid #ccc; +} +.chzn-container-multi .chzn-choices li.search-choice { + background-color: #3071A9; + background-image: none; + border: 0; + box-shadow: none; + color: #fff; + line-height: 20px; + padding: 0 7px; +} +.chzn-container-multi .chzn-choices li.search-choice .search-choice-close { + color: #f5f5f5; + display: inline-block; + margin-left: 5px; + position: relative; + top: 0; + left: 0; + background-image: none; + font-size: inherit; +} +.chzn-container-multi .chzn-choices li.search-choice .search-choice-close:hover { + text-decoration: none; +} +.chzn-container-multi .chzn-choices li.search-choice .search-choice-close:before { + font-family: IcoMoon; + content: '\004A'; + position: relative; + right: 1px; + top: 0; +} +.js-stools .js-stools-container-bar .js-stools-field-filter .chzn-container { + margin: 1px 0; + padding: 0 !important; +} +.chzn-color.chzn-single[rel="value_1"], +.chzn-color-reverse.chzn-single[rel="value_0"], +.chzn-color-state.chzn-single[rel="value_1"], +.chzn-color.chzn-single[rel="value_show_no_link"], +.chzn-color.chzn-single[rel="value_show_with_link"] { + background-color: #46a546; + *background-color: #46a546; + box-shadow: 0 1px 2px rgba(0,0,0,0.05); + color: #ffffff; +} +.chzn-color.chzn-single[rel="value_1"]:hover, +.chzn-color.chzn-single[rel="value_1"]:focus, +.chzn-color.chzn-single[rel="value_1"]:active, +.chzn-color.chzn-single[rel="value_1"].active, +.chzn-color.chzn-single[rel="value_1"].disabled, +.chzn-color.chzn-single[rel="value_1"][disabled], +.chzn-color-reverse.chzn-single[rel="value_0"]:hover, +.chzn-color-reverse.chzn-single[rel="value_0"]:focus, +.chzn-color-reverse.chzn-single[rel="value_0"]:active, +.chzn-color-reverse.chzn-single[rel="value_0"].active, +.chzn-color-reverse.chzn-single[rel="value_0"].disabled, +.chzn-color-reverse.chzn-single[rel="value_0"][disabled], +.chzn-color-state.chzn-single[rel="value_1"]:hover, +.chzn-color-state.chzn-single[rel="value_1"]:focus, +.chzn-color-state.chzn-single[rel="value_1"]:active, +.chzn-color-state.chzn-single[rel="value_1"].active, +.chzn-color-state.chzn-single[rel="value_1"].disabled, +.chzn-color-state.chzn-single[rel="value_1"][disabled], +.chzn-color.chzn-single[rel="value_show_no_link"]:hover, +.chzn-color.chzn-single[rel="value_show_no_link"]:focus, +.chzn-color.chzn-single[rel="value_show_no_link"]:active, +.chzn-color.chzn-single[rel="value_show_no_link"].active, +.chzn-color.chzn-single[rel="value_show_no_link"].disabled, +.chzn-color.chzn-single[rel="value_show_no_link"][disabled], +.chzn-color.chzn-single[rel="value_show_with_link"]:hover, +.chzn-color.chzn-single[rel="value_show_with_link"]:focus, +.chzn-color.chzn-single[rel="value_show_with_link"]:active, +.chzn-color.chzn-single[rel="value_show_with_link"].active, +.chzn-color.chzn-single[rel="value_show_with_link"].disabled, +.chzn-color.chzn-single[rel="value_show_with_link"][disabled] { + color: #fff; + background-color: #2f6f2f; + *background-color: #2f6f2f; +} +.chzn-color.chzn-single[rel="value_1"]:active, +.chzn-color.chzn-single[rel="value_1"].active, +.chzn-color-reverse.chzn-single[rel="value_0"]:active, +.chzn-color-reverse.chzn-single[rel="value_0"].active, +.chzn-color-state.chzn-single[rel="value_1"]:active, +.chzn-color-state.chzn-single[rel="value_1"].active, +.chzn-color.chzn-single[rel="value_show_no_link"]:active, +.chzn-color.chzn-single[rel="value_show_no_link"].active, +.chzn-color.chzn-single[rel="value_show_with_link"]:active, +.chzn-color.chzn-single[rel="value_show_with_link"].active { + background-color: #46a546; +} +.chzn-color-state.chzn-single[rel="value_0"], +.chzn-color-state.chzn-single[rel="value_-2"] { + background-color: #bd362f; + *background-color: #bd362f; + box-shadow: 0 1px 2px rgba(0,0,0,0.05); + color: #ffffff; +} +.chzn-color-state.chzn-single[rel="value_0"]:hover, +.chzn-color-state.chzn-single[rel="value_0"]:focus, +.chzn-color-state.chzn-single[rel="value_0"]:active, +.chzn-color-state.chzn-single[rel="value_0"].active, +.chzn-color-state.chzn-single[rel="value_0"].disabled, +.chzn-color-state.chzn-single[rel="value_0"][disabled], +.chzn-color-state.chzn-single[rel="value_-2"]:hover, +.chzn-color-state.chzn-single[rel="value_-2"]:focus, +.chzn-color-state.chzn-single[rel="value_-2"]:active, +.chzn-color-state.chzn-single[rel="value_-2"].active, +.chzn-color-state.chzn-single[rel="value_-2"].disabled, +.chzn-color-state.chzn-single[rel="value_-2"][disabled] { + color: #fff; + background-color: #802420; + *background-color: #802420; +} +.chzn-color-state.chzn-single[rel="value_0"]:active, +.chzn-color-state.chzn-single[rel="value_0"].active, +.chzn-color-state.chzn-single[rel="value_-2"]:active, +.chzn-color-state.chzn-single[rel="value_-2"].active { + background-color: #bd362f; +} +.CodeMirror { + height: calc(100vh - 400px); + min-height: 400px; + max-height: 800px; +} +.form-horizontal .control-label { + padding-right: 5px; + text-align: left; +} +.form-horizontal .control-label .spacer hr { + width: 380px; +} +@media (max-width: 420px) { + .form-horizontal .control-label .spacer hr { + width: 220px; + } +} +.form-horizontal .field-spacer>.control-label { + width: auto; +} +.form-horizontal #jform_catid_chzn { + vertical-align: middle; +} +.form-vertical .control-label > label { + display: inline-block; + *display: inline; + *zoom: 1; +} +.form-vertical .controls { + margin-left: 0; +} +@media (max-width: 979px) { + .form-horizontal-desktop .control-label { + float: none; + width: auto; + padding-right: 0; + padding-top: 0; + text-align: left; + } + .form-horizontal-desktop .control-label > label { + display: inline-block; + *display: inline; + *zoom: 1; + } + .form-horizontal-desktop .controls { + margin-left: 0; + } +} +@media (max-width: 1199px) { + .row-fluid .row-fluid .form-horizontal-desktop .control-label { + float: none; + width: auto; + padding-right: 0; + padding-top: 0; + text-align: left; + } + .row-fluid .row-fluid .form-horizontal-desktop .control-label > label { + display: inline-block; + *display: inline; + *zoom: 1; + } + .row-fluid .row-fluid .form-horizontal-desktop .controls { + margin-left: 0; + } +} +.form-inline-header { + margin: 5px 0; +} +.form-inline-header .control-group, +.form-inline-header .control-label, +.form-inline-header .controls { + display: inline-block; + *display: inline; + *zoom: 1; +} +.form-inline-header .control-label { + width: auto; + padding-right: 10px; +} +.form-inline-header .controls { + padding-right: 20px; +} +fieldset[class^="form-"] { + min-width: 100%; +} +@-moz-document url-prefix() { + fieldset[class^="form-"] { + display: table-cell; + } +} +fieldset.checkboxes input { + float: left; +} +fieldset.checkboxes li { + list-style: none; +} +.control-group, +.controls, +.controls input[type="text"], +.controls input[type="number"], +.controls input[type="email"], +.controls select, +.controls textarea { + max-width: 100%; +} +.controls .btn-group > .btn { + min-width: 50px; + margin-left: -1px; +} +.controls .btn-group.btn-group-yesno { + width: 220px; + max-width: 100%; +} +.controls .btn-group.btn-group-yesno > .btn { + width: 50%; + min-width: 40px; + padding: 2px 0; +} +input.input-large-text { + font-size: 18px; + line-height: 22px; + height: auto; +} +textarea { + resize: both; +} +textarea.vert { + resize: vertical; +} +textarea.noResize { + resize: none; +} +.subform-repeatable { + padding-right: 10px; +} +.subform-repeatable > .btn-toolbar { + margin: 0; +} +.subform-repeatable > .btn-toolbar .group-add { + line-height: 26px; + width: 56px; + font-size: 13px; + margin-left: 28px; +} +.subform-repeatable-group { + margin-top: 20px; + margin-left: 28px; + border: 1px solid #ccc; + padding: 8px 25px 15px; + position: relative; + border-radius: 3px; +} +.subform-repeatable-group > .btn-toolbar { + margin: 0; +} +.subform-repeatable-group > .btn-toolbar .btn-group { + margin-right: 0px; + margin-top: -1px; + position: static; +} +.subform-repeatable-group > .btn-toolbar .btn { + font-size: 13px; + line-height: 26px; + background-color: #F3F3F3; + position: absolute; +} +.subform-repeatable-group > .btn-toolbar .btn span { + vertical-align: middle; + line-height: 11px; +} +.subform-repeatable-group > .btn-toolbar .btn.btn-success { + color: #378137; + bottom: 0; + right: 0; + border-radius: 3px 0 0 0; + border-width: 1px 0 0 1px; + padding-top: 1px; +} +.subform-repeatable-group > .btn-toolbar .btn.btn-success .icon-plus:before { + content: "]"; +} +.subform-repeatable-group > .btn-toolbar .btn.btn-danger { + color: #942a25; + top: 0; + right: 0; + border-radius: 0 0 0 3px; + border-width: 0 0 1px 1px; +} +.subform-repeatable-group > .btn-toolbar .btn.btn-danger .icon-minus:before { + content: "I"; +} +.subform-repeatable-group > .btn-toolbar .btn.btn-primary { + color: #24748c; + color: #333; + right: 100%; + top: 50%; + margin-top: -27px; + margin-right: 1px; + border-radius: 3px 0 0 3px; + border-width: 1px 0 1px 1px; + line-height: 52px; +} +.subform-repeatable-group > .btn-toolbar .btn.btn-primary .icon-move:before { + content: "Z"; +} +.subform-repeatable-group > .btn-toolbar .btn [class^="icon-"], +.subform-repeatable-group > .btn-toolbar .btn [class*=" icon-"] { + margin: 0; +} +.subform-repeatable-group > .btn-toolbar .btn:hover { + background-color: #E6E6E6; +} +.subform-repeatable-group .control-group:last-of-type { + margin-bottom: 10px; +} +@media (max-width: 979px) { + .subform-repeatable-group > .btn-toolbar .btn-group { + margin-bottom: 10px; + } +} +.subform-table-layout .control-group { + margin-bottom: 10px; +} +.subform-table-layout .control-group:last-of-type { + margin-bottom: 0; +} +.subform-table-layout .controls { + padding-right: 20px; +} +.subform-table-layout input { + width: 100%; + max-width: 206px; +} +.subform-table-layout table .btn-group { + margin: 0 7px; +} +@media (max-width: 1024px) { + .subform-table-layout .subform-repeatable { + padding-right: 0; + } + .subform-table-layout .subform-repeatable tbody td:last-of-type { + text-align: right; + padding-bottom: 15px; + } + .subform-table-layout table, + .subform-table-layout thead, + .subform-table-layout tbody, + .subform-table-layout th, + .subform-table-layout td, + .subform-table-layout tr { + display: block; + } + .subform-table-layout table { + border: 1px solid #ddd; + } + .subform-table-layout thead th { + position: absolute; + top: -9999px; + left: -9999px; + } + .subform-table-layout thead th:last-of-type { + position: static; + width: 100% !important; + text-align: right; + box-sizing: border-box; + border-left: 0; + } + .subform-table-layout tr { + margin: 0; + padding: 0; + border: 0; + } + .subform-table-layout td { + border: none; + position: relative; + padding-left: 50%; + } + .subform-table-layout tbody td:first-of-type { + padding-top: 15px; + border-top: 1px solid #ddd; + } + .subform-table-layout tbody td:first-of-type:before { + top: 18px; + } + .subform-table-layout td:before { + content: attr(data-column); + position: absolute; + top: 13px; + left: 10px; + padding-right: 10px; + } +} +.controls > .radio:first-child, +.controls > .checkbox:first-child { + padding-top: 0; +} +.form-horizontal .controls > .radio:first-child, +.form-horizontal .controls > .checkbox:first-child { + padding-top: 5px; +} +.form-horizontal .controls > .radio.btn-group:first-child { + padding-top: 0; +} +.form-horizontal .controls > .radio.btn-group-yesno:first-child { + padding-top: 2px; +} +input.field-media-input { + width: auto; +} +.header { + background-color: #1a3867; + border-top: 1px solid rgba(255,255,255,0.2); + padding: 8px 25px; +} +@media (max-width: 767px) { + .header { + padding: 4px 18px; + margin-left: -20px; + margin-right: -20px; + } +} +.header .navbar-search { + margin-top: 0; +} +@media (max-width: 979px) { + .header .navbar-search { + border-top: 0; + border-bottom: 0; + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; + } +} +.container-logo { + float: right; + text-align: right; +} +.logo { + width: auto; + max-width: 100%; + max-height: 36px; + height: auto; +} +.page-title { + color: white; + font-weight: normal; + font-size: 20px; + line-height: 36px; + margin: 0; +} +.page-title [class^="icon-"], +.page-title [class*=" icon-"] { + margin-right: 16px; +} +@media (max-width: 767px) { + .container-logo { + display: none; + } + .page-title { + font-size: 18px; + line-height: 28px; + } + .page-title [class^="icon-"], + .page-title [class*=" icon-"] { + margin-right: 10px; + } +} +.view-login { + background-color: #17568c; + padding-top: 0; +} +.view-login .container { + width: 300px; + position: absolute; + top: 50%; + left: 50%; + margin-top: -206px; + margin-left: -150px; +} +.view-login .navbar-fixed-bottom { + padding-left: 20px; + padding-right: 20px; + text-align: center; +} +.view-login .navbar-fixed-bottom, +.view-login .navbar-fixed-bottom a { + color: #FCFCFC; +} +.view-login .navbar-inverse.navbar-fixed-bottom, +.view-login .navbar-inverse.navbar-fixed-bottom a { + color: #555; +} +.view-login .well { + padding-bottom: 0; +} +.view-login .login-joomla { + position: absolute; + left: 50%; + height: 24px; + width: 24px; + margin-left: -12px; + font-size: 22px; +} +.view-login .navbar-fixed-bottom { + position: absolute; +} +.view-login .input-medium { + width: 176px; +} +.view-login #lang_chzn { + width: 233px !important; + max-width: none; +} +.view-login #lang_chzn .chzn-single div { + width: 43px; +} +.view-login .input-prepend .add-on, +.view-login .controls .btn-group > .btn { + margin-left: 0; +} +.navbar-inverse { + color: #333; +} +.login .btn-large { + margin-top: 15px; +} +.login .form-inline .btn-group { + display: block; +} +@media (max-width: 479px) { + .login .chzn-single { + width: 222px !important; + } + .login .chzn-container, + .login .chzn-drop { + width: 230px !important; + } +} +@media (max-width: 319px) { + .view-login .navbar-fixed-bottom { + display: none; + } +} +.ventral-space { + margin-bottom: 5px; +} +ul.manager .height-50 .icon-folder-2 { + height: 35px; + width: 35px; + line-height: 35px; + font-size: 30px; +} +#imageForm .well { + margin-bottom: 5px; +} +.thumbnails-media .thumbnail { + background-color: #f4f4f4; + border-radius: 3px; + border: 0; + box-shadow: 0 0 0 1px rgba(0,0,0,0.05) inset; + padding: 0px; + height: 100px; + width: 100px; + margin: 8px; + position: relative; + text-align: center; + overflow: hidden; +} +.thumbnails-media .thumbnail .close { + background-color: #ccc; + border-left: 1px solid rgba(0,0,0,0.1); + height: 22px; + line-height: 22px; + opacity: 0.3; + text-align: center; + width: 22px; + top: 0; + right: 0; +} +.thumbnails-media .thumbnail .close:hover { + background-color: #bbb; +} +.thumbnails-media .thumbnail *, +.thumbnails-media .thumbnail *:before { + -webkit-transition: all 0.2s ease; + transition: all 0.2s ease; + -webkit-box-sizing: border-box; + box-sizing: border-box; +} +.thumbnails-media .thumbnail input[type="radio"], +.thumbnails-media .thumbnail input[type="checkbox"] { + margin: 0; + opacity: 0.55; + position: absolute; + top: 5px; + left: 5px; +} +.thumbnails-media .thumbnail .controls, +.thumbnails-media .thumbnail .imginfoBorder { + display: none; +} +.thumbnails-media .imgThumb { + position: relative; + z-index: 1; + width: 100%; + display: inline-block; +} +.thumbnails-media .imgThumb input { + display: none; +} +.thumbnails-media .imgThumb label, +.thumbnails-media .imgThumb .imgThumbInside { + display: block; + line-height: 100px; + position: relative; + width: 100%; + border-radius: 3px; + overflow: hidden; +} +.thumbnails-media .imgThumb label:before, +.thumbnails-media .imgThumb .imgThumbInside:before { + font-family: "IcoMoon"; + font-style: normal; + content: 'G'; + position: absolute; + top: 0; + right: 0; + background-color: #46a546; + color: #fff; + line-height: 26px; + width: 26px; + -webkit-transform: scale(0.5); + transform: scale(0.5); + opacity: 0; + border-color: rgba(0,0,0,0.2); + box-shadow: 0 1px 2px rgba(0,0,0,0.05); + border-radius: 0 3px; +} +.thumbnails-media .imgThumb img { + width: auto; +} +.thumbnails-media .selected :checked + label, +.thumbnails-media .selected .imgThumbInside, +.thumbnails-media .imgInput :checked + label, +.thumbnails-media .imgInput .imgThumbInside { + background-color: #ddd; +} +.thumbnails-media .selected :checked + label:before, +.thumbnails-media .selected .imgThumbInside:before, +.thumbnails-media .imgInput :checked + label:before, +.thumbnails-media .imgInput .imgThumbInside:before { + -webkit-transform: scale(1); + transform: scale(1); + opacity: 1; +} +.thumbnails-media .selected :checked + label:after, +.thumbnails-media .selected .imgThumbInside:after, +.thumbnails-media .imgInput :checked + label:after, +.thumbnails-media .imgInput .imgThumbInside:after { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + content: ''; + border: 3px solid #46a546; + border-radius: 5px; +} +.thumbnails-media .imgDelete a.close, +.thumbnails-media .imgPreview a { + padding: 0; + position: absolute; + left: 0; + z-index: 1; + height: 26px; + width: 26px; +} +.thumbnails-media .imgPreview a { + width: 100%; +} +.thumbnails-media .imgDelete a.close { + background-color: #bd362f; + border-color: #bd362f rgba(0,0,0,0.2) rgba(0,0,0,0.2) #bd362f; + top: 0; + line-height: 28px; + font-size: 12px; + padding-left: 1px; + color: #fff; + border-bottom-right-radius: 3px; + border-top-left-radius: 3px; + z-index: 10; + opacity: 0; + -webkit-transform: scale(0.5); + transform: scale(0.5); +} +.thumbnails-media .imgDelete a.close:hover { + background-color: #802420; +} +.thumbnails-media .thumbnail:hover .imgDelete a.close { + opacity: 1; + -webkit-transform: scale(1); + transform: scale(1); +} +.thumbnails-media .imgPreview a, +.thumbnails-media .imgDetails { + position: absolute; + left: 0; + text-align: left; + background-color: #fff; + border-color: rgba(0,0,0,0.2); + bottom: 0; + line-height: 26px; + border: 1px solid rgba(0,0,0,0.1); + border-width: 1px; + border-radius: 0 3px 0 0; + z-index: 1; +} +.thumbnails-media .imgPreview a:hover, +.thumbnails-media .imgDetails:hover { + background-color: #eee; +} +.thumbnails-media .imgDetails { + padding: 0 5px; + line-height: 20px; + color: #555; +} +.thumbnails-media .imgFolder span { + line-height: 90px; + font-size: 38px; + margin: 0; + width: auto; +} +.thumbnails-media .imgFolder + .imgDetails { + color: inherit; +} +.com_media .media a + a { + margin-left: -1px; +} +.com_media .tree-holder { + padding: 0 15px; +} +#folderframe.thumbnail { + border: 0; + box-shadow: none; + padding: 0; +} +#mediamanager-form { + margin: 0 -10px; + overflow-x: hidden; +} +#mediamanager-form > .muted { + padding: 0px; +} +#mediamanager-form .checkbox { + padding-left: 30px; + margin-bottom: 15px; +} +#mediamanager-form .checkbox input { + margin-top: 3px; +} +#mediamanager-form .thumbnails { + margin: 0 -8px; + overflow-x: hidden; +} +#mediamanager-form .thumbnails .thumbnail { + height: 120px; + width: 120px; + margin: 8px; +} +#mediamanager-form .thumbnails .imgThumb label, +#mediamanager-form .thumbnails .imgTotal { + line-height: 120px; +} +#mediamanager-form .icon-search::before { + padding-right: 5px; + padding-left: 1px; +} +#mediamanager-form .height-50 { + background-color: #fafafa; + height: 77px; + position: relative; + z-index: 1; + width: 100%; + display: inline-block; +} +#mediamanager-form .height-50 a, +#mediamanager-form .height-50 .icon-folder-2 { + display: inline-block; + line-height: 75px; + margin-top: -1px; +} +#mediamanager-form .height-50 a:after { + bottom: 0; + box-shadow: 0 0 0 1px rgba(0,0,0,0.08) inset; + content: ""; + display: block; + left: 0; + overflow: hidden; + position: absolute; + right: 0; + top: 0; +} +#mediamanager-form .height-50 .icon-folder-2 { + font-size: 40px; +} +.uploadform { + margin-top: 20px; +} +body.modal-open { + -ms-overflow-style: none; +} +.modal-header { + padding: 0 20px; + text-align: left; +} +.modal-header h3 { + font-weight: normal; + line-height: 50px; +} +.modal-header .close { + width: 50px; + margin-top: 0; + margin-right: -15px; + font-size: 2rem; + line-height: 50px; + border-left: 1px solid #ccc; +} +.modal-body { + padding: 0; + width: 100%; + height: auto; + max-height: none; +} +.modal-body .container-fluid { + padding-top: 15px; + padding-bottom: 15px; +} +.modal-footer { + clear: both; +} +.contentpane { + padding: 10px; + height: auto; +} +@media (min-width: 768px) { + .row-fluid .modal-batch [class*="span"] { + margin-left: 0; + } +} +.container-popup { + padding: 10px; +} +.field-media-wrapper iframe { + max-height: 75vh; +} +body .navbar, +body .navbar-fixed-top { + margin-bottom: 0; +} +.navbar-inner { + min-height: 0; + background: #f2f2f2; + background-image: none; + filter: none; +} +.navbar-inner .container-fluid { + padding-left: 10px; + padding-right: 10px; + font-size: 15px; +} +.navbar-inverse .navbar-inner { + background: #10223e; + background-image: none; + filter: none; +} +.navbar .navbar-text { + line-height: 30px; +} +.navbar .admin-logo { + float: left; + padding: 7px 12px 0px 15px; + font-size: 16px; + color: #555; +} +.navbar .admin-logo:hover { + color: #333; +} +.navbar-inverse.navbar .admin-logo { + color: #d9d9d9; +} +.navbar-inverse.navbar .admin-logo:hover { + color: #ffffff; +} +.navbar .brand { + float: right; + display: block; + padding: 6px 10px; + margin-left: -20px; + font-size: inherit; + font-weight: normal; +} +.navbar .brand:hover, +.navbar .brand:focus { + text-decoration: none; +} +.navbar .nav > li > a { + padding: 6px 10px; +} +.navbar .nav > li > a:hover { + color: white; +} +.navbar .nav > li > a:hover span.carot { + border-bottom-color: #fff; + border-top-color: #fff; +} +.navbar .dropdown-menu, +.navbar .nav-user { + font-size: 13px; +} +.navbar .nav-user .dropdown-menu li span { + padding-left: 10px; +} +.navbar .nav > li ul { + overflow-y: auto; + overflow-x: hidden; + -webkit-overflow-scrolling: touch; + -moz-overflow-scrolling: touch; + -ms-overflow-scrolling: touch; + -o-overflow-scrolling: touch; + overflow-scrolling: touch; + height: auto; + max-height: 500px; + margin: 0; +} +.navbar .nav > li ul::-webkit-scrollbar { + -webkit-appearance: none; + width: 7px; +} +.navbar .nav > li ul::-webkit-scrollbar-thumb { + border-radius: 4px; + background-color: rgba(0,0,0,0.5); + -webkit-box-shadow: 0 0 1px rgba(255,255,255,0.5); +} +.navbar .nav > li > .dropdown-menu:after { + display: none; +} +.navbar .nav > .dropdown.open:after { + content: ''; + display: inline-block; + border-left: 6px solid transparent; + border-right: 6px solid transparent; + border-bottom: 6px solid #fff; + position: absolute; + top: 25px; + left: 10px; + z-index: 1001; +} +.navbar .empty-nav { + display: none; +} +.navbar-fixed-top .navbar-inner, +.navbar-static-top .navbar-inner { + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; +} +.dropdown-menu > li > a:hover, +.dropdown-menu > li > a:focus, +.dropdown-submenu:hover > a, +.dropdown-submenu:focus > a { + background-image: none; +} +.navbar-fixed-bottom { + bottom: 0; +} +.navbar-fixed-bottom .navbar-inner { + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; +} +.navbar .btn-navbar { + background: #17568c; + border: 1px solid #0D2242; + margin-bottom: 2px; +} +@media (max-width: 767px) { + .navbar .admin-logo { + margin-left: 10px; + padding: 9px 9px 0 9px; + } +} +.navbar-search .search-query { + background: rgba(255,255,255,0.3); +} +@media (max-width: 979px) { + .navbar .nav { + font-size: 13px; + margin: 0 2px 0 0; + } + .navbar .nav > li > a { + padding: 6px; + } +} +@media (max-width: 767px) { + .navbar-search.pull-right { + float: none; + text-align: center; + } +} +@media (max-width: 738px) { + .navbar .brand { + font-size: 16px; + } +} +.nav-collapse .nav li a, +.dropdown-menu a { + background-image: none; +} +.nav-collapse .dropdown-menu > li img { + max-width: none; +} +@media (max-width: 767px) { + .navbar-fixed-top .navbar-inner, + .navbar-fixed-top .navbar-inner .container-fluid { + padding: 0; + } + .navbar .brand { + margin-top: 2px; + float: none; + text-align: center; + } + .navbar .btn-navbar { + margin-top: 3px; + margin-right: 3px; + margin-bottom: 3px; + } + .nav-collapse .nav .nav-header { + color: #fff; + } + .nav-collapse .nav, + .navbar .nav-collapse .nav.pull-right { + margin: 0; + } + .nav-collapse .dropdown-menu { + margin: 0; + } + .nav-collapse .dropdown-menu > li > span { + display: block; + padding: 4px 15px; + } + .navbar-inverse .nav-collapse .dropdown-menu > li > span { + color: #d9d9d9; + } + .nav-collapse .nav > li > a.dropdown-toggle { + background-color: rgba(255,255,255,0.07); + font-size: 12px; + font-weight: bold; + color: #eee; + text-transform: uppercase; + padding-left: 15px; + } + .nav-collapse .nav li a { + margin-bottom: 0; + border-top: 1px solid rgba(255,255,255,0.25); + border-bottom: 1px solid rgba(0,0,0,0.5); + } + .nav-collapse .nav li ul li ul.dropdown-menu, + .nav-collapse .nav li ul li:hover ul.dropdown-menu, + .nav-collapse .caret { + display: none !important; + } + .nav-collapse .nav > li > a, + .nav-collapse .dropdown-menu a { + font-size: 15px; + font-weight: normal; + color: #fff; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; + } + .navbar .nav-collapse .nav > li > .dropdown-menu::before, + .navbar .nav-collapse .nav > li > .dropdown-menu::after, + .navbar .nav-collapse .dropdown-submenu > a::after { + display: none; + } + .nav-collapse .dropdown-menu li + li a { + margin-bottom: 0; + } +} +.quick-icons { + font-size: 14px; + margin-bottom: 20px; +} +.quick-icons .nav-header { + margin: 12px 0 5px; + font-size: 13px; +} +.quick-icons .nav-header:first-child { + margin: 0 0 5px; +} +.quick-icons [class^="icon-"], +.quick-icons [class*=" icon-"] { + margin-right: 9px; +} +.quick-icons [class^="icon-"]:before, +.quick-icons [class*=" icon-"]:before { + font-size: 16px; + margin-bottom: 20px; + line-height: 18px; +} +html[dir=rtl] .quick-icons .nav-list [class^="icon-"], +html[dir=rtl] .quick-icons .nav-list [class*=" icon-"] { + margin-left: 9px; + margin-right: 0; +} +.sidebar-nav .nav-list { + padding-left: 25px; + padding-right: 25px; +} +.sidebar-nav .nav-list > li > a { + color: #555; + padding: 3px 25px; + margin-left: -26px; + margin-right: -26px; +} +.sidebar-nav .nav-list > li.active > a { + color: #fff; + margin-right: -26px; +} +.sidebar-nav .nav-list > li > a:focus, +.sidebar-nav .nav-list > li > a:hover { + text-decoration: none; + color: #fff; + background-color: #2d6ca2; + text-shadow: none; +} +.j-sidebar-container { + position: absolute; + display: block; + left: -16.5%; + width: 16.5%; + margin: -18px 0 0 -1px; + padding-top: 28px; + padding-bottom: 40px; + clear: both; + background-color: #F0F0F0; + border-bottom: 1px solid #dedede; + border-right: 1px solid #dedede; + -webkit-border-radius: 0 0 3px 0; + -moz-border-radius: 0 0 3px 0; + border-radius: 0 0 3px 0; +} +.j-sidebar-container.j-sidebar-hidden { + left: -16.5%; +} +.j-sidebar-container.j-sidebar-visible { + left: 0; +} +.j-sidebar-container .filter-select { + padding: 0 14px; +} +.j-toggle-sidebar-header h3 { + font-weight: normal; + padding: 0 15px; +} +.j-toggle-button-wrapper { + position: absolute; + display: block; + top: 7px; + padding: 0; +} +.j-toggle-button-wrapper.j-toggle-hidden { + right: -24px; +} +.j-toggle-button-wrapper.j-toggle-visible { + right: 7px; +} +.j-toggle-sidebar-button { + font-size: 16px; + color: #3071a9; + text-decoration: none; + cursor: pointer; +} +.j-toggle-sidebar-button:hover { + color: #1f496e; +} +#system-message-container, +#j-main-container { + padding: 0 0 0 5px; + min-height: 0; +} +#system-message-container.j-toggle-main, +#j-main-container.j-toggle-main, +#system-debug.j-toggle-main { + float: right; +} +@media (min-width: 768px) { + .j-toggle-transition { + -webkit-transition: all 0.3s ease; + -moz-transition: all 0.3s ease; + -o-transition: all 0.3s ease; + transition: all 0.3s ease; + } +} +@media (max-width: 979px) { + .j-toggle-button-wrapper.j-toggle-hidden { + right: -20px; + } +} +@media (max-width: 767px) { + .j-sidebar-container { + position: relative; + width: 100%; + margin: 0 0 20px 0; + padding: 0; + background: transparent; + border-right: 0; + border-bottom: 0; + } + .j-sidebar-container.j-sidebar-hidden { + margin-left: 16.5%; + } + .j-sidebar-container.j-sidebar-visible { + margin-left: 0; + } + .j-toggle-sidebar-header, + .j-toggle-button-wrapper { + display: none; + } + .view-login select { + width: 232px; + } +} +@media (max-width: 420px) { + .j-sidebar-container { + margin: 0; + } + .view-login .input-medium { + width: 180px; + } + .view-login select { + width: 232px; + } +} +#status { + background: #ebebeb; + border-top: 1px solid #dedede; + padding: 4px 10px; + -webkit-box-shadow: 0 0 3px rgba(0, 0, 0, 0.08); + -moz-box-shadow: 0 0 3px rgba(0, 0, 0, 0.08); + box-shadow: 0 0 3px rgba(0, 0, 0, 0.08); + color: #626262; +} +#status .btn-group { + margin: 0; +} +#status .btn-group.separator:after { + content: ' '; + display: block; + float: left; + background: #ADADAD; + margin: 0 10px; + height: 15px; + width: 1px; +} +#status .btn-toolbar, +#status p { + margin: 0px; +} +#status .btn-toolbar, +#status .btn-group { + font-size: 12px; +} +#status a { + color: #626262; +} +#status .badge { + margin-right: .25em; +} +#status.status-top { + background: #1a3867; + -webkit-box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.2) inset, 0px -1px 0px rgba(0, 0, 0, 0.3) inset, 0px -1px 0px rgba(0, 0, 0, 0.3); + -moz-box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.2) inset, 0px -1px 0px rgba(0, 0, 0, 0.3) inset, 0px -1px 0px rgba(0, 0, 0, 0.3); + box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.2) inset, 0px -1px 0px rgba(0, 0, 0, 0.3) inset, 0px -1px 0px rgba(0, 0, 0, 0.3); + border-top: 0; + color: #d9d9d9; + padding: 2px 20px 6px 20px; +} +#status.status-top a { + color: #d9d9d9; +} +@media (max-width: 479px) { + .pagination a { + padding: 5px; + } + .btn-group.divider, + .header .row-fluid .span3, + .header .row-fluid .span7 { + display: none; + } + .navbar .btn { + margin: 0; + } + .btn-subhead { + display: block; + margin: 10px 0; + } + .subhead-collapse.collapse { + height: 0; + overflow: hidden; + } + .btn-toolbar .btn-wrapper { + display: block; + margin: 0px 10px 5px 10px; + } + .btn-toolbar .btn-wrapper .btn { + width: 100% !important; + } + .subhead { + background: none repeat scroll 0 0 transparent; + border-bottom: 0 solid #dedede; + } + .btn-group + .btn-group { + margin-left: 10px; + } + .login .chzn-single { + width: 222px !important; + } + .login .chzn-container, + .login .chzn-drop { + width: 230px !important; + } + #toolbar [class^="icon-"], + #toolbar [class*=" icon-"] { + background-color: transparent; + border-right: medium none; + width: 10px; + } +} +table label { + margin: 0; +} +td.has-context { + height: 23px; +} +td.nowrap.has-context { + width: 45%; +} +.subhead { + background: #F0F0F0; + border-bottom: 1px solid #dedede; + color: #0C192E; + text-shadow: 0 1px 0 #FFF; + margin-bottom: 10px; + min-height: 51px; +} +.subhead-collapse { + margin-bottom: 19px; +} +.subhead-collapse.collapse { + height: auto; + overflow: visible; +} +.btn-toolbar { + margin-bottom: 5px; +} +.btn-toolbar .btn-wrapper { + display: inline-block; + margin: 0 0 8px 5px; +} +.subhead-fixed { + position: fixed; + width: 100%; + top: 30px; + z-index: 100; +} +@media (max-width: 767px) { + body { + -webkit-overflow-scrolling: touch; + } + .subhead { + margin-left: -20px; + margin-right: -20px; + padding-left: 10px; + padding-right: 10px; + } +} +.subhead h1 { + font-size: 17px; + font-weight: normal; + margin-left: 10px; + margin-top: 6px; +} +#toolbar { + margin-bottom: 2px; + margin-top: 12px; +} +#toolbar .btn { + line-height: 24px; + margin-right: 4px; + padding: 0 10px; +} +#toolbar .btn-success { + min-width: 148px; +} +#toolbar .btn-primary [class^="icon-"], +#toolbar .btn-primary [class*=" icon-"], +#toolbar .btn-warning [class^="icon-"], +#toolbar .btn-warning [class*=" icon-"], +#toolbar .btn-danger [class^="icon-"], +#toolbar .btn-danger [class*=" icon-"], +#toolbar .btn-success [class^="icon-"], +#toolbar .btn-success [class*=" icon-"], +#toolbar .btn-info [class^="icon-"], +#toolbar .btn-info [class*=" icon-"], +#toolbar .btn-inverse [class^="icon-"], +#toolbar .btn-inverse [class*=" icon-"] { + background-color: transparent; + border-right: 0; + border-left: 0; + width: 16px; + margin-left: 0; + margin-right: 0; +} +#toolbar #toolbar-options, +#toolbar #toolbar-help { + float: right; +} +#toolbar [class^="icon-"], +#toolbar [class*=" icon-"] { + background-color: #e6e6e6; + border-radius: 3px 0 0 3px; + border-right: 1px solid #b3b3b3; + height: auto; + line-height: inherit; + margin: 0 6px 0 -10px; + opacity: 1; + text-shadow: none; + width: 28px; + z-index: -1; +} +#toolbar iframe .btn-group .btn { + margin-left: -1px !important; +} +html[dir=rtl] #toolbar #toolbar-options, +html[dir=rtl] #toolbar #toolbar-help { + float: left; +} +@media (max-width: 767px) { + .subhead-fixed { + position: static; + width: auto; + } +} +.btn-subhead { + display: none; +} +@media (min-width: 480px) { + #filter-bar { + height: 29px; + } +} +@media (max-width: 479px) { + .navbar .btn { + margin: 0; + } + .btn-subhead { + display: block; + margin: 10px 0; + } + .subhead-collapse.collapse { + height: 0; + overflow: hidden; + } + .btn-toolbar .btn-wrapper { + display: block; + margin: 0px 10px 5px 10px; + } + .btn-toolbar .btn-wrapper .btn { + width: 100% !important; + } + .subhead { + background: none repeat scroll 0 0 transparent; + border-bottom: 0 solid #dedede; + } + #toolbar [class^="icon-"], + #toolbar [class*=" icon-"] { + background-color: transparent; + border-right: medium none; + width: 10px; + } +} +@media (max-width: 319px) { + .view-login .navbar-fixed-bottom { + display: none; + } +} +ul.treeselect, +ul.treeselect li { + margin: 0; + padding: 0; +} +ul.treeselect { + margin-top: 8px; +} +ul.treeselect li { + padding: 2px 10px 2px; + list-style: none; +} +ul.treeselect i.treeselect-toggle { + line-height: 18px; +} +ul.treeselect label { + font-size: 1em; + margin-left: 8px; +} +ul.treeselect label.nav-header { + padding: 0; +} +ul.treeselect input { + margin: 2px 0 0 8px; +} +ul.treeselect .treeselect-menu { + margin: 0 6px; +} +ul.treeselect ul.dropdown-menu { + margin: 0; +} +ul.treeselect ul.dropdown-menu li { + padding: 0 5px; + border: none; +} +.tree-holder .folder-url, +.tree-holder .file { + position: relative; + background-color: #fefefe; + margin-bottom: 4px; + padding: 0 10px; + line-height: 32px; + border: 1px solid rgba(0,0,0,0.08); +} +.tree-holder .folder-url, +.tree-holder .folder-url:hover, +.tree-holder .folder-url:focus { + font-weight: bold; + background-color: #f5f5f5; + color: #3071a9; +} +.tree-holder .active { + background-color: #3071a9; + color: #fff; + box-shadow: -3px 0 0 #36a2ff !important; +} +.tree-holder .active.folder-url { + background-color: #f5f5f5; + color: #3071a9; +} +.tree-holder .active.file:hover { + background-color: #3071a9; +} +.tree-holder ul ul { + box-shadow: -3px 0 0 rgba(0,0,0,0.08); + padding-right: 0; +} +.tree-holder ul ul .folder-url, +.tree-holder ul ul .file { + box-shadow: -3px 0 0 #3071a9; + border-left: 0; +} +.break-word { + word-break: break-all; + word-wrap: break-word; +} +.disabled { + cursor: default; + background-image: none; + opacity: 0.65; + filter: alpha(opacity=65); + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; +} +.j-links-separator { + margin: 20px 0px; + width: 100%; + height: 0px; + border-top: 2px solid #DDDDDD; +} +.container-main, +#system-debug { + padding-bottom: 50px; +} +.pagination-toolbar { + margin: 0; +} +.pagination-toolbar a { + line-height: 26px; +} +.pull-right > .dropdown-menu, +.dropdown-reverse { + left: auto; + right: 0; +} +.nav-filters hr { + margin: 5px 0; +} +#assignment.tab-pane { + min-height: 500px; +} +@media (max-width: 979px) { + .container-fluid { + padding-left: 10px; + padding-right: 10px; + } +} +@media (min-width: 768px) { + body { + padding-top: 30px; + } + .nav-collapse.collapse.in { + height: auto !important; + } +} +@media (max-width: 767px) { + .container-fluid { + padding-left: 0; + padding-right: 0; + } +} +@media (max-width: 479px) { + .pagination a { + padding: 5px; + } + .btn-group.divider, + .header .row-fluid .span3, + .header .row-fluid .span7 { + display: none; + } + .btn-group + .btn-group { + margin-left: 10px; + } +} +.info-labels { + margin-top: -5px; + margin-bottom: 10px; +} +.sortable-handler.inactive { + opacity: 0.3; + filter: alpha(opacity=30); +} +.alert-joomlaupdate { + text-align: center; +} +.alert-joomlaupdate button { + vertical-align: baseline; +} +.j-jed-message { + line-height: 2em; + color: #333333; +} +.moor-box { + z-index: 3; +} +.admin .chzn-container .chzn-drop { + z-index: 1060; +} +.item-associations { + margin: 0; +} +.item-associations li { + list-style: none; + display: inline-block; + margin: 0 0 3px 0; +} +.item-associations li a { + color: #ffffff; +} +#flag img { + padding-top: 6px; + vertical-align: top; +} +.tooltip { + max-width: 400px; +} +.tooltip-inner { + max-width: none; + text-align: left; + text-shadow: none; +} +th .tooltip-inner { + font-weight: normal; +} +.tooltip.hasimage { + opacity: 1; +} +#permissions-sliders .chzn-container { + margin-top: -5px; + position: absolute; +} +#permissions-sliders .table td { + padding: 8px 8px 9px; +} +.img-preview > img { + max-height: 100%; +} +.alert-no-items { + margin-top: 20px; +} +@media (max-width: 767px) { + html[dir=rtl] #toolbar #toolbar-options, + html[dir=rtl] #toolbar #toolbar-help, + #toolbar #toolbar-options, + #toolbar #toolbar-help { + float: none; + } +} +#permissions-sliders .input-small { + width: 120px; +} +.editor { + overflow: hidden; + position: relative; +} +.editor textarea.mce_editable { + box-sizing: border-box; +} +a.grid_false { + display: inline-block; + height: 16px; + width: 16px; + background-image: url('../images/admin/publish_r.png'); +} +a.grid_true { + display: inline-block; + height: 16px; + width: 16px; + background-image: url('../images/admin/icon-16-allow.png'); +} +textarea, +input, +.uneditable-input { + box-shadow: none !important; +} +textarea:focus, +input:focus, +.uneditable-input:focus { + box-shadow: none; + border: 1px solid #3071A9; +} +.js-pstats-data-details dd { + margin-left: 240px; +} +.js-pstats-data-details dt { + width: 220px; +} +#permissions table td, +#page-permissions table td { + vertical-align: middle; +} +#permissions table select, +#page-permissions table select { + margin-bottom: 0; +} +.js-stools-container-bar .btn-primary .caret { + border-bottom: 4px solid #fff; +} +.input-append .add-on, +.input-append .btn, +.input-append .btn-group > .dropdown-toggle, +.input-prepend .add-on, +.input-prepend .btn, +.input-prepend .btn-group > .dropdown-toggle { + -webkit-border-radius: 0 3px 3px 0; + -moz-border-radius: 0 3px 3px 0; + border-radius: 0 3px 3px 0; +} +.alert, +.alert-options, +.badge, +.breadcrumb > li, +.close, +.input-append .add-on, +.input-prepend .add-on, +.label, +.nav-header, +.nav-list .nav-header, +.nav-list > .active > a, +.nav-list > .active > a:focus, +.nav-list > .active > a:hover, +.nav-list > li > a, +.nav-tabs.nav-dark, +.navbar .brand, +.navbar .nav > li > a, +.navbar-inverse .brand, +.navbar-inverse .nav > li > a, +.navbar-inverse .navbar-search .search-query.focused, +.navbar-inverse .navbar-search .search-query:focus, +.progress .bar, +.subhead { + text-shadow: none; +} +.popover-content { + min-height: 33px; +} +.lead, +.navbar .brand, +.hero-unit, +.hero-unit .lead { + font-weight: 400; +} +@media (min-width: 1200px) { + #permissions .tab-content { + position: sticky; + top: 90px; + } +} +.com_cpanel .well { + padding: 8px 14px; + border: 1px solid rgba(0,0,0,0.05); +} +.com_cpanel .well .module-title.nav-header { + color: #555; +} +.com_cpanel .well > .row-striped, +.com_cpanel .well > .list-striped { + margin: 0 -14px; +} +.com_cpanel .well > .row-striped > .row-fluid, +.com_cpanel .well > .list-striped > .row-fluid { + padding: 8px 14px; +} +.com_cpanel .well > .row-striped > .row-fluid [class*="span"], +.com_cpanel .well > .list-striped > .row-fluid [class*="span"] { + margin-left: 0; +} +.com_cpanel .well > .row-striped > li, +.com_cpanel .well > .list-striped > li { + padding-left: 15px; + padding-right: 15px; +} +.com_postinstall fieldset { + background-color: #fafafa; + border: 1px solid #ccc; + border-radius: 5px; + margin: 0 0 18px; + padding: 4px 18px 18px; +} +.com_postinstall fieldset .btn { + margin-top: 10px; +} +.com_postinstall legend { + border: 0 none; + display: inline-block; + padding: 0 5px; + margin-bottom: 0; + width: auto; +} +.com_privacy .well { + padding: 8px 14px; + border: 1px solid rgba(0,0,0,0.05); +} +.com_privacy .well .module-title.nav-header { + color: #555; +} +.com_privacy .well > .row-striped, +.com_privacy .well > .list-striped { + margin: 0 -14px; +} +.com_privacy .well > .row-striped > .row-fluid, +.com_privacy .well > .list-striped > .row-fluid { + padding: 8px 14px; +} +.com_privacy .well > .row-striped > .row-fluid [class*="span"], +.com_privacy .well > .list-striped > .row-fluid [class*="span"] { + margin-left: 0; +} +.com_privacy .well > .row-striped > li, +.com_privacy .well > .list-striped > li { + padding-left: 15px; + padding-right: 15px; +} +#menu-assignment { + position: relative; +} +#menu-assignment .menu-links { + margin-top: 15px; + margin-left: 0; + -webkit-column-count: 4; + -moz-column-count: 4; + column-count: 4; + -moz-column-gap: 15px; + -webkit-column-gap: 15px; + column-gap: 15px; +} +#menu-assignment .menu-links > li { + display: inline-block; + vertical-align: top; + margin-bottom: 15px; + width: 100%; + list-style: none; + page-break-inside: avoid; + break-inside: avoid; +} +#menu-assignment .menu-links-block { + background-color: #fafafa; + border: 1px solid #ddd; + border-radius: 3px; + padding: 15px; +} +@media (max-width: 1199px) { + #menu-assignment .menu-links { + -webkit-column-count: 3; + -moz-column-count: 3; + column-count: 3; + } +} +@media (max-width: 767px) { + #menu-assignment .menu-links { + -webkit-column-count: auto; + -moz-column-count: auto; + column-count: auto; + } +} +.pull-right { + float: left; +} +.pull-left { + float: right; +} +.table th, +.table td { + text-align: right; +} +.navbar .brand { + float: right; + padding: 8px 20px 8px 12px; + margin-right: -20px; + margin-left: 0; +} +.navbar .nav, +.navbar .nav > li { + float: left; +} +.navbar .nav.pull-right { + margin-right: 10px; + margin-left: 0px; +} +.pull-right > .dropdown-menu { + left: 0; + right: auto; +} +[class*="span"] { + float: right; + margin-right: 20px; + margin-left: 0px; +} +.row-fluid [class*="span"] { + float: right; + margin-right: 2.127659574%; + *margin-right: 2.0744680846382977%; + margin-left: 0px !important; + *margin-left: 0px !important; +} +.row-fluid [class*="span"]:first-child { + margin-right: 0; +} +.form-horizontal .control-label { + float: right; + width: auto; + padding-left: 5px; + padding-right: 0; + text-align: right; +} +.form-horizontal .controls { + *display: inline-block; + *padding-right: 20px; + margin-right: 160px; + *margin-right: 0; + margin-left: 0; + text-align: right; + margin-top: 6px; +} +.form-horizontal .controls:first-child { + *padding-right: 160px; +} +.form-vertical .controls { + *display: inline-block; + *padding-right: 20px; + margin-right: 0; + *margin-right: 0; + margin-left: 0; + text-align: right; + margin-top: 6px; +} +.form-vertical .control-label { + float: none; + padding-right: 0; + padding-top: 0; + text-align: right; + width: auto; +} +.chzn-container-single-nosearch .chzn-search input { + position: absolute; + left: -9000px; + display: none; +} +.nav-tabs > li, +.nav-pills > li { + float: right; +} +.nav-stacked > li { + float: none; +} +.btn-group > .btn { + float: right; + margin-right: -1px; + margin-left: 0; +} +.btn-group > .btn:first-child { + margin-right: 0; +} +.btn-group > .btn:first-child, +.radio.btn-group > label:first-of-type { + margin-left: 0; + -webkit-border-bottom-left-radius: 4px; + border-bottom-left-radius: 4px; + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-bottomleft: 4px; + -moz-border-radius-topleft: 4px; + -webkit-border-bottom-right-radius: 4px; + border-bottom-right-radius: 4px; + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -moz-border-radius-bottomright: 4px; + -moz-border-radius-topright: 4px; +} +.btn-group > .btn:last-child, +.btn-group > .dropdown-toggle { + -webkit-border-top-right-radius: 0px; + border-top-right-radius: 0px; + -webkit-border-bottom-right-radius: 0px; + border-bottom-right-radius: 0px; + -moz-border-radius-topright: 0px; + -moz-border-radius-bottomright: 0px; + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -webkit-border-bottom-left-radius: 4px; + border-bottom-left-radius: 4px; + -moz-border-radius-topleft: 4px; + -moz-border-radius-bottomleft: 4px; +} +.btn-group > .btn.large:first-child { + -webkit-border-bottom-left-radius: 0px; + border-bottom-left-radius: 0px; + -webkit-border-top-left-radius: 0px; + border-top-left-radius: 0px; + -moz-border-radius-bottomleft: 0px; + -moz-border-radius-topleft: 0px; + margin-right: 0; + -webkit-border-bottom-right-radius: 6px; + border-bottom-right-radius: 6px; + -webkit-border-top-right-radius: 6px; + border-top-right-radius: 6px; + -moz-border-radius-bottomright: 6px; + -moz-border-radius-topright: 6px; +} +.btn-group > .btn.large:last-child, +.btn-group > .large.dropdown-toggle { + -webkit-border-top-right-radius: 0px; + border-top-right-radius: 0px; + -webkit-border-bottom-right-radius: 0px; + border-bottom-right-radius: 0px; + -moz-border-radius-topright: 0px; + -moz-border-radius-bottomright: 0px; + -webkit-border-top-left-radius: 6px; + border-top-left-radius: 6px; + -webkit-border-bottom-left-radius: 6px; + border-bottom-left-radius: 6px; + -moz-border-radius-topleft: 6px; + -moz-border-radius-bottomleft: 6px; +} +.btn-group > .btn:first-child:last-child { + margin-left: 0; + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -webkit-border-bottom-left-radius: 4px; + border-bottom-left-radius: 4px; + -moz-border-radius-topleft: 4px; + -moz-border-radius-bottomleft: 4px; + -webkit-border-bottom-right-radius: 4px; + border-bottom-right-radius: 4px; + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -moz-border-radius-bottomright: 4px; + -moz-border-radius-topright: 4px; +} +.input-prepend .add-on { + float: right; +} +.input-append .add-on { + float: none; +} +.input-prepend .add-on, +.input-prepend .btn { + margin-left: -1px; + margin-right: 0; +} +.input-prepend .add-on:first-child, +.input-prepend .btn:first-child { + -webkit-border-radius: 0 3px 3px 0; + -moz-border-radius: 0 3px 3px 0; + border-radius: 0 3px 3px 0; +} +.input-append input, +.input-append select, +.input-append .uneditable-input { + -webkit-border-radius: 0 3px 3px 0; + -moz-border-radius: 0 3px 3px 0; + border-radius: 0 3px 3px 0; +} +.input-append .uneditable-input { + border-left-color: #ccc; + border-right-color: #eee; +} +.input-append .add-on:last-child, +.input-append .btn:last-child { + -webkit-border-radius: 3px 0 0 3px; + -moz-border-radius: 3px 0 0 3px; + border-radius: 3px 0 0 3px; +} +.input-prepend.input-append input, +.input-prepend.input-append select, +.input-prepend.input-append .uneditable-input { + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.input-prepend.input-append .add-on:first-child, +.input-prepend.input-append .btn:first-child { + margin-left: -1px; + margin-right: 0px; + -webkit-border-radius: 0 3px 3px 0; + -moz-border-radius: 0 3px 3px 0; + border-radius: 0 3px 3px 0; + float: right; +} +.input-prepend.input-append .add-on:last-child, +.input-prepend.input-append .btn:last-child { + margin-right: -1px; + margin-left: 0px; + -webkit-border-radius: 3px 0 0 3px; + -moz-border-radius: 3px 0 0 3px; + border-radius: 3px 0 0 3px; +} +.input-prepend input, +.input-prepend select, +.input-prepend .uneditable-input { + -webkit-border-radius: 3px 0 0 3px; + -moz-border-radius: 3px 0 0 3px; + border-radius: 3px 0 0 3px; +} +body { + direction: rtl; +} +.pager .next a { + float: left; +} +.pager .previous a { + float: right; +} +.icon-arrow-right { + background-position: -241px -94px; + float: left; + padding-right: 3px; +} +.icon-arrow-left { + background-position: -264px -95px; +} +.icon-refresh { + background-position: -240px -23px; +} +#refresh-status { + background-position: right center; + padding-left: 0; + padding-right: 25px; +} +.radio input[type="radio"], +.checkbox input[type="checkbox"] { + float: right; + margin-right: 2px; + margin-left: 5px; +} +.list-striped, +.row-striped { + list-style: none; + line-height: 18px; + text-align: right; +} +.btn-group + .btn-group { + margin-right: 5px; + margin-left: 0px; +} +.tabs-left > .nav-tabs { + float: right; + margin-left: 19px; + border-left: 1px solid #DDD; + margin-right: 0px; + border-right: 0px; +} +.tabs-left > .nav-tabs .active > a, +.tabs-left > .nav-tabs .active > a:hover { + border-color: #DDD #DDD #DDD transparent; +} +.tabs-left > .nav-tabs > li > a { + margin-left: -1px; + -webkit-border-radius: 0 4px 4px 0; + -moz-border-radius: 0 4px 4px 0; + border-radius: 0 4px 4px 0; + margin-right: 0px; +} +.controls > .radio:first-child, +.controls > .checkbox:first-child { + padding-top: 0px; +} +.btn-toolbar { + margin-top: 14px; + margin-bottom: 3px; +} +.navbar .nav > li { + float: right; +} +.icon-folder-2 { + line-height: 25px; + padding-left: 5px; +} +.navbar .nav > li > a { + padding: 8px 10px; + color: #FFFFFF; +} +.navigation .nav li li .nav-child { + left: auto; + right: 100%; +} +.navigation .nav li li .nav-child:before { + left: auto; + right: -7px; + border-left: 7px solid rgba(0,0,0,0.2); + border-right-width: 0; +} +.navigation .nav li li .nav-child:after { + left: auto; + right: -6px; + border-left: 6px solid #ffffff; + border-right-width: 0; +} +.container-logo { + padding-top: 6px; + float: left; + text-align: left; +} +.modal-header .close { + float: left; +} +.pagination a { + float: right; +} +.pagination ul { + display: inline-block; + *display: inline; + *zoom: 1; + margin-right: 0; + margin-bottom: 0; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + -webkit-box-shadow: 0 1px 2px rgba(0,0,0,0.05); + -moz-box-shadow: 0 1px 2px rgba(0,0,0,0.05); + box-shadow: 0 1px 2px rgba(0,0,0,0.05); +} +.pagination a { + float: right; + padding: 0 14px; + line-height: 34px; + text-decoration: none; + border: 1px solid #ddd; + border-right-width: 0; +} +.pagination li:first-child a { + border-right-width: 1px; + -webkit-border-radius: 0 3px 3px 0; + -moz-border-radius: 0 3px 3px 0; + border-radius: 0 3px 3px 0; +} +.pagination li:last-child a { + -webkit-border-radius: 3px 0 0 3px; + -moz-border-radius: 3px 0 0 3px; + border-radius: 3px 0 0 3px; +} +.pagination-centered { + text-align: center; +} +.pagination-right { + text-align: right; +} +.icon-first:before { + content: "\e000"; +} +.icon-previous:before { + content: "\7d"; +} +.icon-last:before { + content: "\7b"; +} +.icon-next:before { + content: "\7c"; +} +.dl-horizontal dt { + float: right; + text-align: left; + clear: right; +} +.dl-horizontal dd { + margin-left: 0; + margin-right: 180px; +} +.dl-horizontal dt, +.profile> ul { + margin: 9px 25px 0 0; +} +.dropdown-submenu > a:after { + float: left; + border-width: 5px 5px 5px 0; + margin-left: -10px; + border-left-color: transparent; + border-right-color: #CCC; +} +.badge { + margin-left: 10px; +} +.tip-text { + text-align: right; +} +.icon-file-add:before { + content: "("; +} +.icon-eye-open:before, +.icon-eye:before { + content: ">"; +} +.icon-checkin:before, +.icon-checkbox:before { + content: "<"; +} +.icon-save-new:before, +.icon-plus-2:before { + content: "["; +} +.btn-toolbar .btn + .btn, +.btn-toolbar .btn-group + .btn, +.btn-toolbar .btn + .btn-group { + margin-left: 0; + margin-right: 5px; +} +.btn-toolbar .btn-wrapper { + display: inline-block; + margin: 0 5px 5px 0; +} +.btn-group > .btn + .btn { + margin-left: 0; + margin-right: -1px; +} +.input-append .add-on, +.input-append .btn, +.input-prepend .add-on, +.input-prepend .btn { + margin-left: 0; + margin-right: -1px; +} +.table-bordered { + border-right-width: 0; + border-left-width: 1px; + border-right-style: none; + border-left-style: solid; + border-right-color: -moz-use-text-color; + border-left-color: #DDDDDD; +} +.chzn-container-single .chzn-single { + padding-right: 8px; + padding-left: 0; +} +.chzn-container-single .chzn-single span { + margin-left: 26px; + margin-right: 0; +} +.chzn-container-single .chzn-single abbr { + left: 26px; + right: auto; +} +.chzn-container-single .chzn-single div { + left: 0; + right: auto; +} +.chzn-container-multi .chzn-choices li { + float: right; +} +.chzn-container-multi .chzn-choices .search-choice { + margin-right: 5px; + margin-left: 0; + padding-right: 5px; + padding-left: 20px; +} +.chzn-container-multi .chzn-choices .search-choice .search-choice-close { + left: 3px; + right: auto; +} +.chzn-container.chzn-with-drop .chzn-drop { + right: 0; + left: auto; +} +.chzn-container-single.chzn-container-single-nosearch .chzn-search { + position: absolute; + right: -9999px; + left: auto; +} +.chzn-container .chzn-drop { + right: -9999px; + left: auto; +} +.alert { + padding-right: 14px; + padding-left: 35px; +} +.alert .close { + left: -21px; + right: auto; +} +.close { + float: left; +} +.form-search .radio, +.form-search .checkbox, +.form-inline .radio, +.form-inline .checkbox { + margin-bottom: 9px; +} +.form-search .radio input[type="radio"], +.form-search .checkbox input[type="checkbox"], +.form-inline .radio input[type="radio"], +.form-inline .checkbox input[type="checkbox"] { + float: right; + margin-left: 3px; + margin-right: 0; +} +.com_media .container-main .media { + display: inline-block; +} +.thumbnails > li { + float: right; + margin-bottom: 18px; + margin-right: 20px; +} +#mediamanager-form .description, +#mediamanager-form .filesize, +#mediamanager-form .dimensions { + direction: ltr; +} +.popover, +.tooltip-inner { + text-align: right; +} +.popover.top .arrow, +.popover.bottom .arrow { + margin-right: -11px; +} +.popover.top .arrow:after, +.popover.bottom .arrow:after { + margin-right: -10px; +} +@media (max-width: 480px) { + .btn-toolbar .btn-wrapper { + display: block; + margin: 0 0 5px 0; + } + .btn-toolbar .btn-wrapper .btn { + margin-left: 0px; + margin-right: 10px; + } +} +#pop-print { + float: left; + margin: 10px; +} +#install_url, +#install_directory, +#jform_customurl, +#jform_link, +#jform_params_url, +input[type="url"] { + text-align: left; + direction: ltr; +} +#aside .nav .nav-child { + border-left: 0; + border-right: 2px solid #ddd; + padding-left: 0; + padding-right: 5px; +} +.dropdown-menu { + text-align: right; +} +[class^="icon-"], +[class*=" icon-"] { + margin-left: .25em; +} +.navbar .admin-logo { + float: right; + padding: 7px 15px 0px 12px; +} +.navbar .brand { + float: left; + padding: 6px 10px; +} +.navbar .nav { + margin: 0 0 0 10px; +} +.navbar .nav > li > a { + padding: 6px 10px; +} +.navbar .nav > li ul { + overflow-y: auto; + overflow-x: hidden; + -webkit-overflow-scrolling: touch; + -moz-overflow-scrolling: touch; + -ms-overflow-scrolling: touch; + -o-overflow-scrolling: touch; + overflow-scrolling: touch; + height: auto; + max-height: 500px; + margin: 0; +} +.navbar .nav > li ul::-webkit-scrollbar { + -webkit-appearance: none; + width: 7px; +} +.navbar .nav > li ul::-webkit-scrollbar-thumb { + border-radius: 4px; + background-color: rgba(0,0,0,0.5); + -webkit-box-shadow: 0 0 1px rgba(255,255,255,0.5); +} +.navbar .nav-user .dropdown-menu li span { + padding-left: 0; + padding-right: 10px; +} +.navbar .nav > .dropdown.open:after { + right: 10px; + width: 0; +} +.navbar .empty-nav { + display: none; +} +#toolbar .btn { + padding: 0 10px; +} +#toolbar [class^="icon-"], +#toolbar [class*=" icon-"] { + border-radius: 0 3px 3px 0; + border-right: 0; + border-left: 1px solid #b3b3b3; + margin: 0 -10px 0 6px; +} +.chzn-container-single .chzn-single { + padding-left: 8px; +} +.chzn-container-single .chzn-single div { + border-left: 0; + border-right: 1px solid #cccccc; +} +.chzn-container-single .chzn-single abbr { + left: 36px; +} +.chzn-container-active.chzn-with-drop .chzn-single div { + background-color: #f3f3f3; + border-bottom: 1px solid #cccccc; + border-bottom-left-radius: 0px; + border-bottom-right-radius: 3px; + border-left: 1px solid #cccccc; +} +.chzn-container-multi .chzn-choices .search-choice { + padding-left: 7px; +} +.chzn-container-multi .chzn-choices .search-choice .search-choice-close { + margin-left: 0; + margin-right: 3px; +} +.chzn-container .chzn-single.chzn-color[rel="value_0"] div, +.chzn-container .chzn-single.chzn-color[rel="value_1"] div { + border-right: none; +} +.chzn-container-single .chzn-search::after { + left: 20px; + right: auto; +} +.container-logo { + padding-top: 0; + float: left; + text-align: left; +} +.page-title [class^="icon-"], +.page-title [class*=" icon-"] { + margin-right: 0; + margin-left: 16px; +} +@media (max-width: 767px) { + .navbar .admin-logo { + margin-right: 10px; + padding: 9px 9px 0 9px; + } + .navbar .btn-navbar { + float: left; + margin-right: 5px; + margin-left: 3px; + } + .navbar .nav-collapse .nav.pull-left { + float: none; + margin-left: 0; + margin-right: 0; + } + .nav-collapse .nav > li { + float: none; + } + .page-title [class^="icon-"], + .page-title [class*=" icon-"] { + margin-left: 10px; + } +} +#status { + padding: 4px 10px; +} +#status .btn-group { + margin: 0; +} +#status .btn-group.separator:after { + content: ' '; + display: block; + float: left; + background: #ADADAD; + margin: 0 10px; + height: 15px; + width: 1px; +} +#status .badge { + margin-left: .25em; + margin-right: 0; +} +.dropdown-menu > li > a { + text-align: right; +} +.btn-group.btn-group-yesno > .btn, +.btn-group > .btn, +.btn-group > .btn + .dropdown-toggle { + float: none; +} +a.grid_false { + display: inline-block; + height: 16px; + width: 16px; + background-image: url('../images/admin/publish_r.png'); +} +a.grid_true { + display: inline-block; + height: 16px; + width: 16px; + background-image: url('../images/admin/icon-16-allow.png'); +} +.view-login .login-joomla { + position: absolute; + right: 50%; + height: 24px; + width: 24px; + margin-right: -12px; + font-size: 22px; +} +.view-login .input-medium { + width: 169px; +} +.login .chzn-single { + width: 219px !important; +} +.login .chzn-container, +.login .chzn-drop { + width: 227px !important; + max-width: 227px !important; +} +.login .input-prepend .chzn-container-single .chzn-single { + -webkit-border-radius: 3px 0 0 3px; + -moz-border-radius: 3px 0 0 3px; + border-radius: 3px 0 0 3px; + border-right: 0px; +} +.j-sidebar-container { + position: absolute; + display: block; + left: auto; + right: -16.5%; + padding-top: 28px; + padding-bottom: 40px; + clear: both; + margin: -10px -1px 0 0; + border-right: 0; + border-left: 1px solid #d3d3d3; +} +.j-sidebar-container.j-sidebar-hidden { + left: auto; + right: -16.5%; +} +.j-sidebar-container.j-sidebar-visible { + left: auto; + right: 0; +} +.j-toggle-sidebar-header { + padding: 10px 19px 10px 0; +} +.sidebar { + padding: 3px 4px 3px 3px; +} +.j-toggle-button-wrapper.j-toggle-hidden { + right: auto; + left: -24px; +} +.j-toggle-button-wrapper.j-toggle-visible { + right: auto; + left: 10px; +} +.j-sidebar-container .icon-folder-2 { + line-height: 15px; + padding-left: 0; +} +#system-message-container, +#j-main-container { + padding: 0 5px 0 0; +} +#system-message-container.j-toggle-main, +#j-main-container.j-toggle-main, +#system-debug.j-toggle-main { + float: left; +} +@media (max-width: 979px) { + .j-toggle-button-wrapper.j-toggle-hidden { + right: auto; + left: -20px; + } +} +@media (max-width: 767px) { + .j-sidebar-container { + position: relative; + padding: 0; + border-right: 0; + border-left: 0; + } + .j-sidebar-container.j-sidebar-hidden { + margin-left: auto; + margin-right: 16.5%; + } + .j-sidebar-container.j-sidebar-visible { + margin-left: auto; + margin-right: 0; + } + .view-login select { + width: 229px; + } +} +#j-main-container.expanded { + margin-right: 0; +} +@media (min-width: 768px) { + .row-fluid [class*="span"] { + margin-right: 15px; + margin-left: 0; + } + .row-fluid .modal-batch [class*="span"] { + margin-right: 0; + } +} +.row-fluid .modal-batch [class*="span"] { + margin-right: 0; +} +@media (max-width: 479px) { + .btn-toolbar .btn-wrapper .btn { + width: 100% !important; + margin-right: 0px; + } + .btn-toolbar .btn-wrapper { + margin: 0 10px 5px 10px; + } +} +@media (max-width: 420px) { + .j-sidebar-container { + margin: 0; + } + .view-login .input-medium { + width: 173px; + } + .view-login select { + width: 229px; + } +} +.js-pstats-data-details dd { + margin-right: 240px; +} +.modal-footer button { + float: left; +} +.modal-header { + text-align: right; +} +#mediamanager-form .thumbnails-media .thumbnail { + margin-left: 18px !important; + margin-right: 0; + direction: ltr; + text-align: center; +} +.thumbnails-media .imgThumb label::before, +.thumbnails-media .imgThumb .imgThumbInside::before { + left: 0; + right: auto; + border-radius: 3px 0; +} +.thumbnails-media .thumbnail input[type="radio"], +.thumbnails-media .thumbnail input[type="checkbox"] { + left: auto; + right: 5px; +} +.thumbnails-media .imgDelete a.close { + border-radius: 0 3px; +} +.thumbnails-media .imgPreview a, +.thumbnails-media .imgDetails { + border-radius: 3px 0; + border-width: 1px; + left: 0; + right: 0; + text-align: left; + direction: ltr; +} +.thumbnails-media .imgPreview a { + width: 100%; +} +.subform-table-layout td { + padding-left: 10px; +} +.subform-table-layout td::before { + content: attr(data-column); + left: auto; + right: 10px; + padding-left: 10px; + padding-right: 0; +} +.subform-table-layout .subform-repeatable tbody td:last-of-type { + text-align: left; +} +.subform-table-layout .form-horizontal .controls { + margin-top: 0; +} +.tree-holder ul ul { + padding-right: 15px; + box-shadow: 3px 0 0 rgba(0,0,0,0.08); + padding-left: 0; +} +.tree-holder ul ul .folder-url, +.tree-holder ul ul .file { + box-shadow: 3px 0 0 #3071a9; + border-right: 0; + border-left: 1px solid rgba(0,0,0,0.08); +} +.dropdown-reverse { + left: 0; + right: auto; +} +.com_cpanel .well > .row-striped > .row-fluid [class*="span"], +.com_cpanel .well > .list-striped > .row-fluid [class*="span"] { + margin-right: 0; +} diff --git a/Sites/pages/administrator/templates/isis/css/template.css b/Sites/pages/administrator/templates/isis/css/template.css new file mode 100644 index 00000000..a6996fc1 --- /dev/null +++ b/Sites/pages/administrator/templates/isis/css/template.css @@ -0,0 +1,9142 @@ +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +nav, +section { + display: block; +} +audio, +canvas, +video { + display: inline-block; + *display: inline; + *zoom: 1; +} +audio:not([controls]) { + display: none; +} +html { + font-size: 100%; + -webkit-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; +} +a:focus { + outline: thin dotted #333; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +a:hover, +a:active { + outline: 0; +} +sub, +sup { + position: relative; + font-size: 75%; + line-height: 0; + vertical-align: baseline; +} +sup { + top: -0.5em; +} +sub { + bottom: -0.25em; +} +img { + max-width: 100%; + width: auto \9; + height: auto; + vertical-align: middle; + border: 0; + -ms-interpolation-mode: bicubic; +} +#map_canvas img, +.google-maps img, +.gm-style img { + max-width: none; +} +button, +input, +select, +textarea { + margin: 0; + font-size: 100%; + vertical-align: middle; +} +button, +input { + *overflow: visible; + line-height: normal; +} +button::-moz-focus-inner, +input::-moz-focus-inner { + padding: 0; + border: 0; +} +button, +html input[type="button"], +input[type="reset"], +input[type="submit"] { + -webkit-appearance: button; + cursor: pointer; +} +label, +select, +button, +input[type="button"], +input[type="reset"], +input[type="submit"], +input[type="radio"], +input[type="checkbox"] { + cursor: pointer; +} +input[type="search"] { + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; + -webkit-appearance: textfield; +} +input[type="search"]::-webkit-search-decoration, +input[type="search"]::-webkit-search-cancel-button { + -webkit-appearance: none; +} +textarea { + overflow: auto; + vertical-align: top; +} +@media print { + * { + text-shadow: none !important; + color: #000 !important; + background: transparent !important; + box-shadow: none !important; + } + a, + a:visited { + text-decoration: underline; + } + a[href]:after { + content: " (" attr(href) ")"; + } + abbr[title]:after { + content: " (" attr(title) ")"; + } + .ir a:after, + a[href^="javascript:"]:after, + a[href^="#"]:after { + content: ""; + } + pre, + blockquote { + border: 1px solid #999; + page-break-inside: avoid; + } + thead { + display: table-header-group; + } + tr, + img { + page-break-inside: avoid; + } + img { + max-width: 100% !important; + } + @page { + margin: 0.5cm; + } + p, + h2, + h3 { + orphans: 3; + widows: 3; + } + h2, + h3 { + page-break-after: avoid; + } +} +.clearfix { + *zoom: 1; +} +.clearfix:before, +.clearfix:after { + display: table; + content: ""; + line-height: 0; +} +.clearfix:after { + clear: both; +} +.hide-text { + font: 0/0 a; + color: transparent; + text-shadow: none; + background-color: transparent; + border: 0; +} +.input-block-level { + display: block; + width: 100%; + min-height: 28px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +body { + margin: 0; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 13px; + line-height: 18px; + color: #333; + background-color: #fff; +} +a { + color: #3071a9; + text-decoration: none; +} +a:hover, +a:focus { + color: #1f496e; + text-decoration: underline; +} +.img-rounded { + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} +.img-polaroid { + padding: 4px; + background-color: #fff; + border: 1px solid #ccc; + border: 1px solid rgba(0,0,0,0.2); + -webkit-box-shadow: 0 1px 3px rgba(0,0,0,0.1); + -moz-box-shadow: 0 1px 3px rgba(0,0,0,0.1); + box-shadow: 0 1px 3px rgba(0,0,0,0.1); +} +.img-circle { + -webkit-border-radius: 500px; + -moz-border-radius: 500px; + border-radius: 500px; +} +.row { + margin-left: -20px; + *zoom: 1; +} +.row:before, +.row:after { + display: table; + content: ""; + line-height: 0; +} +.row:after { + clear: both; +} +[class*="span"] { + float: left; + min-height: 1px; + margin-left: 20px; +} +.container, +.navbar-static-top .container, +.navbar-fixed-top .container, +.navbar-fixed-bottom .container { + width: 940px; +} +.span12 { + width: 940px; +} +.span11 { + width: 860px; +} +.span10 { + width: 780px; +} +.span9 { + width: 700px; +} +.span8 { + width: 620px; +} +.span7 { + width: 540px; +} +.span6 { + width: 460px; +} +.span5 { + width: 380px; +} +.span4 { + width: 300px; +} +.span3 { + width: 220px; +} +.span2 { + width: 140px; +} +.span1 { + width: 60px; +} +.offset12 { + margin-left: 980px; +} +.offset11 { + margin-left: 900px; +} +.offset10 { + margin-left: 820px; +} +.offset9 { + margin-left: 740px; +} +.offset8 { + margin-left: 660px; +} +.offset7 { + margin-left: 580px; +} +.offset6 { + margin-left: 500px; +} +.offset5 { + margin-left: 420px; +} +.offset4 { + margin-left: 340px; +} +.offset3 { + margin-left: 260px; +} +.offset2 { + margin-left: 180px; +} +.offset1 { + margin-left: 100px; +} +.row-fluid { + width: 100%; + *zoom: 1; +} +.row-fluid:before, +.row-fluid:after { + display: table; + content: ""; + line-height: 0; +} +.row-fluid:after { + clear: both; +} +.row-fluid [class*="span"] { + display: block; + width: 100%; + min-height: 28px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + float: left; + margin-left: 2.1276595744681%; + *margin-left: 2.0744680851064%; +} +.row-fluid [class*="span"]:first-child { + margin-left: 0; +} +.row-fluid .controls-row [class*="span"] + [class*="span"] { + margin-left: 2.1276595744681%; +} +.row-fluid .span12 { + width: 100%; + *width: 99.946808510638%; +} +.row-fluid .span11 { + width: 91.489361702128%; + *width: 91.436170212766%; +} +.row-fluid .span10 { + width: 82.978723404255%; + *width: 82.925531914894%; +} +.row-fluid .span9 { + width: 74.468085106383%; + *width: 74.414893617021%; +} +.row-fluid .span8 { + width: 65.957446808511%; + *width: 65.904255319149%; +} +.row-fluid .span7 { + width: 57.446808510638%; + *width: 57.393617021277%; +} +.row-fluid .span6 { + width: 48.936170212766%; + *width: 48.882978723404%; +} +.row-fluid .span5 { + width: 40.425531914894%; + *width: 40.372340425532%; +} +.row-fluid .span4 { + width: 31.914893617021%; + *width: 31.86170212766%; +} +.row-fluid .span3 { + width: 23.404255319149%; + *width: 23.351063829787%; +} +.row-fluid .span2 { + width: 14.893617021277%; + *width: 14.840425531915%; +} +.row-fluid .span1 { + width: 6.3829787234043%; + *width: 6.3297872340426%; +} +.row-fluid .offset12 { + margin-left: 104.25531914894%; + *margin-left: 104.14893617021%; +} +.row-fluid .offset12:first-child { + margin-left: 102.12765957447%; + *margin-left: 102.02127659574%; +} +.row-fluid .offset11 { + margin-left: 95.744680851064%; + *margin-left: 95.63829787234%; +} +.row-fluid .offset11:first-child { + margin-left: 93.617021276596%; + *margin-left: 93.510638297872%; +} +.row-fluid .offset10 { + margin-left: 87.234042553191%; + *margin-left: 87.127659574468%; +} +.row-fluid .offset10:first-child { + margin-left: 85.106382978723%; + *margin-left: 85%; +} +.row-fluid .offset9 { + margin-left: 78.723404255319%; + *margin-left: 78.617021276596%; +} +.row-fluid .offset9:first-child { + margin-left: 76.595744680851%; + *margin-left: 76.489361702128%; +} +.row-fluid .offset8 { + margin-left: 70.212765957447%; + *margin-left: 70.106382978723%; +} +.row-fluid .offset8:first-child { + margin-left: 68.085106382979%; + *margin-left: 67.978723404255%; +} +.row-fluid .offset7 { + margin-left: 61.702127659574%; + *margin-left: 61.595744680851%; +} +.row-fluid .offset7:first-child { + margin-left: 59.574468085106%; + *margin-left: 59.468085106383%; +} +.row-fluid .offset6 { + margin-left: 53.191489361702%; + *margin-left: 53.085106382979%; +} +.row-fluid .offset6:first-child { + margin-left: 51.063829787234%; + *margin-left: 50.957446808511%; +} +.row-fluid .offset5 { + margin-left: 44.68085106383%; + *margin-left: 44.574468085106%; +} +.row-fluid .offset5:first-child { + margin-left: 42.553191489362%; + *margin-left: 42.446808510638%; +} +.row-fluid .offset4 { + margin-left: 36.170212765957%; + *margin-left: 36.063829787234%; +} +.row-fluid .offset4:first-child { + margin-left: 34.042553191489%; + *margin-left: 33.936170212766%; +} +.row-fluid .offset3 { + margin-left: 27.659574468085%; + *margin-left: 27.553191489362%; +} +.row-fluid .offset3:first-child { + margin-left: 25.531914893617%; + *margin-left: 25.425531914894%; +} +.row-fluid .offset2 { + margin-left: 19.148936170213%; + *margin-left: 19.042553191489%; +} +.row-fluid .offset2:first-child { + margin-left: 17.021276595745%; + *margin-left: 16.914893617021%; +} +.row-fluid .offset1 { + margin-left: 10.63829787234%; + *margin-left: 10.531914893617%; +} +.row-fluid .offset1:first-child { + margin-left: 8.5106382978723%; + *margin-left: 8.4042553191489%; +} +[class*="span"].hide, +.row-fluid [class*="span"].hide { + display: none; +} +[class*="span"].pull-right, +.row-fluid [class*="span"].pull-right { + float: right; +} +.container { + margin-right: auto; + margin-left: auto; + *zoom: 1; +} +.container:before, +.container:after { + display: table; + content: ""; + line-height: 0; +} +.container:after { + clear: both; +} +.container-fluid { + padding-right: 20px; + padding-left: 20px; + *zoom: 1; +} +.container-fluid:before, +.container-fluid:after { + display: table; + content: ""; + line-height: 0; +} +.container-fluid:after { + clear: both; +} +p { + margin: 0 0 9px; +} +.lead { + margin-bottom: 18px; + font-size: 19.5px; + font-weight: 200; + line-height: 27px; +} +small { + font-size: 85%; +} +strong { + font-weight: bold; +} +em { + font-style: italic; +} +cite { + font-style: normal; +} +.muted { + color: #999; +} +a.muted:hover, +a.muted:focus { + color: #808080; +} +.text-warning { + color: #8a6d3b; +} +a.text-warning:hover, +a.text-warning:focus { + color: #66512c; +} +.text-error { + color: #a94442; +} +a.text-error:hover, +a.text-error:focus { + color: #843534; +} +.text-info { + color: #31708f; +} +a.text-info:hover, +a.text-info:focus { + color: #245269; +} +.text-success { + color: #3c763d; +} +a.text-success:hover, +a.text-success:focus { + color: #2b542c; +} +.text-left { + text-align: left; +} +.text-right { + text-align: right; +} +.text-center { + text-align: center; +} +h1, +h2, +h3, +h4, +h5, +h6 { + margin: 9px 0; + font-family: inherit; + font-weight: bold; + line-height: 18px; + color: inherit; + text-rendering: optimizelegibility; +} +h1 small, +h2 small, +h3 small, +h4 small, +h5 small, +h6 small { + font-weight: normal; + line-height: 1; + color: #999; +} +h1, +h2, +h3 { + line-height: 36px; +} +h1 { + font-size: 35.75px; +} +h2 { + font-size: 29.25px; +} +h3 { + font-size: 22.75px; +} +h4 { + font-size: 16.25px; +} +h5 { + font-size: 13px; +} +h6 { + font-size: 11.05px; +} +h1 small { + font-size: 22.75px; +} +h2 small { + font-size: 16.25px; +} +h3 small { + font-size: 13px; +} +h4 small { + font-size: 13px; +} +.page-header { + padding-bottom: 8px; + margin: 18px 0 27px; + border-bottom: 1px solid #eee; +} +ul, +ol { + padding: 0; + margin: 0 0 9px 25px; +} +ul ul, +ul ol, +ol ol, +ol ul { + margin-bottom: 0; +} +li { + line-height: 18px; +} +ul.unstyled, +ol.unstyled { + margin-left: 0; + list-style: none; +} +ul.inline, +ol.inline { + margin-left: 0; + list-style: none; +} +ul.inline > li, +ol.inline > li { + display: inline-block; + *display: inline; + *zoom: 1; + padding-left: 5px; + padding-right: 5px; +} +dl { + margin-bottom: 18px; +} +dt, +dd { + line-height: 18px; +} +dt { + font-weight: bold; +} +dd { + margin-left: 9px; +} +.dl-horizontal { + *zoom: 1; +} +.dl-horizontal:before, +.dl-horizontal:after { + display: table; + content: ""; + line-height: 0; +} +.dl-horizontal:after { + clear: both; +} +.dl-horizontal dt { + float: left; + width: 160px; + clear: left; + text-align: right; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} +.dl-horizontal dd { + margin-left: 180px; +} +hr { + margin: 18px 0; + border: 0; + border-top: 1px solid #eee; + border-bottom: 1px solid #fff; +} +abbr[title], +abbr[data-original-title] { + cursor: help; + border-bottom: 1px dotted #999; +} +abbr.initialism { + font-size: 90%; + text-transform: uppercase; +} +blockquote { + padding: 0 0 0 15px; + margin: 0 0 18px; + border-left: 5px solid #eee; +} +blockquote p { + margin-bottom: 0; + font-size: 16.25px; + font-weight: 300; + line-height: 1.25; +} +blockquote small { + display: block; + line-height: 18px; + color: #999; +} +blockquote small:before { + content: '\2014 \00A0'; +} +blockquote.pull-right { + float: right; + padding-right: 15px; + padding-left: 0; + border-right: 5px solid #eee; + border-left: 0; +} +blockquote.pull-right p, +blockquote.pull-right small { + text-align: right; +} +blockquote.pull-right small:before { + content: ''; +} +blockquote.pull-right small:after { + content: '\00A0 \2014'; +} +q:before, +q:after, +blockquote:before, +blockquote:after { + content: ""; +} +address { + display: block; + margin-bottom: 18px; + font-style: normal; + line-height: 18px; +} +code, +pre { + padding: 0 3px 2px; + font-family: Monaco, Menlo, Consolas, "Courier New", monospace; + font-size: 11px; + color: #333; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} +code { + padding: 2px 4px; + color: #d14; + background-color: #f7f7f9; + border: 1px solid #e1e1e8; + white-space: nowrap; +} +pre { + display: block; + padding: 8.5px; + margin: 0 0 9px; + font-size: 12px; + line-height: 18px; + word-break: break-all; + word-wrap: break-word; + white-space: pre; + white-space: pre-wrap; + background-color: #f5f5f5; + border: 1px solid #ccc; + border: 1px solid rgba(0,0,0,0.15); + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} +pre.prettyprint { + margin-bottom: 18px; +} +pre code { + padding: 0; + color: inherit; + white-space: pre; + white-space: pre-wrap; + background-color: transparent; + border: 0; +} +.pre-scrollable { + max-height: 340px; + overflow-y: scroll; +} +form { + margin: 0 0 18px; +} +fieldset { + padding: 0; + margin: 0; + border: 0; +} +legend { + display: block; + width: 100%; + padding: 0; + margin-bottom: 18px; + font-size: 19.5px; + line-height: 36px; + color: #333; + border: 0; + border-bottom: 1px solid #e5e5e5; +} +legend small { + font-size: 13.5px; + color: #999; +} +label, +input, +button, +select, +textarea { + font-size: 13px; + font-weight: normal; + line-height: 18px; +} +input, +button, +select, +textarea { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; +} +label { + display: block; + margin-bottom: 5px; +} +select, +textarea, +input[type="text"], +input[type="password"], +input[type="datetime"], +input[type="datetime-local"], +input[type="date"], +input[type="month"], +input[type="time"], +input[type="week"], +input[type="number"], +input[type="email"], +input[type="url"], +input[type="search"], +input[type="tel"], +input[type="color"], +.uneditable-input { + display: inline-block; + height: 18px; + padding: 4px 6px; + margin-bottom: 9px; + font-size: 13px; + line-height: 18px; + color: #555; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + vertical-align: middle; +} +input, +textarea, +.uneditable-input { + width: 206px; +} +textarea { + height: auto; +} +textarea, +input[type="text"], +input[type="password"], +input[type="datetime"], +input[type="datetime-local"], +input[type="date"], +input[type="month"], +input[type="time"], +input[type="week"], +input[type="number"], +input[type="email"], +input[type="url"], +input[type="search"], +input[type="tel"], +input[type="color"], +.uneditable-input { + background-color: #fff; + border: 1px solid #ccc; + -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075); + -moz-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075); + box-shadow: inset 0 1px 1px rgba(0,0,0,0.075); + -webkit-transition: border linear .2s, box-shadow linear .2s; + -moz-transition: border linear .2s, box-shadow linear .2s; + -o-transition: border linear .2s, box-shadow linear .2s; + transition: border linear .2s, box-shadow linear .2s; +} +textarea:focus, +input[type="text"]:focus, +input[type="password"]:focus, +input[type="datetime"]:focus, +input[type="datetime-local"]:focus, +input[type="date"]:focus, +input[type="month"]:focus, +input[type="time"]:focus, +input[type="week"]:focus, +input[type="number"]:focus, +input[type="email"]:focus, +input[type="url"]:focus, +input[type="search"]:focus, +input[type="tel"]:focus, +input[type="color"]:focus, +.uneditable-input:focus { + border-color: rgba(82,168,236,0.8); + outline: 0; + outline: thin dotted \9; + -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6); + -moz-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6); + box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6); +} +input[type="radio"], +input[type="checkbox"] { + margin: 4px 0 0; + *margin-top: 0; + margin-top: 1px \9; + line-height: normal; +} +input[type="file"], +input[type="image"], +input[type="submit"], +input[type="reset"], +input[type="button"], +input[type="radio"], +input[type="checkbox"] { + width: auto; +} +select, +input[type="file"] { + height: 28px; + *margin-top: 4px; + line-height: 28px; +} +select { + width: 220px; + border: 1px solid #ccc; + background-color: #fff; +} +select[multiple], +select[size] { + height: auto; +} +select:focus, +input[type="file"]:focus, +input[type="radio"]:focus, +input[type="checkbox"]:focus { + outline: thin dotted #333; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +.uneditable-input, +.uneditable-textarea { + color: #999; + background-color: #fcfcfc; + border-color: #ccc; + -webkit-box-shadow: inset 0 1px 2px rgba(0,0,0,0.025); + -moz-box-shadow: inset 0 1px 2px rgba(0,0,0,0.025); + box-shadow: inset 0 1px 2px rgba(0,0,0,0.025); + cursor: not-allowed; +} +.uneditable-input { + overflow: hidden; + white-space: nowrap; +} +.uneditable-textarea { + width: auto; + height: auto; +} +input:-moz-placeholder, +textarea:-moz-placeholder { + color: #999; +} +input:-ms-input-placeholder, +textarea:-ms-input-placeholder { + color: #999; +} +input::-webkit-input-placeholder, +textarea::-webkit-input-placeholder { + color: #999; +} +.radio, +.checkbox { + min-height: 18px; + padding-left: 20px; +} +.radio input[type="radio"], +.checkbox input[type="checkbox"] { + float: left; + margin-left: -20px; +} +.controls > .radio:first-child, +.controls > .checkbox:first-child { + padding-top: 5px; +} +.radio.inline, +.checkbox.inline { + display: inline-block; + padding-top: 5px; + margin-bottom: 0; + vertical-align: middle; +} +.radio.inline + .radio.inline, +.checkbox.inline + .checkbox.inline { + margin-left: 10px; +} +.input-mini { + width: 60px; +} +.input-small { + width: 90px; +} +.input-medium { + width: 150px; +} +.input-large { + width: 210px; +} +.input-xlarge { + width: 270px; +} +.input-xxlarge { + width: 530px; +} +input[class*="span"], +select[class*="span"], +textarea[class*="span"], +.uneditable-input[class*="span"], +.row-fluid input[class*="span"], +.row-fluid select[class*="span"], +.row-fluid textarea[class*="span"], +.row-fluid .uneditable-input[class*="span"] { + float: none; + margin-left: 0; +} +.input-append input[class*="span"], +.input-append .uneditable-input[class*="span"], +.input-prepend input[class*="span"], +.input-prepend .uneditable-input[class*="span"], +.row-fluid input[class*="span"], +.row-fluid select[class*="span"], +.row-fluid textarea[class*="span"], +.row-fluid .uneditable-input[class*="span"], +.row-fluid .input-prepend [class*="span"], +.row-fluid .input-append [class*="span"] { + display: inline-block; +} +input, +textarea, +.uneditable-input { + margin-left: 0; +} +.controls-row [class*="span"] + [class*="span"] { + margin-left: 20px; +} +input.span12, +textarea.span12, +.uneditable-input.span12 { + width: 926px; +} +input.span11, +textarea.span11, +.uneditable-input.span11 { + width: 846px; +} +input.span10, +textarea.span10, +.uneditable-input.span10 { + width: 766px; +} +input.span9, +textarea.span9, +.uneditable-input.span9 { + width: 686px; +} +input.span8, +textarea.span8, +.uneditable-input.span8 { + width: 606px; +} +input.span7, +textarea.span7, +.uneditable-input.span7 { + width: 526px; +} +input.span6, +textarea.span6, +.uneditable-input.span6 { + width: 446px; +} +input.span5, +textarea.span5, +.uneditable-input.span5 { + width: 366px; +} +input.span4, +textarea.span4, +.uneditable-input.span4 { + width: 286px; +} +input.span3, +textarea.span3, +.uneditable-input.span3 { + width: 206px; +} +input.span2, +textarea.span2, +.uneditable-input.span2 { + width: 126px; +} +input.span1, +textarea.span1, +.uneditable-input.span1 { + width: 46px; +} +.controls-row { + *zoom: 1; +} +.controls-row:before, +.controls-row:after { + display: table; + content: ""; + line-height: 0; +} +.controls-row:after { + clear: both; +} +.controls-row [class*="span"], +.row-fluid .controls-row [class*="span"] { + float: left; +} +.controls-row .checkbox[class*="span"], +.controls-row .radio[class*="span"] { + padding-top: 5px; +} +input[disabled], +select[disabled], +textarea[disabled], +input[readonly], +select[readonly], +textarea[readonly] { + cursor: not-allowed; + background-color: #eee; +} +input[type="radio"][disabled], +input[type="checkbox"][disabled], +input[type="radio"][readonly], +input[type="checkbox"][readonly] { + background-color: transparent; +} +.control-group.warning .control-label, +.control-group.warning .help-block, +.control-group.warning .help-inline { + color: #8a6d3b; +} +.control-group.warning .checkbox, +.control-group.warning .radio, +.control-group.warning input, +.control-group.warning select, +.control-group.warning textarea { + color: #8a6d3b; +} +.control-group.warning input, +.control-group.warning select, +.control-group.warning textarea { + border-color: #8a6d3b; +} +.control-group.warning input:focus, +.control-group.warning select:focus, +.control-group.warning textarea:focus { + border-color: #66512c; +} +.control-group.warning .input-prepend .add-on, +.control-group.warning .input-append .add-on { + color: #8a6d3b; + background-color: #fcf8e3; + border-color: #8a6d3b; +} +.control-group.error .control-label, +.control-group.error .help-block, +.control-group.error .help-inline { + color: #a94442; +} +.control-group.error .checkbox, +.control-group.error .radio, +.control-group.error input, +.control-group.error select, +.control-group.error textarea { + color: #a94442; +} +.control-group.error input, +.control-group.error select, +.control-group.error textarea { + border-color: #a94442; +} +.control-group.error input:focus, +.control-group.error select:focus, +.control-group.error textarea:focus { + border-color: #843534; +} +.control-group.error .input-prepend .add-on, +.control-group.error .input-append .add-on { + color: #a94442; + background-color: #f2dede; + border-color: #a94442; +} +.control-group.success .control-label, +.control-group.success .help-block, +.control-group.success .help-inline { + color: #3c763d; +} +.control-group.success .checkbox, +.control-group.success .radio, +.control-group.success input, +.control-group.success select, +.control-group.success textarea { + color: #3c763d; +} +.control-group.success input, +.control-group.success select, +.control-group.success textarea { + border-color: #3c763d; +} +.control-group.success input:focus, +.control-group.success select:focus, +.control-group.success textarea:focus { + border-color: #2b542c; +} +.control-group.success .input-prepend .add-on, +.control-group.success .input-append .add-on { + color: #3c763d; + background-color: #dff0d8; + border-color: #3c763d; +} +.control-group.info .control-label, +.control-group.info .help-block, +.control-group.info .help-inline { + color: #31708f; +} +.control-group.info .checkbox, +.control-group.info .radio, +.control-group.info input, +.control-group.info select, +.control-group.info textarea { + color: #31708f; +} +.control-group.info input, +.control-group.info select, +.control-group.info textarea { + border-color: #31708f; +} +.control-group.info input:focus, +.control-group.info select:focus, +.control-group.info textarea:focus { + border-color: #245269; +} +.control-group.info .input-prepend .add-on, +.control-group.info .input-append .add-on { + color: #31708f; + background-color: #d9edf7; + border-color: #31708f; +} +input:focus:invalid, +textarea:focus:invalid, +select:focus:invalid { + color: #b94a48; + border-color: #ee5f5b; +} +input:focus:invalid:focus, +textarea:focus:invalid:focus, +select:focus:invalid:focus { + border-color: #e9322d; + -webkit-box-shadow: 0 0 6px #f8b9b7; + -moz-box-shadow: 0 0 6px #f8b9b7; + box-shadow: 0 0 6px #f8b9b7; +} +.form-actions { + padding: 17px 20px 18px; + margin-top: 18px; + margin-bottom: 18px; + background-color: #F0F0F0; + border-top: 1px solid #e5e5e5; + *zoom: 1; +} +.form-actions:before, +.form-actions:after { + display: table; + content: ""; + line-height: 0; +} +.form-actions:after { + clear: both; +} +.help-block, +.help-inline { + color: #595959; +} +.help-block { + display: block; + margin-bottom: 9px; +} +.help-inline { + display: inline-block; + *display: inline; + *zoom: 1; + vertical-align: middle; + padding-left: 5px; +} +.input-append, +.input-prepend { + display: inline-block; + margin-bottom: 9px; + vertical-align: middle; + font-size: 0; + white-space: nowrap; +} +.input-append input, +.input-append select, +.input-append .uneditable-input, +.input-append .dropdown-menu, +.input-append .popover, +.input-prepend input, +.input-prepend select, +.input-prepend .uneditable-input, +.input-prepend .dropdown-menu, +.input-prepend .popover { + font-size: 13px; +} +.input-append input, +.input-append select, +.input-append .uneditable-input, +.input-prepend input, +.input-prepend select, +.input-prepend .uneditable-input { + position: relative; + margin-bottom: 0; + *margin-left: 0; + vertical-align: top; + -webkit-border-radius: 0 3px 3px 0; + -moz-border-radius: 0 3px 3px 0; + border-radius: 0 3px 3px 0; +} +.input-append input:focus, +.input-append select:focus, +.input-append .uneditable-input:focus, +.input-prepend input:focus, +.input-prepend select:focus, +.input-prepend .uneditable-input:focus { + z-index: 2; +} +.input-append .add-on, +.input-prepend .add-on { + display: inline-block; + width: auto; + height: 18px; + min-width: 16px; + padding: 4px 5px; + font-size: 13px; + font-weight: normal; + line-height: 18px; + text-align: center; + text-shadow: 0 1px 0 #fff; + background-color: #eee; + border: 1px solid #ccc; +} +.input-append .add-on, +.input-append .btn, +.input-append .btn-group > .dropdown-toggle, +.input-prepend .add-on, +.input-prepend .btn, +.input-prepend .btn-group > .dropdown-toggle { + vertical-align: top; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.input-prepend .add-on, +.input-prepend .btn { + margin-right: -1px; +} +.input-prepend .add-on:first-child, +.input-prepend .btn:first-child { + -webkit-border-radius: 3px 0 0 3px; + -moz-border-radius: 3px 0 0 3px; + border-radius: 3px 0 0 3px; +} +.input-append input, +.input-append select, +.input-append .uneditable-input { + -webkit-border-radius: 3px 0 0 3px; + -moz-border-radius: 3px 0 0 3px; + border-radius: 3px 0 0 3px; +} +.input-append input + .btn-group .btn:last-child, +.input-append select + .btn-group .btn:last-child, +.input-append .uneditable-input + .btn-group .btn:last-child { + -webkit-border-radius: 0 3px 3px 0; + -moz-border-radius: 0 3px 3px 0; + border-radius: 0 3px 3px 0; +} +.input-append .add-on, +.input-append .btn, +.input-append .btn-group { + margin-left: -1px; +} +.input-append .add-on:last-child, +.input-append .btn:last-child, +.input-append .btn-group:last-child > .dropdown-toggle { + -webkit-border-radius: 0 3px 3px 0; + -moz-border-radius: 0 3px 3px 0; + border-radius: 0 3px 3px 0; +} +.input-prepend.input-append input, +.input-prepend.input-append select, +.input-prepend.input-append .uneditable-input { + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.input-prepend.input-append input + .btn-group .btn, +.input-prepend.input-append select + .btn-group .btn, +.input-prepend.input-append .uneditable-input + .btn-group .btn { + -webkit-border-radius: 0 3px 3px 0; + -moz-border-radius: 0 3px 3px 0; + border-radius: 0 3px 3px 0; +} +.input-prepend.input-append .add-on:first-child, +.input-prepend.input-append .btn:first-child { + margin-right: -1px; + -webkit-border-radius: 3px 0 0 3px; + -moz-border-radius: 3px 0 0 3px; + border-radius: 3px 0 0 3px; +} +.input-prepend.input-append .add-on:last-child, +.input-prepend.input-append .btn:last-child { + margin-left: -1px; + -webkit-border-radius: 0 3px 3px 0; + -moz-border-radius: 0 3px 3px 0; + border-radius: 0 3px 3px 0; +} +.input-prepend.input-append .btn-group:first-child { + margin-left: 0; +} +input.search-query { + padding-right: 14px; + padding-right: 4px \9; + padding-left: 14px; + padding-left: 4px \9; + margin-bottom: 0; + -webkit-border-radius: 15px; + -moz-border-radius: 15px; + border-radius: 15px; +} +.form-search .input-append .search-query, +.form-search .input-prepend .search-query { + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.form-search .input-append .search-query { + -webkit-border-radius: 14px 0 0 14px; + -moz-border-radius: 14px 0 0 14px; + border-radius: 14px 0 0 14px; +} +.form-search .input-append .btn { + -webkit-border-radius: 0 14px 14px 0; + -moz-border-radius: 0 14px 14px 0; + border-radius: 0 14px 14px 0; +} +.form-search .input-prepend .search-query { + -webkit-border-radius: 0 14px 14px 0; + -moz-border-radius: 0 14px 14px 0; + border-radius: 0 14px 14px 0; +} +.form-search .input-prepend .btn { + -webkit-border-radius: 14px 0 0 14px; + -moz-border-radius: 14px 0 0 14px; + border-radius: 14px 0 0 14px; +} +.js-stools-field-filter .input-prepend, +.js-stools-field-filter .input-append { + margin-bottom: 0; +} +.form-search input, +.form-search textarea, +.form-search select, +.form-search .help-inline, +.form-search .uneditable-input, +.form-search .input-prepend, +.form-search .input-append, +.form-inline input, +.form-inline textarea, +.form-inline select, +.form-inline .help-inline, +.form-inline .uneditable-input, +.form-inline .input-prepend, +.form-inline .input-append, +.form-horizontal input, +.form-horizontal textarea, +.form-horizontal select, +.form-horizontal .help-inline, +.form-horizontal .uneditable-input, +.form-horizontal .input-prepend, +.form-horizontal .input-append { + display: inline-block; + *display: inline; + *zoom: 1; + margin-bottom: 0; + vertical-align: middle; +} +.form-search .hide, +.form-inline .hide, +.form-horizontal .hide { + display: none; +} +.form-search label, +.form-inline label, +.form-search .btn-group, +.form-inline .btn-group { + display: inline-block; +} +.form-search .input-append, +.form-inline .input-append, +.form-search .input-prepend, +.form-inline .input-prepend { + margin-bottom: 0; +} +.form-search .radio, +.form-search .checkbox, +.form-inline .radio, +.form-inline .checkbox { + padding-left: 0; + margin-bottom: 0; + vertical-align: middle; +} +.form-search .radio input[type="radio"], +.form-search .checkbox input[type="checkbox"], +.form-inline .radio input[type="radio"], +.form-inline .checkbox input[type="checkbox"] { + float: left; + margin-right: 3px; + margin-left: 0; +} +.control-group { + margin-bottom: 9px; +} +legend + .control-group { + margin-top: 18px; + -webkit-margin-top-collapse: separate; +} +.form-horizontal .control-group { + margin-bottom: 18px; + *zoom: 1; +} +.form-horizontal .control-group:before, +.form-horizontal .control-group:after { + display: table; + content: ""; + line-height: 0; +} +.form-horizontal .control-group:after { + clear: both; +} +.form-horizontal .control-label { + float: left; + width: 160px; + padding-top: 5px; + text-align: right; +} +.form-horizontal .controls { + *display: inline-block; + *padding-left: 20px; + margin-left: 180px; + *margin-left: 0; +} +.form-horizontal .controls:first-child { + *padding-left: 180px; +} +.form-horizontal .help-block { + margin-bottom: 0; +} +.form-horizontal input + .help-block, +.form-horizontal select + .help-block, +.form-horizontal textarea + .help-block, +.form-horizontal .uneditable-input + .help-block, +.form-horizontal .input-prepend + .help-block, +.form-horizontal .input-append + .help-block { + margin-top: 9px; +} +.form-horizontal .form-actions { + padding-left: 180px; +} +.control-label .hasPopover, +.control-label .hasTooltip { + display: inline-block; +} +.subform-repeatable-wrapper .btn-group>.btn.button { + min-width: 0; +} +.subform-repeatable-wrapper .ui-sortable-helper { + background: #fff; +} +.subform-repeatable-wrapper tr.ui-sortable-helper { + display: table; +} +@media (min-width: 980px) and (max-width: 1215px) { + .float-cols .control-label { + float: none; + } + .float-cols .controls { + margin-left: 0; + } +} +table { + max-width: 100%; + background-color: transparent; + border-collapse: collapse; + border-spacing: 0; +} +.table { + width: 100%; + margin-bottom: 18px; +} +.table th, +.table td { + padding: 8px; + line-height: 18px; + text-align: left; + vertical-align: top; + border-top: 1px solid #ddd; +} +.table th { + font-weight: bold; +} +.table thead th { + vertical-align: bottom; +} +.table caption + thead tr:first-child th, +.table caption + thead tr:first-child td, +.table colgroup + thead tr:first-child th, +.table colgroup + thead tr:first-child td, +.table thead:first-child tr:first-child th, +.table thead:first-child tr:first-child td { + border-top: 0; +} +.table tbody + tbody { + border-top: 2px solid #ddd; +} +.table .table { + background-color: #fff; +} +.table-condensed th, +.table-condensed td { + padding: 4px 5px; +} +.table-bordered { + border: 1px solid #ddd; + border-collapse: separate; + *border-collapse: collapse; + border-left: 0; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} +.table-bordered th, +.table-bordered td { + border-left: 1px solid #ddd; +} +.table-bordered caption + thead tr:first-child th, +.table-bordered caption + tbody tr:first-child th, +.table-bordered caption + tbody tr:first-child td, +.table-bordered colgroup + thead tr:first-child th, +.table-bordered colgroup + tbody tr:first-child th, +.table-bordered colgroup + tbody tr:first-child td, +.table-bordered thead:first-child tr:first-child th, +.table-bordered tbody:first-child tr:first-child th, +.table-bordered tbody:first-child tr:first-child td { + border-top: 0; +} +.table-bordered thead:first-child tr:first-child > th:first-child, +.table-bordered tbody:first-child tr:first-child > td:first-child, +.table-bordered tbody:first-child tr:first-child > th:first-child { + -webkit-border-top-left-radius: 3px; + -moz-border-radius-topleft: 3px; + border-top-left-radius: 3px; +} +.table-bordered thead:first-child tr:first-child > th:last-child, +.table-bordered tbody:first-child tr:first-child > td:last-child, +.table-bordered tbody:first-child tr:first-child > th:last-child { + -webkit-border-top-right-radius: 3px; + -moz-border-radius-topright: 3px; + border-top-right-radius: 3px; +} +.table-bordered thead:last-child tr:last-child > th:first-child, +.table-bordered tbody:last-child tr:last-child > td:first-child, +.table-bordered tbody:last-child tr:last-child > th:first-child, +.table-bordered tfoot:last-child tr:last-child > td:first-child, +.table-bordered tfoot:last-child tr:last-child > th:first-child { + -webkit-border-bottom-left-radius: 3px; + -moz-border-radius-bottomleft: 3px; + border-bottom-left-radius: 3px; +} +.table-bordered thead:last-child tr:last-child > th:last-child, +.table-bordered tbody:last-child tr:last-child > td:last-child, +.table-bordered tbody:last-child tr:last-child > th:last-child, +.table-bordered tfoot:last-child tr:last-child > td:last-child, +.table-bordered tfoot:last-child tr:last-child > th:last-child { + -webkit-border-bottom-right-radius: 3px; + -moz-border-radius-bottomright: 3px; + border-bottom-right-radius: 3px; +} +.table-bordered tfoot + tbody:last-child tr:last-child td:first-child { + -webkit-border-bottom-left-radius: 0; + -moz-border-radius-bottomleft: 0; + border-bottom-left-radius: 0; +} +.table-bordered tfoot + tbody:last-child tr:last-child td:last-child { + -webkit-border-bottom-right-radius: 0; + -moz-border-radius-bottomright: 0; + border-bottom-right-radius: 0; +} +.table-bordered caption + thead tr:first-child th:first-child, +.table-bordered caption + tbody tr:first-child td:first-child, +.table-bordered colgroup + thead tr:first-child th:first-child, +.table-bordered colgroup + tbody tr:first-child td:first-child { + -webkit-border-top-left-radius: 3px; + -moz-border-radius-topleft: 3px; + border-top-left-radius: 3px; +} +.table-bordered caption + thead tr:first-child th:last-child, +.table-bordered caption + tbody tr:first-child td:last-child, +.table-bordered colgroup + thead tr:first-child th:last-child, +.table-bordered colgroup + tbody tr:first-child td:last-child { + -webkit-border-top-right-radius: 3px; + -moz-border-radius-topright: 3px; + border-top-right-radius: 3px; +} +.table-striped tbody > tr:nth-child(odd) > td, +.table-striped tbody > tr:nth-child(odd) > th { + background-color: #f9f9f9; +} +.table-hover tbody tr:hover > td, +.table-hover tbody tr:hover > th { + background-color: #F0F0F0; +} +table td[class*="span"], +table th[class*="span"], +.row-fluid table td[class*="span"], +.row-fluid table th[class*="span"] { + display: table-cell; + float: none; + margin-left: 0; +} +.table td.span1, +.table th.span1 { + float: none; + width: 44px; + margin-left: 0; +} +.table td.span2, +.table th.span2 { + float: none; + width: 124px; + margin-left: 0; +} +.table td.span3, +.table th.span3 { + float: none; + width: 204px; + margin-left: 0; +} +.table td.span4, +.table th.span4 { + float: none; + width: 284px; + margin-left: 0; +} +.table td.span5, +.table th.span5 { + float: none; + width: 364px; + margin-left: 0; +} +.table td.span6, +.table th.span6 { + float: none; + width: 444px; + margin-left: 0; +} +.table td.span7, +.table th.span7 { + float: none; + width: 524px; + margin-left: 0; +} +.table td.span8, +.table th.span8 { + float: none; + width: 604px; + margin-left: 0; +} +.table td.span9, +.table th.span9 { + float: none; + width: 684px; + margin-left: 0; +} +.table td.span10, +.table th.span10 { + float: none; + width: 764px; + margin-left: 0; +} +.table td.span11, +.table th.span11 { + float: none; + width: 844px; + margin-left: 0; +} +.table td.span12, +.table th.span12 { + float: none; + width: 924px; + margin-left: 0; +} +.table tbody tr.success > td { + background-color: #dff0d8; +} +.table tbody tr.error > td { + background-color: #f2dede; +} +.table tbody tr.warning > td { + background-color: #fcf8e3; +} +.table tbody tr.info > td { + background-color: #d9edf7; +} +.table-hover tbody tr.success:hover > td { + background-color: #d0e9c6; +} +.table-hover tbody tr.error:hover > td { + background-color: #ebcccc; +} +.table-hover tbody tr.warning:hover > td { + background-color: #faf2cc; +} +.table-hover tbody tr.info:hover > td { + background-color: #c4e3f3; +} +.table-noheader { + border-collapse: collapse; +} +.table-noheader thead { + display: none; +} +.dropup, +.dropdown { + position: relative; +} +.dropdown-toggle { + *margin-bottom: -3px; +} +.dropdown-toggle:active, +.open .dropdown-toggle { + outline: 0; +} +.caret { + display: inline-block; + width: 0; + height: 0; + vertical-align: top; + border-top: 4px solid #000; + border-right: 4px solid transparent; + border-left: 4px solid transparent; + content: ""; +} +.dropdown .caret { + margin-top: 8px; + margin-left: 2px; +} +.dropdown-menu { + position: absolute; + top: 100%; + left: 0; + z-index: 1000; + display: none; + float: left; + min-width: 160px; + padding: 5px 0; + margin: 2px 0 0; + list-style: none; + background-color: #fff; + border: 1px solid #ccc; + border: 1px solid rgba(0,0,0,0.2); + *border-right-width: 2px; + *border-bottom-width: 2px; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; + -webkit-box-shadow: 0 5px 10px rgba(0,0,0,0.2); + -moz-box-shadow: 0 5px 10px rgba(0,0,0,0.2); + box-shadow: 0 5px 10px rgba(0,0,0,0.2); + -webkit-background-clip: padding-box; + -moz-background-clip: padding; + background-clip: padding-box; +} +.dropdown-menu.pull-right { + right: 0; + left: auto; +} +.dropdown-menu .divider { + *width: 100%; + height: 1px; + margin: 8px 1px; + *margin: -5px 0 5px; + overflow: hidden; + background-color: #F0F0F0; + border-bottom: 1px solid #fff; +} +.dropdown-menu .menuitem-group { + margin: 4px 1px; + overflow: hidden; + border-top: 1px solid #eee; + border-bottom: 1px solid #eee; + background-color: #eee; + color: #555; + text-transform: capitalize; + font-size: 95%; + padding: 3px 20px; +} +.dropdown-menu > li > a { + display: block; + padding: 3px 20px; + clear: both; + font-weight: normal; + line-height: 18px; + color: #333; + white-space: nowrap; +} +.dropdown-menu > li > a:hover, +.dropdown-menu > li > a:focus, +.dropdown-submenu:hover > a, +.dropdown-submenu:focus > a { + text-decoration: none; + color: #fff; + background-color: #2d6ca2; + background-image: -moz-linear-gradient(top,#3071a9,#2a6496); + background-image: -webkit-gradient(linear,0 0,0 100%,from(#3071a9),to(#2a6496)); + background-image: -webkit-linear-gradient(top,#3071a9,#2a6496); + background-image: -o-linear-gradient(top,#3071a9,#2a6496); + background-image: linear-gradient(to bottom,#3071a9,#2a6496); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff2f70a9', endColorstr='#ff296395', GradientType=0); +} +.dropdown-menu > .active > a, +.dropdown-menu > .active > a:hover, +.dropdown-menu > .active > a:focus { + color: #333; + text-decoration: none; + outline: 0; + background-color: #2d6ca2; + background-image: -moz-linear-gradient(top,#3071a9,#2a6496); + background-image: -webkit-gradient(linear,0 0,0 100%,from(#3071a9),to(#2a6496)); + background-image: -webkit-linear-gradient(top,#3071a9,#2a6496); + background-image: -o-linear-gradient(top,#3071a9,#2a6496); + background-image: linear-gradient(to bottom,#3071a9,#2a6496); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff2f70a9', endColorstr='#ff296395', GradientType=0); +} +.dropdown-menu > .disabled > a, +.dropdown-menu > .disabled > a:hover, +.dropdown-menu > .disabled > a:focus { + color: #999; +} +.dropdown-menu > .disabled > a:hover, +.dropdown-menu > .disabled > a:focus { + text-decoration: none; + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + cursor: default; +} +.open { + *z-index: 1000; +} +.open > .dropdown-menu { + display: block; +} +.dropdown-backdrop { + position: fixed; + left: 0; + right: 0; + bottom: 0; + top: 0; + z-index: 990; +} +.pull-right > .dropdown-menu { + right: 0; + left: auto; +} +.dropup .caret, +.navbar-fixed-bottom .dropdown .caret { + border-top: 0; + border-bottom: 4px solid #000; + content: ""; +} +.dropup .dropdown-menu, +.navbar-fixed-bottom .dropdown .dropdown-menu { + top: auto; + bottom: 100%; + margin-bottom: 1px; +} +.dropdown-submenu { + position: relative; +} +.dropdown-submenu > .dropdown-menu { + top: 0; + left: 100%; + margin-top: -6px; + margin-left: -1px; + -webkit-border-radius: 6px 6px 6px 6px; + -moz-border-radius: 6px 6px 6px 6px; + border-radius: 6px 6px 6px 6px; +} +.dropdown-submenu:hover > .dropdown-menu { + display: block; +} +.dropup .dropdown-submenu > .dropdown-menu { + top: auto; + bottom: 0; + margin-top: 0; + margin-bottom: -2px; + -webkit-border-radius: 5px 5px 5px 0; + -moz-border-radius: 5px 5px 5px 0; + border-radius: 5px 5px 5px 0; +} +.dropdown-submenu > a:after { + display: block; + content: " "; + float: right; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; + border-width: 5px 0 5px 5px; + border-left-color: #cccccc; + margin-top: 5px; + margin-right: -10px; +} +.dropdown-submenu:hover > a:after { + border-left-color: #fff; +} +.dropdown-submenu.pull-left { + float: none; +} +.dropdown-submenu.pull-left > .dropdown-menu { + left: -100%; + margin-left: 10px; + -webkit-border-radius: 6px 0 6px 6px; + -moz-border-radius: 6px 0 6px 6px; + border-radius: 6px 0 6px 6px; +} +.dropdown .dropdown-menu .nav-header { + padding-left: 20px; + padding-right: 20px; +} +.typeahead { + z-index: 1051; + margin-top: 2px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} +.well { + min-height: 20px; + padding: 19px; + margin-bottom: 20px; + background-color: #F0F0F0; + border: 1px solid #F0F0F0; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} +.well blockquote { + border-color: #f0f0f0; + border-color: rgba(0,0,0,0.15); +} +.well-large { + padding: 24px; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} +.well-small { + padding: 9px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} +.fade { + opacity: 0; + -webkit-transition: opacity .15s linear; + -moz-transition: opacity .15s linear; + -o-transition: opacity .15s linear; + transition: opacity .15s linear; +} +.fade.in { + opacity: 1; +} +.collapse { + position: relative; + height: 0; + overflow: hidden; + -webkit-transition: height .35s ease; + -moz-transition: height .35s ease; + -o-transition: height .35s ease; + transition: height .35s ease; +} +.collapse.in { + height: auto; +} +.close { + float: right; + font-size: 20px; + font-weight: bold; + line-height: 18px; + color: #000; + text-shadow: 0 1px 0 #ffffff; + opacity: 0.2; + filter: alpha(opacity=20); +} +.close:hover, +.close:focus { + color: #000; + text-decoration: none; + cursor: pointer; + opacity: 0.4; + filter: alpha(opacity=40); +} +button.close { + padding: 3; + cursor: pointer; + background: transparent; + border: 0; + -webkit-appearance: none; +} +.alert-options { + float: right; + line-height: 18px; + color: #000; + text-shadow: 0 1px 0 #ffffff; + opacity: 0.2; + filter: alpha(opacity=20); +} +.alert-options:hover, +.alert-options:focus { + color: #000; + text-decoration: none; + cursor: pointer; + opacity: 0.4; + filter: alpha(opacity=40); +} +.btn { + display: inline-block; + *display: inline; + *zoom: 1; + padding: 4px 12px; + margin-bottom: 0; + font-size: 13px; + line-height: 18px; + text-align: center; + vertical-align: middle; + cursor: pointer; + background-color: #f3f3f3; + color: #333; + border: 1px solid #b3b3b3; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + box-shadow: 0 1px 2px rgba(0,0,0,0.05); +} +.btn:hover, +.btn:focus { + background-color: #e6e6e6; + text-decoration: none; + text-shadow: none; +} +.btn:focus { + outline: thin dotted #333; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +.btn.active, +.btn:active { + background-image: none; + outline: 0; +} +.btn.disabled, +.btn[disabled] { + cursor: default; + background-image: none; + opacity: 0.65; + filter: alpha(opacity=65); + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; +} +.btn-large { + padding: 11px 19px; + font-size: 16.25px; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} +.btn-large [class^="icon-"], +.btn-large [class*=" icon-"] { + margin-top: 4px; +} +.btn-small { + padding: 2px 10px; + font-size: 12px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} +.btn-small [class^="icon-"], +.btn-small [class*=" icon-"] { + margin-top: 0; +} +.btn-mini [class^="icon-"], +.btn-mini [class*=" icon-"] { + margin-top: -1px; +} +.btn-mini { + padding: 0 6px; + font-size: 9.75px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} +.btn-block { + display: block; + width: 100%; + padding-left: 0; + padding-right: 0; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +.btn-block + .btn-block { + margin-top: 5px; +} +input[type="submit"].btn-block, +input[type="reset"].btn-block, +input[type="button"].btn-block { + width: 100%; +} +.btn-primary, +.btn-warning, +.btn-danger, +.btn-success, +.btn-info, +.btn-inverse { + box-shadow: 0 1px 2px rgba(0,0,0,0.05); +} +.btn-primary { + border: 1px solid #15497c; + border: 1px solid rgba(0,0,0,0.2); + color: #fff; + background-color: #2384d3; +} +.btn-primary:hover, +.btn-primary:focus { + background-color: #185b91; + color: #fff; + text-decoration: none; +} +.btn-warning { + border: 1px solid #f89406; + border: 1px solid rgba(0,0,0,0.2); + color: #fff; + background-color: #f89406; +} +.btn-warning:hover, +.btn-warning:focus { + background-color: #ad6704; + color: #fff; + text-decoration: none; + text-shadow: none; +} +.btn-danger { + border: 1px solid #bd362f; + border: 1px solid rgba(0,0,0,0.2); + color: #fff; + background-color: #bd362f; +} +.btn-danger:hover, +.btn-danger:focus { + background-color: #802420; + color: #fff; + text-decoration: none; +} +.btn-success { + border: 1px solid #378137; + border: 1px solid rgba(0,0,0,0.2); + color: #fff; + background-color: #46a546; +} +.btn-success:hover, +.btn-success:focus { + background-color: #2f6f2f; + color: #fff; + text-decoration: none; +} +.btn-info { + border: 1px solid #2f96b4; + border: 1px solid rgba(0,0,0,0.2); + color: #fff; + background-color: #2f96b4; +} +.btn-info:hover, +.btn-info:focus { + background-color: #1f6377; + color: #fff; + text-decoration: none; +} +.btn-inverse { + border: 1px solid #444; + border: 1px solid rgba(0,0,0,0.2); + color: #fff; + background-color: #444; +} +.btn-inverse:hover, +.btn-inverse:focus { + background-color: #1e1e1e; + color: #fff; + text-decoration: none; +} +button.btn, +input[type="submit"].btn { + *padding-top: 3px; + *padding-bottom: 3px; +} +button.btn::-moz-focus-inner, +input[type="submit"].btn::-moz-focus-inner { + padding: 0; + border: 0; +} +button.btn.btn-large, +input[type="submit"].btn.btn-large { + *padding-top: 7px; + *padding-bottom: 7px; +} +button.btn.btn-small, +input[type="submit"].btn.btn-small { + *padding-top: 3px; + *padding-bottom: 3px; +} +button.btn.btn-mini, +input[type="submit"].btn.btn-mini { + *padding-top: 1px; + *padding-bottom: 1px; +} +.btn-link, +.btn-link:active, +.btn-link[disabled] { + background-color: transparent; + background-image: none; + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; +} +.btn-link { + border-color: transparent; + cursor: pointer; + color: #3071a9; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.btn-link:hover, +.btn-link:focus { + color: #1f496e; + text-decoration: underline; + background-color: transparent; +} +.btn-link[disabled]:hover, +.btn-link[disabled]:focus { + color: #333; + text-decoration: none; +} +.btn-group { + position: relative; + display: inline-block; + *display: inline; + *zoom: 1; + font-size: 0; + vertical-align: middle; + white-space: nowrap; + *margin-left: .3em; +} +.btn-group:first-child { + *margin-left: 0; +} +.btn-group .btn + .btn { + margin-left: -1px; +} +.btn-group + .btn-group { + margin-left: 5px; +} +.btn-toolbar { + font-size: 0; + margin-top: 9px; + margin-bottom: 9px; +} +.btn-toolbar > .btn + .btn, +.btn-toolbar > .btn-group + .btn, +.btn-toolbar > .btn + .btn-group { + margin-left: 5px; +} +.btn-group > .btn { + position: relative; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.btn-group > .btn-micro { + margin-left: -1px; +} +.btn-group > .btn, +.btn-group > .dropdown-menu, +.btn-group > .popover { + font-size: 13px; +} +.btn-group > .btn-mini { + font-size: 9.75px; +} +.btn-group > .btn-small { + font-size: 12px; +} +.btn-group > .btn-large { + font-size: 16.25px; +} +.btn-group > .btn:first-child { + margin-left: 0; + -webkit-border-top-left-radius: 3px; + -moz-border-radius-topleft: 3px; + border-top-left-radius: 3px; + -webkit-border-bottom-left-radius: 3px; + -moz-border-radius-bottomleft: 3px; + border-bottom-left-radius: 3px; +} +.btn-group > .btn:last-child, +.btn-group > .dropdown-toggle { + -webkit-border-top-right-radius: 3px; + -moz-border-radius-topright: 3px; + border-top-right-radius: 3px; + -webkit-border-bottom-right-radius: 3px; + -moz-border-radius-bottomright: 3px; + border-bottom-right-radius: 3px; +} +.btn-group > .btn.large:first-child { + margin-left: 0; + -webkit-border-top-left-radius: 6px; + -moz-border-radius-topleft: 6px; + border-top-left-radius: 6px; + -webkit-border-bottom-left-radius: 6px; + -moz-border-radius-bottomleft: 6px; + border-bottom-left-radius: 6px; +} +.btn-group > .btn.large:last-child, +.btn-group > .large.dropdown-toggle { + -webkit-border-top-right-radius: 6px; + -moz-border-radius-topright: 6px; + border-top-right-radius: 6px; + -webkit-border-bottom-right-radius: 6px; + -moz-border-radius-bottomright: 6px; + border-bottom-right-radius: 6px; +} +.btn-group > .btn:hover, +.btn-group > .btn:focus, +.btn-group > .btn:active, +.btn-group > .btn.active { + z-index: 2; +} +.btn-group .dropdown-toggle:active, +.btn-group.open .dropdown-toggle { + outline: 0; +} +.btn-group > .btn + .dropdown-toggle { + padding-left: 8px; + padding-right: 8px; + *padding-top: 5px; + *padding-bottom: 5px; +} +.btn-group > .btn-mini + .dropdown-toggle { + padding-left: 5px; + padding-right: 5px; + *padding-top: 2px; + *padding-bottom: 2px; +} +.btn-group > .btn-small + .dropdown-toggle { + *padding-top: 5px; + *padding-bottom: 4px; +} +.btn-group > .btn-large + .dropdown-toggle { + padding-left: 12px; + padding-right: 12px; + *padding-top: 7px; + *padding-bottom: 7px; +} +.btn-group.open .dropdown-toggle { + background-image: none; +} +.btn-group.open .btn.dropdown-toggle { + background-color: #e6e6e6; +} +.btn-group.open .btn-primary.dropdown-toggle { + background-color: #15497c; +} +.btn-group.open .btn-warning.dropdown-toggle { + background-color: #c67605; +} +.btn-group.open .btn-danger.dropdown-toggle { + background-color: #942a25; +} +.btn-group.open .btn-success.dropdown-toggle { + background-color: #378137; +} +.btn-group.open .btn-info.dropdown-toggle { + background-color: #24748c; +} +.btn-group.open .btn-inverse.dropdown-toggle { + background-color: #222; +} +.btn .caret { + margin-top: 8px; + margin-left: 0; +} +.btn-large .caret { + margin-top: 6px; +} +.btn-large .caret { + border-left-width: 5px; + border-right-width: 5px; + border-top-width: 5px; +} +.btn-mini .caret, +.btn-small .caret { + margin-top: 8px; +} +.dropup .btn-large .caret { + border-bottom-width: 5px; +} +.btn-primary .caret { + border-top-color: #1f496e; + border-bottom-color: #1f496e; +} +.btn-warning .caret, +.btn-danger .caret, +.btn-info .caret, +.btn-success .caret, +.btn-inverse .caret { + border-top-color: #fff; + border-bottom-color: #fff; +} +.btn-group-vertical { + display: inline-block; + *display: inline; + *zoom: 1; +} +.btn-group-vertical > .btn { + display: block; + float: none; + max-width: 100%; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.btn-group-vertical > .btn + .btn { + margin-left: 0; + margin-top: -1px; +} +.btn-group-vertical > .btn:first-child { + -webkit-border-radius: 3px 3px 0 0; + -moz-border-radius: 3px 3px 0 0; + border-radius: 3px 3px 0 0; +} +.btn-group-vertical > .btn:last-child { + -webkit-border-radius: 0 0 3px 3px; + -moz-border-radius: 0 0 3px 3px; + border-radius: 0 0 3px 3px; +} +.btn-group-vertical > .btn-large:first-child { + -webkit-border-radius: 6px 6px 0 0; + -moz-border-radius: 6px 6px 0 0; + border-radius: 6px 6px 0 0; +} +.btn-group-vertical > .btn-large:last-child { + -webkit-border-radius: 0 0 6px 6px; + -moz-border-radius: 0 0 6px 6px; + border-radius: 0 0 6px 6px; +} +.alert { + padding: 8px 35px 8px 14px; + margin-bottom: 18px; + text-shadow: 0 1px 0 rgba(255,255,255,0.5); + background-color: #fcf8e3; + border: 1px solid #faebcc; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} +.alert, +.alert h4 { + color: #8a6d3b; +} +.alert h4 { + margin: 0 0 .5em; +} +.alert .close { + position: relative; + top: -2px; + right: -21px; + line-height: 18px; + cursor: pointer; +} +.alert-success { + background-color: #dff0d8; + border-color: #d6e9c6; + color: #3c763d; +} +.alert-success h4 { + color: #3c763d; +} +.alert-danger, +.alert-error { + background-color: #f2dede; + border-color: #ebccd1; + color: #a94442; +} +.alert-danger h4, +.alert-error h4 { + color: #a94442; +} +.alert-info { + background-color: #d9edf7; + border-color: #bce8f1; + color: #31708f; +} +.alert-info h4 { + color: #31708f; +} +.alert-block { + padding-top: 14px; + padding-bottom: 14px; +} +.alert-block > p, +.alert-block > ul { + margin-bottom: 0; +} +.alert-block p + p { + margin-top: 5px; +} +.nav { + margin-left: 0; + margin-bottom: 18px; + list-style: none; +} +.nav > li > a { + display: block; +} +.nav > li > a:hover, +.nav > li > a:focus { + text-decoration: none; + background-color: #eee; +} +.nav > li > a > img { + max-width: none; +} +.nav > .pull-right { + float: right; +} +.nav-header { + display: block; + padding: 3px 15px; + font-size: 11px; + font-weight: bold; + line-height: 18px; + color: #999; + text-shadow: 0 1px 0 rgba(255,255,255,0.5); + text-transform: uppercase; +} +.nav li + .nav-header { + margin-top: 9px; +} +.nav-list { + padding-left: 15px; + padding-right: 15px; + margin-bottom: 0; +} +.nav-list > li > a, +.nav-list .nav-header { + margin-left: -15px; + margin-right: -15px; + text-shadow: 0 1px 0 rgba(255,255,255,0.5); +} +.nav-list > li > a { + padding: 3px 15px; +} +.nav-list > .active > a, +.nav-list > .active > a:hover, +.nav-list > .active > a:focus { + color: #fff; + text-shadow: 0 -1px 0 rgba(0,0,0,0.2); + background-color: #3071a9; +} +.nav-list [class^="icon-"], +.nav-list [class*=" icon-"] { + margin-right: 2px; +} +.nav-list .divider { + *width: 100%; + height: 1px; + margin: 8px 1px; + *margin: -5px 0 5px; + overflow: hidden; + background-color: #e5e5e5; + border-bottom: 1px solid #fff; +} +.nav-tabs, +.nav-pills { + *zoom: 1; +} +.nav-tabs:before, +.nav-tabs:after, +.nav-pills:before, +.nav-pills:after { + display: table; + content: ""; + line-height: 0; +} +.nav-tabs:after, +.nav-pills:after { + clear: both; +} +.nav-tabs > li, +.nav-pills > li { + float: left; +} +.nav-tabs > li > a, +.nav-pills > li > a { + padding-right: 12px; + padding-left: 12px; + margin-right: 2px; + line-height: 14px; +} +.nav-tabs { + border-bottom: 1px solid #ddd; +} +.nav-tabs > li { + margin-bottom: -1px; +} +.nav-tabs > li > a { + padding-top: 8px; + padding-bottom: 8px; + line-height: 18px; + border: 1px solid transparent; + -webkit-border-radius: 4px 4px 0 0; + -moz-border-radius: 4px 4px 0 0; + border-radius: 4px 4px 0 0; +} +.nav-tabs > li > a:hover, +.nav-tabs > li > a:focus { + border-color: #eee #eee #ddd; +} +.nav-tabs > .active > a, +.nav-tabs > .active > a:hover, +.nav-tabs > .active > a:focus { + color: #555; + background-color: #fff; + border: 1px solid #ddd; + border-bottom-color: transparent; + cursor: default; +} +.nav-pills > li > a { + padding-top: 8px; + padding-bottom: 8px; + margin-top: 2px; + margin-bottom: 2px; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; +} +.nav-pills > .active > a, +.nav-pills > .active > a:hover, +.nav-pills > .active > a:focus { + color: #fff; + background-color: #3071a9; +} +.nav-stacked > li { + float: none; +} +.nav-stacked > li > a { + margin-right: 0; +} +.nav-tabs.nav-stacked { + border-bottom: 0; +} +.nav-tabs.nav-stacked > li > a { + border: 1px solid #ddd; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.nav-tabs.nav-stacked > li:first-child > a { + -webkit-border-top-right-radius: 4px; + -moz-border-radius-topright: 4px; + border-top-right-radius: 4px; + -webkit-border-top-left-radius: 4px; + -moz-border-radius-topleft: 4px; + border-top-left-radius: 4px; +} +.nav-tabs.nav-stacked > li:last-child > a { + -webkit-border-bottom-right-radius: 4px; + -moz-border-radius-bottomright: 4px; + border-bottom-right-radius: 4px; + -webkit-border-bottom-left-radius: 4px; + -moz-border-radius-bottomleft: 4px; + border-bottom-left-radius: 4px; +} +.nav-tabs.nav-stacked > li > a:hover, +.nav-tabs.nav-stacked > li > a:focus { + border-color: #ddd; + z-index: 2; +} +.nav-pills.nav-stacked > li > a { + margin-bottom: 3px; +} +.nav-pills.nav-stacked > li:last-child > a { + margin-bottom: 1px; +} +.nav-tabs .dropdown-menu { + -webkit-border-radius: 0 0 6px 6px; + -moz-border-radius: 0 0 6px 6px; + border-radius: 0 0 6px 6px; +} +.nav-pills .dropdown-menu { + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} +.nav .dropdown-toggle .caret { + border-top-color: #3071a9; + border-bottom-color: #3071a9; + margin-top: 6px; +} +.nav .dropdown-toggle:hover .caret, +.nav .dropdown-toggle:focus .caret { + border-top-color: #1f496e; + border-bottom-color: #1f496e; +} +.nav-tabs .dropdown-toggle .caret { + margin-top: 8px; +} +.nav .active .dropdown-toggle .caret { + border-top-color: #fff; + border-bottom-color: #fff; +} +.nav-tabs .active .dropdown-toggle .caret { + border-top-color: #555; + border-bottom-color: #555; +} +.nav > .dropdown.active > a:hover, +.nav > .dropdown.active > a:focus { + cursor: pointer; +} +.nav-tabs .open .dropdown-toggle, +.nav-pills .open .dropdown-toggle, +.nav > li.dropdown.open.active > a:hover, +.nav > li.dropdown.open.active > a:focus { + color: #fff; + background-color: #999; + border-color: #999; +} +.nav li.dropdown.open .caret, +.nav li.dropdown.open.active .caret, +.nav li.dropdown.open a:hover .caret, +.nav li.dropdown.open a:focus .caret { + border-top-color: #fff; + border-bottom-color: #fff; + opacity: 1; + filter: alpha(opacity=100); +} +.tabs-stacked .open > a:hover, +.tabs-stacked .open > a:focus { + border-color: #999; +} +.tabbable { + *zoom: 1; +} +.tabbable:before, +.tabbable:after { + display: table; + content: ""; + line-height: 0; +} +.tabbable:after { + clear: both; +} +.tab-content { + overflow: auto; +} +.tabs-below > .nav-tabs, +.tabs-right > .nav-tabs, +.tabs-left > .nav-tabs { + border-bottom: 0; +} +.tab-content > .tab-pane, +.pill-content > .pill-pane { + display: none; +} +.tab-content > .active, +.pill-content > .active { + display: block; +} +.tabs-below > .nav-tabs { + border-top: 1px solid #ddd; +} +.tabs-below > .nav-tabs > li { + margin-top: -1px; + margin-bottom: 0; +} +.tabs-below > .nav-tabs > li > a { + -webkit-border-radius: 0 0 4px 4px; + -moz-border-radius: 0 0 4px 4px; + border-radius: 0 0 4px 4px; +} +.tabs-below > .nav-tabs > li > a:hover, +.tabs-below > .nav-tabs > li > a:focus { + border-bottom-color: transparent; + border-top-color: #ddd; +} +.tabs-below > .nav-tabs > .active > a, +.tabs-below > .nav-tabs > .active > a:hover, +.tabs-below > .nav-tabs > .active > a:focus { + border-color: transparent #ddd #ddd #ddd; +} +.tabs-left > .nav-tabs > li, +.tabs-right > .nav-tabs > li { + float: none; +} +.tabs-left > .nav-tabs > li > a, +.tabs-right > .nav-tabs > li > a { + min-width: 74px; + margin-right: 0; + margin-bottom: 3px; +} +.tabs-left > .nav-tabs { + float: left; + margin-right: 19px; + border-right: 1px solid #ddd; +} +.tabs-left > .nav-tabs > li > a { + margin-right: -1px; + -webkit-border-radius: 4px 0 0 4px; + -moz-border-radius: 4px 0 0 4px; + border-radius: 4px 0 0 4px; +} +.tabs-left > .nav-tabs > li > a:hover, +.tabs-left > .nav-tabs > li > a:focus { + border-color: #eee #ddd #eee #eee; +} +.tabs-left > .nav-tabs .active > a, +.tabs-left > .nav-tabs .active > a:hover, +.tabs-left > .nav-tabs .active > a:focus { + border-color: #ddd transparent #ddd #ddd; + *border-right-color: #fff; +} +.tabs-right > .nav-tabs { + float: right; + margin-left: 19px; + border-left: 1px solid #ddd; +} +.tabs-right > .nav-tabs > li > a { + margin-left: -1px; + -webkit-border-radius: 0 4px 4px 0; + -moz-border-radius: 0 4px 4px 0; + border-radius: 0 4px 4px 0; +} +.tabs-right > .nav-tabs > li > a:hover, +.tabs-right > .nav-tabs > li > a:focus { + border-color: #eee #eee #eee #ddd; +} +.tabs-right > .nav-tabs .active > a, +.tabs-right > .nav-tabs .active > a:hover, +.tabs-right > .nav-tabs .active > a:focus { + border-color: #ddd #ddd #ddd transparent; + *border-left-color: #fff; +} +.nav > .disabled > a { + color: #999; +} +.nav > .disabled > a:hover, +.nav > .disabled > a:focus { + text-decoration: none; + background-color: transparent; + cursor: default; +} +.navbar { + overflow: visible; + margin-bottom: 18px; + *position: relative; + *z-index: 2; +} +.navbar-inner { + min-height: 40px; + padding-left: 20px; + padding-right: 20px; + background-color: #fafafa; + background-image: -moz-linear-gradient(top,#ffffff,#f2f2f2); + background-image: -webkit-gradient(linear,0 0,0 100%,from(#ffffff),to(#f2f2f2)); + background-image: -webkit-linear-gradient(top,#ffffff,#f2f2f2); + background-image: -o-linear-gradient(top,#ffffff,#f2f2f2); + background-image: linear-gradient(to bottom,#ffffff,#f2f2f2); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff2f2f2', GradientType=0); + border: 1px solid #d4d4d4; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + -webkit-box-shadow: 0 1px 4px rgba(0,0,0,0.065); + -moz-box-shadow: 0 1px 4px rgba(0,0,0,0.065); + box-shadow: 0 1px 4px rgba(0,0,0,0.065); + *zoom: 1; +} +.navbar-inner:before, +.navbar-inner:after { + display: table; + content: ""; + line-height: 0; +} +.navbar-inner:after { + clear: both; +} +.navbar .container { + width: auto; +} +.nav-collapse.collapse { + height: auto; + overflow: visible; +} +.navbar .brand { + float: left; + display: block; + padding: 11px 20px 11px; + margin-left: -20px; + font-size: 20px; + font-weight: 200; + color: #555; + text-shadow: 0 1px 0 #ffffff; +} +.navbar .brand:hover, +.navbar .brand:focus { + text-decoration: none; +} +.navbar-text { + margin-bottom: 0; + line-height: 40px; + color: #555; +} +.navbar-link { + color: #555; +} +.navbar-link:hover, +.navbar-link:focus { + color: #333; +} +.navbar .divider-vertical { + height: 40px; + margin: 0 9px; + border-left: 1px solid #f2f2f2; + border-right: 1px solid #ffffff; +} +.navbar .btn, +.navbar .btn-group { + margin-top: 5px; +} +.navbar .btn-group .btn, +.navbar .input-prepend .btn, +.navbar .input-append .btn, +.navbar .input-prepend .btn-group, +.navbar .input-append .btn-group { + margin-top: 0; +} +.navbar-form { + margin-bottom: 0; + *zoom: 1; +} +.navbar-form:before, +.navbar-form:after { + display: table; + content: ""; + line-height: 0; +} +.navbar-form:after { + clear: both; +} +.navbar-form input, +.navbar-form select, +.navbar-form .radio, +.navbar-form .checkbox { + margin-top: 5px; +} +.navbar-form input, +.navbar-form select, +.navbar-form .btn { + display: inline-block; + margin-bottom: 0; +} +.navbar-form input[type="image"], +.navbar-form input[type="checkbox"], +.navbar-form input[type="radio"] { + margin-top: 3px; +} +.navbar-form .input-append, +.navbar-form .input-prepend { + margin-top: 5px; + white-space: nowrap; +} +.navbar-form .input-append input, +.navbar-form .input-prepend input { + margin-top: 0; +} +.navbar-search { + position: relative; + float: left; + margin-top: 5px; + margin-bottom: 0; +} +.navbar-search .search-query { + margin-bottom: 0; + padding: 4px 14px; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 13px; + font-weight: normal; + line-height: 1; + -webkit-border-radius: 15px; + -moz-border-radius: 15px; + border-radius: 15px; +} +.navbar-static-top { + position: static; + margin-bottom: 0; +} +.navbar-static-top .navbar-inner { + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.navbar-fixed-top, +.navbar-fixed-bottom { + position: fixed; + right: 0; + left: 0; + z-index: 1030; + margin-bottom: 0; +} +.navbar-fixed-top .navbar-inner, +.navbar-static-top .navbar-inner { + border-width: 0 0 1px; +} +.navbar-fixed-bottom .navbar-inner { + border-width: 1px 0 0; +} +.navbar-fixed-top .navbar-inner, +.navbar-fixed-bottom .navbar-inner { + padding-left: 0; + padding-right: 0; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.navbar-static-top .container, +.navbar-fixed-top .container, +.navbar-fixed-bottom .container { + width: 940px; +} +.navbar-fixed-top { + top: 0; +} +.navbar-fixed-top .navbar-inner, +.navbar-static-top .navbar-inner { + -webkit-box-shadow: 0 1px 10px rgba(0,0,0,.1); + -moz-box-shadow: 0 1px 10px rgba(0,0,0,.1); + box-shadow: 0 1px 10px rgba(0,0,0,.1); +} +.navbar-fixed-bottom { + bottom: 0; +} +.navbar-fixed-bottom .navbar-inner { + -webkit-box-shadow: 0 -1px 10px rgba(0,0,0,.1); + -moz-box-shadow: 0 -1px 10px rgba(0,0,0,.1); + box-shadow: 0 -1px 10px rgba(0,0,0,.1); +} +.navbar .nav { + position: relative; + left: 0; + display: block; + float: left; + margin: 0 10px 0 0; +} +.navbar .nav.pull-right { + float: right; + margin-right: 0; +} +.navbar .nav > li { + float: left; +} +.navbar .nav > li > a { + float: none; + padding: 11px 15px 11px; + color: #555; + text-decoration: none; + text-shadow: 0 1px 0 #ffffff; +} +.navbar .nav .dropdown-toggle .caret { + margin-top: 8px; +} +.navbar .nav > li > a:focus, +.navbar .nav > li > a:hover { + background-color: transparent; + color: #333; + text-decoration: none; +} +.navbar .nav > li > a:focus { + outline: 2px solid #5e9ed6; +} +.navbar .nav > .active > a, +.navbar .nav > .active > a:hover, +.navbar .nav > .active > a:focus { + color: #555; + text-decoration: none; + background-color: #e6e6e6; + -webkit-box-shadow: inset 0 3px 8px rgba(0,0,0,0.125); + -moz-box-shadow: inset 0 3px 8px rgba(0,0,0,0.125); + box-shadow: inset 0 3px 8px rgba(0,0,0,0.125); +} +.navbar .btn-navbar { + display: none; + float: right; + padding: 7px 10px; + margin-left: 5px; + margin-right: 5px; + background-color: #f2f2f2; + *background-color: #f2f2f2; + -webkit-box-shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.075); + -moz-box-shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.075); + box-shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.075); +} +.navbar .btn-navbar:hover, +.navbar .btn-navbar:focus, +.navbar .btn-navbar:active, +.navbar .btn-navbar.active, +.navbar .btn-navbar.disabled, +.navbar .btn-navbar[disabled] { + color: #fff; + background-color: #d9d9d9; + *background-color: #d9d9d9; +} +.navbar .btn-navbar:active, +.navbar .btn-navbar.active { + background-color: #f2f2f2; +} +.navbar .btn-navbar .icon-bar { + display: block; + width: 18px; + height: 2px; + background-color: #f5f5f5; + -webkit-border-radius: 1px; + -moz-border-radius: 1px; + border-radius: 1px; + -webkit-box-shadow: 0 1px 0 rgba(0,0,0,0.25); + -moz-box-shadow: 0 1px 0 rgba(0,0,0,0.25); + box-shadow: 0 1px 0 rgba(0,0,0,0.25); +} +.btn-navbar .icon-bar + .icon-bar { + margin-top: 3px; +} +.navbar .nav > li > .dropdown-menu:before { + content: ''; + display: inline-block; + border-left: 7px solid transparent; + border-right: 7px solid transparent; + border-bottom: 7px solid #ccc; + border-bottom-color: rgba(0,0,0,0.2); + position: absolute; + top: -7px; + left: 9px; +} +.navbar .nav > li > .dropdown-menu:after { + content: ''; + display: inline-block; + border-left: 6px solid transparent; + border-right: 6px solid transparent; + border-bottom: 6px solid #fff; + position: absolute; + top: -6px; + left: 10px; +} +.navbar-fixed-bottom .nav > li > .dropdown-menu:before { + border-top: 7px solid #ccc; + border-top-color: rgba(0,0,0,0.2); + border-bottom: 0; + bottom: -7px; + top: auto; +} +.navbar-fixed-bottom .nav > li > .dropdown-menu:after { + border-top: 6px solid #fff; + border-bottom: 0; + bottom: -6px; + top: auto; +} +.navbar .nav li.dropdown > a:hover .caret, +.navbar .nav li.dropdown > a:focus .caret { + border-top-color: #333; + border-bottom-color: #333; +} +.navbar .nav li.dropdown.open > .dropdown-toggle, +.navbar .nav li.dropdown.active > .dropdown-toggle, +.navbar .nav li.dropdown.open.active > .dropdown-toggle { + background-color: #e6e6e6; + color: #555; +} +.navbar .nav li.dropdown > .dropdown-toggle .caret { + border-top-color: #555; + border-bottom-color: #555; +} +.navbar .nav li.dropdown.open > .dropdown-toggle .caret, +.navbar .nav li.dropdown.active > .dropdown-toggle .caret, +.navbar .nav li.dropdown.open.active > .dropdown-toggle .caret { + border-top-color: #555; + border-bottom-color: #555; +} +.navbar .pull-right > li > .dropdown-menu, +.navbar .nav > li > .dropdown-menu.pull-right { + left: auto; + right: 0; +} +.navbar .pull-right > li > .dropdown-menu:before, +.navbar .nav > li > .dropdown-menu.pull-right:before { + left: auto; + right: 12px; +} +.navbar .pull-right > li > .dropdown-menu:after, +.navbar .nav > li > .dropdown-menu.pull-right:after { + left: auto; + right: 13px; +} +.navbar .pull-right > li > .dropdown-menu .dropdown-menu, +.navbar .nav > li > .dropdown-menu.pull-right .dropdown-menu { + left: auto; + right: 100%; + margin-left: 0; + margin-right: -1px; + -webkit-border-radius: 6px 0 6px 6px; + -moz-border-radius: 6px 0 6px 6px; + border-radius: 6px 0 6px 6px; +} +.navbar-inverse .navbar-inner { + background-color: #13294a; + background-image: -moz-linear-gradient(top,#152d53,#10223e); + background-image: -webkit-gradient(linear,0 0,0 100%,from(#152d53),to(#10223e)); + background-image: -webkit-linear-gradient(top,#152d53,#10223e); + background-image: -o-linear-gradient(top,#152d53,#10223e); + background-image: linear-gradient(to bottom,#152d53,#10223e); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff142c52', endColorstr='#ff0f213e', GradientType=0); + border-color: #0b172a; +} +.navbar-inverse .brand, +.navbar-inverse .nav > li > a { + color: #d9d9d9; + text-shadow: 0 -1px 0 rgba(0,0,0,0.25); +} +.navbar-inverse .brand:hover, +.navbar-inverse .brand:focus, +.navbar-inverse .nav > li > a:hover, +.navbar-inverse .nav > li > a:focus { + color: #fff; +} +.navbar-inverse .brand { + color: #d9d9d9; +} +.navbar-inverse .navbar-text { + color: #d9d9d9; +} +.navbar-inverse .nav > li > a:focus, +.navbar-inverse .nav > li > a:hover { + background-color: transparent; + color: #fff; +} +.navbar-inverse .nav .active > a, +.navbar-inverse .nav .active > a:hover, +.navbar-inverse .nav .active > a:focus { + color: #fff; + background-color: #10223e; +} +.navbar-inverse .navbar-link { + color: #d9d9d9; +} +.navbar-inverse .navbar-link:hover, +.navbar-inverse .navbar-link:focus { + color: #fff; +} +.navbar-inverse .divider-vertical { + border-left-color: #10223e; + border-right-color: #152d53; +} +.navbar-inverse .nav li.dropdown.open > .dropdown-toggle, +.navbar-inverse .nav li.dropdown.active > .dropdown-toggle, +.navbar-inverse .nav li.dropdown.open.active > .dropdown-toggle { + background-color: #10223e; + color: #fff; +} +.navbar-inverse .nav li.dropdown > a:hover .caret, +.navbar-inverse .nav li.dropdown > a:focus .caret { + border-top-color: #fff; + border-bottom-color: #fff; +} +.navbar-inverse .nav li.dropdown > .dropdown-toggle .caret { + border-top-color: #d9d9d9; + border-bottom-color: #d9d9d9; +} +.navbar-inverse .nav li.dropdown.open > .dropdown-toggle .caret, +.navbar-inverse .nav li.dropdown.active > .dropdown-toggle .caret, +.navbar-inverse .nav li.dropdown.open.active > .dropdown-toggle .caret { + border-top-color: #fff; + border-bottom-color: #fff; +} +.navbar-inverse .navbar-search .search-query { + color: #fff; + background-color: #2959a4; + border-color: #10223e; + -webkit-box-shadow: inset 0 1px 2px rgba(0,0,0,.1), 0 1px 0 rgba(255,255,255,.15); + -moz-box-shadow: inset 0 1px 2px rgba(0,0,0,.1), 0 1px 0 rgba(255,255,255,.15); + box-shadow: inset 0 1px 2px rgba(0,0,0,.1), 0 1px 0 rgba(255,255,255,.15); + -webkit-transition: none; + -moz-transition: none; + -o-transition: none; + transition: none; +} +.navbar-inverse .navbar-search .search-query:-moz-placeholder { + color: #ccc; +} +.navbar-inverse .navbar-search .search-query:-ms-input-placeholder { + color: #ccc; +} +.navbar-inverse .navbar-search .search-query::-webkit-input-placeholder { + color: #ccc; +} +.navbar-inverse .navbar-search .search-query:focus, +.navbar-inverse .navbar-search .search-query.focused { + padding: 5px 15px; + color: #333; + text-shadow: 0 1px 0 #fff; + background-color: #fff; + border: 0; + -webkit-box-shadow: 0 0 3px rgba(0,0,0,0.15); + -moz-box-shadow: 0 0 3px rgba(0,0,0,0.15); + box-shadow: 0 0 3px rgba(0,0,0,0.15); + outline: 0; +} +.navbar-inverse .btn-navbar { + background-color: #10223e; + *background-color: #10223e; +} +.navbar-inverse .btn-navbar:hover, +.navbar-inverse .btn-navbar:focus, +.navbar-inverse .btn-navbar:active, +.navbar-inverse .btn-navbar.active, +.navbar-inverse .btn-navbar.disabled, +.navbar-inverse .btn-navbar[disabled] { + color: #fff; + background-color: #050c16; + *background-color: #050c16; +} +.navbar-inverse .btn-navbar:active, +.navbar-inverse .btn-navbar.active { + background-color: #10223e; +} +.breadcrumb { + padding: 8px 15px; + margin: 0 0 18px; + list-style: none; + background-color: #f5f5f5; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} +.breadcrumb > li { + display: inline-block; + *display: inline; + *zoom: 1; + text-shadow: 0 1px 0 #fff; +} +.breadcrumb > li > .divider { + padding: 0 5px; + color: #ccc; +} +.breadcrumb > .active { + color: #999; +} +.pagination { + margin: 18px 0; +} +.pagination ul { + display: inline-block; + *display: inline; + *zoom: 1; + margin-left: 0; + margin-bottom: 0; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + -webkit-box-shadow: 0 1px 2px rgba(0,0,0,0.05); + -moz-box-shadow: 0 1px 2px rgba(0,0,0,0.05); + box-shadow: 0 1px 2px rgba(0,0,0,0.05); +} +.pagination ul > li { + display: inline; +} +.pagination ul > li > a, +.pagination ul > li > span { + float: left; + padding: 4px 12px; + line-height: 18px; + text-decoration: none; + background-color: #fff; + border: 1px solid #ddd; + border-left-width: 0; +} +.pagination ul > li > a:hover, +.pagination ul > li > a:focus, +.pagination ul > .active > a, +.pagination ul > .active > span { + background-color: #F0F0F0; +} +.pagination ul > .active > a, +.pagination ul > .active > span { + color: #999; + cursor: default; +} +.pagination ul > .disabled > span, +.pagination ul > .disabled > a, +.pagination ul > .disabled > a:hover, +.pagination ul > .disabled > a:focus { + color: #999; + background-color: transparent; + cursor: default; +} +.pagination ul > li:first-child > a, +.pagination ul > li:first-child > span { + border-left-width: 1px; + -webkit-border-top-left-radius: 3px; + -moz-border-radius-topleft: 3px; + border-top-left-radius: 3px; + -webkit-border-bottom-left-radius: 3px; + -moz-border-radius-bottomleft: 3px; + border-bottom-left-radius: 3px; +} +.pagination ul > li:last-child > a, +.pagination ul > li:last-child > span { + -webkit-border-top-right-radius: 3px; + -moz-border-radius-topright: 3px; + border-top-right-radius: 3px; + -webkit-border-bottom-right-radius: 3px; + -moz-border-radius-bottomright: 3px; + border-bottom-right-radius: 3px; +} +.pagination-centered { + text-align: center; +} +.pagination-right { + text-align: right; +} +.pagination-large ul > li > a, +.pagination-large ul > li > span { + padding: 11px 19px; + font-size: 16.25px; +} +.pagination-large ul > li:first-child > a, +.pagination-large ul > li:first-child > span { + -webkit-border-top-left-radius: 6px; + -moz-border-radius-topleft: 6px; + border-top-left-radius: 6px; + -webkit-border-bottom-left-radius: 6px; + -moz-border-radius-bottomleft: 6px; + border-bottom-left-radius: 6px; +} +.pagination-large ul > li:last-child > a, +.pagination-large ul > li:last-child > span { + -webkit-border-top-right-radius: 6px; + -moz-border-radius-topright: 6px; + border-top-right-radius: 6px; + -webkit-border-bottom-right-radius: 6px; + -moz-border-radius-bottomright: 6px; + border-bottom-right-radius: 6px; +} +.pagination-mini ul > li:first-child > a, +.pagination-mini ul > li:first-child > span, +.pagination-small ul > li:first-child > a, +.pagination-small ul > li:first-child > span { + -webkit-border-top-left-radius: 3px; + -moz-border-radius-topleft: 3px; + border-top-left-radius: 3px; + -webkit-border-bottom-left-radius: 3px; + -moz-border-radius-bottomleft: 3px; + border-bottom-left-radius: 3px; +} +.pagination-mini ul > li:last-child > a, +.pagination-mini ul > li:last-child > span, +.pagination-small ul > li:last-child > a, +.pagination-small ul > li:last-child > span { + -webkit-border-top-right-radius: 3px; + -moz-border-radius-topright: 3px; + border-top-right-radius: 3px; + -webkit-border-bottom-right-radius: 3px; + -moz-border-radius-bottomright: 3px; + border-bottom-right-radius: 3px; +} +.pagination-small ul > li > a, +.pagination-small ul > li > span { + padding: 2px 10px; + font-size: 12px; +} +.pagination-mini ul > li > a, +.pagination-mini ul > li > span { + padding: 0 6px; + font-size: 9.75px; +} +.pager { + margin: 18px 0; + list-style: none; + text-align: center; + *zoom: 1; +} +.pager:before, +.pager:after { + display: table; + content: ""; + line-height: 0; +} +.pager:after { + clear: both; +} +.pager li { + display: inline; +} +.pager li > a, +.pager li > span { + display: inline-block; + padding: 5px 14px; + background-color: #fff; + border: 1px solid #ddd; + -webkit-border-radius: 15px; + -moz-border-radius: 15px; + border-radius: 15px; +} +.pager li > a:hover, +.pager li > a:focus { + text-decoration: none; + background-color: #f5f5f5; +} +.pager .next > a, +.pager .next > span { + float: right; +} +.pager .previous > a, +.pager .previous > span { + float: left; +} +.pager .disabled > a, +.pager .disabled > a:hover, +.pager .disabled > a:focus, +.pager .disabled > span { + color: #999; + background-color: #fff; + cursor: default; +} +.modal-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1040; + background-color: #000; +} +.modal-backdrop.fade { + opacity: 0; +} +.modal-backdrop, +.modal-backdrop.fade.in { + opacity: 0.8; + filter: alpha(opacity=80); +} +.modal-header { + padding: 9px 15px; + border-bottom: 1px solid #eee; +} +.modal-header .close { + margin-top: 2px; +} +.modal-header h3 { + margin: 0; + line-height: 30px; +} +.modal-body { + width: 98%; + position: relative; + max-height: 400px; + padding: 1%; +} +.modal-body iframe { + width: 100%; + max-height: none; + border: 0 !important; +} +.modal-form { + margin-bottom: 0; +} +.modal-footer { + padding: 14px 15px 15px; + margin-bottom: 0; + text-align: right; + background-color: #f5f5f5; + border-top: 1px solid #ddd; + -webkit-border-radius: 0 0 6px 6px; + -moz-border-radius: 0 0 6px 6px; + border-radius: 0 0 6px 6px; + -webkit-box-shadow: inset 0 1px 0 #fff; + -moz-box-shadow: inset 0 1px 0 #fff; + box-shadow: inset 0 1px 0 #fff; + *zoom: 1; +} +.modal-footer:before, +.modal-footer:after { + display: table; + content: ""; + line-height: 0; +} +.modal-footer:after { + clear: both; +} +.modal-footer .btn + .btn { + margin-left: 5px; + margin-bottom: 0; +} +.modal-footer .btn-group .btn + .btn { + margin-left: -1px; +} +.modal-footer .btn-block + .btn-block { + margin-left: 0; +} +.tooltip { + position: absolute; + z-index: 1030; + display: block; + visibility: visible; + font-size: 11px; + line-height: 1.4; + opacity: 0; + filter: alpha(opacity=0); +} +.tooltip.in { + opacity: 0.8; + filter: alpha(opacity=80); +} +.tooltip.top { + margin-top: -3px; + padding: 5px 0; +} +.tooltip.right { + margin-left: 3px; + padding: 0 5px; +} +.tooltip.bottom { + margin-top: 3px; + padding: 5px 0; +} +.tooltip.left { + margin-left: -3px; + padding: 0 5px; +} +.tooltip-inner { + max-width: 200px; + padding: 8px; + color: #fff; + text-align: center; + text-decoration: none; + background-color: #000; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} +.tooltip-arrow { + position: absolute; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; +} +.tooltip.top .tooltip-arrow { + bottom: 0; + left: 50%; + margin-left: -5px; + border-width: 5px 5px 0; + border-top-color: #000; +} +.tooltip.right .tooltip-arrow { + top: 50%; + left: 0; + margin-top: -5px; + border-width: 5px 5px 5px 0; + border-right-color: #000; +} +.tooltip.left .tooltip-arrow { + top: 50%; + right: 0; + margin-top: -5px; + border-width: 5px 0 5px 5px; + border-left-color: #000; +} +.tooltip.bottom .tooltip-arrow { + top: 0; + left: 50%; + margin-left: -5px; + border-width: 0 5px 5px; + border-bottom-color: #000; +} +.popover { + position: absolute; + top: 0; + left: 0; + z-index: 1060; + display: none; + max-width: 276px; + padding: 1px; + text-align: left; + background-color: #fff; + -webkit-background-clip: padding-box; + -moz-background-clip: padding; + background-clip: padding-box; + border: 1px solid #ccc; + border: 1px solid rgba(0,0,0,0.2); + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; + -webkit-box-shadow: 0 5px 10px rgba(0,0,0,0.2); + -moz-box-shadow: 0 5px 10px rgba(0,0,0,0.2); + box-shadow: 0 5px 10px rgba(0,0,0,0.2); + white-space: normal; +} +.popover.top { + margin-top: -10px; +} +.popover.right { + margin-left: 10px; +} +.popover.bottom { + margin-top: 10px; +} +.popover.left { + margin-left: -10px; +} +.popover-title { + margin: 0; + padding: 8px 14px; + font-size: 14px; + font-weight: normal; + line-height: 18px; + background-color: #f7f7f7; + border-bottom: 1px solid #ebebeb; + -webkit-border-radius: 5px 5px 0 0; + -moz-border-radius: 5px 5px 0 0; + border-radius: 5px 5px 0 0; +} +.popover-title:empty { + display: none; +} +.popover-content { + padding: 9px 14px; +} +.popover .arrow, +.popover .arrow:after { + position: absolute; + display: block; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; +} +.popover .arrow { + border-width: 11px; +} +.popover .arrow:after { + border-width: 10px; + content: ""; +} +.popover.top .arrow { + left: 50%; + margin-left: -11px; + border-bottom-width: 0; + border-top-color: #999; + border-top-color: rgba(0,0,0,0.25); + bottom: -11px; +} +.popover.top .arrow:after { + bottom: 1px; + margin-left: -10px; + border-bottom-width: 0; + border-top-color: #fff; +} +.popover.right .arrow { + top: 50%; + left: -11px; + margin-top: -11px; + border-left-width: 0; + border-right-color: #999; + border-right-color: rgba(0,0,0,0.25); +} +.popover.right .arrow:after { + left: 1px; + bottom: -10px; + border-left-width: 0; + border-right-color: #fff; +} +.popover.bottom .arrow { + left: 50%; + margin-left: -11px; + border-top-width: 0; + border-bottom-color: #999; + border-bottom-color: rgba(0,0,0,0.25); + top: -11px; +} +.popover.bottom .arrow:after { + top: 1px; + margin-left: -10px; + border-top-width: 0; + border-bottom-color: #fff; +} +.popover.left .arrow { + top: 50%; + right: -11px; + margin-top: -11px; + border-right-width: 0; + border-left-color: #999; + border-left-color: rgba(0,0,0,0.25); +} +.popover.left .arrow:after { + right: 1px; + border-right-width: 0; + border-left-color: #fff; + bottom: -10px; +} +.thumbnails { + margin-left: -20px; + list-style: none; + *zoom: 1; +} +.thumbnails:before, +.thumbnails:after { + display: table; + content: ""; + line-height: 0; +} +.thumbnails:after { + clear: both; +} +.row-fluid .thumbnails { + margin-left: 0; +} +.thumbnails > li { + float: left; + margin-bottom: 18px; + margin-left: 20px; +} +.thumbnail { + display: block; + padding: 4px; + line-height: 18px; + border: 1px solid #ddd; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + -webkit-box-shadow: 0 1px 3px rgba(0,0,0,0.055); + -moz-box-shadow: 0 1px 3px rgba(0,0,0,0.055); + box-shadow: 0 1px 3px rgba(0,0,0,0.055); + -webkit-transition: all .2s ease-in-out; + -moz-transition: all .2s ease-in-out; + -o-transition: all .2s ease-in-out; + transition: all .2s ease-in-out; +} +a.thumbnail:hover, +a.thumbnail:focus { + border-color: #3071a9; + -webkit-box-shadow: 0 1px 4px rgba(0,105,214,0.25); + -moz-box-shadow: 0 1px 4px rgba(0,105,214,0.25); + box-shadow: 0 1px 4px rgba(0,105,214,0.25); +} +.thumbnail > img { + display: block; + max-width: 100%; + margin-left: auto; + margin-right: auto; +} +.thumbnail .caption { + padding: 9px; + color: #555; +} +.media, +.media-body { + overflow: hidden; + *overflow: visible; + zoom: 1; +} +.media, +.media .media { + margin-top: 15px; +} +.media:first-child { + margin-top: 0; +} +.media-object { + display: block; +} +.media-heading { + margin: 0 0 5px; +} +.media > .pull-left { + margin-right: 10px; +} +.media > .pull-right { + margin-left: 10px; +} +.media-list { + margin-left: 0; + list-style: none; +} +.label, +.badge { + display: inline-block; + padding: 2px 4px; + font-size: 10.998px; + font-weight: bold; + line-height: 14px; + color: #fff; + vertical-align: baseline; + white-space: nowrap; + text-shadow: 0 -1px 0 rgba(0,0,0,0.25); + background-color: #999; +} +.label { + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} +.badge { + padding-left: 9px; + padding-right: 9px; + -webkit-border-radius: 9px; + -moz-border-radius: 9px; + border-radius: 9px; +} +.label:empty, +.badge:empty { + display: none; +} +a.label:hover, +a.label:focus, +a.badge:hover, +a.badge:focus { + color: #fff; + text-decoration: none; + cursor: pointer; +} +.label-important, +.badge-important { + background-color: #a94442; +} +.label-important[href], +.badge-important[href] { + background-color: #843534; +} +.label-warning, +.badge-warning { + background-color: #f89406; +} +.label-warning[href], +.badge-warning[href] { + background-color: #c67605; +} +.label-success, +.badge-success { + background-color: #3c763d; +} +.label-success[href], +.badge-success[href] { + background-color: #2b542c; +} +.label-info, +.badge-info { + background-color: #31708f; +} +.label-info[href], +.badge-info[href] { + background-color: #245269; +} +.label-inverse, +.badge-inverse { + background-color: #333; +} +.label-inverse[href], +.badge-inverse[href] { + background-color: #1a1a1a; +} +.btn .label, +.btn .badge { + position: relative; + top: -1px; +} +.btn-mini .label, +.btn-mini .badge { + top: 0; +} +@-webkit-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +@-moz-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +@-ms-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +@-o-keyframes progress-bar-stripes { + from { + background-position: 0 0; + } + to { + background-position: 40px 0; + } +} +@keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +.progress { + overflow: hidden; + height: 18px; + margin-bottom: 18px; + background-color: #f7f7f7; + background-image: -moz-linear-gradient(top,#f5f5f5,#f9f9f9); + background-image: -webkit-gradient(linear,0 0,0 100%,from(#f5f5f5),to(#f9f9f9)); + background-image: -webkit-linear-gradient(top,#f5f5f5,#f9f9f9); + background-image: -o-linear-gradient(top,#f5f5f5,#f9f9f9); + background-image: linear-gradient(to bottom,#f5f5f5,#f9f9f9); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#fff9f9f9', GradientType=0); + -webkit-box-shadow: inset 0 1px 2px rgba(0,0,0,0.1); + -moz-box-shadow: inset 0 1px 2px rgba(0,0,0,0.1); + box-shadow: inset 0 1px 2px rgba(0,0,0,0.1); + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} +.progress .bar { + width: 0%; + height: 100%; + color: #fff; + float: left; + font-size: 12px; + text-align: center; + text-shadow: 0 -1px 0 rgba(0,0,0,0.25); + background-color: #0e90d2; + background-image: -moz-linear-gradient(top,#149bdf,#0480be); + background-image: -webkit-gradient(linear,0 0,0 100%,from(#149bdf),to(#0480be)); + background-image: -webkit-linear-gradient(top,#149bdf,#0480be); + background-image: -o-linear-gradient(top,#149bdf,#0480be); + background-image: linear-gradient(to bottom,#149bdf,#0480be); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff149bdf', endColorstr='#ff0480be', GradientType=0); + -webkit-box-shadow: inset 0 -1px 0 rgba(0,0,0,0.15); + -moz-box-shadow: inset 0 -1px 0 rgba(0,0,0,0.15); + box-shadow: inset 0 -1px 0 rgba(0,0,0,0.15); + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + -webkit-transition: width .6s ease; + -moz-transition: width .6s ease; + -o-transition: width .6s ease; + transition: width .6s ease; +} +.progress .bar + .bar { + -webkit-box-shadow: inset 1px 0 0 rgba(0,0,0,.15), inset 0 -1px 0 rgba(0,0,0,.15); + -moz-box-shadow: inset 1px 0 0 rgba(0,0,0,.15), inset 0 -1px 0 rgba(0,0,0,.15); + box-shadow: inset 1px 0 0 rgba(0,0,0,.15), inset 0 -1px 0 rgba(0,0,0,.15); +} +.progress-striped .bar { + background-color: #149bdf; + background-image: -webkit-gradient(linear,0 100%,100% 0,color-stop(.25,rgba(255,255,255,0.15)),color-stop(.25,transparent),color-stop(.5,transparent),color-stop(.5,rgba(255,255,255,0.15)),color-stop(.75,rgba(255,255,255,0.15)),color-stop(.75,transparent),to(transparent)); + background-image: -webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); + background-image: -moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); + background-image: -o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); + background-image: linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); + -webkit-background-size: 40px 40px; + -moz-background-size: 40px 40px; + -o-background-size: 40px 40px; + background-size: 40px 40px; +} +.progress.active .bar { + -webkit-animation: progress-bar-stripes 2s linear infinite; + -moz-animation: progress-bar-stripes 2s linear infinite; + -ms-animation: progress-bar-stripes 2s linear infinite; + -o-animation: progress-bar-stripes 2s linear infinite; + animation: progress-bar-stripes 2s linear infinite; +} +.progress-danger .bar, +.progress .bar-danger { + background-color: #dd514c; + background-image: -moz-linear-gradient(top,#ee5f5b,#c43c35); + background-image: -webkit-gradient(linear,0 0,0 100%,from(#ee5f5b),to(#c43c35)); + background-image: -webkit-linear-gradient(top,#ee5f5b,#c43c35); + background-image: -o-linear-gradient(top,#ee5f5b,#c43c35); + background-image: linear-gradient(to bottom,#ee5f5b,#c43c35); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b', endColorstr='#ffc43c35', GradientType=0); +} +.progress-danger.progress-striped .bar, +.progress-striped .bar-danger { + background-color: #ee5f5b; + background-image: -webkit-gradient(linear,0 100%,100% 0,color-stop(.25,rgba(255,255,255,0.15)),color-stop(.25,transparent),color-stop(.5,transparent),color-stop(.5,rgba(255,255,255,0.15)),color-stop(.75,rgba(255,255,255,0.15)),color-stop(.75,transparent),to(transparent)); + background-image: -webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); + background-image: -moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); + background-image: -o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); + background-image: linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); +} +.progress-success .bar, +.progress .bar-success { + background-color: #5eb95e; + background-image: -moz-linear-gradient(top,#62c462,#57a957); + background-image: -webkit-gradient(linear,0 0,0 100%,from(#62c462),to(#57a957)); + background-image: -webkit-linear-gradient(top,#62c462,#57a957); + background-image: -o-linear-gradient(top,#62c462,#57a957); + background-image: linear-gradient(to bottom,#62c462,#57a957); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462', endColorstr='#ff57a957', GradientType=0); +} +.progress-success.progress-striped .bar, +.progress-striped .bar-success { + background-color: #62c462; + background-image: -webkit-gradient(linear,0 100%,100% 0,color-stop(.25,rgba(255,255,255,0.15)),color-stop(.25,transparent),color-stop(.5,transparent),color-stop(.5,rgba(255,255,255,0.15)),color-stop(.75,rgba(255,255,255,0.15)),color-stop(.75,transparent),to(transparent)); + background-image: -webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); + background-image: -moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); + background-image: -o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); + background-image: linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); +} +.progress-info .bar, +.progress .bar-info { + background-color: #4bb1cf; + background-image: -moz-linear-gradient(top,#5bc0de,#339bb9); + background-image: -webkit-gradient(linear,0 0,0 100%,from(#5bc0de),to(#339bb9)); + background-image: -webkit-linear-gradient(top,#5bc0de,#339bb9); + background-image: -o-linear-gradient(top,#5bc0de,#339bb9); + background-image: linear-gradient(to bottom,#5bc0de,#339bb9); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff339bb9', GradientType=0); +} +.progress-info.progress-striped .bar, +.progress-striped .bar-info { + background-color: #5bc0de; + background-image: -webkit-gradient(linear,0 100%,100% 0,color-stop(.25,rgba(255,255,255,0.15)),color-stop(.25,transparent),color-stop(.5,transparent),color-stop(.5,rgba(255,255,255,0.15)),color-stop(.75,rgba(255,255,255,0.15)),color-stop(.75,transparent),to(transparent)); + background-image: -webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); + background-image: -moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); + background-image: -o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); + background-image: linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); +} +.progress-warning .bar, +.progress .bar-warning { + background-color: #faa732; + background-image: -moz-linear-gradient(top,#fbb450,#f89406); + background-image: -webkit-gradient(linear,0 0,0 100%,from(#fbb450),to(#f89406)); + background-image: -webkit-linear-gradient(top,#fbb450,#f89406); + background-image: -o-linear-gradient(top,#fbb450,#f89406); + background-image: linear-gradient(to bottom,#fbb450,#f89406); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffab44f', endColorstr='#fff89406', GradientType=0); +} +.progress-warning.progress-striped .bar, +.progress-striped .bar-warning { + background-color: #fbb450; + background-image: -webkit-gradient(linear,0 100%,100% 0,color-stop(.25,rgba(255,255,255,0.15)),color-stop(.25,transparent),color-stop(.5,transparent),color-stop(.5,rgba(255,255,255,0.15)),color-stop(.75,rgba(255,255,255,0.15)),color-stop(.75,transparent),to(transparent)); + background-image: -webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); + background-image: -moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); + background-image: -o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); + background-image: linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); +} +.accordion { + margin-bottom: 18px; +} +.accordion-group { + margin-bottom: 2px; + border: 1px solid #e5e5e5; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} +.accordion-heading { + border-bottom: 0; +} +.accordion-heading .accordion-toggle { + display: block; + padding: 8px 15px; +} +.accordion-toggle { + cursor: pointer; +} +.accordion-inner { + padding: 9px 15px; + border-top: 1px solid #e5e5e5; +} +.carousel { + position: relative; + margin-bottom: 18px; + line-height: 1; +} +.carousel-inner { + overflow: hidden; + width: 100%; + position: relative; +} +.carousel-inner > .item { + display: none; + position: relative; + -webkit-transition: .6s ease-in-out left; + -moz-transition: .6s ease-in-out left; + -o-transition: .6s ease-in-out left; + transition: .6s ease-in-out left; +} +.carousel-inner > .item > img, +.carousel-inner > .item > a > img { + display: block; + line-height: 1; +} +.carousel-inner > .active, +.carousel-inner > .next, +.carousel-inner > .prev { + display: block; +} +.carousel-inner > .active { + left: 0; +} +.carousel-inner > .next, +.carousel-inner > .prev { + position: absolute; + top: 0; + width: 100%; +} +.carousel-inner > .next { + left: 100%; +} +.carousel-inner > .prev { + left: -100%; +} +.carousel-inner > .next.left, +.carousel-inner > .prev.right { + left: 0; +} +.carousel-inner > .active.left { + left: -100%; +} +.carousel-inner > .active.right { + left: 100%; +} +.carousel-control { + position: absolute; + top: 40%; + left: 15px; + width: 40px; + height: 40px; + margin-top: -20px; + font-size: 60px; + font-weight: 100; + line-height: 30px; + color: #fff; + text-align: center; + background: #222; + border: 3px solid #fff; + -webkit-border-radius: 23px; + -moz-border-radius: 23px; + border-radius: 23px; + opacity: 0.5; + filter: alpha(opacity=50); +} +.carousel-control.right { + left: auto; + right: 15px; +} +.carousel-control:hover, +.carousel-control:focus { + color: #fff; + text-decoration: none; + opacity: 0.9; + filter: alpha(opacity=90); +} +.carousel-indicators { + position: absolute; + top: 15px; + right: 15px; + z-index: 5; + margin: 0; + list-style: none; +} +.carousel-indicators li { + display: block; + float: left; + width: 10px; + height: 10px; + margin-left: 5px; + text-indent: -999px; + background-color: #ccc; + background-color: rgba(255,255,255,0.25); + border-radius: 5px; +} +.carousel-indicators .active { + background-color: #fff; +} +.carousel-caption { + position: absolute; + left: 0; + right: 0; + bottom: 0; + padding: 15px; + background: #333; + background: rgba(0,0,0,0.75); +} +.carousel-caption h4, +.carousel-caption p { + color: #fff; + line-height: 18px; +} +.carousel-caption h4 { + margin: 0 0 5px; +} +.carousel-caption p { + margin-bottom: 0; +} +.hero-unit { + padding: 60px; + margin-bottom: 30px; + font-size: 18px; + font-weight: 200; + line-height: 27px; + color: inherit; + background-color: #eee; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} +.hero-unit h1 { + margin-bottom: 0; + font-size: 60px; + line-height: 1; + color: inherit; + letter-spacing: -1px; +} +.hero-unit li { + line-height: 27px; +} +.pull-right { + float: right; +} +.pull-left { + float: left; +} +.hide { + display: none; +} +.show { + display: block; +} +.invisible { + visibility: hidden; +} +.affix { + position: fixed; +} +@-ms-viewport { + width: device-width; +} +.hidden { + display: none; + visibility: hidden; +} +.visible-phone { + display: none !important; +} +.visible-tablet { + display: none !important; +} +.hidden-desktop { + display: none !important; +} +.visible-desktop { + display: inherit !important; +} +@media (min-width: 768px) and (max-width: 979px) { + .hidden-desktop { + display: inherit !important; + } + .visible-desktop { + display: none !important; + } + .visible-tablet { + display: inherit !important; + } + .hidden-tablet { + display: none !important; + } +} +@media (max-width: 767px) { + .hidden-desktop { + display: inherit !important; + } + .visible-desktop { + display: none !important; + } + .visible-phone { + display: inherit !important; + } + .hidden-phone { + display: none !important; + } +} +.visible-print { + display: none !important; +} +@media print { + .visible-print { + display: inherit !important; + } + .hidden-print { + display: none !important; + } +} +@media (max-width: 767px) { + body { + padding-left: 20px; + padding-right: 20px; + } + .navbar-fixed-top, + .navbar-fixed-bottom, + .navbar-static-top { + margin-left: -20px; + margin-right: -20px; + } + .container-fluid { + padding: 0; + } + .dl-horizontal dt { + float: none; + clear: none; + width: auto; + text-align: left; + } + .dl-horizontal dd { + margin-left: 0; + } + .dropdown-menu .menuitem-group { + background-color: #10223e; + color: #eee; + } + .container { + width: auto; + } + .row-fluid { + width: 100%; + } + .row, + .thumbnails { + margin-left: 0; + } + .thumbnails > li { + float: none; + margin-left: 0; + } + [class*="span"], + .uneditable-input[class*="span"], + .row-fluid [class*="span"] { + float: none; + display: block; + width: 100%; + margin-left: 0; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + } + .span12, + .row-fluid .span12 { + width: 100%; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + } + .row-fluid [class*="offset"]:first-child { + margin-left: 0; + } + .input-large, + .input-xlarge, + .input-xxlarge, + input[class*="span"], + select[class*="span"], + textarea[class*="span"], + .uneditable-input { + display: block; + width: 100%; + min-height: 28px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + } + .input-prepend input, + .input-append input, + .input-prepend input[class*="span"], + .input-append input[class*="span"] { + display: inline-block; + } + .controls-row [class*="span"] + [class*="span"] { + margin-left: 0; + } +} +@media (max-width: 480px) { + .nav-collapse { + -webkit-transform: translate3d(0,0,0); + } + .page-header h1 small { + display: block; + line-height: 18px; + } + input[type="checkbox"], + input[type="radio"] { + border: 1px solid #ccc; + } + .form-horizontal .control-label { + float: none; + width: auto; + padding-top: 0; + text-align: left; + } + .form-horizontal .controls { + margin-left: 0; + } + .form-horizontal .control-list { + padding-top: 0; + } + .form-horizontal .form-actions { + padding-left: 10px; + padding-right: 10px; + } + .tag-category input#filter-search, + .newsfeed-category input#filter-search { + width: auto; + margin-bottom: 9px; + } + .category-list input#filter-search { + width: auto; + } + .media .pull-left, + .media .pull-right { + float: none; + display: block; + margin-bottom: 10px; + } + .media-object { + margin-right: 0; + margin-left: 0; + } + .modal-header .close { + padding: 10px; + margin: -10px; + } + .carousel-caption { + position: static; + } +} +@media (min-width: 768px) and (max-width: 979px) { + .row { + margin-left: -20px; + *zoom: 1; + } + .row:before, + .row:after { + display: table; + content: ""; + line-height: 0; + } + .row:after { + clear: both; + } + [class*="span"] { + float: left; + min-height: 1px; + margin-left: 20px; + } + .container, + .navbar-static-top .container, + .navbar-fixed-top .container, + .navbar-fixed-bottom .container { + width: 724px; + } + .span12 { + width: 724px; + } + .span11 { + width: 662px; + } + .span10 { + width: 600px; + } + .span9 { + width: 538px; + } + .span8 { + width: 476px; + } + .span7 { + width: 414px; + } + .span6 { + width: 352px; + } + .span5 { + width: 290px; + } + .span4 { + width: 228px; + } + .span3 { + width: 166px; + } + .span2 { + width: 104px; + } + .span1 { + width: 42px; + } + .offset12 { + margin-left: 764px; + } + .offset11 { + margin-left: 702px; + } + .offset10 { + margin-left: 640px; + } + .offset9 { + margin-left: 578px; + } + .offset8 { + margin-left: 516px; + } + .offset7 { + margin-left: 454px; + } + .offset6 { + margin-left: 392px; + } + .offset5 { + margin-left: 330px; + } + .offset4 { + margin-left: 268px; + } + .offset3 { + margin-left: 206px; + } + .offset2 { + margin-left: 144px; + } + .offset1 { + margin-left: 82px; + } + .row-fluid { + width: 100%; + *zoom: 1; + } + .row-fluid:before, + .row-fluid:after { + display: table; + content: ""; + line-height: 0; + } + .row-fluid:after { + clear: both; + } + .row-fluid [class*="span"] { + display: block; + width: 100%; + min-height: 28px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + float: left; + margin-left: 2.76243094%; + *margin-left: 2.70923945%; + } + .row-fluid [class*="span"]:first-child { + margin-left: 0; + } + .row-fluid .controls-row [class*="span"] + [class*="span"] { + margin-left: 2.76243094%; + } + .row-fluid .span12 { + width: 100%; + *width: 99.94680851%; + } + .row-fluid .span11 { + width: 91.43646409%; + *width: 91.3832726%; + } + .row-fluid .span10 { + width: 82.87292818%; + *width: 82.81973669%; + } + .row-fluid .span9 { + width: 74.30939227%; + *width: 74.25620078%; + } + .row-fluid .span8 { + width: 65.74585635%; + *width: 65.69266486%; + } + .row-fluid .span7 { + width: 57.18232044%; + *width: 57.12912895%; + } + .row-fluid .span6 { + width: 48.61878453%; + *width: 48.56559304%; + } + .row-fluid .span5 { + width: 40.05524862%; + *width: 40.00205713%; + } + .row-fluid .span4 { + width: 31.49171271%; + *width: 31.43852122%; + } + .row-fluid .span3 { + width: 22.9281768%; + *width: 22.87498531%; + } + .row-fluid .span2 { + width: 14.36464088%; + *width: 14.31144939%; + } + .row-fluid .span1 { + width: 5.80110497%; + *width: 5.74791348%; + } + .row-fluid .offset12 { + margin-left: 105.52486188%; + *margin-left: 105.4184789%; + } + .row-fluid .offset12:first-child { + margin-left: 102.76243094%; + *margin-left: 102.65604796%; + } + .row-fluid .offset11 { + margin-left: 96.96132597%; + *margin-left: 96.85494299%; + } + .row-fluid .offset11:first-child { + margin-left: 94.19889503%; + *margin-left: 94.09251205%; + } + .row-fluid .offset10 { + margin-left: 88.39779006%; + *margin-left: 88.29140708%; + } + .row-fluid .offset10:first-child { + margin-left: 85.63535912%; + *margin-left: 85.52897614%; + } + .row-fluid .offset9 { + margin-left: 79.83425414%; + *margin-left: 79.72787116%; + } + .row-fluid .offset9:first-child { + margin-left: 77.0718232%; + *margin-left: 76.96544023%; + } + .row-fluid .offset8 { + margin-left: 71.27071823%; + *margin-left: 71.16433525%; + } + .row-fluid .offset8:first-child { + margin-left: 68.50828729%; + *margin-left: 68.40190431%; + } + .row-fluid .offset7 { + margin-left: 62.70718232%; + *margin-left: 62.60079934%; + } + .row-fluid .offset7:first-child { + margin-left: 59.94475138%; + *margin-left: 59.8383684%; + } + .row-fluid .offset6 { + margin-left: 54.14364641%; + *margin-left: 54.03726343%; + } + .row-fluid .offset6:first-child { + margin-left: 51.38121547%; + *margin-left: 51.27483249%; + } + .row-fluid .offset5 { + margin-left: 45.5801105%; + *margin-left: 45.47372752%; + } + .row-fluid .offset5:first-child { + margin-left: 42.81767956%; + *margin-left: 42.71129658%; + } + .row-fluid .offset4 { + margin-left: 37.01657459%; + *margin-left: 36.91019161%; + } + .row-fluid .offset4:first-child { + margin-left: 34.25414365%; + *margin-left: 34.14776067%; + } + .row-fluid .offset3 { + margin-left: 28.45303867%; + *margin-left: 28.3466557%; + } + .row-fluid .offset3:first-child { + margin-left: 25.69060773%; + *margin-left: 25.58422476%; + } + .row-fluid .offset2 { + margin-left: 19.88950276%; + *margin-left: 19.78311978%; + } + .row-fluid .offset2:first-child { + margin-left: 17.12707182%; + *margin-left: 17.02068884%; + } + .row-fluid .offset1 { + margin-left: 11.32596685%; + *margin-left: 11.21958387%; + } + .row-fluid .offset1:first-child { + margin-left: 8.56353591%; + *margin-left: 8.45715293%; + } + input, + textarea, + .uneditable-input { + margin-left: 0; + } + .controls-row [class*="span"] + [class*="span"] { + margin-left: 20px; + } + input.span12, + textarea.span12, + .uneditable-input.span12 { + width: 710px; + } + input.span11, + textarea.span11, + .uneditable-input.span11 { + width: 648px; + } + input.span10, + textarea.span10, + .uneditable-input.span10 { + width: 586px; + } + input.span9, + textarea.span9, + .uneditable-input.span9 { + width: 524px; + } + input.span8, + textarea.span8, + .uneditable-input.span8 { + width: 462px; + } + input.span7, + textarea.span7, + .uneditable-input.span7 { + width: 400px; + } + input.span6, + textarea.span6, + .uneditable-input.span6 { + width: 338px; + } + input.span5, + textarea.span5, + .uneditable-input.span5 { + width: 276px; + } + input.span4, + textarea.span4, + .uneditable-input.span4 { + width: 214px; + } + input.span3, + textarea.span3, + .uneditable-input.span3 { + width: 152px; + } + input.span2, + textarea.span2, + .uneditable-input.span2 { + width: 90px; + } + input.span1, + textarea.span1, + .uneditable-input.span1 { + width: 28px; + } +} +@media (min-width: 1200px) { + .row { + margin-left: -30px; + *zoom: 1; + } + .row:before, + .row:after { + display: table; + content: ""; + line-height: 0; + } + .row:after { + clear: both; + } + [class*="span"] { + float: left; + min-height: 1px; + margin-left: 30px; + } + .container, + .navbar-static-top .container, + .navbar-fixed-top .container, + .navbar-fixed-bottom .container { + width: 1170px; + } + .span12 { + width: 1170px; + } + .span11 { + width: 1070px; + } + .span10 { + width: 970px; + } + .span9 { + width: 870px; + } + .span8 { + width: 770px; + } + .span7 { + width: 670px; + } + .span6 { + width: 570px; + } + .span5 { + width: 470px; + } + .span4 { + width: 370px; + } + .span3 { + width: 270px; + } + .span2 { + width: 170px; + } + .span1 { + width: 70px; + } + .offset12 { + margin-left: 1230px; + } + .offset11 { + margin-left: 1130px; + } + .offset10 { + margin-left: 1030px; + } + .offset9 { + margin-left: 930px; + } + .offset8 { + margin-left: 830px; + } + .offset7 { + margin-left: 730px; + } + .offset6 { + margin-left: 630px; + } + .offset5 { + margin-left: 530px; + } + .offset4 { + margin-left: 430px; + } + .offset3 { + margin-left: 330px; + } + .offset2 { + margin-left: 230px; + } + .offset1 { + margin-left: 130px; + } + .row-fluid { + width: 100%; + *zoom: 1; + } + .row-fluid:before, + .row-fluid:after { + display: table; + content: ""; + line-height: 0; + } + .row-fluid:after { + clear: both; + } + .row-fluid [class*="span"] { + display: block; + width: 100%; + min-height: 28px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + float: left; + margin-left: 2.76243094%; + *margin-left: 2.70923945%; + } + .row-fluid [class*="span"]:first-child { + margin-left: 0; + } + .row-fluid .controls-row [class*="span"] + [class*="span"] { + margin-left: 2.76243094%; + } + .row-fluid .span12 { + width: 100%; + *width: 99.94680851%; + } + .row-fluid .span11 { + width: 91.43646409%; + *width: 91.3832726%; + } + .row-fluid .span10 { + width: 82.87292818%; + *width: 82.81973669%; + } + .row-fluid .span9 { + width: 74.30939227%; + *width: 74.25620078%; + } + .row-fluid .span8 { + width: 65.74585635%; + *width: 65.69266486%; + } + .row-fluid .span7 { + width: 57.18232044%; + *width: 57.12912895%; + } + .row-fluid .span6 { + width: 48.61878453%; + *width: 48.56559304%; + } + .row-fluid .span5 { + width: 40.05524862%; + *width: 40.00205713%; + } + .row-fluid .span4 { + width: 31.49171271%; + *width: 31.43852122%; + } + .row-fluid .span3 { + width: 22.9281768%; + *width: 22.87498531%; + } + .row-fluid .span2 { + width: 14.36464088%; + *width: 14.31144939%; + } + .row-fluid .span1 { + width: 5.80110497%; + *width: 5.74791348%; + } + .row-fluid .offset12 { + margin-left: 105.52486188%; + *margin-left: 105.4184789%; + } + .row-fluid .offset12:first-child { + margin-left: 102.76243094%; + *margin-left: 102.65604796%; + } + .row-fluid .offset11 { + margin-left: 96.96132597%; + *margin-left: 96.85494299%; + } + .row-fluid .offset11:first-child { + margin-left: 94.19889503%; + *margin-left: 94.09251205%; + } + .row-fluid .offset10 { + margin-left: 88.39779006%; + *margin-left: 88.29140708%; + } + .row-fluid .offset10:first-child { + margin-left: 85.63535912%; + *margin-left: 85.52897614%; + } + .row-fluid .offset9 { + margin-left: 79.83425414%; + *margin-left: 79.72787116%; + } + .row-fluid .offset9:first-child { + margin-left: 77.0718232%; + *margin-left: 76.96544023%; + } + .row-fluid .offset8 { + margin-left: 71.27071823%; + *margin-left: 71.16433525%; + } + .row-fluid .offset8:first-child { + margin-left: 68.50828729%; + *margin-left: 68.40190431%; + } + .row-fluid .offset7 { + margin-left: 62.70718232%; + *margin-left: 62.60079934%; + } + .row-fluid .offset7:first-child { + margin-left: 59.94475138%; + *margin-left: 59.8383684%; + } + .row-fluid .offset6 { + margin-left: 54.14364641%; + *margin-left: 54.03726343%; + } + .row-fluid .offset6:first-child { + margin-left: 51.38121547%; + *margin-left: 51.27483249%; + } + .row-fluid .offset5 { + margin-left: 45.5801105%; + *margin-left: 45.47372752%; + } + .row-fluid .offset5:first-child { + margin-left: 42.81767956%; + *margin-left: 42.71129658%; + } + .row-fluid .offset4 { + margin-left: 37.01657459%; + *margin-left: 36.91019161%; + } + .row-fluid .offset4:first-child { + margin-left: 34.25414365%; + *margin-left: 34.14776067%; + } + .row-fluid .offset3 { + margin-left: 28.45303867%; + *margin-left: 28.3466557%; + } + .row-fluid .offset3:first-child { + margin-left: 25.69060773%; + *margin-left: 25.58422476%; + } + .row-fluid .offset2 { + margin-left: 19.88950276%; + *margin-left: 19.78311978%; + } + .row-fluid .offset2:first-child { + margin-left: 17.12707182%; + *margin-left: 17.02068884%; + } + .row-fluid .offset1 { + margin-left: 11.32596685%; + *margin-left: 11.21958387%; + } + .row-fluid .offset1:first-child { + margin-left: 8.56353591%; + *margin-left: 8.45715293%; + } + input, + textarea, + .uneditable-input { + margin-left: 0; + } + .controls-row [class*="span"] + [class*="span"] { + margin-left: 30px; + } + input.span12, + textarea.span12, + .uneditable-input.span12 { + width: 1156px; + } + input.span11, + textarea.span11, + .uneditable-input.span11 { + width: 1056px; + } + input.span10, + textarea.span10, + .uneditable-input.span10 { + width: 956px; + } + input.span9, + textarea.span9, + .uneditable-input.span9 { + width: 856px; + } + input.span8, + textarea.span8, + .uneditable-input.span8 { + width: 756px; + } + input.span7, + textarea.span7, + .uneditable-input.span7 { + width: 656px; + } + input.span6, + textarea.span6, + .uneditable-input.span6 { + width: 556px; + } + input.span5, + textarea.span5, + .uneditable-input.span5 { + width: 456px; + } + input.span4, + textarea.span4, + .uneditable-input.span4 { + width: 356px; + } + input.span3, + textarea.span3, + .uneditable-input.span3 { + width: 256px; + } + input.span2, + textarea.span2, + .uneditable-input.span2 { + width: 156px; + } + input.span1, + textarea.span1, + .uneditable-input.span1 { + width: 56px; + } + .thumbnails { + margin-left: -30px; + } + .thumbnails > li { + margin-left: 30px; + } + .row-fluid .thumbnails { + margin-left: 0; + } +} +@media (max-width: 767px) { + body { + padding-top: 0; + } + .navbar-fixed-top, + .navbar-fixed-bottom { + position: static; + } + .navbar-fixed-top { + margin-bottom: 18px; + } + .navbar-fixed-bottom { + margin-top: 18px; + } + .navbar-fixed-top .navbar-inner, + .navbar-fixed-bottom .navbar-inner { + padding: 5px; + } + .navbar .container { + width: auto; + padding: 0; + } + .navbar .brand { + padding-left: 10px; + padding-right: 10px; + margin: 0 0 0 -5px; + } + .nav-collapse { + clear: both; + } + .nav-collapse .nav { + float: none; + margin: 0 0 9px; + } + .nav-collapse .nav > li { + float: none; + } + .nav-collapse .nav > li > a { + margin-bottom: 2px; + } + .nav-collapse .nav > .divider-vertical { + display: none; + } + .nav-collapse .nav .nav-header { + color: #555; + text-shadow: none; + } + .nav-collapse .nav > li > a, + .nav-collapse .dropdown-menu a { + padding: 9px 15px; + font-weight: bold; + color: #555; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + } + .nav-collapse .btn { + padding: 4px 10px 4px; + font-weight: normal; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + } + .nav-collapse .dropdown-menu li + li a { + margin-bottom: 2px; + } + .nav-collapse .nav > li > a:hover, + .nav-collapse .nav > li > a:focus, + .nav-collapse .dropdown-menu a:hover, + .nav-collapse .dropdown-menu a:focus { + background-color: #f2f2f2; + } + .navbar-inverse .nav-collapse .nav > li > a, + .navbar-inverse .nav-collapse .dropdown-menu a { + color: #d9d9d9; + } + .navbar-inverse .nav-collapse .nav > li > a:hover, + .navbar-inverse .nav-collapse .nav > li > a:focus, + .navbar-inverse .nav-collapse .dropdown-menu a:hover, + .navbar-inverse .nav-collapse .dropdown-menu a:focus { + background-color: #10223e; + } + .nav-collapse.in .btn-group { + margin-top: 5px; + padding: 0; + } + .nav-collapse .dropdown-menu { + position: static; + top: auto; + left: auto; + float: none; + display: none; + max-width: none; + margin: 0 15px; + padding: 0; + background-color: transparent; + border: none; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; + } + .nav-collapse .open > .dropdown-menu { + display: block; + } + .nav-collapse .dropdown-menu:before, + .nav-collapse .dropdown-menu:after { + display: none; + } + .nav-collapse .dropdown-menu .divider { + display: none; + } + .nav-collapse .nav > li > .dropdown-menu:before, + .nav-collapse .nav > li > .dropdown-menu:after { + display: none; + } + .nav-collapse .navbar-form, + .nav-collapse .navbar-search { + float: none; + padding: 9px 15px; + margin: 9px 0; + border-top: 1px solid #f2f2f2; + border-bottom: 1px solid #f2f2f2; + -webkit-box-shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1); + -moz-box-shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1); + box-shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1); + } + .navbar-inverse .nav-collapse .navbar-form, + .navbar-inverse .nav-collapse .navbar-search { + border-top-color: #10223e; + border-bottom-color: #10223e; + } + .navbar .nav-collapse .nav.pull-right { + float: none; + margin-left: 0; + } + .nav-collapse, + .nav-collapse.collapse { + overflow: hidden; + height: 0; + } + .navbar .btn-navbar { + display: block; + } + .navbar-static .navbar-inner { + padding-left: 10px; + padding-right: 10px; + } +} +@media (min-width: 768px) { + .nav-collapse.collapse { + height: auto !important; + overflow: visible !important; + } +} +.small { + font-size: 11px; +} +iframe, +svg { + max-width: 100%; +} +.nowrap { + white-space: nowrap; +} +.center, +.table td.center, +.table th.center { + text-align: center; +} +a.disabled, +a.disabled:hover { + color: #999999; + background-color: transparent; + cursor: default; + text-decoration: none; +} +.hero-unit { + text-align: center; +} +.hero-unit .lead { + margin-bottom: 18px; + font-size: 20px; + font-weight: 200; + line-height: 27px; +} +.btn .caret { + margin-bottom: 7px; +} +.btn.btn-micro .caret { + margin: 5px 0; +} +.blog-row-rule, +.blog-item-rule { + border: 0; +} +body.modal { + padding-top: 0; +} +.row-even, +.row-odd { + padding: 5px; + width: 99%; + border-bottom: 1px solid #ddd; +} +.row-odd { + background-color: transparent; +} +.row-even { + background-color: #f9f9f9; +} +.blog-row-rule, +.blog-item-rule { + border: 0; +} +.row-fluid .row-reveal { + visibility: hidden; +} +.row-fluid:hover .row-reveal { + visibility: visible; +} +.btn-wide { + width: 80%; +} +.nav-list > li.offset > a { + padding-left: 30px; + font-size: 12px; +} +.blog-row-rule, +.blog-item-rule { + border: 0; +} +.row-fluid .offset1 { + margin-left: 8.382978723%; +} +.row-fluid .offset2 { + margin-left: 16.89361702%; +} +.row-fluid .offset3 { + margin-left: 25.404255317%; +} +.row-fluid .offset4 { + margin-left: 33.914893614%; +} +.row-fluid .offset5 { + margin-left: 42.425531911%; +} +.row-fluid .offset6 { + margin-left: 50.93617020799999%; +} +.row-fluid .offset7 { + margin-left: 59.446808505%; +} +.row-fluid .offset8 { + margin-left: 67.95744680199999%; +} +.row-fluid .offset9 { + margin-left: 76.468085099%; +} +.row-fluid .offset10 { + margin-left: 84.97872339599999%; +} +.row-fluid .offset11 { + margin-left: 91.489361693%; +} +.navbar .nav > li > a.btn { + padding: 4px 10px; + line-height: 18px; +} +.nav-tabs.nav-dark { + border-bottom: 1px solid #333; + text-shadow: 1px 1px 1px #000; +} +.nav-tabs.nav-dark > li > a { + color: #F8F8F8; +} +.nav-tabs.nav-dark > li > a:hover { + border-color: #333 #333 #111; + background-color: #777777; +} +.nav-tabs.nav-dark > .active > a, +.nav-tabs.nav-dark > .active > a:hover { + color: #ffffff; + background-color: #555555; + border: 1px solid #222; + border-bottom-color: transparent; +} +.thumbnail.pull-left { + margin: 0 10px 10px 0; +} +.thumbnail.pull-right { + margin: 0 0 10px 10px; +} +.width-10 { + width: 10px; +} +.width-20 { + width: 20px; +} +.width-30 { + width: 30px; +} +.width-40 { + width: 40px; +} +.width-50 { + width: 50px; +} +.width-60 { + width: 60px; +} +.width-70 { + width: 70px; +} +.width-80 { + width: 80px; +} +.width-90 { + width: 90px; +} +.width-100 { + width: 100px; +} +.height-10 { + height: 10px; +} +.height-20 { + height: 20px; +} +.height-30 { + height: 30px; +} +.height-40 { + height: 40px; +} +.height-50 { + height: 50px; +} +.height-60 { + height: 60px; +} +.height-70 { + height: 70px; +} +.height-80 { + height: 80px; +} +.height-90 { + height: 90px; +} +.height-100 { + height: 100px; +} +hr.hr-condensed { + margin: 10px 0; +} +.list-striped, +.row-striped { + list-style: none; + line-height: 18px; + text-align: left; + vertical-align: middle; + border-top: 1px solid #ddd; + margin-left: 0; +} +.list-striped li, +.list-striped dd, +.row-striped .row, +.row-striped .row-fluid { + border-bottom: 1px solid #ddd; + padding: 8px; +} +.list-striped li:nth-child(odd), +.list-striped dd:nth-child(odd), +.row-striped .row:nth-child(odd), +.row-striped .row-fluid:nth-child(odd) { + background-color: #f9f9f9; +} +.list-striped li:hover, +.list-striped dd:hover, +.row-striped .row:hover, +.row-striped .row-fluid:hover { + background-color: #F0F0F0; +} +.row-striped .row-fluid { + width: 100%; + box-sizing: border-box; +} +.row-striped .row-fluid [class*="span"] { + min-height: 10px; +} +.row-striped .row-fluid [class*="span"] { + margin-left: 8px; +} +.row-striped .row-fluid [class*="span"]:first-child { + margin-left: 0; +} +.list-condensed li { + padding: 4px 5px; +} +.row-condensed .row, +.row-condensed .row-fluid { + padding: 4px 5px; +} +.list-bordered, +.row-bordered { + list-style: none; + line-height: 18px; + text-align: left; + vertical-align: middle; + margin-left: 0; + border: 1px solid #ddd; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} +.radio.btn-group input[type=radio] { + display: none; +} +.radio.btn-group > label { + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} +.radio.btn-group > label:first-of-type { + margin-left: 0; + -webkit-border-bottom-left-radius: 4px; + border-bottom-left-radius: 4px; + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-bottomleft: 4px; + -moz-border-radius-topleft: 4px; +} +fieldset.radio.btn-group { + padding-left: 0; +} +.iframe-bordered { + border: 1px solid #ddd; +} +.tab-content { + overflow: visible; +} +.tabs-left .tab-content { + overflow: auto; +} +.nav-tabs > li > span { + display: block; + margin-right: 2px; + padding-right: 12px; + padding-left: 12px; + padding-top: 8px; + padding-bottom: 8px; + line-height: 18px; + border: 1px solid transparent; + -webkit-border-radius: 4px 4px 0 0; + -moz-border-radius: 4px 4px 0 0; + border-radius: 4px 4px 0 0; +} +.btn-micro { + padding: 1px 4px; + font-size: 10px; + line-height: 8px; +} +.btn-group > .btn-micro { + font-size: 10px; +} +.tip-wrap { + max-width: 200px; + padding: 3px 8px; + color: #fff; + text-align: center; + text-decoration: none; + background-color: #000; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + z-index: 100; +} +.page-header { + margin: 2px 0px 10px 0px; + padding-bottom: 5px; +} +.input-prepend > .add-on, +.input-append > .add-on { + vertical-align: top; +} +.input-prepend .chzn-container-single .chzn-single { + -webkit-border-radius: 0 3px 3px 0; + -moz-border-radius: 0 3px 3px 0; + border-radius: 0 3px 3px 0; +} +.input-prepend .chzn-container-single .chzn-single-with-drop { + -webkit-border-radius: 0 3px 0 0; + -moz-border-radius: 0 3px 0 0; + border-radius: 0 3px 0 0; +} +.input-append .chzn-container-single .chzn-single { + -webkit-border-radius: 3px 0 0 3px; + -moz-border-radius: 3px 0 0 3px; + border-radius: 3px 0 0 3px; +} +.input-append .chzn-container-single .chzn-single-with-drop { + -webkit-border-radius: 3px 0 0 0; + -moz-border-radius: 3px 0 0 0; + border-radius: 3px 0 0 0; +} +.input-prepend.input-append .chzn-container-single .chzn-single, +.input-prepend.input-append .chzn-container-single .chzn-single-with-drop { + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.element-invisible { + position: absolute; + padding: 0; + margin: 0; + border: 0; + height: 1px; + width: 1px; + overflow: hidden; +} +.element-invisible:focus { + width: auto; + height: auto; + overflow: auto; + background: #eee; + color: #000; + padding: 1em; +} +.form-vertical .control-label { + float: none; + width: auto; + padding-right: 0; + padding-top: 0; + text-align: left; +} +.form-vertical .controls { + margin-left: 0; +} +.width-auto { + width: auto; +} +.btn-group .chzn-results { + white-space: normal; +} +.accordion-body.in:hover { + overflow: visible; +} +.invalid { + color: #9d261d; + font-weight: bold; +} +input.invalid { + border: 1px solid #9d261d; + background: #f2dede; +} +select.chzn-done.invalid + .chzn-container.chzn-container-single > a.chzn-single, +select.chzn-done.invalid + .chzn-container.chzn-container-multi > ul.chzn-choices { + border-color: #9d261d; + color: #9d261d; +} +.tooltip { + max-width: 400px; +} +.tooltip-inner { + max-width: none; + text-align: left; + text-shadow: none; +} +th .tooltip-inner { + font-weight: normal; +} +.tooltip.hasimage { + opacity: 1; +} +.tip-text { + text-align: left; +} +.btn-group > .btn + .dropdown-backdrop + .btn { + margin-left: -1px; +} +.btn-group > .btn + .dropdown-backdrop + .dropdown-toggle { + padding-left: 8px; + padding-right: 8px; + -webkit-box-shadow: inset 1px 0 0 rgba(255,255,255,.125), inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); + -moz-box-shadow: inset 1px 0 0 rgba(255,255,255,.125), inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); + box-shadow: inset 1px 0 0 rgba(255,255,255,.125), inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); + *padding-top: 5px; + *padding-bottom: 5px; +} +.btn-group > .btn-mini + .dropdown-backdrop + .dropdown-toggle { + padding-left: 5px; + padding-right: 5px; + *padding-top: 2px; + *padding-bottom: 2px; +} +.btn-group > .btn-small + .dropdown-backdrop + .dropdown-toggle { + *padding-top: 5px; + *padding-bottom: 4px; +} +.btn-group > .btn-large + .dropdown-backdrop + .dropdown-toggle { + padding-left: 12px; + padding-right: 12px; + *padding-top: 7px; + *padding-bottom: 7px; +} +.dropdown-menu { + text-align: left; +} +.alert-link { + font-weight: bold; +} +.alert .alert-link { + color: #66512c; +} +.alert-success .alert-link { + color: #2b542c; +} +.alert-danger .alert-link, +.alert-error .alert-link { + color: #843534; +} +.alert-info .alert-link { + color: #245269; +} +div.modal { + position: fixed; + top: 5%; + left: 50%; + z-index: 1050; + width: 80%; + margin-left: -40%; + background-color: #fff; + border: 1px solid #999; + border: 1px solid rgba(0,0,0,0.3); + *border: 1px solid #999; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; + -webkit-box-shadow: 0 3px 7px rgba(0,0,0,0.3); + -moz-box-shadow: 0 3px 7px rgba(0,0,0,0.3); + box-shadow: 0 3px 7px rgba(0,0,0,0.3); + -webkit-background-clip: padding-box; + -moz-background-clip: padding-box; + background-clip: padding-box; + outline: none; +} +div.modal.fade { + -webkit-transition: opacity .3s linear, top .3s ease-out; + -moz-transition: opacity .3s linear, top .3s ease-out; + -o-transition: opacity .3s linear, top .3s ease-out; + transition: opacity .3s linear, top .3s ease-out; + top: -25%; +} +div.modal.fade.in { + top: 5%; +} +.modal-batch { + overflow-y: visible; +} +.modal-body[class^="jviewport-height"], +.modal-body[class*="jviewport-height"] { + max-height: none; +} +.jviewport-height10 { + height: 10vh; +} +.jviewport-height20 { + height: 20vh; +} +.jviewport-height30 { + height: 30vh; +} +.jviewport-height40 { + height: 40vh; +} +.jviewport-height50 { + height: 50vh; +} +.jviewport-height60 { + height: 60vh; +} +.jviewport-height70 { + height: 70vh; +} +.jviewport-height80 { + height: 80vh; +} +.jviewport-height90 { + height: 90vh; +} +.jviewport-height100 { + height: 100vh; +} +div.modal.jviewport-width10 { + width: 10vw; + margin-left: -5vw; +} +div.modal.jviewport-width20 { + width: 20vw; + margin-left: -10vw; +} +div.modal.jviewport-width30 { + width: 30vw; + margin-left: -15vw; +} +div.modal.jviewport-width40 { + width: 40vw; + margin-left: -20vw; +} +div.modal.jviewport-width50 { + width: 50vw; + margin-left: -25vw; +} +div.modal.jviewport-width60 { + width: 60vw; + margin-left: -30vw; +} +div.modal.jviewport-width70 { + width: 70vw; + margin-left: -35vw; +} +div.modal.jviewport-width80 { + width: 80vw; + margin-left: -40vw; +} +div.modal.jviewport-width90 { + width: 90vw; + margin-left: -45vw; +} +div.modal.jviewport-width100 { + width: 100vw; + margin-left: -50vw; +} +@media (max-width: 767px) { + div.modal { + position: fixed; + top: 20px; + left: 20px; + right: 20px; + width: auto; + margin: 0; + } + div.modal.fade { + top: -100px; + } + div.modal.fade.in { + top: 20px; + } + div.modal[class*="jviewport-width"] { + width: auto; + margin: 0; + } +} +@media (max-width: 480px) { + div.modal { + top: 10px; + left: 10px; + right: 10px; + } +} +@font-face { + font-family: 'IcoMoon'; + src: url('../../../../media/jui/fonts/IcoMoon.eot'); + src: url('../../../../media/jui/fonts/IcoMoon.eot?#iefix') format('embedded-opentype'), url('../../../../media/jui/fonts/IcoMoon.woff') format('woff'), url('../../../../media/jui/fonts/IcoMoon.ttf') format('truetype'), url('../../../../media/jui/fonts/IcoMoon.svg#IcoMoon') format('svg'); + font-weight: normal; + font-style: normal; +} +[data-icon]:before { + font-family: 'IcoMoon'; + content: attr(data-icon); + speak: none; +} +[class^="icon-"], +[class*=" icon-"] { + display: inline-block; + width: 14px; + height: 14px; + margin-right: .25em; + line-height: 14px; +} +[class^="icon-"]:before, +[class*=" icon-"]:before { + font-family: 'IcoMoon'; + font-style: normal; + speak: none; +} +[class^="icon-"].disabled, +[class*=" icon-"].disabled { + font-weight: normal; +} +.icon-joomla:before { + content: "\e200"; +} +.icon-chevron-up:before, +.icon-uparrow:before, +.icon-arrow-up:before { + content: "\e005"; +} +.icon-chevron-right:before, +.icon-rightarrow:before, +.icon-arrow-right:before { + content: "\e006"; +} +.icon-chevron-down:before, +.icon-downarrow:before, +.icon-arrow-down:before { + content: "\e007"; +} +.icon-chevron-left:before, +.icon-leftarrow:before, +.icon-arrow-left:before { + content: "\e008"; +} +.icon-arrow-first:before { + content: "\e003"; +} +.icon-arrow-last:before { + content: "\e004"; +} +.icon-arrow-up-2:before { + content: "\e009"; +} +.icon-arrow-right-2:before { + content: "\e00a"; +} +.icon-arrow-down-2:before { + content: "\e00b"; +} +.icon-arrow-left-2:before { + content: "\e00c"; +} +.icon-arrow-up-3:before { + content: "\e00f"; +} +.icon-arrow-right-3:before { + content: "\e010"; +} +.icon-arrow-down-3:before { + content: "\e011"; +} +.icon-arrow-left-3:before { + content: "\e012"; +} +.icon-menu-2:before { + content: "\e00e"; +} +.icon-arrow-up-4:before { + content: "\e201"; +} +.icon-arrow-right-4:before { + content: "\e202"; +} +.icon-arrow-down-4:before { + content: "\e203"; +} +.icon-arrow-left-4:before { + content: "\e204"; +} +.icon-share:before, +.icon-redo:before { + content: "\27"; +} +.icon-undo:before { + content: "\28"; +} +.icon-forward-2:before { + content: "\e205"; +} +.icon-backward-2:before, +.icon-reply:before { + content: "\e206"; +} +.icon-unblock:before, +.icon-refresh:before, +.icon-redo-2:before { + content: "\6c"; +} +.icon-undo-2:before { + content: "\e207"; +} +.icon-move:before { + content: "\7a"; +} +.icon-expand:before { + content: "\66"; +} +.icon-contract:before { + content: "\67"; +} +.icon-expand-2:before { + content: "\68"; +} +.icon-contract-2:before { + content: "\69"; +} +.icon-play:before { + content: "\e208"; +} +.icon-pause:before { + content: "\e209"; +} +.icon-stop:before { + content: "\e210"; +} +.icon-previous:before, +.icon-backward:before { + content: "\7c"; +} +.icon-next:before, +.icon-forward:before { + content: "\7b"; +} +.icon-first:before { + content: "\7d"; +} +.icon-last:before { + content: "\e000"; +} +.icon-play-circle:before { + content: "\e00d"; +} +.icon-pause-circle:before { + content: "\e211"; +} +.icon-stop-circle:before { + content: "\e212"; +} +.icon-backward-circle:before { + content: "\e213"; +} +.icon-forward-circle:before { + content: "\e214"; +} +.icon-loop:before { + content: "\e001"; +} +.icon-shuffle:before { + content: "\e002"; +} +.icon-search:before { + content: "\53"; +} +.icon-zoom-in:before { + content: "\64"; +} +.icon-zoom-out:before { + content: "\65"; +} +.icon-apply:before, +.icon-edit:before, +.icon-pencil:before { + content: "\2b"; +} +.icon-pencil-2:before { + content: "\2c"; +} +.icon-brush:before { + content: "\3b"; +} +.icon-save-new:before, +.icon-plus-2:before { + content: "\5d"; +} +.icon-minus-sign:before, +.icon-minus-2:before { + content: "\5e"; +} +.icon-delete:before, +.icon-remove:before, +.icon-cancel-2:before { + content: "\49"; +} +.icon-publish:before, +.icon-save:before, +.icon-ok:before, +.icon-checkmark:before { + content: "\47"; +} +.icon-new:before, +.icon-plus:before { + content: "\2a"; +} +.icon-plus-circle:before { + content: "\e215"; +} +.icon-minus:before, +.icon-not-ok:before { + content: "\4b"; +} +.icon-ban-circle:before, +.icon-minus-circle:before { + content: "\e216"; +} +.icon-unpublish:before, +.icon-cancel:before { + content: "\4a"; +} +.icon-cancel-circle:before { + content: "\e217"; +} +.icon-checkmark-2:before { + content: "\e218"; +} +.icon-checkmark-circle:before { + content: "\e219"; +} +.icon-info:before { + content: "\e220"; +} +.icon-info-2:before, +.icon-info-circle:before { + content: "\e221"; +} +.icon-question:before, +.icon-question-sign:before, +.icon-help:before { + content: "\45"; +} +.icon-question-2:before, +.icon-question-circle:before { + content: "\e222"; +} +.icon-notification:before { + content: "\e223"; +} +.icon-notification-2:before, +.icon-notification-circle:before { + content: "\e224"; +} +.icon-pending:before, +.icon-warning:before { + content: "\48"; +} +.icon-warning-2:before, +.icon-warning-circle:before { + content: "\e225"; +} +.icon-checkbox-unchecked:before { + content: "\3d"; +} +.icon-checkin:before, +.icon-checkbox:before, +.icon-checkbox-checked:before { + content: "\3e"; +} +.icon-checkbox-partial:before { + content: "\3f"; +} +.icon-square:before { + content: "\e226"; +} +.icon-radio-unchecked:before { + content: "\e227"; +} +.icon-radio-checked:before, +.icon-generic:before { + content: "\e228"; +} +.icon-circle:before { + content: "\e229"; +} +.icon-signup:before { + content: "\e230"; +} +.icon-grid:before, +.icon-grid-view:before { + content: "\58"; +} +.icon-grid-2:before, +.icon-grid-view-2:before { + content: "\59"; +} +.icon-menu:before { + content: "\5a"; +} +.icon-list:before, +.icon-list-view:before { + content: "\31"; +} +.icon-list-2:before { + content: "\e231"; +} +.icon-menu-3:before { + content: "\e232"; +} +.icon-folder-open:before, +.icon-folder:before { + content: "\2d"; +} +.icon-folder-close:before, +.icon-folder-2:before { + content: "\2e"; +} +.icon-folder-plus:before { + content: "\e234"; +} +.icon-folder-minus:before { + content: "\e235"; +} +.icon-folder-3:before { + content: "\e236"; +} +.icon-folder-plus-2:before { + content: "\e237"; +} +.icon-folder-remove:before { + content: "\e238"; +} +.icon-file:before { + content: "\e016"; +} +.icon-file-2:before { + content: "\e239"; +} +.icon-file-add:before, +.icon-file-plus:before { + content: "\29"; +} +.icon-file-minus:before { + content: "\e017"; +} +.icon-file-check:before { + content: "\e240"; +} +.icon-file-remove:before { + content: "\e241"; +} +.icon-save-copy:before, +.icon-copy:before { + content: "\e018"; +} +.icon-stack:before { + content: "\e242"; +} +.icon-tree:before { + content: "\e243"; +} +.icon-tree-2:before { + content: "\e244"; +} +.icon-paragraph-left:before { + content: "\e246"; +} +.icon-paragraph-center:before { + content: "\e247"; +} +.icon-paragraph-right:before { + content: "\e248"; +} +.icon-paragraph-justify:before { + content: "\e249"; +} +.icon-screen:before { + content: "\e01c"; +} +.icon-tablet:before { + content: "\e01d"; +} +.icon-mobile:before { + content: "\e01e"; +} +.icon-box-add:before { + content: "\51"; +} +.icon-box-remove:before { + content: "\52"; +} +.icon-download:before { + content: "\e021"; +} +.icon-upload:before { + content: "\e022"; +} +.icon-home:before { + content: "\21"; +} +.icon-home-2:before { + content: "\e250"; +} +.icon-out-2:before, +.icon-new-tab:before { + content: "\e024"; +} +.icon-out-3:before, +.icon-new-tab-2:before { + content: "\e251"; +} +.icon-link:before { + content: "\e252"; +} +.icon-picture:before, +.icon-image:before { + content: "\2f"; +} +.icon-pictures:before, +.icon-images:before { + content: "\30"; +} +.icon-palette:before, +.icon-color-palette:before { + content: "\e014"; +} +.icon-camera:before { + content: "\55"; +} +.icon-camera-2:before, +.icon-video:before { + content: "\e015"; +} +.icon-play-2:before, +.icon-video-2:before, +.icon-youtube:before { + content: "\56"; +} +.icon-music:before { + content: "\57"; +} +.icon-user:before { + content: "\22"; +} +.icon-users:before { + content: "\e01f"; +} +.icon-vcard:before { + content: "\6d"; +} +.icon-address:before { + content: "\70"; +} +.icon-share-alt:before, +.icon-out:before { + content: "\26"; +} +.icon-enter:before { + content: "\e257"; +} +.icon-exit:before { + content: "\e258"; +} +.icon-comment:before, +.icon-comments:before { + content: "\24"; +} +.icon-comments-2:before { + content: "\25"; +} +.icon-quote:before, +.icon-quotes-left:before { + content: "\60"; +} +.icon-quote-2:before, +.icon-quotes-right:before { + content: "\61"; +} +.icon-quote-3:before, +.icon-bubble-quote:before { + content: "\e259"; +} +.icon-phone:before { + content: "\e260"; +} +.icon-phone-2:before { + content: "\e261"; +} +.icon-envelope:before, +.icon-mail:before { + content: "\4d"; +} +.icon-envelope-opened:before, +.icon-mail-2:before { + content: "\4e"; +} +.icon-unarchive:before, +.icon-drawer:before { + content: "\4f"; +} +.icon-archive:before, +.icon-drawer-2:before { + content: "\50"; +} +.icon-briefcase:before { + content: "\e020"; +} +.icon-tag:before { + content: "\e262"; +} +.icon-tag-2:before { + content: "\e263"; +} +.icon-tags:before { + content: "\e264"; +} +.icon-tags-2:before { + content: "\e265"; +} +.icon-options:before, +.icon-cog:before { + content: "\38"; +} +.icon-cogs:before { + content: "\37"; +} +.icon-screwdriver:before, +.icon-tools:before { + content: "\36"; +} +.icon-wrench:before { + content: "\3a"; +} +.icon-equalizer:before { + content: "\39"; +} +.icon-dashboard:before { + content: "\78"; +} +.icon-switch:before { + content: "\e266"; +} +.icon-filter:before { + content: "\54"; +} +.icon-purge:before, +.icon-trash:before { + content: "\4c"; +} +.icon-checkedout:before, +.icon-lock:before, +.icon-locked:before { + content: "\23"; +} +.icon-unlock:before { + content: "\e267"; +} +.icon-key:before { + content: "\5f"; +} +.icon-support:before { + content: "\46"; +} +.icon-database:before { + content: "\62"; +} +.icon-scissors:before { + content: "\e268"; +} +.icon-health:before { + content: "\6a"; +} +.icon-wand:before { + content: "\6b"; +} +.icon-eye-open:before, +.icon-eye:before { + content: "\3c"; +} +.icon-eye-close:before, +.icon-eye-blocked:before, +.icon-eye-2:before { + content: "\e269"; +} +.icon-clock:before { + content: "\6e"; +} +.icon-compass:before { + content: "\6f"; +} +.icon-broadcast:before, +.icon-connection:before, +.icon-wifi:before { + content: "\e01b"; +} +.icon-book:before { + content: "\e271"; +} +.icon-lightning:before, +.icon-flash:before { + content: "\79"; +} +.icon-print:before, +.icon-printer:before { + content: "\e013"; +} +.icon-feed:before { + content: "\71"; +} +.icon-calendar:before { + content: "\43"; +} +.icon-calendar-2:before { + content: "\44"; +} +.icon-calendar-3:before { + content: "\e273"; +} +.icon-pie:before { + content: "\77"; +} +.icon-bars:before { + content: "\76"; +} +.icon-chart:before { + content: "\75"; +} +.icon-power-cord:before { + content: "\32"; +} +.icon-cube:before { + content: "\33"; +} +.icon-puzzle:before { + content: "\34"; +} +.icon-attachment:before, +.icon-paperclip:before, +.icon-flag-2:before { + content: "\72"; +} +.icon-lamp:before { + content: "\74"; +} +.icon-pin:before, +.icon-pushpin:before { + content: "\73"; +} +.icon-location:before { + content: "\63"; +} +.icon-shield:before { + content: "\e274"; +} +.icon-flag:before { + content: "\35"; +} +.icon-flag-3:before { + content: "\e275"; +} +.icon-bookmark:before { + content: "\e023"; +} +.icon-bookmark-2:before { + content: "\e276"; +} +.icon-heart:before { + content: "\e277"; +} +.icon-heart-2:before { + content: "\e278"; +} +.icon-thumbs-up:before { + content: "\5b"; +} +.icon-thumbs-down:before { + content: "\5c"; +} +.icon-unfeatured:before, +.icon-asterisk:before, +.icon-star-empty:before { + content: "\40"; +} +.icon-star-2:before { + content: "\41"; +} +.icon-featured:before, +.icon-default:before, +.icon-star:before { + content: "\42"; +} +.icon-smiley:before, +.icon-smiley-happy:before { + content: "\e279"; +} +.icon-smiley-2:before, +.icon-smiley-happy-2:before { + content: "\e280"; +} +.icon-smiley-sad:before { + content: "\e281"; +} +.icon-smiley-sad-2:before { + content: "\e282"; +} +.icon-smiley-neutral:before { + content: "\e283"; +} +.icon-smiley-neutral-2:before { + content: "\e284"; +} +.icon-cart:before { + content: "\e019"; +} +.icon-basket:before { + content: "\e01a"; +} +.icon-credit:before { + content: "\e286"; +} +.icon-credit-2:before { + content: "\e287"; +} +.icon-expired:before { + content: "\4b"; +} +.icon-edit:before { + color: #24748c; +} +.icon-publish:before, +.icon-save:before, +.icon-ok:before, +.icon-save-new:before, +.icon-save-copy:before, +.btn-toolbar .icon-copy:before { + color: #378137; +} +.icon-unpublish:before, +.icon-not-ok:before, +.icon-eye-close:before, +.icon-ban-circle:before, +.icon-minus-sign:before, +.btn-toolbar .icon-cancel:before { + color: #942a25; +} +.icon-featured:before, +.icon-default:before, +.icon-expired:before, +.icon-pending:before { + color: #c67605; +} +.icon-back:before { + content: "\e008"; +} +html { + height: 100%; +} +body { + height: 100%; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + box-sizing: border-box; +} +a:hover, +a:active, +a:focus { + outline: none; +} +.small { + font-size: 11px; +} +.row-even .small, +.row-odd .small, +.row-even .small a, +.row-odd .small a { + color: #888; +} +.content-title { + font-size: 24px; + font-weight: normal; + line-height: 26px; + margin-top: 0; +} +.well .page-header { + margin: -10px 0 18px 0; + padding-bottom: 5px; +} +.well .module-title.nav-header { + padding: 0 0 7px; + margin: 0; + font-size: 13px; +} +.well .row-even p, +.well .row-odd p { + margin-bottom: 0; +} +h1, +h2, +h3, +h4, +h5, +h6 { + margin: 12px 0; +} +h1 { + font-size: 26px; + line-height: 28px; +} +h2 { + font-size: 22px; + line-height: 24px; +} +h3 { + font-size: 18px; + line-height: 20px; +} +h4 { + font-size: 14px; + line-height: 16px; +} +h5 { + font-size: 13px; + line-height: 15px; +} +h6 { + font-size: 12px; + line-height: 14px; +} +.truncate { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} +.chzn-container .chzn-drop { + border-radius: 0 0 3px 3px; +} +.control-group .chzn-container { + max-width: 100%; +} +.control-group .chzn-container .chzn-choices li.search-field, +.control-group .chzn-container .chzn-choices li.search-field input { + width: 100% !important; +} +.chzn-container-single .chzn-single { + background-color: #fff; + background-clip: inherit; + background-image: none; + border: 1px solid #ccc; + border: 1px solid rgba(0,0,0,0.2); + border-radius: 3px; + box-shadow: 0 1px 0 rgba(255,255,255,0.2) inset, 0 1px 2px rgba(0,0,0,0.05); + height: auto; + line-height: 26px; +} +.chzn-container-single .chzn-single div { + background-color: #f3f3f3; + border-left: 1px solid #ccc; + bottom: 0; + height: auto; + text-align: center; + width: 28px; +} +.chzn-container-single .chzn-single div b { + background-image: none; + display: inline-block; +} +.chzn-container-single .chzn-single div b:after { + content: '\E011'; + font-family: IcoMoon; +} +.chzn-container-single .chzn-single abbr { + background: none; + right: 36px; + top: 0; +} +.chzn-container-single .chzn-single abbr:before { + font-family: IcoMoon; + content: '\0049'; + font-size: 10px; + line-height: 26px; +} +.chzn-container-single .chzn-single abbr:hover { + color: #000; +} +.chzn-container-single .chzn-search:after { + content: '\0053'; + font-family: IcoMoon; + position: relative; + right: 20px; + top: 2px; +} +.chzn-container-single .chzn-search input[type="text"] { + background: none; + border-radius: 3px; + border: 1px solid #ccc; + box-shadow: none; + height: 25px; +} +.chzn-container-single .chzn-search input[type="text"]:focus { + border-color: #3071A9; +} +.chzn-container-single .chzn-drop { + background-clip: padding-box; + border-color: #3071A9; + border-radius: 0 0 3px 3px; +} +.chzn-container-active .chzn-single { + color: #3071A9; +} +.chzn-container-active.chzn-with-drop .chzn-single { + background-image: none; + border: 1px solid #3071A9; + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; +} +.chzn-container-active.chzn-with-drop .chzn-single div { + background-color: #f3f3f3; + border-bottom: 1px solid #ccc; + border-bottom-left-radius: 3px; + border-left: 1px solid #ccc; +} +.chzn-container-active.chzn-with-drop .chzn-single div b:after { + content: '\E00F'; + font-family: IcoMoon; +} +.chzn-container-active.chzn-container-multi .chzn-choices { + border: 1px solid #3071A9; + box-shadow: none; +} +.chzn-container .chzn-results { + background-color: #fff; + border-radius: 0 0 3px 3px; + margin: 0; + padding: 0; +} +.chzn-container .chzn-results li.highlighted { + background-color: #3071A9; + background-image: none; +} +.chzn-color[rel="value_"] div { + background-color: #f3f3f3; + border-left: 1px solid #ccc; +} +.chzn-color-state.chzn-single div, +.chzn-color.chzn-single[rel="value_0"] div, +.chzn-color.chzn-single[rel="value_1"] div, +.chzn-color-state.chzn-single[rel="value_-1"] div, +.chzn-color-state.chzn-single[rel="value_-2"] div, +.chzn-color.chzn-single[rel="value_hide"] div, +.chzn-color.chzn-single[rel="value_show_no_link"] div, +.chzn-color.chzn-single[rel="value_show_with_link"] div { + background-color: transparent !important; + border: none !important; +} +.chzn-container-active .chzn-choices { + border: 1px solid #3071A9; +} +.chzn-container-multi .chzn-choices { + background-image: none; + border-radius: 3px; + border: 1px solid #ccc; +} +.chzn-container-multi .chzn-choices li.search-choice { + background-color: #3071A9; + background-image: none; + border: 0; + box-shadow: none; + color: #fff; + line-height: 20px; + padding: 0 7px; +} +.chzn-container-multi .chzn-choices li.search-choice .search-choice-close { + color: #f5f5f5; + display: inline-block; + margin-left: 5px; + position: relative; + top: 0; + left: 0; + background-image: none; + font-size: inherit; +} +.chzn-container-multi .chzn-choices li.search-choice .search-choice-close:hover { + text-decoration: none; +} +.chzn-container-multi .chzn-choices li.search-choice .search-choice-close:before { + font-family: IcoMoon; + content: '\004A'; + position: relative; + right: 1px; + top: 0; +} +.js-stools .js-stools-container-bar .js-stools-field-filter .chzn-container { + margin: 1px 0; + padding: 0 !important; +} +.chzn-color.chzn-single[rel="value_1"], +.chzn-color-reverse.chzn-single[rel="value_0"], +.chzn-color-state.chzn-single[rel="value_1"], +.chzn-color.chzn-single[rel="value_show_no_link"], +.chzn-color.chzn-single[rel="value_show_with_link"] { + background-color: #46a546; + *background-color: #46a546; + box-shadow: 0 1px 2px rgba(0,0,0,0.05); + color: #ffffff; +} +.chzn-color.chzn-single[rel="value_1"]:hover, +.chzn-color.chzn-single[rel="value_1"]:focus, +.chzn-color.chzn-single[rel="value_1"]:active, +.chzn-color.chzn-single[rel="value_1"].active, +.chzn-color.chzn-single[rel="value_1"].disabled, +.chzn-color.chzn-single[rel="value_1"][disabled], +.chzn-color-reverse.chzn-single[rel="value_0"]:hover, +.chzn-color-reverse.chzn-single[rel="value_0"]:focus, +.chzn-color-reverse.chzn-single[rel="value_0"]:active, +.chzn-color-reverse.chzn-single[rel="value_0"].active, +.chzn-color-reverse.chzn-single[rel="value_0"].disabled, +.chzn-color-reverse.chzn-single[rel="value_0"][disabled], +.chzn-color-state.chzn-single[rel="value_1"]:hover, +.chzn-color-state.chzn-single[rel="value_1"]:focus, +.chzn-color-state.chzn-single[rel="value_1"]:active, +.chzn-color-state.chzn-single[rel="value_1"].active, +.chzn-color-state.chzn-single[rel="value_1"].disabled, +.chzn-color-state.chzn-single[rel="value_1"][disabled], +.chzn-color.chzn-single[rel="value_show_no_link"]:hover, +.chzn-color.chzn-single[rel="value_show_no_link"]:focus, +.chzn-color.chzn-single[rel="value_show_no_link"]:active, +.chzn-color.chzn-single[rel="value_show_no_link"].active, +.chzn-color.chzn-single[rel="value_show_no_link"].disabled, +.chzn-color.chzn-single[rel="value_show_no_link"][disabled], +.chzn-color.chzn-single[rel="value_show_with_link"]:hover, +.chzn-color.chzn-single[rel="value_show_with_link"]:focus, +.chzn-color.chzn-single[rel="value_show_with_link"]:active, +.chzn-color.chzn-single[rel="value_show_with_link"].active, +.chzn-color.chzn-single[rel="value_show_with_link"].disabled, +.chzn-color.chzn-single[rel="value_show_with_link"][disabled] { + color: #fff; + background-color: #2f6f2f; + *background-color: #2f6f2f; +} +.chzn-color.chzn-single[rel="value_1"]:active, +.chzn-color.chzn-single[rel="value_1"].active, +.chzn-color-reverse.chzn-single[rel="value_0"]:active, +.chzn-color-reverse.chzn-single[rel="value_0"].active, +.chzn-color-state.chzn-single[rel="value_1"]:active, +.chzn-color-state.chzn-single[rel="value_1"].active, +.chzn-color.chzn-single[rel="value_show_no_link"]:active, +.chzn-color.chzn-single[rel="value_show_no_link"].active, +.chzn-color.chzn-single[rel="value_show_with_link"]:active, +.chzn-color.chzn-single[rel="value_show_with_link"].active { + background-color: #46a546; +} +.chzn-color-state.chzn-single[rel="value_0"], +.chzn-color-state.chzn-single[rel="value_-2"] { + background-color: #bd362f; + *background-color: #bd362f; + box-shadow: 0 1px 2px rgba(0,0,0,0.05); + color: #ffffff; +} +.chzn-color-state.chzn-single[rel="value_0"]:hover, +.chzn-color-state.chzn-single[rel="value_0"]:focus, +.chzn-color-state.chzn-single[rel="value_0"]:active, +.chzn-color-state.chzn-single[rel="value_0"].active, +.chzn-color-state.chzn-single[rel="value_0"].disabled, +.chzn-color-state.chzn-single[rel="value_0"][disabled], +.chzn-color-state.chzn-single[rel="value_-2"]:hover, +.chzn-color-state.chzn-single[rel="value_-2"]:focus, +.chzn-color-state.chzn-single[rel="value_-2"]:active, +.chzn-color-state.chzn-single[rel="value_-2"].active, +.chzn-color-state.chzn-single[rel="value_-2"].disabled, +.chzn-color-state.chzn-single[rel="value_-2"][disabled] { + color: #fff; + background-color: #802420; + *background-color: #802420; +} +.chzn-color-state.chzn-single[rel="value_0"]:active, +.chzn-color-state.chzn-single[rel="value_0"].active, +.chzn-color-state.chzn-single[rel="value_-2"]:active, +.chzn-color-state.chzn-single[rel="value_-2"].active { + background-color: #bd362f; +} +.CodeMirror { + height: calc(100vh - 400px); + min-height: 400px; + max-height: 800px; +} +.form-horizontal .control-label { + padding-right: 5px; + text-align: left; +} +.form-horizontal .control-label .spacer hr { + width: 380px; +} +@media (max-width: 420px) { + .form-horizontal .control-label .spacer hr { + width: 220px; + } +} +.form-horizontal .field-spacer>.control-label { + width: auto; +} +.form-horizontal #jform_catid_chzn { + vertical-align: middle; +} +.form-vertical .control-label > label { + display: inline-block; + *display: inline; + *zoom: 1; +} +.form-vertical .controls { + margin-left: 0; +} +@media (max-width: 979px) { + .form-horizontal-desktop .control-label { + float: none; + width: auto; + padding-right: 0; + padding-top: 0; + text-align: left; + } + .form-horizontal-desktop .control-label > label { + display: inline-block; + *display: inline; + *zoom: 1; + } + .form-horizontal-desktop .controls { + margin-left: 0; + } +} +@media (max-width: 1199px) { + .row-fluid .row-fluid .form-horizontal-desktop .control-label { + float: none; + width: auto; + padding-right: 0; + padding-top: 0; + text-align: left; + } + .row-fluid .row-fluid .form-horizontal-desktop .control-label > label { + display: inline-block; + *display: inline; + *zoom: 1; + } + .row-fluid .row-fluid .form-horizontal-desktop .controls { + margin-left: 0; + } +} +.form-inline-header { + margin: 5px 0; +} +.form-inline-header .control-group, +.form-inline-header .control-label, +.form-inline-header .controls { + display: inline-block; + *display: inline; + *zoom: 1; +} +.form-inline-header .control-label { + width: auto; + padding-right: 10px; +} +.form-inline-header .controls { + padding-right: 20px; +} +fieldset[class^="form-"] { + min-width: 100%; +} +@-moz-document url-prefix() { + fieldset[class^="form-"] { + display: table-cell; + } +} +fieldset.checkboxes input { + float: left; +} +fieldset.checkboxes li { + list-style: none; +} +.control-group, +.controls, +.controls input[type="text"], +.controls input[type="number"], +.controls input[type="email"], +.controls select, +.controls textarea { + max-width: 100%; +} +.controls .btn-group > .btn { + min-width: 50px; + margin-left: -1px; +} +.controls .btn-group.btn-group-yesno { + width: 220px; + max-width: 100%; +} +.controls .btn-group.btn-group-yesno > .btn { + width: 50%; + min-width: 40px; + padding: 2px 0; +} +input.input-large-text { + font-size: 18px; + line-height: 22px; + height: auto; +} +textarea { + resize: both; +} +textarea.vert { + resize: vertical; +} +textarea.noResize { + resize: none; +} +.subform-repeatable { + padding-right: 10px; +} +.subform-repeatable > .btn-toolbar { + margin: 0; +} +.subform-repeatable > .btn-toolbar .group-add { + line-height: 26px; + width: 56px; + font-size: 13px; + margin-left: 28px; +} +.subform-repeatable-group { + margin-top: 20px; + margin-left: 28px; + border: 1px solid #ccc; + padding: 8px 25px 15px; + position: relative; + border-radius: 3px; +} +.subform-repeatable-group > .btn-toolbar { + margin: 0; +} +.subform-repeatable-group > .btn-toolbar .btn-group { + margin-right: 0px; + margin-top: -1px; + position: static; +} +.subform-repeatable-group > .btn-toolbar .btn { + font-size: 13px; + line-height: 26px; + background-color: #F3F3F3; + position: absolute; +} +.subform-repeatable-group > .btn-toolbar .btn span { + vertical-align: middle; + line-height: 11px; +} +.subform-repeatable-group > .btn-toolbar .btn.btn-success { + color: #378137; + bottom: 0; + right: 0; + border-radius: 3px 0 0 0; + border-width: 1px 0 0 1px; + padding-top: 1px; +} +.subform-repeatable-group > .btn-toolbar .btn.btn-success .icon-plus:before { + content: "]"; +} +.subform-repeatable-group > .btn-toolbar .btn.btn-danger { + color: #942a25; + top: 0; + right: 0; + border-radius: 0 0 0 3px; + border-width: 0 0 1px 1px; +} +.subform-repeatable-group > .btn-toolbar .btn.btn-danger .icon-minus:before { + content: "I"; +} +.subform-repeatable-group > .btn-toolbar .btn.btn-primary { + color: #24748c; + color: #333; + right: 100%; + top: 50%; + margin-top: -27px; + margin-right: 1px; + border-radius: 3px 0 0 3px; + border-width: 1px 0 1px 1px; + line-height: 52px; +} +.subform-repeatable-group > .btn-toolbar .btn.btn-primary .icon-move:before { + content: "Z"; +} +.subform-repeatable-group > .btn-toolbar .btn [class^="icon-"], +.subform-repeatable-group > .btn-toolbar .btn [class*=" icon-"] { + margin: 0; +} +.subform-repeatable-group > .btn-toolbar .btn:hover { + background-color: #E6E6E6; +} +.subform-repeatable-group .control-group:last-of-type { + margin-bottom: 10px; +} +@media (max-width: 979px) { + .subform-repeatable-group > .btn-toolbar .btn-group { + margin-bottom: 10px; + } +} +.subform-table-layout .control-group { + margin-bottom: 10px; +} +.subform-table-layout .control-group:last-of-type { + margin-bottom: 0; +} +.subform-table-layout .controls { + padding-right: 20px; +} +.subform-table-layout input { + width: 100%; + max-width: 206px; +} +.subform-table-layout table .btn-group { + margin: 0 7px; +} +@media (max-width: 1024px) { + .subform-table-layout .subform-repeatable { + padding-right: 0; + } + .subform-table-layout .subform-repeatable tbody td:last-of-type { + text-align: right; + padding-bottom: 15px; + } + .subform-table-layout table, + .subform-table-layout thead, + .subform-table-layout tbody, + .subform-table-layout th, + .subform-table-layout td, + .subform-table-layout tr { + display: block; + } + .subform-table-layout table { + border: 1px solid #ddd; + } + .subform-table-layout thead th { + position: absolute; + top: -9999px; + left: -9999px; + } + .subform-table-layout thead th:last-of-type { + position: static; + width: 100% !important; + text-align: right; + box-sizing: border-box; + border-left: 0; + } + .subform-table-layout tr { + margin: 0; + padding: 0; + border: 0; + } + .subform-table-layout td { + border: none; + position: relative; + padding-left: 50%; + } + .subform-table-layout tbody td:first-of-type { + padding-top: 15px; + border-top: 1px solid #ddd; + } + .subform-table-layout tbody td:first-of-type:before { + top: 18px; + } + .subform-table-layout td:before { + content: attr(data-column); + position: absolute; + top: 13px; + left: 10px; + padding-right: 10px; + } +} +.controls > .radio:first-child, +.controls > .checkbox:first-child { + padding-top: 0; +} +.form-horizontal .controls > .radio:first-child, +.form-horizontal .controls > .checkbox:first-child { + padding-top: 5px; +} +.form-horizontal .controls > .radio.btn-group:first-child { + padding-top: 0; +} +.form-horizontal .controls > .radio.btn-group-yesno:first-child { + padding-top: 2px; +} +input.field-media-input { + width: auto; +} +.header { + background-color: #1a3867; + border-top: 1px solid rgba(255,255,255,0.2); + padding: 8px 25px; +} +@media (max-width: 767px) { + .header { + padding: 4px 18px; + margin-left: -20px; + margin-right: -20px; + } +} +.header .navbar-search { + margin-top: 0; +} +@media (max-width: 979px) { + .header .navbar-search { + border-top: 0; + border-bottom: 0; + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; + } +} +.container-logo { + float: right; + text-align: right; +} +.logo { + width: auto; + max-width: 100%; + max-height: 36px; + height: auto; +} +.page-title { + color: white; + font-weight: normal; + font-size: 20px; + line-height: 36px; + margin: 0; +} +.page-title [class^="icon-"], +.page-title [class*=" icon-"] { + margin-right: 16px; +} +@media (max-width: 767px) { + .container-logo { + display: none; + } + .page-title { + font-size: 18px; + line-height: 28px; + } + .page-title [class^="icon-"], + .page-title [class*=" icon-"] { + margin-right: 10px; + } +} +.view-login { + background-color: #17568c; + padding-top: 0; +} +.view-login .container { + width: 300px; + position: absolute; + top: 50%; + left: 50%; + margin-top: -206px; + margin-left: -150px; +} +.view-login .navbar-fixed-bottom { + padding-left: 20px; + padding-right: 20px; + text-align: center; +} +.view-login .navbar-fixed-bottom, +.view-login .navbar-fixed-bottom a { + color: #FCFCFC; +} +.view-login .navbar-inverse.navbar-fixed-bottom, +.view-login .navbar-inverse.navbar-fixed-bottom a { + color: #555; +} +.view-login .well { + padding-bottom: 0; +} +.view-login .login-joomla { + position: absolute; + left: 50%; + height: 24px; + width: 24px; + margin-left: -12px; + font-size: 22px; +} +.view-login .navbar-fixed-bottom { + position: absolute; +} +.view-login .input-medium { + width: 176px; +} +.view-login #lang_chzn { + width: 233px !important; + max-width: none; +} +.view-login #lang_chzn .chzn-single div { + width: 43px; +} +.view-login .input-prepend .add-on, +.view-login .controls .btn-group > .btn { + margin-left: 0; +} +.navbar-inverse { + color: #333; +} +.login .btn-large { + margin-top: 15px; +} +.login .form-inline .btn-group { + display: block; +} +@media (max-width: 479px) { + .login .chzn-single { + width: 222px !important; + } + .login .chzn-container, + .login .chzn-drop { + width: 230px !important; + } +} +@media (max-width: 319px) { + .view-login .navbar-fixed-bottom { + display: none; + } +} +.ventral-space { + margin-bottom: 5px; +} +ul.manager .height-50 .icon-folder-2 { + height: 35px; + width: 35px; + line-height: 35px; + font-size: 30px; +} +#imageForm .well { + margin-bottom: 5px; +} +.thumbnails-media .thumbnail { + background-color: #f4f4f4; + border-radius: 3px; + border: 0; + box-shadow: 0 0 0 1px rgba(0,0,0,0.05) inset; + padding: 0px; + height: 100px; + width: 100px; + margin: 8px; + position: relative; + text-align: center; + overflow: hidden; +} +.thumbnails-media .thumbnail .close { + background-color: #ccc; + border-left: 1px solid rgba(0,0,0,0.1); + height: 22px; + line-height: 22px; + opacity: 0.3; + text-align: center; + width: 22px; + top: 0; + right: 0; +} +.thumbnails-media .thumbnail .close:hover { + background-color: #bbb; +} +.thumbnails-media .thumbnail *, +.thumbnails-media .thumbnail *:before { + -webkit-transition: all 0.2s ease; + transition: all 0.2s ease; + -webkit-box-sizing: border-box; + box-sizing: border-box; +} +.thumbnails-media .thumbnail input[type="radio"], +.thumbnails-media .thumbnail input[type="checkbox"] { + margin: 0; + opacity: 0.55; + position: absolute; + top: 5px; + left: 5px; +} +.thumbnails-media .thumbnail .controls, +.thumbnails-media .thumbnail .imginfoBorder { + display: none; +} +.thumbnails-media .imgThumb { + position: relative; + z-index: 1; + width: 100%; + display: inline-block; +} +.thumbnails-media .imgThumb input { + display: none; +} +.thumbnails-media .imgThumb label, +.thumbnails-media .imgThumb .imgThumbInside { + display: block; + line-height: 100px; + position: relative; + width: 100%; + border-radius: 3px; + overflow: hidden; +} +.thumbnails-media .imgThumb label:before, +.thumbnails-media .imgThumb .imgThumbInside:before { + font-family: "IcoMoon"; + font-style: normal; + content: 'G'; + position: absolute; + top: 0; + right: 0; + background-color: #46a546; + color: #fff; + line-height: 26px; + width: 26px; + -webkit-transform: scale(0.5); + transform: scale(0.5); + opacity: 0; + border-color: rgba(0,0,0,0.2); + box-shadow: 0 1px 2px rgba(0,0,0,0.05); + border-radius: 0 3px; +} +.thumbnails-media .imgThumb img { + width: auto; +} +.thumbnails-media .selected :checked + label, +.thumbnails-media .selected .imgThumbInside, +.thumbnails-media .imgInput :checked + label, +.thumbnails-media .imgInput .imgThumbInside { + background-color: #ddd; +} +.thumbnails-media .selected :checked + label:before, +.thumbnails-media .selected .imgThumbInside:before, +.thumbnails-media .imgInput :checked + label:before, +.thumbnails-media .imgInput .imgThumbInside:before { + -webkit-transform: scale(1); + transform: scale(1); + opacity: 1; +} +.thumbnails-media .selected :checked + label:after, +.thumbnails-media .selected .imgThumbInside:after, +.thumbnails-media .imgInput :checked + label:after, +.thumbnails-media .imgInput .imgThumbInside:after { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + content: ''; + border: 3px solid #46a546; + border-radius: 5px; +} +.thumbnails-media .imgDelete a.close, +.thumbnails-media .imgPreview a { + padding: 0; + position: absolute; + left: 0; + z-index: 1; + height: 26px; + width: 26px; +} +.thumbnails-media .imgPreview a { + width: 100%; +} +.thumbnails-media .imgDelete a.close { + background-color: #bd362f; + border-color: #bd362f rgba(0,0,0,0.2) rgba(0,0,0,0.2) #bd362f; + top: 0; + line-height: 28px; + font-size: 12px; + padding-left: 1px; + color: #fff; + border-bottom-right-radius: 3px; + border-top-left-radius: 3px; + z-index: 10; + opacity: 0; + -webkit-transform: scale(0.5); + transform: scale(0.5); +} +.thumbnails-media .imgDelete a.close:hover { + background-color: #802420; +} +.thumbnails-media .thumbnail:hover .imgDelete a.close { + opacity: 1; + -webkit-transform: scale(1); + transform: scale(1); +} +.thumbnails-media .imgPreview a, +.thumbnails-media .imgDetails { + position: absolute; + left: 0; + text-align: left; + background-color: #fff; + border-color: rgba(0,0,0,0.2); + bottom: 0; + line-height: 26px; + border: 1px solid rgba(0,0,0,0.1); + border-width: 1px; + border-radius: 0 3px 0 0; + z-index: 1; +} +.thumbnails-media .imgPreview a:hover, +.thumbnails-media .imgDetails:hover { + background-color: #eee; +} +.thumbnails-media .imgDetails { + padding: 0 5px; + line-height: 20px; + color: #555; +} +.thumbnails-media .imgFolder span { + line-height: 90px; + font-size: 38px; + margin: 0; + width: auto; +} +.thumbnails-media .imgFolder + .imgDetails { + color: inherit; +} +.com_media .media a + a { + margin-left: -1px; +} +.com_media .tree-holder { + padding: 0 15px; +} +#folderframe.thumbnail { + border: 0; + box-shadow: none; + padding: 0; +} +#mediamanager-form { + margin: 0 -10px; + overflow-x: hidden; +} +#mediamanager-form > .muted { + padding: 0px; +} +#mediamanager-form .checkbox { + padding-left: 30px; + margin-bottom: 15px; +} +#mediamanager-form .checkbox input { + margin-top: 3px; +} +#mediamanager-form .thumbnails { + margin: 0 -8px; + overflow-x: hidden; +} +#mediamanager-form .thumbnails .thumbnail { + height: 120px; + width: 120px; + margin: 8px; +} +#mediamanager-form .thumbnails .imgThumb label, +#mediamanager-form .thumbnails .imgTotal { + line-height: 120px; +} +#mediamanager-form .icon-search::before { + padding-right: 5px; + padding-left: 1px; +} +#mediamanager-form .height-50 { + background-color: #fafafa; + height: 77px; + position: relative; + z-index: 1; + width: 100%; + display: inline-block; +} +#mediamanager-form .height-50 a, +#mediamanager-form .height-50 .icon-folder-2 { + display: inline-block; + line-height: 75px; + margin-top: -1px; +} +#mediamanager-form .height-50 a:after { + bottom: 0; + box-shadow: 0 0 0 1px rgba(0,0,0,0.08) inset; + content: ""; + display: block; + left: 0; + overflow: hidden; + position: absolute; + right: 0; + top: 0; +} +#mediamanager-form .height-50 .icon-folder-2 { + font-size: 40px; +} +.uploadform { + margin-top: 20px; +} +body.modal-open { + -ms-overflow-style: none; +} +.modal-header { + padding: 0 20px; + text-align: left; +} +.modal-header h3 { + font-weight: normal; + line-height: 50px; +} +.modal-header .close { + width: 50px; + margin-top: 0; + margin-right: -15px; + font-size: 2rem; + line-height: 50px; + border-left: 1px solid #ccc; +} +.modal-body { + padding: 0; + width: 100%; + height: auto; + max-height: none; +} +.modal-body .container-fluid { + padding-top: 15px; + padding-bottom: 15px; +} +.modal-footer { + clear: both; +} +.contentpane { + padding: 10px; + height: auto; +} +@media (min-width: 768px) { + .row-fluid .modal-batch [class*="span"] { + margin-left: 0; + } +} +.container-popup { + padding: 10px; +} +.field-media-wrapper iframe { + max-height: 75vh; +} +body .navbar, +body .navbar-fixed-top { + margin-bottom: 0; +} +.navbar-inner { + min-height: 0; + background: #f2f2f2; + background-image: none; + filter: none; +} +.navbar-inner .container-fluid { + padding-left: 10px; + padding-right: 10px; + font-size: 15px; +} +.navbar-inverse .navbar-inner { + background: #10223e; + background-image: none; + filter: none; +} +.navbar .navbar-text { + line-height: 30px; +} +.navbar .admin-logo { + float: left; + padding: 7px 12px 0px 15px; + font-size: 16px; + color: #555; +} +.navbar .admin-logo:hover { + color: #333; +} +.navbar-inverse.navbar .admin-logo { + color: #d9d9d9; +} +.navbar-inverse.navbar .admin-logo:hover { + color: #ffffff; +} +.navbar .brand { + float: right; + display: block; + padding: 6px 10px; + margin-left: -20px; + font-size: inherit; + font-weight: normal; +} +.navbar .brand:hover, +.navbar .brand:focus { + text-decoration: none; +} +.navbar .nav > li > a { + padding: 6px 10px; +} +.navbar .nav > li > a:hover { + color: white; +} +.navbar .nav > li > a:hover span.carot { + border-bottom-color: #fff; + border-top-color: #fff; +} +.navbar .dropdown-menu, +.navbar .nav-user { + font-size: 13px; +} +.navbar .nav-user .dropdown-menu li span { + padding-left: 10px; +} +.navbar .nav > li ul { + overflow-y: auto; + overflow-x: hidden; + -webkit-overflow-scrolling: touch; + -moz-overflow-scrolling: touch; + -ms-overflow-scrolling: touch; + -o-overflow-scrolling: touch; + overflow-scrolling: touch; + height: auto; + max-height: 500px; + margin: 0; +} +.navbar .nav > li ul::-webkit-scrollbar { + -webkit-appearance: none; + width: 7px; +} +.navbar .nav > li ul::-webkit-scrollbar-thumb { + border-radius: 4px; + background-color: rgba(0,0,0,0.5); + -webkit-box-shadow: 0 0 1px rgba(255,255,255,0.5); +} +.navbar .nav > li > .dropdown-menu:after { + display: none; +} +.navbar .nav > .dropdown.open:after { + content: ''; + display: inline-block; + border-left: 6px solid transparent; + border-right: 6px solid transparent; + border-bottom: 6px solid #fff; + position: absolute; + top: 25px; + left: 10px; + z-index: 1001; +} +.navbar .empty-nav { + display: none; +} +.navbar-fixed-top .navbar-inner, +.navbar-static-top .navbar-inner { + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; +} +.dropdown-menu > li > a:hover, +.dropdown-menu > li > a:focus, +.dropdown-submenu:hover > a, +.dropdown-submenu:focus > a { + background-image: none; +} +.navbar-fixed-bottom { + bottom: 0; +} +.navbar-fixed-bottom .navbar-inner { + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; +} +.navbar .btn-navbar { + background: #17568c; + border: 1px solid #0D2242; + margin-bottom: 2px; +} +@media (max-width: 767px) { + .navbar .admin-logo { + margin-left: 10px; + padding: 9px 9px 0 9px; + } +} +.navbar-search .search-query { + background: rgba(255,255,255,0.3); +} +@media (max-width: 979px) { + .navbar .nav { + font-size: 13px; + margin: 0 2px 0 0; + } + .navbar .nav > li > a { + padding: 6px; + } +} +@media (max-width: 767px) { + .navbar-search.pull-right { + float: none; + text-align: center; + } +} +@media (max-width: 738px) { + .navbar .brand { + font-size: 16px; + } +} +.nav-collapse .nav li a, +.dropdown-menu a { + background-image: none; +} +.nav-collapse .dropdown-menu > li img { + max-width: none; +} +@media (max-width: 767px) { + .navbar-fixed-top .navbar-inner, + .navbar-fixed-top .navbar-inner .container-fluid { + padding: 0; + } + .navbar .brand { + margin-top: 2px; + float: none; + text-align: center; + } + .navbar .btn-navbar { + margin-top: 3px; + margin-right: 3px; + margin-bottom: 3px; + } + .nav-collapse .nav .nav-header { + color: #fff; + } + .nav-collapse .nav, + .navbar .nav-collapse .nav.pull-right { + margin: 0; + } + .nav-collapse .dropdown-menu { + margin: 0; + } + .nav-collapse .dropdown-menu > li > span { + display: block; + padding: 4px 15px; + } + .navbar-inverse .nav-collapse .dropdown-menu > li > span { + color: #d9d9d9; + } + .nav-collapse .nav > li > a.dropdown-toggle { + background-color: rgba(255,255,255,0.07); + font-size: 12px; + font-weight: bold; + color: #eee; + text-transform: uppercase; + padding-left: 15px; + } + .nav-collapse .nav li a { + margin-bottom: 0; + border-top: 1px solid rgba(255,255,255,0.25); + border-bottom: 1px solid rgba(0,0,0,0.5); + } + .nav-collapse .nav li ul li ul.dropdown-menu, + .nav-collapse .nav li ul li:hover ul.dropdown-menu, + .nav-collapse .caret { + display: none !important; + } + .nav-collapse .nav > li > a, + .nav-collapse .dropdown-menu a { + font-size: 15px; + font-weight: normal; + color: #fff; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; + } + .navbar .nav-collapse .nav > li > .dropdown-menu::before, + .navbar .nav-collapse .nav > li > .dropdown-menu::after, + .navbar .nav-collapse .dropdown-submenu > a::after { + display: none; + } + .nav-collapse .dropdown-menu li + li a { + margin-bottom: 0; + } +} +.quick-icons { + font-size: 14px; + margin-bottom: 20px; +} +.quick-icons .nav-header { + margin: 12px 0 5px; + font-size: 13px; +} +.quick-icons .nav-header:first-child { + margin: 0 0 5px; +} +.quick-icons [class^="icon-"], +.quick-icons [class*=" icon-"] { + margin-right: 9px; +} +.quick-icons [class^="icon-"]:before, +.quick-icons [class*=" icon-"]:before { + font-size: 16px; + margin-bottom: 20px; + line-height: 18px; +} +html[dir=rtl] .quick-icons .nav-list [class^="icon-"], +html[dir=rtl] .quick-icons .nav-list [class*=" icon-"] { + margin-left: 9px; + margin-right: 0; +} +.sidebar-nav .nav-list { + padding-left: 25px; + padding-right: 25px; +} +.sidebar-nav .nav-list > li > a { + color: #555; + padding: 3px 25px; + margin-left: -26px; + margin-right: -26px; +} +.sidebar-nav .nav-list > li.active > a { + color: #fff; + margin-right: -26px; +} +.sidebar-nav .nav-list > li > a:focus, +.sidebar-nav .nav-list > li > a:hover { + text-decoration: none; + color: #fff; + background-color: #2d6ca2; + text-shadow: none; +} +.j-sidebar-container { + position: absolute; + display: block; + left: -16.5%; + width: 16.5%; + margin: -18px 0 0 -1px; + padding-top: 28px; + padding-bottom: 40px; + clear: both; + background-color: #F0F0F0; + border-bottom: 1px solid #dedede; + border-right: 1px solid #dedede; + -webkit-border-radius: 0 0 3px 0; + -moz-border-radius: 0 0 3px 0; + border-radius: 0 0 3px 0; +} +.j-sidebar-container.j-sidebar-hidden { + left: -16.5%; +} +.j-sidebar-container.j-sidebar-visible { + left: 0; +} +.j-sidebar-container .filter-select { + padding: 0 14px; +} +.j-toggle-sidebar-header h3 { + font-weight: normal; + padding: 0 15px; +} +.j-toggle-button-wrapper { + position: absolute; + display: block; + top: 7px; + padding: 0; +} +.j-toggle-button-wrapper.j-toggle-hidden { + right: -24px; +} +.j-toggle-button-wrapper.j-toggle-visible { + right: 7px; +} +.j-toggle-sidebar-button { + font-size: 16px; + color: #3071a9; + text-decoration: none; + cursor: pointer; +} +.j-toggle-sidebar-button:hover { + color: #1f496e; +} +#system-message-container, +#j-main-container { + padding: 0 0 0 5px; + min-height: 0; +} +#system-message-container.j-toggle-main, +#j-main-container.j-toggle-main, +#system-debug.j-toggle-main { + float: right; +} +@media (min-width: 768px) { + .j-toggle-transition { + -webkit-transition: all 0.3s ease; + -moz-transition: all 0.3s ease; + -o-transition: all 0.3s ease; + transition: all 0.3s ease; + } +} +@media (max-width: 979px) { + .j-toggle-button-wrapper.j-toggle-hidden { + right: -20px; + } +} +@media (max-width: 767px) { + .j-sidebar-container { + position: relative; + width: 100%; + margin: 0 0 20px 0; + padding: 0; + background: transparent; + border-right: 0; + border-bottom: 0; + } + .j-sidebar-container.j-sidebar-hidden { + margin-left: 16.5%; + } + .j-sidebar-container.j-sidebar-visible { + margin-left: 0; + } + .j-toggle-sidebar-header, + .j-toggle-button-wrapper { + display: none; + } + .view-login select { + width: 232px; + } +} +@media (max-width: 420px) { + .j-sidebar-container { + margin: 0; + } + .view-login .input-medium { + width: 180px; + } + .view-login select { + width: 232px; + } +} +#status { + background: #ebebeb; + border-top: 1px solid #dedede; + padding: 4px 10px; + -webkit-box-shadow: 0 0 3px rgba(0, 0, 0, 0.08); + -moz-box-shadow: 0 0 3px rgba(0, 0, 0, 0.08); + box-shadow: 0 0 3px rgba(0, 0, 0, 0.08); + color: #626262; +} +#status .btn-group { + margin: 0; +} +#status .btn-group.separator:after { + content: ' '; + display: block; + float: left; + background: #ADADAD; + margin: 0 10px; + height: 15px; + width: 1px; +} +#status .btn-toolbar, +#status p { + margin: 0px; +} +#status .btn-toolbar, +#status .btn-group { + font-size: 12px; +} +#status a { + color: #626262; +} +#status .badge { + margin-right: .25em; +} +#status.status-top { + background: #1a3867; + -webkit-box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.2) inset, 0px -1px 0px rgba(0, 0, 0, 0.3) inset, 0px -1px 0px rgba(0, 0, 0, 0.3); + -moz-box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.2) inset, 0px -1px 0px rgba(0, 0, 0, 0.3) inset, 0px -1px 0px rgba(0, 0, 0, 0.3); + box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.2) inset, 0px -1px 0px rgba(0, 0, 0, 0.3) inset, 0px -1px 0px rgba(0, 0, 0, 0.3); + border-top: 0; + color: #d9d9d9; + padding: 2px 20px 6px 20px; +} +#status.status-top a { + color: #d9d9d9; +} +@media (max-width: 479px) { + .pagination a { + padding: 5px; + } + .btn-group.divider, + .header .row-fluid .span3, + .header .row-fluid .span7 { + display: none; + } + .navbar .btn { + margin: 0; + } + .btn-subhead { + display: block; + margin: 10px 0; + } + .subhead-collapse.collapse { + height: 0; + overflow: hidden; + } + .btn-toolbar .btn-wrapper { + display: block; + margin: 0px 10px 5px 10px; + } + .btn-toolbar .btn-wrapper .btn { + width: 100% !important; + } + .subhead { + background: none repeat scroll 0 0 transparent; + border-bottom: 0 solid #dedede; + } + .btn-group + .btn-group { + margin-left: 10px; + } + .login .chzn-single { + width: 222px !important; + } + .login .chzn-container, + .login .chzn-drop { + width: 230px !important; + } + #toolbar [class^="icon-"], + #toolbar [class*=" icon-"] { + background-color: transparent; + border-right: medium none; + width: 10px; + } +} +table label { + margin: 0; +} +td.has-context { + height: 23px; +} +td.nowrap.has-context { + width: 45%; +} +.subhead { + background: #F0F0F0; + border-bottom: 1px solid #dedede; + color: #0C192E; + text-shadow: 0 1px 0 #FFF; + margin-bottom: 10px; + min-height: 51px; +} +.subhead-collapse { + margin-bottom: 19px; +} +.subhead-collapse.collapse { + height: auto; + overflow: visible; +} +.btn-toolbar { + margin-bottom: 5px; +} +.btn-toolbar .btn-wrapper { + display: inline-block; + margin: 0 0 8px 5px; +} +.subhead-fixed { + position: fixed; + width: 100%; + top: 30px; + z-index: 100; +} +@media (max-width: 767px) { + body { + -webkit-overflow-scrolling: touch; + } + .subhead { + margin-left: -20px; + margin-right: -20px; + padding-left: 10px; + padding-right: 10px; + } +} +.subhead h1 { + font-size: 17px; + font-weight: normal; + margin-left: 10px; + margin-top: 6px; +} +#toolbar { + margin-bottom: 2px; + margin-top: 12px; +} +#toolbar .btn { + line-height: 24px; + margin-right: 4px; + padding: 0 10px; +} +#toolbar .btn-success { + min-width: 148px; +} +#toolbar .btn-primary [class^="icon-"], +#toolbar .btn-primary [class*=" icon-"], +#toolbar .btn-warning [class^="icon-"], +#toolbar .btn-warning [class*=" icon-"], +#toolbar .btn-danger [class^="icon-"], +#toolbar .btn-danger [class*=" icon-"], +#toolbar .btn-success [class^="icon-"], +#toolbar .btn-success [class*=" icon-"], +#toolbar .btn-info [class^="icon-"], +#toolbar .btn-info [class*=" icon-"], +#toolbar .btn-inverse [class^="icon-"], +#toolbar .btn-inverse [class*=" icon-"] { + background-color: transparent; + border-right: 0; + border-left: 0; + width: 16px; + margin-left: 0; + margin-right: 0; +} +#toolbar #toolbar-options, +#toolbar #toolbar-help { + float: right; +} +#toolbar [class^="icon-"], +#toolbar [class*=" icon-"] { + background-color: #e6e6e6; + border-radius: 3px 0 0 3px; + border-right: 1px solid #b3b3b3; + height: auto; + line-height: inherit; + margin: 0 6px 0 -10px; + opacity: 1; + text-shadow: none; + width: 28px; + z-index: -1; +} +#toolbar iframe .btn-group .btn { + margin-left: -1px !important; +} +html[dir=rtl] #toolbar #toolbar-options, +html[dir=rtl] #toolbar #toolbar-help { + float: left; +} +@media (max-width: 767px) { + .subhead-fixed { + position: static; + width: auto; + } +} +.btn-subhead { + display: none; +} +@media (min-width: 480px) { + #filter-bar { + height: 29px; + } +} +@media (max-width: 479px) { + .navbar .btn { + margin: 0; + } + .btn-subhead { + display: block; + margin: 10px 0; + } + .subhead-collapse.collapse { + height: 0; + overflow: hidden; + } + .btn-toolbar .btn-wrapper { + display: block; + margin: 0px 10px 5px 10px; + } + .btn-toolbar .btn-wrapper .btn { + width: 100% !important; + } + .subhead { + background: none repeat scroll 0 0 transparent; + border-bottom: 0 solid #dedede; + } + #toolbar [class^="icon-"], + #toolbar [class*=" icon-"] { + background-color: transparent; + border-right: medium none; + width: 10px; + } +} +@media (max-width: 319px) { + .view-login .navbar-fixed-bottom { + display: none; + } +} +ul.treeselect, +ul.treeselect li { + margin: 0; + padding: 0; +} +ul.treeselect { + margin-top: 8px; +} +ul.treeselect li { + padding: 2px 10px 2px; + list-style: none; +} +ul.treeselect i.treeselect-toggle { + line-height: 18px; +} +ul.treeselect label { + font-size: 1em; + margin-left: 8px; +} +ul.treeselect label.nav-header { + padding: 0; +} +ul.treeselect input { + margin: 2px 0 0 8px; +} +ul.treeselect .treeselect-menu { + margin: 0 6px; +} +ul.treeselect ul.dropdown-menu { + margin: 0; +} +ul.treeselect ul.dropdown-menu li { + padding: 0 5px; + border: none; +} +.tree-holder .folder-url, +.tree-holder .file { + position: relative; + background-color: #fefefe; + margin-bottom: 4px; + padding: 0 10px; + line-height: 32px; + border: 1px solid rgba(0,0,0,0.08); +} +.tree-holder .folder-url, +.tree-holder .folder-url:hover, +.tree-holder .folder-url:focus { + font-weight: bold; + background-color: #f5f5f5; + color: #3071a9; +} +.tree-holder .active { + background-color: #3071a9; + color: #fff; + box-shadow: -3px 0 0 #36a2ff !important; +} +.tree-holder .active.folder-url { + background-color: #f5f5f5; + color: #3071a9; +} +.tree-holder .active.file:hover { + background-color: #3071a9; +} +.tree-holder ul ul { + box-shadow: -3px 0 0 rgba(0,0,0,0.08); + padding-right: 0; +} +.tree-holder ul ul .folder-url, +.tree-holder ul ul .file { + box-shadow: -3px 0 0 #3071a9; + border-left: 0; +} +.break-word { + word-break: break-all; + word-wrap: break-word; +} +.disabled { + cursor: default; + background-image: none; + opacity: 0.65; + filter: alpha(opacity=65); + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; +} +.j-links-separator { + margin: 20px 0px; + width: 100%; + height: 0px; + border-top: 2px solid #DDDDDD; +} +.container-main, +#system-debug { + padding-bottom: 50px; +} +.pagination-toolbar { + margin: 0; +} +.pagination-toolbar a { + line-height: 26px; +} +.pull-right > .dropdown-menu, +.dropdown-reverse { + left: auto; + right: 0; +} +.nav-filters hr { + margin: 5px 0; +} +#assignment.tab-pane { + min-height: 500px; +} +@media (max-width: 979px) { + .container-fluid { + padding-left: 10px; + padding-right: 10px; + } +} +@media (min-width: 768px) { + body { + padding-top: 30px; + } + .nav-collapse.collapse.in { + height: auto !important; + } +} +@media (max-width: 767px) { + .container-fluid { + padding-left: 0; + padding-right: 0; + } +} +@media (max-width: 479px) { + .pagination a { + padding: 5px; + } + .btn-group.divider, + .header .row-fluid .span3, + .header .row-fluid .span7 { + display: none; + } + .btn-group + .btn-group { + margin-left: 10px; + } +} +.info-labels { + margin-top: -5px; + margin-bottom: 10px; +} +.sortable-handler.inactive { + opacity: 0.3; + filter: alpha(opacity=30); +} +.alert-joomlaupdate { + text-align: center; +} +.alert-joomlaupdate button { + vertical-align: baseline; +} +.j-jed-message { + line-height: 2em; + color: #333333; +} +.moor-box { + z-index: 3; +} +.admin .chzn-container .chzn-drop { + z-index: 1060; +} +.item-associations { + margin: 0; +} +.item-associations li { + list-style: none; + display: inline-block; + margin: 0 0 3px 0; +} +.item-associations li a { + color: #ffffff; +} +#flag img { + padding-top: 6px; + vertical-align: top; +} +.tooltip { + max-width: 400px; +} +.tooltip-inner { + max-width: none; + text-align: left; + text-shadow: none; +} +th .tooltip-inner { + font-weight: normal; +} +.tooltip.hasimage { + opacity: 1; +} +#permissions-sliders .chzn-container { + margin-top: -5px; + position: absolute; +} +#permissions-sliders .table td { + padding: 8px 8px 9px; +} +.img-preview > img { + max-height: 100%; +} +.alert-no-items { + margin-top: 20px; +} +@media (max-width: 767px) { + html[dir=rtl] #toolbar #toolbar-options, + html[dir=rtl] #toolbar #toolbar-help, + #toolbar #toolbar-options, + #toolbar #toolbar-help { + float: none; + } +} +#permissions-sliders .input-small { + width: 120px; +} +.editor { + overflow: hidden; + position: relative; +} +.editor textarea.mce_editable { + box-sizing: border-box; +} +a.grid_false { + display: inline-block; + height: 16px; + width: 16px; + background-image: url('../images/admin/publish_r.png'); +} +a.grid_true { + display: inline-block; + height: 16px; + width: 16px; + background-image: url('../images/admin/icon-16-allow.png'); +} +textarea, +input, +.uneditable-input { + box-shadow: none !important; +} +textarea:focus, +input:focus, +.uneditable-input:focus { + box-shadow: none; + border: 1px solid #3071A9; +} +.js-pstats-data-details dd { + margin-left: 240px; +} +.js-pstats-data-details dt { + width: 220px; +} +#permissions table td, +#page-permissions table td { + vertical-align: middle; +} +#permissions table select, +#page-permissions table select { + margin-bottom: 0; +} +.js-stools-container-bar .btn-primary .caret { + border-bottom: 4px solid #fff; +} +.input-append .add-on, +.input-append .btn, +.input-append .btn-group > .dropdown-toggle, +.input-prepend .add-on, +.input-prepend .btn, +.input-prepend .btn-group > .dropdown-toggle { + -webkit-border-radius: 0 3px 3px 0; + -moz-border-radius: 0 3px 3px 0; + border-radius: 0 3px 3px 0; +} +.alert, +.alert-options, +.badge, +.breadcrumb > li, +.close, +.input-append .add-on, +.input-prepend .add-on, +.label, +.nav-header, +.nav-list .nav-header, +.nav-list > .active > a, +.nav-list > .active > a:focus, +.nav-list > .active > a:hover, +.nav-list > li > a, +.nav-tabs.nav-dark, +.navbar .brand, +.navbar .nav > li > a, +.navbar-inverse .brand, +.navbar-inverse .nav > li > a, +.navbar-inverse .navbar-search .search-query.focused, +.navbar-inverse .navbar-search .search-query:focus, +.progress .bar, +.subhead { + text-shadow: none; +} +.popover-content { + min-height: 33px; +} +.lead, +.navbar .brand, +.hero-unit, +.hero-unit .lead { + font-weight: 400; +} +@media (min-width: 1200px) { + #permissions .tab-content { + position: sticky; + top: 90px; + } +} +.com_cpanel .well { + padding: 8px 14px; + border: 1px solid rgba(0,0,0,0.05); +} +.com_cpanel .well .module-title.nav-header { + color: #555; +} +.com_cpanel .well > .row-striped, +.com_cpanel .well > .list-striped { + margin: 0 -14px; +} +.com_cpanel .well > .row-striped > .row-fluid, +.com_cpanel .well > .list-striped > .row-fluid { + padding: 8px 14px; +} +.com_cpanel .well > .row-striped > .row-fluid [class*="span"], +.com_cpanel .well > .list-striped > .row-fluid [class*="span"] { + margin-left: 0; +} +.com_cpanel .well > .row-striped > li, +.com_cpanel .well > .list-striped > li { + padding-left: 15px; + padding-right: 15px; +} +.com_postinstall fieldset { + background-color: #fafafa; + border: 1px solid #ccc; + border-radius: 5px; + margin: 0 0 18px; + padding: 4px 18px 18px; +} +.com_postinstall fieldset .btn { + margin-top: 10px; +} +.com_postinstall legend { + border: 0 none; + display: inline-block; + padding: 0 5px; + margin-bottom: 0; + width: auto; +} +.com_privacy .well { + padding: 8px 14px; + border: 1px solid rgba(0,0,0,0.05); +} +.com_privacy .well .module-title.nav-header { + color: #555; +} +.com_privacy .well > .row-striped, +.com_privacy .well > .list-striped { + margin: 0 -14px; +} +.com_privacy .well > .row-striped > .row-fluid, +.com_privacy .well > .list-striped > .row-fluid { + padding: 8px 14px; +} +.com_privacy .well > .row-striped > .row-fluid [class*="span"], +.com_privacy .well > .list-striped > .row-fluid [class*="span"] { + margin-left: 0; +} +.com_privacy .well > .row-striped > li, +.com_privacy .well > .list-striped > li { + padding-left: 15px; + padding-right: 15px; +} +#menu-assignment { + position: relative; +} +#menu-assignment .menu-links { + margin-top: 15px; + margin-left: 0; + -webkit-column-count: 4; + -moz-column-count: 4; + column-count: 4; + -moz-column-gap: 15px; + -webkit-column-gap: 15px; + column-gap: 15px; +} +#menu-assignment .menu-links > li { + display: inline-block; + vertical-align: top; + margin-bottom: 15px; + width: 100%; + list-style: none; + page-break-inside: avoid; + break-inside: avoid; +} +#menu-assignment .menu-links-block { + background-color: #fafafa; + border: 1px solid #ddd; + border-radius: 3px; + padding: 15px; +} +@media (max-width: 1199px) { + #menu-assignment .menu-links { + -webkit-column-count: 3; + -moz-column-count: 3; + column-count: 3; + } +} +@media (max-width: 767px) { + #menu-assignment .menu-links { + -webkit-column-count: auto; + -moz-column-count: auto; + column-count: auto; + } +} diff --git a/Sites/pages/administrator/templates/isis/error.php b/Sites/pages/administrator/templates/isis/error.php new file mode 100644 index 00000000..cf2f29df --- /dev/null +++ b/Sites/pages/administrator/templates/isis/error.php @@ -0,0 +1,296 @@ +getTemplate(true)->params; + +$app = JFactory::getApplication(); +$lang = JFactory::getLanguage(); +$input = $app->input; +$user = JFactory::getUser(); + +// Gets the FrontEnd Main page Uri +$frontEndUri = JUri::getInstance(JUri::root()); +$frontEndUri->setScheme(((int) $app->get('force_ssl', 0) === 2) ? 'https' : 'http'); +$mainPageUri = $frontEndUri->toString(); + +// Detecting Active Variables +$option = $input->get('option', ''); +$view = $input->get('view', ''); +$layout = $input->get('layout', ''); +$task = $input->get('task', ''); +$itemid = $input->get('Itemid', 0, 'int'); +$sitename = htmlspecialchars($app->get('sitename'), ENT_QUOTES, 'UTF-8'); + +$cpanel = ($option === 'com_cpanel'); + +$showSubmenu = false; +$this->submenumodules = JModuleHelper::getModules('submenu'); +foreach ($this->submenumodules as $submenumodule) +{ + $output = JModuleHelper::renderModule($submenumodule); + if ($output !== '') + { + $showSubmenu = true; + break; + } +} + +// Logo file +if ($params->get('logoFile')) +{ + $logo = JUri::root() . $params->get('logoFile'); +} +else +{ + $logo = $this->baseurl . '/templates/' . $this->template . '/images/logo.png'; +} + +// Template Parameters +$displayHeader = $params->get('displayHeader', '1'); +$statusFixed = $params->get('statusFixed', '1'); +$stickyToolbar = $params->get('stickyToolbar', '1'); +?> + + + + + + + <?php echo $this->title; ?> <?php echo htmlspecialchars($this->error->getMessage(), ENT_QUOTES, 'UTF-8'); ?> + get('debug_lang', '0') == '1' || $app->get('debug', '0') == '1') : ?> + + + + + direction == 'rtl') : ?> + + + + getTag() . '/' . $lang->getTag() . '.css'; ?> + + + + + + + get('templateColor')) : ?> + + + + get('headerColor')) : ?> + + + + get('sidebarColor')) : ?> + + + + + + + + + + + + +
        + + + +
        +

        +
        +
        + getInstance()->countModules('status')) : ?> + + + + +
        + +
        +
        + +
        +
        + +

        +
        + error->getCode(); ?> error->getMessage(), ENT_QUOTES, 'UTF-8');?> + debug) : ?> +
        error->getFile(), ENT_QUOTES, 'UTF-8');?>:error->getLine(); ?> + +
        + debug) : ?> +
        + renderBacktrace(); ?> + + error->getPrevious()) : ?> + + _error here and in the loop as setError() assigns errors to this property and we need this for the backtrace to work correctly ?> + + setError($this->_error->getPrevious()); ?> + +

        +

        + _error->getMessage(), ENT_QUOTES, 'UTF-8'); ?> +
        _error->getFile(), ENT_QUOTES, 'UTF-8');?>:_error->getLine(); ?> +

        + renderBacktrace(); ?> + setError($this->_error->getPrevious()); ?> + + + setError($this->error); ?> + +
        + +

        + +
        +
        + +
        +
        +
        + + + diff --git a/Sites/pages/administrator/templates/isis/favicon.ico b/Sites/pages/administrator/templates/isis/favicon.ico new file mode 100644 index 00000000..1a4d7979 Binary files /dev/null and b/Sites/pages/administrator/templates/isis/favicon.ico differ diff --git a/Sites/pages/administrator/templates/isis/html/com_media/imageslist/default_folder.php b/Sites/pages/administrator/templates/isis/html/com_media/imageslist/default_folder.php new file mode 100644 index 00000000..8b3d5a94 --- /dev/null +++ b/Sites/pages/administrator/templates/isis/html/com_media/imageslist/default_folder.php @@ -0,0 +1,23 @@ +input; +?> +
      • + +
        + +
        +
        + escape($this->_tmp_folder->name), 10, false); ?> +
        +
        +
      • diff --git a/Sites/pages/administrator/templates/isis/html/com_media/imageslist/default_image.php b/Sites/pages/administrator/templates/isis/html/com_media/imageslist/default_image.php new file mode 100644 index 00000000..25c8633e --- /dev/null +++ b/Sites/pages/administrator/templates/isis/html/com_media/imageslist/default_image.php @@ -0,0 +1,32 @@ +trigger('onContentBeforeDisplay', array('com_media.file', &$this->_tmp_img, &$params, 0)); +?> + +
      • + +
        +
        + baseURL . '/' . $this->escape($this->_tmp_img->path_relative), JText::sprintf('COM_MEDIA_IMAGE_TITLE', $this->_tmp_img->title, JHtml::_('number.bytes', $this->_tmp_img->size)), array('width' => $this->_tmp_img->width_60, 'height' => $this->_tmp_img->height_60)); ?> +
        +
        +
        + escape($this->_tmp_img->name), 10, false); ?> +
        +
        +
      • +trigger('onContentAfterDisplay', array('com_media.file', &$this->_tmp_img, &$params, 0)); diff --git a/Sites/pages/administrator/templates/isis/html/com_media/medialist/thumbs_folders.php b/Sites/pages/administrator/templates/isis/html/com_media/medialist/thumbs_folders.php new file mode 100644 index 00000000..70045638 --- /dev/null +++ b/Sites/pages/administrator/templates/isis/html/com_media/medialist/thumbs_folders.php @@ -0,0 +1,35 @@ + +folders as $i => $folder) : ?> +
      • + canDelete):?> + × +
        + escape($folder->name), false, 'rm', 'cb-folder'); ?> +
        +
        + + +
        + + + +
        + + +
      • + diff --git a/Sites/pages/administrator/templates/isis/html/com_media/medialist/thumbs_imgs.php b/Sites/pages/administrator/templates/isis/html/com_media/medialist/thumbs_imgs.php new file mode 100644 index 00000000..5dd3be7d --- /dev/null +++ b/Sites/pages/administrator/templates/isis/html/com_media/medialist/thumbs_imgs.php @@ -0,0 +1,46 @@ + + +images as $i => $img) : ?> + trigger('onContentBeforeDisplay', array('com_media.file', &$img, &$params, 0)); ?> +
      • + + canDelete):?> +
        + +
        + + +
        + canDelete):?> + escape($img->name), false, 'rm', 'cb-image'); ?> + + +
        + + +
      • + trigger('onContentAfterDisplay', array('com_media.file', &$img, &$params, 0)); ?> + diff --git a/Sites/pages/administrator/templates/isis/html/editor_content.css b/Sites/pages/administrator/templates/isis/html/editor_content.css new file mode 100644 index 00000000..fb191b6b --- /dev/null +++ b/Sites/pages/administrator/templates/isis/html/editor_content.css @@ -0,0 +1,50 @@ +body { + background: #000; + font-family: Arial,sans-serif; + line-height: 1.3em; + font-size: 96%; + color: #333; +} + +h1 { + font-family:Helvetica ,Arial,sans-serif; + font-size: 16px; + font-weight: bold; + color: #ff0000; +} + +h2 { + font-family: Arial, Helvetica,sans-serif; + font-size: 14px; + font-weight: normal; + color: #333; +} + +h3 { + font-weight: bold; + font-family: Helvetica,Arial,sans-serif; + font-size: 19px; + color: #135cae; +} + +h4 { + font-weight: bold; + font-family: Arial, Helvetica, sans-serif; + color: #333; +} + +a:link, a:visited { + color: #1B57B1; text-decoration: none; + font-weight: normal; +} + +a:hover { + color: #00c; text-decoration: underline; + font-weight: normal; +} + +div.caption { padding: 0 10px 0 10px; } +div.caption img { border: 1px solid #CCC; } +div.caption p { font-size: .90em; color: #666; text-align: center; } + +div.teaser { background:#ccc; } diff --git a/Sites/pages/administrator/templates/isis/html/layouts/joomla/form/field/media.php b/Sites/pages/administrator/templates/isis/html/layouts/joomla/form/field/media.php new file mode 100644 index 00000000..bf5bf26e --- /dev/null +++ b/Sites/pages/administrator/templates/isis/html/layouts/joomla/form/field/media.php @@ -0,0 +1,146 @@ + +
        + JText::_('JLIB_FORM_CHANGE_IMAGE'), + 'closeButton' => true, + ) + ); + + JHtml::_('script', 'media/mediafield.min.js', array('version' => 'auto', 'relative' => true)); + ?> + +
        + + + + +
        + + /> + + + + +
        + +
        + +
        diff --git a/Sites/pages/administrator/templates/isis/html/layouts/joomla/form/field/user.php b/Sites/pages/administrator/templates/isis/html/layouts/joomla/form/field/user.php new file mode 100644 index 00000000..4b4c06ff --- /dev/null +++ b/Sites/pages/administrator/templates/isis/html/layouts/joomla/form/field/user.php @@ -0,0 +1,134 @@ + section in form XML. + * @var boolean $hidden Is this field hidden in the form? + * @var string $hint Placeholder for the field. + * @var string $id DOM id of the field. + * @var string $label Label of the field. + * @var string $labelclass Classes to apply to the label. + * @var boolean $multiple Does this field support multiple values? + * @var string $name Name of the input field. + * @var string $onchange Onchange attribute for the field. + * @var string $onclick Onclick attribute for the field. + * @var string $pattern Pattern (Reg Ex) of value of the form field. + * @var boolean $readonly Is this field read only? + * @var boolean $repeat Allows extensions to duplicate elements. + * @var boolean $required Is this field required? + * @var integer $size Size attribute of the input. + * @var boolean $spellcheck Spellcheck state for the form field. + * @var string $validate Validation rules to apply. + * @var string $value Value attribute of the field. + * + * @var string $userName The user name + * @var mixed $groups The filtering groups (null means no filtering) + * @var mixed $excluded The users to exclude from the list of users + */ + +if (!$readonly) +{ + JHtml::_('script', 'jui/fielduser.min.js', array('version' => 'auto', 'relative' => true)); +} + +$uri = new JUri('index.php?option=com_users&view=users&layout=modal&tmpl=component&required=0&field={field-user-id}&ismoo=0'); + +if ($required) +{ + $uri->setVar('required', 1); +} + +if (!empty($groups)) +{ + $uri->setVar('groups', base64_encode(json_encode($groups))); +} + +if (!empty($excluded)) +{ + $uri->setVar('excluded', base64_encode(json_encode($excluded))); +} + +// Invalidate the input value if no user selected +if ($this->escape($userName) === JText::_('JLIB_FORM_SELECT_USER')) +{ + $userName = ''; +} + +$inputAttributes = array( + 'type' => 'text', 'id' => $id, 'class' => 'field-user-input-name', 'value' => $this->escape($userName) +); + +if ($class) +{ + $inputAttributes['class'] .= ' ' . $class; +} + +if ($size) +{ + $inputAttributes['size'] = (int) $size; +} + +if ($required) +{ + $inputAttributes['required'] = 'required'; +} + +if (!$readonly) +{ + $inputAttributes['placeholder'] = JText::_('JLIB_FORM_SELECT_USER'); +} + +?> +
        +
        + readonly /> + + + JText::_('JLIB_FORM_CHANGE_USER'), + 'closeButton' => true, + 'footer' => '', + ) + ); ?> + +
        + + + +
        diff --git a/Sites/pages/administrator/templates/isis/html/layouts/joomla/pagination/link.php b/Sites/pages/administrator/templates/isis/html/layouts/joomla/pagination/link.php new file mode 100644 index 00000000..773020e7 --- /dev/null +++ b/Sites/pages/administrator/templates/isis/html/layouts/joomla/pagination/link.php @@ -0,0 +1,113 @@ +get('liClass', ''); + $addText = $options->get('addText', ''); +} +else +{ + $liClass = $addText = ''; +} + +$display = $item->text; + +switch ((string) $item->text) +{ + // Check for "Start" item + case JText::_('JLIB_HTML_START') : + $icon = 'icon-backward icon-first'; + $aria = JText::sprintf('JLIB_HTML_GOTO_POSITION', strtolower($item->text)); + break; + + // Check for "Prev" item + case JText::_('JPREV') : + $item->text = JText::_('JPREVIOUS'); + $icon = 'icon-step-backward icon-previous'; + $aria = JText::sprintf('JLIB_HTML_GOTO_POSITION', strtolower($item->text)); + break; + + // Check for "Next" item + case JText::_('JNEXT') : + $icon = 'icon-step-forward icon-next'; + $aria = JText::sprintf('JLIB_HTML_GOTO_POSITION', strtolower($item->text)); + break; + + // Check for "End" item + case JText::_('JLIB_HTML_END') : + $icon = 'icon-forward icon-last'; + $aria = JText::sprintf('JLIB_HTML_GOTO_POSITION', strtolower($item->text)); + break; + + default: + $icon = null; + $aria = JText::sprintf('JLIB_HTML_GOTO_PAGE', $item->text); + break; +} + +$item->text .= $addText ?: ''; + +if ($icon !== null) +{ + $display = ''; +} + +if ($displayData['active']) +{ + if ($item->base > 0) + { + $limit = 'limitstart.value=' . $item->base; + } + else + { + $limit = 'limitstart.value=0'; + } + + $cssClasses = array(); + + $title = ''; + + if (!is_numeric($item->text)) + { + JHtml::_('bootstrap.tooltip'); + $cssClasses[] = 'hasTooltip'; + $title = ' title="' . $item->text . '" '; + } + + $onClick = 'document.adminForm.' . $item->prefix . 'limitstart.value=' . ($item->base > 0 ? $item->base : '0') . '; Joomla.submitform();return false;'; +} +else +{ + $class = (property_exists($item, 'active') && $item->active) ? 'active' : 'disabled'; + if ($class != 'active') + { + $class .= $liClass ? ($class ? ' ' : '') . $liClass : ''; + } +} +?> + + > + href="#" onclick=""> + + + + +
      • + > + + +
      • +get('showLimitBox', 0); +$showPagesLinks = $options->get('showPagesLinks', true); +$showLimitStart = $options->get('showLimitStart', true); +?> + + diff --git a/Sites/pages/administrator/templates/isis/html/layouts/joomla/system/message.php b/Sites/pages/administrator/templates/isis/html/layouts/joomla/system/message.php new file mode 100644 index 00000000..004460e2 --- /dev/null +++ b/Sites/pages/administrator/templates/isis/html/layouts/joomla/system/message.php @@ -0,0 +1,30 @@ + 'alert-error', 'warning' => '', 'notice' => 'alert-info', 'message' => 'alert-success'); +?> +
        + + $msgs) : ?> +
        + + +

        + +
        + + +
        + + +
        diff --git a/Sites/pages/administrator/templates/isis/html/layouts/joomla/toolbar/versions.php b/Sites/pages/administrator/templates/isis/html/layouts/joomla/toolbar/versions.php new file mode 100644 index 00000000..64a0b0ec --- /dev/null +++ b/Sites/pages/administrator/templates/isis/html/layouts/joomla/toolbar/versions.php @@ -0,0 +1,43 @@ + 'auto', 'relative' => true)); + +$link = 'index.php?option=com_contenthistory&view=history&layout=modal&tmpl=component&item_id=' + . (int) $itemId . '&type_id=' . $typeId . '&type_alias=' + . $typeAlias . '&' . JSession::getFormToken() . '=1'; + +echo JHtml::_( + 'bootstrap.renderModal', + 'versionsModal', + array( + 'url' => $link, + 'title' => JText::_('COM_CONTENTHISTORY_MODAL_TITLE'), + 'height' => '300px', + 'width' => '800px', + 'footer' => '' + ) +); +?> + diff --git a/Sites/pages/administrator/templates/isis/html/mod_version/default.php b/Sites/pages/administrator/templates/isis/html/mod_version/default.php new file mode 100644 index 00000000..d403363e --- /dev/null +++ b/Sites/pages/administrator/templates/isis/html/mod_version/default.php @@ -0,0 +1,15 @@ + + + + + diff --git a/Sites/pages/administrator/templates/isis/html/modules.php b/Sites/pages/administrator/templates/isis/html/modules.php new file mode 100644 index 00000000..6c46c475 --- /dev/null +++ b/Sites/pages/administrator/templates/isis/html/modules.php @@ -0,0 +1,69 @@ + + * + * This gives template designers ultimate control over how modules are rendered. + * + * NOTICE: All chrome wrapping methods should be named: modChrome_{STYLE} and take the same + * two arguments. + */ + +/* + * Module chrome for rendering the module in a submenu + */ +function modChrome_title($module, &$params, &$attribs) +{ + if ($module->content) + { + echo '
        ' . $module->title . '
        '; + echo $module->content; + } +} + +function modChrome_no($module, &$params, &$attribs) +{ + if ($module->content) + { + echo $module->content; + } +} + +function modChrome_well($module, &$params, &$attribs) +{ + if ($module->content) + { + $moduleTag = $params->get('module_tag', 'div'); + $bootstrapSize = (int) $params->get('bootstrap_size'); + $moduleClass = $bootstrapSize ? ' span' . $bootstrapSize : ''; + $headerTag = htmlspecialchars($params->get('header_tag', 'h2'), ENT_COMPAT, 'UTF-8'); + + // Temporarily store header class in variable + $headerClass = $params->get('header_class'); + $headerClass = $headerClass ? ' ' . htmlspecialchars($headerClass, ENT_COMPAT, 'UTF-8') : ''; + + echo '<' . $moduleTag . ' class="well well-small' . $moduleClass . '">'; + + if ($module->showtitle) + { + echo '<' . $headerTag . ' class="module-title nav-header' . $headerClass . '">' . $module->title . ''; + } + + echo $module->content; + echo ''; + } +} diff --git a/Sites/pages/administrator/templates/isis/html/pagination.php b/Sites/pages/administrator/templates/isis/html/pagination.php new file mode 100644 index 00000000..298eb169 --- /dev/null +++ b/Sites/pages/administrator/templates/isis/html/pagination.php @@ -0,0 +1,220 @@ +base : integer + * $item->link : string + * $item->text : string + * + * pagination_item_inactive + * Input variable $item is an object with fields: + * $item->base : integer + * $item->link : string + * $item->text : string + * + * This gives template designers ultimate control over how pagination is rendered. + * + * NOTE: If you override pagination_item_active OR pagination_item_inactive you MUST override them both + */ + + +/** + * Renders the pagination list + * + * @param array $list Array containing pagination information + * + * @return string HTML markup for the full pagination object + * + * @since 3.0 + */ +function pagination_list_render($list) +{ + // Calculate to display range of pages + $currentPage = 1; + $range = 1; + $step = 5; + foreach ($list['pages'] as $k => $page) + { + if (!$page['active']) + { + $currentPage = $k; + } + } + if ($currentPage >= $step) + { + if ($currentPage % $step == 0) + { + $range = ceil($currentPage / $step) + 1; + } + else + { + $range = ceil($currentPage / $step); + } + } + + $html = '
          '; + $html .= $list['start']['data']; + $html .= $list['previous']['data']; + + foreach ($list['pages'] as $k => $page) + { + $html .= $page['data']; + } + + $html .= $list['next']['data']; + $html .= $list['end']['data']; + + $html .= '
        '; + return $html; +} + +/** + * Renders an active item in the pagination block + * + * @param JPaginationObject $item The current pagination object + * + * @return string HTML markup for active item + * + * @since 3.0 + */ +function pagination_item_active(&$item) +{ + $class = ''; + + // Check for "Start" item + if ($item->text == JText::_('JLIB_HTML_START')) + { + $display = ''; + } + + // Check for "Prev" item + if ($item->text == JText::_('JPREV')) + { + $item->text = JText::_('JPREVIOUS'); + $display = ''; + } + + // Check for "Next" item + if ($item->text == JText::_('JNEXT')) + { + $display = ''; + } + + // Check for "End" item + if ($item->text == JText::_('JLIB_HTML_END')) + { + $display = ''; + } + + // If the display object isn't set already, just render the item with its text + if (!isset($display)) + { + $display = $item->text; + $class = ' class="hidden-phone"'; + } + + if ($item->base > 0) + { + $limit = 'limitstart.value=' . $item->base; + } + else + { + $limit = 'limitstart.value=0'; + } + + $title = ''; + if (!is_numeric($item->text)) + { + JHtml::_('bootstrap.tooltip'); + $title = ' class="hasTooltip" title="' . $item->text . '"'; + } + + return '' . $display . ''; +} + +/** + * Renders an inactive item in the pagination block + * + * @param JPaginationObject $item The current pagination object + * + * @return string HTML markup for inactive item + * + * @since 3.0 + */ +function pagination_item_inactive(&$item) +{ + // Check for "Start" item + if ($item->text == JText::_('JLIB_HTML_START')) + { + return '
      • '; + } + + // Check for "Prev" item + if ($item->text == JText::_('JPREV')) + { + return '
      • '; + } + + // Check for "Next" item + if ($item->text == JText::_('JNEXT')) + { + return '
      • '; + } + + // Check for "End" item + if ($item->text == JText::_('JLIB_HTML_END')) + { + return '
      • '; + } + + // Check if the item is the active page + if (isset($item->active) && $item->active) + { + return '
      • ' . $item->text . '
      • '; + } + + // Doesn't match any other condition, render a normal item + return '
      • ' . $item->text . '
      • '; +} diff --git a/Sites/pages/administrator/templates/isis/images/admin/blank.png b/Sites/pages/administrator/templates/isis/images/admin/blank.png new file mode 100644 index 00000000..1797bf90 Binary files /dev/null and b/Sites/pages/administrator/templates/isis/images/admin/blank.png differ diff --git a/Sites/pages/administrator/templates/isis/images/admin/checked_out.png b/Sites/pages/administrator/templates/isis/images/admin/checked_out.png new file mode 100644 index 00000000..6ad8f25a Binary files /dev/null and b/Sites/pages/administrator/templates/isis/images/admin/checked_out.png differ diff --git a/Sites/pages/administrator/templates/isis/images/admin/collapseall.png b/Sites/pages/administrator/templates/isis/images/admin/collapseall.png new file mode 100644 index 00000000..a986d3b4 Binary files /dev/null and b/Sites/pages/administrator/templates/isis/images/admin/collapseall.png differ diff --git a/Sites/pages/administrator/templates/isis/images/admin/disabled.png b/Sites/pages/administrator/templates/isis/images/admin/disabled.png new file mode 100644 index 00000000..4c1f7c3b Binary files /dev/null and b/Sites/pages/administrator/templates/isis/images/admin/disabled.png differ diff --git a/Sites/pages/administrator/templates/isis/images/admin/downarrow-1.png b/Sites/pages/administrator/templates/isis/images/admin/downarrow-1.png new file mode 100644 index 00000000..c94074e5 Binary files /dev/null and b/Sites/pages/administrator/templates/isis/images/admin/downarrow-1.png differ diff --git a/Sites/pages/administrator/templates/isis/images/admin/downarrow.png b/Sites/pages/administrator/templates/isis/images/admin/downarrow.png new file mode 100644 index 00000000..69950e19 Binary files /dev/null and b/Sites/pages/administrator/templates/isis/images/admin/downarrow.png differ diff --git a/Sites/pages/administrator/templates/isis/images/admin/downarrow0.png b/Sites/pages/administrator/templates/isis/images/admin/downarrow0.png new file mode 100644 index 00000000..69950e19 Binary files /dev/null and b/Sites/pages/administrator/templates/isis/images/admin/downarrow0.png differ diff --git a/Sites/pages/administrator/templates/isis/images/admin/expandall.png b/Sites/pages/administrator/templates/isis/images/admin/expandall.png new file mode 100644 index 00000000..64b8c4b5 Binary files /dev/null and b/Sites/pages/administrator/templates/isis/images/admin/expandall.png differ diff --git a/Sites/pages/administrator/templates/isis/images/admin/featured.png b/Sites/pages/administrator/templates/isis/images/admin/featured.png new file mode 100644 index 00000000..e03064c7 Binary files /dev/null and b/Sites/pages/administrator/templates/isis/images/admin/featured.png differ diff --git a/Sites/pages/administrator/templates/isis/images/admin/filesave.png b/Sites/pages/administrator/templates/isis/images/admin/filesave.png new file mode 100644 index 00000000..65a45b55 Binary files /dev/null and b/Sites/pages/administrator/templates/isis/images/admin/filesave.png differ diff --git a/Sites/pages/administrator/templates/isis/images/admin/filter_16.png b/Sites/pages/administrator/templates/isis/images/admin/filter_16.png new file mode 100644 index 00000000..cbc62b7d Binary files /dev/null and b/Sites/pages/administrator/templates/isis/images/admin/filter_16.png differ diff --git a/Sites/pages/administrator/templates/isis/images/admin/icon-16-add.png b/Sites/pages/administrator/templates/isis/images/admin/icon-16-add.png new file mode 100644 index 00000000..6e7aa02a Binary files /dev/null and b/Sites/pages/administrator/templates/isis/images/admin/icon-16-add.png differ diff --git a/Sites/pages/administrator/templates/isis/images/admin/icon-16-allow.png b/Sites/pages/administrator/templates/isis/images/admin/icon-16-allow.png new file mode 100644 index 00000000..d28a18b2 Binary files /dev/null and b/Sites/pages/administrator/templates/isis/images/admin/icon-16-allow.png differ diff --git a/Sites/pages/administrator/templates/isis/images/admin/icon-16-allowinactive.png b/Sites/pages/administrator/templates/isis/images/admin/icon-16-allowinactive.png new file mode 100644 index 00000000..d20e059d Binary files /dev/null and b/Sites/pages/administrator/templates/isis/images/admin/icon-16-allowinactive.png differ diff --git a/Sites/pages/administrator/templates/isis/images/admin/icon-16-deny.png b/Sites/pages/administrator/templates/isis/images/admin/icon-16-deny.png new file mode 100644 index 00000000..ebeb69cd Binary files /dev/null and b/Sites/pages/administrator/templates/isis/images/admin/icon-16-deny.png differ diff --git a/Sites/pages/administrator/templates/isis/images/admin/icon-16-denyinactive.png b/Sites/pages/administrator/templates/isis/images/admin/icon-16-denyinactive.png new file mode 100644 index 00000000..0dc1b43e Binary files /dev/null and b/Sites/pages/administrator/templates/isis/images/admin/icon-16-denyinactive.png differ diff --git a/Sites/pages/administrator/templates/isis/images/admin/icon-16-links.png b/Sites/pages/administrator/templates/isis/images/admin/icon-16-links.png new file mode 100644 index 00000000..52b4cb43 Binary files /dev/null and b/Sites/pages/administrator/templates/isis/images/admin/icon-16-links.png differ diff --git a/Sites/pages/administrator/templates/isis/images/admin/icon-16-notice-note.png b/Sites/pages/administrator/templates/isis/images/admin/icon-16-notice-note.png new file mode 100644 index 00000000..a207d70a Binary files /dev/null and b/Sites/pages/administrator/templates/isis/images/admin/icon-16-notice-note.png differ diff --git a/Sites/pages/administrator/templates/isis/images/admin/icon-16-protected.png b/Sites/pages/administrator/templates/isis/images/admin/icon-16-protected.png new file mode 100644 index 00000000..b72ad935 Binary files /dev/null and b/Sites/pages/administrator/templates/isis/images/admin/icon-16-protected.png differ diff --git a/Sites/pages/administrator/templates/isis/images/admin/menu_divider.png b/Sites/pages/administrator/templates/isis/images/admin/menu_divider.png new file mode 100644 index 00000000..b4706b18 Binary files /dev/null and b/Sites/pages/administrator/templates/isis/images/admin/menu_divider.png differ diff --git a/Sites/pages/administrator/templates/isis/images/admin/note_add_16.png b/Sites/pages/administrator/templates/isis/images/admin/note_add_16.png new file mode 100644 index 00000000..0acd4a59 Binary files /dev/null and b/Sites/pages/administrator/templates/isis/images/admin/note_add_16.png differ diff --git a/Sites/pages/administrator/templates/isis/images/admin/publish_g.png b/Sites/pages/administrator/templates/isis/images/admin/publish_g.png new file mode 100644 index 00000000..d3794988 Binary files /dev/null and b/Sites/pages/administrator/templates/isis/images/admin/publish_g.png differ diff --git a/Sites/pages/administrator/templates/isis/images/admin/publish_r.png b/Sites/pages/administrator/templates/isis/images/admin/publish_r.png new file mode 100644 index 00000000..1405a790 Binary files /dev/null and b/Sites/pages/administrator/templates/isis/images/admin/publish_r.png differ diff --git a/Sites/pages/administrator/templates/isis/images/admin/publish_x.png b/Sites/pages/administrator/templates/isis/images/admin/publish_x.png new file mode 100644 index 00000000..87190439 Binary files /dev/null and b/Sites/pages/administrator/templates/isis/images/admin/publish_x.png differ diff --git a/Sites/pages/administrator/templates/isis/images/admin/publish_y.png b/Sites/pages/administrator/templates/isis/images/admin/publish_y.png new file mode 100644 index 00000000..75b0ddf9 Binary files /dev/null and b/Sites/pages/administrator/templates/isis/images/admin/publish_y.png differ diff --git a/Sites/pages/administrator/templates/isis/images/admin/sort_asc.png b/Sites/pages/administrator/templates/isis/images/admin/sort_asc.png new file mode 100644 index 00000000..1204f31f Binary files /dev/null and b/Sites/pages/administrator/templates/isis/images/admin/sort_asc.png differ diff --git a/Sites/pages/administrator/templates/isis/images/admin/sort_desc.png b/Sites/pages/administrator/templates/isis/images/admin/sort_desc.png new file mode 100644 index 00000000..c0ca72e6 Binary files /dev/null and b/Sites/pages/administrator/templates/isis/images/admin/sort_desc.png differ diff --git a/Sites/pages/administrator/templates/isis/images/admin/tick.png b/Sites/pages/administrator/templates/isis/images/admin/tick.png new file mode 100644 index 00000000..7cf3ad3a Binary files /dev/null and b/Sites/pages/administrator/templates/isis/images/admin/tick.png differ diff --git a/Sites/pages/administrator/templates/isis/images/admin/trash.png b/Sites/pages/administrator/templates/isis/images/admin/trash.png new file mode 100644 index 00000000..9c100938 Binary files /dev/null and b/Sites/pages/administrator/templates/isis/images/admin/trash.png differ diff --git a/Sites/pages/administrator/templates/isis/images/admin/uparrow-1.png b/Sites/pages/administrator/templates/isis/images/admin/uparrow-1.png new file mode 100644 index 00000000..20175936 Binary files /dev/null and b/Sites/pages/administrator/templates/isis/images/admin/uparrow-1.png differ diff --git a/Sites/pages/administrator/templates/isis/images/admin/uparrow.png b/Sites/pages/administrator/templates/isis/images/admin/uparrow.png new file mode 100644 index 00000000..b5b5bedd Binary files /dev/null and b/Sites/pages/administrator/templates/isis/images/admin/uparrow.png differ diff --git a/Sites/pages/administrator/templates/isis/images/admin/uparrow0.png b/Sites/pages/administrator/templates/isis/images/admin/uparrow0.png new file mode 100644 index 00000000..b5b5bedd Binary files /dev/null and b/Sites/pages/administrator/templates/isis/images/admin/uparrow0.png differ diff --git a/Sites/pages/administrator/templates/isis/images/emailButton.png b/Sites/pages/administrator/templates/isis/images/emailButton.png new file mode 100644 index 00000000..cd7ff64b Binary files /dev/null and b/Sites/pages/administrator/templates/isis/images/emailButton.png differ diff --git a/Sites/pages/administrator/templates/isis/images/joomla.png b/Sites/pages/administrator/templates/isis/images/joomla.png new file mode 100644 index 00000000..239f5778 Binary files /dev/null and b/Sites/pages/administrator/templates/isis/images/joomla.png differ diff --git a/Sites/pages/administrator/templates/isis/images/login-joomla-inverse.png b/Sites/pages/administrator/templates/isis/images/login-joomla-inverse.png new file mode 100644 index 00000000..04050ad3 Binary files /dev/null and b/Sites/pages/administrator/templates/isis/images/login-joomla-inverse.png differ diff --git a/Sites/pages/administrator/templates/isis/images/login-joomla.png b/Sites/pages/administrator/templates/isis/images/login-joomla.png new file mode 100644 index 00000000..edd17ca9 Binary files /dev/null and b/Sites/pages/administrator/templates/isis/images/login-joomla.png differ diff --git a/Sites/pages/administrator/templates/isis/images/logo-inverse.png b/Sites/pages/administrator/templates/isis/images/logo-inverse.png new file mode 100644 index 00000000..4e60f867 Binary files /dev/null and b/Sites/pages/administrator/templates/isis/images/logo-inverse.png differ diff --git a/Sites/pages/administrator/templates/isis/images/logo.png b/Sites/pages/administrator/templates/isis/images/logo.png new file mode 100644 index 00000000..8c1c265a Binary files /dev/null and b/Sites/pages/administrator/templates/isis/images/logo.png differ diff --git a/Sites/pages/administrator/templates/isis/images/pdf_button.png b/Sites/pages/administrator/templates/isis/images/pdf_button.png new file mode 100644 index 00000000..c4a1d044 Binary files /dev/null and b/Sites/pages/administrator/templates/isis/images/pdf_button.png differ diff --git a/Sites/pages/administrator/templates/isis/images/printButton.png b/Sites/pages/administrator/templates/isis/images/printButton.png new file mode 100644 index 00000000..e56670c1 Binary files /dev/null and b/Sites/pages/administrator/templates/isis/images/printButton.png differ diff --git a/Sites/pages/administrator/templates/isis/images/system/sort_asc.png b/Sites/pages/administrator/templates/isis/images/system/sort_asc.png new file mode 100644 index 00000000..67742449 Binary files /dev/null and b/Sites/pages/administrator/templates/isis/images/system/sort_asc.png differ diff --git a/Sites/pages/administrator/templates/isis/images/system/sort_desc.png b/Sites/pages/administrator/templates/isis/images/system/sort_desc.png new file mode 100644 index 00000000..c38b9803 Binary files /dev/null and b/Sites/pages/administrator/templates/isis/images/system/sort_desc.png differ diff --git a/Sites/pages/administrator/templates/isis/img/glyphicons-halflings-white.png b/Sites/pages/administrator/templates/isis/img/glyphicons-halflings-white.png new file mode 100644 index 00000000..c1ab5815 Binary files /dev/null and b/Sites/pages/administrator/templates/isis/img/glyphicons-halflings-white.png differ diff --git a/Sites/pages/administrator/templates/isis/img/glyphicons-halflings.png b/Sites/pages/administrator/templates/isis/img/glyphicons-halflings.png new file mode 100644 index 00000000..f241c76f Binary files /dev/null and b/Sites/pages/administrator/templates/isis/img/glyphicons-halflings.png differ diff --git a/Sites/pages/administrator/templates/isis/index.php b/Sites/pages/administrator/templates/isis/index.php new file mode 100644 index 00000000..ca17ca7f --- /dev/null +++ b/Sites/pages/administrator/templates/isis/index.php @@ -0,0 +1,338 @@ +input; +$user = JFactory::getUser(); + +// Output as HTML5 +$this->setHtml5(true); + +// Gets the FrontEnd Main page Uri +$frontEndUri = JUri::getInstance(JUri::root()); +$frontEndUri->setScheme(((int) $app->get('force_ssl', 0) === 2) ? 'https' : 'http'); +$mainPageUri = $frontEndUri->toString(); + +// Add JavaScript Frameworks +JHtml::_('bootstrap.framework'); + +// Add filter polyfill for IE8 +JHtml::_('behavior.polyfill', array('filter'), 'lte IE 9'); + +// Add template js +JHtml::_('script', 'template.js', array('version' => 'auto', 'relative' => true)); + +// Add html5 shiv +JHtml::_('script', 'jui/html5.js', array('version' => 'auto', 'relative' => true, 'conditional' => 'lt IE 9')); + +// Add Stylesheets +JHtml::_('stylesheet', 'template' . ($this->direction === 'rtl' ? '-rtl' : '') . '.css', array('version' => 'auto', 'relative' => true)); + +// Load specific language related CSS +JHtml::_('stylesheet', 'administrator/language/' . $lang->getTag() . '/' . $lang->getTag() . '.css', array('version' => 'auto')); + +// Load custom.css +JHtml::_('stylesheet', 'custom.css', array('version' => 'auto', 'relative' => true)); + +JHtml::_('stylesheet', 'responsive.css', array('version' => 'auto', 'relative' => true)); + + +// Detecting Active Variables +$option = $input->get('option', ''); +$view = $input->get('view', ''); +$layout = $input->get('layout', ''); +$task = $input->get('task', ''); +$itemid = $input->get('Itemid', 0, 'int'); +$sitename = htmlspecialchars($app->get('sitename', ''), ENT_QUOTES, 'UTF-8'); +$cpanel = $option === 'com_cpanel'; + +$hidden = $app->input->get('hidemainmenu'); + +$showSubmenu = false; +$this->submenumodules = JModuleHelper::getModules('submenu'); + +foreach ($this->submenumodules as $submenumodule) +{ + $output = JModuleHelper::renderModule($submenumodule); + + if ($output !== '') + { + $showSubmenu = true; + break; + } +} + +// Template Parameters +$displayHeader = $this->params->get('displayHeader', '1'); +$statusFixed = $this->params->get('statusFixed', '1'); +$stickyToolbar = $this->params->get('stickyToolbar', '1'); + +// Header classes +$navbar_color = $this->params->get('templateColor') ?: ''; +$header_color = $displayHeader && $this->params->get('headerColor') ? $this->params->get('headerColor') : ''; +$navbar_is_light = $navbar_color && colorIsLight($navbar_color); +$header_is_light = $header_color && colorIsLight($header_color); + +if ($displayHeader) +{ + // Logo file + if ($this->params->get('logoFile')) + { + $logo = JUri::root() . htmlspecialchars($this->params->get('logoFile'), ENT_QUOTES); + } + else + { + $logo = $this->baseurl . '/templates/' . $this->template . '/images/logo' . ($header_is_light ? '-inverse' : '') . '.png'; + } +} + +function colorIsLight($color) +{ + $r = hexdec(substr($color, 1, 2)); + $g = hexdec(substr($color, 3, 2)); + $b = hexdec(substr($color, 5, 2)); + + $yiq = (($r * 299) + ($g * 587) + ($b * 114)) / 1000; + + return $yiq >= 200; +} + +// Pass some values to javascript +$offset = 20; + +if ($displayHeader || !$statusFixed) +{ + $offset = 30; +} + +$stickyBar = 0; + +if ($stickyToolbar) +{ + $stickyBar = 'true'; +} + +// Template color +if ($navbar_color) +{ + $this->addStyleDeclaration(' + .navbar-inner, + .navbar-inverse .navbar-inner, + .dropdown-menu li > a:hover, + .dropdown-menu .active > a, + .dropdown-menu .active > a:hover, + .navbar-inverse .nav li.dropdown.open > .dropdown-toggle, + .navbar-inverse .nav li.dropdown.active > .dropdown-toggle, + .navbar-inverse .nav li.dropdown.open.active > .dropdown-toggle, + #status.status-top { + background: ' . $navbar_color . '; + }'); +} + +// Template header color +if ($header_color) +{ + $this->addStyleDeclaration(' + .header { + background: ' . $header_color . '; + }'); +} + +// Sidebar background color +if ($this->params->get('sidebarColor')) +{ + $this->addStyleDeclaration(' + .nav-list > .active > a, + .nav-list > .active > a:hover { + background: ' . $this->params->get('sidebarColor') . '; + }'); +} + +// Link color +if ($this->params->get('linkColor')) +{ + $this->addStyleDeclaration(' + a, + .j-toggle-sidebar-button { + color: ' . $this->params->get('linkColor') . '; + }'); +} +?> + + + + + + + + + +
        + + + +
        + +
        + +
        +
        + +countModules('status')) : ?> + + + + + + + + +
        +
        +
        +
        +
        +
        + + + +
        +
        +
        +
        +
        + +
        + + +
        + + +
        +
        + + +
        + +
        + +
        +
        + +
        + + + +
        +
        + countModules('bottom')) : ?> + + + +
        + + countModules('status') || (!$statusFixed && $this->countModules('status'))) : ?> +
        +

        + + ©

        +
        + +
        +countModules('status')) : ?> + + + + + + + diff --git a/Sites/pages/administrator/templates/isis/js/application.js b/Sites/pages/administrator/templates/isis/js/application.js new file mode 100644 index 00000000..783c73ed --- /dev/null +++ b/Sites/pages/administrator/templates/isis/js/application.js @@ -0,0 +1,7 @@ +$('.dropdown-toggle').dropdown() +$('.collapse').collapse('show') +$('#myModal').modal('hide') +$('.typeahead').typeahead() +$('.tabs').button() +$('.tip').tooltip() +$(".alert-message").alert() \ No newline at end of file diff --git a/Sites/pages/administrator/templates/isis/js/classes.js b/Sites/pages/administrator/templates/isis/js/classes.js new file mode 100644 index 00000000..2f467730 --- /dev/null +++ b/Sites/pages/administrator/templates/isis/js/classes.js @@ -0,0 +1,45 @@ +// Add classes + +window.onload=function() { +var input = document.getElementsByTagName("input"); +for (var i = 0; i < input.length; i++) { + if (input[i].className == 'button') { + input[i].className = 'btn btn-primary'; + } +} + +var button = document.getElementsByTagName("button"); +for (var i = 0; i < input.length; i++) { + if (button[i].className == 'button') { + button[i].className = 'btn btn-primary'; + } +} + +var p = document.getElementsByTagName("p"); +for (var i = 0; i < p.length; i++) { + if (p[i].className == 'readmore') { + p[i].className = 'btn'; + } +} + +var table = document.getElementsByTagName("table"); +for (var i = 0; i < table.length; i++) { + if (table[i].className == 'category') { + table[i].className = 'table table-striped'; + } +} + +var ul = document.getElementsByTagName("ul"); +for (var i = 0; i < ul.length; i++) { + if (ul[i].className == 'actions') { + ul[i].className = 'nav nav-pills'; + } +} + +var ul = document.getElementsByTagName("ul"); +for (var i = 0; i < ul.length; i++) { + if (ul[i].className == 'pagenav') { + ul[i].className = 'pagination'; + } +} +} \ No newline at end of file diff --git a/Sites/pages/administrator/templates/isis/js/template.js b/Sites/pages/administrator/templates/isis/js/template.js new file mode 100644 index 00000000..6966c1f3 --- /dev/null +++ b/Sites/pages/administrator/templates/isis/js/template.js @@ -0,0 +1,390 @@ +/** + * @package Joomla.Administrator + * @subpackage Templates.isis + * @copyright Copyright (C) 2005 - 2020 Open Source Matters, Inc. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + * @since 3.0 + */ + +jQuery(function($) +{ + 'use strict'; + + var $w = $(window); + + $(document.body) + // add color classes to chosen field based on value + .on('liszt:ready', 'select[class^="chzn-color"], select[class*=" chzn-color"]', function() { + var $select = $(this); + var cls = this.className.replace(/^.(chzn-color[a-z0-9-_]*)$.*/, '$1'); + var $container = $select.next('.chzn-container').find('.chzn-single'); + + $container.addClass(cls).attr('rel', 'value_' + $select.val()); + $select.on('change click', function() { + $container.attr('rel', 'value_' + $select.val()); + }); + }) + // Handle changes to (radio) button groups + .on('change', '.btn-group input:radio', function () { + var $this = $(this); + var $group = $this.closest('.btn-group'); + var name = $this.prop('name'); + var reversed = $group.hasClass('btn-group-reversed'); + + $group.find('input:radio[name="' + name + '"]').each(function () { + var $input = $(this); + // Get the enclosing label + var $label = $input.closest('label'); + var inputId = $input.attr('id'); + var inputVal = $input.val(); + var btnClass = 'primary'; + + // Include any additional labels for this control + if (inputId) { + $label = $label.add($('label[for="' + inputId + '"]')); + } + + if ($input.prop('checked')) { + if (inputVal != '') { + btnClass = (inputVal == 0 ? !reversed : reversed) ? 'danger' : 'success'; + } + + $label.addClass('active btn-' + btnClass); + } else { + $label.removeClass('active btn-success btn-danger btn-primary'); + } + }) + }) + .on('subform-row-add', initTemplate); + + initTemplate(); + + // Called once on domready, again when a subform row is added + function initTemplate(event, container) + { + var $container = $(container || document); + + // Create tooltips + $container.find('*[rel=tooltip]').tooltip(); + + // Turn radios into btn-group + $container.find('.radio.btn-group label').addClass('btn'); + + // Handle disabled, prevent clicks on the container, and add disabled style to each button + $container.find('fieldset.btn-group:disabled').each(function() { + $(this).css('pointer-events', 'none').off('click').find('.btn').addClass('disabled'); + }); + + // Setup coloring for buttons + $container.find('.btn-group input:checked').each(function() { + var $input = $(this); + var $label = $('label[for=' + $input.attr('id') + ']'); + var btnClass = 'primary'; + + if ($input.val() != '') + { + var reversed = $input.parent().hasClass('btn-group-reversed'); + btnClass = ($input.val() == 0 ? !reversed : reversed) ? 'danger' : 'success'; + } + + $label.addClass('active btn-' + btnClass); + }); + } + + + /** + * Append submenu items to empty UL on hover allowing a scrollable dropdown + */ + if ($w.width() > 767) + { + var menuScroll = $('#menu > li > ul'), + emptyMenu = $('#nav-empty'), + linkWidth, + menuWidth, + offsetLeft; + + $('#menu > li').on('click mouseenter', function() { + + // Set max-height (and width if scroll) for dropdown menu, depending of window height + var $self = $(this), + $dropdownMenu = $self.children('ul'), + windowHeight = $w.height(), + linkHeight = $self.outerHeight(true), + statusHeight = $('#status').outerHeight(true), + menuHeight = $dropdownMenu.height(), + menuOuterHeight = $dropdownMenu.outerHeight(true), + scrollMenuWidth = $dropdownMenu.width() + 15, + maxHeight = windowHeight - (linkHeight + statusHeight + (menuOuterHeight - menuHeight) + 20), + linkPaddingLeft = $self.children('a').css('padding-left'); + + if (maxHeight < menuHeight) + { + $dropdownMenu.css('width', scrollMenuWidth); + } + else if (maxHeight > menuHeight) + { + $dropdownMenu.css('width', 'auto'); + } + + $dropdownMenu.css('max-height', maxHeight); + + // Get the submenu position + linkWidth = $self.outerWidth(true); + menuWidth = $dropdownMenu.width(); + offsetLeft = Math.round($self.offset().left) - parseInt(linkPaddingLeft); + + emptyMenu.empty().hide(); + + }); + + menuScroll.find('.dropdown-submenu > a').on('mouseover', function() { + + var $self = $(this), + dropdown = $self.next('ul'), + submenuWidth = dropdown.outerWidth(), + offsetTop = $self.offset().top, + linkPaddingTop = parseInt(dropdown.css('padding-top')) + parseInt($self.css('padding-top')), + scroll = $w.scrollTop() + linkPaddingTop; + + // Set the submenu position + if ($('html').attr('dir') == 'rtl') + { + emptyMenu.css({ + top : offsetTop - scroll, + left: offsetLeft - (menuWidth - linkWidth) - submenuWidth + }); + } + else + { + emptyMenu.css({ + top : offsetTop - scroll, + left: offsetLeft + menuWidth + }); + } + + // Append items to empty
          and show it + dropdown.hide(); + emptyMenu.show().html(dropdown.html()); + + // Check if the full element is visible. If not, adjust the position + if (emptyMenu.Jvisible() !== true) + { + emptyMenu.css({ + top : ($w.height() - emptyMenu.outerHeight()) - $('#status').height() + }); + } + + }); + + menuScroll.find('a.no-dropdown').on('mouseenter', function() { + + emptyMenu.empty().hide(); + + }); + + // obtain a reference to the original handler + var _clearMenus = $._data(document, 'events').click.filter(function (el) { + return el.namespace === 'data-api.dropdown' && el.selector === undefined + })[0].handler; + + // disable the old listener + $(document) + .off('click.data-api.dropdown', _clearMenus) + .on('click.data-api.dropdown', function(e) { + e.button === 2 || _clearMenus(); + + if (!$('#menu').find('> li').hasClass('open')) + { + emptyMenu.empty().hide(); + } + }); + + $.fn.Jvisible = function(partial,hidden) + { + if (this.length < 1) + { + return; + } + + var $t = this.length > 1 ? this.eq(0) : this, + t = $t.get(0) + + var viewTop = $w.scrollTop(), + viewBottom = (viewTop + $w.height()) - $('#status').height(), + offset = $t.offset(), + _top = offset.top, + _bottom = _top + $t.height(), + compareTop = partial === true ? _bottom : _top, + compareBottom = partial === true ? _top : _bottom; + + return !!t.offsetWidth * t.offsetHeight && ((compareBottom <= viewBottom) && (compareTop >= viewTop)); + }; + + } + + /** + * USED IN: All views with toolbar and sticky bar enabled + */ + var navTop; + var isFixed = false; + + if (document.getElementById('isisJsData') && document.getElementById('isisJsData').getAttribute('data-tmpl-sticky') == "true") { + processScrollInit(); + processScroll(); + + $(window).on('resize', processScrollInit); + $(window).on('scroll', processScroll); + } + + function processScrollInit() { + if ($('.subhead').length) { + navTop = $('.subhead').length && $('.subhead').offset().top - parseInt(document.getElementById('isisJsData').getAttribute('data-tmpl-offset')); + + // Fix the container top + $(".container-main").css("top", $('.subhead').height() + $('nav.navbar').height()); + + // Only apply the scrollspy when the toolbar is not collapsed + if (document.body.clientWidth > 480) { + $('.subhead-collapse').height($('.subhead').height()); + $('.subhead').scrollspy({offset: {top: $('.subhead').offset().top - $('nav.navbar').height()}}); + } + } + } + + function processScroll() { + if ($('.subhead').length) { + var scrollTop = $(window).scrollTop(); + if (scrollTop >= navTop && !isFixed) { + isFixed = true; + $('.subhead').addClass('subhead-fixed'); + + // Fix the container top + $(".container-main").css("top", $('.subhead').height() + $('nav.navbar').height()); + } else if (scrollTop <= navTop && isFixed) { + isFixed = false; + $('.subhead').removeClass('subhead-fixed'); + } + } + } + + /** + * USED IN: All list views to hide/show the sidebar + */ + window.toggleSidebar = function(force) + { + var context = 'jsidebar'; + + var $sidebar = $('#j-sidebar-container'), + $main = $('#j-main-container'), + $message = $('#system-message-container'), + $debug = $('#system-debug'), + $toggleSidebarIcon = $('#j-toggle-sidebar-icon'), + $toggleButtonWrapper = $('#j-toggle-button-wrapper'), + $toggleButton = $('#j-toggle-sidebar-button'), + $sidebarToggle = $('#j-toggle-sidebar'); + + var openIcon = 'icon-arrow-left-2', + closedIcon = 'icon-arrow-right-2'; + + var $visible = $sidebarToggle.is(":visible"); + + if (jQuery(document.querySelector("html")).attr('dir') == 'rtl') + { + openIcon = 'icon-arrow-right-2'; + closedIcon = 'icon-arrow-left-2'; + } + + var isComponent = $('body').hasClass('component'); + + $sidebar.removeClass('span2').addClass('j-sidebar-container'); + $message.addClass('j-toggle-main'); + $main.addClass('j-toggle-main'); + if (!isComponent) { + $debug.addClass('j-toggle-main'); + } + + var mainHeight = $main.outerHeight()+30, + sidebarHeight = $sidebar.outerHeight(), + bodyWidth = $('body').outerWidth(), + sidebarWidth = $sidebar.outerWidth(), + contentWidth = $('#content').outerWidth(), + contentWidthRelative = contentWidth / bodyWidth * 100, + mainWidthRelative = (contentWidth - sidebarWidth) / bodyWidth * 100; + + if (force) + { + // Load the value from localStorage + if (typeof(Storage) !== "undefined") + { + $visible = localStorage.getItem(context); + } + + // Need to convert the value to a boolean + $visible = ($visible == 'true'); + } + else + { + $message.addClass('j-toggle-transition'); + $sidebar.addClass('j-toggle-transition'); + $toggleButtonWrapper.addClass('j-toggle-transition'); + $main.addClass('j-toggle-transition'); + if (!isComponent) { + $debug.addClass('j-toggle-transition'); + } + } + + if ($visible) + { + $sidebarToggle.hide(); + $sidebar.removeClass('j-sidebar-visible').addClass('j-sidebar-hidden'); + $toggleButtonWrapper.removeClass('j-toggle-visible').addClass('j-toggle-hidden'); + $toggleSidebarIcon.removeClass('j-toggle-visible').addClass('j-toggle-hidden'); + $message.removeClass('span10').addClass('span12'); + $main.removeClass('span10').addClass('span12 expanded'); + $toggleSidebarIcon.removeClass(openIcon).addClass(closedIcon); + $toggleButton.attr( 'data-original-title', Joomla.JText._('JTOGGLE_SHOW_SIDEBAR') ); + $sidebar.attr('aria-hidden', true); + $sidebar.find('a').attr('tabindex', '-1'); + $sidebar.find(':input').attr('tabindex', '-1'); + + if (!isComponent) { + $debug.css( 'width', contentWidthRelative + '%' ); + } + + if (typeof(Storage) !== "undefined") + { + // Set the last selection in localStorage + localStorage.setItem(context, true); + } + } + else + { + $sidebarToggle.show(); + $sidebar.removeClass('j-sidebar-hidden').addClass('j-sidebar-visible'); + $toggleButtonWrapper.removeClass('j-toggle-hidden').addClass('j-toggle-visible'); + $toggleSidebarIcon.removeClass('j-toggle-hidden').addClass('j-toggle-visible'); + $message.removeClass('span12').addClass('span10'); + $main.removeClass('span12 expanded').addClass('span10'); + $toggleSidebarIcon.removeClass(closedIcon).addClass(openIcon); + $toggleButton.attr( 'data-original-title', Joomla.JText._('JTOGGLE_HIDE_SIDEBAR') ); + $sidebar.removeAttr('aria-hidden'); + $sidebar.find('a').removeAttr('tabindex'); + $sidebar.find(':input').removeAttr('tabindex'); + + if (!isComponent && bodyWidth > 768 && mainHeight < sidebarHeight) + { + $debug.css( 'width', mainWidthRelative + '%' ); + } + else if (!isComponent) + { + $debug.css( 'width', contentWidthRelative + '%' ); + } + + if (typeof(Storage) !== "undefined") + { + // Set the last selection in localStorage + localStorage.setItem( context, false ); + } + } + } +}); diff --git a/Sites/pages/administrator/templates/isis/language/en-GB/en-GB.tpl_isis.ini b/Sites/pages/administrator/templates/isis/language/en-GB/en-GB.tpl_isis.ini new file mode 100644 index 00000000..f8a3af4d --- /dev/null +++ b/Sites/pages/administrator/templates/isis/language/en-GB/en-GB.tpl_isis.ini @@ -0,0 +1,43 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +ISIS="Isis Administrator template" +TPL_ISIS_CLEAR_CACHE="Clear Cache" +TPL_ISIS_COLOR_DESC="Choose a colour for the navigation bar." +TPL_ISIS_COLOR_HEADER_DESC="Choose a colour for the header." +TPL_ISIS_COLOR_HEADER_LABEL="Header Colour" +TPL_ISIS_COLOR_LABEL="Nav Bar Colour" +TPL_ISIS_COLOR_LOGIN_BACKGROUND_DESC="Choose a colour for the background of the login screen." +TPL_ISIS_COLOR_LOGIN_BACKGROUND_LABEL="Login Background Colour" +TPL_ISIS_COLOR_SIDEBAR_DESC="Choose a colour for the Sidebar Background." +TPL_ISIS_COLOR_SIDEBAR_LABEL="Sidebar Colour" +TPL_ISIS_COLOR_LINK_DESC="Choose a colour for the Link." +TPL_ISIS_COLOR_LINK_LABEL="Link Colour" +TPL_ISIS_CONTROL_PANEL="Control Panel" +TPL_ISIS_EDIT_ACCOUNT="Edit Account" +TPL_ISIS_FIELD_ADMIN_MENUS_DESC="If you intend to use Joomla Administrator on a monitor, set this to 'No'. It will prevent the collapse of the Administrator menus when reducing the width of the window. Default is 'Yes'." +TPL_ISIS_FIELD_ADMIN_MENUS_LABEL="Collapse Administrator Menu" +TPL_ISIS_HEADER_DESC="Optional display of header." +TPL_ISIS_HEADER_LABEL="Display Header" +TPL_ISIS_INSTALLER="Installer" +TPL_ISIS_ISFREESOFTWARE="Joomla is free software released under the GNU General Public License." +TPL_ISIS_LOGIN_LOGO_DESC="Select or upload a custom logo for the login area of administrator template." +TPL_ISIS_LOGIN_LOGO_LABEL="Login Logo" +TPL_ISIS_LOGO_DESC="Upload a custom logo for the administrator template." +TPL_ISIS_LOGO_LABEL="Logo" +TPL_ISIS_LOGOUT="Logout" +TPL_ISIS_PREVIEW="Preview %s" +TPL_ISIS_SKIP_TO_MAIN_CONTENT="Skip to Main Content" +TPL_ISIS_SKIP_TO_MAIN_CONTENT_HERE="Main content begins here" +TPL_ISIS_STATUS_BOTTOM="Fixed bottom" +TPL_ISIS_STATUS_DESC="Choose the location of the status module." +TPL_ISIS_STATUS_LABEL="Status Module Position" +TPL_ISIS_STATUS_TOP="Top" +TPL_ISIS_STICKY_DESC="Optionally set the toolbar to a fixed (pinned) location." +TPL_ISIS_STICKY_LABEL="Pinned Toolbar" +TPL_ISIS_TOGGLE_MENU="Toggle Navigation" +TPL_ISIS_TOOLBAR="Toolbar" +TPL_ISIS_USERMENU="User Menu" +TPL_ISIS_XML_DESCRIPTION="Continuing the Egyptian god/goddess theme (Khepri from 1.5 and Hathor from 1.6), Isis is the Joomla 3 administrator template based on Bootstrap and the launch of the Joomla User Interface library (JUI)." diff --git a/Sites/pages/administrator/templates/isis/language/en-GB/en-GB.tpl_isis.sys.ini b/Sites/pages/administrator/templates/isis/language/en-GB/en-GB.tpl_isis.sys.ini new file mode 100644 index 00000000..4db5416c --- /dev/null +++ b/Sites/pages/administrator/templates/isis/language/en-GB/en-GB.tpl_isis.sys.ini @@ -0,0 +1,20 @@ +; Joomla! Project +; Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +ISIS="Isis Administrator template" +TPL_ISIS_POSITION_BOTTOM="Bottom" +TPL_ISIS_POSITION_CPANEL="Cpanel" +TPL_ISIS_POSITION_CP_SHELL="Unused" +TPL_ISIS_POSITION_DEBUG="Debug" +TPL_ISIS_POSITION_FOOTER="Footer" +TPL_ISIS_POSITION_ICON="Quick Icons" +TPL_ISIS_POSITION_LOGIN="Login" +TPL_ISIS_POSITION_MENU="Menu" +TPL_ISIS_POSITION_POSTINSTALL="Postinstall" +TPL_ISIS_POSITION_STATUS="Status" +TPL_ISIS_POSITION_SUBMENU="Submenu" +TPL_ISIS_POSITION_TITLE="Title" +TPL_ISIS_POSITION_TOOLBAR="Toolbar" +TPL_ISIS_XML_DESCRIPTION="Continuing the Egyptian god/goddess theme (Khepri from 1.5 and Hathor from 1.6), Isis is the Joomla 3 administrator template based on Bootstrap and the launch of the Joomla User Interface library (JUI)." diff --git a/Sites/pages/administrator/templates/isis/less/blocks/_chzn-override.less b/Sites/pages/administrator/templates/isis/less/blocks/_chzn-override.less new file mode 100644 index 00000000..485771e9 --- /dev/null +++ b/Sites/pages/administrator/templates/isis/less/blocks/_chzn-override.less @@ -0,0 +1,201 @@ +.chzn-container { + .chzn-drop { + border-radius: 0 0 3px 3px; + } +} + +// Fluid width +.control-group .chzn-container { + max-width: 100%; + .chzn-choices li.search-field, + .chzn-choices li.search-field input { // Fix for #13594 + width: 100% !important; + } +} + +.chzn-container-single { + .chzn-single { + background-color: @white; + background-clip: inherit; + background-image: none; + border: 1px solid @inputBorder; + border: 1px solid rgba(0, 0, 0, 0.2); + border-radius: 3px; + box-shadow: 0 1px 0 rgba(255, 255, 255, 0.2) inset, 0 1px 2px rgba(0, 0, 0, 0.05); + height: auto; + line-height: 26px; + div { + background-color: @btnBackground; + border-left: 1px solid @inputBorder; + bottom: 0; + height: auto; + text-align: center; + width: 28px; + b { + background-image: none; + display: inline-block; + &:after { + content: '\E011'; + font-family: IcoMoon; + } + } + } + abbr { + background: none; + right: 36px; + top: 0; + &:before { + font-family: IcoMoon; + content: '\0049'; + font-size: 10px; + line-height: 26px; + } + &:hover { + color: #000; + } + } + } + .chzn-search { + &:after { + content: '\0053'; + font-family: IcoMoon; + position: relative; + right: 20px; + top: 2px; + } + input[type="text"] { + background: none; + border-radius: @inputBorderRadius; + border: 1px solid @inputBorder; + box-shadow: none; + height: 25px; + &:focus { + border-color: @inputBorderHighlight; + } + } + } + .chzn-drop { + background-clip: padding-box; + border-color: @inputBorderHighlight; + border-radius: 0 0 3px 3px; + } +} +.chzn-container-active { + .chzn-single { + color: @inputBorderHighlight; + } + &.chzn-with-drop { + .chzn-single { + background-image: none; + border: 1px solid @inputBorderHighlight; + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + div { + background-color: @btnBackground; + border-bottom: 1px solid @inputBorder; + border-bottom-left-radius: @inputBorderRadius; + border-left: 1px solid @inputBorder; + b { + &:after { + content: '\E00F'; + font-family: IcoMoon; + } + } + } + } + } + &.chzn-container-multi { + .chzn-choices { + border: 1px solid @inputBorderHighlight; + box-shadow: none; + } + } +} +.chzn-container .chzn-results { + background-color: @white; + border-radius: 0 0 @inputBorderRadius @inputBorderRadius; + margin: 0; + padding: 0; + li.highlighted { + background-color: @inputBorderHighlight; + background-image: none; + } +} +.chzn-color[rel="value_"] div { + background-color: @btnBackground; + border-left: 1px solid @inputBorder; +} +.chzn-color-state.chzn-single, +.chzn-color.chzn-single[rel="value_0"], +.chzn-color.chzn-single[rel="value_1"], +.chzn-color-state.chzn-single[rel="value_-1"], +.chzn-color-state.chzn-single[rel="value_-2"], +.chzn-color.chzn-single[rel="value_hide"], +.chzn-color.chzn-single[rel="value_show_no_link"], +.chzn-color.chzn-single[rel="value_show_with_link"] { + div { + background-color: transparent !important; + border: none !important; + } +} +.chzn-container-active .chzn-choices { + border: 1px solid @inputBorderHighlight; +} +.chzn-container-multi { + .chzn-choices { + background-image: none; + border-radius: @inputBorderRadius; + border: 1px solid @inputBorder; + li.search-choice { + background-color: @inputBorderHighlight; + background-image: none; + border: 0; + box-shadow: none; + color: #fff; + line-height: 20px; + padding: 0 7px; + .search-choice-close { + color: #f5f5f5; + display: inline-block; + margin-left: 5px; + position: relative; + top: 0; + left: 0; + background-image: none; + font-size: inherit; + &:hover { + text-decoration: none; + } + &:before { + font-family: IcoMoon; + content: '\004A'; + position: relative; + right: 1px; + top: 0; + } + } + } + } +} +.js-stools .js-stools-container-bar .js-stools-field-filter .chzn-container { + margin: 1px 0; + padding: 0 !important; +} + +/* Chosen color styles */ +.chzn-color.chzn-single[rel="value_1"], +.chzn-color-reverse.chzn-single[rel="value_0"], +.chzn-color-state.chzn-single[rel="value_1"], +.chzn-color.chzn-single[rel="value_show_no_link"], +.chzn-color.chzn-single[rel="value_show_with_link"] { + .buttonBackground(@btnSuccessBackground, @btnSuccessBackgroundHighlight); + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); + color: #ffffff; +} + +.chzn-color-state.chzn-single[rel="value_0"], +.chzn-color-state.chzn-single[rel="value_-2"] { + .buttonBackground(@btnDangerBackground, @btnDangerBackgroundHighlight); + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); + color: #ffffff; +} diff --git a/Sites/pages/administrator/templates/isis/less/blocks/_custom.less b/Sites/pages/administrator/templates/isis/less/blocks/_custom.less new file mode 100644 index 00000000..219a2e7d --- /dev/null +++ b/Sites/pages/administrator/templates/isis/less/blocks/_custom.less @@ -0,0 +1,292 @@ +// Custom + +/* Links */ +.j-links-separator { + margin: 20px 0px; + width: 100%; + height: 0px; + border-top: 2px solid #DDDDDD; +} +/* Main Container & System Debug Padding */ +.container-main, +#system-debug { + padding-bottom: 50px; +} + +/* Pagination in toolbar */ +.pagination-toolbar { + margin: 0; +} + +.pagination-toolbar a { + line-height: 26px; +} + +/* Dropdown */ +.pull-right > .dropdown-menu, +.dropdown-reverse { + left: auto; + right: 0; +} + +/* Nav list filters */ +.nav-filters hr { + margin: 5px 0; +} +/* Module Assignment Tab */ +#assignment.tab-pane { + min-height: 500px; +} + +@media (max-width: @lg-max) { + .container-fluid { + padding-left: 10px; + padding-right: 10px; + } +} + +@media (min-width: @md) { + body { + padding-top: 30px; + } + + .nav-collapse.collapse.in { + height: auto !important; + } +} + +@media (max-width: @md-max) { + .container-fluid { + padding-left: 0; + padding-right: 0; + } +} + +@media (max-width: @sm-max) { + + .pagination a { + padding: 5px; + } + + .btn-group.divider, + .header .row-fluid .span3, + .header .row-fluid .span7 { + display: none; + } + + .btn-group + .btn-group { + margin-left: 10px; + } +} + +/* Extension type labels */ +.info-labels { + margin-top: -5px; + margin-bottom: 10px; +} + +/* Sortable list*/ +.sortable-handler.inactive { + opacity: 0.3; + filter: alpha(opacity=30); +} +/* Joomla and Extension update message */ +.alert-joomlaupdate { + text-align: center; + button { + vertical-align: baseline; + } +} +.j-jed-message { + line-height: 2em; + color:#333333; +} + +/* z-index issues */ +.moor-box { + z-index: 3; +} + +.admin .chzn-container .chzn-drop { + z-index: 1060; +} + +/* Item associations */ +.item-associations { + margin: 0; +} + +.item-associations li { + list-style: none; + display: inline-block; + margin: 0 0 3px 0; +} + +.item-associations li a { + color: #ffffff; +} + +/* Content Languages flag */ +#flag img { + padding-top: 6px; + vertical-align: top; +} +/* Tweaking of tooltips */ +.tooltip { + max-width: 400px; +} + +.tooltip-inner { + max-width: none; + text-align: left; + text-shadow: none; +} + +th .tooltip-inner { + font-weight: normal; +} + +.tooltip.hasimage { + opacity: 1; +} + +/* Permissions dropdown display */ +#permissions-sliders { + .chzn-container { + margin-top: -5px; + position: absolute; + } + .table td { + padding: 8px 8px 9px; + } +} + +.img-preview > img { + max-height: 100%; +} + +.alert-no-items { + margin-top: 20px; +} +@media (max-width: @md-max) { + html[dir=rtl] #toolbar #toolbar-options, + html[dir=rtl] #toolbar #toolbar-help, + #toolbar #toolbar-options, + #toolbar #toolbar-help { + float: none; + } +} + +/* Widen the drop downs for the Permissions Field */ +#permissions-sliders .input-small { + width: 120px; +} +.editor { + overflow: hidden; + position: relative +} + +.editor textarea.mce_editable { + box-sizing: border-box; +} +/* For grid.boolean */ +a.grid_false { + display: inline-block; + height: 16px; + width: 16px; + background-image: url('../images/admin/publish_r.png'); +} + +a.grid_true { + display: inline-block; + height: 16px; + width: 16px; + background-image: url('../images/admin/icon-16-allow.png'); +} + +/* Box-shadow from focused fields */ +textarea, input, .uneditable-input { + box-shadow: none !important; +} +textarea:focus, input:focus, .uneditable-input:focus { + box-shadow: none; + border: 1px solid @inputBorderHighlight; +} + +/* Stats plugin */ +.js-pstats-data-details dd { + margin-left: 240px; +} +.js-pstats-data-details dt { + width: 220px; +} + +/* ACL Permission page */ +#permissions, +#page-permissions { + table { + td { + vertical-align: middle; + } + select { + margin-bottom: 0; + } + } +} + +.js-stools-container-bar .btn-primary .caret { + border-bottom: 4px solid @white; +} + +.input-append .add-on, .input-append .btn, .input-append .btn-group > .dropdown-toggle, .input-prepend .add-on, .input-prepend .btn, .input-prepend .btn-group > .dropdown-toggle { + -webkit-border-radius: 0 @inputBorderRadius @inputBorderRadius 0; + -moz-border-radius: 0 @inputBorderRadius @inputBorderRadius 0; + border-radius: 0 @inputBorderRadius @inputBorderRadius 0; +} + +/* Removes Text Shadows */ +.alert, +.alert-options, +.badge, +.breadcrumb > li, +.close, +.input-append .add-on, +.input-prepend .add-on, +.label, +.nav-header, +.nav-list .nav-header, +.nav-list > .active > a, +.nav-list > .active > a:focus, +.nav-list > .active > a:hover, +.nav-list > li > a, +.nav-tabs.nav-dark, +.navbar .brand, +.navbar .nav > li > a, +.navbar-inverse .brand, +.navbar-inverse .nav > li > a, +.navbar-inverse .navbar-search .search-query.focused, +.navbar-inverse .navbar-search .search-query:focus, +.progress .bar, +.subhead { + text-shadow: none; +} + +/* Popover minimum height - overwrite bootstrap default */ +.popover-content { + min-height: 33px; +} + +/* Overrid font-weight 200 */ +.lead, .navbar .brand, .hero-unit, .hero-unit .lead { + font-weight: 400; +} + +/* Stick permissions tab */ +@media (min-width: @xl) { + #permissions { + .tab-content { + position: sticky; + top: 90px; + } + } +} diff --git a/Sites/pages/administrator/templates/isis/less/blocks/_editors.less b/Sites/pages/administrator/templates/isis/less/blocks/_editors.less new file mode 100644 index 00000000..12877e14 --- /dev/null +++ b/Sites/pages/administrator/templates/isis/less/blocks/_editors.less @@ -0,0 +1,7 @@ +// Editors + +.CodeMirror { + height: calc(~"100vh - 400px"); + min-height: 400px; + max-height: 800px; +} diff --git a/Sites/pages/administrator/templates/isis/less/blocks/_forms.less b/Sites/pages/administrator/templates/isis/less/blocks/_forms.less new file mode 100644 index 00000000..8ec7b971 --- /dev/null +++ b/Sites/pages/administrator/templates/isis/less/blocks/_forms.less @@ -0,0 +1,357 @@ +// Forms + + +// Normalize LTR Label (JBS request) +// -------------------------- + +.form-horizontal { + // Float the labels left + .control-label { + padding-right: 5px; + text-align: left; + // Set a width for the spacer hr so it shows + .spacer hr { + width: 380px; + @media (max-width: 420px) { + width: 220px; + } + } + } + .field-spacer>.control-label{ + width: auto; + } + #jform_catid_chzn { + vertical-align: middle; + } +} + +.form-vertical { + .control-label { + > label { + display: inline-block; + .ie7-inline-block(); + } + } + .controls { + margin-left: 0; + } +} +@media (max-width: @lg-max) { + .form-horizontal-desktop { + .control-label { + float: none; + width: auto; + padding-right: 0; + padding-top: 0; + text-align: left; + > label { + display: inline-block; + .ie7-inline-block(); + } + } + .controls { + margin-left: 0; + } + } +} + +@media (max-width: @xl-max) { + .row-fluid .row-fluid .form-horizontal-desktop { + .control-label { + float: none; + width: auto; + padding-right: 0; + padding-top: 0; + text-align: left; + > label { + display: inline-block; + .ie7-inline-block(); + } + } + .controls { + margin-left: 0; + } + } +} + +.form-inline-header { + margin: 5px 0; + .control-group, + .control-label, + .controls { + display: inline-block; + .ie7-inline-block(); + } + .control-label { + width: auto; + padding-right: 10px; + } + .controls { + padding-right: 20px; + } +} +/* Make fieldsets responsive */ +fieldset[class^="form-"] { + min-width: 100%; +} +/* Make fieldsets responsive in Firefox. See http://getbootstrap.com/css/#tables-responsive */ +@-moz-document url-prefix() { + fieldset[class^="form-"] { display: table-cell; } +} + +/* Display checkboxes without bullets in list */ +fieldset.checkboxes input { + float: left; +} + +fieldset.checkboxes li { + list-style: none; +} + +/* Make form elements responsive */ +.control-group, +.controls, +.controls input[type="text"], +.controls input[type="number"], +.controls input[type="email"], +.controls select, +.controls textarea +{ + max-width: 100%; +} + +/* Min-width on buttons */ +.controls .btn-group > .btn { + min-width: 50px; + margin-left: -1px; +} + +.controls .btn-group.btn-group-yesno { + width: 220px; + max-width: 100%; + > .btn { + width: 50%; + min-width: 40px; + padding: 2px 0; + } +} + +/* Title field */ +input.input-large-text { + font-size: 18px; + line-height: 22px; + height: auto; +} + +/* Customize Textarea Resizing */ +textarea { + resize: both; +} + +textarea.vert { + resize: vertical; +} + +textarea.noResize { + resize: none; +} + +/* Repeatable SubForm */ +.subform-repeatable { + padding-right: 10px; + > .btn-toolbar { + margin: 0; + .group-add { + line-height: 26px; + width: 56px; + font-size: 13px; + margin-left: 28px; + } + } +} +.subform-repeatable-group { + margin-top: 20px; + margin-left: 28px; + border: 1px solid @inputBorder; + padding: 8px 25px 15px; + position: relative; + border-radius: @inputBorderRadius; + > .btn-toolbar { + margin: 0; + .btn-group { + margin-right: 0px; + margin-top: -1px; + position: static; + } + .btn { + font-size: 13px; + line-height: 26px; + background-color: #F3F3F3; + position: absolute; + span { + vertical-align: middle; + line-height: 11px; + } + &.btn-success { + color: #378137; + bottom: 0; + right: 0; + border-radius: @inputBorderRadius 0 0 0; + border-width: 1px 0 0 1px; + padding-top: 1px; + .icon-plus:before { + content: "]"; + } + } + &.btn-danger { + color: #942a25; + top: 0; + right: 0; + border-radius: 0 0 0 @inputBorderRadius; + border-width: 0 0 1px 1px; + .icon-minus:before { + content: "I"; + + } + } + &.btn-primary { + color: #24748c; + color: #333; + right: 100%; + top: 50%; + margin-top: -27px; + margin-right: 1px; + border-radius: @inputBorderRadius 0 0 @inputBorderRadius; + border-width: 1px 0 1px 1px; + line-height: 52px; + .icon-move:before { + content: "Z"; + } + } + [class^="icon-"], [class*=" icon-"] { + margin: 0; + } + &:hover { + background-color: #E6E6E6; + } + } + } + &:nth-child(odd) { + } + &:nth-child(even) { + } + &:last-of-type { + } + .control-group:last-of-type { + margin-bottom: 10px; + } +} +@media (max-width: @lg-max) { + .subform-repeatable-group > .btn-toolbar .btn-group { + margin-bottom: 10px; + } +} + +.subform-table-layout { + .control-group { + margin-bottom: 10px; + &:last-of-type { + margin-bottom: 0; + } + } + .controls { + padding-right: 20px; + } + .btn-group { + + } + input { + width: 100%; + max-width: 206px; + } + table .btn-group { + margin: 0 7px; + } +} +@media (max-width: 1024px) { + .subform-table-layout { + .subform-repeatable { + padding-right: 0; + tbody td:last-of-type { + text-align: right; + padding-bottom: 15px; + } + } + table, thead, tbody, th, td, tr { + display: block; + } + table { + border: 1px solid #ddd; + } + thead { + + th { + position: absolute; + top: -9999px; + left: -9999px; + &:last-of-type { + position: static; + width: 100% !important; + text-align: right; + box-sizing: border-box; + border-left: 0; + } + } + } + tr { + margin: 0; + padding: 0; + border: 0; + } + td { + border: none; + position: relative; + padding-left: 50%; + } + tbody { + td:first-of-type { + padding-top: 15px; + border-top: 1px solid #ddd; + &:before {top:18px;} + } + } + + td:before { + content: attr(data-column); + position: absolute; + top: 13px; + left: 10px; + padding-right: 10px; + } + } +} + +/* Remove unneeded space between label and field in vertical forms */ +.controls > .radio:first-child, +.controls > .checkbox:first-child { + padding-top: 0; + + .form-horizontal & { + padding-top: 5px; + } +} + +/* Align btn-group to label */ +.form-horizontal .controls > .radio.btn-group:first-child { + padding-top: 0; +} + +/* Align btn-group-yesno to label */ +.form-horizontal .controls > .radio.btn-group-yesno:first-child { + padding-top: 2px; +} + +/* Fix field media width */ +input.field-media-input { + width: auto; +} diff --git a/Sites/pages/administrator/templates/isis/less/blocks/_global.less b/Sites/pages/administrator/templates/isis/less/blocks/_global.less new file mode 100644 index 00000000..614f734b --- /dev/null +++ b/Sites/pages/administrator/templates/isis/less/blocks/_global.less @@ -0,0 +1,98 @@ +// Global + +/* Body */ +html { + height: 100%; +} + +body { + height: 100%; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + box-sizing: border-box; +} + +a:hover, +a:active, +a:focus { + outline: none; +} + +/* Typography */ +.small { + font-size: 11px; +} + +.row-even .small, +.row-odd .small, +.row-even .small a, +.row-odd .small a { + color: #888; +} + +/* Page Title in Content */ +.content-title { + font-size: 24px; + font-weight: normal; + line-height: 26px; + margin-top: 0; +} + +/* Content */ +.well .page-header { + margin: -10px 0 18px 0; + padding-bottom: 5px; +} + +.well .module-title.nav-header { + padding: 0 0 7px; + margin: 0; + font-size: 13px; +} + +.well .row-even p, +.well .row-odd p { + margin-bottom: 0; +} + +/* Headings */ + +h1, h2, h3, h4, h5, h6 { + margin: (@baseLineHeight / 1.5) 0; +} + +h1 { + font-size: 26px; + line-height: 28px; +} + +h2 { + font-size: 22px; + line-height: 24px; +} + +h3 { + font-size: 18px; + line-height: 20px; +} + +h4 { + font-size: 14px; + line-height: 16px; +} + +h5 { + font-size: 13px; + line-height: 15px; +} + +h6 { + font-size: 12px; + line-height: 14px; +} + +.truncate { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} diff --git a/Sites/pages/administrator/templates/isis/less/blocks/_header.less b/Sites/pages/administrator/templates/isis/less/blocks/_header.less new file mode 100644 index 00000000..6d604a1a --- /dev/null +++ b/Sites/pages/administrator/templates/isis/less/blocks/_header.less @@ -0,0 +1,68 @@ +// header + +.header { + background-color: @headerBackground; + border-top: 1px solid rgba(255, 255, 255, 0.2); + padding: 8px 25px; +} + +@media (max-width: @md-max) { + .header { + padding: 4px 18px; + margin-left: -20px; + margin-right: -20px; + } +} + +.header .navbar-search { + margin-top: 0; +} + +@media (max-width: @lg-max) { + .header .navbar-search { + border-top: 0; + border-bottom: 0; + .box-shadow(none); + } +} + +/* Logo */ +.container-logo { + float: right; + text-align: right; +} + +.logo { + width: auto; + max-width: 100%; + max-height: 36px; + height: auto; +} + +/* Page Title */ +.page-title { + color: white; + font-weight: normal; + font-size: 20px; + line-height: 36px; + margin: 0; + [class^="icon-"], + [class*=" icon-"] { + margin-right: 16px; + } +} + +@media (max-width: @md-max) { + .container-logo { + display: none; + } + + .page-title { + font-size: 18px; + line-height: 28px; + [class^="icon-"], + [class*=" icon-"] { + margin-right: 10px; + } + } +} diff --git a/Sites/pages/administrator/templates/isis/less/blocks/_login.less b/Sites/pages/administrator/templates/isis/less/blocks/_login.less new file mode 100644 index 00000000..7f0c02aa --- /dev/null +++ b/Sites/pages/administrator/templates/isis/less/blocks/_login.less @@ -0,0 +1,87 @@ +// Login + +.view-login { + background-color: @loginBackground; + padding-top: 0; + + .container { + width: 300px; + position: absolute; + top: 50%; + left: 50%; + margin-top: -206px; + margin-left: -150px; + } + .navbar-fixed-bottom { + padding-left: 20px; + padding-right: 20px; + text-align: center; + } + .navbar-fixed-bottom, + .navbar-fixed-bottom a { + color: #FCFCFC; + } + .navbar-inverse.navbar-fixed-bottom, + .navbar-inverse.navbar-fixed-bottom a { + color: @gray; + } + .well { + padding-bottom: 0; + } + .login-joomla { + position: absolute; + left: 50%; + height: 24px; + width: 24px; + margin-left: -12px; + font-size: 22px; + } + .navbar-fixed-bottom { + position: absolute; + } + .input-medium { + width: 176px; + } + #lang_chzn { + width: 233px !important; + max-width: none; + .chzn-single div { + width:43px; + } + } + .input-prepend .add-on, .controls .btn-group > .btn { + margin-left:0; + } +} + +.navbar-inverse { + color: @textColor; +} + +.login { + .btn-large { + margin-top: 15px; + } + .form-inline .btn-group { + display:block; + } +} + +@media (max-width: @sm-max) { + .login .chzn-single { + width: 222px !important; + } + + .login .chzn-container, + .login .chzn-drop { + width: 230px !important; + } +} + + +@media (max-width: @xs-max) { + .view-login .navbar-fixed-bottom { + display: none; + } + +} \ No newline at end of file diff --git a/Sites/pages/administrator/templates/isis/less/blocks/_media.less b/Sites/pages/administrator/templates/isis/less/blocks/_media.less new file mode 100644 index 00000000..1116a7df --- /dev/null +++ b/Sites/pages/administrator/templates/isis/less/blocks/_media.less @@ -0,0 +1,268 @@ +// Media + +/* Spacing below buttons in media manager */ +.ventral-space{ + margin-bottom: 5px; +} + +/* Media Manager folder icon override */ +ul.manager .height-50 .icon-folder-2 { + height: 35px; + width: 35px; + line-height: 35px; + font-size: 30px; +} + +#imageForm { + .well { + margin-bottom: 5px; + } +} +.thumbnails-media { + @thumbSize:100px; + .thumbnail { + background-color: #f4f4f4; + border-radius: @inputBorderRadius; + border: 0; + box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.05) inset; + padding: 0px; + height: @thumbSize; + width: @thumbSize; + margin: 8px; + position: relative; + text-align: center; + overflow: hidden; + .close { + background-color: #ccc; + border-left: 1px solid rgba(0, 0, 0, 0.1); + height: 22px; + line-height: 22px; + opacity: 0.3; + text-align: center; + width: 22px; + top: 0; + right: 0; + &:hover { + background-color: #bbb; + } + } + *, *:before { + -webkit-transition: all 0.2s ease; + transition: all 0.2s ease; + -webkit-box-sizing: border-box; + box-sizing: border-box; + } + input[type="radio"], input[type="checkbox"] { + margin: 0; + opacity: 0.55; + position: absolute; + top: 5px; + left: 5px; + } + .controls, .imginfoBorder { + display: none; + } + } + .imgThumb { + position: relative; + z-index: 1; + width:100%; + display: inline-block; + input { + display: none; + } + label, .imgThumbInside { + display: block; + line-height: @thumbSize; + position: relative; + width: 100%; + border-radius: @inputBorderRadius; + overflow: hidden; + &:before { + font-family: "IcoMoon"; + font-style: normal; + content: 'G'; + position: absolute; + top: 0; + right: 0; + background-color: @btnSuccessBackground; + color: #fff; + line-height: 26px; + width: 26px; + -webkit-transform: scale(0.5); + transform: scale(0.5); + opacity: 0; + border-color: rgba(0, 0, 0, 0.2); + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); + border-radius: 0 @inputBorderRadius; + } + } + img { + width: auto; + } + } + .selected, .imgInput { + :checked + label, .imgThumbInside { + background-color: #ddd; + &:before { + -webkit-transform: scale(1); + transform: scale(1); + opacity: 1; + } + &:after { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + content: ''; + border: 3px solid @btnSuccessBackground; + border-radius: 5px; + } + } + } + .imgDelete a.close, .imgPreview a { + padding: 0; + position: absolute; + left: 0; + z-index: 1; + height: 26px; + width: 26px; + } + .imgPreview a { + width: 100%; + } + .imgDelete a.close { + background-color: @btnDangerBackground; + border-color: @btnDangerBackground rgba(0, 0, 0, 0.2) rgba(0, 0, 0, 0.2) @btnDangerBackground; + top: 0; + line-height: 28px; + font-size: 12px; + padding-left: 1px; + color: #fff; + border-bottom-right-radius: @inputBorderRadius; + border-top-left-radius: @inputBorderRadius; + z-index: 10; + opacity: 0; + -webkit-transform: scale(0.5); + transform: scale(0.5); + &:hover { + background-color: darken(@btnDangerBackground, 15%); + } + } + .thumbnail:hover .imgDelete a.close { + opacity: 1; + -webkit-transform: scale(1); + transform: scale(1); + } + .imgPreview a, .imgDetails { + position: absolute; + left:0; + text-align: left; + background-color: #fff; + border-color: rgba(0, 0, 0, 0.2); + bottom: 0; + line-height: 26px; + border: 1px solid rgba(0, 0, 0, 0.1); + border-width: 1px; + border-radius: 0 @inputBorderRadius 0 0; + z-index: 1; + &:hover { + background-color: #eee; + } + } + .imgDetails { + padding: 0 5px; + line-height: 20px; + color: #555; + } + .imgFolder { + span { + line-height: 90px; + font-size: 38px; + margin: 0; + width: auto; + } + } + .imgFolder + .imgDetails { + color: inherit; + } +} + +// Media Manager +.com_media { + .media a + a { + margin-left: -1px; + } + .tree-holder { + padding: 0 15px; + } +} +#folderframe.thumbnail { + border: 0; + box-shadow: none; + padding: 0; +} +#mediamanager-form { + margin: 0 -10px; + overflow-x: hidden; + > .muted { + padding: 0px; + } + .checkbox { + padding-left: 30px; + margin-bottom: 15px; + input { + margin-top: 3px; + } + } + .thumbnails { + margin: 0 -8px; + overflow-x: hidden; + .thumbnail { + height: 120px; + width: 120px; + margin: 8px + } + .imgThumb label, .imgTotal { + line-height: 120px; + } + } + .icon-search::before { + padding-right: 5px; + padding-left: 1px; + } + .height-50 { + background-color: #fafafa; + height: 77px; + position: relative; + z-index: 1; + width:100%; + display: inline-block; + a, .icon-folder-2 { + display: inline-block; + line-height: 75px; + margin-top: -1px; + } + a { + &:after { + bottom: 0; + box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.08) inset; + content: ""; + display: block; + left: 0; + overflow: hidden; + position: absolute; + right: 0; + top: 0; + } + } + .icon-folder-2 { + font-size: 40px; + } + } +} + +.uploadform { + margin-top: 20px; +} diff --git a/Sites/pages/administrator/templates/isis/less/blocks/_modals.less b/Sites/pages/administrator/templates/isis/less/blocks/_modals.less new file mode 100644 index 00000000..f4e57c43 --- /dev/null +++ b/Sites/pages/administrator/templates/isis/less/blocks/_modals.less @@ -0,0 +1,58 @@ +// Modals + +body.modal-open { + -ms-overflow-style: none; +} + +.modal-header { + padding: 0 20px; + text-align: left; + h3 { + font-weight: normal; + line-height: 50px; + } + .close { + width: 50px; + margin-top: 0; + margin-right: -15px; + font-size: 2rem; + line-height: 50px; + border-left: 1px solid #ccc; + } +} + +.modal-body { + padding: 0; + width: 100%; + height: auto; + max-height: none; + .container-fluid { + padding-top: 15px; + padding-bottom: 15px; + } +} + +.modal-footer { + clear: both; +} + +.contentpane { + padding: 10px; + height: auto +} + +@media (min-width: @md) { + .row-fluid .modal-batch [class*="span"] { + margin-left: 0; + } +} + +// Component pop-up +.container-popup { + padding: 10px; +} + +// Media modal +.field-media-wrapper iframe { + max-height: 75vh; +} \ No newline at end of file diff --git a/Sites/pages/administrator/templates/isis/less/blocks/_navbar.less b/Sites/pages/administrator/templates/isis/less/blocks/_navbar.less new file mode 100644 index 00000000..e6eece66 --- /dev/null +++ b/Sites/pages/administrator/templates/isis/less/blocks/_navbar.less @@ -0,0 +1,272 @@ +// Navbar + +body .navbar, +body .navbar-fixed-top { + margin-bottom: 0; +} + +.navbar-inner { + min-height: 0; + background: @navbarBackground; + background-image: none; + filter: none; + .container-fluid { + padding-left: 10px; + padding-right: 10px; + font-size: 15px; + } +} + +.navbar-inverse { + .navbar-inner { + background: @navbarInverseBackground; + background-image: none; + filter: none; + } +} + +.navbar { + .navbar-text { + line-height: 30px; + } + .admin-logo { + float: left; + padding: 7px 12px 0px 15px; + font-size: 16px; + color: @gray; + &:hover { + color: @grayDark; + } + .navbar-inverse& { + color: #d9d9d9; + &:hover { + color: #ffffff; + } + } + } + .brand { + float: right; + display: block; + padding: 6px 10px; + margin-left: -20px; + font-size: inherit; + font-weight: normal; + &:hover, + &:focus { + text-decoration: none; + } + } + .nav > li > a { + padding: 6px 10px; + &:hover { + color: white; + } + &:hover span.carot { + border-bottom-color: #fff; + border-top-color: #fff; + } + } + .dropdown-menu, + .nav-user { + font-size: 13px; + } + .nav-user .dropdown-menu li span { + padding-left: 10px; + } + .nav > li ul { + overflow-y: auto; + overflow-x: hidden; + -webkit-overflow-scrolling: touch; + -moz-overflow-scrolling: touch; + -ms-overflow-scrolling: touch; + -o-overflow-scrolling: touch; + overflow-scrolling: touch; + height: auto; + max-height: 500px; + margin: 0; + &::-webkit-scrollbar { + -webkit-appearance: none; + width: 7px; + } + &::-webkit-scrollbar-thumb { + border-radius: 4px; + background-color: rgba(0,0,0,.5); + -webkit-box-shadow: 0 0 1px rgba(255,255,255,.5); + } + } + .nav > li > .dropdown-menu:after { + display: none; + } + .nav > .dropdown.open:after { + content: ''; + display: inline-block; + border-left: 6px solid transparent; + border-right: 6px solid transparent; + border-bottom: 6px solid #fff; + position: absolute; + top: 25px; + left: 10px; + z-index: 1001; + } + .empty-nav { + display: none; + } +} + +.navbar-fixed-top, +.navbar-static-top { + .navbar-inner { + .box-shadow(none); + } +} +.dropdown-menu > li > a:hover, .dropdown-menu > li > a:focus, .dropdown-submenu:hover > a, .dropdown-submenu:focus > a { + background-image: none; +} + +// Fixed to bottom +.navbar-fixed-bottom { + bottom: 0; + .navbar-inner { + .box-shadow(none); + } +} + +.navbar .btn-navbar { + background: #17568c; + border: 1px solid #0D2242; + margin-bottom: 2px; +} + +@media (max-width: @md-max) { + .navbar .admin-logo { + margin-left: 10px; + padding: 9px 9px 0 9px; + } +} + +/* Search Module */ +.navbar-search .search-query { + background: rgba(255, 255, 255, 0.3); +} + +@media (max-width: @lg-max) { + .navbar { + .nav { + font-size: 13px; + margin: 0 2px 0 0; + > li { + > a { + padding: 6px; + } + } + } + } +} + +@media (max-width: @md-max) { + .navbar-search.pull-right { + float: none; + text-align: center; + } +} + +@media (max-width: 738px) { + .navbar { + .brand { + font-size: 16px; + + } + } +} + +// Navbar +.nav-collapse .nav li a, +.dropdown-menu a { + background-image: none; +} + +.nav-collapse .dropdown-menu > li { + img { + max-width: none; + } +} + +@media (max-width: @navbarCollapseWidth) { + .navbar-fixed-top .navbar-inner, + .navbar-fixed-top .navbar-inner .container-fluid { + padding: 0; + } + + .navbar .brand { + margin-top: 2px; + float: none; + text-align: center; + } + + .navbar .btn-navbar { + margin-top: 3px; + margin-right: 3px; + margin-bottom: 3px; + } + + .nav-collapse .nav .nav-header { + color: @white; + } + + .nav-collapse .nav, + .navbar .nav-collapse .nav.pull-right { + margin: 0; + } + + .nav-collapse .dropdown-menu { + margin: 0; + } + + .nav-collapse .dropdown-menu > li > span { + display: block; + padding: 4px 15px; + } + + .navbar-inverse .nav-collapse .dropdown-menu > li > span { + color: @navbarInverseLinkColor; + } + + .nav-collapse .nav > li > a.dropdown-toggle { + background-color: rgba(255, 255, 255, 0.07); + font-size: 12px; + font-weight: bold; + color: @grayLighter; + text-transform: uppercase; + padding-left: 15px; + } + + .nav-collapse .nav li a { + margin-bottom: 0; + border-top: 1px solid rgba(255, 255, 255, 0.25); + border-bottom: 1px solid rgba(0, 0, 0, 0.5); + } + + .nav-collapse .nav li ul li ul.dropdown-menu, + .nav-collapse .nav li ul li:hover ul.dropdown-menu, + .nav-collapse .caret { + display: none !important; + } + + .nav-collapse .nav > li > a, + .nav-collapse .dropdown-menu a { + font-size: 15px; + font-weight: normal; + color: @white; + .border-radius(0); + } + + .navbar .nav-collapse .nav > li > .dropdown-menu::before, + .navbar .nav-collapse .nav > li > .dropdown-menu::after, + .navbar .nav-collapse .dropdown-submenu > a::after { + display: none; + } + + .nav-collapse .dropdown-menu li + li a { + margin-bottom: 0; + } +} \ No newline at end of file diff --git a/Sites/pages/administrator/templates/isis/less/blocks/_quickicons.less b/Sites/pages/administrator/templates/isis/less/blocks/_quickicons.less new file mode 100644 index 00000000..9843de84 --- /dev/null +++ b/Sites/pages/administrator/templates/isis/less/blocks/_quickicons.less @@ -0,0 +1,27 @@ +// Quick-icons + +.quick-icons { + font-size: 14px; + margin-bottom: 20px; + .nav-header { + margin: 12px 0 5px; + font-size: 13px; + &:first-child { + margin: 0 0 5px; + } + } + [class^="icon-"], + [class*=" icon-"] { + margin-right: 9px; + &:before { + font-size: 16px; + margin-bottom: 20px; + line-height: 18px; + } + } +} + +html[dir=rtl] .quick-icons .nav-list [class^="icon-"], html[dir=rtl] .quick-icons .nav-list [class*=" icon-"] { + margin-left: 9px; + margin-right: 0; +} diff --git a/Sites/pages/administrator/templates/isis/less/blocks/_sidebar.less b/Sites/pages/administrator/templates/isis/less/blocks/_sidebar.less new file mode 100644 index 00000000..d5fc72de --- /dev/null +++ b/Sites/pages/administrator/templates/isis/less/blocks/_sidebar.less @@ -0,0 +1,150 @@ +// Sidebar + +.sidebar-nav .nav-list { + padding-left: 25px; + padding-right: 25px; +} + +.sidebar-nav .nav-list > li > a { + color: #555; + padding: 3px 25px; + margin-left: -26px; + margin-right: -26px; +} + +.sidebar-nav .nav-list > li.active > a { + color: #fff; + margin-right: -26px; +} +.sidebar-nav .nav-list > li > a:focus, +.sidebar-nav .nav-list > li > a:hover { + text-decoration: none; + color: #fff; + background-color: #2d6ca2; + text-shadow: none; +} + +/* For collapsible sidebar */ +.j-sidebar-container { + position: absolute; + display: block; + left: -16.5%; + width: 16.5%; + margin: -18px 0 0 -1px; + padding-top: 28px; + padding-bottom: 40px; + clear: both; + background-color: @wellBackground; + border-bottom: 1px solid darken(@wellBackground, 7%); + border-right: 1px solid darken(@wellBackground, 7%); + .border-radius(0 0 @baseBorderRadius 0); + &.j-sidebar-hidden { + left: -16.5%; + } + &.j-sidebar-visible { + left: 0; + } + .filter-select { + padding: 0 14px; + } +} + +.j-toggle-sidebar-header { + h3 { + font-weight: normal; + padding: 0 15px; + } +} + +.j-toggle-button-wrapper { + position: absolute; + display: block; + top: 7px; + padding: 0; + &.j-toggle-hidden { + right: -24px; + } + &.j-toggle-visible { + right: 7px; + } +} + +.j-toggle-sidebar-button { + font-size: 16px; + color: @linkColor; + text-decoration: none; + cursor: pointer; + &:hover { + color: @linkColorHover; + } +} + +#system-message-container, +#j-main-container { + padding: 0 0 0 5px; + min-height: 0; +} + +#system-message-container.j-toggle-main, +#j-main-container.j-toggle-main, +#system-debug.j-toggle-main { + float: right; +} + +@media (min-width: @md) { + .j-toggle-transition { + .transition(all 0.3s ease); + } +} + +@media (max-width: @lg-max) { + .j-toggle-button-wrapper.j-toggle-hidden { + right: -20px; + } +} + +@media (max-width: @md-max) { + .j-sidebar-container { + position: relative; + width: 100%; + margin: 0 0 20px 0; + padding: 0; + background: transparent; + border-right: 0; + border-bottom: 0; + } + + .j-sidebar-container.j-sidebar-hidden { + margin-left: 16.5%; + } + + .j-sidebar-container.j-sidebar-visible { + margin-left: 0; + } + + .j-toggle-sidebar-header, + .j-toggle-button-wrapper { + display: none; + } + + .view-login { + select { + width: 232px; + } + } +} + +@media (max-width: 420px) { + .j-sidebar-container { + margin: 0; + } + + .view-login { + .input-medium { + width: 180px; + } + select { + width: 232px + } + } +} \ No newline at end of file diff --git a/Sites/pages/administrator/templates/isis/less/blocks/_status.less b/Sites/pages/administrator/templates/isis/less/blocks/_status.less new file mode 100644 index 00000000..11945092 --- /dev/null +++ b/Sites/pages/administrator/templates/isis/less/blocks/_status.less @@ -0,0 +1,46 @@ +// Status + +#status { + background: #ebebeb; + border-top: 1px solid #dedede; + padding: 4px 10px; + .box-shadow(~"0 0 3px rgba(0, 0, 0, 0.08)"); + color: #626262; + + .btn-group { + margin: 0; + } + .btn-group.separator:after { + content: ' '; + display: block; + float: left; + background: #ADADAD; + margin: 0 10px; + height: 15px; + width: 1px; + } + .btn-toolbar, p { + margin: 0px; + } + .btn-toolbar, .btn-group { + font-size: 12px; + } + a { + color: #626262; + } + .badge { + margin-right: .25em; + } +} +/* Status Module in top position */ +#status.status-top { + background: @headerBackground; + .box-shadow(~"0px 1px 0px rgba(255, 255, 255, 0.2) inset, 0px -1px 0px rgba(0, 0, 0, 0.3) inset, 0px -1px 0px rgba(0, 0, 0, 0.3)"); + border-top: 0; + color: @navbarInverseText; + padding: 2px 20px 6px 20px; + + a { + color: @navbarInverseLinkColor; + } +} \ No newline at end of file diff --git a/Sites/pages/administrator/templates/isis/less/blocks/_tables.less b/Sites/pages/administrator/templates/isis/less/blocks/_tables.less new file mode 100644 index 00000000..7ca893a5 --- /dev/null +++ b/Sites/pages/administrator/templates/isis/less/blocks/_tables.less @@ -0,0 +1,74 @@ +// Tables + +@media (max-width: @sm-max) { + + .pagination a { + padding: 5px; + } + + .btn-group.divider, + .header .row-fluid .span3, + .header .row-fluid .span7 { + display: none; + } + + .navbar .btn { + margin: 0; + } + + .btn-subhead { + display: block; + margin: 10px 0; + } + + .subhead-collapse.collapse { + height: 0; + overflow: hidden; + } + + .btn-toolbar .btn-wrapper { + display: block; + margin:0px 10px 5px 10px; + } + + .btn-toolbar .btn-wrapper .btn { + width: 100% !important; + } + + .subhead { + background: none repeat scroll 0 0 transparent; + border-bottom: 0 solid darken(@wellBackground, 7%); + } + + .btn-group + .btn-group { + margin-left: 10px; + } + + .login .chzn-single { + width: 222px !important; + } + + .login .chzn-container, + .login .chzn-drop { + width: 230px !important; + } + #toolbar [class^="icon-"], #toolbar [class*=" icon-"] { + background-color: transparent; + border-right: medium none; + width: 10px; + } +} + +/* Tables */ +table label { + margin: 0; +} + +td.has-context { + // Fixes difference in height between normal and hover on cell with context + height: 23px; +} + +td.nowrap.has-context { + width: 45%; +} \ No newline at end of file diff --git a/Sites/pages/administrator/templates/isis/less/blocks/_toolbar.less b/Sites/pages/administrator/templates/isis/less/blocks/_toolbar.less new file mode 100644 index 00000000..8d1f3617 --- /dev/null +++ b/Sites/pages/administrator/templates/isis/less/blocks/_toolbar.less @@ -0,0 +1,165 @@ +// Toolbar + +/* Subhead */ +.subhead { + background: @wellBackground; + border-bottom: 1px solid darken(@wellBackground, 7%); + color: #0C192E; + text-shadow: 0 1px 0 #FFF; + margin-bottom: 10px; + min-height: 51px; +} + +.subhead-collapse { + margin-bottom: 19px; +} + +.subhead-collapse.collapse { + height: auto; + overflow: visible; +} + +.btn-toolbar { + margin-bottom: 5px; + .btn-wrapper { + display: inline-block; + margin: 0 0 8px 5px; + } +} + +.subhead-fixed { + position: fixed; + width: 100%; + top: 30px; + z-index: 100; +} +@media (max-width: @md-max) { + /* Fix ios scrolling inside bootstrap modals */ + body { + -webkit-overflow-scrolling: touch; + } + .subhead { + margin-left: -20px; + margin-right: -20px; + padding-left: 10px; + padding-right: 10px; + } +} + +.subhead h1 { + font-size: 17px; + font-weight: normal; + margin-left: 10px; + margin-top: 6px; +} + +/* Toolbar */ +#toolbar { + margin-bottom: 2px; + margin-top: 12px; + .btn { + line-height: 24px; + margin-right: 4px; + padding: 0 10px; + } + .btn-success { + min-width: 148px; + } + .btn-primary, + .btn-warning, + .btn-danger, + .btn-success, + .btn-info, + .btn-inverse { + [class^="icon-"], [class*=" icon-"] { + background-color: transparent; + border-right: 0; + border-left: 0; + width: 16px; + margin-left: 0; + margin-right: 0; + } + } + #toolbar-options, #toolbar-help { + float: right; + } + [class^="icon-"], [class*=" icon-"] { + background-color: @btnBackgroundHighlight; + border-radius: 3px 0 0 3px; + border-right: 1px solid @btnBorder; + height: auto; + line-height: inherit; + margin: 0 6px 0 -10px; + opacity: 1; + text-shadow: none; + width: 28px; + z-index: -1; + } + iframe .btn-group .btn { + margin-left: -1px !important; + } +} +html[dir=rtl] #toolbar #toolbar-options, +html[dir=rtl] #toolbar #toolbar-help { + float: left; +} + +@media (max-width: @md-max) { + .subhead-fixed { + position: static; + width: auto; + } +} + +/* Subhead (toolbar) Collapse Button */ +.btn-subhead { + display: none; +} +@media (min-width: @sm) { + #filter-bar { + // Fix for Firefox + height: 29px; + } +} + +@media (max-width: @sm-max) { + .navbar .btn { + margin: 0; + } + + .btn-subhead { + display: block; + margin: 10px 0; + } + + .subhead-collapse.collapse { + height: 0; + overflow: hidden; + } + + .btn-toolbar .btn-wrapper { + display: block; + margin:0px 10px 5px 10px; + } + + .btn-toolbar .btn-wrapper .btn { + width: 100% !important; + } + + .subhead { + background: none repeat scroll 0 0 transparent; + border-bottom: 0 solid darken(@wellBackground, 7%); + } + + #toolbar [class^="icon-"], #toolbar [class*=" icon-"] { + background-color: transparent; + border-right: medium none; + width: 10px; + } +} + +@media (max-width: @xs-max) { + .view-login .navbar-fixed-bottom { + display: none; + } +} diff --git a/Sites/pages/administrator/templates/isis/less/blocks/_treeselect.less b/Sites/pages/administrator/templates/isis/less/blocks/_treeselect.less new file mode 100644 index 00000000..c3ee4b36 --- /dev/null +++ b/Sites/pages/administrator/templates/isis/less/blocks/_treeselect.less @@ -0,0 +1,85 @@ +// Tree Select + +ul.treeselect, +ul.treeselect li { + margin: 0; + padding: 0; +} + +ul.treeselect { + margin-top: 8px; +} + +ul.treeselect li { + padding: 2px 10px 2px; + list-style: none; +} + +ul.treeselect i.treeselect-toggle { + line-height: 18px; +} + +ul.treeselect label { + font-size: 1em; + margin-left: 8px; +} + +ul.treeselect label.nav-header { + padding: 0; +} + +ul.treeselect input { + margin: 2px 0 0 8px; +} + +ul.treeselect .treeselect-menu { + margin: 0 6px; +} + +ul.treeselect ul.dropdown-menu { + margin: 0; +} + +ul.treeselect ul.dropdown-menu li { + padding: 0 5px; + border: none; +} + +.tree-holder { + .folder-url, .file { + position: relative; + background-color: #fefefe; + margin-bottom: 4px; + padding: 0 10px; + line-height: 32px; + border: 1px solid rgba(0, 0, 0, 0.08); + + } + .folder-url, .folder-url:hover, .folder-url:focus { + font-weight: bold; + background-color: #f5f5f5; + color: @linkColor; + } + .active { + background-color: @linkColor; + color: #fff; + box-shadow: -3px 0 0 #36a2ff !important; + &.folder-url { + background-color: #f5f5f5; + color: @linkColor; + } + &.file:hover { + background-color: #3071a9; + } + } + ul { + ul { + box-shadow: -3px 0 0 rgba(0, 0, 0, 0.08); + padding-right: 0; + .folder-url, .file { + box-shadow: -3px 0 0 @linkColor; + border-left: 0; + } + } + } +} diff --git a/Sites/pages/administrator/templates/isis/less/blocks/_utility-classes.less b/Sites/pages/administrator/templates/isis/less/blocks/_utility-classes.less new file mode 100644 index 00000000..72eb5dff --- /dev/null +++ b/Sites/pages/administrator/templates/isis/less/blocks/_utility-classes.less @@ -0,0 +1,13 @@ +// Utility Classes + +.break-word { + word-break: break-all; + word-wrap: break-word; +} + +.disabled { + cursor: default; + background-image: none; + .opacity(65); + .box-shadow(none); +} diff --git a/Sites/pages/administrator/templates/isis/less/bootstrap/button-groups.less b/Sites/pages/administrator/templates/isis/less/bootstrap/button-groups.less new file mode 100644 index 00000000..c861628c --- /dev/null +++ b/Sites/pages/administrator/templates/isis/less/bootstrap/button-groups.less @@ -0,0 +1,239 @@ +// +// Button groups +// -------------------------------------------------- + + +// Make the div behave like a button +.btn-group { + position: relative; + display: inline-block; + .ie7-inline-block(); + font-size: 0; // remove as part 1 of font-size inline-block hack + vertical-align: middle; // match .btn alignment given font-size hack above + white-space: nowrap; // prevent buttons from wrapping when in tight spaces (e.g., the table on the tests page) + .ie7-restore-left-whitespace(); + .btn + .btn { + margin-left: -1px; + } +} + +// Space out series of button groups +.btn-group + .btn-group { + margin-left: 5px; +} + +// Optional: Group multiple button groups together for a toolbar +.btn-toolbar { + font-size: 0; // Hack to remove whitespace that results from using inline-block + margin-top: @baseLineHeight / 2; + margin-bottom: @baseLineHeight / 2; + > .btn + .btn, + > .btn-group + .btn, + > .btn + .btn-group { + margin-left: 5px; + } +} + +// Float them, remove border radius, then re-add to first and last elements +.btn-group > .btn { + position: relative; + .border-radius(0); +} +.btn-group > .btn + .btn { + // margin-left: -1px; +} +.btn-group > .btn-micro { + margin-left: -1px; +} +.btn-group > .btn, +.btn-group > .dropdown-menu, +.btn-group > .popover { + font-size: @baseFontSize; // redeclare as part 2 of font-size inline-block hack +} + +// Reset fonts for other sizes +.btn-group > .btn-mini { + font-size: @fontSizeMini; +} +.btn-group > .btn-small { + font-size: @fontSizeSmall; +} +.btn-group > .btn-large { + font-size: @fontSizeLarge; +} + +// Set corners individual because sometimes a single button can be in a .btn-group and we need :first-child and :last-child to both match +.btn-group > .btn:first-child { + margin-left: 0; + .border-top-left-radius(@baseBorderRadius); + .border-bottom-left-radius(@baseBorderRadius); +} +// Need .dropdown-toggle since :last-child doesn't apply given a .dropdown-menu immediately after it +.btn-group > .btn:last-child, +.btn-group > .dropdown-toggle { + .border-top-right-radius(@baseBorderRadius); + .border-bottom-right-radius(@baseBorderRadius); +} +// Reset corners for large buttons +.btn-group > .btn.large:first-child { + margin-left: 0; + .border-top-left-radius(@borderRadiusLarge); + .border-bottom-left-radius(@borderRadiusLarge); +} +.btn-group > .btn.large:last-child, +.btn-group > .large.dropdown-toggle { + .border-top-right-radius(@borderRadiusLarge); + .border-bottom-right-radius(@borderRadiusLarge); +} + +// On hover/focus/active, bring the proper btn to front +.btn-group > .btn:hover, +.btn-group > .btn:focus, +.btn-group > .btn:active, +.btn-group > .btn.active { + z-index: 2; +} + +// On active and open, don't show outline +.btn-group .dropdown-toggle:active, +.btn-group.open .dropdown-toggle { + outline: 0; +} + + + +// Split button dropdowns +// ---------------------- + +// Give the line between buttons some depth +.btn-group > .btn + .dropdown-toggle { + padding-left: 8px; + padding-right: 8px; + *padding-top: 5px; + *padding-bottom: 5px; +} +.btn-group > .btn-mini + .dropdown-toggle { + padding-left: 5px; + padding-right: 5px; + *padding-top: 2px; + *padding-bottom: 2px; +} +.btn-group > .btn-small + .dropdown-toggle { + *padding-top: 5px; + *padding-bottom: 4px; +} +.btn-group > .btn-large + .dropdown-toggle { + padding-left: 12px; + padding-right: 12px; + *padding-top: 7px; + *padding-bottom: 7px; +} + +.btn-group.open { + + // The clickable button for toggling the menu + // Remove the gradient and set the same inset shadow as the :active state + .dropdown-toggle { + background-image: none; + } + + // Keep the hover's background when dropdown is open + .btn.dropdown-toggle { + background-color: @btnBackgroundHighlight; + } + .btn-primary.dropdown-toggle { + background-color: @btnPrimaryBackgroundHighlight; + } + .btn-warning.dropdown-toggle { + background-color: @btnWarningBackgroundHighlight; + } + .btn-danger.dropdown-toggle { + background-color: @btnDangerBackgroundHighlight; + } + .btn-success.dropdown-toggle { + background-color: @btnSuccessBackgroundHighlight; + } + .btn-info.dropdown-toggle { + background-color: @btnInfoBackgroundHighlight; + } + .btn-inverse.dropdown-toggle { + background-color: @btnInverseBackgroundHighlight; + } +} + + +// Reposition the caret +.btn .caret { + margin-top: 8px; + margin-left: 0; +} +// Carets in other button sizes +.btn-large .caret { + margin-top: 6px; +} +.btn-large .caret { + border-left-width: 5px; + border-right-width: 5px; + border-top-width: 5px; +} +.btn-mini .caret, +.btn-small .caret { + margin-top: 8px; +} +// Upside down carets for .dropup +.dropup .btn-large .caret { + border-bottom-width: 5px; +} + + + +// Account for other colors +.btn-primary { + .caret { + border-top-color: @linkColorHover; + border-bottom-color: @linkColorHover; + } +} +.btn-warning, +.btn-danger, +.btn-info, +.btn-success, +.btn-inverse { + .caret { + border-top-color: @white; + border-bottom-color: @white; + } +} + + + +// Vertical button groups +// ---------------------- + +.btn-group-vertical { + display: inline-block; // makes buttons only take up the width they need + .ie7-inline-block(); +} +.btn-group-vertical > .btn { + display: block; + float: none; + max-width: 100%; + .border-radius(0); +} +.btn-group-vertical > .btn + .btn { + margin-left: 0; + margin-top: -1px; +} +.btn-group-vertical > .btn:first-child { + .border-radius(@baseBorderRadius @baseBorderRadius 0 0); +} +.btn-group-vertical > .btn:last-child { + .border-radius(0 0 @baseBorderRadius @baseBorderRadius); +} +.btn-group-vertical > .btn-large:first-child { + .border-radius(@borderRadiusLarge @borderRadiusLarge 0 0); +} +.btn-group-vertical > .btn-large:last-child { + .border-radius(0 0 @borderRadiusLarge @borderRadiusLarge); +} + diff --git a/Sites/pages/administrator/templates/isis/less/bootstrap/buttons.less b/Sites/pages/administrator/templates/isis/less/bootstrap/buttons.less new file mode 100644 index 00000000..6ee0c6db --- /dev/null +++ b/Sites/pages/administrator/templates/isis/less/bootstrap/buttons.less @@ -0,0 +1,285 @@ +// +// Buttons +// -------------------------------------------------- + + +// Base styles +// -------------------------------------------------- + +// Core +.btn { + display: inline-block; + .ie7-inline-block(); + padding: 4px 12px; + margin-bottom: 0; // For input.btn + font-size: @baseFontSize; + line-height: @baseLineHeight; + text-align: center; + vertical-align: middle; + cursor: pointer; + background-color: @btnBackground; + color: #333; + // .buttonBackground(@btnBackground, @btnBackgroundHighlight, @grayDark, 0 1px 1px rgba(255,255,255,.75)); + border: 1px solid @btnBorder; + .border-radius(@baseBorderRadius); + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); + &:hover, + &:focus { + background-color: @btnBackgroundHighlight; + text-decoration: none; + text-shadow: none; + } + + // Focus state for keyboard and accessibility + &:focus { + .tab-focus(); + } + + // Active state + &.active, + &:active { + background-image: none; + outline: 0; + // .box-shadow(~"inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05)"); + } + + // Disabled state + &.disabled, + &[disabled] { + cursor: default; + background-image: none; + .opacity(65); + .box-shadow(none); + } + +} + + + +// Button Sizes +// -------------------------------------------------- + +// Large +.btn-large { + padding: @paddingLarge; + font-size: @fontSizeLarge; + .border-radius(@borderRadiusLarge); +} +.btn-large [class^="icon-"], +.btn-large [class*=" icon-"] { + margin-top: 4px; +} + +// Small +.btn-small { + padding: @paddingSmall; + font-size: @fontSizeSmall; + .border-radius(@borderRadiusSmall); +} +.btn-small [class^="icon-"], +.btn-small [class*=" icon-"] { + margin-top: 0; +} +.btn-mini [class^="icon-"], +.btn-mini [class*=" icon-"] { + margin-top: -1px; +} + +// Mini +.btn-mini { + padding: @paddingMini; + font-size: @fontSizeMini; + .border-radius(@borderRadiusSmall); +} + + +// Block button +// ------------------------- + +.btn-block { + display: block; + width: 100%; + padding-left: 0; + padding-right: 0; + .box-sizing(border-box); +} + +// Vertically space out multiple block buttons +.btn-block + .btn-block { + margin-top: 5px; +} + +// Specificity overrides +input[type="submit"], +input[type="reset"], +input[type="button"] { + &.btn-block { + width: 100%; + } +} + + + +// Alternate buttons +// -------------------------------------------------- + +.btn-primary, +.btn-warning, +.btn-danger, +.btn-success, +.btn-info, +.btn-inverse { + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); +} + +// Provide *some* extra contrast for those who can get it +.btn-primary.active, +.btn-warning.active, +.btn-danger.active, +.btn-success.active, +.btn-info.active, +.btn-inverse.active { + // color: rgba(255,255,255,.75); +} + +// Set the backgrounds +// ------------------------- +.btn-primary { + border: 1px solid @btnPrimaryBackgroundHighlight; + border: 1px solid rgba(0, 0, 0, 0.2); + color: #fff; + background-color: @btnPrimaryBackground; + &:hover, + &:focus { + background-color: darken(@btnPrimaryBackground, 15%); + color: #fff; + text-decoration: none; + } +} +// Warning appears are orange +.btn-warning { + border: 1px solid @btnWarningBackground; + border: 1px solid rgba(0, 0, 0, 0.2); + color: #fff; + background-color: @btnWarningBackground; + &:hover, + &:focus { + background-color: darken(@btnWarningBackground, 15%); + color: #fff; + text-decoration: none; + text-shadow: none; + } +} +// Danger and error appear as red +.btn-danger { + border: 1px solid @btnDangerBackground; + border: 1px solid rgba(0, 0, 0, 0.2); + color: #fff; + background-color: @btnDangerBackground; + &:hover, + &:focus { + background-color: darken(@btnDangerBackground, 15%); + color: #fff; + text-decoration: none; + } +} +// Success appears as green +.btn-success { + border: 1px solid @btnSuccessBackgroundHighlight; + border: 1px solid rgba(0, 0, 0, 0.2); + color: #fff; + background-color: @btnSuccessBackground; + &:hover, + &:focus { + background-color: darken(@btnSuccessBackground, 15%); + color: #fff; + text-decoration: none; + } +} +// Info appears as a neutral blue +.btn-info { + border: 1px solid @btnInfoBackground; + border: 1px solid rgba(0, 0, 0, 0.2); + color: #fff; + background-color: @btnInfoBackground; + &:hover, + &:focus { + background-color: darken(@btnInfoBackground, 15%); + color: #fff; + text-decoration: none; + } +} +// Inverse appears as dark gray +.btn-inverse { + border: 1px solid @btnInverseBackground; + border: 1px solid rgba(0, 0, 0, 0.2); + color: #fff; + background-color: @btnInverseBackground; + &:hover, + &:focus { + background-color: darken(@btnInverseBackground, 15%); + color: #fff; + text-decoration: none; + } +} + + +// Cross-browser Jank +// -------------------------------------------------- + +button.btn, +input[type="submit"].btn { + + // Firefox 3.6 only I believe + &::-moz-focus-inner { + padding: 0; + border: 0; + } + + // IE7 has some default padding on button controls + *padding-top: 3px; + *padding-bottom: 3px; + + &.btn-large { + *padding-top: 7px; + *padding-bottom: 7px; + } + &.btn-small { + *padding-top: 3px; + *padding-bottom: 3px; + } + &.btn-mini { + *padding-top: 1px; + *padding-bottom: 1px; + } +} + + +// Link buttons +// -------------------------------------------------- + +// Make a button look and behave like a link +.btn-link, +.btn-link:active, +.btn-link[disabled] { + background-color: transparent; + background-image: none; + .box-shadow(none); +} +.btn-link { + border-color: transparent; + cursor: pointer; + color: @linkColor; + .border-radius(0); +} +.btn-link:hover, +.btn-link:focus { + color: @linkColorHover; + text-decoration: underline; + background-color: transparent; +} +.btn-link[disabled]:hover, +.btn-link[disabled]:focus { + color: @grayDark; + text-decoration: none; +} diff --git a/Sites/pages/administrator/templates/isis/less/bootstrap/mixins.less b/Sites/pages/administrator/templates/isis/less/bootstrap/mixins.less new file mode 100644 index 00000000..5ecf2cea --- /dev/null +++ b/Sites/pages/administrator/templates/isis/less/bootstrap/mixins.less @@ -0,0 +1,708 @@ +// +// Mixins +// -------------------------------------------------- + + +// UTILITY MIXINS +// -------------------------------------------------- + +// Clearfix +// -------- +// For clearing floats like a boss h5bp.com/q +.clearfix { + *zoom: 1; + &:before, + &:after { + display: table; + content: ""; + // Fixes Opera/contenteditable bug: + // http://nicolasgallagher.com/micro-clearfix-hack/#comment-36952 + line-height: 0; + } + &:after { + clear: both; + } +} + +// Webkit-style focus +// ------------------ +.tab-focus() { + // Default + outline: thin dotted #333; + // Webkit + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} + +// Center-align a block level element +// ---------------------------------- +.center-block() { + display: block; + margin-left: auto; + margin-right: auto; +} + +// IE7 inline-block +// ---------------- +.ie7-inline-block() { + *display: inline; /* IE7 inline-block hack */ + *zoom: 1; +} + +// IE7 likes to collapse whitespace on either side of the inline-block elements. +// Ems because we're attempting to match the width of a space character. Left +// version is for form buttons, which typically come after other elements, and +// right version is for icons, which come before. Applying both is ok, but it will +// mean that space between those elements will be .6em (~2 space characters) in IE7, +// instead of the 1 space in other browsers. +.ie7-restore-left-whitespace() { + *margin-left: .3em; + + &:first-child { + *margin-left: 0; + } +} + +.ie7-restore-right-whitespace() { + *margin-right: .3em; +} + +// Sizing shortcuts +// ------------------------- +.size(@height, @width) { + width: @width; + height: @height; +} +.square(@size) { + .size(@size, @size); +} + +// Placeholder text +// ------------------------- +.placeholder(@color: @placeholderText) { + &:-moz-placeholder { + color: @color; + } + &:-ms-input-placeholder { + color: @color; + } + &::-webkit-input-placeholder { + color: @color; + } +} + +// Text overflow +// ------------------------- +// Requires inline-block or block for proper styling +.text-overflow() { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +// CSS image replacement +// ------------------------- +// Source: https://github.com/h5bp/html5-boilerplate/commit/aa0396eae757 +.hide-text { + font: 0/0 a; + color: transparent; + text-shadow: none; + background-color: transparent; + border: 0; +} + + +// FONTS +// -------------------------------------------------- + +#font { + #family { + .serif() { + font-family: @serifFontFamily; + } + .sans-serif() { + font-family: @sansFontFamily; + } + .monospace() { + font-family: @monoFontFamily; + } + } + .shorthand(@size: @baseFontSize, @weight: normal, @lineHeight: @baseLineHeight) { + font-size: @size; + font-weight: @weight; + line-height: @lineHeight; + } + .serif(@size: @baseFontSize, @weight: normal, @lineHeight: @baseLineHeight) { + #font > #family > .serif; + #font > .shorthand(@size, @weight, @lineHeight); + } + .sans-serif(@size: @baseFontSize, @weight: normal, @lineHeight: @baseLineHeight) { + #font > #family > .sans-serif; + #font > .shorthand(@size, @weight, @lineHeight); + } + .monospace(@size: @baseFontSize, @weight: normal, @lineHeight: @baseLineHeight) { + #font > #family > .monospace; + #font > .shorthand(@size, @weight, @lineHeight); + } +} + + +// FORMS +// -------------------------------------------------- + +// Block level inputs +.input-block-level { + display: block; + width: 100%; + min-height: @inputHeight; // Make inputs at least the height of their button counterpart (base line-height + padding + border) + .box-sizing(border-box); // Makes inputs behave like true block-level elements +} + + + +// Mixin for form field states +.formFieldState(@textColor: #555, @borderColor: #ccc, @backgroundColor: #f5f5f5) { + // Set the text color + .control-label, + .help-block, + .help-inline { + color: @textColor; + } + // Style inputs accordingly + .checkbox, + .radio, + input, + select, + textarea { + color: @textColor; + } + input, + select, + textarea { + border-color: @borderColor; + //.box-shadow(inset 0 1px 1px rgba(0,0,0,.075)); // Redeclare so transitions work + &:focus { + border-color: darken(@borderColor, 10%); + @shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 6px lighten(@borderColor, 20%); + //.box-shadow(@shadow); + } + } + // Give a small background color for input-prepend/-append + .input-prepend .add-on, + .input-append .add-on { + color: @textColor; + background-color: @backgroundColor; + border-color: @textColor; + } +} + + + +// CSS3 PROPERTIES +// -------------------------------------------------- + +// Border Radius +.border-radius(@radius) { + -webkit-border-radius: @radius; + -moz-border-radius: @radius; + border-radius: @radius; +} + +// Single Corner Border Radius +.border-top-left-radius(@radius) { + -webkit-border-top-left-radius: @radius; + -moz-border-radius-topleft: @radius; + border-top-left-radius: @radius; +} +.border-top-right-radius(@radius) { + -webkit-border-top-right-radius: @radius; + -moz-border-radius-topright: @radius; + border-top-right-radius: @radius; +} +.border-bottom-right-radius(@radius) { + -webkit-border-bottom-right-radius: @radius; + -moz-border-radius-bottomright: @radius; + border-bottom-right-radius: @radius; +} +.border-bottom-left-radius(@radius) { + -webkit-border-bottom-left-radius: @radius; + -moz-border-radius-bottomleft: @radius; + border-bottom-left-radius: @radius; +} + +// Single Side Border Radius +.border-top-radius(@radius) { + .border-top-right-radius(@radius); + .border-top-left-radius(@radius); +} +.border-right-radius(@radius) { + .border-top-right-radius(@radius); + .border-bottom-right-radius(@radius); +} +.border-bottom-radius(@radius) { + .border-bottom-right-radius(@radius); + .border-bottom-left-radius(@radius); +} +.border-left-radius(@radius) { + .border-top-left-radius(@radius); + .border-bottom-left-radius(@radius); +} + +// Drop shadows +.box-shadow(@shadow) { + -webkit-box-shadow: @shadow; + -moz-box-shadow: @shadow; + box-shadow: @shadow; +} + +// Transitions +.transition(@transition) { + -webkit-transition: @transition; + -moz-transition: @transition; + -o-transition: @transition; + transition: @transition; +} +.transition-delay(@transition-delay) { + -webkit-transition-delay: @transition-delay; + -moz-transition-delay: @transition-delay; + -o-transition-delay: @transition-delay; + transition-delay: @transition-delay; +} +.transition-duration(@transition-duration) { + -webkit-transition-duration: @transition-duration; + -moz-transition-duration: @transition-duration; + -o-transition-duration: @transition-duration; + transition-duration: @transition-duration; +} + +// Transformations +.rotate(@degrees) { + -webkit-transform: rotate(@degrees); + -moz-transform: rotate(@degrees); + -ms-transform: rotate(@degrees); + -o-transform: rotate(@degrees); + transform: rotate(@degrees); +} +.scale(@ratio) { + -webkit-transform: scale(@ratio); + -moz-transform: scale(@ratio); + -ms-transform: scale(@ratio); + -o-transform: scale(@ratio); + transform: scale(@ratio); +} +.translate(@x, @y) { + -webkit-transform: translate(@x, @y); + -moz-transform: translate(@x, @y); + -ms-transform: translate(@x, @y); + -o-transform: translate(@x, @y); + transform: translate(@x, @y); +} +.skew(@x, @y) { + -webkit-transform: skew(@x, @y); + -moz-transform: skew(@x, @y); + -ms-transform: skewX(@x) skewY(@y); // See https://github.com/twitter/bootstrap/issues/4885 + -o-transform: skew(@x, @y); + transform: skew(@x, @y); + -webkit-backface-visibility: hidden; // See https://github.com/twitter/bootstrap/issues/5319 +} +.translate3d(@x, @y, @z) { + -webkit-transform: translate3d(@x, @y, @z); + -moz-transform: translate3d(@x, @y, @z); + -o-transform: translate3d(@x, @y, @z); + transform: translate3d(@x, @y, @z); +} + +// Backface visibility +// Prevent browsers from flickering when using CSS 3D transforms. +// Default value is `visible`, but can be changed to `hidden +// See git pull https://github.com/dannykeane/bootstrap.git backface-visibility for examples +.backface-visibility(@visibility){ + -webkit-backface-visibility: @visibility; + -moz-backface-visibility: @visibility; + backface-visibility: @visibility; +} + +// Background clipping +// Heads up: FF 3.6 and under need "padding" instead of "padding-box" +.background-clip(@clip) { + -webkit-background-clip: @clip; + -moz-background-clip: @clip; + background-clip: @clip; +} + +// Background sizing +.background-size(@size) { + -webkit-background-size: @size; + -moz-background-size: @size; + -o-background-size: @size; + background-size: @size; +} + + +// Box sizing +.box-sizing(@boxmodel) { + -webkit-box-sizing: @boxmodel; + -moz-box-sizing: @boxmodel; + box-sizing: @boxmodel; +} + +// User select +// For selecting text on the page +.user-select(@select) { + -webkit-user-select: @select; + -moz-user-select: @select; + -ms-user-select: @select; + -o-user-select: @select; + user-select: @select; +} + +// Resize anything +.resizable(@direction) { + resize: @direction; // Options: horizontal, vertical, both + overflow: auto; // Safari fix +} + +// CSS3 Content Columns +.content-columns(@columnCount, @columnGap: @gridGutterWidth) { + -webkit-column-count: @columnCount; + -moz-column-count: @columnCount; + column-count: @columnCount; + -webkit-column-gap: @columnGap; + -moz-column-gap: @columnGap; + column-gap: @columnGap; +} + +// Optional hyphenation +.hyphens(@mode: auto) { + word-wrap: break-word; + -webkit-hyphens: @mode; + -moz-hyphens: @mode; + -ms-hyphens: @mode; + -o-hyphens: @mode; + hyphens: @mode; +} + +// Opacity +.opacity(@opacity) { + opacity: @opacity / 100; + filter: ~"alpha(opacity=@{opacity})"; +} + + + +// BACKGROUNDS +// -------------------------------------------------- + +// Add an alphatransparency value to any background or border color (via Elyse Holladay) +#translucent { + .background(@color: @white, @alpha: 1) { + background-color: hsla(hue(@color), saturation(@color), lightness(@color), @alpha); + } + .border(@color: @white, @alpha: 1) { + border-color: hsla(hue(@color), saturation(@color), lightness(@color), @alpha); + .background-clip(padding-box); + } +} + +// Gradient Bar Colors for buttons and alerts +.gradientBar(@primaryColor, @secondaryColor, @textColor: #fff, @textShadow: 0 -1px 0 rgba(0,0,0,.25)) { + color: @textColor; + text-shadow: @textShadow; + #gradient > .vertical(@primaryColor, @secondaryColor); + border-color: @secondaryColor @secondaryColor darken(@secondaryColor, 15%); + // No idea why this is here, as it makes the border grey instead of the given colors + // border-color: rgba(0,0,0,.1) rgba(0,0,0,.1) fadein(rgba(0,0,0,.1), 15%); +} + +// Gradients +#gradient { + .horizontal(@startColor: #555, @endColor: #333) { + background-color: @endColor; + background-image: -moz-linear-gradient(left, @startColor, @endColor); // FF 3.6+ + background-image: -webkit-gradient(linear, 0 0, 100% 0, from(@startColor), to(@endColor)); // Safari 4+, Chrome 2+ + background-image: -webkit-linear-gradient(left, @startColor, @endColor); // Safari 5.1+, Chrome 10+ + background-image: -o-linear-gradient(left, @startColor, @endColor); // Opera 11.10 + background-image: linear-gradient(to right, @startColor, @endColor); // Standard, IE10 + background-repeat: repeat-x; + filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)",argb(@startColor),argb(@endColor))); // IE9 and down + } + .vertical(@startColor: #555, @endColor: #333) { + background-color: mix(@startColor, @endColor, 60%); + background-image: -moz-linear-gradient(top, @startColor, @endColor); // FF 3.6+ + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(@startColor), to(@endColor)); // Safari 4+, Chrome 2+ + background-image: -webkit-linear-gradient(top, @startColor, @endColor); // Safari 5.1+, Chrome 10+ + background-image: -o-linear-gradient(top, @startColor, @endColor); // Opera 11.10 + background-image: linear-gradient(to bottom, @startColor, @endColor); // Standard, IE10 + background-repeat: repeat-x; + filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)",argb(@startColor),argb(@endColor))); // IE9 and down + } + .directional(@startColor: #555, @endColor: #333, @deg: 45deg) { + background-color: @endColor; + background-repeat: repeat-x; + background-image: -moz-linear-gradient(@deg, @startColor, @endColor); // FF 3.6+ + background-image: -webkit-linear-gradient(@deg, @startColor, @endColor); // Safari 5.1+, Chrome 10+ + background-image: -o-linear-gradient(@deg, @startColor, @endColor); // Opera 11.10 + background-image: linear-gradient(@deg, @startColor, @endColor); // Standard, IE10 + } + .horizontal-three-colors(@startColor: #00b3ee, @midColor: #7a43b6, @colorStop: 50%, @endColor: #c3325f) { + background-color: mix(@midColor, @endColor, 80%); + background-image: -webkit-gradient(left, linear, 0 0, 0 100%, from(@startColor), color-stop(@colorStop, @midColor), to(@endColor)); + background-image: -webkit-linear-gradient(left, @startColor, @midColor @colorStop, @endColor); + background-image: -moz-linear-gradient(left, @startColor, @midColor @colorStop, @endColor); + background-image: -o-linear-gradient(left, @startColor, @midColor @colorStop, @endColor); + background-image: linear-gradient(to right, @startColor, @midColor @colorStop, @endColor); + background-repeat: no-repeat; + filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)",argb(@startColor),argb(@endColor))); // IE9 and down, gets no color-stop at all for proper fallback + } + + .vertical-three-colors(@startColor: #00b3ee, @midColor: #7a43b6, @colorStop: 50%, @endColor: #c3325f) { + background-color: mix(@midColor, @endColor, 80%); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(@startColor), color-stop(@colorStop, @midColor), to(@endColor)); + background-image: -webkit-linear-gradient(@startColor, @midColor @colorStop, @endColor); + background-image: -moz-linear-gradient(top, @startColor, @midColor @colorStop, @endColor); + background-image: -o-linear-gradient(@startColor, @midColor @colorStop, @endColor); + background-image: linear-gradient(@startColor, @midColor @colorStop, @endColor); + background-repeat: no-repeat; + filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)",argb(@startColor),argb(@endColor))); // IE9 and down, gets no color-stop at all for proper fallback + } + .radial(@innerColor: #555, @outerColor: #333) { + background-color: @outerColor; + background-image: -webkit-gradient(radial, center center, 0, center center, 460, from(@innerColor), to(@outerColor)); + background-image: -webkit-radial-gradient(circle, @innerColor, @outerColor); + background-image: -moz-radial-gradient(circle, @innerColor, @outerColor); + background-image: -o-radial-gradient(circle, @innerColor, @outerColor); + // > Joomla JUI + /* Joomla JUI NOTE: makes radial gradient IE 10+, also confirmed in Bootstrap, https://github.com/twbs/bootstrap/issues/7462 */ + background-image: radial-gradient(circle, @innerColor, @outerColor); + // < Joomla JUI + background-repeat: no-repeat; + } + .striped(@color: #555, @angle: 45deg) { + background-color: @color; + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(.25, rgba(255,255,255,.15)), color-stop(.25, transparent), color-stop(.5, transparent), color-stop(.5, rgba(255,255,255,.15)), color-stop(.75, rgba(255,255,255,.15)), color-stop(.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(@angle, rgba(255,255,255,.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,.15) 50%, rgba(255,255,255,.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(@angle, rgba(255,255,255,.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,.15) 50%, rgba(255,255,255,.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(@angle, rgba(255,255,255,.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,.15) 50%, rgba(255,255,255,.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(@angle, rgba(255,255,255,.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,.15) 50%, rgba(255,255,255,.15) 75%, transparent 75%, transparent); + } +} +// Reset filters for IE +.reset-filter() { + filter: e(%("progid:DXImageTransform.Microsoft.gradient(enabled = false)")); +} + + + +// COMPONENT MIXINS +// -------------------------------------------------- + +// Horizontal dividers +// ------------------------- +// Dividers (basically an hr) within dropdowns and nav lists +.nav-divider(@top: #e5e5e5, @bottom: @white) { + // IE7 needs a set width since we gave a height. Restricting just + // to IE7 to keep the 1px left/right space in other browsers. + // It is unclear where IE is getting the extra space that we need + // to negative-margin away, but so it goes. + *width: 100%; + height: 1px; + margin: ((@baseLineHeight / 2) - 1) 1px; // 8px 1px + *margin: -5px 0 5px; + overflow: hidden; + background-color: @top; + border-bottom: 1px solid @bottom; +} + +// Button backgrounds +// ------------------ +.buttonBackground(@startColor, @endColor, @textColor: #fff, @textShadow: 0 -1px 0 rgba(0,0,0,.25)) { + // gradientBar will set the background to a pleasing blend of these, to support IE<=9 + //.gradientBar(@startColor, @endColor, @textColor, @textShadow); + background-color: @startColor; + *background-color: @startColor; /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + //.reset-filter(); + + // in these cases the gradient won't cover the background, so we override + &:hover, &:focus, &:active, &.active, &.disabled, &[disabled] { + color: @textColor; + background-color: darken(@endColor, 5%); + *background-color: darken(@endColor, 5%); + } + + // IE 7 + 8 can't handle box-shadow to show active, so we darken a bit ourselves + &:active, + &.active { + background-color: @startColor; + } +} + +// Navbar vertical align +// ------------------------- +// Vertically center elements in the navbar. +// Example: an element has a height of 30px, so write out `.navbarVerticalAlign(30px);` to calculate the appropriate top margin. +.navbarVerticalAlign(@elementHeight) { + margin-top: (@navbarHeight - @elementHeight) / 2; +} + + + +// Grid System +// ----------- + +// Centered container element +.container-fixed() { + margin-right: auto; + margin-left: auto; + .clearfix(); +} + +// Table columns +.tableColumns(@columnSpan: 1) { + float: none; // undo default grid column styles + width: ((@gridColumnWidth) * @columnSpan) + (@gridGutterWidth * (@columnSpan - 1)) - 16; // 16 is total padding on left and right of table cells + margin-left: 0; // undo default grid column styles +} + +// Make a Grid +// Use .makeRow and .makeColumn to assign semantic layouts grid system behavior +.makeRow() { + margin-left: @gridGutterWidth * -1; + .clearfix(); +} +.makeColumn(@columns: 1, @offset: 0) { + float: left; + margin-left: (@gridColumnWidth * @offset) + (@gridGutterWidth * (@offset - 1)) + (@gridGutterWidth * 2); + width: (@gridColumnWidth * @columns) + (@gridGutterWidth * (@columns - 1)); +} + +// The Grid +#grid { + + .core (@gridColumnWidth, @gridGutterWidth) { + + .spanX (@index) when (@index > 0) { + .span@{index} { .span(@index); } + .spanX(@index - 1); + } + .spanX (0) {} + + .offsetX (@index) when (@index > 0) { + .offset@{index} { .offset(@index); } + .offsetX(@index - 1); + } + .offsetX (0) {} + + .offset (@columns) { + margin-left: (@gridColumnWidth * @columns) + (@gridGutterWidth * (@columns + 1)); + } + + .span (@columns) { + width: (@gridColumnWidth * @columns) + (@gridGutterWidth * (@columns - 1)); + } + + .row { + margin-left: @gridGutterWidth * -1; + .clearfix(); + } + + [class*="span"] { + float: left; + min-height: 1px; // prevent collapsing columns + margin-left: @gridGutterWidth; + } + + // Set the container width, and override it for fixed navbars in media queries + .container, + .navbar-static-top .container, + .navbar-fixed-top .container, + .navbar-fixed-bottom .container { .span(@gridColumns); } + + // generate .spanX and .offsetX + .spanX (@gridColumns); + .offsetX (@gridColumns); + + } + + .fluid (@fluidGridColumnWidth, @fluidGridGutterWidth) { + + .spanX (@index) when (@index > 0) { + .span@{index} { .span(@index); } + .spanX(@index - 1); + } + .spanX (0) {} + + .offsetX (@index) when (@index > 0) { + .offset@{index} { .offset(@index); } + .offset@{index}:first-child { .offsetFirstChild(@index); } + .offsetX(@index - 1); + } + .offsetX (0) {} + + .offset (@columns) { + margin-left: (@fluidGridColumnWidth * @columns) + (@fluidGridGutterWidth * (@columns - 1)) + (@fluidGridGutterWidth*2); + *margin-left: (@fluidGridColumnWidth * @columns) + (@fluidGridGutterWidth * (@columns - 1)) - (.5 / @gridRowWidth * 100 * 1%) + (@fluidGridGutterWidth*2) - (.5 / @gridRowWidth * 100 * 1%); + } + + .offsetFirstChild (@columns) { + margin-left: (@fluidGridColumnWidth * @columns) + (@fluidGridGutterWidth * (@columns - 1)) + (@fluidGridGutterWidth); + *margin-left: (@fluidGridColumnWidth * @columns) + (@fluidGridGutterWidth * (@columns - 1)) - (.5 / @gridRowWidth * 100 * 1%) + @fluidGridGutterWidth - (.5 / @gridRowWidth * 100 * 1%); + } + + .span (@columns) { + width: (@fluidGridColumnWidth * @columns) + (@fluidGridGutterWidth * (@columns - 1)); + *width: (@fluidGridColumnWidth * @columns) + (@fluidGridGutterWidth * (@columns - 1)) - (.5 / @gridRowWidth * 100 * 1%); + } + + .row-fluid { + width: 100%; + .clearfix(); + [class*="span"] { + .input-block-level(); + float: left; + margin-left: @fluidGridGutterWidth; + *margin-left: @fluidGridGutterWidth - (.5 / @gridRowWidth * 100 * 1%); + } + [class*="span"]:first-child { + margin-left: 0; + } + + // Space grid-sized controls properly if multiple per line + .controls-row [class*="span"] + [class*="span"] { + margin-left: @fluidGridGutterWidth; + } + + // generate .spanX and .offsetX + .spanX (@gridColumns); + .offsetX (@gridColumns); + } + + } + + .input(@gridColumnWidth, @gridGutterWidth) { + + .spanX (@index) when (@index > 0) { + input.span@{index}, textarea.span@{index}, .uneditable-input.span@{index} { .span(@index); } + .spanX(@index - 1); + } + .spanX (0) {} + + .span(@columns) { + width: ((@gridColumnWidth) * @columns) + (@gridGutterWidth * (@columns - 1)) - 14; + } + + input, + textarea, + .uneditable-input { + margin-left: 0; // override margin-left from core grid system + } + + // Space grid-sized controls properly if multiple per line + .controls-row [class*="span"] + [class*="span"] { + margin-left: @gridGutterWidth; + } + + // generate .spanX + .spanX (@gridColumns); + + } +} diff --git a/Sites/pages/administrator/templates/isis/less/bootstrap/responsive-1200px-min.less b/Sites/pages/administrator/templates/isis/less/bootstrap/responsive-1200px-min.less new file mode 100644 index 00000000..cd7d2812 --- /dev/null +++ b/Sites/pages/administrator/templates/isis/less/bootstrap/responsive-1200px-min.less @@ -0,0 +1,201 @@ +// +// Responsive: Large desktop and up +// -------------------------------------------------- + + +@media (min-width: 1200px) { + + // Fixed grid + #grid > .core(@gridColumnWidth1200, @gridGutterWidth1200); + + // Fluid grid + .row-fluid { + width: 100%; + *zoom: 1; + } + .row-fluid:before, + .row-fluid:after { + display: table; + content: ""; + line-height: 0; + } + .row-fluid:after { + clear: both; + } + .row-fluid [class*="span"] { + display: block; + width: 100%; + min-height: 28px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + float: left; + margin-left: 2.76243094%; + *margin-left: 2.70923945%; + } + .row-fluid [class*="span"]:first-child { + margin-left: 0; + } + .row-fluid .controls-row [class*="span"] + [class*="span"] { + margin-left: 2.76243094%; + } + .row-fluid .span12 { + width: 100%; + *width: 99.94680851%; + } + .row-fluid .span11 { + width: 91.43646409%; + *width: 91.3832726%; + } + .row-fluid .span10 { + width: 82.87292818%; + *width: 82.81973669%; + } + .row-fluid .span9 { + width: 74.30939227%; + *width: 74.25620078%; + } + .row-fluid .span8 { + width: 65.74585635%; + *width: 65.69266486%; + } + .row-fluid .span7 { + width: 57.18232044%; + *width: 57.12912895%; + } + .row-fluid .span6 { + width: 48.61878453%; + *width: 48.56559304%; + } + .row-fluid .span5 { + width: 40.05524862%; + *width: 40.00205713%; + } + .row-fluid .span4 { + width: 31.49171271%; + *width: 31.43852122%; + } + .row-fluid .span3 { + width: 22.9281768%; + *width: 22.87498531%; + } + .row-fluid .span2 { + width: 14.36464088%; + *width: 14.31144939%; + } + .row-fluid .span1 { + width: 5.80110497%; + *width: 5.74791348%; + } + .row-fluid .offset12 { + margin-left: 105.52486188%; + *margin-left: 105.4184789%; + } + .row-fluid .offset12:first-child { + margin-left: 102.76243094%; + *margin-left: 102.65604796%; + } + .row-fluid .offset11 { + margin-left: 96.96132597%; + *margin-left: 96.85494299%; + } + .row-fluid .offset11:first-child { + margin-left: 94.19889503%; + *margin-left: 94.09251205%; + } + .row-fluid .offset10 { + margin-left: 88.39779006%; + *margin-left: 88.29140708%; + } + .row-fluid .offset10:first-child { + margin-left: 85.63535912%; + *margin-left: 85.52897614%; + } + .row-fluid .offset9 { + margin-left: 79.83425414%; + *margin-left: 79.72787116%; + } + .row-fluid .offset9:first-child { + margin-left: 77.0718232%; + *margin-left: 76.96544023%; + } + .row-fluid .offset8 { + margin-left: 71.27071823%; + *margin-left: 71.16433525%; + } + .row-fluid .offset8:first-child { + margin-left: 68.50828729%; + *margin-left: 68.40190431%; + } + .row-fluid .offset7 { + margin-left: 62.70718232%; + *margin-left: 62.60079934%; + } + .row-fluid .offset7:first-child { + margin-left: 59.94475138%; + *margin-left: 59.8383684%; + } + .row-fluid .offset6 { + margin-left: 54.14364641%; + *margin-left: 54.03726343%; + } + .row-fluid .offset6:first-child { + margin-left: 51.38121547%; + *margin-left: 51.27483249%; + } + .row-fluid .offset5 { + margin-left: 45.5801105%; + *margin-left: 45.47372752%; + } + .row-fluid .offset5:first-child { + margin-left: 42.81767956%; + *margin-left: 42.71129658%; + } + .row-fluid .offset4 { + margin-left: 37.01657459%; + *margin-left: 36.91019161%; + } + .row-fluid .offset4:first-child { + margin-left: 34.25414365%; + *margin-left: 34.14776067%; + } + .row-fluid .offset3 { + margin-left: 28.45303867%; + *margin-left: 28.3466557%; + } + .row-fluid .offset3:first-child { + margin-left: 25.69060773%; + *margin-left: 25.58422476%; + } + .row-fluid .offset2 { + margin-left: 19.88950276%; + *margin-left: 19.78311978%; + } + .row-fluid .offset2:first-child { + margin-left: 17.12707182%; + *margin-left: 17.02068884%; + } + .row-fluid .offset1 { + margin-left: 11.32596685%; + *margin-left: 11.21958387%; + } + .row-fluid .offset1:first-child { + margin-left: 8.56353591%; + *margin-left: 8.45715293%; + } + + // Input grid + #grid > .input(@gridColumnWidth1200, @gridGutterWidth1200); + + // Thumbnails + .thumbnails { + margin-left: -@gridGutterWidth1200; + } + .thumbnails > li { + margin-left: @gridGutterWidth1200; + } + .row-fluid .thumbnails { + margin-left: 0; + } + +} diff --git a/Sites/pages/administrator/templates/isis/less/bootstrap/responsive-768px-979px.less b/Sites/pages/administrator/templates/isis/less/bootstrap/responsive-768px-979px.less new file mode 100644 index 00000000..805e65a4 --- /dev/null +++ b/Sites/pages/administrator/templates/isis/less/bootstrap/responsive-768px-979px.less @@ -0,0 +1,192 @@ +// +// Responsive: Tablet to desktop +// -------------------------------------------------- + + +@media (min-width: 768px) and (max-width: 979px) { + + // Fixed grid + #grid > .core(@gridColumnWidth768, @gridGutterWidth768); + + // Fluid grid + .row-fluid { + width: 100%; + *zoom: 1; + } + .row-fluid:before, + .row-fluid:after { + display: table; + content: ""; + line-height: 0; + } + .row-fluid:after { + clear: both; + } + .row-fluid [class*="span"] { + display: block; + width: 100%; + min-height: 28px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + float: left; + margin-left: 2.76243094%; + *margin-left: 2.70923945%; + } + .row-fluid [class*="span"]:first-child { + margin-left: 0; + } + .row-fluid .controls-row [class*="span"] + [class*="span"] { + margin-left: 2.76243094%; + } + .row-fluid .span12 { + width: 100%; + *width: 99.94680851%; + } + .row-fluid .span11 { + width: 91.43646409%; + *width: 91.3832726%; + } + .row-fluid .span10 { + width: 82.87292818%; + *width: 82.81973669%; + } + .row-fluid .span9 { + width: 74.30939227%; + *width: 74.25620078%; + } + .row-fluid .span8 { + width: 65.74585635%; + *width: 65.69266486%; + } + .row-fluid .span7 { + width: 57.18232044%; + *width: 57.12912895%; + } + .row-fluid .span6 { + width: 48.61878453%; + *width: 48.56559304%; + } + .row-fluid .span5 { + width: 40.05524862%; + *width: 40.00205713%; + } + .row-fluid .span4 { + width: 31.49171271%; + *width: 31.43852122%; + } + .row-fluid .span3 { + width: 22.9281768%; + *width: 22.87498531%; + } + .row-fluid .span2 { + width: 14.36464088%; + *width: 14.31144939%; + } + .row-fluid .span1 { + width: 5.80110497%; + *width: 5.74791348%; + } + .row-fluid .offset12 { + margin-left: 105.52486188%; + *margin-left: 105.4184789%; + } + .row-fluid .offset12:first-child { + margin-left: 102.76243094%; + *margin-left: 102.65604796%; + } + .row-fluid .offset11 { + margin-left: 96.96132597%; + *margin-left: 96.85494299%; + } + .row-fluid .offset11:first-child { + margin-left: 94.19889503%; + *margin-left: 94.09251205%; + } + .row-fluid .offset10 { + margin-left: 88.39779006%; + *margin-left: 88.29140708%; + } + .row-fluid .offset10:first-child { + margin-left: 85.63535912%; + *margin-left: 85.52897614%; + } + .row-fluid .offset9 { + margin-left: 79.83425414%; + *margin-left: 79.72787116%; + } + .row-fluid .offset9:first-child { + margin-left: 77.0718232%; + *margin-left: 76.96544023%; + } + .row-fluid .offset8 { + margin-left: 71.27071823%; + *margin-left: 71.16433525%; + } + .row-fluid .offset8:first-child { + margin-left: 68.50828729%; + *margin-left: 68.40190431%; + } + .row-fluid .offset7 { + margin-left: 62.70718232%; + *margin-left: 62.60079934%; + } + .row-fluid .offset7:first-child { + margin-left: 59.94475138%; + *margin-left: 59.8383684%; + } + .row-fluid .offset6 { + margin-left: 54.14364641%; + *margin-left: 54.03726343%; + } + .row-fluid .offset6:first-child { + margin-left: 51.38121547%; + *margin-left: 51.27483249%; + } + .row-fluid .offset5 { + margin-left: 45.5801105%; + *margin-left: 45.47372752%; + } + .row-fluid .offset5:first-child { + margin-left: 42.81767956%; + *margin-left: 42.71129658%; + } + .row-fluid .offset4 { + margin-left: 37.01657459%; + *margin-left: 36.91019161%; + } + .row-fluid .offset4:first-child { + margin-left: 34.25414365%; + *margin-left: 34.14776067%; + } + .row-fluid .offset3 { + margin-left: 28.45303867%; + *margin-left: 28.3466557%; + } + .row-fluid .offset3:first-child { + margin-left: 25.69060773%; + *margin-left: 25.58422476%; + } + .row-fluid .offset2 { + margin-left: 19.88950276%; + *margin-left: 19.78311978%; + } + .row-fluid .offset2:first-child { + margin-left: 17.12707182%; + *margin-left: 17.02068884%; + } + .row-fluid .offset1 { + margin-left: 11.32596685%; + *margin-left: 11.21958387%; + } + .row-fluid .offset1:first-child { + margin-left: 8.56353591%; + *margin-left: 8.45715293%; + } + + // Input grid + #grid > .input(@gridColumnWidth768, @gridGutterWidth768); + + // No need to reset .thumbnails here since it's the same @gridGutterWidth + +} diff --git a/Sites/pages/administrator/templates/isis/less/bootstrap/wells.less b/Sites/pages/administrator/templates/isis/less/bootstrap/wells.less new file mode 100644 index 00000000..41aea380 --- /dev/null +++ b/Sites/pages/administrator/templates/isis/less/bootstrap/wells.less @@ -0,0 +1,29 @@ +// +// Wells +// -------------------------------------------------- + + +// Base class +.well { + min-height: 20px; + padding: 19px; + margin-bottom: 20px; + background-color: @wellBackground; + border: 1px solid @wellBackground; + .border-radius(@baseBorderRadius); + //.box-shadow(inset 0 1px 1px rgba(0,0,0,.05)); + blockquote { + border-color: #f0f0f0; + border-color: rgba(0,0,0,.15); + } +} + +// Sizes +.well-large { + padding: 24px; + .border-radius(@borderRadiusLarge); +} +.well-small { + padding: 9px; + .border-radius(@borderRadiusSmall); +} diff --git a/Sites/pages/administrator/templates/isis/less/icomoon.less b/Sites/pages/administrator/templates/isis/less/icomoon.less new file mode 100644 index 00000000..46f801b4 --- /dev/null +++ b/Sites/pages/administrator/templates/isis/less/icomoon.less @@ -0,0 +1,39 @@ +@font-face { + font-family: 'IcoMoon'; + src: url('../../../../media/jui/fonts/IcoMoon.eot'); + src: url('../../../../media/jui/fonts/IcoMoon.eot?#iefix') format('embedded-opentype'), + url('../../../../media/jui/fonts/IcoMoon.woff') format('woff'), + url('../../../../media/jui/fonts/IcoMoon.ttf') format('truetype'), + url('../../../../media/jui/fonts/IcoMoon.svg#IcoMoon') format('svg'); + font-weight: normal; + font-style: normal; +} +@import "../../../../media/jui/less/icomoon.less"; +.icon-edit:before { + color: @btnInfoBackgroundHighlight; +} +.icon-publish:before, +.icon-save:before, +.icon-ok:before, +.icon-save-new:before, +.icon-save-copy:before, +.btn-toolbar .icon-copy:before { + color: @btnSuccessBackgroundHighlight; +} +.icon-unpublish:before, +.icon-not-ok:before, +.icon-eye-close:before, +.icon-ban-circle:before, +.icon-minus-sign:before, +.btn-toolbar .icon-cancel:before { + color: @btnDangerBackgroundHighlight; +} +.icon-featured:before, +.icon-default:before, +.icon-expired:before, +.icon-pending:before { + color: @btnWarningBackgroundHighlight; +} +.icon-back:before { + content: "\e008"; +} \ No newline at end of file diff --git a/Sites/pages/administrator/templates/isis/less/pages/_com_cpanel.less b/Sites/pages/administrator/templates/isis/less/pages/_com_cpanel.less new file mode 100644 index 00000000..18d8a44c --- /dev/null +++ b/Sites/pages/administrator/templates/isis/less/pages/_com_cpanel.less @@ -0,0 +1,24 @@ +// com_cpanel + +.com_cpanel { + .well { + padding: 8px 14px; + border: 1px solid rgba(0,0,0,0.05); + .module-title.nav-header { + color: #555; + } + > .row-striped, > .list-striped { + margin: 0 -14px; + > .row-fluid { + padding: 8px 14px; + [class*="span"] { + margin-left: 0; + } + } + > li { + padding-left: 15px; + padding-right: 15px; + } + } + } +} \ No newline at end of file diff --git a/Sites/pages/administrator/templates/isis/less/pages/_com_postinstall.less b/Sites/pages/administrator/templates/isis/less/pages/_com_postinstall.less new file mode 100644 index 00000000..2c80f6f5 --- /dev/null +++ b/Sites/pages/administrator/templates/isis/less/pages/_com_postinstall.less @@ -0,0 +1,21 @@ +// com_postinstall + +.com_postinstall { + fieldset { + background-color: #fafafa; + border: 1px solid #ccc; + border-radius: 5px; + margin: 0 0 18px; + padding: 4px 18px 18px; + .btn { + margin-top: 10px; + } + } + legend { + border: 0 none; + display: inline-block; + padding: 0 5px; + margin-bottom: 0; + width: auto; + } +} diff --git a/Sites/pages/administrator/templates/isis/less/pages/_com_privacy.less b/Sites/pages/administrator/templates/isis/less/pages/_com_privacy.less new file mode 100644 index 00000000..18e3bd72 --- /dev/null +++ b/Sites/pages/administrator/templates/isis/less/pages/_com_privacy.less @@ -0,0 +1,24 @@ +// com_privacy + +.com_privacy { + .well { + padding: 8px 14px; + border: 1px solid rgba(0,0,0,0.05); + .module-title.nav-header { + color: #555; + } + > .row-striped, > .list-striped { + margin: 0 -14px; + > .row-fluid { + padding: 8px 14px; + [class*="span"] { + margin-left: 0; + } + } + > li { + padding-left: 15px; + padding-right: 15px; + } + } + } +} \ No newline at end of file diff --git a/Sites/pages/administrator/templates/isis/less/pages/_com_templates.less b/Sites/pages/administrator/templates/isis/less/pages/_com_templates.less new file mode 100644 index 00000000..d175cd51 --- /dev/null +++ b/Sites/pages/administrator/templates/isis/less/pages/_com_templates.less @@ -0,0 +1,44 @@ +// Template Menu Assignment + +#menu-assignment { + position: relative; + .menu-links { + margin-top: 15px; + margin-left: 0; + -webkit-column-count: 4; + -moz-column-count: 4; + column-count: 4; + -moz-column-gap: 15px; + -webkit-column-gap: 15px; + column-gap: 15px; + > li { + display: inline-block; + vertical-align: top; + margin-bottom: 15px; + width: 100%; + list-style: none; + page-break-inside: avoid; + break-inside: avoid; + } + } + .menu-links-block { + background-color: #fafafa; + border: 1px solid #ddd; + border-radius: 3px; + padding: 15px; + } +} +@media (max-width: @xl-max) { + #menu-assignment .menu-links { + -webkit-column-count: 3; + -moz-column-count: 3; + column-count: 3; + } +} +@media (max-width: @md-max) { + #menu-assignment .menu-links { + -webkit-column-count: auto; + -moz-column-count: auto; + column-count: auto; + } +} diff --git a/Sites/pages/administrator/templates/isis/less/template-rtl.less b/Sites/pages/administrator/templates/isis/less/template-rtl.less new file mode 100644 index 00000000..bea733e2 --- /dev/null +++ b/Sites/pages/administrator/templates/isis/less/template-rtl.less @@ -0,0 +1,448 @@ +@import "template.less"; +@import "../../../../media/jui/less/bootstrap-rtl.less"; + +.navbar { + .admin-logo { + float: right; + padding: 7px 15px 0px 12px; + } + .brand { + float: left; + padding: 6px 10px; + } + .nav { + margin: 0 0 0 10px; + > li > a { + padding: 6px 10px; + } + > li ul { + overflow-y: auto; + overflow-x: hidden; + -webkit-overflow-scrolling: touch; + -moz-overflow-scrolling: touch; + -ms-overflow-scrolling: touch; + -o-overflow-scrolling: touch; + overflow-scrolling: touch; + height: auto; + max-height: 500px; + margin: 0; + &::-webkit-scrollbar { + -webkit-appearance: none; + width: 7px; + } + &::-webkit-scrollbar-thumb { + border-radius: 4px; + background-color: rgba(0,0,0,.5); + -webkit-box-shadow: 0 0 1px rgba(255,255,255,.5); + } + } + } + .nav-user .dropdown-menu li span { + padding-left: 0; + padding-right: 10px; + } + .nav > .dropdown.open:after { + right: 10px; + width: 0; + } + .empty-nav { + display: none; + } +} + +#toolbar { + .btn { + padding: 0 10px; + } + [class^="icon-"], [class*=" icon-"] { + border-radius: 0 3px 3px 0; + border-right: 0; + border-left: 1px solid #b3b3b3; + margin: 0 -10px 0 6px; + } +} +.chzn-container-single .chzn-single { + padding-left: 8px; + div { + border-left: 0; + border-right: 1px solid #cccccc; + } + abbr { + left: 36px; + } +} +.chzn-container-active.chzn-with-drop .chzn-single div { + background-color: #f3f3f3; + border-bottom: 1px solid #cccccc; + border-bottom-left-radius: 0px; + border-bottom-right-radius: 3px; + border-left: 1px solid #cccccc; +} +.chzn-container-multi .chzn-choices .search-choice { + padding-left: 7px; + .search-choice-close { + margin-left: 0; + margin-right: 3px; + } +} +.chzn-container .chzn-single.chzn-color[rel="value_0"] div, +.chzn-container .chzn-single.chzn-color[rel="value_1"] div { + border-right: none; +} +.chzn-container-single .chzn-search::after { + left: 20px; + right: auto; +} + +.container-logo { + padding-top: 0; + float: left; + text-align: left; +} + +.page-title { + [class^="icon-"], + [class*=" icon-"] { + margin-right: 0; + margin-left: 16px; + } +} + +@media (max-width: @md-max) { + .navbar { + .admin-logo { + margin-right: 10px; + padding: 9px 9px 0 9px; + } + .btn-navbar { + float: left; + margin-right: 5px; + margin-left: 3px; + } + .nav-collapse .nav.pull-left { + float: none; + margin-left: 0; + margin-right: 0; + } + } + + .nav-collapse .nav > li { + float: none; + } + + .page-title { + [class^="icon-"], + [class*=" icon-"] { + margin-left: 10px; + } + } +} + +/* Status module */ +#status { + padding: 4px 10px; + + .btn-group { + margin: 0; + } + .btn-group.separator:after { + content: ' '; + display: block; + float: left; + background: #ADADAD; + margin: 0 10px; + height: 15px; + width: 1px; + } + .badge { + margin-left: .25em; + margin-right: 0; + } +} + +/* Menus */ +.dropdown-menu > li > a { + text-align: right; +} + +/* btn-group */ +.btn-group.btn-group-yesno > .btn, .btn-group > .btn, .btn-group > .btn + .dropdown-toggle { + float: none; +} + +/* For grid.boolean */ +a.grid_false { + display: inline-block; + height: 16px; + width: 16px; + background-image: url('../images/admin/publish_r.png'); +} + +a.grid_true { + display: inline-block; + height: 16px; + width: 16px; + background-image: url('../images/admin/icon-16-allow.png'); +} + +/* Login */ +.view-login { + .login-joomla { + position: absolute; + right: 50%; + height: 24px; + width: 24px; + margin-right: -12px; + font-size: 22px; + } + .input-medium { + width: 169px; + } +} +.login { + .chzn-single { + width: 219px !important; + } + .chzn-container, + .chzn-drop { + width: 227px !important; + max-width: 227px !important; + } + .input-prepend .chzn-container-single .chzn-single { + .border-radius(3px 0 0 3px); + border-right:0px; + } +} + +/* For collapsible sidebar */ +.j-sidebar-container { + position: absolute; + display: block; + left: auto; + right: -16.5%; + padding-top: 28px; + padding-bottom: 40px; + clear: both; + margin: -10px -1px 0 0; + border-right: 0; + border-left: 1px solid #d3d3d3; +} + +.j-sidebar-container.j-sidebar-hidden { + left: auto; + right: -16.5%; +} + +.j-sidebar-container.j-sidebar-visible { + left: auto; + right: 0; +} + +.j-toggle-sidebar-header { + padding: 10px 19px 10px 0; +} + +.sidebar { + padding: 3px 4px 3px 3px; +} + +.j-toggle-button-wrapper { + &.j-toggle-hidden { + right: auto; + left: -24px; + } + &.j-toggle-visible { + right: auto; + left: 10px; + } +} + +.j-sidebar-container .icon-folder-2 { + line-height: 15px; + padding-left: 0; +} + +#system-message-container, +#j-main-container { + padding: 0 5px 0 0; +} + +#system-message-container.j-toggle-main, +#j-main-container.j-toggle-main, +#system-debug.j-toggle-main { + float: left; +} + +@media (max-width: @lg-max) { + .j-toggle-button-wrapper.j-toggle-hidden { + right: auto; + left: -20px; + } +} + +@media (max-width: @md-max) { + .j-sidebar-container { + position: relative; + padding: 0; + border-right: 0; + border-left: 0; + } + + .j-sidebar-container.j-sidebar-hidden { + margin-left: auto; + margin-right: 16.5%; + } + + .j-sidebar-container.j-sidebar-visible { + margin-left: auto; + margin-right: 0; + } + + /* login */ + .view-login { + select { + width: 229px + } + } +} + +#j-main-container.expanded { + margin-right: 0; +} + +/* Modal batch */ +@media (min-width: @md) { + .row-fluid [class*="span"] { + margin-right: 15px; + margin-left: 0; + } + + .row-fluid .modal-batch [class*="span"] { + margin-right: 0; + } +} + +.row-fluid .modal-batch [class*="span"] { + margin-right: 0; +} + +/* Extended Responsive Styles */ +@media (max-width: @sm-max) { + .btn-toolbar .btn-wrapper .btn { + width: 100% !important; + margin-right:0px; + } + .btn-toolbar .btn-wrapper { + margin:0 10px 5px 10px; + } +} + +@media (max-width: 420px) { + .j-sidebar-container { + margin: 0; + } + /* login */ + .view-login { + .input-medium { + width: 173px; + } + select { + width: 229px + } + } +} + +/* Stats plugin */ +.js-pstats-data-details dd { + margin-right: 240px; +} + +/* Modal footer */ +.modal-footer button { + float: left; +} + +/* Modal Header text align right even if parent container centered */ +.modal-header { + text-align: right; +} + + +/* Media Manager */ +#mediamanager-form .thumbnails-media .thumbnail { + margin-left: 18px !important; + margin-right: 0; + direction: ltr; + text-align: center; +} +.thumbnails-media .imgThumb label::before, .thumbnails-media .imgThumb .imgThumbInside::before { + left: 0; + right: auto; + border-radius: 3px 0; +} +.thumbnails-media .thumbnail input[type="radio"], .thumbnails-media .thumbnail input[type="checkbox"] { + left: auto; + right: 5px; +} +.thumbnails-media .imgDelete a.close { + border-radius: 0 3px; +} +.thumbnails-media .imgPreview a, .thumbnails-media .imgDetails { + border-radius: 3px 0; + border-width: 1px; + left: 0; + right: 0; + text-align: left; + direction: ltr; +} +.thumbnails-media .imgPreview a { + width: 100%; +} + +/* SubForms (Table) */ +.subform-table-layout { + td { + padding-left: 10px; + &::before { + content: attr(data-column); + left: auto; + right: 10px; + padding-left: 10px; + padding-right: 0; + } + } + .subform-repeatable tbody td:last-of-type { + text-align: left; + } + .form-horizontal .controls { + margin-top: 0; + } +} + +/* com_templates */ +.tree-holder { + ul { + ul { + padding-right: 15px; + box-shadow: 3px 0 0 rgba(0, 0, 0, 0.08); + padding-left: 0; + .folder-url, .file { + box-shadow: 3px 0 0 @linkColor; + border-right: 0; + border-left: 1px solid rgba(0, 0, 0, 0.08); + } + } + } +} + +/* Dropdown */ +.dropdown-reverse { + left: 0; + right: auto; +} + +/* CPanel Site Information mod_stats_admin */ +.com_cpanel .well > .row-striped > .row-fluid [class*="span"], +.com_cpanel .well > .list-striped > .row-fluid [class*="span"] { + margin-right: 0; +} diff --git a/Sites/pages/administrator/templates/isis/less/template.less b/Sites/pages/administrator/templates/isis/less/template.less new file mode 100644 index 00000000..d66f34f1 --- /dev/null +++ b/Sites/pages/administrator/templates/isis/less/template.less @@ -0,0 +1,94 @@ +// CSS Reset +@import "../../../../media/jui/less/reset.less"; +// Core variables and mixins +@import "variables.less"; +// Custom for this template +@import "bootstrap/mixins.less"; +// Grid system and page structure +@import "../../../../media/jui/less/scaffolding.less"; +@import "../../../../media/jui/less/grid.less"; +@import "../../../../media/jui/less/layouts.less"; +// Base CSS +@import "../../../../media/jui/less/type.less"; +@import "../../../../media/jui/less/code.less"; +@import "../../../../media/jui/less/forms.less"; +@import "../../../../media/jui/less/tables.less"; +// Components: common +// @import "../../../../media/jui/less/sprites.less"; +@import "../../../../media/jui/less/dropdowns.less"; +@import "bootstrap/wells.less"; +@import "../../../../media/jui/less/component-animations.less"; +@import "../../../../media/jui/less/close.less"; +// Components: Buttons & Alerts +@import "bootstrap/buttons.less"; +@import "bootstrap/button-groups.less"; +@import "../../../../media/jui/less/alerts.less"; +// Note: alerts share common CSS with buttons and thus have styles in buttons.less +// Components: Nav +@import "../../../../media/jui/less/navs.less"; +@import "../../../../media/jui/less/navbar.less"; +@import "../../../../media/jui/less/breadcrumbs.less"; +@import "../../../../media/jui/less/pagination.less"; +@import "../../../../media/jui/less/pager.less"; +// Components: Popovers +@import "../../../../media/jui/less/modals.less"; +@import "../../../../media/jui/less/tooltip.less"; +@import "../../../../media/jui/less/popovers.less"; +// Components: Misc +@import "../../../../media/jui/less/thumbnails.less"; +@import "../../../../media/jui/less/media.less"; +@import "../../../../media/jui/less/labels-badges.less"; +@import "../../../../media/jui/less/progress-bars.less"; +@import "../../../../media/jui/less/accordion.less"; +@import "../../../../media/jui/less/carousel.less"; +@import "../../../../media/jui/less/hero-unit.less"; +// Utility classes +@import "../../../../media/jui/less/utilities.less"; +// RESPONSIVE CLASSES +// ------------------ +@import "../../../../media/jui/less/responsive-utilities.less"; +// MEDIA QUERIES +// ------------------ +// Phones to portrait tablets and narrow desktops +@import "../../../../media/jui/less/responsive-767px-max.less"; +// Tablets to regular desktops +@import "bootstrap/responsive-768px-979px.less"; +// Large desktops +@import "bootstrap/responsive-1200px-min.less"; +// RESPONSIVE NAVBAR +// ------------------ +// From 979px and below, show a button to toggle navbar contents +@import "../../../../media/jui/less/responsive-navbar.less"; +// Extended for JUI +@import "../../../../media/jui/less/bootstrap-extended.less"; +// Has to be last to override when necessary +// div.modal (instead of .modal) +@import "../../../../media/jui/less/modals.joomla.less"; +@import "../../../../media/jui/less/responsive-767px-max.joomla.less"; +// Icon Font +@import "icomoon.less"; + +// Blocks +@import "blocks/_global.less"; +@import "blocks/_chzn-override.less"; +@import "blocks/_editors.less"; +@import "blocks/_forms.less"; +@import "blocks/_header.less"; +@import "blocks/_login.less"; +@import "blocks/_media.less"; +@import "blocks/_modals.less"; +@import "blocks/_navbar.less"; +@import "blocks/_quickicons.less"; +@import "blocks/_sidebar.less"; +@import "blocks/_status.less"; +@import "blocks/_tables.less"; +@import "blocks/_toolbar.less"; +@import "blocks/_treeselect.less"; +@import "blocks/_utility-classes.less"; +@import "blocks/_custom.less"; + +// Pages +@import "pages/_com_cpanel.less"; +@import "pages/_com_postinstall.less"; +@import "pages/_com_privacy.less"; +@import "pages/_com_templates.less"; diff --git a/Sites/pages/administrator/templates/isis/less/variables.less b/Sites/pages/administrator/templates/isis/less/variables.less new file mode 100644 index 00000000..6d6a804f --- /dev/null +++ b/Sites/pages/administrator/templates/isis/less/variables.less @@ -0,0 +1,340 @@ +// +// Variables +// -------------------------------------------------- + +// > Joomla JUI +// Responsive Breakpoints +// ------------------------- +@xs: 320px; +@sm: 480px; +@md: 768px; +@lg: 980px; +@xl: 1200px; + +@xs-max: @xs - 1; +@sm-max: @sm - 1; +@md-max: @md - 1; +@lg-max: @lg - 1; +@xl-max: @xl - 1; +// < Joomla JUI + +// Global values +// -------------------------------------------------- + + +// Grays +// ------------------------- +@black: #000; +@grayDarker: #222; +@grayDark: #333; +@gray: #555; +@grayLight: #999; +@grayLighter: #eee; +@white: #fff; + + +// Accent colors +// ------------------------- +@blue: #049cdb; +@blueDark: #0064cd; +@green: #46a546; +@red: #9d261d; +@yellow: #ffc40d; +@orange: #f89406; +@pink: #c3325f; +@purple: #7a43b6; + + +// Scaffolding +// ------------------------- +@bodyBackground: @white; +@textColor: @grayDark; + + +// Links +// ------------------------- +@linkColor: darken(#428bca, 10%); +@linkColorHover: darken(@linkColor, 15%); + + +// Typography +// ------------------------- +@sansFontFamily: "Helvetica Neue", Helvetica, Arial, sans-serif; +@serifFontFamily: Georgia, "Times New Roman", Times, serif; +@monoFontFamily: Monaco, Menlo, Consolas, "Courier New", monospace; +// > Joomla JUI +@baseFontSize: 13px; +// < Joomla JUI +@baseFontFamily: @sansFontFamily; +// > Joomla JUI +@baseLineHeight: 18px; +// < Joomla JUI +@altFontFamily: @serifFontFamily; + +@headingsFontFamily: inherit; // empty to use BS default, @baseFontFamily +@headingsFontWeight: bold; // instead of browser default, bold +@headingsColor: inherit; // empty to use BS default, @textColor + + +// Component sizing +// ------------------------- +// Based on 14px font-size and 20px line-height + +@fontSizeLarge: @baseFontSize * 1.25; // ~18px +// > Joomla JUI +@fontSizeSmall: ceil(@baseFontSize * 0.85); // ~12px +// < Joomla JUI +@fontSizeMini: @baseFontSize * 0.75; // ~11px + +@paddingLarge: 11px 19px; // 44px +@paddingSmall: 2px 10px; // 26px +@paddingMini: 0 6px; // 22px + +@baseBorderRadius: 3px; +@borderRadiusLarge: 6px; +@borderRadiusSmall: 3px; + + +// Tables +// ------------------------- +@tableBackground: transparent; // overall background-color +@tableBackgroundAccent: #f9f9f9; // for striping +@tableBackgroundHover: #F0F0F0; // for hover +@tableBorder: #ddd; // table and cell border + +// Buttons +// ------------------------- +@btnBackground: #f3f3f3; +@btnBackgroundHighlight: darken(@grayLighter, 3%); +@btnBorder: lighten(@grayLight, 10%); + +// > Joomla JUI +@btnPrimaryBackground: #2384d3; +@btnPrimaryBackgroundHighlight: #15497c; +// < Joomla JUI + +@btnInfoBackground: #2f96b4; +@btnInfoBackgroundHighlight: darken(@btnInfoBackground, 10%); + +@btnSuccessBackground: #46a546; +@btnSuccessBackgroundHighlight: darken(@btnSuccessBackground, 10%); + +@btnWarningBackground: @orange; +@btnWarningBackgroundHighlight: darken(@btnWarningBackground, 10%); + +@btnDangerBackground: #bd362f; +@btnDangerBackgroundHighlight: darken(@btnDangerBackground, 10%); + +@btnInverseBackground: #444; +@btnInverseBackgroundHighlight: @grayDarker; + + +// Forms +// ------------------------- +@inputBackground: @white; +@inputBorder: #ccc; +@inputBorderHighlight: #3071A9; +@inputBorderRadius: 3px; +@inputDisabledBackground: @grayLighter; +@formActionsBackground: #F0F0F0; +@inputHeight: @baseLineHeight + 10px; // base line-height + 8px vertical padding + 2px top/bottom border + + +// Dropdowns +// ------------------------- +@dropdownBackground: @white; +@dropdownBorder: rgba(0,0,0,.2); +@dropdownDividerTop: #F0F0F0; +@dropdownDividerBottom: @white; + +@dropdownLinkColor: @grayDark; +@dropdownLinkColorHover: @white; +@dropdownLinkColorActive: @dropdownLinkColor; + +@dropdownLinkBackgroundHover: @dropdownLinkBackgroundActive; +@dropdownLinkBackgroundActive: @linkColor; + + + +// COMPONENT VARIABLES +// -------------------------------------------------- + + +// Z-index master list +// ------------------------- +// Used for a bird's eye view of components dependent on the z-axis +// Try to avoid customizing these :) +@zindexDropdown: 1000; +@zindexTooltip: 1030; +@zindexFixedNavbar: 1030; +@zindexModalBackdrop: 1040; +@zindexModal: 1050; +@zindexPopover: 1060; + + +// Sprite icons path +// ------------------------- +@iconSpritePath: "../img/glyphicons-halflings.png"; +@iconWhiteSpritePath: "../img/glyphicons-halflings-white.png"; + + +// Input placeholder text color +// ------------------------- +@placeholderText: @grayLight; + + +// Hr border color +// ------------------------- +@hrBorder: @grayLighter; + + +// Horizontal forms & lists +// ------------------------- +@horizontalComponentOffset: 180px; + + +// Wells +// ------------------------- +@wellBackground: #F0F0F0; + + +// Navbar +// ------------------------- +// > Joomla JUI +@navbarCollapseWidth: @md-max; +// < Joomla JUI +@navbarCollapseDesktopWidth: (@navbarCollapseWidth + 1); + +@navbarHeight: 40px; +@navbarBackgroundHighlight: #ffffff; +@navbarBackground: darken(@navbarBackgroundHighlight, 5%); +@navbarBorder: darken(@navbarBackground, 12%); + +@navbarText: @gray; +@navbarLinkColor: @gray; +@navbarLinkColorHover: @grayDark; +@navbarLinkColorActive: @gray; +@navbarLinkBackgroundHover: transparent; +@navbarLinkBackgroundActive: darken(@navbarBackground, 5%); + +@navbarBrandColor: @navbarLinkColor; + +// Inverted navbar +// > Joomla JUI +@navbarInverseBackground: darken(@headerBackground, 10%); +@navbarInverseBackgroundHighlight: darken(@headerBackground, 5%); +@navbarInverseBorder: darken(@headerBackground, 15%); + +@navbarInverseText: lighten(@grayLight, 25%); +@navbarInverseLinkColor: lighten(@grayLight, 25%); +// < Joomla JUI +@navbarInverseLinkColorHover: @white; +@navbarInverseLinkColorActive: @navbarInverseLinkColorHover; +@navbarInverseLinkBackgroundHover: transparent; +@navbarInverseLinkBackgroundActive: @navbarInverseBackground; + +@navbarInverseSearchBackground: lighten(@navbarInverseBackground, 25%); +@navbarInverseSearchBackgroundFocus: @white; +@navbarInverseSearchBorder: @navbarInverseBackground; +@navbarInverseSearchPlaceholderColor: #ccc; + +@navbarInverseBrandColor: @navbarInverseLinkColor; + + +// Pagination +// ------------------------- +@paginationBackground: #fff; +@paginationBorder: #ddd; +@paginationActiveBackground: #F0F0F0; + + +// Hero unit +// ------------------------- +@heroUnitBackground: @grayLighter; +@heroUnitHeadingColor: inherit; +@heroUnitLeadColor: inherit; + + +// Form states and alerts +// ------------------------- +@warningText: #8a6d3b; +@warningBackground: #fcf8e3; +@warningBorder: darken(spin(@warningBackground, -10), 5%); + +@errorText: #a94442; +@errorBackground: #f2dede; +@errorBorder: darken(spin(@errorBackground, -10), 5%); + +@successText: #3c763d; +@successBackground: #dff0d8; +@successBorder: darken(spin(@successBackground, -10), 5%); + +@infoText: #31708f; +@infoBackground: #d9edf7; +@infoBorder: darken(spin(@infoBackground, -10), 7%); + + +// Tooltips and popovers +// ------------------------- +@tooltipColor: #fff; +@tooltipBackground: #000; +@tooltipArrowWidth: 5px; +@tooltipArrowColor: @tooltipBackground; + +@popoverBackground: #fff; +@popoverArrowWidth: 10px; +@popoverArrowColor: #fff; +@popoverTitleBackground: darken(@popoverBackground, 3%); + +// Special enhancement for popovers +@popoverArrowOuterWidth: @popoverArrowWidth + 1; +@popoverArrowOuterColor: rgba(0,0,0,.25); + + + +// GRID +// -------------------------------------------------- + + +// Default 940px grid +// ------------------------- +@gridColumns: 12; +@gridColumnWidth: 60px; +@gridGutterWidth: 20px; +@gridRowWidth: (@gridColumns * @gridColumnWidth) + (@gridGutterWidth * (@gridColumns - 1)); + +// 1200px min +@gridColumnWidth1200: 70px; +@gridGutterWidth1200: 30px; +@gridRowWidth1200: (@gridColumns * @gridColumnWidth1200) + (@gridGutterWidth1200 * (@gridColumns - 1)); + +// 768px-979px +@gridColumnWidth768: 42px; +@gridGutterWidth768: 20px; +@gridRowWidth768: (@gridColumns * @gridColumnWidth768) + (@gridGutterWidth768 * (@gridColumns - 1)); + + +// Fluid grid +// ------------------------- +@fluidGridColumnWidth: percentage(@gridColumnWidth/@gridRowWidth); +@fluidGridGutterWidth: percentage(@gridGutterWidth/@gridRowWidth); + +// 1200px min +@fluidGridColumnWidth1200: percentage(@gridColumnWidth1200/@gridRowWidth1200); +@fluidGridGutterWidth1200: percentage(@gridGutterWidth1200/@gridRowWidth1200); + +// 768px-979px +@fluidGridColumnWidth768: percentage(@gridColumnWidth768/@gridRowWidth768); +@fluidGridGutterWidth768: percentage(@gridGutterWidth768/@gridRowWidth768); + + +// > Joomla JUI +// Login +// ------------------------- +@loginBackground: #17568c; + +// Header +// ------------------------- +@headerBackground: #1a3867; +@headerBackgroundHighlight: #17568c; +// < Joomla JUI \ No newline at end of file diff --git a/Sites/pages/administrator/templates/isis/login.php b/Sites/pages/administrator/templates/isis/login.php new file mode 100644 index 00000000..b33e4434 --- /dev/null +++ b/Sites/pages/administrator/templates/isis/login.php @@ -0,0 +1,142 @@ +setHtml5(true); + +// Gets the FrontEnd Main page Uri +$frontEndUri = JUri::getInstance(JUri::root()); +$frontEndUri->setScheme(((int) $app->get('force_ssl', 0) === 2) ? 'https' : 'http'); + +// Color Params +$background_color = $this->params->get('loginBackgroundColor') ?: ''; +$color_is_light = $background_color && colorIsLight($background_color); + +// Add JavaScript Frameworks +JHtml::_('bootstrap.framework'); +JHtml::_('bootstrap.tooltip'); + +// Add html5 shiv +JHtml::_('script', 'jui/html5.js', array('version' => 'auto', 'relative' => true, 'conditional' => 'lt IE 9')); + +// Add Stylesheets +JHtml::_('stylesheet', 'template' . ($this->direction === 'rtl' ? '-rtl' : '') . '.css', array('version' => 'auto', 'relative' => true)); + +// Load optional RTL Bootstrap CSS +JHtml::_('bootstrap.loadCss', false, $this->direction); + +// Load specific language related CSS +JHtml::_('stylesheet', 'administrator/language/' . $lang->getTag() . '/' . $lang->getTag() . '.css', array('version' => 'auto')); + +// Load custom.css +JHtml::_('stylesheet', 'custom.css', array('version' => 'auto', 'relative' => true)); + +// Detecting Active Variables +$option = $app->input->getCmd('option', ''); +$view = $app->input->getCmd('view', ''); +$layout = $app->input->getCmd('layout', ''); +$task = $app->input->getCmd('task', ''); +$itemid = $app->input->getCmd('Itemid', ''); +$sitename = htmlspecialchars($app->get('sitename', ''), ENT_QUOTES, 'UTF-8'); + +function colorIsLight($color) +{ + $r = hexdec(substr($color, 1, 2)); + $g = hexdec(substr($color, 3, 2)); + $b = hexdec(substr($color, 5, 2)); + + $yiq = (($r * 299) + ($g * 587) + ($b * 114)) / 1000; + + return $yiq >= 200; +} + +// Background color +if ($background_color) +{ + $this->addStyleDeclaration(' + .view-login { + background-color: ' . $background_color . '; + }'); +} + +// Responsive Styles +$this->addStyleDeclaration(' + @media (max-width: 480px) { + .view-login .container { + margin-top: -170px; + } + .btn { + font-size: 13px; + padding: 4px 10px 4px; + } + }'); + +// Check if debug is on +if (JPluginHelper::isEnabled('system', 'debug') && ($app->get('debug_lang', 0) || $app->get('debug', 0))) +{ + $this->addStyleDeclaration(' + .view-login .container { + position: static; + margin-top: 20px; + margin-left: auto; + margin-right: auto; + } + .view-login .navbar-fixed-bottom { + position: relative; + }'); +} +?> + + + + + + + + + +
          +
          + + + + +
          +
          + + + + diff --git a/Sites/pages/administrator/templates/isis/templateDetails.xml b/Sites/pages/administrator/templates/isis/templateDetails.xml new file mode 100644 index 00000000..794e6979 --- /dev/null +++ b/Sites/pages/administrator/templates/isis/templateDetails.xml @@ -0,0 +1,172 @@ + + + + isis + 1.0 + 3/30/2012 + Kyle Ledbetter + admin@joomla.org + Copyright (C) 2005 - 2020 Open Source Matters, Inc. All rights reserved. + TPL_ISIS_XML_DESCRIPTION + + component.php + cpanel.php + favicon.ico + index.php + login.php + templateDetails.xml + template_preview.png + template_thumbnail.png + css + html + images + img + js + language + less + + + menu + submenu + toolbar + title + status + icon + cp_shell + cpanel + bottom + footer + login + debug + + + en-GB/en-GB.tpl_isis.ini + en-GB/en-GB.tpl_isis.sys.ini + + + +
          + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          +
          +
          +
          diff --git a/Sites/pages/administrator/templates/isis/template_preview.png b/Sites/pages/administrator/templates/isis/template_preview.png new file mode 100644 index 00000000..a5eb718d Binary files /dev/null and b/Sites/pages/administrator/templates/isis/template_preview.png differ diff --git a/Sites/pages/administrator/templates/isis/template_thumbnail.png b/Sites/pages/administrator/templates/isis/template_thumbnail.png new file mode 100644 index 00000000..ea155b07 Binary files /dev/null and b/Sites/pages/administrator/templates/isis/template_thumbnail.png differ diff --git a/Sites/pages/administrator/templates/system/component.php b/Sites/pages/administrator/templates/system/component.php new file mode 100644 index 00000000..9e9a92d3 --- /dev/null +++ b/Sites/pages/administrator/templates/system/component.php @@ -0,0 +1,29 @@ +setHtml5(true); + +// Add html5 shiv +JHtml::_('script', 'jui/html5.js', array('version' => 'auto', 'relative' => true, 'conditional' => 'lt IE 9')); +?> + + + + + + + + + + diff --git a/Sites/pages/administrator/templates/system/css/error.css b/Sites/pages/administrator/templates/system/css/error.css new file mode 100644 index 00000000..2f03d07f --- /dev/null +++ b/Sites/pages/administrator/templates/system/css/error.css @@ -0,0 +1,53 @@ +/** + * @copyright Copyright (C) 2005 - 2020 Open Source Matters, Inc. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +.outline { + border: 1px solid #cccccc; + background: #ffffff; + padding: 2px; +} + +body { + margin: 15px; + height: 100%; + padding: 0; + font-family: Arial, Helvetica, Sans Serif; + font-size: 11px; + color: #333333; + background: #ffffff; +} + +.frame { + background-color: #FEFCF3; + padding: 8px; + border: solid 1px #000000; + margin-top: 13px; + margin-bottom: 25px; +} + +h1 { + color: #cc3333; + font-size: 18px; +} + +.table { + border-collapse: collapse; + margin-top: 13px; +} + +td { + padding: 3px; + padding-left: 5px; + padding-right: 5px; + border: solid 1px #bbbbbb; + font-size: 10px; +} + +.type { + background-color: #cc0000; + color: #ffffff; + font-weight: bold; + padding: 3px; +} \ No newline at end of file diff --git a/Sites/pages/administrator/templates/system/css/system.css b/Sites/pages/administrator/templates/system/css/system.css new file mode 100644 index 00000000..5282e226 --- /dev/null +++ b/Sites/pages/administrator/templates/system/css/system.css @@ -0,0 +1,7 @@ +/** + * @copyright Copyright (C) 2005 - 2020 Open Source Matters, Inc. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +/* Import project-level system CSS */ +@import url(../../../../media/system/css/system.css); \ No newline at end of file diff --git a/Sites/pages/administrator/templates/system/error.php b/Sites/pages/administrator/templates/system/error.php new file mode 100644 index 00000000..420dac44 --- /dev/null +++ b/Sites/pages/administrator/templates/system/error.php @@ -0,0 +1,66 @@ + + + + + + <?php echo $this->error->getCode(); ?> - <?php echo htmlspecialchars($this->error->getMessage(), ENT_QUOTES, 'UTF-8'); ?> + + + + + + + + + + + +
          +

          error->getCode() ?> -

          +
          +

          + error->getMessage(), ENT_QUOTES, 'UTF-8'); ?> + debug) : ?> +
          error->getFile(), ENT_QUOTES, 'UTF-8');?>:error->getLine(); ?> + +

          +

          + debug) : ?> +
          + renderBacktrace(); ?> + + error->getPrevious()) : ?> + + _error here and in the loop as setError() assigns errors to this property and we need this for the backtrace to work correctly ?> + + setError($this->_error->getPrevious()); ?> + +

          +

          + _error->getMessage(), ENT_QUOTES, 'UTF-8'); ?> +
          _error->getFile(), ENT_QUOTES, 'UTF-8');?>:_error->getLine(); ?> +

          + renderBacktrace(); ?> + setError($this->_error->getPrevious()); ?> + + + setError($this->error); ?> + +
          + +
          + + diff --git a/Sites/pages/administrator/templates/system/html/modules.php b/Sites/pages/administrator/templates/system/html/modules.php new file mode 100644 index 00000000..e0036288 --- /dev/null +++ b/Sites/pages/administrator/templates/system/html/modules.php @@ -0,0 +1,101 @@ +content; +} + +/* + * html5 (chosen html5 tag and font header tags) + */ +function modChrome_html5($module, &$params, &$attribs) +{ + $moduleTag = $params->get('module_tag'); + $headerTag = htmlspecialchars($params->get('header_tag'), ENT_COMPAT, 'UTF-8'); + $headerClass = $params->get('header_class'); + $bootstrapSize = $params->get('bootstrap_size'); + $moduleClass = !empty($bootstrapSize) ? ' span' . (int) $bootstrapSize . '' : ''; + $moduleClassSfx = htmlspecialchars($params->get('moduleclass_sfx'), ENT_COMPAT, 'UTF-8'); + + if (!empty ($module->content)) + { + $html = "<{$moduleTag} class=\"moduletable{$moduleClassSfx} {$moduleClass}\">"; + + if ((bool) $module->showtitle) + { + $html .= "<{$headerTag} class=\"{$headerClass}\">{$module->title}"; + } + + $html .= $module->content; + $html .= ""; + + echo $html; + } +} + +/* + * xhtml (divs and font header tags) + * With the new advanced parameter it does the same as the html5 chrome + */ +function modChrome_xhtml($module, &$params, &$attribs) +{ + $moduleTag = $params->get('module_tag', 'div'); + $headerTag = htmlspecialchars($params->get('header_tag', 'h3'), ENT_COMPAT, 'UTF-8'); + $bootstrapSize = (int) $params->get('bootstrap_size', 0); + $moduleClass = $bootstrapSize != 0 ? ' span' . $bootstrapSize : ''; + + // Temporarily store header class in variable + $headerClass = $params->get('header_class'); + $headerClass = $headerClass ? ' class="' . htmlspecialchars($headerClass, ENT_COMPAT, 'UTF-8') . '"' : ''; + + $content = trim($module->content); + + if (!empty ($content)) : ?> + < class="moduleget('moduleclass_sfx'), ENT_COMPAT, 'UTF-8') . $moduleClass; ?>"> + showtitle != 0) : ?> + <' . $module->title; ?>> + + + > + content); + + if (!empty($content)) + { + echo JHtml::_('sliders.panel', $module->title, 'module' . $module->id); + echo $content; + } +} + +/* + * allows tabs + */ +function modChrome_tabs($module, &$params, &$attribs) +{ + $content = trim($module->content); + + if (!empty($content)) + { + echo JHtml::_('tabs.panel', $module->title, 'module' . $module->id); + echo $content; + } +} diff --git a/Sites/pages/administrator/templates/system/images/calendar.png b/Sites/pages/administrator/templates/system/images/calendar.png new file mode 100644 index 00000000..586bc28e Binary files /dev/null and b/Sites/pages/administrator/templates/system/images/calendar.png differ diff --git a/Sites/pages/administrator/templates/system/index.php b/Sites/pages/administrator/templates/system/index.php new file mode 100644 index 00000000..f66218e4 --- /dev/null +++ b/Sites/pages/administrator/templates/system/index.php @@ -0,0 +1,12 @@ + diff --git a/Sites/pages/bin/keychain.php b/Sites/pages/bin/keychain.php new file mode 100644 index 00000000..0c8a9f12 --- /dev/null +++ b/Sites/pages/bin/keychain.php @@ -0,0 +1,415 @@ +#!/usr/bin/env php +input->args)) + { + // Check if they passed --help in otherwise display short usage summary + if ($this->input->get('help', false) === false) + { + $this->out("usage: {$this->input->executable} [options] [command] []"); + exit(1); + } + else + { + $this->displayHelp(); + exit(0); + } + } + + // For all tasks but help and init we use the keychain + if (!in_array($this->input->args[0], array('help', 'init'))) + { + $this->loadKeychain(); + } + + switch ($this->input->args[0]) + { + case 'init': + $this->initPassphraseFile(); + break; + case 'list': + $this->listEntries(); + break; + case 'create': + $this->create(); + break; + case 'change': + $this->change(); + break; + case 'delete': + $this->delete(); + break; + case 'read': + $this->read(); + break; + case 'help': + $this->displayHelp(); + break; + default: + $this->out('Invalid command.'); + break; + } + + if ($this->updated) + { + $this->saveKeychain(); + } + + exit(0); + } + + /** + * Load the keychain from a file. + * + * @return void + * + * @since 3.1.4 + */ + protected function loadKeychain() + { + $keychain = $this->input->get('keychain', '', 'raw'); + $publicKeyFile = $this->input->get('public-key', '', 'raw'); + $passphraseFile = $this->input->get('passphrase', '', 'raw'); + + $this->keychain = new JKeychain; + + if (file_exists($keychain)) + { + if (file_exists($publicKeyFile)) + { + $this->keychain->loadKeychain($keychain, $passphraseFile, $publicKeyFile); + } + else + { + $this->out('Public key not specified or missing!'); + exit(1); + } + } + } + + /** + * Save this keychain to a file. + * + * @return void + * + * @since 3.1.4 + */ + protected function saveKeychain() + { + $keychain = $this->input->get('keychain', '', 'raw'); + $publicKeyFile = $this->input->get('public-key', '', 'raw'); + $passphraseFile = $this->input->get('passphrase', '', 'raw'); + + if (!file_exists($publicKeyFile)) + { + $this->out("Public key file specified doesn't exist: $publicKeyFile"); + exit(1); + } + + $this->keychain->saveKeychain($keychain, $passphraseFile, $publicKeyFile); + } + + /** + * Initialise a new passphrase file. + * + * @return void + * + * @since 3.1.4 + */ + protected function initPassphraseFile() + { + $keychain = new JKeychain; + + $passphraseFile = $this->input->get('passphrase', '', 'raw'); + $privateKeyFile = $this->input->get('private-key', '', 'raw'); + + if (!strlen($passphraseFile)) + { + $this->out('A passphrase file must be specified with --passphrase'); + exit(1); + } + + if (!file_exists($privateKeyFile)) + { + $this->out("protected key file specified doesn't exist: $privateKeyFile"); + exit(1); + } + + $this->out('Please enter the new passphrase:'); + $passphrase = $this->in(); + + $this->out('Please enter the passphrase for the protected key:'); + $privateKeyPassphrase = $this->in(); + + $keychain->createPassphraseFile($passphrase, $passphraseFile, $privateKeyFile, $privateKeyPassphrase); + } + + /** + * Create a new entry + * + * @return void + * + * @since 3.1.4 + */ + protected function create() + { + if (count($this->input->args) != 3) + { + $this->out("usage: {$this->input->executable} [options] create entry_name entry_value"); + exit(1); + } + + if ($this->keychain->exists($this->input->args[1])) + { + $this->out('error: entry already exists. To change this entry, use "change"'); + exit(1); + } + + $this->change(); + } + + /** + * Change an existing entry to a new value or create an entry if missing. + * + * @return void + * + * @since 3.1.4 + */ + protected function change() + { + if (count($this->input->args) != 3) + { + $this->out("usage: {$this->input->executable} [options] change entry_name entry_value"); + exit(1); + } + + $this->updated = true; + $this->keychain->setValue($this->input->args[1], $this->input->args[2]); + } + + /** + * Read an entry from the keychain + * + * @return void + * + * @since 3.1.4 + */ + protected function read() + { + if (count($this->input->args) != 2) + { + $this->out("usage: {$this->input->executable} [options] read entry_name"); + exit(1); + } + + $key = $this->input->args[1]; + $this->out($key . ': ' . $this->dumpVar($this->keychain->get($key))); + } + + /** + * Get the string from var_dump + * + * @param mixed $var The variable you want to have dumped. + * + * @return string The result of var_dump + * + * @since 3.1.4 + */ + private function dumpVar($var) + { + ob_start(); + var_dump($var); + $result = trim(ob_get_contents()); + ob_end_clean(); + + return $result; + } + + /** + * Delete an entry from the keychain + * + * @return void + * + * @since 3.1.4 + */ + protected function delete() + { + if (count($this->input->args) != 2) + { + $this->out("usage: {$this->input->executable} [options] delete entry_name"); + exit(1); + } + + $this->updated = true; + $this->keychain->deleteValue($this->input->args[1]); + } + + /** + * List entries in the keychain + * + * @return void + * + * @since 3.1.4 + */ + protected function listEntries() + { + foreach ($this->keychain->toArray() as $key => $value) + { + $line = $key; + + if ($this->input->get('print-values')) + { + $line .= ': ' . $this->dumpVar($value); + } + + $this->out($line); + } + } + + /** + * Display the help information + * + * @return void + * + * @since 3.1.4 + */ + protected function displayHelp() + { +/* +COMMANDS + + - list + - create entry_name entry_value + - change entry_name entry_value + - delete entry_name + - read entry_name +*/ + + $help = <<input->executable} [--keychain=/path/to/keychain] + [--passphrase=/path/to/passphrase.dat] [--public-key=/path/to/public.pem] + [command] [] + +OPTIONS + + --keychain=/path/to/keychain + Path to a keychain file to manipulate. + + --passphrase=/path/to/passphrase.dat + Path to a passphrase file containing the encryption/decryption key. + + --public-key=/path/to/public.pem + Path to a public key file to decrypt the passphrase file. + + +COMMANDS + + list: + Usage: list [--print-values] + Lists all entries in the keychain. Optionally pass --print-values to print the values as well. + + create: + Usage: create entry_name entry_value + Creates a new entry in the keychain called "entry_name" with the plaintext value "entry_value". + NOTE: This is an alias for change. + + change: + Usage: change entry_name entry_value + Updates the keychain entry called "entry_name" with the value "entry_value". + + delete: + Usage: delete entry_name + Removes an entry called "entry_name" from the keychain. + + read: + Usage: read entry_name + Outputs the plaintext value of "entry_name" from the keychain. + + init: + Usage: init + Creates a new passphrase file and prompts for a new passphrase. + +HELP; + $this->out($help); + } +} + +try +{ + JApplicationCli::getInstance('KeychainManager')->execute(); +} +catch (Exception $e) +{ + echo $e->getMessage() . "\n"; + exit(1); +} diff --git a/Sites/pages/cache/index.html b/Sites/pages/cache/index.html new file mode 100644 index 00000000..2efb97f3 --- /dev/null +++ b/Sites/pages/cache/index.html @@ -0,0 +1 @@ + diff --git a/Sites/pages/cli/deletefiles.php b/Sites/pages/cli/deletefiles.php new file mode 100644 index 00000000..d34241a6 --- /dev/null +++ b/Sites/pages/cli/deletefiles.php @@ -0,0 +1,79 @@ +load('files_joomla.sys', JPATH_SITE, null, false, false) +// Fallback to the files_joomla file in the default language +|| $lang->load('files_joomla.sys', JPATH_SITE, null, true); + +/** + * A command line cron job to attempt to remove files that should have been deleted at update. + * + * @since 3.0 + */ +class DeletefilesCli extends JApplicationCli +{ + /** + * Entry point for CLI script + * + * @return void + * + * @since 3.0 + */ + public function doExecute() + { + // Import the dependencies + jimport('joomla.filesystem.file'); + jimport('joomla.filesystem.folder'); + + // We need the update script + JLoader::register('JoomlaInstallerScript', JPATH_ADMINISTRATOR . '/components/com_admin/script.php'); + + // Instantiate the class + $class = new JoomlaInstallerScript; + + // Run the delete method + $class->deleteUnexistingFiles(); + } +} + +// Instantiate the application object, passing the class name to JCli::getInstance +// and use chaining to execute the application. +JApplicationCli::getInstance('DeletefilesCli')->execute(); diff --git a/Sites/pages/cli/finder_indexer.php b/Sites/pages/cli/finder_indexer.php new file mode 100644 index 00000000..a6d5f8fc --- /dev/null +++ b/Sites/pages/cli/finder_indexer.php @@ -0,0 +1,477 @@ +debug); + +// Configure error reporting to maximum for CLI output. +error_reporting(E_ALL); +ini_set('display_errors', 1); + +// Load Library language +$lang = JFactory::getLanguage(); + +// Try the finder_cli file in the current language (without allowing the loading of the file in the default language) +$lang->load('finder_cli', JPATH_SITE, null, false, false) +// Fallback to the finder_cli file in the default language +|| $lang->load('finder_cli', JPATH_SITE, null, true); + +/** + * A command line cron job to run the Smart Search indexer. + * + * @since 2.5 + */ +class FinderCli extends JApplicationCli +{ + /** + * Start time for the index process + * + * @var string + * @since 2.5 + */ + private $time; + + /** + * Start time for each batch + * + * @var string + * @since 2.5 + */ + private $qtime; + + /** + * Static filters information. + * + * @var array + * @since 3.3 + */ + private $filters = array(); + + /** + * Pausing type or defined pause time in seconds. + * One pausing type is implemented: 'division' for dynamic calculation of pauses + * + * Defaults to 'division' + * + * @var string|integer + * @since 3.9.12 + */ + private $pause = 'division'; + + /** + * The divisor of the division: batch-processing time / divisor. + * This is used together with --pause=division in order to pause dynamically + * in relation to the processing time + * Defaults to 5 + * + * @var integer + * @since 3.9.12 + */ + private $divisor = 5; + + /** + * Minimum processing time in seconds, in order to apply a pause + * Defaults to 1 + * + * @var integer + * @since 3.9.12 + */ + private $minimumBatchProcessingTime = 1; + + /** + * Entry point for Smart Search CLI script + * + * @return void + * + * @since 2.5 + */ + public function doExecute() + { + // Print a blank line. + $this->out(JText::_('FINDER_CLI')); + $this->out('============================'); + + // Initialize the time value. + $this->time = microtime(true); + + // Remove the script time limit. + @set_time_limit(0); + + // Fool the system into thinking we are running as JSite with Smart Search as the active component. + $_SERVER['HTTP_HOST'] = 'domain.com'; + JFactory::getApplication('site'); + + $this->minimumBatchProcessingTime = $this->input->getInt('minproctime', 1); + + // Pause between batches to let the server catch a breath. The default, if not set by the user, is set in the class property `pause` + $pauseArg = $this->input->get('pause', $this->pause, 'raw'); + + if ($pauseArg === 'division') + { + $this->divisor = $this->input->getInt('divisor', $this->divisor); + } + else + { + $this->pause = (int) $pauseArg; + } + + // Purge before indexing if --purge on the command line. + if ($this->input->getString('purge', false)) + { + // Taxonomy ids will change following a purge/index, so save filter information first. + $this->getFilters(); + + // Purge the index. + $this->purge(); + + // Run the indexer. + $this->index(); + + // Restore the filters again. + $this->putFilters(); + } + else + { + // Run the indexer. + $this->index(); + } + + // Total reporting. + $this->out(JText::sprintf('FINDER_CLI_PROCESS_COMPLETE', round(microtime(true) - $this->time, 3)), true); + $this->out(JText::sprintf('FINDER_CLI_PEAK_MEMORY_USAGE', number_format(memory_get_peak_usage(true)))); + + // Print a blank line at the end. + $this->out(); + } + + /** + * Run the indexer. + * + * @return void + * + * @since 2.5 + */ + private function index() + { + JLoader::register('FinderIndexer', JPATH_ADMINISTRATOR . '/components/com_finder/helpers/indexer/indexer.php'); + + // Disable caching. + $config = JFactory::getConfig(); + $config->set('caching', 0); + $config->set('cache_handler', 'file'); + + // Reset the indexer state. + FinderIndexer::resetState(); + + // Import the plugins. + JPluginHelper::importPlugin('system'); + JPluginHelper::importPlugin('finder'); + + // Starting Indexer. + $this->out(JText::_('FINDER_CLI_STARTING_INDEXER'), true); + + // Trigger the onStartIndex event. + JEventDispatcher::getInstance()->trigger('onStartIndex'); + + // Remove the script time limit. + @set_time_limit(0); + + // Get the indexer state. + $state = FinderIndexer::getState(); + + // Setting up plugins. + $this->out(JText::_('FINDER_CLI_SETTING_UP_PLUGINS'), true); + + // Trigger the onBeforeIndex event. + JEventDispatcher::getInstance()->trigger('onBeforeIndex'); + + // Startup reporting. + $this->out(JText::sprintf('FINDER_CLI_SETUP_ITEMS', $state->totalItems, round(microtime(true) - $this->time, 3)), true); + + // Get the number of batches. + $t = (int) $state->totalItems; + $c = (int) ceil($t / $state->batchSize); + $c = $c === 0 ? 1 : $c; + + try + { + // Process the batches. + for ($i = 0; $i < $c; $i++) + { + // Set the batch start time. + $this->qtime = microtime(true); + + // Reset the batch offset. + $state->batchOffset = 0; + + // Trigger the onBuildIndex event. + JEventDispatcher::getInstance()->trigger('onBuildIndex'); + + // Batch reporting. + $this->out(JText::sprintf('FINDER_CLI_BATCH_COMPLETE', $i + 1, $processingTime = round(microtime(true) - $this->qtime, 3)), true); + + if ($this->pause !== 0) + { + // Pausing Section + $skip = !($processingTime >= $this->minimumBatchProcessingTime); + $pause = 0; + + if ($this->pause === 'division' && $this->divisor > 0) + { + if (!$skip) + { + $pause = round($processingTime / $this->divisor); + } + else + { + $pause = 1; + } + } + elseif ($this->pause > 0) + { + $pause = $this->pause; + } + + if ($pause > 0 && !$skip) + { + $this->out(JText::sprintf('FINDER_CLI_BATCH_PAUSING', $pause), true); + sleep($pause); + $this->out(JText::_('FINDER_CLI_BATCH_CONTINUING')); + } + + if ($skip) + { + $this->out(JText::sprintf('FINDER_CLI_SKIPPING_PAUSE_LOW_BATCH_PROCESSING_TIME', $processingTime, $this->minimumBatchProcessingTime), true); + } + // End of Pausing Section + } + } + } + catch (Exception $e) + { + // Display the error + $this->out($e->getMessage(), true); + + // Reset the indexer state. + FinderIndexer::resetState(); + + // Close the app + $this->close($e->getCode()); + } + + // Reset the indexer state. + FinderIndexer::resetState(); + } + + /** + * Purge the index. + * + * @return void + * + * @since 3.3 + */ + private function purge() + { + $this->out(JText::_('FINDER_CLI_INDEX_PURGE')); + + // Load the model. + JModelLegacy::addIncludePath(JPATH_COMPONENT_ADMINISTRATOR . '/models', 'FinderModel'); + $model = JModelLegacy::getInstance('Index', 'FinderModel'); + + // Attempt to purge the index. + $return = $model->purge(); + + // If unsuccessful then abort. + if (!$return) + { + $message = JText::_('FINDER_CLI_INDEX_PURGE_FAILED', $model->getError()); + $this->out($message); + exit(); + } + + $this->out(JText::_('FINDER_CLI_INDEX_PURGE_SUCCESS')); + } + + /** + * Restore static filters. + * + * Using the saved filter information, update the filter records + * with the new taxonomy ids. + * + * @return void + * + * @since 3.3 + */ + private function putFilters() + { + $this->out(JText::_('FINDER_CLI_RESTORE_FILTERS')); + + $db = JFactory::getDbo(); + + // Use the temporary filter information to update the filter taxonomy ids. + foreach ($this->filters as $filter_id => $filter) + { + $tids = array(); + + foreach ($filter as $element) + { + // Look for the old taxonomy in the new taxonomy table. + $query = $db->getQuery(true); + $query + ->select('t.id') + ->from($db->qn('#__finder_taxonomy') . ' AS t') + ->leftJoin($db->qn('#__finder_taxonomy') . ' AS p ON p.id = t.parent_id') + ->where($db->qn('t.title') . ' = ' . $db->q($element['title'])) + ->where($db->qn('p.title') . ' = ' . $db->q($element['parent'])); + $taxonomy = $db->setQuery($query)->loadResult(); + + // If we found it then add it to the list. + if ($taxonomy) + { + $tids[] = $taxonomy; + } + else + { + $this->out(JText::sprintf('FINDER_CLI_FILTER_RESTORE_WARNING', $element['parent'], $element['title'], $element['filter'])); + } + } + + // Construct a comma-separated string from the taxonomy ids. + $taxonomyIds = empty($tids) ? '' : implode(',', $tids); + + // Update the filter with the new taxonomy ids. + $query = $db->getQuery(true); + $query + ->update($db->qn('#__finder_filters')) + ->set($db->qn('data') . ' = ' . $db->q($taxonomyIds)) + ->where($db->qn('filter_id') . ' = ' . (int) $filter_id); + $db->setQuery($query)->execute(); + } + + $this->out(JText::sprintf('FINDER_CLI_RESTORE_FILTER_COMPLETED', count($this->filters))); + } + + /** + * Save static filters. + * + * Since a purge/index cycle will cause all the taxonomy ids to change, + * the static filters need to be updated with the new taxonomy ids. + * The static filter information is saved prior to the purge/index + * so that it can later be used to update the filters with new ids. + * + * @return void + * + * @since 3.3 + */ + private function getFilters() + { + $this->out(JText::_('FINDER_CLI_SAVE_FILTERS')); + + // Get the taxonomy ids used by the filters. + $db = JFactory::getDbo(); + $query = $db->getQuery(true); + $query + ->select('filter_id, title, data') + ->from($db->qn('#__finder_filters')); + $filters = $db->setQuery($query)->loadObjectList(); + + // Get the name of each taxonomy and the name of its parent. + foreach ($filters as $filter) + { + // Skip empty filters. + if ($filter->data === '') + { + continue; + } + + // Get taxonomy records. + $query = $db->getQuery(true); + $query + ->select('t.title, p.title AS parent') + ->from($db->qn('#__finder_taxonomy') . ' AS t') + ->leftJoin($db->qn('#__finder_taxonomy') . ' AS p ON p.id = t.parent_id') + ->where($db->qn('t.id') . ' IN (' . $filter->data . ')'); + $taxonomies = $db->setQuery($query)->loadObjectList(); + + // Construct a temporary data structure to hold the filter information. + foreach ($taxonomies as $taxonomy) + { + $this->filters[$filter->filter_id][] = array( + 'filter' => $filter->title, + 'title' => $taxonomy->title, + 'parent' => $taxonomy->parent, + ); + } + } + + $this->out(JText::sprintf('FINDER_CLI_SAVE_FILTER_COMPLETED', count($filters))); + } +} + +// Instantiate the application object, passing the class name to JCli::getInstance +// and use chaining to execute the application. +JApplicationCli::getInstance('FinderCli')->execute(); diff --git a/Sites/pages/cli/garbagecron.php b/Sites/pages/cli/garbagecron.php new file mode 100644 index 00000000..c549e18d --- /dev/null +++ b/Sites/pages/cli/garbagecron.php @@ -0,0 +1,55 @@ +gc(); + } +} + +JApplicationCli::getInstance('GarbageCron')->execute(); diff --git a/Sites/pages/cli/index.html b/Sites/pages/cli/index.html new file mode 100644 index 00000000..2efb97f3 --- /dev/null +++ b/Sites/pages/cli/index.html @@ -0,0 +1 @@ + diff --git a/Sites/pages/cli/sessionGc.php b/Sites/pages/cli/sessionGc.php new file mode 100644 index 00000000..728e19f3 --- /dev/null +++ b/Sites/pages/cli/sessionGc.php @@ -0,0 +1,56 @@ +gc(); + } +} + +JApplicationCli::getInstance('SessionGc')->execute(); diff --git a/Sites/pages/cli/sessionMetadataGc.php b/Sites/pages/cli/sessionMetadataGc.php new file mode 100644 index 00000000..3f200286 --- /dev/null +++ b/Sites/pages/cli/sessionMetadataGc.php @@ -0,0 +1,59 @@ +getExpire(); + + $metadataManager->deletePriorTo(time() - $sessionExpire); + } +} + +JApplicationCli::getInstance('SessionMetadataGc')->execute(); diff --git a/Sites/pages/cli/update_cron.php b/Sites/pages/cli/update_cron.php new file mode 100644 index 00000000..5ad1b121 --- /dev/null +++ b/Sites/pages/cli/update_cron.php @@ -0,0 +1,71 @@ +params; + $cache_timeout = $params->get('cachetimeout', 6, 'int'); + $cache_timeout = 3600 * $cache_timeout; + + // Find all updates + $this->out('Fetching updates...'); + $updater = JUpdater::getInstance(); + $updater->findUpdates(0, $cache_timeout); + $this->out('Finished fetching updates'); + } +} + +JApplicationCli::getInstance('Updatecron')->execute(); diff --git a/Sites/pages/components/com_ajax/ajax.php b/Sites/pages/components/com_ajax/ajax.php new file mode 100644 index 00000000..984c9ac4 --- /dev/null +++ b/Sites/pages/components/com_ajax/ajax.php @@ -0,0 +1,275 @@ +allowCache(false); + +// Prevent the api url from being indexed +$app->setHeader('X-Robots-Tag', 'noindex, nofollow'); + +// JInput object +$input = $app->input; + +// Requested format passed via URL +$format = strtolower($input->getWord('format')); + +// Initialize default response and module name +$results = null; +$parts = null; + +// Check for valid format +if (!$format) +{ + $results = new InvalidArgumentException(JText::_('COM_AJAX_SPECIFY_FORMAT'), 404); +} +/* + * Module support. + * + * modFooHelper::getAjax() is called where 'foo' is the value + * of the 'module' variable passed via the URL + * (i.e. index.php?option=com_ajax&module=foo). + * + */ +elseif ($input->get('module')) +{ + $module = $input->get('module'); + $table = JTable::getInstance('extension'); + $moduleId = $table->find(array('type' => 'module', 'element' => 'mod_' . $module)); + + if ($moduleId && $table->load($moduleId) && $table->enabled) + { + $helperFile = JPATH_BASE . '/modules/mod_' . $module . '/helper.php'; + + if (strpos($module, '_')) + { + $parts = explode('_', $module); + } + elseif (strpos($module, '-')) + { + $parts = explode('-', $module); + } + + if ($parts) + { + $class = 'Mod'; + + foreach ($parts as $part) + { + $class .= ucfirst($part); + } + + $class .= 'Helper'; + } + else + { + $class = 'Mod' . ucfirst($module) . 'Helper'; + } + + $method = $input->get('method') ?: 'get'; + + if (is_file($helperFile)) + { + JLoader::register($class, $helperFile); + + if (method_exists($class, $method . 'Ajax')) + { + // Load language file for module + $basePath = JPATH_BASE; + $lang = JFactory::getLanguage(); + $lang->load('mod_' . $module, $basePath, null, false, true) + || $lang->load('mod_' . $module, $basePath . '/modules/mod_' . $module, null, false, true); + + try + { + $results = call_user_func($class . '::' . $method . 'Ajax'); + } + catch (Exception $e) + { + $results = $e; + } + } + // Method does not exist + else + { + $results = new LogicException(JText::sprintf('COM_AJAX_METHOD_NOT_EXISTS', $method . 'Ajax'), 404); + } + } + // The helper file does not exist + else + { + $results = new RuntimeException(JText::sprintf('COM_AJAX_FILE_NOT_EXISTS', 'mod_' . $module . '/helper.php'), 404); + } + } + // Module is not published, you do not have access to it, or it is not assigned to the current menu item + else + { + $results = new LogicException(JText::sprintf('COM_AJAX_MODULE_NOT_ACCESSIBLE', 'mod_' . $module), 404); + } +} +/* + * Plugin support by default is based on the "Ajax" plugin group. + * An optional 'group' variable can be passed via the URL. + * + * The plugin event triggered is onAjaxFoo, where 'foo' is + * the value of the 'plugin' variable passed via the URL + * (i.e. index.php?option=com_ajax&plugin=foo) + * + */ +elseif ($input->get('plugin')) +{ + $group = $input->get('group', 'ajax'); + JPluginHelper::importPlugin($group); + $plugin = ucfirst($input->get('plugin')); + $dispatcher = JEventDispatcher::getInstance(); + + try + { + $results = $dispatcher->trigger('onAjax' . $plugin); + } + catch (Exception $e) + { + $results = $e; + } +} +/* + * Template support. + * + * tplFooHelper::getAjax() is called where 'foo' is the value + * of the 'template' variable passed via the URL + * (i.e. index.php?option=com_ajax&template=foo). + * + */ +elseif ($input->get('template')) +{ + $template = $input->get('template'); + $table = JTable::getInstance('extension'); + $templateId = $table->find(array('type' => 'template', 'element' => $template)); + + if ($templateId && $table->load($templateId) && $table->enabled) + { + $basePath = ($table->client_id) ? JPATH_ADMINISTRATOR : JPATH_SITE; + $helperFile = $basePath . '/templates/' . $template . '/helper.php'; + + if (strpos($template, '_')) + { + $parts = explode('_', $template); + } + elseif (strpos($template, '-')) + { + $parts = explode('-', $template); + } + + if ($parts) + { + $class = 'Tpl'; + + foreach ($parts as $part) + { + $class .= ucfirst($part); + } + + $class .= 'Helper'; + } + else + { + $class = 'Tpl' . ucfirst($template) . 'Helper'; + } + + $method = $input->get('method') ?: 'get'; + + if (is_file($helperFile)) + { + JLoader::register($class, $helperFile); + + if (method_exists($class, $method . 'Ajax')) + { + // Load language file for template + $lang = JFactory::getLanguage(); + $lang->load('tpl_' . $template, $basePath, null, false, true) + || $lang->load('tpl_' . $template, $basePath . '/templates/' . $template, null, false, true); + + try + { + $results = call_user_func($class . '::' . $method . 'Ajax'); + } + catch (Exception $e) + { + $results = $e; + } + } + // Method does not exist + else + { + $results = new LogicException(JText::sprintf('COM_AJAX_METHOD_NOT_EXISTS', $method . 'Ajax'), 404); + } + } + // The helper file does not exist + else + { + $results = new RuntimeException(JText::sprintf('COM_AJAX_FILE_NOT_EXISTS', 'tpl_' . $template . '/helper.php'), 404); + } + } + // Template is not assigned to the current menu item + else + { + $results = new LogicException(JText::sprintf('COM_AJAX_TEMPLATE_NOT_ACCESSIBLE', 'tpl_' . $template), 404); + } +} + +// Return the results in the desired format +switch ($format) +{ + // JSONinzed + case 'json' : + + echo new JResponseJson($results, null, false, $input->get('ignoreMessages', true, 'bool')); + + break; + + // Handle as raw format + default : + // Output exception + if ($results instanceof Exception) + { + // Log an error + JLog::add($results->getMessage(), JLog::ERROR); + + // Set status header code + $app->setHeader('status', $results->getCode(), true); + + // Echo exception type and message + $out = get_class($results) . ': ' . $results->getMessage(); + } + // Output string/ null + elseif (is_scalar($results)) + { + $out = (string) $results; + } + // Output array/ object + else + { + $out = implode((array) $results); + } + + echo $out; + + break; +} diff --git a/Sites/pages/components/com_banners/banners.php b/Sites/pages/components/com_banners/banners.php new file mode 100644 index 00000000..ad29df2d --- /dev/null +++ b/Sites/pages/components/com_banners/banners.php @@ -0,0 +1,14 @@ +execute(JFactory::getApplication()->input->get('task')); +$controller->redirect(); diff --git a/Sites/pages/components/com_banners/controller.php b/Sites/pages/components/com_banners/controller.php new file mode 100644 index 00000000..68cc85bf --- /dev/null +++ b/Sites/pages/components/com_banners/controller.php @@ -0,0 +1,38 @@ +input->getInt('id', 0); + + if ($id) + { + $model = $this->getModel('Banner', 'BannersModel', array('ignore_request' => true)); + $model->setState('banner.id', $id); + $model->click(); + $this->setRedirect($model->getUrl()); + } + } +} diff --git a/Sites/pages/components/com_banners/helpers/banner.php b/Sites/pages/components/com_banners/helpers/banner.php new file mode 100644 index 00000000..7a17315e --- /dev/null +++ b/Sites/pages/components/com_banners/helpers/banner.php @@ -0,0 +1,46 @@ +getItem(); + + if (empty($item)) + { + throw new Exception(JText::_('JERROR_PAGE_NOT_FOUND'), 404); + } + + $id = $this->getState('banner.id'); + + // Update click count + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->update('#__banners') + ->set('clicks = (clicks + 1)') + ->where('id = ' . (int) $id); + + $db->setQuery($query); + + try + { + $db->execute(); + } + catch (RuntimeException $e) + { + JError::raiseError(500, $e->getMessage()); + } + + // Track clicks + $trackClicks = $item->track_clicks; + + if ($trackClicks < 0 && $item->cid) + { + $trackClicks = $item->client_track_clicks; + } + + if ($trackClicks < 0) + { + $config = JComponentHelper::getParams('com_banners'); + $trackClicks = $config->get('track_clicks'); + } + + if ($trackClicks > 0) + { + $trackDate = JFactory::getDate()->toSql(); + + $query->clear() + ->select($db->quoteName('count')) + ->from('#__banner_tracks') + ->where('track_type=2') + ->where('banner_id=' . (int) $id) + ->where('track_date=' . $db->quote($trackDate)); + + $db->setQuery($query); + + try + { + $db->execute(); + } + catch (RuntimeException $e) + { + JError::raiseError(500, $e->getMessage()); + } + + $count = $db->loadResult(); + + $query->clear(); + + if ($count) + { + // Update count + $query->update('#__banner_tracks') + ->set($db->quoteName('count') . ' = (' . $db->quoteName('count') . ' + 1)') + ->where('track_type=2') + ->where('banner_id=' . (int) $id) + ->where('track_date=' . $db->quote($trackDate)); + } + else + { + // Insert new count + $query->insert('#__banner_tracks') + ->columns( + array( + $db->quoteName('count'), $db->quoteName('track_type'), + $db->quoteName('banner_id'), $db->quoteName('track_date') + ) + ) + ->values('1, 2,' . (int) $id . ',' . $db->quote($trackDate)); + } + + $db->setQuery($query); + + try + { + $db->execute(); + } + catch (RuntimeException $e) + { + JError::raiseError(500, $e->getMessage()); + } + } + } + + /** + * Get the data for a banner. + * + * @return object + * + * @since 1.6 + */ + public function &getItem() + { + if (!isset($this->_item)) + { + /** @var JCacheControllerCallback $cache */ + $cache = JFactory::getCache('com_banners', 'callback'); + + $id = $this->getState('banner.id'); + + // For PHP 5.3 compat we can't use $this in the lambda function below, so grab the database driver now to use it + $db = $this->getDbo(); + + $loader = function ($id) use ($db) + { + $query = $db->getQuery(true) + ->select( + array( + $db->quoteName('a.clickurl', 'clickurl'), + $db->quoteName('a.cid', 'cid'), + $db->quoteName('a.track_clicks', 'track_clicks'), + $db->quoteName('cl.track_clicks', 'client_track_clicks'), + ) + ) + ->from($db->quoteName('#__banners', 'a')) + ->join('LEFT', '#__banner_clients AS cl ON cl.id = a.cid') + ->where('a.id = ' . (int) $id); + + $db->setQuery($query); + + return $db->loadObject(); + }; + + try + { + $this->_item = $cache->get($loader, array($id), md5(__METHOD__ . $id)); + } + catch (JCacheException $e) + { + $this->_item = $loader($id); + } + } + + return $this->_item; + } + + /** + * Get the URL for a banner + * + * @return string + * + * @since 1.5 + */ + public function getUrl() + { + $item = $this->getItem(); + $url = $item->clickurl; + + // Check for links + if (!preg_match('#http[s]?://|index[2]?\.php#', $url)) + { + $url = "http://$url"; + } + + return $url; + } +} diff --git a/Sites/pages/components/com_banners/models/banners.php b/Sites/pages/components/com_banners/models/banners.php new file mode 100644 index 00000000..a0c74af0 --- /dev/null +++ b/Sites/pages/components/com_banners/models/banners.php @@ -0,0 +1,339 @@ +getState('filter.search'); + $id .= ':' . $this->getState('filter.tag_search'); + $id .= ':' . $this->getState('filter.client_id'); + $id .= ':' . serialize($this->getState('filter.category_id')); + $id .= ':' . serialize($this->getState('filter.keywords')); + + return parent::getStoreId($id); + } + + /** + * Method to get a JDatabaseQuery object for retrieving the data set from a database. + * + * @return JDatabaseQuery A JDatabaseQuery object to retrieve the data set. + * + * @since 1.6 + */ + protected function getListQuery() + { + $db = $this->getDbo(); + $query = $db->getQuery(true); + $ordering = $this->getState('filter.ordering'); + $tagSearch = $this->getState('filter.tag_search'); + $cid = $this->getState('filter.client_id'); + $categoryId = $this->getState('filter.category_id'); + $keywords = $this->getState('filter.keywords'); + $randomise = ($ordering === 'random'); + $nullDate = $db->quote($db->getNullDate()); + $nowDate = $db->quote(JFactory::getDate()->toSql()); + + $query->select( + 'a.id as id,' + . 'a.type as type,' + . 'a.name as name,' + . 'a.clickurl as clickurl,' + . 'a.cid as cid,' + . 'a.description as description,' + . 'a.params as params,' + . 'a.custombannercode as custombannercode,' + . 'a.track_impressions as track_impressions,' + . 'cl.track_impressions as client_track_impressions' + ) + ->from('#__banners as a') + ->join('LEFT', '#__banner_clients AS cl ON cl.id = a.cid') + ->where('a.state=1') + ->where('(a.publish_up = ' . $nullDate . ' OR a.publish_up <= ' . $nowDate . ')') + ->where('(a.publish_down = ' . $nullDate . ' OR a.publish_down >= ' . $nowDate . ')') + ->where('(a.imptotal = 0 OR a.impmade < a.imptotal)'); + + if ($cid) + { + $query->where('a.cid = ' . (int) $cid) + ->where('cl.state = 1'); + } + + // Filter by a single or group of categories + if (is_numeric($categoryId)) + { + $type = $this->getState('filter.category_id.include', true) ? '= ' : '<> '; + + // Add subcategory check + $includeSubcategories = $this->getState('filter.subcategories', false); + $categoryEquals = 'a.catid ' . $type . (int) $categoryId; + + if ($includeSubcategories) + { + $levels = (int) $this->getState('filter.max_category_levels', '1'); + + // Create a subquery for the subcategory list + $subQuery = $db->getQuery(true); + $subQuery->select('sub.id') + ->from('#__categories as sub') + ->join('INNER', '#__categories as this ON sub.lft > this.lft AND sub.rgt < this.rgt') + ->where('this.id = ' . (int) $categoryId) + ->where('sub.level <= this.level + ' . $levels); + + // Add the subquery to the main query + $query->where('(' . $categoryEquals . ' OR a.catid IN (' . (string) $subQuery . '))'); + } + else + { + $query->where($categoryEquals); + } + } + elseif (is_array($categoryId) && (count($categoryId) > 0)) + { + $categoryId = ArrayHelper::toInteger($categoryId); + $categoryId = implode(',', $categoryId); + + if ($categoryId != '0') + { + $type = $this->getState('filter.category_id.include', true) ? 'IN' : 'NOT IN'; + $query->where('a.catid ' . $type . ' (' . $categoryId . ')'); + } + } + + if ($tagSearch) + { + if (!$keywords) + { + $query->where('0 != 0'); + } + else + { + $temp = array(); + $config = JComponentHelper::getParams('com_banners'); + $prefix = $config->get('metakey_prefix'); + + if ($categoryId) + { + $query->join('LEFT', '#__categories as cat ON a.catid = cat.id'); + } + + foreach ($keywords as $keyword) + { + $condition1 = 'a.own_prefix=1 ' + . ' AND a.metakey_prefix=SUBSTRING(' . $db->quote($keyword) . ',1,LENGTH( a.metakey_prefix)) ' + . ' OR a.own_prefix=0 ' + . ' AND cl.own_prefix=1 ' + . ' AND cl.metakey_prefix=SUBSTRING(' . $db->quote($keyword) . ',1,LENGTH(cl.metakey_prefix)) ' + . ' OR a.own_prefix=0 ' + . ' AND cl.own_prefix=0 ' + . ' AND ' . ($prefix == substr($keyword, 0, strlen($prefix)) ? '0 = 0' : '0 != 0'); + + $regexp = $db->quote("[[:<:]]" . $db->escape($keyword) . "[[:>:]]"); + $condition2 = "a.metakey " . $query->regexp($regexp) . " "; + + if ($cid) + { + $condition2 .= " OR cl.metakey " . $query->regexp($regexp) . " "; + } + + if ($categoryId) + { + $condition2 .= " OR cat.metakey " . $query->regexp($regexp) . " "; + } + + $temp[] = "($condition1) AND ($condition2)"; + } + + $query->where('(' . implode(' OR ', $temp) . ')'); + } + } + + // Filter by language + if ($this->getState('filter.language')) + { + $query->where('a.language in (' . $db->quote(JFactory::getLanguage()->getTag()) . ',' . $db->quote('*') . ')'); + } + + $query->order('a.sticky DESC,' . ($randomise ? $query->Rand() : 'a.ordering')); + + return $query; + } + + /** + * Get a list of banners. + * + * @return array + * + * @since 1.6 + */ + public function getItems() + { + if ($this->getState('filter.tag_search')) + { + // Filter out empty keywords. + $keywords = array_values(array_filter(array_map('trim', $this->getState('filter.keywords')), 'strlen')); + + // Re-set state before running the query. + $this->setState('filter.keywords', $keywords); + + // If no keywords are provided, avoid running the query. + if (!$keywords) + { + $this->cache['items'] = array(); + + return $this->cache['items']; + } + } + + if (!isset($this->cache['items'])) + { + $this->cache['items'] = parent::getItems(); + + foreach ($this->cache['items'] as &$item) + { + $item->params = new Registry($item->params); + } + } + + return $this->cache['items']; + } + + /** + * Makes impressions on a list of banners + * + * @return void + * + * @since 1.6 + */ + public function impress() + { + $trackDate = JFactory::getDate()->toSql(); + $items = $this->getItems(); + $db = $this->getDbo(); + $query = $db->getQuery(true); + + if (!count($items)) + { + return; + } + + foreach ($items as $item) + { + $bid[] = (int) $item->id; + } + + // Increment impression made + $query->clear() + ->update('#__banners') + ->set('impmade = (impmade + 1)') + ->where('id IN (' . implode(',', $bid) . ')'); + $db->setQuery($query); + + try + { + $db->execute(); + } + catch (JDatabaseExceptionExecuting $e) + { + JError::raiseError(500, $e->getMessage()); + } + + foreach ($items as $item) + { + // Track impressions + $trackImpressions = $item->track_impressions; + + if ($trackImpressions < 0 && $item->cid) + { + $trackImpressions = $item->client_track_impressions; + } + + if ($trackImpressions < 0) + { + $config = JComponentHelper::getParams('com_banners'); + $trackImpressions = $config->get('track_impressions'); + } + + if ($trackImpressions > 0) + { + // Is track already created? + // Update count + $query->clear(); + $query->update('#__banner_tracks') + ->set($db->quoteName('count') . ' = (' . $db->quoteName('count') . ' + 1)') + ->where('track_type=1') + ->where('banner_id=' . (int) $item->id) + ->where('track_date=' . $db->quote($trackDate)); + + $db->setQuery($query); + + try + { + $db->execute(); + } + catch (JDatabaseExceptionExecuting $e) + { + JError::raiseError(500, $e->getMessage()); + } + + if ($db->getAffectedRows() === 0) + { + // Insert new count + $query->clear(); + + $query->insert('#__banner_tracks') + ->columns( + array( + $db->quoteName('count'), $db->quoteName('track_type'), + $db->quoteName('banner_id'), $db->quoteName('track_date') + ) + ) + ->values('1, 1, ' . (int) $item->id . ', ' . $db->quote($trackDate)); + + $db->setQuery($query); + + try + { + $db->execute(); + } + catch (JDatabaseExceptionExecuting $e) + { + JError::raiseError(500, $e->getMessage()); + } + } + } + } + } +} diff --git a/Sites/pages/components/com_banners/router.php b/Sites/pages/components/com_banners/router.php new file mode 100644 index 00000000..86c72b16 --- /dev/null +++ b/Sites/pages/components/com_banners/router.php @@ -0,0 +1,143 @@ +build($query); +} + +/** + * Parse the segments of a URL. + * + * This function is a proxy for the new router interface + * for old SEF extensions. + * + * @param array $segments The segments of the URL to parse. + * + * @return array The URL attributes to be used by the application. + * + * @since 3.3 + * @deprecated 4.0 Use Class based routers instead + */ +function bannersParseRoute($segments) +{ + $router = new BannersRouter; + + return $router->parse($segments); +} diff --git a/Sites/pages/components/com_config/config.php b/Sites/pages/components/com_config/config.php new file mode 100644 index 00000000..4322c399 --- /dev/null +++ b/Sites/pages/components/com_config/config.php @@ -0,0 +1,27 @@ +setHeader('Expires', 'Mon, 26 Jul 1997 05:00:00 GMT', true); + +$controllerHelper = new ConfigControllerHelper; +$controller = $controllerHelper->parseController($app); + +$controller->prefix = 'Config'; + +// Perform the Request task +$controller->execute(); diff --git a/Sites/pages/components/com_config/controller/cancel.php b/Sites/pages/components/com_config/controller/cancel.php new file mode 100644 index 00000000..c8eddaff --- /dev/null +++ b/Sites/pages/components/com_config/controller/cancel.php @@ -0,0 +1,39 @@ +app->redirect(JUri::base()); + } +} diff --git a/Sites/pages/components/com_config/controller/canceladmin.php b/Sites/pages/components/com_config/controller/canceladmin.php new file mode 100644 index 00000000..d770e1b1 --- /dev/null +++ b/Sites/pages/components/com_config/controller/canceladmin.php @@ -0,0 +1,83 @@ +app->enqueueMessage(JText::_('JINVALID_TOKEN_NOTICE')); + $this->app->redirect('index.php'); + } + + if (empty($this->context)) + { + $this->context = $this->option . '.edit' . $this->context; + } + + // Redirect. + $this->app->setUserState($this->context . '.data', null); + + if (!empty($this->redirect)) + { + // Don't redirect to an external URL. + if (!JUri::isInternal($this->redirect)) + { + $this->redirect = JUri::base(); + } + + $this->app->redirect($this->redirect); + } + else + { + parent::execute(); + } + } +} diff --git a/Sites/pages/components/com_config/controller/cmsbase.php b/Sites/pages/components/com_config/controller/cmsbase.php new file mode 100644 index 00000000..6480bb85 --- /dev/null +++ b/Sites/pages/components/com_config/controller/cmsbase.php @@ -0,0 +1,52 @@ +app->enqueueMessage(JText::_('JINVALID_TOKEN_NOTICE')); + $this->app->redirect('index.php'); + } + + // Get the application + $this->app = $this->getApplication(); + $this->app->redirect('index.php?option=' . $this->input->get('option')); + + $this->componentFolder = $this->input->getWord('option', 'com_content'); + $this->viewName = $this->input->getWord('view'); + + return $this; + } +} diff --git a/Sites/pages/components/com_config/controller/config/display.php b/Sites/pages/components/com_config/controller/config/display.php new file mode 100644 index 00000000..a0636e2f --- /dev/null +++ b/Sites/pages/components/com_config/controller/config/display.php @@ -0,0 +1,98 @@ +getApplication(); + + // Get the document object. + $document = JFactory::getDocument(); + + $viewName = $this->input->getWord('view', 'config'); + $viewFormat = $document->getType(); + $layoutName = $this->input->getWord('layout', 'default'); + + // Access backend com_config + JLoader::registerPrefix(ucfirst($viewName), JPATH_ADMINISTRATOR . '/components/com_config'); + $displayClass = new ConfigControllerApplicationDisplay; + + // Set backend required params + $document->setType('json'); + $app->input->set('view', 'application'); + + // Execute backend controller + $serviceData = json_decode($displayClass->execute(), true); + + // Reset params back after requesting from service + $document->setType('html'); + $app->input->set('view', $viewName); + + // Register the layout paths for the view + $paths = new SplPriorityQueue; + $paths->insert(JPATH_COMPONENT . '/view/' . $viewName . '/tmpl', 'normal'); + + $viewClass = 'ConfigView' . ucfirst($viewName) . ucfirst($viewFormat); + $modelClass = 'ConfigModel' . ucfirst($viewName); + + if (class_exists($viewClass)) + { + if ($viewName !== 'close') + { + $model = new $modelClass; + + // Access check. + if (!JFactory::getUser()->authorise('core.admin', $model->getState('component.option'))) + { + return; + } + } + + $view = new $viewClass($model, $paths); + + $view->setLayout($layoutName); + + // Push document object into the view. + $view->document = $document; + + // Load form and bind data + $form = $model->getForm(); + + if ($form) + { + $form->bind($serviceData); + } + + // Set form and data to the view + $view->form = &$form; + $view->data = &$serviceData; + + // Render view. + echo $view->render(); + } + + return true; + } +} diff --git a/Sites/pages/components/com_config/controller/config/save.php b/Sites/pages/components/com_config/controller/config/save.php new file mode 100644 index 00000000..2fd3195a --- /dev/null +++ b/Sites/pages/components/com_config/controller/config/save.php @@ -0,0 +1,113 @@ +app->enqueueMessage(JText::_('JINVALID_TOKEN_NOTICE')); + $this->app->redirect('index.php'); + } + + // Check if the user is authorized to do this. + if (!JFactory::getUser()->authorise('core.admin')) + { + $this->app->enqueueMessage(JText::_('JERROR_ALERTNOAUTHOR')); + $this->app->redirect('index.php'); + } + + // Set FTP credentials, if given. + JClientHelper::setCredentialsFromRequest('ftp'); + + $model = new ConfigModelConfig; + $form = $model->getForm(); + $data = $this->input->post->get('jform', array(), 'array'); + + // Validate the posted data. + $return = $model->validate($form, $data); + + // Check for validation errors. + if ($return === false) + { + /* + * The validate method enqueued all messages for us, so we just need to redirect back. + */ + + // Save the data in the session. + $this->app->setUserState('com_config.config.global.data', $data); + + // Redirect back to the edit screen. + $this->app->redirect(JRoute::_('index.php?option=com_config&controller=config.display.config', false)); + } + + // Attempt to save the configuration. + $data = $return; + + // Access backend com_config + JLoader::registerPrefix('Config', JPATH_ADMINISTRATOR . '/components/com_config'); + $saveClass = new ConfigControllerApplicationSave; + + // Get a document object + $document = JFactory::getDocument(); + + // Set backend required params + $document->setType('json'); + + // Execute backend controller + $return = $saveClass->execute(); + + // Reset params back after requesting from service + $document->setType('html'); + + // Check the return value. + if ($return === false) + { + /* + * The save method enqueued all messages for us, so we just need to redirect back. + */ + + // Save the data in the session. + $this->app->setUserState('com_config.config.global.data', $data); + + // Save failed, go back to the screen and display a notice. + $this->app->redirect(JRoute::_('index.php?option=com_config&controller=config.display.config', false)); + } + + // Redirect back to com_config display + $this->app->enqueueMessage(JText::_('COM_CONFIG_SAVE_SUCCESS')); + $this->app->redirect(JRoute::_('index.php?option=com_config&controller=config.display.config', false)); + + return true; + } +} diff --git a/Sites/pages/components/com_config/controller/display.php b/Sites/pages/components/com_config/controller/display.php new file mode 100644 index 00000000..10ec8f8e --- /dev/null +++ b/Sites/pages/components/com_config/controller/display.php @@ -0,0 +1,119 @@ +input->getWord('option', 'com_config'); + + if ($this->app->isClient('administrator')) + { + $viewName = $this->input->getWord('view', 'application'); + } + else + { + $viewName = $this->input->getWord('view', 'config'); + } + + $viewFormat = $document->getType(); + $layoutName = $this->input->getWord('layout', 'default'); + + // Register the layout paths for the view + $paths = new SplPriorityQueue; + + if ($this->app->isClient('administrator')) + { + $paths->insert(JPATH_ADMINISTRATOR . '/components/' . $componentFolder . '/view/' . $viewName . '/tmpl', 1); + } + else + { + $paths->insert(JPATH_BASE . '/components/' . $componentFolder . '/view/' . $viewName . '/tmpl', 1); + } + + $viewClass = $this->prefix . 'View' . ucfirst($viewName) . ucfirst($viewFormat); + $modelClass = $this->prefix . 'Model' . ucfirst($viewName); + + if (class_exists($viewClass)) + { + $model = new $modelClass; + $component = $model->getState()->get('component.option'); + + // Make sure com_joomlaupdate and com_privacy can only be accessed by SuperUser + if (in_array(strtolower($component), array('com_joomlaupdate', 'com_privacy')) + && !JFactory::getUser()->authorise('core.admin')) + { + $this->app->enqueueMessage(JText::_('JERROR_ALERTNOAUTHOR'), 'error'); + + return; + } + + // Access check. + if (!JFactory::getUser()->authorise('core.admin', $component) + && !JFactory::getUser()->authorise('core.options', $component)) + { + $this->app->enqueueMessage(JText::_('JERROR_ALERTNOAUTHOR'), 'error'); + + return; + } + + $view = new $viewClass($model, $paths); + + $view->setLayout($layoutName); + + // Push document object into the view. + $view->document = $document; + + // Reply for service requests + if ($viewFormat === 'json') + { + $this->app->allowCache(false); + return $view->render(); + } + + // Render view. + echo $view->render(); + } + + return true; + } +} diff --git a/Sites/pages/components/com_config/controller/helper.php b/Sites/pages/components/com_config/controller/helper.php new file mode 100644 index 00000000..0d40c93a --- /dev/null +++ b/Sites/pages/components/com_config/controller/helper.php @@ -0,0 +1,120 @@ +input->get('task')) + { + // Toolbar expects old style but we are using new style + // Remove when toolbar can handle either directly + if (strpos($task, '/') !== false) + { + $tasks = explode('/', $task); + } + else + { + $tasks = explode('.', $task); + } + } + elseif ($controllerTask = $app->input->get('controller')) + { + // Temporary solution + if (strpos($controllerTask, '/') !== false) + { + $tasks = explode('/', $controllerTask); + } + else + { + $tasks = explode('.', $controllerTask); + } + } + + if (empty($tasks[0]) || $tasks[0] === 'Config') + { + $location = 'Config'; + } + else + { + $location = ucfirst(strtolower($tasks[0])); + } + + if (empty($tasks[1])) + { + $activity = 'Display'; + } + else + { + $activity = ucfirst(strtolower($tasks[1])); + } + + $view = ''; + + if (!empty($tasks[2])) + { + $view = ucfirst(strtolower($tasks[2])); + } + + // Some special handling for com_config administrator + $option = $app->input->get('option'); + + if ($option === 'com_config' && $app->isClient('administrator')) + { + $component = $app->input->get('component'); + + if (!empty($component)) + { + $view = 'Component'; + } + elseif ($option === 'com_config') + { + $view = 'Application'; + } + } + + $controllerName = $location . 'Controller' . $view . $activity; + + if (!class_exists($controllerName)) + { + return false; + } + + $controller = new $controllerName; + $controller->options = array(); + $controller->options = $tasks; + + return $controller; + } +} diff --git a/Sites/pages/components/com_config/controller/modules/cancel.php b/Sites/pages/components/com_config/controller/modules/cancel.php new file mode 100644 index 00000000..307d2590 --- /dev/null +++ b/Sites/pages/components/com_config/controller/modules/cancel.php @@ -0,0 +1,66 @@ +authorise('module.edit.frontend', 'com_modules.module.' . $this->input->get('id'))) + { + $this->app->enqueueMessage(JText::_('JERROR_ALERTNOAUTHOR')); + $this->app->redirect('index.php'); + } + + $this->context = 'com_config.config.global'; + + // Get returnUri + $returnUri = $this->input->post->get('return', null, 'base64'); + + if (!empty($returnUri)) + { + $this->redirect = base64_decode(urldecode($returnUri)); + } + else + { + $this->redirect = JUri::base(); + } + + $id = $this->input->getInt('id'); + + // Access backend com_module + JLoader::register('ModulesControllerModule', JPATH_ADMINISTRATOR . '/components/com_modules/controllers/module.php'); + JLoader::register('ModulesViewModule', JPATH_ADMINISTRATOR . '/components/com_modules/views/module/view.json.php'); + JLoader::register('ModulesModelModule', JPATH_ADMINISTRATOR . '/components/com_modules/models/module.php'); + + $cancelClass = new ModulesControllerModule; + + $cancelClass->cancel($id); + + parent::execute(); + } +} diff --git a/Sites/pages/components/com_config/controller/modules/display.php b/Sites/pages/components/com_config/controller/modules/display.php new file mode 100644 index 00000000..7ddf6fbb --- /dev/null +++ b/Sites/pages/components/com_config/controller/modules/display.php @@ -0,0 +1,126 @@ +getApplication(); + + // Get the document object. + $document = JFactory::getDocument(); + + $viewName = $this->input->getWord('view', 'modules'); + $viewFormat = $document->getType(); + $layoutName = $this->input->getWord('layout', 'default'); + $returnUri = $this->input->get->get('return', null, 'base64'); + + // Construct redirect URI + if (!empty($returnUri)) + { + $redirect = base64_decode(urldecode($returnUri)); + + // Don't redirect to an external URL. + if (!JUri::isInternal($redirect)) + { + $redirect = JUri::base(); + } + } + else + { + $redirect = JUri::base(); + } + + // Access backend com_module + JLoader::register('ModulesController', JPATH_ADMINISTRATOR . '/components/com_modules/controller.php'); + JLoader::register('ModulesViewModule', JPATH_ADMINISTRATOR . '/components/com_modules/views/module/view.json.php'); + JLoader::register('ModulesModelModule', JPATH_ADMINISTRATOR . '/components/com_modules/models/module.php'); + + $displayClass = new ModulesController; + + // Get the parameters of the module with Id + $document->setType('json'); + + // Execute backend controller + if (!($serviceData = json_decode($displayClass->display(), true))) + { + $app->redirect($redirect); + } + + // Reset params back after requesting from service + $document->setType('html'); + $app->input->set('view', $viewName); + + // Register the layout paths for the view + $paths = new SplPriorityQueue; + $paths->insert(JPATH_COMPONENT . '/view/' . $viewName . '/tmpl', 'normal'); + + $viewClass = 'ConfigView' . ucfirst($viewName) . ucfirst($viewFormat); + $modelClass = 'ConfigModel' . ucfirst($viewName); + + if (class_exists($viewClass)) + { + $model = new $modelClass; + + // Access check. + $user = JFactory::getUser(); + + if (!$user->authorise('module.edit.frontend', 'com_modules.module.' . $serviceData['id'])) + { + $app->enqueueMessage(JText::_('JERROR_ALERTNOAUTHOR'), 'error'); + $app->redirect($redirect); + } + + // Need to add module name to the state of model + $model->getState()->set('module.name', $serviceData['module']); + + $view = new $viewClass($model, $paths); + + $view->setLayout($layoutName); + + // Push document object into the view. + $view->document = $document; + + // Load form and bind data + $form = $model->getForm(); + + if ($form) + { + $form->bind($serviceData); + } + + // Set form and data to the view + $view->form = &$form; + $view->item = &$serviceData; + + // Render view. + echo $view->render(); + } + + return true; + } +} diff --git a/Sites/pages/components/com_config/controller/modules/save.php b/Sites/pages/components/com_config/controller/modules/save.php new file mode 100644 index 00000000..750b0c6b --- /dev/null +++ b/Sites/pages/components/com_config/controller/modules/save.php @@ -0,0 +1,124 @@ +app->enqueueMessage(JText::_('JINVALID_TOKEN')); + $this->app->redirect('index.php'); + } + + // Check if the user is authorized to do this. + $user = JFactory::getUser(); + + if (!$user->authorise('module.edit.frontend', 'com_modules.module.' . $this->input->get('id'))) + { + $this->app->enqueueMessage(JText::_('JERROR_ALERTNOAUTHOR'), 'error'); + $this->app->redirect('index.php'); + } + + // Set FTP credentials, if given. + JClientHelper::setCredentialsFromRequest('ftp'); + + // Get submitted module id + $moduleId = '&id=' . $this->input->get('id'); + + // Get returnUri + $returnUri = $this->input->post->get('return', null, 'base64'); + $redirect = ''; + + if (!empty($returnUri)) + { + $redirect = '&return=' . $returnUri; + } + + // Access backend com_modules to be done + JLoader::register('ModulesControllerModule', JPATH_ADMINISTRATOR . '/components/com_modules/controllers/module.php'); + JLoader::register('ModulesModelModule', JPATH_ADMINISTRATOR . '/components/com_modules/models/module.php'); + + $controllerClass = new ModulesControllerModule; + + // Get a document object + $document = JFactory::getDocument(); + + // Set backend required params + $document->setType('json'); + + // Execute backend controller + $return = $controllerClass->save(); + + // Reset params back after requesting from service + $document->setType('html'); + + // Check the return value. + if ($return === false) + { + // Save the data in the session. + $data = $this->input->post->get('jform', array(), 'array'); + + $this->app->setUserState('com_config.modules.global.data', $data); + + // Save failed, go back to the screen and display a notice. + $this->app->enqueueMessage(JText::_('JERROR_SAVE_FAILED')); + $this->app->redirect(JRoute::_('index.php?option=com_config&controller=config.display.modules' . $moduleId . $redirect, false)); + } + + // Redirect back to com_config display + $this->app->enqueueMessage(JText::_('COM_CONFIG_MODULES_SAVE_SUCCESS')); + + // Set the redirect based on the task. + switch ($this->options[3]) + { + case 'apply': + $this->app->redirect(JRoute::_('index.php?option=com_config&controller=config.display.modules' . $moduleId . $redirect, false)); + break; + + case 'save': + default: + + if (!empty($returnUri)) + { + $redirect = base64_decode(urldecode($returnUri)); + + // Don't redirect to an external URL. + if (!JUri::isInternal($redirect)) + { + $redirect = JUri::base(); + } + } + else + { + $redirect = JUri::base(); + } + + $this->app->redirect($redirect); + break; + } + } +} diff --git a/Sites/pages/components/com_config/controller/templates/display.php b/Sites/pages/components/com_config/controller/templates/display.php new file mode 100644 index 00000000..1e3c6760 --- /dev/null +++ b/Sites/pages/components/com_config/controller/templates/display.php @@ -0,0 +1,102 @@ +getApplication(); + + // Get the document object. + $document = JFactory::getDocument(); + + $viewName = $this->input->getWord('view', 'templates'); + $viewFormat = $document->getType(); + $layoutName = $this->input->getWord('layout', 'default'); + + // Access backend com_config + JLoader::register('TemplatesController', JPATH_ADMINISTRATOR . '/components/com_templates/controller.php'); + JLoader::register('TemplatesViewStyle', JPATH_ADMINISTRATOR . '/components/com_templates/views/style/view.json.php'); + JLoader::register('TemplatesModelStyle', JPATH_ADMINISTRATOR . '/components/com_templates/models/style.php'); + + $displayClass = new TemplatesController; + + // Set backend required params + $document->setType('json'); + $this->input->set('id', $app->getTemplate(true)->id); + + // Execute backend controller + $serviceData = json_decode($displayClass->display(), true); + + // Reset params back after requesting from service + $document->setType('html'); + $this->input->set('view', $viewName); + + // Register the layout paths for the view + $paths = new SplPriorityQueue; + $paths->insert(JPATH_COMPONENT . '/view/' . $viewName . '/tmpl', 'normal'); + + $viewClass = 'ConfigView' . ucfirst($viewName) . ucfirst($viewFormat); + $modelClass = 'ConfigModel' . ucfirst($viewName); + + if (class_exists($viewClass)) + { + if ($viewName !== 'close') + { + $model = new $modelClass; + + // Access check. + if (!JFactory::getUser()->authorise('core.admin', $model->getState('component.option'))) + { + $app->enqueueMessage(JText::_('JERROR_ALERTNOAUTHOR'), 'error'); + + return; + } + } + + $view = new $viewClass($model, $paths); + + $view->setLayout($layoutName); + + // Push document object into the view. + $view->document = $document; + + // Load form and bind data + $form = $model->getForm(); + + if ($form) + { + $form->bind($serviceData); + } + + // Set form and data to the view + $view->form = &$form; + + // Render view. + echo $view->render(); + } + + return true; + } +} diff --git a/Sites/pages/components/com_config/controller/templates/save.php b/Sites/pages/components/com_config/controller/templates/save.php new file mode 100644 index 00000000..b93854a5 --- /dev/null +++ b/Sites/pages/components/com_config/controller/templates/save.php @@ -0,0 +1,88 @@ +redirect('index.php', JText::_('JINVALID_TOKEN')); + } + + // Check if the user is authorized to do this. + if (!JFactory::getUser()->authorise('core.admin')) + { + JFactory::getApplication()->redirect('index.php', JText::_('JERROR_ALERTNOAUTHOR')); + + return; + } + + // Set FTP credentials, if given. + JClientHelper::setCredentialsFromRequest('ftp'); + + $app = JFactory::getApplication(); + + // Access backend com_templates + JLoader::register('TemplatesControllerStyle', JPATH_ADMINISTRATOR . '/components/com_templates/controllers/style.php'); + JLoader::register('TemplatesModelStyle', JPATH_ADMINISTRATOR . '/components/com_templates/models/style.php'); + JLoader::register('TemplatesTableStyle', JPATH_ADMINISTRATOR . '/components/com_templates/tables/style.php'); + $controllerClass = new TemplatesControllerStyle; + + // Get a document object + $document = JFactory::getDocument(); + + // Set backend required params + $document->setType('json'); + $this->input->set('id', $app->getTemplate(true)->id); + + // Execute backend controller + $return = $controllerClass->save(); + + // Reset params back after requesting from service + $document->setType('html'); + + // Check the return value. + if ($return === false) + { + // Save the data in the session. + $app->setUserState('com_config.config.global.data', $data); + + // Save failed, go back to the screen and display a notice. + $message = JText::sprintf('JERROR_SAVE_FAILED'); + + $app->redirect(JRoute::_('index.php?option=com_config&controller=config.display.templates', false), $message, 'error'); + + return false; + } + + // Set the success message. + $message = JText::_('COM_CONFIG_SAVE_SUCCESS'); + + // Redirect back to com_config display + $app->redirect(JRoute::_('index.php?option=com_config&controller=config.display.templates', false), $message); + + return true; + } +} diff --git a/Sites/pages/components/com_config/model/cms.php b/Sites/pages/components/com_config/model/cms.php new file mode 100644 index 00000000..fc361497 --- /dev/null +++ b/Sites/pages/components/com_config/model/cms.php @@ -0,0 +1,280 @@ +option)) + { + $r = null; + + if (!preg_match('/(.*)Model/i', get_class($this), $r)) + { + throw new Exception(JText::_('JLIB_APPLICATION_ERROR_MODEL_GET_NAME'), 500); + } + + $this->option = 'com_' . strtolower($r[1]); + } + + // 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 model state + if (array_key_exists('state', $config)) + { + $this->state = $config['state']; + } + else + { + $this->state = new Registry; + } + + // Set the model dbo + if (array_key_exists('dbo', $config)) + { + $this->db = $config['dbo']; + } + + // Register the paths for the form + $paths = $this->registerTablePaths($config); + + // Set the internal state marker - used to ignore setting state from the request + if (!empty($config['ignore_request'])) + { + $this->__state_set = true; + } + + // Set the clean cache event + if (isset($config['event_clean_cache'])) + { + $this->event_clean_cache = $config['event_clean_cache']; + } + elseif (empty($this->event_clean_cache)) + { + $this->event_clean_cache = 'onContentCleanCache'; + } + + $state = new Registry($config); + + parent::__construct($state); + } + + /** + * Method to get the model 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 3.2 + * @throws Exception + */ + public function getName() + { + if (empty($this->name)) + { + $r = null; + + if (!preg_match('/Model(.*)/i', get_class($this), $r)) + { + throw new Exception(JText::_('JLIB_APPLICATION_ERROR_MODEL_GET_NAME'), 500); + } + + $this->name = strtolower($r[1]); + } + + return $this->name; + } + + /** + * Method to get model state variables + * + * @return object The property where specified, the state object where omitted + * + * @since 3.2 + */ + public function getState() + { + if (!$this->__state_set) + { + // Protected method to auto-populate the model state. + $this->populateState(); + + // Set the model state set flag to true. + $this->__state_set = true; + } + + return $this->state; + } + + /** + * Method to register paths for tables + * + * @param array $config Configuration array + * + * @return object The property where specified, the state object where omitted + * + * @since 3.2 + */ + public function registerTablePaths($config = array()) + { + // Set the default view search path + if (array_key_exists('table_path', $config)) + { + $this->addTablePath($config['table_path']); + } + elseif (defined('JPATH_COMPONENT_ADMINISTRATOR')) + { + // Register the paths for the form + $paths = new SplPriorityQueue; + $paths->insert(JPATH_COMPONENT_ADMINISTRATOR . '/table', 'normal'); + + // For legacy purposes. Remove for 4.0 + $paths->insert(JPATH_COMPONENT_ADMINISTRATOR . '/tables', 'normal'); + } + } + + /** + * Clean the cache + * + * @param string $group The cache group + * @param integer $clientId The ID of the client + * + * @return void + * + * @since 3.2 + */ + protected function cleanCache($group = null, $clientId = 0) + { + $conf = JFactory::getConfig(); + $dispatcher = JEventDispatcher::getInstance(); + + $options = array( + 'defaultgroup' => $group ?: (isset($this->option) ? $this->option : JFactory::getApplication()->input->get('option')), + 'cachebase' => $clientId ? JPATH_ADMINISTRATOR . '/cache' : $conf->get('cache_path', JPATH_SITE . '/cache')); + + $cache = JCache::getInstance('callback', $options); + $cache->clean(); + + // Trigger the onContentCleanCache event. + $dispatcher->trigger($this->event_clean_cache, $options); + } + + /** + * Method to auto-populate the model state. + * + * This method should only be called once per instantiation and is designed + * to be called on the first call to the getState() method unless the model + * configuration flag to ignore the request is set. + * + * @return void + * + * @note Calling getState in this method will result in recursion. + * @since 3.2 + */ + protected function populateState() + { + $this->loadState(); + } + + /** + * Method to test whether a record can be deleted. + * + * @param object $record A record object. + * + * @return boolean True if allowed to delete the record. Defaults to the permission set in the component. + * + * @since 3.2 + */ + protected function canDelete($record) + { + if (empty($record->id) || $record->published != -2) + { + return false; + } + + return JFactory::getUser()->authorise('core.delete', $this->option); + } + + /** + * Method to test whether a record can have its state changed. + * + * @param object $record A record object. + * + * @return boolean True if allowed to change the state of the record. Defaults to the permission set in the component. + * + * @since 3.2 + */ + protected function canEditState($record) + { + return JFactory::getUser()->authorise('core.edit.state', $this->option); + } +} diff --git a/Sites/pages/components/com_config/model/config.php b/Sites/pages/components/com_config/model/config.php new file mode 100644 index 00000000..a5cdbae8 --- /dev/null +++ b/Sites/pages/components/com_config/model/config.php @@ -0,0 +1,41 @@ +loadForm('com_config.config', 'config', array('control' => 'jform', 'load_data' => $loadData)); + + if (empty($form)) + { + return false; + } + + return $form; + } +} diff --git a/Sites/pages/components/com_config/model/form.php b/Sites/pages/components/com_config/model/form.php new file mode 100644 index 00000000..5dafb86c --- /dev/null +++ b/Sites/pages/components/com_config/model/form.php @@ -0,0 +1,330 @@ +getTable(); + + if (!$table->load($pk)) + { + throw new RuntimeException($table->getError()); + } + + // Check if this is the user has previously checked out the row. + if ($table->checked_out > 0 && $table->checked_out != $user->get('id') && !$user->authorise('core.admin', 'com_checkin')) + { + throw new RuntimeException($table->getError()); + } + + // Attempt to check the row in. + if (!$table->checkin($pk)) + { + throw new RuntimeException($table->getError()); + } + } + + return true; + } + + /** + * Method to check-out a row for editing. + * + * @param integer $pk The numeric id of the primary key. + * + * @return boolean False on failure or error, true otherwise. + * + * @since 3.2 + */ + public function checkout($pk = null) + { + // Only attempt to check the row in if it exists. + if ($pk) + { + $user = JFactory::getUser(); + + // Get an instance of the row to checkout. + $table = $this->getTable(); + + if (!$table->load($pk)) + { + throw new RuntimeException($table->getError()); + } + + // Check if this is the user having previously checked out the row. + if ($table->checked_out > 0 && $table->checked_out != $user->get('id')) + { + throw new RuntimeException(JText::_('JLIB_APPLICATION_ERROR_CHECKOUT_USER_MISMATCH')); + } + + // Attempt to check the row out. + if (!$table->checkout($user->get('id'), $pk)) + { + throw new RuntimeException($table->getError()); + } + } + + return true; + } + + /** + * Abstract method for getting the form from the model. + * + * @param array $data Data for the form. + * @param boolean $loadData True if the form is to load its own data (default case), false if not. + * + * @return mixed A JForm object on success, false on failure + * + * @since 3.2 + */ + abstract public function getForm($data = array(), $loadData = true); + + /** + * Method to get a form object. + * + * @param string $name The name of the form. + * @param string $source The form source. Can be XML string if file flag is set to false. + * @param array $options Optional array of options for the form creation. + * @param boolean $clear Optional argument to force load a new form. + * @param string $xpath An optional xpath to search for the fields. + * + * @return mixed JForm object on success, False on error. + * + * @see JForm + * @since 3.2 + */ + protected function loadForm($name, $source = null, $options = array(), $clear = false, $xpath = false) + { + // Handle the optional arguments. + $options['control'] = ArrayHelper::getValue($options, 'control', false); + + // Create a signature hash. + $hash = sha1($source . serialize($options)); + + // Check if we can use a previously loaded form. + if (isset($this->_forms[$hash]) && !$clear) + { + return $this->_forms[$hash]; + } + + // Get the form. + // Register the paths for the form -- failing here + $paths = new SplPriorityQueue; + $paths->insert(JPATH_COMPONENT_ADMINISTRATOR . '/model/form', 'normal'); + $paths->insert(JPATH_COMPONENT_ADMINISTRATOR . '/model/field', 'normal'); + $paths->insert(JPATH_COMPONENT . '/model/form', 'normal'); + $paths->insert(JPATH_COMPONENT . '/model/field', 'normal'); + $paths->insert(JPATH_COMPONENT . '/model/rule', 'normal'); + + // Legacy support to be removed in 4.0. -- failing here + $paths->insert(JPATH_COMPONENT . '/models/forms', 'normal'); + $paths->insert(JPATH_COMPONENT . '/models/fields', 'normal'); + $paths->insert(JPATH_COMPONENT . '/models/rules', 'normal'); + + // Solution until JForm supports splqueue + JForm::addFormPath(JPATH_COMPONENT . '/models/forms'); + JForm::addFieldPath(JPATH_COMPONENT . '/models/fields'); + JForm::addFormPath(JPATH_COMPONENT_ADMINISTRATOR . '/model/form'); + JForm::addFieldPath(JPATH_COMPONENT_ADMINISTRATOR . '/model/field'); + JForm::addFormPath(JPATH_COMPONENT . '/model/form'); + JForm::addFieldPath(JPATH_COMPONENT . '/model/field'); + + try + { + $form = JForm::getInstance($name, $source, $options, false, $xpath); + + if (isset($options['load_data']) && $options['load_data']) + { + // Get the data for the form. + $data = $this->loadFormData(); + } + else + { + $data = array(); + } + + // Allow for additional modification of the form, and events to be triggered. + // We pass the data because plugins may require it. + $this->preprocessForm($form, $data); + + // Load the data into the form after the plugins have operated. + $form->bind($data); + } + catch (Exception $e) + { + JFactory::getApplication()->enqueueMessage($e->getMessage()); + + return false; + } + + // Store the form for later. + $this->_forms[$hash] = $form; + + return $form; + } + + /** + * Method to get the data that should be injected in the form. + * + * @return array The default data is an empty array. + * + * @since 3.2 + */ + protected function loadFormData() + { + return array(); + } + + /** + * Method to allow derived classes to preprocess the data. + * + * @param string $context The context identifier. + * @param mixed &$data The data to be processed. It gets altered directly. + * + * @return void + * + * @since 3.2 + */ + protected function preprocessData($context, &$data) + { + // Get the dispatcher and load the users plugins. + $dispatcher = JEventDispatcher::getInstance(); + JPluginHelper::importPlugin('content'); + + // Trigger the data preparation event. + $results = $dispatcher->trigger('onContentPrepareData', array($context, $data)); + + // Check for errors encountered while preparing the data. + if (count($results) > 0 && in_array(false, $results, true)) + { + JFactory::getApplication()->enqueueMessage($dispatcher->getError(), 'error'); + } + } + + /** + * Method to allow derived classes to preprocess the form. + * + * @param JForm $form A JForm object. + * @param mixed $data The data expected for the form. + * @param string $group The name of the plugin group to import (defaults to "content"). + * + * @return void + * + * @see JFormField + * @since 3.2 + * @throws Exception if there is an error in the form event. + */ + protected function preprocessForm(JForm $form, $data, $group = 'content') + { + // Import the appropriate plugin group. + JPluginHelper::importPlugin($group); + + // Get the dispatcher. + $dispatcher = JEventDispatcher::getInstance(); + + // Trigger the form preparation event. + $results = $dispatcher->trigger('onContentPrepareForm', array($form, $data)); + + // Check for errors encountered while preparing the form. + if (count($results) && in_array(false, $results, true)) + { + // Get the last error. + $error = $dispatcher->getError(); + + if (!($error instanceof Exception)) + { + throw new Exception($error); + } + } + } + + /** + * Method to validate the form data. + * + * @param JForm $form The form to validate against. + * @param array $data The data to validate. + * @param string $group The name of the field group to validate. + * + * @return mixed Array of filtered data if valid, false otherwise. + * + * @see JFormRule + * @see JFilterInput + * @since 3.2 + */ + public function validate($form, $data, $group = null) + { + // Filter and validate the form data. + $data = $form->filter($data); + $return = $form->validate($data, $group); + + // Check for an error. + if ($return instanceof Exception) + { + JFactory::getApplication()->enqueueMessage($return->getMessage(), 'error'); + + return false; + } + + // Check the validation results. + if ($return === false) + { + // Get the validation messages from the form. + foreach ($form->getErrors() as $message) + { + if ($message instanceof Exception) + { + $message = $message->getMessage(); + } + + JFactory::getApplication()->enqueueMessage($message, 'error'); + } + + return false; + } + + return $data; + } +} diff --git a/Sites/pages/components/com_config/model/form/config.xml b/Sites/pages/components/com_config/model/form/config.xml new file mode 100644 index 00000000..d8c54e3d --- /dev/null +++ b/Sites/pages/components/com_config/model/form/config.xml @@ -0,0 +1,131 @@ + +
          +
          + + + + + + +
          + +
          + + + + + + + + + + + +
          + +
          + + + + + + + + + + + + + + + + + + + + + +
          + +
          + +
          +
          diff --git a/Sites/pages/components/com_config/model/form/modules.xml b/Sites/pages/components/com_config/model/form/modules.xml new file mode 100644 index 00000000..f8dab88a --- /dev/null +++ b/Sites/pages/components/com_config/model/form/modules.xml @@ -0,0 +1,149 @@ + +
          +
          + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          +
          diff --git a/Sites/pages/components/com_config/model/form/modules_advanced.xml b/Sites/pages/components/com_config/model/form/modules_advanced.xml new file mode 100644 index 00000000..eee1a2dc --- /dev/null +++ b/Sites/pages/components/com_config/model/form/modules_advanced.xml @@ -0,0 +1,50 @@ + +
          + +
          + + + + + + + + + + +
          +
          +
          diff --git a/Sites/pages/components/com_config/model/form/templates.xml b/Sites/pages/components/com_config/model/form/templates.xml new file mode 100644 index 00000000..67b25eee --- /dev/null +++ b/Sites/pages/components/com_config/model/form/templates.xml @@ -0,0 +1,48 @@ + +
          +
          + + + + + + + + + + +
          +
          diff --git a/Sites/pages/components/com_config/model/modules.php b/Sites/pages/components/com_config/model/modules.php new file mode 100644 index 00000000..ba135091 --- /dev/null +++ b/Sites/pages/components/com_config/model/modules.php @@ -0,0 +1,266 @@ +input->getInt('id'); + + $state = $this->loadState(); + + $state->set('module.id', $pk); + + $this->setState($state); + } + + /** + * Method to get the record form. + * + * @param array $data Data for the form. + * @param boolean $loadData True if the form is to load its own data (default case), false if not. + * + * @return JForm A JForm object on success, false on failure + * + * @since 3.2 + */ + public function getForm($data = array(), $loadData = true) + { + // Get the form. + $form = $this->loadForm('com_config.modules', 'modules', array('control' => 'jform', 'load_data' => $loadData)); + + if (empty($form)) + { + return false; + } + + $form->setFieldAttribute('position', 'client', 'site'); + + return $form; + } + + /** + * Method to preprocess the form + * + * @param JForm $form A form object. + * @param mixed $data The data expected for the form. + * @param string $group The name of the plugin group to import (defaults to "content"). + * + * @return void + * + * @since 3.2 + * @throws Exception if there is an error loading the form. + */ + protected function preprocessForm(JForm $form, $data, $group = 'content') + { + jimport('joomla.filesystem.path'); + + $lang = JFactory::getLanguage(); + + $module = $this->getState()->get('module.name'); + $basePath = JPATH_BASE; + + $formFile = JPath::clean($basePath . '/modules/' . $module . '/' . $module . '.xml'); + + // Load the core and/or local language file(s). + $lang->load($module, $basePath, null, false, true) + || $lang->load($module, $basePath . '/modules/' . $module, null, false, true); + + if (file_exists($formFile)) + { + // Get the module form. + if (!$form->loadFile($formFile, false, '//config')) + { + throw new Exception(JText::_('JERROR_LOADFILE_FAILED')); + } + + // Attempt to load the xml file. + if (!$xml = simplexml_load_file($formFile)) + { + throw new Exception(JText::_('JERROR_LOADFILE_FAILED')); + } + } + + // Load the default advanced params + JForm::addFormPath(JPATH_BASE . '/components/com_config/model/form'); + $form->loadFile('modules_advanced', false); + + // Trigger the default form events. + parent::preprocessForm($form, $data, $group); + } + + /** + * Method to get list of module positions in current template + * + * @return array + * + * @since 3.2 + */ + public function getPositions() + { + $lang = JFactory::getLanguage(); + $templateName = JFactory::getApplication()->getTemplate(); + + // Load templateDetails.xml file + $path = JPath::clean(JPATH_BASE . '/templates/' . $templateName . '/templateDetails.xml'); + $currentTemplatePositions = array(); + + if (file_exists($path)) + { + $xml = simplexml_load_file($path); + + if (isset($xml->positions[0])) + { + // Load language files + $lang->load('tpl_' . $templateName . '.sys', JPATH_BASE, null, false, true) + || $lang->load('tpl_' . $templateName . '.sys', JPATH_BASE . '/templates/' . $templateName, null, false, true); + + foreach ($xml->positions[0] as $position) + { + $value = (string) $position; + $text = preg_replace('/[^a-zA-Z0-9_\-]/', '_', 'TPL_' . strtoupper($templateName) . '_POSITION_' . strtoupper($value)); + + // Construct list of positions + $currentTemplatePositions[] = self::createOption($value, JText::_($text) . ' [' . $value . ']'); + } + } + } + + $templateGroups = array(); + + // Add an empty value to be able to deselect a module position + $option = self::createOption(); + $templateGroups[''] = self::createOptionGroup('', array($option)); + + $templateGroups[$templateName] = self::createOptionGroup($templateName, $currentTemplatePositions); + + // Add custom position to options + $customGroupText = JText::_('COM_MODULES_CUSTOM_POSITION'); + + $editPositions = true; + $customPositions = self::getActivePositions(0, $editPositions); + $templateGroups[$customGroupText] = self::createOptionGroup($customGroupText, $customPositions); + + return $templateGroups; + } + + /** + * Get a list of modules positions + * + * @param integer $clientId Client ID + * @param boolean $editPositions Allow to edit the positions + * + * @return array A list of positions + * + * @since 3.6.3 + */ + public static function getActivePositions($clientId, $editPositions = false) + { + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->select('DISTINCT position') + ->from($db->quoteName('#__modules')) + ->where($db->quoteName('client_id') . ' = ' . (int) $clientId) + ->order($db->quoteName('position')); + + $db->setQuery($query); + + try + { + $positions = $db->loadColumn(); + $positions = is_array($positions) ? $positions : array(); + } + catch (RuntimeException $e) + { + JError::raiseWarning(500, $e->getMessage()); + + return; + } + + // Build the list + $options = array(); + + foreach ($positions as $position) + { + if (!$position && !$editPositions) + { + $options[] = JHtml::_('select.option', 'none', ':: ' . JText::_('JNONE') . ' ::'); + } + else + { + $options[] = JHtml::_('select.option', $position, $position); + } + } + + return $options; + } + + /** + * Create and return a new Option + * + * @param string $value The option value [optional] + * @param string $text The option text [optional] + * + * @return object The option as an object (stdClass instance) + * + * @since 3.6.3 + */ + private static function createOption($value = '', $text = '') + { + if (empty($text)) + { + $text = $value; + } + + $option = new stdClass; + $option->value = $value; + $option->text = $text; + + return $option; + } + + /** + * Create and return a new Option Group + * + * @param string $label Value and label for group [optional] + * @param array $options Array of options to insert into group [optional] + * + * @return array Return the new group as an array + * + * @since 3.6.3 + */ + private static function createOptionGroup($label = '', $options = array()) + { + $group = array(); + $group['value'] = $label; + $group['text'] = $label; + $group['items'] = $options; + + return $group; + } +} diff --git a/Sites/pages/components/com_config/model/templates.php b/Sites/pages/components/com_config/model/templates.php new file mode 100644 index 00000000..e6e5c879 --- /dev/null +++ b/Sites/pages/components/com_config/model/templates.php @@ -0,0 +1,126 @@ +loadState(); + + // Load the parameters. + $params = JComponentHelper::getParams('com_templates'); + $state->set('params', $params); + + $this->setState($state); + } + + /** + * Method to get the record form. + * + * @param array $data An optional array of data for the form to interrogate. + * @param boolean $loadData True if the form is to load its own data (default case), false if not. + * + * @return JForm A JForm object on success, false on failure + * + * @since 3.2 + */ + public function getForm($data = array(), $loadData = true) + { + // Get the form. + $form = $this->loadForm('com_config.templates', 'templates', array('control' => 'jform', 'load_data' => $loadData)); + + try + { + $form = new JForm('com_config.templates'); + $data = array(); + $this->preprocessForm($form, $data); + + // Load the data into the form + $form->bind($data); + } + catch (Exception $e) + { + JFactory::getApplication()->enqueueMessage($e->getMessage()); + + return false; + } + + if (empty($form)) + { + return false; + } + + return $form; + } + + /** + * Method to preprocess the form + * + * @param JForm $form A form object. + * @param mixed $data The data expected for the form. + * @param string $group Plugin group to load + * + * @return void + * + * @since 3.2 + * @throws Exception if there is an error in the form event. + */ + protected function preprocessForm(JForm $form, $data, $group = 'content') + { + $lang = JFactory::getLanguage(); + + $template = JFactory::getApplication()->getTemplate(); + + jimport('joomla.filesystem.path'); + + // Load the core and/or local language file(s). + $lang->load('tpl_' . $template, JPATH_BASE, null, false, true) + || $lang->load('tpl_' . $template, JPATH_BASE . '/templates/' . $template, null, false, true); + + // Look for com_config.xml, which contains fields to display + $formFile = JPath::clean(JPATH_BASE . '/templates/' . $template . '/com_config.xml'); + + if (!file_exists($formFile)) + { + // If com_config.xml not found, fall back to templateDetails.xml + $formFile = JPath::clean(JPATH_BASE . '/templates/' . $template . '/templateDetails.xml'); + } + + // Get the template form. + if (file_exists($formFile) && !$form->loadFile($formFile, false, '//config')) + { + throw new Exception(JText::_('JERROR_LOADFILE_FAILED')); + } + + // Attempt to load the xml file. + if (!$xml = simplexml_load_file($formFile)) + { + throw new Exception(JText::_('JERROR_LOADFILE_FAILED')); + } + + // Trigger the default form events. + parent::preprocessForm($form, $data, $group); + } +} diff --git a/Sites/pages/components/com_config/view/cms/html.php b/Sites/pages/components/com_config/view/cms/html.php new file mode 100644 index 00000000..7424290f --- /dev/null +++ b/Sites/pages/components/com_config/view/cms/html.php @@ -0,0 +1,221 @@ + array(), 'helper' => array()); + + /** + * Layout extension + * + * @var string + * @since 3.2 + */ + protected $_layoutExt = 'php'; + + /** + * Method to instantiate the view. + * + * @param JModel $model The model object. + * @param SplPriorityQueue $paths The paths queue. + * + * @since 3.2 + */ + public function __construct(JModel $model, SplPriorityQueue $paths = null) + { + $app = JFactory::getApplication(); + $component = JApplicationHelper::getComponentName(); + $component = preg_replace('/[^A-Z0-9_\.-]/i', '', $component); + + if (isset($paths)) + { + $paths->insert(JPATH_THEMES . '/' . $app->getTemplate() . '/html/' . $component . '/' . $this->getName(), 2); + } + + parent::__construct($model, $paths); + } + + /** + * 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 3.2 + * @throws Exception + */ + public function loadTemplate($tpl = null) + { + // Clear prior output + $this->_output = null; + + $template = JFactory::getApplication()->getTemplate(); + $layout = $this->getLayout(); + + // 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, true) + || $lang->load('tpl_' . $template, JPATH_THEMES . "/$template", null, false, true); + + // Prevents adding path twise + if (empty($this->_path['template'])) + { + // Adding template paths + $this->paths->top(); + $defaultPath = $this->paths->current(); + $this->paths->next(); + $templatePath = $this->paths->current(); + $this->_path['template'] = array($defaultPath, $templatePath); + } + + // 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, $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 + { + throw new Exception(JText::sprintf('JLIB_APPLICATION_ERROR_LAYOUTFILE_NOT_FOUND', $file), 500); + } + } + + /** + * 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 3.2 + */ + protected function _createFileName($type, $parts = array()) + { + switch ($type) + { + case 'template': + $filename = strtolower($parts['name']) . '.' . $this->_layoutExt; + break; + + default: + $filename = strtolower($parts['name']) . '.php'; + break; + } + + return $filename; + } + + /** + * 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 3.2 + * @throws Exception + */ + public function getName() + { + if (empty($this->_name)) + { + $classname = get_class($this); + $viewpos = strpos($classname, 'View'); + + if ($viewpos === false) + { + throw new Exception(JText::_('JLIB_APPLICATION_ERROR_VIEW_GET_NAME'), 500); + } + + $lastPart = substr($classname, $viewpos + 4); + $pathParts = explode(' ', JStringNormalise::fromCamelCase($lastPart)); + + if (!empty($pathParts[1])) + { + $this->_name = strtolower($pathParts[0]); + } + else + { + $this->_name = strtolower($lastPart); + } + } + + return $this->_name; + } +} diff --git a/Sites/pages/components/com_config/view/cms/json.php b/Sites/pages/components/com_config/view/cms/json.php new file mode 100644 index 00000000..ab655773 --- /dev/null +++ b/Sites/pages/components/com_config/view/cms/json.php @@ -0,0 +1,36 @@ +data = $this->model->getData(); + + return json_encode($this->data); + } +} diff --git a/Sites/pages/components/com_config/view/config/html.php b/Sites/pages/components/com_config/view/config/html.php new file mode 100644 index 00000000..3c4288fa --- /dev/null +++ b/Sites/pages/components/com_config/view/config/html.php @@ -0,0 +1,37 @@ +userIsSuperAdmin = $user->authorise('core.admin'); + + return parent::render(); + } +} diff --git a/Sites/pages/components/com_config/view/config/tmpl/default.php b/Sites/pages/components/com_config/view/config/tmpl/default.php new file mode 100644 index 00000000..188c33b6 --- /dev/null +++ b/Sites/pages/components/com_config/view/config/tmpl/default.php @@ -0,0 +1,61 @@ +addScriptDeclaration(" + Joomla.submitbutton = function(task) + { + if (task == 'config.cancel' || document.formvalidator.isValid(document.getElementById('application-form'))) { + Joomla.submitform(task, document.getElementById('application-form')); + } + } +"); +?> + +
          + +
          + + + + +
          + +
          +
          + loadTemplate('site'); ?> + loadTemplate('metadata'); ?> + loadTemplate('seo'); ?> +
          +
          + + + + + +
          + +
          diff --git a/Sites/pages/components/com_config/view/config/tmpl/default.xml b/Sites/pages/components/com_config/view/config/tmpl/default.xml new file mode 100644 index 00000000..ba08bfc1 --- /dev/null +++ b/Sites/pages/components/com_config/view/config/tmpl/default.xml @@ -0,0 +1,20 @@ + + + + + + + + + +
          + +
          +
          +
          \ No newline at end of file diff --git a/Sites/pages/components/com_config/view/config/tmpl/default_metadata.php b/Sites/pages/components/com_config/view/config/tmpl/default_metadata.php new file mode 100644 index 00000000..e9a4590e --- /dev/null +++ b/Sites/pages/components/com_config/view/config/tmpl/default_metadata.php @@ -0,0 +1,24 @@ + +
          + + form->getFieldset('metadata') as $field) : + ?> +
          +
          label; ?>
          +
          input; ?>
          +
          + +
          diff --git a/Sites/pages/components/com_config/view/config/tmpl/default_seo.php b/Sites/pages/components/com_config/view/config/tmpl/default_seo.php new file mode 100644 index 00000000..1c20ba23 --- /dev/null +++ b/Sites/pages/components/com_config/view/config/tmpl/default_seo.php @@ -0,0 +1,24 @@ + +
          + + form->getFieldset('seo') as $field) : + ?> +
          +
          label; ?>
          +
          input; ?>
          +
          + +
          diff --git a/Sites/pages/components/com_config/view/config/tmpl/default_site.php b/Sites/pages/components/com_config/view/config/tmpl/default_site.php new file mode 100644 index 00000000..d047f22c --- /dev/null +++ b/Sites/pages/components/com_config/view/config/tmpl/default_site.php @@ -0,0 +1,24 @@ + +
          + + form->getFieldset('site') as $field) : + ?> +
          +
          label; ?>
          +
          input; ?>
          +
          + +
          diff --git a/Sites/pages/components/com_config/view/modules/html.php b/Sites/pages/components/com_config/view/modules/html.php new file mode 100644 index 00000000..0ce96555 --- /dev/null +++ b/Sites/pages/components/com_config/view/modules/html.php @@ -0,0 +1,40 @@ +getLanguage(); + $lang->load('', JPATH_ADMINISTRATOR, $lang->getTag()); + $lang->load('com_modules', JPATH_ADMINISTRATOR, $lang->getTag()); + + return parent::render(); + } +} diff --git a/Sites/pages/components/com_config/view/modules/tmpl/default.php b/Sites/pages/components/com_config/view/modules/tmpl/default.php new file mode 100644 index 00000000..a0e280a3 --- /dev/null +++ b/Sites/pages/components/com_config/view/modules/tmpl/default.php @@ -0,0 +1,214 @@ +item['module'] . '/' . $this->item['module'] . '.xml'; + +if (JFile::exists($moduleXml)) +{ + $xml = simplexml_load_file($moduleXml); + + if (isset($xml->customContent)) + { + $editorText = true; + } +} + +// If multi-language site, make language read-only +if (JLanguageMultilang::isEnabled()) +{ + $this->form->setFieldAttribute('language', 'readonly', 'true'); +} + +JFactory::getDocument()->addScriptDeclaration(" + Joomla.submitbutton = function(task) + { + if (task == 'config.cancel.modules' || document.formvalidator.isValid(document.getElementById('modules-form'))) + { + Joomla.submitform(task, document.getElementById('modules-form')); + } + } +"); +?> + +
          + +
          + + +
          + + + +
          + + + +
          + + item['title']; ?> +    + + item['module']; ?> +
          +
          + +
          +
          +
          +
          +
          + form->getLabel('title'); ?> +
          +
          + form->getInput('title'); ?> +
          +
          +
          +
          + form->getLabel('showtitle'); ?> +
          +
          + form->getInput('showtitle'); ?> +
          +
          +
          +
          + form->getLabel('position'); ?> +
          +
          + loadTemplate('positions'); ?> +
          +
          + +
          + + authorise('core.edit.state', 'com_modules.module.' . $this->item['id'])) : ?> +
          +
          + form->getLabel('published'); ?> +
          +
          + form->getInput('published'); ?> +
          +
          + + +
          +
          + form->getLabel('publish_up'); ?> +
          +
          + form->getInput('publish_up'); ?> +
          +
          +
          +
          + form->getLabel('publish_down'); ?> +
          +
          + form->getInput('publish_down'); ?> +
          +
          + +
          +
          + form->getLabel('access'); ?> +
          +
          + form->getInput('access'); ?> +
          +
          +
          +
          + form->getLabel('ordering'); ?> +
          +
          + form->getInput('ordering'); ?> +
          +
          + +
          +
          + form->getLabel('language'); ?> +
          +
          + form->getInput('language'); ?> +
          +
          +
          +
          + form->getLabel('note'); ?> +
          +
          + form->getInput('note'); ?> +
          +
          + +
          + +
          + loadTemplate('options'); ?> +
          + + +
          + form->getInput('content'); ?> +
          + +
          +
          + + + + + + +
          + +
          + +
          + +
          diff --git a/Sites/pages/components/com_config/view/modules/tmpl/default_options.php b/Sites/pages/components/com_config/view/modules/tmpl/default_options.php new file mode 100644 index 00000000..bfa18939 --- /dev/null +++ b/Sites/pages/components/com_config/view/modules/tmpl/default_options.php @@ -0,0 +1,45 @@ +form->getFieldsets('params'); + +echo JHtml::_('bootstrap.startAccordion', 'collapseTypes'); +$i = 0; + +foreach ($fieldSets as $name => $fieldSet) : + +$label = !empty($fieldSet->label) ? $fieldSet->label : 'COM_MODULES_' . $name . '_FIELDSET_LABEL'; +$class = isset($fieldSet->class) && !empty($fieldSet->class) ? $fieldSet->class : ''; + + +if (isset($fieldSet->description) && trim($fieldSet->description)) : +echo '

          ' . $this->escape(JText::_($fieldSet->description)) . '

          '; +endif; +?> + + + + + + + diff --git a/Sites/pages/components/com_config/view/modules/tmpl/default_positions.php b/Sites/pages/components/com_config/view/modules/tmpl/default_positions.php new file mode 100644 index 00000000..e375d7dd --- /dev/null +++ b/Sites/pages/components/com_config/view/modules/tmpl/default_positions.php @@ -0,0 +1,26 @@ +model->getPositions(); + +// Add custom position to options +$customGroupText = JText::_('COM_MODULES_CUSTOM_POSITION'); + +// Build field +$attr = array( + 'id' => 'jform_position', + 'list.select' => $this->item['position'], + 'list.attr' => 'class="chzn-custom-value" ' + . 'data-custom_group_text="' . $customGroupText . '" ' + . 'data-no_results_text="' . JText::_('COM_MODULES_ADD_CUSTOM_POSITION') . '" ' + . 'data-placeholder="' . JText::_('COM_MODULES_TYPE_OR_SELECT_POSITION') . '" ' +); + +echo JHtml::_('select.groupedlist', $positions, 'jform[position]', $attr); diff --git a/Sites/pages/components/com_config/view/templates/html.php b/Sites/pages/components/com_config/view/templates/html.php new file mode 100644 index 00000000..c04272b3 --- /dev/null +++ b/Sites/pages/components/com_config/view/templates/html.php @@ -0,0 +1,37 @@ +userIsSuperAdmin = $user->authorise('core.admin'); + + return parent::render(); + } +} diff --git a/Sites/pages/components/com_config/view/templates/tmpl/default.php b/Sites/pages/components/com_config/view/templates/tmpl/default.php new file mode 100644 index 00000000..865a3555 --- /dev/null +++ b/Sites/pages/components/com_config/view/templates/tmpl/default.php @@ -0,0 +1,60 @@ +addScriptDeclaration(" + Joomla.submitbutton = function(task) + { + if (task == 'config.cancel' || document.formvalidator.isValid(document.getElementById('templates-form'))) + { + Joomla.submitform(task, document.getElementById('templates-form')); + } + } +"); +?> + +
          + +
          + + + + +
          + +
          +
          + loadTemplate('options'); ?> +
          +
          + + + + + +
          + +
          diff --git a/Sites/pages/components/com_config/view/templates/tmpl/default.xml b/Sites/pages/components/com_config/view/templates/tmpl/default.xml new file mode 100644 index 00000000..7409a844 --- /dev/null +++ b/Sites/pages/components/com_config/view/templates/tmpl/default.xml @@ -0,0 +1,20 @@ + + + + + + + + + +
          + +
          +
          +
          \ No newline at end of file diff --git a/Sites/pages/components/com_config/view/templates/tmpl/default_options.php b/Sites/pages/components/com_config/view/templates/tmpl/default_options.php new file mode 100644 index 00000000..16ce3bf6 --- /dev/null +++ b/Sites/pages/components/com_config/view/templates/tmpl/default_options.php @@ -0,0 +1,47 @@ + +form->getFieldsets('params'); +?> + + + + + +
          + form->renderFieldset('com_config'); ?> +
          + + $fieldSet) : + $label = !empty($fieldSet->label) ? $fieldSet->label : 'COM_CONFIG_' . $name . '_FIELDSET_LABEL'; + + if (isset($fieldSet->description) && trim($fieldSet->description)) : + echo '

          ' . $this->escape(JText::_($fieldSet->description)) . '

          '; + endif; + ?> + +
          + form->renderFieldset($name); ?> +
          + input; + +if ($input->get('view') === 'contacts' && $input->get('layout') === 'modal') +{ + if (!JFactory::getUser()->authorise('core.create', 'com_contact')) + { + JFactory::getApplication()->enqueueMessage(JText::_('JERROR_ALERTNOAUTHOR'), 'warning'); + + return; + } + + JFactory::getLanguage()->load('com_contact', JPATH_ADMINISTRATOR); +} + +$controller = JControllerLegacy::getInstance('Contact'); +$controller->execute(JFactory::getApplication()->input->get('task')); +$controller->redirect(); diff --git a/Sites/pages/components/com_contact/controller.php b/Sites/pages/components/com_contact/controller.php new file mode 100644 index 00000000..5472ac84 --- /dev/null +++ b/Sites/pages/components/com_contact/controller.php @@ -0,0 +1,72 @@ +input = JFactory::getApplication()->input; + + // Contact frontpage Editor contacts proxying: + if ($this->input->get('view') === 'contacts' && $this->input->get('layout') === 'modal') + { + JHtml::_('stylesheet', 'system/adminlist.css', array(), true); + $config['base_path'] = JPATH_COMPONENT_ADMINISTRATOR; + } + + parent::__construct($config); + } + + /** + * Method to display a view. + * + * @param boolean $cachable If true, the view output will be cached + * @param array $urlparams An array of safe URL parameters and their variable types, for valid values see {@link JFilterInput::clean()}. + * + * @return JControllerLegacy This object to support chaining. + * + * @since 1.5 + */ + public function display($cachable = false, $urlparams = array()) + { + if (JFactory::getApplication()->getUserState('com_contact.contact.data') === null) + { + $cachable = true; + } + + // Set the default view name and format from the Request. + $vName = $this->input->get('view', 'categories'); + $this->input->set('view', $vName); + + $safeurlparams = array('catid' => 'INT', 'id' => 'INT', 'cid' => 'ARRAY', 'year' => 'INT', 'month' => 'INT', + 'limit' => 'UINT', 'limitstart' => 'UINT', 'showall' => 'INT', 'return' => 'BASE64', 'filter' => 'STRING', + 'filter_order' => 'CMD', 'filter_order_Dir' => 'CMD', 'filter-search' => 'STRING', 'print' => 'BOOLEAN', + 'lang' => 'CMD'); + + parent::display($cachable, $safeurlparams); + + return $this; + } +} diff --git a/Sites/pages/components/com_contact/controllers/contact.php b/Sites/pages/components/com_contact/controllers/contact.php new file mode 100644 index 00000000..919d9507 --- /dev/null +++ b/Sites/pages/components/com_contact/controllers/contact.php @@ -0,0 +1,268 @@ + true)) + { + return parent::getModel($name, $prefix, array('ignore_request' => false)); + } + + /** + * Method to submit the contact form and send an email. + * + * @return boolean True on success sending the email. False on failure. + * + * @since 1.5.19 + */ + public function submit() + { + // Check for request forgeries. + $this->checkToken(); + + $app = JFactory::getApplication(); + $model = $this->getModel('contact'); + $stub = $this->input->getString('id'); + $id = (int) $stub; + + // Get the data from POST + $data = $this->input->post->get('jform', array(), 'array'); + + // Get item + $model->setState('filter.published', 1); + $contact = $model->getItem($id); + + // Get item params, take menu parameters into account if necessary + $active = $app->getMenu()->getActive(); + $stateParams = clone $model->getState()->get('params'); + + // If the current view is the active item and a contact view for this contact, then the menu item params take priority + if ($active && strpos($active->link, 'view=contact') && strpos($active->link, '&id=' . (int) $contact->id)) + { + // $item->params are the contact params, $temp are the menu item params + // Merge so that the menu item params take priority + $contact->params->merge($stateParams); + } + else + { + // Current view is not a single contact, so the contact params take priority here + $stateParams->merge($contact->params); + $contact->params = $stateParams; + } + + // Check if the contact form is enabled + if (!$contact->params->get('show_email_form')) + { + $this->setRedirect(JRoute::_('index.php?option=com_contact&view=contact&id=' . $stub . '&catid=' . $contact->catid, false)); + + return false; + } + + // Check for a valid session cookie + if ($contact->params->get('validate_session', 0)) + { + if (JFactory::getSession()->getState() !== 'active') + { + JError::raiseWarning(403, JText::_('JLIB_ENVIRONMENT_SESSION_INVALID')); + + // Save the data in the session. + $app->setUserState('com_contact.contact.data', $data); + + // Redirect back to the contact form. + $this->setRedirect(JRoute::_('index.php?option=com_contact&view=contact&id=' . $stub . '&catid=' . $contact->catid, false)); + + return false; + } + } + + // Contact plugins + JPluginHelper::importPlugin('contact'); + $dispatcher = JEventDispatcher::getInstance(); + + // Validate the posted data. + $form = $model->getForm(); + + if (!$form) + { + JError::raiseError(500, $model->getError()); + + return false; + } + + if (!$model->validate($form, $data)) + { + $errors = $model->getErrors(); + + foreach ($errors as $error) + { + $errorMessage = $error; + + if ($error instanceof Exception) + { + $errorMessage = $error->getMessage(); + } + + $app->enqueueMessage($errorMessage, 'error'); + } + + $app->setUserState('com_contact.contact.data', $data); + + $this->setRedirect(JRoute::_('index.php?option=com_contact&view=contact&id=' . $stub . '&catid=' . $contact->catid, false)); + + return false; + } + + // Validation succeeded, continue with custom handlers + $results = $dispatcher->trigger('onValidateContact', array(&$contact, &$data)); + + foreach ($results as $result) + { + if ($result instanceof Exception) + { + return false; + } + } + + // Passed Validation: Process the contact plugins to integrate with other applications + $dispatcher->trigger('onSubmitContact', array(&$contact, &$data)); + + // Send the email + $sent = false; + + if (!$contact->params->get('custom_reply')) + { + $sent = $this->_sendEmail($data, $contact, $contact->params->get('show_email_copy', 0)); + } + + // Set the success message if it was a success + if (!($sent instanceof Exception)) + { + $msg = JText::_('COM_CONTACT_EMAIL_THANKS'); + } + else + { + $msg = ''; + } + + // Flush the data from the session + $app->setUserState('com_contact.contact.data', null); + + // Redirect if it is set in the parameters, otherwise redirect back to where we came from + if ($contact->params->get('redirect')) + { + $this->setRedirect($contact->params->get('redirect'), $msg); + } + else + { + $this->setRedirect(JRoute::_('index.php?option=com_contact&view=contact&id=' . $stub . '&catid=' . $contact->catid, false), $msg); + } + + return true; + } + + /** + * Method to get a model object, loading it if required. + * + * @param array $data The data to send in the email. + * @param stdClass $contact The user information to send the email to + * @param boolean $emailCopyToSender True to send a copy of the email to the user. + * + * @return boolean True on success sending the email, false on failure. + * + * @since 1.6.4 + */ + private function _sendEmail($data, $contact, $emailCopyToSender) + { + $app = JFactory::getApplication(); + + if ($contact->email_to == '' && $contact->user_id != 0) + { + $contact_user = JUser::getInstance($contact->user_id); + $contact->email_to = $contact_user->get('email'); + } + + $mailfrom = $app->get('mailfrom'); + $fromname = $app->get('fromname'); + $sitename = $app->get('sitename'); + + $name = $data['contact_name']; + $email = JStringPunycode::emailToPunycode($data['contact_email']); + $subject = $data['contact_subject']; + $body = $data['contact_message']; + + // Prepare email body + $prefix = JText::sprintf('COM_CONTACT_ENQUIRY_TEXT', JUri::base()); + $body = $prefix . "\n" . $name . ' <' . $email . '>' . "\r\n\r\n" . stripslashes($body); + + // Load the custom fields + if (!empty($data['com_fields']) && $fields = FieldsHelper::getFields('com_contact.mail', $contact, true, $data['com_fields'])) + { + $output = FieldsHelper::render( + 'com_contact.mail', + 'fields.render', + array( + 'context' => 'com_contact.mail', + 'item' => $contact, + 'fields' => $fields, + ) + ); + + if ($output) + { + $body .= "\r\n\r\n" . $output; + } + } + + $mail = JFactory::getMailer(); + $mail->addRecipient($contact->email_to); + $mail->addReplyTo($email, $name); + $mail->setSender(array($mailfrom, $fromname)); + $mail->setSubject($sitename . ': ' . $subject); + $mail->setBody($body); + $sent = $mail->Send(); + + // If we are supposed to copy the sender, do so. + + // Check whether email copy function activated + if ($emailCopyToSender == true && !empty($data['contact_email_copy'])) + { + $copytext = JText::sprintf('COM_CONTACT_COPYTEXT_OF', $contact->name, $sitename); + $copytext .= "\r\n\r\n" . $body; + $copysubject = JText::sprintf('COM_CONTACT_COPYSUBJECT_OF', $subject); + + $mail = JFactory::getMailer(); + $mail->addRecipient($email); + $mail->addReplyTo($email, $name); + $mail->setSender(array($mailfrom, $fromname)); + $mail->setSubject($copysubject); + $mail->setBody($copytext); + $sent = $mail->Send(); + } + + return $sent; + } +} diff --git a/Sites/pages/components/com_contact/helpers/association.php b/Sites/pages/components/com_contact/helpers/association.php new file mode 100644 index 00000000..7b9d314e --- /dev/null +++ b/Sites/pages/components/com_contact/helpers/association.php @@ -0,0 +1,64 @@ +input; + $view = $view === null ? $jinput->get('view') : $view; + $id = empty($id) ? $jinput->getInt('id') : $id; + + if ($view === 'contact') + { + if ($id) + { + $associations = JLanguageAssociations::getAssociations('com_contact', '#__contact_details', 'com_contact.item', $id); + + $return = array(); + + foreach ($associations as $tag => $item) + { + $return[$tag] = ContactHelperRoute::getContactRoute($item->id, (int) $item->catid, $item->language); + } + + return $return; + } + } + + if ($view === 'category' || $view === 'categories') + { + return self::getCategoryAssociations($id, 'com_contact'); + } + + return array(); + + } +} diff --git a/Sites/pages/components/com_contact/helpers/category.php b/Sites/pages/components/com_contact/helpers/category.php new file mode 100644 index 00000000..87a23a4f --- /dev/null +++ b/Sites/pages/components/com_contact/helpers/category.php @@ -0,0 +1,33 @@ +router = $router; + } + + /** + * Preprocess the route for the com_contact component + * + * @param array &$query An array of URL arguments + * + * @return void + * + * @since 3.6 + * @deprecated 4.0 + */ + public function preprocess(&$query) + { + } + + /** + * Build the route for the com_contact component + * + * @param array &$query An array of URL arguments + * @param array &$segments The URL arguments to use to assemble the subsequent URL. + * + * @return void + * + * @since 3.6 + * @deprecated 4.0 + */ + public function build(&$query, &$segments) + { + // Get a menu item based on Itemid or currently active + $params = JComponentHelper::getParams('com_contact'); + $advanced = $params->get('sef_advanced_link', 0); + + if (empty($query['Itemid'])) + { + $menuItem = $this->router->menu->getActive(); + } + else + { + $menuItem = $this->router->menu->getItem($query['Itemid']); + } + + $mView = empty($menuItem->query['view']) ? null : $menuItem->query['view']; + $mId = empty($menuItem->query['id']) ? null : $menuItem->query['id']; + + if (isset($query['view'])) + { + $view = $query['view']; + + if (empty($query['Itemid']) || empty($menuItem) || $menuItem->component != 'com_contact') + { + $segments[] = $query['view']; + } + + unset($query['view']); + } + + // Are we dealing with a contact that is attached to a menu item? + if (isset($view) && ($mView == $view) && isset($query['id']) && ($mId == (int) $query['id'])) + { + unset($query['view'], $query['catid'], $query['id']); + + return; + } + + if (isset($view) && ($view == 'category' || $view == 'contact')) + { + if ($mId != (int) $query['id'] || $mView != $view) + { + if ($view == 'contact' && isset($query['catid'])) + { + $catid = $query['catid']; + } + elseif (isset($query['id'])) + { + $catid = $query['id']; + } + + $menuCatid = $mId; + $categories = JCategories::getInstance('Contact'); + $category = $categories->get($catid); + + if ($category) + { + // TODO Throw error that the category either not exists or is unpublished + $path = array_reverse($category->getPath()); + + $array = array(); + + foreach ($path as $id) + { + if ((int) $id == (int) $menuCatid) + { + break; + } + + if ($advanced) + { + list($tmp, $id) = explode(':', $id, 2); + } + + $array[] = $id; + } + + $segments = array_merge($segments, array_reverse($array)); + } + + if ($view == 'contact') + { + if ($advanced) + { + list($tmp, $id) = explode(':', $query['id'], 2); + } + else + { + $id = $query['id']; + } + + $segments[] = $id; + } + } + + unset($query['id'], $query['catid']); + } + + if (isset($query['layout'])) + { + if (!empty($query['Itemid']) && isset($menuItem->query['layout'])) + { + if ($query['layout'] == $menuItem->query['layout']) + { + unset($query['layout']); + } + } + else + { + if ($query['layout'] == 'default') + { + unset($query['layout']); + } + } + } + + $total = count($segments); + + for ($i = 0; $i < $total; $i++) + { + $segments[$i] = str_replace(':', '-', $segments[$i]); + } + } + + /** + * Parse the segments of a URL. + * + * @param array &$segments The segments of the URL to parse. + * @param array &$vars The URL attributes to be used by the application. + * + * @return void + * + * @since 3.6 + * @deprecated 4.0 + */ + public function parse(&$segments, &$vars) + { + $total = count($segments); + + for ($i = 0; $i < $total; $i++) + { + $segments[$i] = preg_replace('/-/', ':', $segments[$i], 1); + } + + // Get the active menu item. + $item = $this->router->menu->getActive(); + $params = JComponentHelper::getParams('com_contact'); + $advanced = $params->get('sef_advanced_link', 0); + + // Count route segments + $count = count($segments); + + // Standard routing for newsfeeds. + if (!isset($item)) + { + $vars['view'] = $segments[0]; + $vars['id'] = $segments[$count - 1]; + + return; + } + + // From the categories view, we can only jump to a category. + $id = (isset($item->query['id']) && $item->query['id'] > 1) ? $item->query['id'] : 'root'; + + $contactCategory = JCategories::getInstance('Contact')->get($id); + + $categories = $contactCategory ? $contactCategory->getChildren() : array(); + $vars['catid'] = $id; + $vars['id'] = $id; + $found = 0; + + foreach ($segments as $segment) + { + $segment = $advanced ? str_replace(':', '-', $segment) : $segment; + + foreach ($categories as $category) + { + if ($category->slug == $segment || $category->alias == $segment) + { + $vars['id'] = $category->id; + $vars['catid'] = $category->id; + $vars['view'] = 'category'; + $categories = $category->getChildren(); + $found = 1; + break; + } + } + + if ($found == 0) + { + if ($advanced) + { + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->select($db->quoteName('id')) + ->from('#__contact_details') + ->where($db->quoteName('catid') . ' = ' . (int) $vars['catid']) + ->where($db->quoteName('alias') . ' = ' . $db->quote($segment)); + $db->setQuery($query); + $nid = $db->loadResult(); + } + else + { + $nid = $segment; + } + + $vars['id'] = $nid; + $vars['view'] = 'contact'; + } + + $found = 0; + } + } +} diff --git a/Sites/pages/components/com_contact/helpers/route.php b/Sites/pages/components/com_contact/helpers/route.php new file mode 100644 index 00000000..2817b228 --- /dev/null +++ b/Sites/pages/components/com_contact/helpers/route.php @@ -0,0 +1,89 @@ + 1) + { + $link .= '&catid=' . $catid; + } + + if ($language && $language !== '*' && JLanguageMultilang::isEnabled()) + { + $link .= '&lang=' . $language; + } + + return $link; + } + + /** + * Get the URL route for a contact category from a contact category ID and language + * + * @param mixed $catid The id of the contact's category either an integer id or an instance of JCategoryNode + * @param mixed $language The id of the language being used. + * + * @return string The link to the contact + * + * @since 1.5 + */ + public static function getCategoryRoute($catid, $language = 0) + { + if ($catid instanceof JCategoryNode) + { + $id = $catid->id; + } + else + { + $id = (int) $catid; + } + + if ($id < 1) + { + $link = ''; + } + else + { + // Create the link + $link = 'index.php?option=com_contact&view=category&id=' . $id; + + if ($language && $language !== '*' && JLanguageMultilang::isEnabled()) + { + $link .= '&lang=' . $language; + } + } + + return $link; + } +} diff --git a/Sites/pages/components/com_contact/layouts/field/render.php b/Sites/pages/components/com_contact/layouts/field/render.php new file mode 100644 index 00000000..afe2a301 --- /dev/null +++ b/Sites/pages/components/com_contact/layouts/field/render.php @@ -0,0 +1,45 @@ +label); +$value = $field->value; +$class = $field->params->get('render_class'); +$showLabel = $field->params->get('showlabel'); +$labelClass = $field->params->get('label_render_class'); + +if ($field->context == 'com_contact.mail') +{ + // Prepare the value for the contact form mail + $value = html_entity_decode($value); + + echo ($showLabel ? $label . ': ' : '') . $value . "\r\n"; + return; +} + +if (!strlen($value)) +{ + return; +} + +?> +
          + + : + +
          +
          + +
          diff --git a/Sites/pages/components/com_contact/layouts/fields/render.php b/Sites/pages/components/com_contact/layouts/fields/render.php new file mode 100644 index 00000000..6248798f --- /dev/null +++ b/Sites/pages/components/com_contact/layouts/fields/render.php @@ -0,0 +1,79 @@ +jcfields ?: FieldsHelper::getFields($context, $item, true); +} + +if (!$fields) +{ + return; +} + +// Check if we have mail context in first element +$isMail = (reset($fields)->context == 'com_contact.mail'); + +if (!$isMail) +{ + // Print the container tag + echo '
          '; +} + +// Loop through the fields and print them +foreach ($fields as $field) +{ + // If the value is empty do nothing + if (!strlen($field->value) && !$isMail) + { + continue; + } + + $layout = $field->params->get('layout', 'render'); + echo FieldsHelper::render($context, 'field.' . $layout, array('field' => $field)); +} + +if (!$isMail) +{ + // Close the container + echo '
          '; +} + diff --git a/Sites/pages/components/com_contact/layouts/joomla/form/renderfield.php b/Sites/pages/components/com_contact/layouts/joomla/form/renderfield.php new file mode 100644 index 00000000..7cd3b745 --- /dev/null +++ b/Sites/pages/components/com_contact/layouts/joomla/form/renderfield.php @@ -0,0 +1,57 @@ + 'auto', 'relative' => true)); +} + +$class = empty($options['class']) ? '' : ' ' . $options['class']; +$rel = empty($options['rel']) ? '' : ' ' . $options['rel']; + +/** + * @TODO: + * + * As mentioned in #8473 (https://github.com/joomla/joomla-cms/pull/8473), ... + * as long as we cannot access the field properties properly, this seems to + * be the way to go for now. + * + * On a side note: Parsing html is seldom a good idea. + * https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/1732454#1732454 + */ +preg_match('/class=\"([^\"]+)\"/i', $input, $match); + +$required = (strpos($input, 'aria-required="true"') !== false || (!empty($match[1]) && strpos($match[1], 'required') !== false)); +$typeOfSpacer = (strpos($label, 'spacer-lbl') !== false); + +?> +
          > + +
          + + + + +
          + +
          +
          diff --git a/Sites/pages/components/com_contact/models/categories.php b/Sites/pages/components/com_contact/models/categories.php new file mode 100644 index 00000000..fe747af1 --- /dev/null +++ b/Sites/pages/components/com_contact/models/categories.php @@ -0,0 +1,142 @@ +setState('filter.extension', $this->_extension); + + // Get the parent id if defined. + $parentId = $app->input->getInt('id'); + $this->setState('filter.parentId', $parentId); + + $params = $app->getParams(); + $this->setState('params', $params); + + $this->setState('filter.published', 1); + $this->setState('filter.access', true); + } + + /** + * Method to get a store id based on model configuration state. + * + * This is necessary because the model is used by the component and + * different modules that might need different sets of data or different + * ordering requirements. + * + * @param string $id A prefix for the store id. + * + * @return string A store id. + */ + protected function getStoreId($id = '') + { + // Compile the store id. + $id .= ':' . $this->getState('filter.extension'); + $id .= ':' . $this->getState('filter.published'); + $id .= ':' . $this->getState('filter.access'); + $id .= ':' . $this->getState('filter.parentId'); + + return parent::getStoreId($id); + } + + /** + * Redefine the function an add some properties to make the styling more easy + * + * @return mixed An array of data items on success, false on failure. + */ + public function getItems() + { + if ($this->_items === null) + { + $app = JFactory::getApplication(); + $menu = $app->getMenu(); + $active = $menu->getActive(); + $params = new Registry; + + if ($active) + { + $params->loadString($active->params); + } + + $options = array(); + $options['countItems'] = $params->get('show_cat_items_cat', 1) || !$params->get('show_empty_categories_cat', 0); + $categories = JCategories::getInstance('Contact', $options); + $this->_parent = $categories->get($this->getState('filter.parentId', 'root')); + + if (is_object($this->_parent)) + { + $this->_items = $this->_parent->getChildren(); + } + else + { + $this->_items = false; + } + } + + return $this->_items; + } + + /** + * Gets the id of the parent category for the selected list of categories + * + * @return integer The id of the parent category + * + * @since 1.6.0 + */ + public function getParent() + { + if (!is_object($this->_parent)) + { + $this->getItems(); + } + + return $this->_parent; + } +} diff --git a/Sites/pages/components/com_contact/models/category.php b/Sites/pages/components/com_contact/models/category.php new file mode 100644 index 00000000..b8e565ca --- /dev/null +++ b/Sites/pages/components/com_contact/models/category.php @@ -0,0 +1,444 @@ +_params)) + { + $item->params = new Registry($item->params); + } + + // Some contexts may not use tags data at all, so we allow callers to disable loading tag data + if ($this->getState('load_tags', true)) + { + $this->tags = new JHelperTags; + $this->tags->getItemTags('com_contact.contact', $item->id); + } + } + + return $items; + } + + /** + * Method to build an SQL query to load the list data. + * + * @return string An SQL query + * + * @since 1.6 + */ + protected function getListQuery() + { + $user = JFactory::getUser(); + $groups = implode(',', $user->getAuthorisedViewLevels()); + + // Create a new query object. + $db = $this->getDbo(); + $query = $db->getQuery(true); + + // Select required fields from the categories. + // Changes for sqlsrv + $case_when = ' CASE WHEN '; + $case_when .= $query->charLength('a.alias', '!=', '0'); + $case_when .= ' THEN '; + $a_id = $query->castAsChar('a.id'); + $case_when .= $query->concatenate(array($a_id, 'a.alias'), ':'); + $case_when .= ' ELSE '; + $case_when .= $a_id . ' END as slug'; + + $case_when1 = ' CASE WHEN '; + $case_when1 .= $query->charLength('c.alias', '!=', '0'); + $case_when1 .= ' THEN '; + $c_id = $query->castAsChar('c.id'); + $case_when1 .= $query->concatenate(array($c_id, 'c.alias'), ':'); + $case_when1 .= ' ELSE '; + $case_when1 .= $c_id . ' END as catslug'; + $query->select($this->getState('list.select', 'a.*') . ',' . $case_when . ',' . $case_when1) + /** + * TODO: we actually should be doing it but it's wrong this way + * . ' CASE WHEN CHAR_LENGTH(a.alias) THEN CONCAT_WS(\':\', a.id, a.alias) ELSE a.id END as slug, ' + * . ' CASE WHEN CHAR_LENGTH(c.alias) THEN CONCAT_WS(\':\', c.id, c.alias) ELSE c.id END AS catslug '); + */ + ->from($db->quoteName('#__contact_details') . ' AS a') + ->join('LEFT', '#__categories AS c ON c.id = a.catid') + ->where('a.access IN (' . $groups . ')'); + + // Filter by category. + if ($categoryId = $this->getState('category.id')) + { + $query->where('a.catid = ' . (int) $categoryId) + ->where('c.access IN (' . $groups . ')'); + } + + // Join over the users for the author and modified_by names. + $query->select("CASE WHEN a.created_by_alias > ' ' THEN a.created_by_alias ELSE ua.name END AS author") + ->select('ua.email AS author_email') + + ->join('LEFT', '#__users AS ua ON ua.id = a.created_by') + ->join('LEFT', '#__users AS uam ON uam.id = a.modified_by'); + + // Filter by state + $state = $this->getState('filter.published'); + + if (is_numeric($state)) + { + $query->where('a.published = ' . (int) $state); + } + else + { + $query->where('(a.published IN (0,1,2))'); + } + + // Filter by start and end dates. + $nullDate = $db->quote($db->getNullDate()); + $nowDate = $db->quote(JFactory::getDate()->toSql()); + + if ($this->getState('filter.publish_date')) + { + $query->where('(a.publish_up = ' . $nullDate . ' OR a.publish_up <= ' . $nowDate . ')') + ->where('(a.publish_down = ' . $nullDate . ' OR a.publish_down >= ' . $nowDate . ')'); + } + + // Filter by search in title + $search = $this->getState('list.filter'); + + if (!empty($search)) + { + $search = $db->quote('%' . $db->escape($search, true) . '%'); + $query->where('(a.name LIKE ' . $search . ')'); + } + + // Filter by language + if ($this->getState('filter.language')) + { + $query->where('a.language in (' . $db->quote(JFactory::getLanguage()->getTag()) . ',' . $db->quote('*') . ')'); + } + + // Set sortname ordering if selected + if ($this->getState('list.ordering') === 'sortname') + { + $query->order($db->escape('a.sortname1') . ' ' . $db->escape($this->getState('list.direction', 'ASC'))) + ->order($db->escape('a.sortname2') . ' ' . $db->escape($this->getState('list.direction', 'ASC'))) + ->order($db->escape('a.sortname3') . ' ' . $db->escape($this->getState('list.direction', 'ASC'))); + } + else + { + $query->order($db->escape($this->getState('list.ordering', 'a.ordering')) . ' ' . $db->escape($this->getState('list.direction', 'ASC'))); + } + + return $query; + } + + /** + * Method to auto-populate the model state. + * + * Note. Calling getState in this method will result in recursion. + * + * @param string $ordering An optional ordering field. + * @param string $direction An optional direction (asc|desc). + * + * @return void + * + * @since 1.6 + */ + protected function populateState($ordering = null, $direction = null) + { + $app = JFactory::getApplication(); + $params = JComponentHelper::getParams('com_contact'); + + // List state information + $format = $app->input->getWord('format'); + + if ($format === 'feed') + { + $limit = $app->get('feed_limit'); + } + else + { + $limit = $app->getUserStateFromRequest('global.list.limit', 'limit', $app->get('list_limit'), 'uint'); + } + + $this->setState('list.limit', $limit); + + $limitstart = $app->input->get('limitstart', 0, 'uint'); + $this->setState('list.start', $limitstart); + + // Optional filter text + $itemid = $app->input->get('Itemid', 0, 'int'); + $search = $app->getUserStateFromRequest('com_contact.category.list.' . $itemid . '.filter-search', 'filter-search', '', 'string'); + $this->setState('list.filter', $search); + + // Get list ordering default from the parameters + $menuParams = new Registry; + + if ($menu = $app->getMenu()->getActive()) + { + $menuParams->loadString($menu->params); + } + + $mergedParams = clone $params; + $mergedParams->merge($menuParams); + + $orderCol = $app->input->get('filter_order', $mergedParams->get('initial_sort', 'ordering')); + + if (!in_array($orderCol, $this->filter_fields)) + { + $orderCol = 'ordering'; + } + + $this->setState('list.ordering', $orderCol); + + $listOrder = $app->input->get('filter_order_Dir', 'ASC'); + + if (!in_array(strtoupper($listOrder), array('ASC', 'DESC', ''))) + { + $listOrder = 'ASC'; + } + + $this->setState('list.direction', $listOrder); + + $id = $app->input->get('id', 0, 'int'); + $this->setState('category.id', $id); + + $user = JFactory::getUser(); + + if ((!$user->authorise('core.edit.state', 'com_contact')) && (!$user->authorise('core.edit', 'com_contact'))) + { + // Limit to published for people who can't edit or edit.state. + $this->setState('filter.published', 1); + + // Filter by start and end dates. + $this->setState('filter.publish_date', true); + } + + $this->setState('filter.language', JLanguageMultilang::isEnabled()); + + // Load the parameters. + $this->setState('params', $params); + } + + /** + * Method to get category data for the current category + * + * @return object The category object + * + * @since 1.5 + */ + public function getCategory() + { + if (!is_object($this->_item)) + { + $app = JFactory::getApplication(); + $menu = $app->getMenu(); + $active = $menu->getActive(); + $params = new Registry; + + if ($active) + { + $params->loadString($active->params); + } + + $options = array(); + $options['countItems'] = $params->get('show_cat_items', 1) || $params->get('show_empty_categories', 0); + $categories = JCategories::getInstance('Contact', $options); + $this->_item = $categories->get($this->getState('category.id', 'root')); + + if (is_object($this->_item)) + { + $this->_children = $this->_item->getChildren(); + $this->_parent = false; + + if ($this->_item->getParent()) + { + $this->_parent = $this->_item->getParent(); + } + + $this->_rightsibling = $this->_item->getSibling(); + $this->_leftsibling = $this->_item->getSibling(false); + } + else + { + $this->_children = false; + $this->_parent = false; + } + } + + return $this->_item; + } + + /** + * Get the parent category. + * + * @return mixed An array of categories or false if an error occurs. + */ + public function getParent() + { + if (!is_object($this->_item)) + { + $this->getCategory(); + } + + return $this->_parent; + } + + /** + * Get the sibling (adjacent) categories. + * + * @return mixed An array of categories or false if an error occurs. + */ + public function &getLeftSibling() + { + if (!is_object($this->_item)) + { + $this->getCategory(); + } + + return $this->_leftsibling; + } + + /** + * Get the sibling (adjacent) categories. + * + * @return mixed An array of categories or false if an error occurs. + */ + public function &getRightSibling() + { + if (!is_object($this->_item)) + { + $this->getCategory(); + } + + return $this->_rightsibling; + } + + /** + * Get the child categories. + * + * @return mixed An array of categories or false if an error occurs. + */ + public function &getChildren() + { + if (!is_object($this->_item)) + { + $this->getCategory(); + } + + return $this->_children; + } + + /** + * Increment the hit counter for the category. + * + * @param integer $pk Optional primary key of the category to increment. + * + * @return boolean True if successful; false otherwise and internal error set. + * + * @since 3.2 + */ + public function hit($pk = 0) + { + $input = JFactory::getApplication()->input; + $hitcount = $input->getInt('hitcount', 1); + + if ($hitcount) + { + $pk = (!empty($pk)) ? $pk : (int) $this->getState('category.id'); + + $table = JTable::getInstance('Category', 'JTable'); + $table->hit($pk); + } + + return true; + } +} diff --git a/Sites/pages/components/com_contact/models/contact.php b/Sites/pages/components/com_contact/models/contact.php new file mode 100644 index 00000000..1b0255c1 --- /dev/null +++ b/Sites/pages/components/com_contact/models/contact.php @@ -0,0 +1,634 @@ +setState('contact.id', $app->input->getInt('id')); + $this->setState('params', $app->getParams()); + + $user = JFactory::getUser(); + + if ((!$user->authorise('core.edit.state', 'com_contact')) && (!$user->authorise('core.edit', 'com_contact'))) + { + $this->setState('filter.published', 1); + $this->setState('filter.archived', 2); + } + } + + /** + * Method to get the contact form. + * The base form is loaded from XML and then an event is fired + * + * @param array $data An optional array of data for the form to interrogate. + * @param boolean $loadData True if the form is to load its own data (default case), false if not. + * + * @return JForm A JForm object on success, false on failure + * + * @since 1.6 + */ + public function getForm($data = array(), $loadData = true) + { + $form = $this->loadForm('com_contact.contact', 'contact', array('control' => 'jform', 'load_data' => true)); + + if (empty($form)) + { + return false; + } + + $temp = clone $this->getState('params'); + + $contact = $this->_item[$this->getState('contact.id')]; + + $active = JFactory::getApplication()->getMenu()->getActive(); + + if ($active) + { + // If the current view is the active item and a contact view for this contact, then the menu item params take priority + if (strpos($active->link, 'view=contact') && strpos($active->link, '&id=' . (int) $contact->id)) + { + // $contact->params are the contact params, $temp are the menu item params + // Merge so that the menu item params take priority + $contact->params->merge($temp); + } + else + { + // Current view is not a single contact, so the contact params take priority here + // Merge the menu item params with the contact params so that the contact params take priority + $temp->merge($contact->params); + $contact->params = $temp; + } + } + else + { + // Merge so that contact params take priority + $temp->merge($contact->params); + $contact->params = $temp; + } + + if (!$contact->params->get('show_email_copy', 0)) + { + $form->removeField('contact_email_copy'); + } + + return $form; + } + + /** + * Method to get the data that should be injected in the form. + * + * @return array The default data is an empty array. + * + * @since 1.6.2 + */ + protected function loadFormData() + { + $data = (array) JFactory::getApplication()->getUserState('com_contact.contact.data', array()); + + if (empty($data['language']) && JLanguageMultilang::isEnabled()) + { + $data['language'] = JFactory::getLanguage()->getTag(); + } + + // Add contact id to contact form data, so fields plugin can work properly + if (empty($data['catid'])) + { + $data['catid'] = $this->getItem()->catid; + } + + $this->preprocessData('com_contact.contact', $data); + + return $data; + } + + /** + * Gets a contact + * + * @param integer $pk Id for the contact + * + * @return mixed Object or null + * + * @since 1.6.0 + */ + public function &getItem($pk = null) + { + $pk = (!empty($pk)) ? $pk : (int) $this->getState('contact.id'); + + if ($this->_item === null) + { + $this->_item = array(); + } + + if (!isset($this->_item[$pk])) + { + try + { + $db = $this->getDbo(); + $query = $db->getQuery(true); + + // Changes for sqlsrv + $case_when = ' CASE WHEN '; + $case_when .= $query->charLength('a.alias', '!=', '0'); + $case_when .= ' THEN '; + $a_id = $query->castAsChar('a.id'); + $case_when .= $query->concatenate(array($a_id, 'a.alias'), ':'); + $case_when .= ' ELSE '; + $case_when .= $a_id . ' END as slug'; + + $case_when1 = ' CASE WHEN '; + $case_when1 .= $query->charLength('c.alias', '!=', '0'); + $case_when1 .= ' THEN '; + $c_id = $query->castAsChar('c.id'); + $case_when1 .= $query->concatenate(array($c_id, 'c.alias'), ':'); + $case_when1 .= ' ELSE '; + $case_when1 .= $c_id . ' END as catslug'; + + $query->select($this->getState('item.select', 'a.*') . ',' . $case_when . ',' . $case_when1) + ->from('#__contact_details AS a') + + // Join on category table. + ->select('c.title AS category_title, c.alias AS category_alias, c.access AS category_access') + ->join('LEFT', '#__categories AS c on c.id = a.catid') + + // Join over the categories to get parent category titles + ->select('parent.title as parent_title, parent.id as parent_id, parent.path as parent_route, parent.alias as parent_alias') + ->join('LEFT', '#__categories as parent ON parent.id = c.parent_id') + + ->where('a.id = ' . (int) $pk); + + // Filter by start and end dates. + $nullDate = $db->quote($db->getNullDate()); + $nowDate = $db->quote(JFactory::getDate()->toSql()); + + // Filter by published state. + $published = $this->getState('filter.published'); + $archived = $this->getState('filter.archived'); + + if (is_numeric($published)) + { + $query->where('(a.published = ' . (int) $published . ' OR a.published =' . (int) $archived . ')') + ->where('(a.publish_up = ' . $nullDate . ' OR a.publish_up <= ' . $nowDate . ')') + ->where('(a.publish_down = ' . $nullDate . ' OR a.publish_down >= ' . $nowDate . ')'); + } + + $db->setQuery($query); + $data = $db->loadObject(); + + if (empty($data)) + { + JError::raiseError(404, JText::_('COM_CONTACT_ERROR_CONTACT_NOT_FOUND')); + } + + // Check for published state if filter set. + if ((is_numeric($published) || is_numeric($archived)) && (($data->published != $published) && ($data->published != $archived))) + { + JError::raiseError(404, JText::_('COM_CONTACT_ERROR_CONTACT_NOT_FOUND')); + } + + /** + * In case some entity params have been set to "use global", those are + * represented as an empty string and must be "overridden" by merging + * the component and / or menu params here. + */ + $registry = new Registry($data->params); + + $data->params = clone $this->getState('params'); + $data->params->merge($registry); + + $registry = new Registry($data->metadata); + $data->metadata = $registry; + + // Some contexts may not use tags data at all, so we allow callers to disable loading tag data + if ($this->getState('load_tags', true)) + { + $data->tags = new JHelperTags; + $data->tags->getItemTags('com_contact.contact', $data->id); + } + + // Compute access permissions. + if (($access = $this->getState('filter.access'))) + { + // If the access filter has been set, we already know this user can view. + $data->params->set('access-view', true); + } + else + { + // If no access filter is set, the layout takes some responsibility for display of limited information. + $user = JFactory::getUser(); + $groups = $user->getAuthorisedViewLevels(); + + if ($data->catid == 0 || $data->category_access === null) + { + $data->params->set('access-view', in_array($data->access, $groups)); + } + else + { + $data->params->set('access-view', in_array($data->access, $groups) && in_array($data->category_access, $groups)); + } + } + + $this->_item[$pk] = $data; + } + catch (Exception $e) + { + $this->setError($e); + $this->_item[$pk] = false; + } + } + + if ($this->_item[$pk]) + { + $this->buildContactExtendedData($this->_item[$pk]); + } + + return $this->_item[$pk]; + } + + /** + * Load extended data (profile, articles) for a contact + * + * @param object $contact The contact object + * + * @return void + */ + protected function buildContactExtendedData($contact) + { + $db = $this->getDbo(); + $nullDate = $db->quote($db->getNullDate()); + $nowDate = $db->quote(JFactory::getDate()->toSql()); + $user = JFactory::getUser(); + $groups = implode(',', $user->getAuthorisedViewLevels()); + $published = $this->getState('filter.published'); + + // If we are showing a contact list, then the contact parameters take priority + // So merge the contact parameters with the merged parameters + if ($this->getState('params')->get('show_contact_list')) + { + $this->getState('params')->merge($contact->params); + } + + // Get the com_content articles by the linked user + if ((int) $contact->user_id && $this->getState('params')->get('show_articles')) + { + $query = $db->getQuery(true) + ->select('a.id') + ->select('a.title') + ->select('a.state') + ->select('a.access') + ->select('a.catid') + ->select('a.created') + ->select('a.language') + ->select('a.publish_up'); + + // SQL Server changes + $case_when = ' CASE WHEN '; + $case_when .= $query->charLength('a.alias', '!=', '0'); + $case_when .= ' THEN '; + $a_id = $query->castAsChar('a.id'); + $case_when .= $query->concatenate(array($a_id, 'a.alias'), ':'); + $case_when .= ' ELSE '; + $case_when .= $a_id . ' END as slug'; + $case_when1 = ' CASE WHEN '; + $case_when1 .= $query->charLength('c.alias', '!=', '0'); + $case_when1 .= ' THEN '; + $c_id = $query->castAsChar('c.id'); + $case_when1 .= $query->concatenate(array($c_id, 'c.alias'), ':'); + $case_when1 .= ' ELSE '; + $case_when1 .= $c_id . ' END as catslug'; + $query->select($case_when1 . ',' . $case_when) + ->from('#__content as a') + ->join('LEFT', '#__categories as c on a.catid=c.id') + ->where('a.created_by = ' . (int) $contact->user_id) + ->where('a.access IN (' . $groups . ')') + ->order('a.publish_up DESC'); + + // Filter per language if plugin published + if (JLanguageMultilang::isEnabled()) + { + $query->where('a.language IN (' . $db->quote(JFactory::getLanguage()->getTag()) . ',' . $db->quote('*') . ')'); + } + + if (is_numeric($published)) + { + $query->where('a.state IN (1,2)') + ->where('(a.publish_up = ' . $nullDate . ' OR a.publish_up <= ' . $nowDate . ')') + ->where('(a.publish_down = ' . $nullDate . ' OR a.publish_down >= ' . $nowDate . ')'); + } + + // Number of articles to display from config/menu params + $articles_display_num = $this->getState('params')->get('articles_display_num', 10); + + // Use contact setting? + if ($articles_display_num === 'use_contact') + { + $articles_display_num = $contact->params->get('articles_display_num', 10); + + // Use global? + if ((string) $articles_display_num === '') + { + $articles_display_num = JComponentHelper::getParams('com_contact')->get('articles_display_num', 10); + } + } + + $db->setQuery($query, 0, (int) $articles_display_num); + $articles = $db->loadObjectList(); + $contact->articles = $articles; + } + else + { + $contact->articles = null; + } + + // Get the profile information for the linked user + JModelLegacy::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_users/models', 'UsersModel'); + $userModel = JModelLegacy::getInstance('User', 'UsersModel', array('ignore_request' => true)); + $data = $userModel->getItem((int) $contact->user_id); + + JPluginHelper::importPlugin('user'); + + // Get the form. + JForm::addFormPath(JPATH_SITE . '/components/com_users/models/forms'); + JForm::addFieldPath(JPATH_SITE . '/components/com_users/models/fields'); + JForm::addFormPath(JPATH_SITE . '/components/com_users/model/form'); + JForm::addFieldPath(JPATH_SITE . '/components/com_users/model/field'); + + $form = JForm::getInstance('com_users.profile', 'profile'); + + // Get the dispatcher. + $dispatcher = JEventDispatcher::getInstance(); + + // Trigger the form preparation event. + $dispatcher->trigger('onContentPrepareForm', array($form, $data)); + + // Trigger the data preparation event. + $dispatcher->trigger('onContentPrepareData', array('com_users.profile', $data)); + + // Load the data into the form after the plugins have operated. + $form->bind($data); + $contact->profile = $form; + } + + /** + * Gets the query to load a contact item + * + * @param integer $pk The item to be loaded + * + * @return mixed The contact object on success, false on failure + * + * @throws Exception On database failure + * @deprecated 4.0 Use ContactModelContact::getItem() instead + */ + protected function getContactQuery($pk = null) + { + // @todo Cache on the fingerprint of the arguments + $db = $this->getDbo(); + $nullDate = $db->quote($db->getNullDate()); + $nowDate = $db->quote(JFactory::getDate()->toSql()); + $user = JFactory::getUser(); + $pk = (!empty($pk)) ? $pk : (int) $this->getState('contact.id'); + $query = $db->getQuery(true); + + if ($pk) + { + // Sqlsrv changes + $case_when = ' CASE WHEN '; + $case_when .= $query->charLength('a.alias', '!=', '0'); + $case_when .= ' THEN '; + + $a_id = $query->castAsChar('a.id'); + $case_when .= $query->concatenate(array($a_id, 'a.alias'), ':'); + $case_when .= ' ELSE '; + $case_when .= $a_id . ' END as slug'; + + $case_when1 = ' CASE WHEN '; + $case_when1 .= $query->charLength('cc.alias', '!=', '0'); + $case_when1 .= ' THEN '; + + $c_id = $query->castAsChar('cc.id'); + $case_when1 .= $query->concatenate(array($c_id, 'cc.alias'), ':'); + $case_when1 .= ' ELSE '; + $case_when1 .= $c_id . ' END as catslug'; + + $query->select( + 'a.*, cc.access as category_access, cc.title as category_name, ' + . $case_when . ',' . $case_when1 + ) + ->from('#__contact_details AS a') + ->join('INNER', '#__categories AS cc on cc.id = a.catid') + ->where('a.id = ' . (int) $pk); + + $published = $this->getState('filter.published'); + + if (is_numeric($published)) + { + $query->where('a.published IN (1,2)') + ->where('cc.published IN (1,2)'); + } + + $groups = implode(',', $user->getAuthorisedViewLevels()); + $query->where('a.access IN (' . $groups . ')'); + + try + { + $db->setQuery($query); + $result = $db->loadObject(); + + if (empty($result)) + { + return false; + } + } + catch (Exception $e) + { + $this->setError($e->getMessage()); + + return false; + } + + if ($result) + { + $contactParams = new Registry($result->params); + + // If we are showing a contact list, then the contact parameters take priority + // So merge the contact parameters with the merged parameters + if ($this->getState('params')->get('show_contact_list')) + { + $this->getState('params')->merge($contactParams); + } + + // Get the com_content articles by the linked user + if ((int) $result->user_id && $this->getState('params')->get('show_articles')) + { + $query = $db->getQuery(true) + ->select('a.id') + ->select('a.title') + ->select('a.state') + ->select('a.access') + ->select('a.catid') + ->select('a.created') + ->select('a.language') + ->select('a.publish_up'); + + // SQL Server changes + $case_when = ' CASE WHEN '; + $case_when .= $query->charLength('a.alias', '!=', '0'); + $case_when .= ' THEN '; + $a_id = $query->castAsChar('a.id'); + $case_when .= $query->concatenate(array($a_id, 'a.alias'), ':'); + $case_when .= ' ELSE '; + $case_when .= $a_id . ' END as slug'; + $case_when1 = ' CASE WHEN '; + $case_when1 .= $query->charLength('c.alias', '!=', '0'); + $case_when1 .= ' THEN '; + $c_id = $query->castAsChar('c.id'); + $case_when1 .= $query->concatenate(array($c_id, 'c.alias'), ':'); + $case_when1 .= ' ELSE '; + $case_when1 .= $c_id . ' END as catslug'; + $query->select($case_when1 . ',' . $case_when) + ->from('#__content as a') + ->join('LEFT', '#__categories as c on a.catid=c.id') + ->where('a.created_by = ' . (int) $result->user_id) + ->where('a.access IN (' . $groups . ')') + ->order('a.publish_up DESC'); + + // Filter per language if plugin published + if (JLanguageMultilang::isEnabled()) + { + $query->where('a.language IN (' . $db->quote(JFactory::getLanguage()->getTag()) . ',' . $db->quote('*') . ')'); + } + + if (is_numeric($published)) + { + $query->where('a.state IN (1,2)') + ->where('(a.publish_up = ' . $nullDate . ' OR a.publish_up <= ' . $nowDate . ')') + ->where('(a.publish_down = ' . $nullDate . ' OR a.publish_down >= ' . $nowDate . ')'); + } + + // Number of articles to display from config/menu params + $articles_display_num = $this->getState('params')->get('articles_display_num', 10); + + // Use contact setting? + if ($articles_display_num === 'use_contact') + { + $articles_display_num = $contactParams->get('articles_display_num', 10); + + // Use global? + if ((string) $articles_display_num === '') + { + $articles_display_num = JComponentHelper::getParams('com_contact')->get('articles_display_num', 10); + } + } + + $db->setQuery($query, 0, (int) $articles_display_num); + $articles = $db->loadObjectList(); + $result->articles = $articles; + } + else + { + $result->articles = null; + } + + // Get the profile information for the linked user + JModelLegacy::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_users/models', 'UsersModel'); + $userModel = JModelLegacy::getInstance('User', 'UsersModel', array('ignore_request' => true)); + $data = $userModel->getItem((int) $result->user_id); + + JPluginHelper::importPlugin('user'); + $form = new JForm('com_users.profile'); + + // Get the dispatcher. + $dispatcher = JEventDispatcher::getInstance(); + + // Trigger the form preparation event. + $dispatcher->trigger('onContentPrepareForm', array($form, $data)); + + // Trigger the data preparation event. + $dispatcher->trigger('onContentPrepareData', array('com_users.profile', $data)); + + // Load the data into the form after the plugins have operated. + $form->bind($data); + $result->profile = $form; + $this->contact = $result; + + return $result; + } + } + + return false; + } + + /** + * Increment the hit counter for the contact. + * + * @param integer $pk Optional primary key of the contact to increment. + * + * @return boolean True if successful; false otherwise and internal error set. + * + * @since 3.0 + */ + public function hit($pk = 0) + { + $input = JFactory::getApplication()->input; + $hitcount = $input->getInt('hitcount', 1); + + if ($hitcount) + { + $pk = (!empty($pk)) ? $pk : (int) $this->getState('contact.id'); + + $table = JTable::getInstance('Contact', 'ContactTable'); + $table->hit($pk); + } + + return true; + } +} diff --git a/Sites/pages/components/com_contact/models/featured.php b/Sites/pages/components/com_contact/models/featured.php new file mode 100644 index 00000000..c217b1b3 --- /dev/null +++ b/Sites/pages/components/com_contact/models/featured.php @@ -0,0 +1,252 @@ +_params)) + { + $item->params = new Registry($item->params); + } + } + + return $items; + } + + /** + * Method to build an SQL query to load the list data. + * + * @return string An SQL query + * + * @since 1.6 + */ + protected function getListQuery() + { + $user = JFactory::getUser(); + $groups = implode(',', $user->getAuthorisedViewLevels()); + + // Create a new query object. + $db = $this->getDbo(); + $query = $db->getQuery(true); + + // Select required fields from the categories. + $query->select($this->getState('list.select', 'a.*')) + ->from($db->quoteName('#__contact_details') . ' AS a') + ->where('a.access IN (' . $groups . ')') + ->where('a.featured=1') + ->join('INNER', '#__categories AS c ON c.id = a.catid') + ->where('c.access IN (' . $groups . ')'); + + // Filter by category. + if ($categoryId = $this->getState('category.id')) + { + $query->where('a.catid = ' . (int) $categoryId); + } + + // Change for sqlsrv... aliased c.published to cat_published + $query->select('c.published as cat_published, c.published AS parents_published') + ->where('c.published = 1'); + + // Filter by state + $state = $this->getState('filter.published'); + + if (is_numeric($state)) + { + $query->where('a.published = ' . (int) $state); + + // Filter by start and end dates. + $nullDate = $db->quote($db->getNullDate()); + $date = JFactory::getDate(); + $nowDate = $db->quote($date->toSql()); + $query->where('(a.publish_up = ' . $nullDate . ' OR a.publish_up <= ' . $nowDate . ')') + ->where('(a.publish_down = ' . $nullDate . ' OR a.publish_down >= ' . $nowDate . ')'); + } + + // Filter by language + if ($this->getState('filter.language')) + { + $query->where('a.language in (' . $db->quote(JFactory::getLanguage()->getTag()) . ',' . $db->quote('*') . ')'); + } + + // Add the list ordering clause. + $query->order($db->escape($this->getState('list.ordering', 'a.ordering')) . ' ' . $db->escape($this->getState('list.direction', 'ASC'))); + + return $query; + } + + /** + * Method to auto-populate the model state. + * + * Note. Calling getState in this method will result in recursion. + * + * @param string $ordering An optional ordering field. + * @param string $direction An optional direction (asc|desc). + * + * @return void + * + * @since 1.6 + */ + protected function populateState($ordering = null, $direction = null) + { + $app = JFactory::getApplication(); + $params = JComponentHelper::getParams('com_contact'); + + // List state information + $limit = $app->getUserStateFromRequest('global.list.limit', 'limit', $app->get('list_limit'), 'uint'); + $this->setState('list.limit', $limit); + + $limitstart = $app->input->get('limitstart', 0, 'uint'); + $this->setState('list.start', $limitstart); + + $orderCol = $app->input->get('filter_order', 'ordering'); + + if (!in_array($orderCol, $this->filter_fields)) + { + $orderCol = 'ordering'; + } + + $this->setState('list.ordering', $orderCol); + + $listOrder = $app->input->get('filter_order_Dir', 'ASC'); + + if (!in_array(strtoupper($listOrder), array('ASC', 'DESC', ''))) + { + $listOrder = 'ASC'; + } + + $this->setState('list.direction', $listOrder); + + $user = JFactory::getUser(); + + if ((!$user->authorise('core.edit.state', 'com_contact')) && (!$user->authorise('core.edit', 'com_contact'))) + { + // Limit to published for people who can't edit or edit.state. + $this->setState('filter.published', 1); + + // Filter by start and end dates. + $this->setState('filter.publish_date', true); + } + + $this->setState('filter.language', JLanguageMultilang::isEnabled()); + + // Load the parameters. + $this->setState('params', $params); + } +} diff --git a/Sites/pages/components/com_contact/models/forms/contact.xml b/Sites/pages/components/com_contact/models/forms/contact.xml new file mode 100644 index 00000000..8e641c2b --- /dev/null +++ b/Sites/pages/components/com_contact/models/forms/contact.xml @@ -0,0 +1,80 @@ + +
          +
          + + + + + + + + + + + +
          + +
          + +
          +
          diff --git a/Sites/pages/components/com_contact/models/forms/filter_contacts.xml b/Sites/pages/components/com_contact/models/forms/filter_contacts.xml new file mode 100644 index 00000000..96b40fd8 --- /dev/null +++ b/Sites/pages/components/com_contact/models/forms/filter_contacts.xml @@ -0,0 +1,138 @@ + +
          +
          + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Sites/pages/components/com_contact/models/forms/form.xml b/Sites/pages/components/com_contact/models/forms/form.xml new file mode 100644 index 00000000..32c11a03 --- /dev/null +++ b/Sites/pages/components/com_contact/models/forms/form.xml @@ -0,0 +1,745 @@ + + +
          +
          + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + +
          + + + + + + + + + + +
          +
          + + +
          + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          +
          + + +
          + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          +
          +
          + diff --git a/Sites/pages/components/com_contact/models/rules/contactemail.php b/Sites/pages/components/com_contact/models/rules/contactemail.php new file mode 100644 index 00000000..e6528594 --- /dev/null +++ b/Sites/pages/components/com_contact/models/rules/contactemail.php @@ -0,0 +1,60 @@ + tag for the form field object. + * @param mixed $value The form field value to validate. + * @param string $group The field name group control value. This acts as an array container for the field. + * For example if the field has name="foo" and the group value is set to "bar" then the + * full field name would end up being "bar[foo]". + * @param Registry $input An optional Registry object with the entire data set to validate against the entire form. + * @param JForm $form The form object for which the field is being tested. + * + * @return boolean True if the value is valid, false otherwise. + */ + public function test(SimpleXMLElement $element, $value, $group = null, Registry $input = null, JForm $form = null) + { + if (!parent::test($element, $value, $group, $input, $form)) + { + return false; + } + + $params = JComponentHelper::getParams('com_contact'); + $banned = $params->get('banned_email'); + + if ($banned) + { + foreach (explode(';', $banned) as $item) + { + if ($item != '' && StringHelper::stristr($value, $item) !== false) + { + return false; + } + } + } + + return true; + } +} diff --git a/Sites/pages/components/com_contact/models/rules/contactemailmessage.php b/Sites/pages/components/com_contact/models/rules/contactemailmessage.php new file mode 100644 index 00000000..6ea3a16c --- /dev/null +++ b/Sites/pages/components/com_contact/models/rules/contactemailmessage.php @@ -0,0 +1,53 @@ + tag for the form field object. + * @param mixed $value The form field value to validate. + * @param string $group The field name group control value. This acts as an array container for the field. + * For example if the field has name="foo" and the group value is set to "bar" then the + * full field name would end up being "bar[foo]". + * @param Registry $input An optional Registry object with the entire data set to validate against the entire form. + * @param JForm $form The form object for which the field is being tested. + * + * @return boolean True if the value is valid, false otherwise. + */ + public function test(SimpleXMLElement $element, $value, $group = null, Registry $input = null, JForm $form = null) + { + $params = JComponentHelper::getParams('com_contact'); + $banned = $params->get('banned_text'); + + if ($banned) + { + foreach (explode(';', $banned) as $item) + { + if ($item != '' && StringHelper::stristr($value, $item) !== false) + { + return false; + } + } + } + + return true; + } +} diff --git a/Sites/pages/components/com_contact/models/rules/contactemailsubject.php b/Sites/pages/components/com_contact/models/rules/contactemailsubject.php new file mode 100644 index 00000000..11fbb04c --- /dev/null +++ b/Sites/pages/components/com_contact/models/rules/contactemailsubject.php @@ -0,0 +1,53 @@ + tag for the form field object. + * @param mixed $value The form field value to validate. + * @param string $group The field name group control value. This acts as an array container for the field. + * For example if the field has name="foo" and the group value is set to "bar" then the + * full field name would end up being "bar[foo]". + * @param Registry $input An optional Registry object with the entire data set to validate against the entire form. + * @param JForm $form The form object for which the field is being tested. + * + * @return boolean True if the value is valid, false otherwise + */ + public function test(SimpleXMLElement $element, $value, $group = null, Registry $input = null, JForm $form = null) + { + $params = JComponentHelper::getParams('com_contact'); + $banned = $params->get('banned_subject'); + + if ($banned) + { + foreach (explode(';', $banned) as $item) + { + if ($item != '' && StringHelper::stristr($value, $item) !== false) + { + return false; + } + } + } + + return true; + } +} diff --git a/Sites/pages/components/com_contact/router.php b/Sites/pages/components/com_contact/router.php new file mode 100644 index 00000000..107b2557 --- /dev/null +++ b/Sites/pages/components/com_contact/router.php @@ -0,0 +1,251 @@ +noIDs = (bool) $params->get('sef_ids'); + $categories = new JComponentRouterViewconfiguration('categories'); + $categories->setKey('id'); + $this->registerView($categories); + $category = new JComponentRouterViewconfiguration('category'); + $category->setKey('id')->setParent($categories, 'catid')->setNestable(); + $this->registerView($category); + $contact = new JComponentRouterViewconfiguration('contact'); + $contact->setKey('id')->setParent($category, 'catid'); + $this->registerView($contact); + $this->registerView(new JComponentRouterViewconfiguration('featured')); + + parent::__construct($app, $menu); + + $this->attachRule(new JComponentRouterRulesMenu($this)); + + if ($params->get('sef_advanced', 0)) + { + $this->attachRule(new JComponentRouterRulesStandard($this)); + $this->attachRule(new JComponentRouterRulesNomenu($this)); + } + else + { + JLoader::register('ContactRouterRulesLegacy', __DIR__ . '/helpers/legacyrouter.php'); + $this->attachRule(new ContactRouterRulesLegacy($this)); + } + } + + /** + * Method to get the segment(s) for a category + * + * @param string $id ID of the category to retrieve the segments for + * @param array $query The request that is built right now + * + * @return array|string The segments of this item + */ + public function getCategorySegment($id, $query) + { + $category = JCategories::getInstance($this->getName())->get($id); + + if ($category) + { + $path = array_reverse($category->getPath(), true); + $path[0] = '1:root'; + + if ($this->noIDs) + { + foreach ($path as &$segment) + { + list($id, $segment) = explode(':', $segment, 2); + } + } + + return $path; + } + + return array(); + } + + /** + * Method to get the segment(s) for a category + * + * @param string $id ID of the category to retrieve the segments for + * @param array $query The request that is built right now + * + * @return array|string The segments of this item + */ + public function getCategoriesSegment($id, $query) + { + return $this->getCategorySegment($id, $query); + } + + /** + * Method to get the segment(s) for a contact + * + * @param string $id ID of the contact to retrieve the segments for + * @param array $query The request that is built right now + * + * @return array|string The segments of this item + */ + public function getContactSegment($id, $query) + { + if (!strpos($id, ':')) + { + $db = JFactory::getDbo(); + $dbquery = $db->getQuery(true); + $dbquery->select($dbquery->qn('alias')) + ->from($dbquery->qn('#__contact_details')) + ->where('id = ' . $dbquery->q((int) $id)); + $db->setQuery($dbquery); + + $id .= ':' . $db->loadResult(); + } + + if ($this->noIDs) + { + list($void, $segment) = explode(':', $id, 2); + + return array($void => $segment); + } + + return array((int) $id => $id); + } + + /** + * Method to get the id for a category + * + * @param string $segment Segment to retrieve the ID for + * @param array $query The request that is parsed right now + * + * @return mixed The id of this item or false + */ + public function getCategoryId($segment, $query) + { + if (isset($query['id'])) + { + $category = JCategories::getInstance($this->getName(), array('access' => false))->get($query['id']); + + if ($category) + { + foreach ($category->getChildren() as $child) + { + if ($this->noIDs) + { + if ($child->alias == $segment) + { + return $child->id; + } + } + else + { + if ($child->id == (int) $segment) + { + return $child->id; + } + } + } + } + } + + return false; + } + + /** + * Method to get the segment(s) for a category + * + * @param string $segment Segment to retrieve the ID for + * @param array $query The request that is parsed right now + * + * @return mixed The id of this item or false + */ + public function getCategoriesId($segment, $query) + { + return $this->getCategoryId($segment, $query); + } + + /** + * Method to get the segment(s) for a contact + * + * @param string $segment Segment of the contact to retrieve the ID for + * @param array $query The request that is parsed right now + * + * @return mixed The id of this item or false + */ + public function getContactId($segment, $query) + { + if ($this->noIDs) + { + $db = JFactory::getDbo(); + $dbquery = $db->getQuery(true); + $dbquery->select($dbquery->qn('id')) + ->from($dbquery->qn('#__contact_details')) + ->where('alias = ' . $dbquery->q($segment)) + ->where('catid = ' . $dbquery->q($query['id'])); + $db->setQuery($dbquery); + + return (int) $db->loadResult(); + } + + return (int) $segment; + } +} + +/** + * Contact router functions + * + * These functions are proxys for the new router interface + * for old SEF extensions. + * + * @param array &$query An array of URL arguments + * + * @return array The URL arguments to use to assemble the subsequent URL. + * + * @deprecated 4.0 Use Class based routers instead + */ +function ContactBuildRoute(&$query) +{ + $app = JFactory::getApplication(); + $router = new ContactRouter($app, $app->getMenu()); + + return $router->build($query); +} + +/** + * Contact router functions + * + * These functions are proxys for the new router interface + * for old SEF extensions. + * + * @param array $segments The segments of the URL to parse. + * + * @return array The URL attributes to be used by the application. + * + * @deprecated 4.0 Use Class based routers instead + */ +function ContactParseRoute($segments) +{ + $app = JFactory::getApplication(); + $router = new ContactRouter($app, $app->getMenu()); + + return $router->parse($segments); +} diff --git a/Sites/pages/components/com_contact/views/categories/tmpl/default.php b/Sites/pages/components/com_contact/views/categories/tmpl/default.php new file mode 100644 index 00000000..37b86d3e --- /dev/null +++ b/Sites/pages/components/com_contact/views/categories/tmpl/default.php @@ -0,0 +1,42 @@ +addScriptDeclaration(" +jQuery(function($) { + $('.categories-list').find('[id^=category-btn-]').each(function(index, btn) { + var btn = $(btn); + btn.on('click', function() { + btn.find('span').toggleClass('icon-plus'); + btn.find('span').toggleClass('icon-minus'); + if (btn.attr('aria-label') === Joomla.JText._('JGLOBAL_EXPAND_CATEGORIES')) + { + btn.attr('aria-label', Joomla.JText._('JGLOBAL_COLLAPSE_CATEGORIES')); + } else { + btn.attr('aria-label', Joomla.JText._('JGLOBAL_EXPAND_CATEGORIES')); + } + }); + }); +});"); +?> +
          + loadTemplate('items'); + ?> +
          diff --git a/Sites/pages/components/com_contact/views/categories/tmpl/default.xml b/Sites/pages/components/com_contact/views/categories/tmpl/default.xml new file mode 100644 index 00000000..c4af3dee --- /dev/null +++ b/Sites/pages/components/com_contact/views/categories/tmpl/default.xml @@ -0,0 +1,787 @@ + + + + + + + + + + + +
          + +
          +
          + +
          + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          +
          + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + +
          + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + +
          + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + +
          + + + + + + + + + + + + + + + + + + + + + +
          + +
          + + + + + + +
          +
          +
          diff --git a/Sites/pages/components/com_contact/views/categories/tmpl/default_items.php b/Sites/pages/components/com_contact/views/categories/tmpl/default_items.php new file mode 100644 index 00000000..a85f9667 --- /dev/null +++ b/Sites/pages/components/com_contact/views/categories/tmpl/default_items.php @@ -0,0 +1,63 @@ +maxLevelcat != 0 && count($this->items[$this->parent->id]) > 0) : +?> + items[$this->parent->id] as $id => $item) : ?> + params->get('show_empty_categories_cat') || $item->numitems || count($item->getChildren())) : + if (!isset($this->items[$this->parent->id][$id + 1])) + { + $class = ' class="last"'; + } + ?> +
          > + + + params->get('show_subcat_desc_cat') == 1) : ?> + description) : ?> +
          + description, '', 'com_contact.categories'); ?> +
          + + + + maxLevelcat > 1 && count($item->getChildren()) > 0) : ?> +
          + items[$item->id] = $item->getChildren(); + $this->parent = $item; + $this->maxLevelcat--; + echo $this->loadTemplate('items'); + $this->parent = $item->getParent(); + $this->maxLevelcat++; + ?> +
          + +
          + + diff --git a/Sites/pages/components/com_contact/views/categories/view.html.php b/Sites/pages/components/com_contact/views/categories/view.html.php new file mode 100644 index 00000000..6a740757 --- /dev/null +++ b/Sites/pages/components/com_contact/views/categories/view.html.php @@ -0,0 +1,32 @@ +subtemplatename = 'items'; +echo JLayoutHelper::render('joomla.content.category_default', $this); diff --git a/Sites/pages/components/com_contact/views/category/tmpl/default.xml b/Sites/pages/components/com_contact/views/category/tmpl/default.xml new file mode 100644 index 00000000..e3a53fa7 --- /dev/null +++ b/Sites/pages/components/com_contact/views/category/tmpl/default.xml @@ -0,0 +1,777 @@ + + + + + + + + + + + +
          + +
          +
          + + + + +
          + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + +
          + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + +
          + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + +
          + + + + + + + + + + + + + + + + + + + + + + +
          + +
          + + + + + + +
          +
          +
          diff --git a/Sites/pages/components/com_contact/views/category/tmpl/default_children.php b/Sites/pages/components/com_contact/views/category/tmpl/default_children.php new file mode 100644 index 00000000..49a830b5 --- /dev/null +++ b/Sites/pages/components/com_contact/views/category/tmpl/default_children.php @@ -0,0 +1,55 @@ +maxLevel != 0 && count($this->children[$this->category->id]) > 0) : +?> +
            +children[$this->category->id] as $id => $child) : ?> + params->get('show_empty_categories') || $child->numitems || count($child->getChildren())) : + if (!isset($this->children[$this->category->id][$id + 1])) + { + $class = ' class="last"'; + } + ?> + > + +

            + + escape($child->title); ?> + + + params->get('show_cat_items') == 1) : ?> + numitems; ?> + +

            + + params->get('show_subcat_desc') == 1) : ?> + description) : ?> +
            + description, '', 'com_contact.category'); ?> +
            + + + + getChildren()) > 0 ) : + $this->children[$child->id] = $child->getChildren(); + $this->category = $child; + $this->maxLevel--; + echo $this->loadTemplate('children'); + $this->category = $child->getParent(); + $this->maxLevel++; + endif; ?> + + + +
          + diff --git a/Sites/pages/components/com_contact/views/category/tmpl/default_items.php b/Sites/pages/components/com_contact/views/category/tmpl/default_items.php new file mode 100644 index 00000000..044c5dce --- /dev/null +++ b/Sites/pages/components/com_contact/views/category/tmpl/default_items.php @@ -0,0 +1,138 @@ + +
          + params->get('filter_field') || $this->params->get('show_pagination_limit')) : ?> +
          + params->get('filter_field')) : ?> +
          + + +
          + + params->get('show_pagination_limit')) : ?> +
          + + pagination->getLimitBox(); ?> +
          + +
          + + items)) : ?> +

          + +

          + +
            + items as $i => $item) : ?> + access, $this->user->getAuthorisedViewLevels())) : ?> + items[$i]->published == 0) : ?> +
          • + +
          • + + params->get('show_image_heading')) : ?> + + + + + +
            + + name; ?> + + items[$i]->published == 0) : ?> + + + + + event->afterDisplayTitle; ?> + event->beforeDisplayContent; ?> + params->get('show_position_headings')) : ?> + con_position; ?>
            + + params->get('show_email_headings')) : ?> + email_to; ?>
            + + + params->get('show_suburb_headings') && !empty($item->suburb)) : ?> + suburb; ?> + + params->get('show_state_headings') && !empty($item->state)) : ?> + state; ?> + + params->get('show_country_headings') && !empty($item->country)) : ?> + country; ?> + + +
            +
            + params->get('show_telephone_headings') && !empty($item->telephone)) : ?> + telephone); ?>
            + + params->get('show_mobile_headings') && !empty ($item->mobile)) : ?> + mobile); ?>
            + + params->get('show_fax_headings') && !empty($item->fax)) : ?> + fax); ?>
            + +
            + event->afterDisplayContent; ?> +
          • + + +
          + + params->get('show_pagination', 2)) : ?> + + +
          + + +
          +
          diff --git a/Sites/pages/components/com_contact/views/category/view.feed.php b/Sites/pages/components/com_contact/views/category/view.feed.php new file mode 100644 index 00000000..21ec29c6 --- /dev/null +++ b/Sites/pages/components/com_contact/views/category/view.feed.php @@ -0,0 +1,41 @@ +description = $item->address; + } +} diff --git a/Sites/pages/components/com_contact/views/category/view.html.php b/Sites/pages/components/com_contact/views/category/view.html.php new file mode 100644 index 00000000..ce310802 --- /dev/null +++ b/Sites/pages/components/com_contact/views/category/view.html.php @@ -0,0 +1,121 @@ +pagination->hideEmptyLimitstart = true; + + // Prepare the data. + // Compute the contact slug. + foreach ($this->items as $item) + { + $item->slug = $item->alias ? ($item->id . ':' . $item->alias) : $item->id; + $temp = $item->params; + $item->params = clone $this->params; + $item->params->merge($temp); + + if ($item->params->get('show_email_headings', 0) == 1) + { + $item->email_to = trim($item->email_to); + + if (!empty($item->email_to) && JMailHelper::isEmailAddress($item->email_to)) + { + $item->email_to = JHtml::_('email.cloak', $item->email_to); + } + else + { + $item->email_to = ''; + } + } + } + + return parent::display($tpl); + } + + /** + * Prepares the document + * + * @return void + */ + protected function prepareDocument() + { + parent::prepareDocument(); + + $menu = $this->menu; + $id = (int) @$menu->query['id']; + + if ($menu && (!isset($menu->query['option']) || $menu->query['option'] != $this->extension || $menu->query['view'] == $this->viewName + || $id != $this->category->id)) + { + $path = array(array('title' => $this->category->title, 'link' => '')); + $category = $this->category->getParent(); + + while ((!isset($menu->query['option']) || $menu->query['option'] !== 'com_contact' || $menu->query['view'] === 'contact' + || $id != $category->id) && $category->id > 1) + { + $path[] = array('title' => $category->title, 'link' => ContactHelperRoute::getCategoryRoute($category->id)); + $category = $category->getParent(); + } + + $path = array_reverse($path); + + foreach ($path as $item) + { + $this->pathway->addItem($item['title'], $item['link']); + } + } + + parent::addFeed(); + } +} diff --git a/Sites/pages/components/com_contact/views/contact/tmpl/default.php b/Sites/pages/components/com_contact/views/contact/tmpl/default.php new file mode 100644 index 00000000..e1a0a5ef --- /dev/null +++ b/Sites/pages/components/com_contact/views/contact/tmpl/default.php @@ -0,0 +1,270 @@ +item->params; +?> + +
          + get('show_page_heading')) : ?> +

          + escape($tparams->get('page_heading')); ?> +

          + + + contact->name && $tparams->get('show_name')) : ?> + + + + get('show_contact_category'); ?> + + +

          + contact->category_title; ?> +

          + + contact->catid); ?> +

          + + escape($this->contact->category_title); ?> + +

          + + + item->event->afterDisplayTitle; ?> + + get('show_contact_list') && count($this->contacts) > 1) : ?> +
          + + contacts, 'select_contact', 'class="inputbox" onchange="document.location.href = this.value"', 'link', 'name', $this->contact->link); ?> +
          + + + get('show_tags', 1) && !empty($this->item->tags->itemTags)) : ?> + item->tagLayout = new JLayoutFile('joomla.content.tags'); ?> + item->tagLayout->render($this->item->tags->itemTags); ?> + + + item->event->beforeDisplayContent; ?> + + get('presentation_style'); ?> + + + + params->get('show_info', 1)) : ?> + + 'basic-details')); ?> + + + + 'basic-details')); ?> + + + + ' . JText::_('COM_CONTACT_DETAILS') . ''; ?> + + + contact->image && $tparams->get('show_image')) : ?> +
          + contact->image, htmlspecialchars($this->contact->name, ENT_QUOTES, 'UTF-8'), array('itemprop' => 'image')); ?> +
          + + + contact->con_position && $tparams->get('show_position')) : ?> +
          +
          :
          +
          + contact->con_position; ?> +
          +
          + + + loadTemplate('address'); ?> + + get('allow_vcard')) : ?> + + + + + + + + + + + + + get('show_email_form') && ($this->contact->email_to || $this->contact->user_id)) : ?> + + 'display-form')); + $accordionStarted = true; + } + ?> + + + 'display-form')); + $tabSetStarted = true; + } + ?> + + + ' . JText::_('COM_CONTACT_EMAIL_FORM') . ''; ?> + + + loadTemplate('form'); ?> + + + + + + + + + get('show_links')) : ?> + + + 'display-links')); ?> + + + + + 'display-links')); ?> + + + + loadTemplate('links'); ?> + + + get('show_articles') && $this->contact->user_id && $this->contact->articles) : ?> + + 'display-articles')); + $accordionStarted = true; + } + ?> + + + 'display-articles')); + $tabSetStarted = true; + } + ?> + + + ' . JText::_('JGLOBAL_ARTICLES') . ''; ?> + + + loadTemplate('articles'); ?> + + + + + + + + + get('show_profile') && $this->contact->user_id && JPluginHelper::isEnabled('user', 'profile')) : ?> + + 'display-profile')); + $accordionStarted = true; + } + ?> + + + 'display-profile')); + $tabSetStarted = true; + } + ?> + + + ' . JText::_('COM_CONTACT_PROFILE') . ''; ?> + + + loadTemplate('profile'); ?> + + + + + + + + + get('show_user_custom_fields') && $this->contactUser) : ?> + loadTemplate('user_custom_fields'); ?> + + + contact->misc && $tparams->get('show_misc')) : ?> + + 'display-misc')); + $accordionStarted = true; + } + ?> + + + 'display-misc')); + $tabSetStarted = true; + } + ?> + + + ' . JText::_('COM_CONTACT_OTHER_INFORMATION') . ''; ?> + + +
          +
          +
          + + get('marker_misc'); ?> + +
          +
          + + contact->misc; ?> + +
          +
          +
          + + + + + + + + + + + + + + + item->event->afterDisplayContent; ?> +
          diff --git a/Sites/pages/components/com_contact/views/contact/tmpl/default.xml b/Sites/pages/components/com_contact/views/contact/tmpl/default.xml new file mode 100644 index 00000000..fef91cd7 --- /dev/null +++ b/Sites/pages/components/com_contact/views/contact/tmpl/default.xml @@ -0,0 +1,486 @@ + + + + + + + + + + + +
          + +
          +
          + + + + + +
          + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + +
          + + + + + + + + + + + + + + + + + + + + + + +
          +
          +
          diff --git a/Sites/pages/components/com_contact/views/contact/tmpl/default_address.php b/Sites/pages/components/com_contact/views/contact/tmpl/default_address.php new file mode 100644 index 00000000..31ca92f2 --- /dev/null +++ b/Sites/pages/components/com_contact/views/contact/tmpl/default_address.php @@ -0,0 +1,130 @@ + +
          + params->get('address_check') > 0) && + ($this->contact->address || $this->contact->suburb || $this->contact->state || $this->contact->country || $this->contact->postcode)) : ?> +
          + + params->get('marker_address'); ?> + +
          + + contact->address && $this->params->get('show_street_address')) : ?> +
          + + contact->address); ?> +
          +
          +
          + + + contact->suburb && $this->params->get('show_suburb')) : ?> +
          + + contact->suburb; ?> +
          +
          +
          + + contact->state && $this->params->get('show_state')) : ?> +
          + + contact->state; ?> +
          +
          +
          + + contact->postcode && $this->params->get('show_postcode')) : ?> +
          + + contact->postcode; ?> +
          +
          +
          + + contact->country && $this->params->get('show_country')) : ?> +
          + + contact->country; ?> +
          +
          +
          + + + +contact->email_to && $this->params->get('show_email')) : ?> +
          + + params->get('marker_email')); ?> + +
          +
          + + contact->email_to; ?> + +
          + + +contact->telephone && $this->params->get('show_telephone')) : ?> +
          + + params->get('marker_telephone'); ?> + +
          +
          + + contact->telephone; ?> + +
          + +contact->fax && $this->params->get('show_fax')) : ?> +
          + + params->get('marker_fax'); ?> + +
          +
          + + contact->fax; ?> + +
          + +contact->mobile && $this->params->get('show_mobile')) : ?> +
          + + params->get('marker_mobile'); ?> + +
          +
          + + contact->mobile; ?> + +
          + +contact->webpage && $this->params->get('show_webpage')) : ?> +
          + + +
          +
          + + + +
          + +
          diff --git a/Sites/pages/components/com_contact/views/contact/tmpl/default_articles.php b/Sites/pages/components/com_contact/views/contact/tmpl/default_articles.php new file mode 100644 index 00000000..17f01ae7 --- /dev/null +++ b/Sites/pages/components/com_contact/views/contact/tmpl/default_articles.php @@ -0,0 +1,25 @@ + +params->get('show_articles')) : ?> +
          + +
          + diff --git a/Sites/pages/components/com_contact/views/contact/tmpl/default_form.php b/Sites/pages/components/com_contact/views/contact/tmpl/default_form.php new file mode 100644 index 00000000..9d35ca07 --- /dev/null +++ b/Sites/pages/components/com_contact/views/contact/tmpl/default_form.php @@ -0,0 +1,45 @@ + +
          +
          + form->getFieldsets() as $fieldset) : ?> + name === 'captcha' && !$this->captchaEnabled) : ?> + + + form->getFieldset($fieldset->name); ?> + +
          + label) && ($legend = trim(JText::_($fieldset->label))) !== '') : ?> + + + + renderField(); ?> + +
          + + +
          +
          + + + + + + +
          +
          +
          +
          diff --git a/Sites/pages/components/com_contact/views/contact/tmpl/default_links.php b/Sites/pages/components/com_contact/views/contact/tmpl/default_links.php new file mode 100644 index 00000000..49fe4470 --- /dev/null +++ b/Sites/pages/components/com_contact/views/contact/tmpl/default_links.php @@ -0,0 +1,55 @@ + + +params->get('presentation_style') === 'sliders') : ?> + + +params->get('presentation_style') === 'tabs') : ?> + + +params->get('presentation_style') === 'plain') : ?> + ' . JText::_('COM_CONTACT_LINKS') . ''; ?> + + + + +params->get('presentation_style') === 'sliders') : ?> + + +params->get('presentation_style') === 'tabs') : ?> + + diff --git a/Sites/pages/components/com_contact/views/contact/tmpl/default_profile.php b/Sites/pages/components/com_contact/views/contact/tmpl/default_profile.php new file mode 100644 index 00000000..f6994f77 --- /dev/null +++ b/Sites/pages/components/com_contact/views/contact/tmpl/default_profile.php @@ -0,0 +1,44 @@ + +item->profile->getFieldset('profile'); ?> +
          +
          + value) : + echo '
          ' . $profile->label . '
          '; + $profile->text = htmlspecialchars($profile->value, ENT_COMPAT, 'UTF-8'); + + switch ($profile->id) : + case 'profile_website': + $v_http = substr($profile->value, 0, 4); + + if ($v_http === 'http') : + echo '
          ' . JStringPunycode::urlToUTF8($profile->text) . '
          '; + else : + echo '
          ' . JStringPunycode::urlToUTF8($profile->text) . '
          '; + endif; + break; + + case 'profile_dob': + echo '
          ' . JHtml::_('date', $profile->text, JText::_('DATE_FORMAT_LC4'), false) . '
          '; + break; + + default: + echo '
          ' . $profile->text . '
          '; + break; + endswitch; + endif; + endforeach; ?> +
          +
          + diff --git a/Sites/pages/components/com_contact/views/contact/tmpl/default_user_custom_fields.php b/Sites/pages/components/com_contact/views/contact/tmpl/default_user_custom_fields.php new file mode 100644 index 00000000..0654a1ba --- /dev/null +++ b/Sites/pages/components/com_contact/views/contact/tmpl/default_user_custom_fields.php @@ -0,0 +1,64 @@ +item->params; +$presentation_style = $params->get('presentation_style'); + +$displayGroups = $params->get('show_user_custom_fields'); +$userFieldGroups = array(); +?> + +contactUser) : ?> + + + +contactUser->jcfields as $field) : ?> + group_id || !in_array($field->group_id, $displayGroups))) : ?> + + + group_title, $userFieldGroups)) : ?> + group_title] = array(); ?> + + group_title][] = $field; ?> + + + $fields) : ?> + + + + + + + ' . ($groupTitle ?: JText::_('COM_CONTACT_USER_FIELDS')) . ''; ?> + + +
          +
          + + value) : ?> + + + + params->get('showlabel')) : ?> + ' . JText::_($field->label) . ''; ?> + + + ' . $field->value . ''; ?> + +
          +
          + + + + + + + diff --git a/Sites/pages/components/com_contact/views/contact/view.html.php b/Sites/pages/components/com_contact/views/contact/view.html.php new file mode 100644 index 00000000..1abc6529 --- /dev/null +++ b/Sites/pages/components/com_contact/views/contact/view.html.php @@ -0,0 +1,500 @@ +get('Item'); + $state = $this->get('State'); + $contacts = array(); + + // Get submitted values + $data = $app->getUserState('com_contact.contact.data', array()); + + // Add catid for selecting custom fields + $data['catid'] = $item->catid; + + $app->setUserState('com_contact.contact.data', $data); + + $this->form = $this->get('Form'); + + $params = $state->get('params'); + + $temp = clone $params; + + $active = $app->getMenu()->getActive(); + + if ($active) + { + // If the current view is the active item and a contact view for this contact, then the menu item params take priority + if (strpos($active->link, 'view=contact') && strpos($active->link, '&id=' . (int) $item->id)) + { + // $item->params are the contact params, $temp are the menu item params + // Merge so that the menu item params take priority + $item->params->merge($temp); + } + else + { + // Current view is not a single contact, so the contact params take priority here + // Merge the menu item params with the contact params so that the contact params take priority + $temp->merge($item->params); + $item->params = $temp; + } + } + else + { + // Merge so that contact params take priority + $temp->merge($item->params); + $item->params = $temp; + } + + // Collect extra contact information when this information is required + if ($item && $item->params->get('show_contact_list')) + { + // Get Category Model data + $categoryModel = JModelLegacy::getInstance('Category', 'ContactModel', array('ignore_request' => true)); + + $categoryModel->setState('category.id', $item->catid); + $categoryModel->setState('list.ordering', 'a.name'); + $categoryModel->setState('list.direction', 'asc'); + $categoryModel->setState('filter.published', 1); + + $contacts = $categoryModel->getItems(); + } + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + JError::raiseWarning(500, implode("\n", $errors)); + + return false; + } + + // Check if access is not public + $groups = $user->getAuthorisedViewLevels(); + + $return = ''; + + if ((!in_array($item->access, $groups)) || (!in_array($item->category_access, $groups))) + { + $app->enqueueMessage(JText::_('JERROR_ALERTNOAUTHOR'), 'error'); + $app->setHeader('status', 403, true); + + return false; + } + + $options['category_id'] = $item->catid; + $options['order by'] = 'a.default_con DESC, a.ordering ASC'; + + /** + * Handle email cloaking + * + * Keep a copy of the raw email address so it can + * still be accessed in the layout if needed. + */ + $item->email_raw = $item->email_to; + + if ($item->email_to && $item->params->get('show_email')) + { + $item->email_to = JHtml::_('email.cloak', $item->email_to, (bool) $item->params->get('add_mailto_link', true)); + } + + if ($item->params->get('show_street_address') || $item->params->get('show_suburb') || $item->params->get('show_state') + || $item->params->get('show_postcode') || $item->params->get('show_country')) + { + if (!empty($item->address) || !empty($item->suburb) || !empty($item->state) || !empty($item->country) || !empty($item->postcode)) + { + $item->params->set('address_check', 1); + } + } + else + { + $item->params->set('address_check', 0); + } + + // Manage the display mode for contact detail groups + switch ($item->params->get('contact_icons')) + { + case 1 : + // Text + $item->params->set('marker_address', JText::_('COM_CONTACT_ADDRESS') . ': '); + $item->params->set('marker_email', JText::_('JGLOBAL_EMAIL') . ': '); + $item->params->set('marker_telephone', JText::_('COM_CONTACT_TELEPHONE') . ': '); + $item->params->set('marker_fax', JText::_('COM_CONTACT_FAX') . ': '); + $item->params->set('marker_mobile', JText::_('COM_CONTACT_MOBILE') . ': '); + $item->params->set('marker_misc', JText::_('COM_CONTACT_OTHER_INFORMATION') . ': '); + $item->params->set('marker_class', 'jicons-text'); + break; + + case 2 : + // None + $item->params->set('marker_address', ''); + $item->params->set('marker_email', ''); + $item->params->set('marker_telephone', ''); + $item->params->set('marker_mobile', ''); + $item->params->set('marker_fax', ''); + $item->params->set('marker_misc', ''); + $item->params->set('marker_class', 'jicons-none'); + break; + + default : + if ($item->params->get('icon_address')) + { + $image1 = JHtml::_('image', $item->params->get('icon_address', 'con_address.png'), JText::_('COM_CONTACT_ADDRESS') . ': ', null, false); + } + else + { + $image1 = JHtml::_( + 'image', 'contacts/' . $item->params->get('icon_address', 'con_address.png'), JText::_('COM_CONTACT_ADDRESS') . ': ', null, true + ); + } + + if ($item->params->get('icon_email')) + { + $image2 = JHtml::_('image', $item->params->get('icon_email', 'emailButton.png'), JText::_('JGLOBAL_EMAIL') . ': ', null, false); + } + else + { + $image2 = JHtml::_('image', 'contacts/' . $item->params->get('icon_email', 'emailButton.png'), JText::_('JGLOBAL_EMAIL') . ': ', null, true); + } + + if ($item->params->get('icon_telephone')) + { + $image3 = JHtml::_('image', $item->params->get('icon_telephone', 'con_tel.png'), JText::_('COM_CONTACT_TELEPHONE') . ': ', null, false); + } + else + { + $image3 = JHtml::_( + 'image', 'contacts/' . $item->params->get('icon_telephone', 'con_tel.png'), JText::_('COM_CONTACT_TELEPHONE') . ': ', null, true + ); + } + + if ($item->params->get('icon_fax')) + { + $image4 = JHtml::_('image', $item->params->get('icon_fax', 'con_fax.png'), JText::_('COM_CONTACT_FAX') . ': ', null, false); + } + else + { + $image4 = JHtml::_('image', 'contacts/' . $item->params->get('icon_fax', 'con_fax.png'), JText::_('COM_CONTACT_FAX') . ': ', null, true); + } + + if ($item->params->get('icon_misc')) + { + $image5 = JHtml::_('image', $item->params->get('icon_misc', 'con_info.png'), JText::_('COM_CONTACT_OTHER_INFORMATION') . ': ', null, false); + } + else + { + $image5 = JHtml::_( + 'image', + 'contacts/' . $item->params->get('icon_misc', 'con_info.png'), + JText::_('COM_CONTACT_OTHER_INFORMATION') . ': ', null, true + ); + } + + if ($item->params->get('icon_mobile')) + { + $image6 = JHtml::_('image', $item->params->get('icon_mobile', 'con_mobile.png'), JText::_('COM_CONTACT_MOBILE') . ': ', null, false); + } + else + { + $image6 = JHtml::_( + 'image', 'contacts/' . $item->params->get('icon_mobile', 'con_mobile.png'), JText::_('COM_CONTACT_MOBILE') . ': ', null, true + ); + } + + $item->params->set('marker_address', $image1); + $item->params->set('marker_email', $image2); + $item->params->set('marker_telephone', $image3); + $item->params->set('marker_fax', $image4); + $item->params->set('marker_misc', $image5); + $item->params->set('marker_mobile', $image6); + $item->params->set('marker_class', 'jicons-icons'); + break; + } + + // Add links to contacts + if ($item->params->get('show_contact_list') && count($contacts) > 1) + { + foreach ($contacts as &$contact) + { + $contact->link = JRoute::_(ContactHelperRoute::getContactRoute($contact->slug, $contact->catid), false); + } + + $item->link = JRoute::_(ContactHelperRoute::getContactRoute($item->slug, $item->catid), false); + } + + // Process the content plugins + JPluginHelper::importPlugin('content'); + + $dispatcher = JEventDispatcher::getInstance(); + + $offset = $state->get('list.offset'); + + // Fix for where some plugins require a text attribute + $item->text = null; + + if (!empty($item->misc)) + { + $item->text = $item->misc; + } + + $dispatcher->trigger('onContentPrepare', array('com_contact.contact', &$item, &$item->params, $offset)); + + // Store the events for later + $item->event = new stdClass; + + $results = $dispatcher->trigger('onContentAfterTitle', array('com_contact.contact', &$item, &$item->params, $offset)); + $item->event->afterDisplayTitle = trim(implode("\n", $results)); + + $results = $dispatcher->trigger('onContentBeforeDisplay', array('com_contact.contact', &$item, &$item->params, $offset)); + $item->event->beforeDisplayContent = trim(implode("\n", $results)); + + $results = $dispatcher->trigger('onContentAfterDisplay', array('com_contact.contact', &$item, &$item->params, $offset)); + $item->event->afterDisplayContent = trim(implode("\n", $results)); + + if (!empty($item->text)) + { + $item->misc = $item->text; + } + + $contactUser = null; + + if ($item->params->get('show_user_custom_fields') && $item->user_id && $contactUser = JFactory::getUser($item->user_id)) + { + $contactUser->text = ''; + + JEventDispatcher::getInstance()->trigger('onContentPrepare', array ('com_users.user', &$contactUser, &$item->params, 0)); + + if (!isset($contactUser->jcfields)) + { + $contactUser->jcfields = array(); + } + } + + // Escape strings for HTML output + $this->pageclass_sfx = htmlspecialchars($item->params->get('pageclass_sfx')); + + $this->contact = &$item; + $this->params = &$item->params; + $this->return = &$return; + $this->state = &$state; + $this->item = &$item; + $this->user = &$user; + $this->contacts = &$contacts; + $this->contactUser = $contactUser; + + $item->tags = new JHelperTags; + $item->tags->getItemTags('com_contact.contact', $this->item->id); + + // Override the layout only if this is not the active menu item + // If it is the active menu item, then the view and item id will match + if ((!$active) || ((strpos($active->link, 'view=contact') === false) || (strpos($active->link, '&id=' . (string) $this->item->id) === false))) + { + if (($layout = $item->params->get('contact_layout'))) + { + $this->setLayout($layout); + } + } + elseif (isset($active->query['layout'])) + { + // We need to set the layout in case this is an alternative menu item (with an alternative layout) + $this->setLayout($active->query['layout']); + } + + $model = $this->getModel(); + $model->hit(); + + $captchaSet = $item->params->get('captcha', JFactory::getApplication()->get('captcha', '0')); + + foreach (JPluginHelper::getPlugin('captcha') as $plugin) + { + if ($captchaSet === $plugin->name) + { + $this->captchaEnabled = true; + break; + } + } + + $this->_prepareDocument(); + + return parent::display($tpl); + } + + /** + * Prepares the document + * + * @return void + * + * @since 1.6 + */ + protected function _prepareDocument() + { + $app = JFactory::getApplication(); + $menus = $app->getMenu(); + $pathway = $app->getPathway(); + $title = null; + + // Because the application sets a default page title, + // we need to get it from the menu item itself + $menu = $menus->getActive(); + + if ($menu) + { + $this->params->def('page_heading', $this->params->get('page_title', $menu->title)); + } + else + { + $this->params->def('page_heading', JText::_('COM_CONTACT_DEFAULT_PAGE_TITLE')); + } + + $title = $this->params->get('page_title', ''); + + $id = (int) @$menu->query['id']; + + // If the menu item does not concern this contact + if ($menu && (!isset($menu->query['option']) || $menu->query['option'] !== 'com_contact' || $menu->query['view'] !== 'contact' + || $id != $this->item->id)) + { + // If this is not a single contact menu item, set the page title to the contact title + if ($this->item->name) + { + $title = $this->item->name; + } + + $path = array(array('title' => $this->contact->name, 'link' => '')); + $category = JCategories::getInstance('Contact')->get($this->contact->catid); + + while ($category && (!isset($menu->query['option']) || $menu->query['option'] !== 'com_contact' || $menu->query['view'] === 'contact' + || $id != $category->id) && $category->id > 1) + { + $path[] = array('title' => $category->title, 'link' => ContactHelperRoute::getCategoryRoute($this->contact->catid)); + $category = $category->getParent(); + } + + $path = array_reverse($path); + + foreach ($path as $item) + { + $pathway->addItem($item['title'], $item['link']); + } + } + + if (empty($title)) + { + $title = $app->get('sitename'); + } + elseif ($app->get('sitename_pagetitles', 0) == 1) + { + $title = JText::sprintf('JPAGETITLE', $app->get('sitename'), $title); + } + elseif ($app->get('sitename_pagetitles', 0) == 2) + { + $title = JText::sprintf('JPAGETITLE', $title, $app->get('sitename')); + } + + if (empty($title)) + { + $title = $this->item->name; + } + + $this->document->setTitle($title); + + if ($this->item->metadesc) + { + $this->document->setDescription($this->item->metadesc); + } + elseif ($this->params->get('menu-meta_description')) + { + $this->document->setDescription($this->params->get('menu-meta_description')); + } + + if ($this->item->metakey) + { + $this->document->setMetadata('keywords', $this->item->metakey); + } + elseif ($this->params->get('menu-meta_keywords')) + { + $this->document->setMetadata('keywords', $this->params->get('menu-meta_keywords')); + } + + if ($this->params->get('robots')) + { + $this->document->setMetadata('robots', $this->params->get('robots')); + } + + $mdata = $this->item->metadata->toArray(); + + foreach ($mdata as $k => $v) + { + if ($v) + { + $this->document->setMetadata($k, $v); + } + } + } +} diff --git a/Sites/pages/components/com_contact/views/contact/view.vcf.php b/Sites/pages/components/com_contact/views/contact/view.vcf.php new file mode 100644 index 00000000..8a179487 --- /dev/null +++ b/Sites/pages/components/com_contact/views/contact/view.vcf.php @@ -0,0 +1,113 @@ +get('Item'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + JError::raiseWarning(500, implode("\n", $errors)); + + return false; + } + + JFactory::getDocument()->setMimeEncoding('text/directory', true); + + // Compute lastname, firstname and middlename + $item->name = trim($item->name); + + // "Lastname, Firstname Midlename" format support + // e.g. "de Gaulle, Charles" + $namearray = explode(',', $item->name); + + if (count($namearray) > 1) + { + $lastname = $namearray[0]; + $card_name = $lastname; + $name_and_midname = trim($namearray[1]); + + $firstname = ''; + + if (!empty($name_and_midname)) + { + $namearray = explode(' ', $name_and_midname); + + $firstname = $namearray[0]; + $middlename = (count($namearray) > 1) ? $namearray[1] : ''; + $card_name = $firstname . ' ' . ($middlename ? $middlename . ' ' : '') . $card_name; + } + } + // "Firstname Middlename Lastname" format support + else + { + $namearray = explode(' ', $item->name); + + $middlename = (count($namearray) > 2) ? $namearray[1] : ''; + $firstname = array_shift($namearray); + $lastname = count($namearray) ? end($namearray) : ''; + $card_name = $firstname . ($middlename ? ' ' . $middlename : '') . ($lastname ? ' ' . $lastname : ''); + } + + $rev = date('c', strtotime($item->modified)); + + JFactory::getApplication()->setHeader('Content-disposition', 'attachment; filename="' . $card_name . '.vcf"', true); + + $vcard = array(); + $vcard[] .= 'BEGIN:VCARD'; + $vcard[] .= 'VERSION:3.0'; + $vcard[] = 'N:' . $lastname . ';' . $firstname . ';' . $middlename; + $vcard[] = 'FN:' . $item->name; + $vcard[] = 'TITLE:' . $item->con_position; + $vcard[] = 'TEL;TYPE=WORK,VOICE:' . $item->telephone; + $vcard[] = 'TEL;TYPE=WORK,FAX:' . $item->fax; + $vcard[] = 'TEL;TYPE=WORK,MOBILE:' . $item->mobile; + $vcard[] = 'ADR;TYPE=WORK:;;' . $item->address . ';' . $item->suburb . ';' . $item->state . ';' . $item->postcode . ';' . $item->country; + $vcard[] = 'LABEL;TYPE=WORK:' . $item->address . "\n" . $item->suburb . "\n" . $item->state . "\n" . $item->postcode . "\n" . $item->country; + $vcard[] = 'EMAIL;TYPE=PREF,INTERNET:' . $item->email_to; + $vcard[] = 'URL:' . $item->webpage; + $vcard[] = 'REV:' . $rev . 'Z'; + $vcard[] = 'END:VCARD'; + + echo implode("\n", $vcard); + } +} diff --git a/Sites/pages/components/com_contact/views/featured/tmpl/default.php b/Sites/pages/components/com_contact/views/featured/tmpl/default.php new file mode 100644 index 00000000..9196cf09 --- /dev/null +++ b/Sites/pages/components/com_contact/views/featured/tmpl/default.php @@ -0,0 +1,38 @@ + +
          +params->get('show_page_heading') != 0 ) : ?> +

          + escape($this->params->get('page_heading')); ?> +

          + + +loadTemplate('items'); ?> + +params->def('show_pagination', 2) == 1 || ($this->params->get('show_pagination') == 2 && $this->pagination->pagesTotal > 1)) : ?> + + +
          diff --git a/Sites/pages/components/com_contact/views/featured/tmpl/default.xml b/Sites/pages/components/com_contact/views/featured/tmpl/default.xml new file mode 100644 index 00000000..242a2bce --- /dev/null +++ b/Sites/pages/components/com_contact/views/featured/tmpl/default.xml @@ -0,0 +1,552 @@ + + + + + + + + + + + + + + + +
          + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + +
          + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + +
          + + + + + + + + + + + + + + + + + + + + + + +
          + +
          +
          diff --git a/Sites/pages/components/com_contact/views/featured/tmpl/default_items.php b/Sites/pages/components/com_contact/views/featured/tmpl/default_items.php new file mode 100644 index 00000000..2a688cef --- /dev/null +++ b/Sites/pages/components/com_contact/views/featured/tmpl/default_items.php @@ -0,0 +1,164 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); + +?> + +items)) : ?> +

          + + +
          +
          + + params->get('show_pagination_limit')) : ?> +
          +   + pagination->getLimitBox(); ?> +
          + + + +
          + + + params->get('show_headings')) : ?> + + + + params->get('show_position_headings')) : ?> + + + params->get('show_email_headings')) : ?> + + + params->get('show_telephone_headings')) : ?> + + + + params->get('show_mobile_headings')) : ?> + + + + params->get('show_fax_headings')) : ?> + + + + params->get('show_suburb_headings')) : ?> + + + + params->get('show_state_headings')) : ?> + + + + params->get('show_country_headings')) : ?> + + + + + + + + + items as $i => $item) : ?> + + + + + + params->get('show_position_headings')) : ?> + + + + params->get('show_email_headings')) : ?> + + + + params->get('show_telephone_headings')) : ?> + + + + params->get('show_mobile_headings')) : ?> + + + + params->get('show_fax_headings')) : ?> + + + + params->get('show_suburb_headings')) : ?> + + + + params->get('show_state_headings')) : ?> + + + + params->get('show_country_headings')) : ?> + + + + + + +
          + + + + + + + + + + + + + + + + + +
          + + + items[$i]->published == 0) : ?> + + + + + con_position; ?> + + telephone; ?> + + mobile; ?> + + fax; ?> + + suburb; ?> + + state; ?> + + country; ?> +
          + +
          + diff --git a/Sites/pages/components/com_contact/views/featured/view.html.php b/Sites/pages/components/com_contact/views/featured/view.html.php new file mode 100644 index 00000000..1aba7a4a --- /dev/null +++ b/Sites/pages/components/com_contact/views/featured/view.html.php @@ -0,0 +1,197 @@ +getParams(); + + // Get some data from the models + $state = $this->get('State'); + $items = $this->get('Items'); + $category = $this->get('Category'); + $children = $this->get('Children'); + $parent = $this->get('Parent'); + $pagination = $this->get('Pagination'); + + // Flag indicates to not add limitstart=0 to URL + $pagination->hideEmptyLimitstart = true; + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + JError::raiseWarning(500, implode("\n", $errors)); + + return false; + } + + // Prepare the data. + // Compute the contact slug. + for ($i = 0, $n = count($items); $i < $n; $i++) + { + $item = &$items[$i]; + $item->slug = $item->alias ? ($item->id . ':' . $item->alias) : $item->id; + $temp = $item->params; + $item->params = clone $params; + $item->params->merge($temp); + + if ($item->params->get('show_email', 0) == 1) + { + $item->email_to = trim($item->email_to); + + if (!empty($item->email_to) && JMailHelper::isEmailAddress($item->email_to)) + { + $item->email_to = JHtml::_('email.cloak', $item->email_to); + } + else + { + $item->email_to = ''; + } + } + } + + // Escape strings for HTML output + $this->pageclass_sfx = htmlspecialchars($params->get('pageclass_sfx'), ENT_COMPAT, 'UTF-8'); + + $maxLevel = $params->get('maxLevel', -1); + $this->maxLevel = &$maxLevel; + $this->state = &$state; + $this->items = &$items; + $this->category = &$category; + $this->children = &$children; + $this->params = &$params; + $this->parent = &$parent; + $this->pagination = &$pagination; + + $this->_prepareDocument(); + + return parent::display($tpl); + } + + /** + * Prepares the document + * + * @return void + * + * @since 1.6 + */ + protected function _prepareDocument() + { + $app = JFactory::getApplication(); + $menus = $app->getMenu(); + $title = null; + + // Because the application sets a default page title, + // we need to get it from the menu item itself + $menu = $menus->getActive(); + + if ($menu) + { + $this->params->def('page_heading', $this->params->get('page_title', $menu->title)); + } + else + { + $this->params->def('page_heading', JText::_('COM_CONTACT_DEFAULT_PAGE_TITLE')); + } + + $title = $this->params->get('page_title', ''); + + if (empty($title)) + { + $title = $app->get('sitename'); + } + elseif ($app->get('sitename_pagetitles', 0) == 1) + { + $title = JText::sprintf('JPAGETITLE', $app->get('sitename'), $title); + } + elseif ($app->get('sitename_pagetitles', 0) == 2) + { + $title = JText::sprintf('JPAGETITLE', $title, $app->get('sitename')); + } + + $this->document->setTitle($title); + + if ($this->params->get('menu-meta_description')) + { + $this->document->setDescription($this->params->get('menu-meta_description')); + } + + if ($this->params->get('menu-meta_keywords')) + { + $this->document->setMetadata('keywords', $this->params->get('menu-meta_keywords')); + } + + if ($this->params->get('robots')) + { + $this->document->setMetadata('robots', $this->params->get('robots')); + } + } +} diff --git a/Sites/pages/components/com_content/content.php b/Sites/pages/components/com_content/content.php new file mode 100644 index 00000000..7b2ed2da --- /dev/null +++ b/Sites/pages/components/com_content/content.php @@ -0,0 +1,44 @@ +input; +$user = JFactory::getUser(); + +$checkCreateEdit = ($input->get('view') === 'articles' && $input->get('layout') === 'modal') + || ($input->get('view') === 'article' && $input->get('layout') === 'pagebreak'); + +if ($checkCreateEdit) +{ + // Can create in any category (component permission) or at least in one category + $canCreateRecords = $user->authorise('core.create', 'com_content') + || count($user->getAuthorisedCategories('com_content', 'core.create')) > 0; + + // Instead of checking edit on all records, we can use **same** check as the form editing view + $values = (array) JFactory::getApplication()->getUserState('com_content.edit.article.id'); + $isEditingRecords = count($values); + + $hasAccess = $canCreateRecords || $isEditingRecords; + + if (!$hasAccess) + { + JFactory::getApplication()->enqueueMessage(JText::_('JERROR_ALERTNOAUTHOR'), 'warning'); + + return; + } +} + +$controller = JControllerLegacy::getInstance('Content'); +$controller->execute(JFactory::getApplication()->input->get('task')); +$controller->redirect(); diff --git a/Sites/pages/components/com_content/controller.php b/Sites/pages/components/com_content/controller.php new file mode 100644 index 00000000..8d484a78 --- /dev/null +++ b/Sites/pages/components/com_content/controller.php @@ -0,0 +1,122 @@ +input = JFactory::getApplication()->input; + + // Article frontpage Editor pagebreak proxying: + if ($this->input->get('view') === 'article' && $this->input->get('layout') === 'pagebreak') + { + $config['base_path'] = JPATH_COMPONENT_ADMINISTRATOR; + } + // Article frontpage Editor article proxying: + elseif ($this->input->get('view') === 'articles' && $this->input->get('layout') === 'modal') + { + JHtml::_('stylesheet', 'system/adminlist.css', array('version' => 'auto', 'relative' => true)); + $config['base_path'] = JPATH_COMPONENT_ADMINISTRATOR; + } + + parent::__construct($config); + } + + /** + * Method to display a view. + * + * @param boolean $cachable If true, the view output will be cached. + * @param boolean $urlparams An array of safe URL parameters and their variable types, for valid values see {@link JFilterInput::clean()}. + * + * @return JController This object to support chaining. + * + * @since 1.5 + */ + public function display($cachable = false, $urlparams = false) + { + $cachable = true; + + /** + * Set the default view name and format from the Request. + * Note we are using a_id to avoid collisions with the router and the return page. + * Frontend is a bit messier than the backend. + */ + $id = $this->input->getInt('a_id'); + $vName = $this->input->getCmd('view', 'categories'); + $this->input->set('view', $vName); + + $user = JFactory::getUser(); + + if ($user->get('id') + || ($this->input->getMethod() === 'POST' + && (($vName === 'category' && $this->input->get('layout') !== 'blog') || $vName === 'archive' ))) + { + $cachable = false; + } + + $safeurlparams = array( + 'catid' => 'INT', + 'id' => 'INT', + 'cid' => 'ARRAY', + 'year' => 'INT', + 'month' => 'INT', + 'limit' => 'UINT', + 'limitstart' => 'UINT', + 'showall' => 'INT', + 'return' => 'BASE64', + 'filter' => 'STRING', + 'filter_order' => 'CMD', + 'filter_order_Dir' => 'CMD', + 'filter-search' => 'STRING', + 'print' => 'BOOLEAN', + 'lang' => 'CMD', + 'Itemid' => 'INT'); + + // Check for edit form. + if ($vName === 'form' && !$this->checkEditId('com_content.edit.article', $id)) + { + // Somehow the person just went to the form - we don't allow that. + return JError::raiseError(403, JText::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id)); + } + + if ($vName === 'article') + { + // Get/Create the model + if ($model = $this->getModel($vName)) + { + if (ComponentHelper::getParams('com_content')->get('record_hits', 1) == 1) + { + $model->hit(); + } + } + } + + parent::display($cachable, $safeurlparams); + + return $this; + } +} diff --git a/Sites/pages/components/com_content/controllers/article.php b/Sites/pages/components/com_content/controllers/article.php new file mode 100644 index 00000000..eb7adaf2 --- /dev/null +++ b/Sites/pages/components/com_content/controllers/article.php @@ -0,0 +1,444 @@ +setRedirect($this->getReturnPage()); + + return; + } + + // Redirect to the edit screen. + $this->setRedirect( + JRoute::_( + 'index.php?option=' . $this->option . '&view=' . $this->view_item . '&a_id=0' + . $this->getRedirectToItemAppend(), false + ) + ); + + return true; + } + + /** + * Method override to check if you can add a new record. + * + * @param array $data An array of input data. + * + * @return boolean + * + * @since 1.6 + */ + protected function allowAdd($data = array()) + { + $user = JFactory::getUser(); + $categoryId = ArrayHelper::getValue($data, 'catid', $this->input->getInt('catid'), 'int'); + $allow = null; + + if ($categoryId) + { + // If the category has been passed in the data or URL check it. + $allow = $user->authorise('core.create', 'com_content.category.' . $categoryId); + } + + if ($allow === null) + { + // In the absence of better information, revert to the component permissions. + return parent::allowAdd(); + } + else + { + return $allow; + } + } + + /** + * Method override to check if you can edit an existing record. + * + * @param array $data An array of input data. + * @param string $key The name of the key for the primary key; default is id. + * + * @return boolean + * + * @since 1.6 + */ + protected function allowEdit($data = array(), $key = 'id') + { + $recordId = (int) isset($data[$key]) ? $data[$key] : 0; + $user = JFactory::getUser(); + + // Zero record (id:0), return component edit permission by calling parent controller method + if (!$recordId) + { + return parent::allowEdit($data, $key); + } + + // Check edit on the record asset (explicit or inherited) + if ($user->authorise('core.edit', 'com_content.article.' . $recordId)) + { + return true; + } + + // Check edit own on the record asset (explicit or inherited) + if ($user->authorise('core.edit.own', 'com_content.article.' . $recordId)) + { + // Existing record already has an owner, get it + $record = $this->getModel()->getItem($recordId); + + if (empty($record)) + { + return false; + } + + // Grant if current user is owner of the record + return $user->get('id') == $record->created_by; + } + + return false; + } + + /** + * Method to cancel an edit. + * + * @param string $key The name of the primary key of the URL variable. + * + * @return boolean True if access level checks pass, false otherwise. + * + * @since 1.6 + */ + public function cancel($key = 'a_id') + { + parent::cancel($key); + + $app = JFactory::getApplication(); + + // Load the parameters. + $params = $app->getParams(); + + $customCancelRedir = (bool) $params->get('custom_cancel_redirect'); + + if ($customCancelRedir) + { + $cancelMenuitemId = (int) $params->get('cancel_redirect_menuitem'); + + if ($cancelMenuitemId > 0) + { + $item = $app->getMenu()->getItem($cancelMenuitemId); + $lang = ''; + + if (JLanguageMultilang::isEnabled()) + { + $lang = !is_null($item) && $item->language != '*' ? '&lang=' . $item->language : ''; + } + + // Redirect to the user specified return page. + $redirlink = $item->link . $lang . '&Itemid=' . $cancelMenuitemId; + } + else + { + // Redirect to the same article submission form (clean form). + $redirlink = $app->getMenu()->getActive()->link . '&Itemid=' . $app->getMenu()->getActive()->id; + } + } + else + { + $menuitemId = (int) $params->get('redirect_menuitem'); + $lang = ''; + + if ($menuitemId > 0) + { + $lang = ''; + $item = $app->getMenu()->getItem($menuitemId); + + if (JLanguageMultilang::isEnabled()) + { + $lang = !is_null($item) && $item->language != '*' ? '&lang=' . $item->language : ''; + } + + // Redirect to the general (redirect_menuitem) user specified return page. + $redirlink = $item->link . $lang . '&Itemid=' . $menuitemId; + } + else + { + // Redirect to the return page. + $redirlink = $this->getReturnPage(); + } + } + + $this->setRedirect(JRoute::_($redirlink, false)); + } + + /** + * Method to edit an existing record. + * + * @param string $key The name of the primary key of the URL variable. + * @param string $urlVar The name of the URL variable if different from the primary key + * (sometimes required to avoid router collisions). + * + * @return boolean True if access level check and checkout passes, false otherwise. + * + * @since 1.6 + */ + public function edit($key = null, $urlVar = 'a_id') + { + $result = parent::edit($key, $urlVar); + + if (!$result) + { + $this->setRedirect(JRoute::_($this->getReturnPage(), false)); + } + + return $result; + } + + /** + * Method to get a model object, loading it if required. + * + * @param string $name The model name. Optional. + * @param string $prefix The class prefix. Optional. + * @param array $config Configuration array for model. Optional. + * + * @return object The model. + * + * @since 1.5 + */ + public function getModel($name = 'form', $prefix = '', $config = array('ignore_request' => true)) + { + return parent::getModel($name, $prefix, $config); + } + + /** + * Gets the URL arguments to append to an item redirect. + * + * @param integer $recordId The primary key id for the item. + * @param string $urlVar The name of the URL variable for the id. + * + * @return string The arguments to append to the redirect URL. + * + * @since 1.6 + */ + protected function getRedirectToItemAppend($recordId = null, $urlVar = 'a_id') + { + // Need to override the parent method completely. + $tmpl = $this->input->get('tmpl'); + + $append = ''; + + // Setup redirect info. + if ($tmpl) + { + $append .= '&tmpl=' . $tmpl; + } + + // TODO This is a bandaid, not a long term solution. + /** + * if ($layout) + * { + * $append .= '&layout=' . $layout; + * } + */ + + $append .= '&layout=edit'; + + if ($recordId) + { + $append .= '&' . $urlVar . '=' . $recordId; + } + + $itemId = $this->input->getInt('Itemid'); + $return = $this->getReturnPage(); + $catId = $this->input->getInt('catid'); + + if ($itemId) + { + $append .= '&Itemid=' . $itemId; + } + + if ($catId) + { + $append .= '&catid=' . $catId; + } + + if ($return) + { + $append .= '&return=' . base64_encode($return); + } + + return $append; + } + + /** + * Get the return URL. + * + * If a "return" variable has been passed in the request + * + * @return string The return URL. + * + * @since 1.6 + */ + protected function getReturnPage() + { + $return = $this->input->get('return', null, 'base64'); + + if (empty($return) || !JUri::isInternal(base64_decode($return))) + { + return JUri::base(); + } + else + { + return base64_decode($return); + } + } + + /** + * Method to save a record. + * + * @param string $key The name of the primary key of the URL variable. + * @param string $urlVar The name of the URL variable if different from the primary key (sometimes required to avoid router collisions). + * + * @return boolean True if successful, false otherwise. + * + * @since 1.6 + */ + public function save($key = null, $urlVar = 'a_id') + { + $result = parent::save($key, $urlVar); + $app = JFactory::getApplication(); + $articleId = $app->input->getInt('a_id'); + + // Load the parameters. + $params = $app->getParams(); + $menuitem = (int) $params->get('redirect_menuitem'); + + // Check for redirection after submission when creating a new article only + if ($menuitem > 0 && $articleId == 0) + { + $lang = ''; + + if (JLanguageMultilang::isEnabled()) + { + $item = $app->getMenu()->getItem($menuitem); + $lang = !is_null($item) && $item->language != '*' ? '&lang=' . $item->language : ''; + } + + // If ok, redirect to the return page. + if ($result) + { + $this->setRedirect(JRoute::_('index.php?Itemid=' . $menuitem . $lang, false)); + } + } + else + { + // If ok, redirect to the return page. + if ($result) + { + $this->setRedirect(JRoute::_($this->getReturnPage(), false)); + } + } + + return $result; + } + + /** + * Method to reload a record. + * + * @param string $key The name of the primary key of the URL variable. + * @param string $urlVar The name of the URL variable if different from the primary key (sometimes required to avoid router collisions). + * + * @return void + * + * @since 3.8.0 + */ + public function reload($key = null, $urlVar = 'a_id') + { + return parent::reload($key, $urlVar); + } + + /** + * Method to save a vote. + * + * @return void + * + * @since 1.6 + */ + public function vote() + { + // Check for request forgeries. + $this->checkToken(); + + $user_rating = $this->input->getInt('user_rating', -1); + + if ($user_rating > -1) + { + $url = $this->input->getString('url', ''); + $id = $this->input->getInt('id', 0); + $viewName = $this->input->getString('view', $this->default_view); + $model = $this->getModel($viewName); + + // Don't redirect to an external URL. + if (!JUri::isInternal($url)) + { + $url = JRoute::_('index.php'); + } + + if ($model->storeVote($id, $user_rating)) + { + $this->setRedirect($url, JText::_('COM_CONTENT_ARTICLE_VOTE_SUCCESS')); + } + else + { + $this->setRedirect($url, JText::_('COM_CONTENT_ARTICLE_VOTE_FAILURE')); + } + } + } +} diff --git a/Sites/pages/components/com_content/helpers/association.php b/Sites/pages/components/com_content/helpers/association.php new file mode 100644 index 00000000..24341bee --- /dev/null +++ b/Sites/pages/components/com_content/helpers/association.php @@ -0,0 +1,147 @@ +input; + $view = $view === null ? $jinput->get('view') : $view; + $component = $jinput->getCmd('option'); + $id = empty($id) ? $jinput->getInt('id') : $id; + + if ($layout === null && $jinput->get('view') == $view && $component == 'com_content') + { + $layout = $jinput->get('layout', '', 'string'); + } + + if ($view === 'article') + { + if ($id) + { + $user = JFactory::getUser(); + $groups = implode(',', $user->getAuthorisedViewLevels()); + $db = JFactory::getDbo(); + $advClause = array(); + + // Filter by user groups + $advClause[] = 'c2.access IN (' . $groups . ')'; + + // Filter by current language + $advClause[] = 'c2.language != ' . $db->quote(JFactory::getLanguage()->getTag()); + + if (!$user->authorise('core.edit.state', 'com_content') && !$user->authorise('core.edit', 'com_content')) + { + // Filter by start and end dates. + $nullDate = $db->quote($db->getNullDate()); + $date = JFactory::getDate(); + + $nowDate = $db->quote($date->toSql()); + + $advClause[] = '(c2.publish_up = ' . $nullDate . ' OR c2.publish_up <= ' . $nowDate . ')'; + $advClause[] = '(c2.publish_down = ' . $nullDate . ' OR c2.publish_down >= ' . $nowDate . ')'; + + // Filter by published + $advClause[] = 'c2.state = 1'; + } + + $associations = JLanguageAssociations::getAssociations('com_content', '#__content', 'com_content.item', $id, 'id', 'alias', 'catid', $advClause); + + $return = array(); + + foreach ($associations as $tag => $item) + { + $return[$tag] = ContentHelperRoute::getArticleRoute($item->id, (int) $item->catid, $item->language, $layout); + } + + return $return; + } + } + + if ($view === 'category' || $view === 'categories') + { + return self::getCategoryAssociations($id, 'com_content', $layout); + } + + return array(); + } + + /** + * Method to display in frontend the associations for a given article + * + * @param integer $id Id of the article + * + * @return array An array containing the association URL and the related language object + * + * @since 3.7.0 + */ + public static function displayAssociations($id) + { + $return = array(); + + if ($associations = self::getAssociations($id, 'article')) + { + $levels = JFactory::getUser()->getAuthorisedViewLevels(); + $languages = JLanguageHelper::getLanguages(); + + foreach ($languages as $language) + { + // Do not display language when no association + if (empty($associations[$language->lang_code])) + { + continue; + } + + // Do not display language without frontend UI + if (!array_key_exists($language->lang_code, JLanguageHelper::getInstalledLanguages(0))) + { + continue; + } + + // Do not display language without specific home menu + if (!array_key_exists($language->lang_code, JLanguageMultilang::getSiteHomePages())) + { + continue; + } + + // Do not display language without authorized access level + if (isset($language->access) && $language->access && !in_array($language->access, $levels)) + { + continue; + } + + $return[$language->lang_code] = array('item' => $associations[$language->lang_code], 'language' => $language); + } + } + + return $return; + } +} diff --git a/Sites/pages/components/com_content/helpers/category.php b/Sites/pages/components/com_content/helpers/category.php new file mode 100644 index 00000000..b1f71050 --- /dev/null +++ b/Sites/pages/components/com_content/helpers/category.php @@ -0,0 +1,33 @@ +id; + + $text = JLayoutHelper::render('joomla.content.icons.create', array('params' => $params, 'legacy' => $legacy)); + + // Add the button classes to the attribs array + if (isset($attribs['class'])) + { + $attribs['class'] .= ' btn btn-primary'; + } + else + { + $attribs['class'] = 'btn btn-primary'; + } + + $button = JHtml::_('link', JRoute::_($url), $text, $attribs); + + $output = '' . $button . ''; + + return $output; + } + + /** + * Method to generate a link to the email item page for the given article + * + * @param object $article The article information + * @param Registry $params The item parameters + * @param array $attribs Optional attributes for the link + * @param boolean $legacy True to use legacy images, false to use icomoon based graphic + * + * @return string The HTML markup for the email item link + */ + public static function email($article, $params, $attribs = array(), $legacy = false) + { + JLoader::register('MailtoHelper', JPATH_SITE . '/components/com_mailto/helpers/mailto.php'); + + $uri = JUri::getInstance(); + $base = $uri->toString(array('scheme', 'host', 'port')); + $template = JFactory::getApplication()->getTemplate(); + $link = $base . JRoute::_(ContentHelperRoute::getArticleRoute($article->slug, $article->catid, $article->language), false); + $url = 'index.php?option=com_mailto&tmpl=component&template=' . $template . '&link=' . MailtoHelper::addLink($link); + + $height = JFactory::getApplication()->get('captcha', '0') === '0' ? 450 : 550; + $status = 'width=400,height=' . $height . ',menubar=yes,resizable=yes'; + + $text = JLayoutHelper::render('joomla.content.icons.email', array('params' => $params, 'legacy' => $legacy)); + + $attribs['title'] = JText::_('JGLOBAL_EMAIL_TITLE'); + $attribs['onclick'] = "window.open(this.href,'win2','" . $status . "'); return false;"; + $attribs['rel'] = 'nofollow'; + + return JHtml::_('link', JRoute::_($url), $text, $attribs); + } + + /** + * Display an edit icon for the article. + * + * This icon will not display in a popup window, nor if the article is trashed. + * Edit access checks must be performed in the calling code. + * + * @param object $article The article information + * @param Registry $params The item parameters + * @param array $attribs Optional attributes for the link + * @param boolean $legacy True to use legacy images, false to use icomoon based graphic + * + * @return string The HTML for the article edit icon. + * + * @since 1.6 + */ + public static function edit($article, $params, $attribs = array(), $legacy = false) + { + $user = JFactory::getUser(); + $uri = JUri::getInstance(); + + // Ignore if in a popup window. + if ($params && $params->get('popup')) + { + return; + } + + // Ignore if the state is negative (trashed). + if ($article->state < 0) + { + return; + } + + // Show checked_out icon if the article is checked out by a different user + if (property_exists($article, 'checked_out') + && property_exists($article, 'checked_out_time') + && $article->checked_out > 0 + && $article->checked_out != $user->get('id')) + { + $checkoutUser = JFactory::getUser($article->checked_out); + $date = JHtml::_('date', $article->checked_out_time); + $tooltip = JText::_('JLIB_HTML_CHECKED_OUT') . ' :: ' . JText::sprintf('COM_CONTENT_CHECKED_OUT_BY', $checkoutUser->name) + . '
          ' . $date; + + $text = JLayoutHelper::render('joomla.content.icons.edit_lock', array('tooltip' => $tooltip, 'legacy' => $legacy)); + + $output = JHtml::_('link', '#', $text, $attribs); + + return $output; + } + + $contentUrl = ContentHelperRoute::getArticleRoute($article->slug, $article->catid, $article->language); + $url = $contentUrl . '&task=article.edit&a_id=' . $article->id . '&return=' . base64_encode($uri); + + if ($article->state == 0) + { + $overlib = JText::_('JUNPUBLISHED'); + } + else + { + $overlib = JText::_('JPUBLISHED'); + } + + $date = JHtml::_('date', $article->created); + $author = $article->created_by_alias ?: $article->author; + + $overlib .= '<br />'; + $overlib .= $date; + $overlib .= '<br />'; + $overlib .= JText::sprintf('COM_CONTENT_WRITTEN_BY', htmlspecialchars($author, ENT_COMPAT, 'UTF-8')); + + $text = JLayoutHelper::render('joomla.content.icons.edit', array('article' => $article, 'overlib' => $overlib, 'legacy' => $legacy)); + + $attribs['title'] = JText::_('JGLOBAL_EDIT_TITLE'); + $output = JHtml::_('link', JRoute::_($url), $text, $attribs); + + return $output; + } + + /** + * Method to generate a popup link to print an article + * + * @param object $article The article information + * @param Registry $params The item parameters + * @param array $attribs Optional attributes for the link + * @param boolean $legacy True to use legacy images, false to use icomoon based graphic + * + * @return string The HTML markup for the popup link + */ + public static function print_popup($article, $params, $attribs = array(), $legacy = false) + { + $url = ContentHelperRoute::getArticleRoute($article->slug, $article->catid, $article->language); + $url .= '&tmpl=component&print=1&layout=default'; + + $status = 'status=no,toolbar=no,scrollbars=yes,titlebar=no,menubar=no,resizable=yes,width=640,height=480,directories=no,location=no'; + + $text = JLayoutHelper::render('joomla.content.icons.print_popup', array('params' => $params, 'legacy' => $legacy)); + + $attribs['title'] = JText::sprintf('JGLOBAL_PRINT_TITLE', htmlspecialchars($article->title, ENT_QUOTES, 'UTF-8')); + $attribs['onclick'] = "window.open(this.href,'win2','" . $status . "'); return false;"; + $attribs['rel'] = 'nofollow'; + + return JHtml::_('link', JRoute::_($url), $text, $attribs); + } + + /** + * Method to generate a link to print an article + * + * @param object $article Not used, @deprecated for 4.0 + * @param Registry $params The item parameters + * @param array $attribs Not used, @deprecated for 4.0 + * @param boolean $legacy True to use legacy images, false to use icomoon based graphic + * + * @return string The HTML markup for the popup link + */ + public static function print_screen($article, $params, $attribs = array(), $legacy = false) + { + $text = JLayoutHelper::render('joomla.content.icons.print_screen', array('params' => $params, 'legacy' => $legacy)); + + return '' . $text . ''; + } +} diff --git a/Sites/pages/components/com_content/helpers/legacyrouter.php b/Sites/pages/components/com_content/helpers/legacyrouter.php new file mode 100644 index 00000000..ff95b640 --- /dev/null +++ b/Sites/pages/components/com_content/helpers/legacyrouter.php @@ -0,0 +1,476 @@ +router = $router; + } + + /** + * Preprocess the route for the com_content component + * + * @param array &$query An array of URL arguments + * + * @return void + * + * @since 3.6 + * @deprecated 4.0 + */ + public function preprocess(&$query) + { + } + + /** + * Build the route for the com_content component + * + * @param array &$query An array of URL arguments + * @param array &$segments The URL arguments to use to assemble the subsequent URL. + * + * @return void + * + * @since 3.6 + * @deprecated 4.0 + */ + public function build(&$query, &$segments) + { + // Get a menu item based on Itemid or currently active + $params = JComponentHelper::getParams('com_content'); + $advanced = $params->get('sef_advanced_link', 0); + + // We need a menu item. Either the one specified in the query, or the current active one if none specified + if (empty($query['Itemid'])) + { + $menuItem = $this->router->menu->getActive(); + $menuItemGiven = false; + } + else + { + $menuItem = $this->router->menu->getItem($query['Itemid']); + $menuItemGiven = true; + } + + // Check again + if ($menuItemGiven && isset($menuItem) && $menuItem->component != 'com_content') + { + $menuItemGiven = false; + unset($query['Itemid']); + } + + if (isset($query['view'])) + { + $view = $query['view']; + } + else + { + // We need to have a view in the query or it is an invalid URL + return; + } + + // Are we dealing with an article or category that is attached to a menu item? + if ($menuItem !== null + && isset($menuItem->query['view'], $query['view'], $menuItem->query['id'], $query['id']) + && $menuItem->query['view'] == $query['view'] + && $menuItem->query['id'] == (int) $query['id']) + { + unset($query['view']); + + if (isset($query['catid'])) + { + unset($query['catid']); + } + + if (isset($query['layout'])) + { + unset($query['layout']); + } + + unset($query['id']); + + return; + } + + if ($view == 'category' || $view == 'article') + { + if (!$menuItemGiven) + { + $segments[] = $view; + } + + unset($query['view']); + + if ($view == 'article') + { + if (isset($query['id']) && isset($query['catid']) && $query['catid']) + { + $catid = $query['catid']; + + // Make sure we have the id and the alias + if (strpos($query['id'], ':') === false) + { + $db = JFactory::getDbo(); + $dbQuery = $db->getQuery(true) + ->select('alias') + ->from('#__content') + ->where('id=' . (int) $query['id']); + $db->setQuery($dbQuery); + $alias = $db->loadResult(); + $query['id'] = $query['id'] . ':' . $alias; + } + } + else + { + // We should have these two set for this view. If we don't, it is an error + return; + } + } + else + { + if (isset($query['id'])) + { + $catid = $query['id']; + } + else + { + // We should have id set for this view. If we don't, it is an error + return; + } + } + + if ($menuItemGiven && isset($menuItem->query['id'])) + { + $mCatid = $menuItem->query['id']; + } + else + { + $mCatid = 0; + } + + $categories = JCategories::getInstance('Content'); + $category = $categories->get($catid); + + if (!$category) + { + // We couldn't find the category we were given. Bail. + return; + } + + $path = array_reverse($category->getPath()); + + $array = array(); + + foreach ($path as $id) + { + if ((int) $id == (int) $mCatid) + { + break; + } + + list($tmp, $id) = explode(':', $id, 2); + + $array[] = $id; + } + + $array = array_reverse($array); + + if (!$advanced && count($array)) + { + $array[0] = (int) $catid . ':' . $array[0]; + } + + $segments = array_merge($segments, $array); + + if ($view == 'article') + { + if ($advanced) + { + list($tmp, $id) = explode(':', $query['id'], 2); + } + else + { + $id = $query['id']; + } + + $segments[] = $id; + } + + unset($query['id'], $query['catid']); + } + + if ($view == 'archive') + { + if (!$menuItemGiven) + { + $segments[] = $view; + unset($query['view']); + } + + if (isset($query['year'])) + { + if ($menuItemGiven) + { + $segments[] = $query['year']; + unset($query['year']); + } + } + + if (isset($query['year']) && isset($query['month'])) + { + if ($menuItemGiven) + { + $segments[] = $query['month']; + unset($query['month']); + } + } + } + + if ($view == 'featured') + { + if (!$menuItemGiven) + { + $segments[] = $view; + } + + unset($query['view']); + } + + /* + * If the layout is specified and it is the same as the layout in the menu item, we + * unset it so it doesn't go into the query string. + */ + if (isset($query['layout'])) + { + if ($menuItemGiven && isset($menuItem->query['layout'])) + { + if ($query['layout'] == $menuItem->query['layout']) + { + unset($query['layout']); + } + } + else + { + if ($query['layout'] == 'default') + { + unset($query['layout']); + } + } + } + + $total = count($segments); + + for ($i = 0; $i < $total; $i++) + { + $segments[$i] = str_replace(':', '-', $segments[$i]); + } + } + + /** + * Parse the segments of a URL. + * + * @param array &$segments The segments of the URL to parse. + * @param array &$vars The URL attributes to be used by the application. + * + * @return void + * + * @since 3.6 + * @deprecated 4.0 + */ + public function parse(&$segments, &$vars) + { + $total = count($segments); + + for ($i = 0; $i < $total; $i++) + { + $segments[$i] = preg_replace('/-/', ':', $segments[$i], 1); + } + + // Get the active menu item. + $item = $this->router->menu->getActive(); + $params = JComponentHelper::getParams('com_content'); + $advanced = $params->get('sef_advanced_link', 0); + $db = JFactory::getDbo(); + + // Count route segments + $count = count($segments); + + /* + * Standard routing for articles. If we don't pick up an Itemid then we get the view from the segments + * the first segment is the view and the last segment is the id of the article or category. + */ + if (!isset($item)) + { + $vars['view'] = $segments[0]; + $vars['id'] = $segments[$count - 1]; + + return; + } + + /* + * If there is only one segment, then it points to either an article or a category. + * We test it first to see if it is a category. If the id and alias match a category, + * then we assume it is a category. If they don't we assume it is an article + */ + if ($count == 1) + { + // We check to see if an alias is given. If not, we assume it is an article + if (strpos($segments[0], ':') === false) + { + $vars['view'] = 'article'; + $vars['id'] = (int) $segments[0]; + + return; + } + + list($id, $alias) = explode(':', $segments[0], 2); + + // First we check if it is a category + $category = JCategories::getInstance('Content')->get($id); + + if ($category && $category->alias == $alias) + { + $vars['view'] = 'category'; + $vars['id'] = $id; + + return; + } + else + { + $query = $db->getQuery(true) + ->select($db->quoteName(array('alias', 'catid'))) + ->from($db->quoteName('#__content')) + ->where($db->quoteName('id') . ' = ' . (int) $id); + $db->setQuery($query); + $article = $db->loadObject(); + + if ($article) + { + if ($article->alias == $alias) + { + $vars['view'] = 'article'; + $vars['catid'] = (int) $article->catid; + $vars['id'] = (int) $id; + + return; + } + } + } + } + + /* + * If there was more than one segment, then we can determine where the URL points to + * because the first segment will have the target category id prepended to it. If the + * last segment has a number prepended, it is an article, otherwise, it is a category. + */ + if (!$advanced) + { + $cat_id = (int) $segments[0]; + + $article_id = (int) $segments[$count - 1]; + + if ($article_id > 0) + { + $vars['view'] = 'article'; + $vars['catid'] = $cat_id; + $vars['id'] = $article_id; + } + else + { + $vars['view'] = 'category'; + $vars['id'] = $cat_id; + } + + return; + } + + // We get the category id from the menu item and search from there + $id = $item->query['id']; + $category = JCategories::getInstance('Content')->get($id); + + if (!$category) + { + JError::raiseError(404, JText::_('COM_CONTENT_ERROR_PARENT_CATEGORY_NOT_FOUND')); + + return; + } + + $categories = $category->getChildren(); + $vars['catid'] = $id; + $vars['id'] = $id; + $found = 0; + + foreach ($segments as $segment) + { + $segment = str_replace(':', '-', $segment); + + foreach ($categories as $category) + { + if ($category->alias == $segment) + { + $vars['id'] = $category->id; + $vars['catid'] = $category->id; + $vars['view'] = 'category'; + $categories = $category->getChildren(); + $found = 1; + break; + } + } + + if ($found == 0) + { + if ($advanced) + { + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->select($db->quoteName('id')) + ->from('#__content') + ->where($db->quoteName('catid') . ' = ' . (int) $vars['catid']) + ->where($db->quoteName('alias') . ' = ' . $db->quote($segment)); + $db->setQuery($query); + $cid = $db->loadResult(); + } + else + { + $cid = $segment; + } + + $vars['id'] = $cid; + + if ($item->query['view'] == 'archive' && $count != 1) + { + $vars['year'] = $count >= 2 ? $segments[$count - 2] : null; + $vars['month'] = $segments[$count - 1]; + $vars['view'] = 'archive'; + } + else + { + $vars['view'] = 'article'; + } + } + + $found = 0; + } + } +} diff --git a/Sites/pages/components/com_content/helpers/query.php b/Sites/pages/components/com_content/helpers/query.php new file mode 100644 index 00000000..a9d447fe --- /dev/null +++ b/Sites/pages/components/com_content/helpers/query.php @@ -0,0 +1,320 @@ +getQuery(true)->Rand(); + break; + + case 'vote' : + $orderby = 'a.id DESC '; + + if (JPluginHelper::isEnabled('content', 'vote')) + { + $orderby = 'rating_count DESC '; + } + break; + + case 'rvote' : + $orderby = 'a.id ASC '; + + if (JPluginHelper::isEnabled('content', 'vote')) + { + $orderby = 'rating_count ASC '; + } + break; + + case 'rank' : + $orderby = 'a.id DESC '; + + if (JPluginHelper::isEnabled('content', 'vote')) + { + $orderby = 'rating DESC '; + } + break; + + case 'rrank' : + $orderby = 'a.id ASC '; + + if (JPluginHelper::isEnabled('content', 'vote')) + { + $orderby = 'rating ASC '; + } + break; + + default : + $orderby = 'a.ordering'; + break; + } + + return $orderby; + } + + /** + * Translate an order code to a field for primary category ordering. + * + * @param string $orderDate The ordering code. + * + * @return string The SQL field(s) to order by. + * + * @since 1.6 + */ + public static function getQueryDate($orderDate) + { + $db = JFactory::getDbo(); + + switch ($orderDate) + { + case 'modified' : + $queryDate = ' CASE WHEN a.modified = ' . $db->quote($db->getNullDate()) . ' THEN a.created ELSE a.modified END'; + break; + + // Use created if publish_up is not set + case 'published' : + $queryDate = ' CASE WHEN a.publish_up = ' . $db->quote($db->getNullDate()) . ' THEN a.created ELSE a.publish_up END '; + break; + + case 'unpublished' : + $queryDate = ' CASE WHEN a.publish_down = ' . $db->quote($db->getNullDate()) . ' THEN a.created ELSE a.publish_down END '; + break; + case 'created' : + default : + $queryDate = ' a.created '; + break; + } + + return $queryDate; + } + + /** + * Get join information for the voting query. + * + * @param \Joomla\Registry\Registry $params An options object for the article. + * + * @return array A named array with "select" and "join" keys. + * + * @since 1.5 + */ + public static function buildVotingQuery($params = null) + { + if (!$params) + { + $params = JComponentHelper::getParams('com_content'); + } + + $voting = $params->get('show_vote'); + + if ($voting) + { + // Calculate voting count + $select = ' , ROUND(v.rating_sum / v.rating_count) AS rating, v.rating_count'; + $join = ' LEFT JOIN #__content_rating AS v ON a.id = v.content_id'; + } + else + { + $select = ''; + $join = ''; + } + + return array('select' => $select, 'join' => $join); + } + + /** + * Method to order the intro articles array for ordering + * down the columns instead of across. + * The layout always lays the introtext articles out across columns. + * Array is reordered so that, when articles are displayed in index order + * across columns in the layout, the result is that the + * desired article ordering is achieved down the columns. + * + * @param array &$articles Array of intro text articles + * @param integer $numColumns Number of columns in the layout + * + * @return array Reordered array to achieve desired ordering down columns + * + * @since 1.6 + * @deprecated 4.0 + */ + public static function orderDownColumns(&$articles, $numColumns = 1) + { + $count = count($articles); + + // Just return the same array if there is nothing to change + if ($numColumns == 1 || !is_array($articles) || $count <= $numColumns) + { + $return = $articles; + } + // We need to re-order the intro articles array + else + { + // We need to preserve the original array keys + $keys = array_keys($articles); + + $maxRows = ceil($count / $numColumns); + $numCells = $maxRows * $numColumns; + $numEmpty = $numCells - $count; + $index = array(); + + // Calculate number of empty cells in the array + + // Fill in all cells of the array + // Put -1 in empty cells so we can skip later + for ($row = 1, $i = 1; $row <= $maxRows; $row++) + { + for ($col = 1; $col <= $numColumns; $col++) + { + if ($numEmpty > ($numCells - $i)) + { + // Put -1 in empty cells + $index[$row][$col] = -1; + } + else + { + // Put in zero as placeholder + $index[$row][$col] = 0; + } + + $i++; + } + } + + // Layout the articles in column order, skipping empty cells + $i = 0; + + for ($col = 1; ($col <= $numColumns) && ($i < $count); $col++) + { + for ($row = 1; ($row <= $maxRows) && ($i < $count); $row++) + { + if ($index[$row][$col] != - 1) + { + $index[$row][$col] = $keys[$i]; + $i++; + } + } + } + + // Now read the $index back row by row to get articles in right row/col + // so that they will actually be ordered down the columns (when read by row in the layout) + $return = array(); + $i = 0; + + for ($row = 1; ($row <= $maxRows) && ($i < $count); $row++) + { + for ($col = 1; ($col <= $numColumns) && ($i < $count); $col++) + { + $return[$keys[$i]] = $articles[$index[$row][$col]]; + $i++; + } + } + } + + return $return; + } +} diff --git a/Sites/pages/components/com_content/helpers/route.php b/Sites/pages/components/com_content/helpers/route.php new file mode 100644 index 00000000..27a235f9 --- /dev/null +++ b/Sites/pages/components/com_content/helpers/route.php @@ -0,0 +1,109 @@ + 1) + { + $link .= '&catid=' . $catid; + } + + if ($language && $language !== '*' && JLanguageMultilang::isEnabled()) + { + $link .= '&lang=' . $language; + } + + if ($layout) + { + $link .= '&layout=' . $layout; + } + + return $link; + } + + /** + * Get the category route. + * + * @param integer $catid The category ID. + * @param integer $language The language code. + * @param string $layout The layout value. + * + * @return string The article route. + * + * @since 1.5 + */ + public static function getCategoryRoute($catid, $language = 0, $layout = null) + { + if ($catid instanceof JCategoryNode) + { + $id = $catid->id; + } + else + { + $id = (int) $catid; + } + + if ($id < 1) + { + return ''; + } + + $link = 'index.php?option=com_content&view=category&id=' . $id; + + if ($language && $language !== '*' && JLanguageMultilang::isEnabled()) + { + $link .= '&lang=' . $language; + } + + if ($layout) + { + $link .= '&layout=' . $layout; + } + + return $link; + } + + /** + * Get the form route. + * + * @param integer $id The form ID. + * + * @return string The article route. + * + * @since 1.5 + */ + public static function getFormRoute($id) + { + return 'index.php?option=com_content&task=article.edit&a_id=' . (int) $id; + } +} diff --git a/Sites/pages/components/com_content/models/archive.php b/Sites/pages/components/com_content/models/archive.php new file mode 100644 index 00000000..4d012e5c --- /dev/null +++ b/Sites/pages/components/com_content/models/archive.php @@ -0,0 +1,219 @@ +state->params; + + // Filter on archived articles + $this->setState('filter.published', 2); + + // Filter on month, year + $this->setState('filter.month', $app->input->getInt('month')); + $this->setState('filter.year', $app->input->getInt('year')); + + // Optional filter text + $this->setState('list.filter', $app->input->getString('filter-search')); + + // Get list limit + $itemid = $app->input->get('Itemid', 0, 'int'); + $limit = $app->getUserStateFromRequest('com_content.archive.list' . $itemid . '.limit', 'limit', $params->get('display_num'), 'uint'); + $this->setState('list.limit', $limit); + + // Set the archive ordering + $articleOrderby = $params->get('orderby_sec', 'rdate'); + $articleOrderDate = $params->get('order_date'); + + // No category ordering + $secondary = ContentHelperQuery::orderbySecondary($articleOrderby, $articleOrderDate); + + $this->setState('list.ordering', $secondary . ', a.created DESC'); + $this->setState('list.direction', ''); + } + + /** + * Get the master query for retrieving a list of articles subject to the model state. + * + * @return JDatabaseQuery + * + * @since 1.6 + */ + protected function getListQuery() + { + $params = $this->state->params; + $app = JFactory::getApplication('site'); + $catids = ArrayHelper::toInteger($app->input->get('catid', array(), 'array')); + $catids = array_values(array_diff($catids, array(0))); + $articleOrderDate = $params->get('order_date'); + + // Create a new query object. + $query = parent::getListQuery(); + + // Add routing for archive + // Sqlsrv changes + $case_when = ' CASE WHEN '; + $case_when .= $query->charLength('a.alias', '!=', '0'); + $case_when .= ' THEN '; + $a_id = $query->castAsChar('a.id'); + $case_when .= $query->concatenate(array($a_id, 'a.alias'), ':'); + $case_when .= ' ELSE '; + $case_when .= $a_id . ' END as slug'; + + $query->select($case_when); + + $case_when = ' CASE WHEN '; + $case_when .= $query->charLength('c.alias', '!=', '0'); + $case_when .= ' THEN '; + $c_id = $query->castAsChar('c.id'); + $case_when .= $query->concatenate(array($c_id, 'c.alias'), ':'); + $case_when .= ' ELSE '; + $case_when .= $c_id . ' END as catslug'; + $query->select($case_when); + + // Filter on month, year + // First, get the date field + $queryDate = ContentHelperQuery::getQueryDate($articleOrderDate); + + if ($month = $this->getState('filter.month')) + { + $query->where($query->month($queryDate) . ' = ' . $month); + } + + if ($year = $this->getState('filter.year')) + { + $query->where($query->year($queryDate) . ' = ' . $year); + } + + if (count($catids) > 0) + { + $query->where('c.id IN (' . implode(', ', $catids) . ')'); + } + + return $query; + } + + /** + * Method to get the archived article list + * + * @access public + * @return array + */ + public function getData() + { + $app = JFactory::getApplication(); + + // Lets load the content if it doesn't already exist + if (empty($this->_data)) + { + // Get the page/component configuration + $params = $app->getParams(); + + // Get the pagination request variables + $limit = $app->input->get('limit', $params->get('display_num', 20), 'uint'); + $limitstart = $app->input->get('limitstart', 0, 'uint'); + + $query = $this->_buildQuery(); + + $this->_data = $this->_getList($query, $limitstart, $limit); + } + + return $this->_data; + } + + /** + * JModelLegacy override to add alternating value for $odd + * + * @param string $query The query. + * @param integer $limitstart Offset. + * @param integer $limit The number of records. + * + * @return array An array of results. + * + * @since 3.0.1 + * @throws RuntimeException + */ + protected function _getList($query, $limitstart=0, $limit=0) + { + $result = parent::_getList($query, $limitstart, $limit); + + $odd = 1; + + foreach ($result as $k => $row) + { + $result[$k]->odd = $odd; + $odd = 1 - $odd; + } + + return $result; + } + + /** + * Gets the archived articles years + * + * @return array + * + * @since 3.6.0 + */ + public function getYears() + { + $db = $this->getDbo(); + $nullDate = $db->quote($db->getNullDate()); + $nowDate = $db->quote(JFactory::getDate()->toSql()); + + $query = $db->getQuery(true); + $years = $query->year($db->qn('created')); + $query->select('DISTINCT (' . $years . ')') + ->from($db->qn('#__content')) + ->where($db->qn('state') . '= 2') + ->where('(publish_up = ' . $nullDate . ' OR publish_up <= ' . $nowDate . ')') + ->where('(publish_down = ' . $nullDate . ' OR publish_down >= ' . $nowDate . ')') + ->order('1 ASC'); + + $db->setQuery($query); + + return $db->loadColumn(); + } +} diff --git a/Sites/pages/components/com_content/models/article.php b/Sites/pages/components/com_content/models/article.php new file mode 100644 index 00000000..c2865eee --- /dev/null +++ b/Sites/pages/components/com_content/models/article.php @@ -0,0 +1,385 @@ +input->getInt('id'); + $this->setState('article.id', $pk); + + $offset = $app->input->getUInt('limitstart'); + $this->setState('list.offset', $offset); + + // Load the parameters. + $params = $app->getParams(); + $this->setState('params', $params); + + $user = JFactory::getUser(); + + // If $pk is set then authorise on complete asset, else on component only + $asset = empty($pk) ? 'com_content' : 'com_content.article.' . $pk; + + if ((!$user->authorise('core.edit.state', $asset)) && (!$user->authorise('core.edit', $asset))) + { + $this->setState('filter.published', 1); + $this->setState('filter.archived', 2); + } + + $this->setState('filter.language', JLanguageMultilang::isEnabled()); + } + + /** + * Method to get article data. + * + * @param integer $pk The id of the article. + * + * @return object|boolean|JException Menu item data object on success, boolean false or JException instance on error + */ + public function getItem($pk = null) + { + $user = JFactory::getUser(); + + $pk = (!empty($pk)) ? $pk : (int) $this->getState('article.id'); + + if ($this->_item === null) + { + $this->_item = array(); + } + + if (!isset($this->_item[$pk])) + { + try + { + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select( + $this->getState( + 'item.select', 'a.id, a.asset_id, a.title, a.alias, a.introtext, a.fulltext, ' . + 'a.state, a.catid, a.created, a.created_by, a.created_by_alias, ' . + // Use created if modified is 0 + 'CASE WHEN a.modified = ' . $db->quote($db->getNullDate()) . ' THEN a.created ELSE a.modified END as modified, ' . + 'a.modified_by, a.checked_out, a.checked_out_time, a.publish_up, a.publish_down, ' . + 'a.images, a.urls, a.attribs, a.version, a.ordering, ' . + 'a.metakey, a.metadesc, a.access, a.hits, a.metadata, a.featured, a.language, a.xreference' + ) + ); + $query->from('#__content AS a') + ->where('a.id = ' . (int) $pk); + + // Join on category table. + $query->select('c.title AS category_title, c.alias AS category_alias, c.access AS category_access') + ->innerJoin('#__categories AS c on c.id = a.catid') + ->where('c.published > 0'); + + // Join on user table. + $query->select('u.name AS author') + ->join('LEFT', '#__users AS u on u.id = a.created_by'); + + // Filter by language + if ($this->getState('filter.language')) + { + $query->where('a.language in (' . $db->quote(JFactory::getLanguage()->getTag()) . ',' . $db->quote('*') . ')'); + } + + // Join over the categories to get parent category titles + $query->select('parent.title as parent_title, parent.id as parent_id, parent.path as parent_route, parent.alias as parent_alias') + ->join('LEFT', '#__categories as parent ON parent.id = c.parent_id'); + + // Join on voting table + $query->select('ROUND(v.rating_sum / v.rating_count, 0) AS rating, v.rating_count as rating_count') + ->join('LEFT', '#__content_rating AS v ON a.id = v.content_id'); + + if ((!$user->authorise('core.edit.state', 'com_content.article.' . $pk)) && (!$user->authorise('core.edit', 'com_content.article.' . $pk))) + { + // Filter by start and end dates. + $nullDate = $db->quote($db->getNullDate()); + $date = JFactory::getDate(); + + $nowDate = $db->quote($date->toSql()); + + $query->where('(a.publish_up = ' . $nullDate . ' OR a.publish_up <= ' . $nowDate . ')') + ->where('(a.publish_down = ' . $nullDate . ' OR a.publish_down >= ' . $nowDate . ')'); + } + + // Filter by published state. + $published = $this->getState('filter.published'); + $archived = $this->getState('filter.archived'); + + if (is_numeric($published)) + { + $query->where('(a.state = ' . (int) $published . ' OR a.state =' . (int) $archived . ')'); + } + + $db->setQuery($query); + + $data = $db->loadObject(); + + if (empty($data)) + { + return JError::raiseError(404, JText::_('COM_CONTENT_ERROR_ARTICLE_NOT_FOUND')); + } + + // Check for published state if filter set. + if ((is_numeric($published) || is_numeric($archived)) && (($data->state != $published) && ($data->state != $archived))) + { + return JError::raiseError(404, JText::_('COM_CONTENT_ERROR_ARTICLE_NOT_FOUND')); + } + + // Convert parameter fields to objects. + $registry = new Registry($data->attribs); + + $data->params = clone $this->getState('params'); + $data->params->merge($registry); + + $data->metadata = new Registry($data->metadata); + + // Technically guest could edit an article, but lets not check that to improve performance a little. + if (!$user->get('guest')) + { + $userId = $user->get('id'); + $asset = 'com_content.article.' . $data->id; + + // Check general edit permission first. + if ($user->authorise('core.edit', $asset)) + { + $data->params->set('access-edit', true); + } + + // Now check if edit.own is available. + elseif (!empty($userId) && $user->authorise('core.edit.own', $asset)) + { + // Check for a valid user and that they are the owner. + if ($userId == $data->created_by) + { + $data->params->set('access-edit', true); + } + } + } + + // Compute view access permissions. + if ($access = $this->getState('filter.access')) + { + // If the access filter has been set, we already know this user can view. + $data->params->set('access-view', true); + } + else + { + // If no access filter is set, the layout takes some responsibility for display of limited information. + $user = JFactory::getUser(); + $groups = $user->getAuthorisedViewLevels(); + + if ($data->catid == 0 || $data->category_access === null) + { + $data->params->set('access-view', in_array($data->access, $groups)); + } + else + { + $data->params->set('access-view', in_array($data->access, $groups) && in_array($data->category_access, $groups)); + } + } + + $this->_item[$pk] = $data; + } + catch (Exception $e) + { + if ($e->getCode() == 404) + { + // Need to go thru the error handler to allow Redirect to work. + JError::raiseError(404, $e->getMessage()); + } + else + { + $this->setError($e); + $this->_item[$pk] = false; + } + } + } + + return $this->_item[$pk]; + } + + /** + * Increment the hit counter for the article. + * + * @param integer $pk Optional primary key of the article to increment. + * + * @return boolean True if successful; false otherwise and internal error set. + */ + public function hit($pk = 0) + { + $input = JFactory::getApplication()->input; + $hitcount = $input->getInt('hitcount', 1); + + if ($hitcount) + { + $pk = (!empty($pk)) ? $pk : (int) $this->getState('article.id'); + + $table = JTable::getInstance('Content', 'JTable'); + $table->hit($pk); + } + + return true; + } + + /** + * Save user vote on article + * + * @param integer $pk Joomla Article Id + * @param integer $rate Voting rate + * + * @return boolean Return true on success + */ + public function storeVote($pk = 0, $rate = 0) + { + if ($rate >= 1 && $rate <= 5 && $pk > 0) + { + $userIP = IpHelper::getIp(); + + // Initialize variables. + $db = $this->getDbo(); + $query = $db->getQuery(true); + + // Create the base select statement. + $query->select('*') + ->from($db->quoteName('#__content_rating')) + ->where($db->quoteName('content_id') . ' = ' . (int) $pk); + + // Set the query and load the result. + $db->setQuery($query); + + // Check for a database error. + try + { + $rating = $db->loadObject(); + } + catch (RuntimeException $e) + { + JError::raiseWarning(500, $e->getMessage()); + + return false; + } + + // There are no ratings yet, so lets insert our rating + if (!$rating) + { + $query = $db->getQuery(true); + + // Create the base insert statement. + $query->insert($db->quoteName('#__content_rating')) + ->columns(array($db->quoteName('content_id'), $db->quoteName('lastip'), $db->quoteName('rating_sum'), $db->quoteName('rating_count'))) + ->values((int) $pk . ', ' . $db->quote($userIP) . ',' . (int) $rate . ', 1'); + + // Set the query and execute the insert. + $db->setQuery($query); + + try + { + $db->execute(); + } + catch (RuntimeException $e) + { + JError::raiseWarning(500, $e->getMessage()); + + return false; + } + } + else + { + if ($userIP != $rating->lastip) + { + $query = $db->getQuery(true); + + // Create the base update statement. + $query->update($db->quoteName('#__content_rating')) + ->set($db->quoteName('rating_count') . ' = rating_count + 1') + ->set($db->quoteName('rating_sum') . ' = rating_sum + ' . (int) $rate) + ->set($db->quoteName('lastip') . ' = ' . $db->quote($userIP)) + ->where($db->quoteName('content_id') . ' = ' . (int) $pk); + + // Set the query and execute the update. + $db->setQuery($query); + + try + { + $db->execute(); + } + catch (RuntimeException $e) + { + JError::raiseWarning(500, $e->getMessage()); + + return false; + } + } + else + { + return false; + } + } + + $this->cleanCache(); + + return true; + } + + JError::raiseWarning(500, JText::sprintf('COM_CONTENT_INVALID_RATING', $rate), "JModelArticle::storeVote($rate)"); + + return false; + } + + /** + * Cleans the cache of com_content and content modules + * + * @param string $group The cache group + * @param integer $clientId The ID of the client + * + * @return void + * + * @since 3.9.9 + */ + protected function cleanCache($group = null, $clientId = 0) + { + parent::cleanCache('com_content'); + parent::cleanCache('mod_articles_archive'); + parent::cleanCache('mod_articles_categories'); + parent::cleanCache('mod_articles_category'); + parent::cleanCache('mod_articles_latest'); + parent::cleanCache('mod_articles_news'); + parent::cleanCache('mod_articles_popular'); + } +} diff --git a/Sites/pages/components/com_content/models/articles.php b/Sites/pages/components/com_content/models/articles.php new file mode 100644 index 00000000..b0e18324 --- /dev/null +++ b/Sites/pages/components/com_content/models/articles.php @@ -0,0 +1,761 @@ +input->get('limit', $app->get('list_limit', 0), 'uint'); + $this->setState('list.limit', $value); + + $value = $app->input->get('limitstart', 0, 'uint'); + $this->setState('list.start', $value); + + $value = $app->input->get('filter_tag', 0, 'uint'); + $this->setState('filter.tag', $value); + + $orderCol = $app->input->get('filter_order', 'a.ordering'); + + if (!in_array($orderCol, $this->filter_fields)) + { + $orderCol = 'a.ordering'; + } + + $this->setState('list.ordering', $orderCol); + + $listOrder = $app->input->get('filter_order_Dir', 'ASC'); + + if (!in_array(strtoupper($listOrder), array('ASC', 'DESC', ''))) + { + $listOrder = 'ASC'; + } + + $this->setState('list.direction', $listOrder); + + $params = $app->getParams(); + $this->setState('params', $params); + $user = JFactory::getUser(); + + if ((!$user->authorise('core.edit.state', 'com_content')) && (!$user->authorise('core.edit', 'com_content'))) + { + // Filter on published for those who do not have edit or edit.state rights. + $this->setState('filter.published', 1); + } + + $this->setState('filter.language', JLanguageMultilang::isEnabled()); + + // Process show_noauth parameter + if ((!$params->get('show_noauth')) || (!JComponentHelper::getParams('com_content')->get('show_noauth'))) + { + $this->setState('filter.access', true); + } + else + { + $this->setState('filter.access', false); + } + + $this->setState('layout', $app->input->getString('layout')); + } + + /** + * Method to get a store id based on model configuration state. + * + * This is necessary because the model is used by the component and + * different modules that might need different sets of data or different + * ordering requirements. + * + * @param string $id A prefix for the store id. + * + * @return string A store id. + * + * @since 1.6 + */ + protected function getStoreId($id = '') + { + // Compile the store id. + $id .= ':' . serialize($this->getState('filter.published')); + $id .= ':' . $this->getState('filter.access'); + $id .= ':' . $this->getState('filter.featured'); + $id .= ':' . serialize($this->getState('filter.article_id')); + $id .= ':' . $this->getState('filter.article_id.include'); + $id .= ':' . serialize($this->getState('filter.category_id')); + $id .= ':' . $this->getState('filter.category_id.include'); + $id .= ':' . serialize($this->getState('filter.author_id')); + $id .= ':' . $this->getState('filter.author_id.include'); + $id .= ':' . serialize($this->getState('filter.author_alias')); + $id .= ':' . $this->getState('filter.author_alias.include'); + $id .= ':' . $this->getState('filter.date_filtering'); + $id .= ':' . $this->getState('filter.date_field'); + $id .= ':' . $this->getState('filter.start_date_range'); + $id .= ':' . $this->getState('filter.end_date_range'); + $id .= ':' . $this->getState('filter.relative_date'); + $id .= ':' . serialize($this->getState('filter.tag')); + + return parent::getStoreId($id); + } + + /** + * Get the master query for retrieving a list of articles subject to the model state. + * + * @return JDatabaseQuery + * + * @since 1.6 + */ + protected function getListQuery() + { + // Get the current user for authorisation checks + $user = JFactory::getUser(); + + // Create a new query object. + $db = $this->getDbo(); + $query = $db->getQuery(true); + + // Select the required fields from the table. + $query->select( + $this->getState( + 'list.select', + 'a.id, a.title, a.alias, a.introtext, a.fulltext, ' . + 'a.checked_out, a.checked_out_time, ' . + 'a.catid, a.created, a.created_by, a.created_by_alias, ' . + // Published/archived article in archive category is treats as archive article + // If category is not published then force 0 + 'CASE WHEN c.published = 2 AND a.state > 0 THEN 2 WHEN c.published != 1 THEN 0 ELSE a.state END as state,' . + // Use created if modified is 0 + 'CASE WHEN a.modified = ' . $db->quote($db->getNullDate()) . ' THEN a.created ELSE a.modified END as modified, ' . + 'a.modified_by, uam.name as modified_by_name,' . + // Use created if publish_up is 0 + 'CASE WHEN a.publish_up = ' . $db->quote($db->getNullDate()) . ' THEN a.created ELSE a.publish_up END as publish_up,' . + 'a.publish_down, a.images, a.urls, a.attribs, a.metadata, a.metakey, a.metadesc, a.access, ' . + 'a.hits, a.xreference, a.featured, a.language, ' . ' ' . $query->length('a.fulltext') . ' AS readmore, a.ordering' + ) + ); + + $query->from('#__content AS a'); + + $params = $this->getState('params'); + $orderby_sec = $params->get('orderby_sec'); + + // Join over the frontpage articles if required. + if ($this->getState('filter.frontpage')) + { + if ($orderby_sec === 'front') + { + $query->select('fp.ordering'); + $query->join('INNER', '#__content_frontpage AS fp ON fp.content_id = a.id'); + } + else + { + $query->where('a.featured = 1'); + } + } + elseif ($orderby_sec === 'front' || $this->getState('list.ordering') === 'fp.ordering') + { + $query->select('fp.ordering'); + $query->join('LEFT', '#__content_frontpage AS fp ON fp.content_id = a.id'); + } + + // Join over the categories. + $query->select('c.title AS category_title, c.path AS category_route, c.access AS category_access, c.alias AS category_alias') + ->select('c.published, c.published AS parents_published, c.lft') + ->join('LEFT', '#__categories AS c ON c.id = a.catid'); + + // Join over the users for the author and modified_by names. + $query->select("CASE WHEN a.created_by_alias > ' ' THEN a.created_by_alias ELSE ua.name END AS author") + ->select('ua.email AS author_email') + ->join('LEFT', '#__users AS ua ON ua.id = a.created_by') + ->join('LEFT', '#__users AS uam ON uam.id = a.modified_by'); + + // Join over the categories to get parent category titles + $query->select('parent.title as parent_title, parent.id as parent_id, parent.path as parent_route, parent.alias as parent_alias') + ->join('LEFT', '#__categories as parent ON parent.id = c.parent_id'); + + if (JPluginHelper::isEnabled('content', 'vote')) + { + // Join on voting table + $query->select('COALESCE(NULLIF(ROUND(v.rating_sum / v.rating_count, 0), 0), 0) AS rating, + COALESCE(NULLIF(v.rating_count, 0), 0) as rating_count') + ->join('LEFT', '#__content_rating AS v ON a.id = v.content_id'); + } + + // Filter by access level. + if ($this->getState('filter.access', true)) + { + $groups = implode(',', $user->getAuthorisedViewLevels()); + $query->where('a.access IN (' . $groups . ')') + ->where('c.access IN (' . $groups . ')'); + } + + // Filter by published state + $published = $this->getState('filter.published'); + + if (is_numeric($published) && $published == 2) + { + /** + * If category is archived then article has to be published or archived. + * Or categogy is published then article has to be archived. + */ + $query->where('((c.published = 2 AND a.state > 0) OR (c.published = 1 AND a.state = 2))'); + } + elseif (is_numeric($published)) + { + // Category has to be published + $query->where('c.published = 1 AND a.state = ' . (int) $published); + } + elseif (is_array($published)) + { + $published = ArrayHelper::toInteger($published); + $published = implode(',', $published); + + // Category has to be published + $query->where('c.published = 1 AND a.state IN (' . $published . ')'); + } + + // Filter by featured state + $featured = $this->getState('filter.featured'); + + switch ($featured) + { + case 'hide': + $query->where('a.featured = 0'); + break; + + case 'only': + $query->where('a.featured = 1'); + break; + + case 'show': + default: + // Normally we do not discriminate between featured/unfeatured items. + break; + } + + // Filter by a single or group of articles. + $articleId = $this->getState('filter.article_id'); + + if (is_numeric($articleId)) + { + $type = $this->getState('filter.article_id.include', true) ? '= ' : '<> '; + $query->where('a.id ' . $type . (int) $articleId); + } + elseif (is_array($articleId)) + { + $articleId = ArrayHelper::toInteger($articleId); + $articleId = implode(',', $articleId); + $type = $this->getState('filter.article_id.include', true) ? 'IN' : 'NOT IN'; + $query->where('a.id ' . $type . ' (' . $articleId . ')'); + } + + // Filter by a single or group of categories + $categoryId = $this->getState('filter.category_id'); + + if (is_numeric($categoryId)) + { + $type = $this->getState('filter.category_id.include', true) ? '= ' : '<> '; + + // Add subcategory check + $includeSubcategories = $this->getState('filter.subcategories', false); + $categoryEquals = 'a.catid ' . $type . (int) $categoryId; + + if ($includeSubcategories) + { + $levels = (int) $this->getState('filter.max_category_levels', '1'); + + // Create a subquery for the subcategory list + $subQuery = $db->getQuery(true) + ->select('sub.id') + ->from('#__categories as sub') + ->join('INNER', '#__categories as this ON sub.lft > this.lft AND sub.rgt < this.rgt') + ->where('this.id = ' . (int) $categoryId); + + if ($levels >= 0) + { + $subQuery->where('sub.level <= this.level + ' . $levels); + } + + // Add the subquery to the main query + $query->where('(' . $categoryEquals . ' OR a.catid IN (' . (string) $subQuery . '))'); + } + else + { + $query->where($categoryEquals); + } + } + elseif (is_array($categoryId) && (count($categoryId) > 0)) + { + $categoryId = ArrayHelper::toInteger($categoryId); + $categoryId = implode(',', $categoryId); + + if (!empty($categoryId)) + { + $type = $this->getState('filter.category_id.include', true) ? 'IN' : 'NOT IN'; + $query->where('a.catid ' . $type . ' (' . $categoryId . ')'); + } + } + + // Filter by author + $authorId = $this->getState('filter.author_id'); + $authorWhere = ''; + + if (is_numeric($authorId)) + { + $type = $this->getState('filter.author_id.include', true) ? '= ' : '<> '; + $authorWhere = 'a.created_by ' . $type . (int) $authorId; + } + elseif (is_array($authorId)) + { + $authorId = array_filter($authorId, 'is_numeric'); + + if ($authorId) + { + $authorId = implode(',', $authorId); + $type = $this->getState('filter.author_id.include', true) ? 'IN' : 'NOT IN'; + $authorWhere = 'a.created_by ' . $type . ' (' . $authorId . ')'; + } + } + + // Filter by author alias + $authorAlias = $this->getState('filter.author_alias'); + $authorAliasWhere = ''; + + if (is_string($authorAlias)) + { + $type = $this->getState('filter.author_alias.include', true) ? '= ' : '<> '; + $authorAliasWhere = 'a.created_by_alias ' . $type . $db->quote($authorAlias); + } + elseif (is_array($authorAlias)) + { + $first = current($authorAlias); + + if (!empty($first)) + { + foreach ($authorAlias as $key => $alias) + { + $authorAlias[$key] = $db->quote($alias); + } + + $authorAlias = implode(',', $authorAlias); + + if ($authorAlias) + { + $type = $this->getState('filter.author_alias.include', true) ? 'IN' : 'NOT IN'; + $authorAliasWhere = 'a.created_by_alias ' . $type . ' (' . $authorAlias . + ')'; + } + } + } + + if (!empty($authorWhere) && !empty($authorAliasWhere)) + { + $query->where('(' . $authorWhere . ' OR ' . $authorAliasWhere . ')'); + } + elseif (empty($authorWhere) && empty($authorAliasWhere)) + { + // If both are empty we don't want to add to the query + } + else + { + // One of these is empty, the other is not so we just add both + $query->where($authorWhere . $authorAliasWhere); + } + + // Define null and now dates + $nullDate = $db->quote($db->getNullDate()); + $nowDate = $db->quote(JFactory::getDate()->toSql()); + + // Filter by start and end dates. + if ((!$user->authorise('core.edit.state', 'com_content')) && (!$user->authorise('core.edit', 'com_content'))) + { + $query->where('(a.publish_up = ' . $nullDate . ' OR a.publish_up <= ' . $nowDate . ')') + ->where('(a.publish_down = ' . $nullDate . ' OR a.publish_down >= ' . $nowDate . ')'); + } + + // Filter by Date Range or Relative Date + $dateFiltering = $this->getState('filter.date_filtering', 'off'); + $dateField = $this->getState('filter.date_field', 'a.created'); + + switch ($dateFiltering) + { + case 'range': + $startDateRange = $db->quote($this->getState('filter.start_date_range', $nullDate)); + $endDateRange = $db->quote($this->getState('filter.end_date_range', $nullDate)); + $query->where( + '(' . $dateField . ' >= ' . $startDateRange . ' AND ' . $dateField . + ' <= ' . $endDateRange . ')' + ); + break; + + case 'relative': + $relativeDate = (int) $this->getState('filter.relative_date', 0); + $query->where( + $dateField . ' >= ' . $query->dateAdd($nowDate, -1 * $relativeDate, 'DAY') + ); + break; + + case 'off': + default: + break; + } + + // Process the filter for list views with user-entered filters + if (is_object($params) && ($params->get('filter_field') !== 'hide') && ($filter = $this->getState('list.filter'))) + { + // Clean filter variable + $filter = StringHelper::strtolower($filter); + $monthFilter = $filter; + $hitsFilter = (int) $filter; + $filter = $db->quote('%' . $db->escape($filter, true) . '%', false); + + switch ($params->get('filter_field')) + { + case 'author': + $query->where( + 'LOWER( CASE WHEN a.created_by_alias > ' . $db->quote(' ') . + ' THEN a.created_by_alias ELSE ua.name END ) LIKE ' . $filter . ' ' + ); + break; + + case 'hits': + $query->where('a.hits >= ' . $hitsFilter . ' '); + break; + + case 'month': + if ($monthFilter != '') + { + $query->where( + $db->quote(date("Y-m-d", strtotime($monthFilter)) . ' 00:00:00') . ' <= CASE WHEN a.publish_up = ' . + $db->quote($db->getNullDate()) . ' THEN a.created ELSE a.publish_up END' + ); + + $query->where( + $db->quote(date("Y-m-t", strtotime($monthFilter)) . ' 23:59:59') . ' >= CASE WHEN a.publish_up = ' . + $db->quote($db->getNullDate()) . ' THEN a.created ELSE a.publish_up END' + ); + } + break; + + case 'title': + default: + // Default to 'title' if parameter is not valid + $query->where('LOWER( a.title ) LIKE ' . $filter); + break; + } + } + + // Filter by language + if ($this->getState('filter.language')) + { + $query->where('a.language IN (' . $db->quote(JFactory::getLanguage()->getTag()) . ',' . $db->quote('*') . ')'); + } + + // Filter by a single or group of tags. + $tagId = $this->getState('filter.tag'); + + if (is_array($tagId) && count($tagId) === 1) + { + $tagId = current($tagId); + } + + if (is_array($tagId)) + { + $tagId = implode(',', ArrayHelper::toInteger($tagId)); + + if ($tagId) + { + $subQuery = $db->getQuery(true) + ->select('DISTINCT content_item_id') + ->from($db->quoteName('#__contentitem_tag_map')) + ->where('tag_id IN (' . $tagId . ')') + ->where('type_alias = ' . $db->quote('com_content.article')); + + $query->innerJoin('(' . (string) $subQuery . ') AS tagmap ON tagmap.content_item_id = a.id'); + } + } + elseif ($tagId) + { + $query->innerJoin( + $db->quoteName('#__contentitem_tag_map', 'tagmap') + . ' ON tagmap.tag_id = ' . (int) $tagId + . ' AND tagmap.content_item_id = a.id' + . ' AND tagmap.type_alias = ' . $db->quote('com_content.article') + ); + } + + // Add the list ordering clause. + $query->order($this->getState('list.ordering', 'a.ordering') . ' ' . $this->getState('list.direction', 'ASC')); + + return $query; + } + + /** + * Method to get a list of articles. + * + * Overridden to inject convert the attribs field into a JParameter object. + * + * @return mixed An array of objects on success, false on failure. + * + * @since 1.6 + */ + public function getItems() + { + $items = parent::getItems(); + $user = JFactory::getUser(); + $userId = $user->get('id'); + $guest = $user->get('guest'); + $groups = $user->getAuthorisedViewLevels(); + $input = JFactory::getApplication()->input; + + // Get the global params + $globalParams = JComponentHelper::getParams('com_content', true); + + // Convert the parameter fields into objects. + foreach ($items as &$item) + { + $articleParams = new Registry($item->attribs); + + // Unpack readmore and layout params + $item->alternative_readmore = $articleParams->get('alternative_readmore'); + $item->layout = $articleParams->get('layout'); + + $item->params = clone $this->getState('params'); + + /** + * For blogs, article params override menu item params only if menu param = 'use_article' + * Otherwise, menu item params control the layout + * If menu item is 'use_article' and there is no article param, use global + */ + if (($input->getString('layout') === 'blog') || ($input->getString('view') === 'featured') + || ($this->getState('params')->get('layout_type') === 'blog')) + { + // Create an array of just the params set to 'use_article' + $menuParamsArray = $this->getState('params')->toArray(); + $articleArray = array(); + + foreach ($menuParamsArray as $key => $value) + { + if ($value === 'use_article') + { + // If the article has a value, use it + if ($articleParams->get($key) != '') + { + // Get the value from the article + $articleArray[$key] = $articleParams->get($key); + } + else + { + // Otherwise, use the global value + $articleArray[$key] = $globalParams->get($key); + } + } + } + + // Merge the selected article params + if (count($articleArray) > 0) + { + $articleParams = new Registry($articleArray); + $item->params->merge($articleParams); + } + } + else + { + // For non-blog layouts, merge all of the article params + $item->params->merge($articleParams); + } + + // Get display date + switch ($item->params->get('list_show_date')) + { + case 'modified': + $item->displayDate = $item->modified; + break; + + case 'published': + $item->displayDate = ($item->publish_up == 0) ? $item->created : $item->publish_up; + break; + + default: + case 'created': + $item->displayDate = $item->created; + break; + } + + /** + * Compute the asset access permissions. + * Technically guest could edit an article, but lets not check that to improve performance a little. + */ + if (!$guest) + { + $asset = 'com_content.article.' . $item->id; + + // Check general edit permission first. + if ($user->authorise('core.edit', $asset)) + { + $item->params->set('access-edit', true); + } + + // Now check if edit.own is available. + elseif (!empty($userId) && $user->authorise('core.edit.own', $asset)) + { + // Check for a valid user and that they are the owner. + if ($userId == $item->created_by) + { + $item->params->set('access-edit', true); + } + } + } + + $access = $this->getState('filter.access'); + + if ($access) + { + // If the access filter has been set, we already have only the articles this user can view. + $item->params->set('access-view', true); + } + else + { + // If no access filter is set, the layout takes some responsibility for display of limited information. + if ($item->catid == 0 || $item->category_access === null) + { + $item->params->set('access-view', in_array($item->access, $groups)); + } + else + { + $item->params->set('access-view', in_array($item->access, $groups) && in_array($item->category_access, $groups)); + } + } + + // Some contexts may not use tags data at all, so we allow callers to disable loading tag data + if ($this->getState('load_tags', $item->params->get('show_tags', '1'))) + { + $item->tags = new JHelperTags; + $item->tags->getItemTags('com_content.article', $item->id); + } + + if ($item->params->get('show_associations')) + { + $item->associations = ContentHelperAssociation::displayAssociations($item->id); + } + } + + return $items; + } + + /** + * Method to get the starting number of items for the data set. + * + * @return integer The starting number of items available in the data set. + * + * @since 3.0.1 + */ + public function getStart() + { + return $this->getState('list.start'); + } + + /** + * Count Items by Month + * + * @return mixed An array of objects on success, false on failure. + * + * @since 3.9.0 + */ + public function countItemsByMonth() + { + // Create a new query object. + $db = $this->getDbo(); + $query = $db->getQuery(true); + + $query + ->select('DATE(' . + $query->concatenate( + array( + $query->year($query->quoteName('publish_up')), + $query->quote('-'), + $query->month($query->quoteName('publish_up')), + $query->quote('-01') + ) + ) . ') as d' + ) + ->select('COUNT(*) as c') + ->from('(' . $this->getListQuery() . ') as b') + ->group($query->quoteName('d')) + ->order($query->quoteName('d') . ' desc'); + + return $db->setQuery($query)->loadObjectList(); + } +} diff --git a/Sites/pages/components/com_content/models/categories.php b/Sites/pages/components/com_content/models/categories.php new file mode 100644 index 00000000..821fedab --- /dev/null +++ b/Sites/pages/components/com_content/models/categories.php @@ -0,0 +1,146 @@ +setState('filter.extension', $this->_extension); + + // Get the parent id if defined. + $parentId = $app->input->getInt('id'); + $this->setState('filter.parentId', $parentId); + + $params = $app->getParams(); + $this->setState('params', $params); + + $this->setState('filter.published', 1); + $this->setState('filter.access', true); + } + + /** + * Method to get a store id based on model configuration state. + * + * This is necessary because the model is used by the component and + * different modules that might need different sets of data or different + * ordering requirements. + * + * @param string $id A prefix for the store id. + * + * @return string A store id. + */ + protected function getStoreId($id = '') + { + // Compile the store id. + $id .= ':' . $this->getState('filter.extension'); + $id .= ':' . $this->getState('filter.published'); + $id .= ':' . $this->getState('filter.access'); + $id .= ':' . $this->getState('filter.parentId'); + + return parent::getStoreId($id); + } + + /** + * Redefine the function an add some properties to make the styling more easy + * + * @param bool $recursive True if you want to return children recursively. + * + * @return mixed An array of data items on success, false on failure. + * + * @since 1.6 + */ + public function getItems($recursive = false) + { + $store = $this->getStoreId(); + + if (!isset($this->cache[$store])) + { + $app = JFactory::getApplication(); + $menu = $app->getMenu(); + $active = $menu->getActive(); + $params = new Registry; + + if ($active) + { + $params->loadString($active->params); + } + + $options = array(); + $options['countItems'] = $params->get('show_cat_num_articles_cat', 1) || !$params->get('show_empty_categories_cat', 0); + $categories = JCategories::getInstance('Content', $options); + $this->_parent = $categories->get($this->getState('filter.parentId', 'root')); + + if (is_object($this->_parent)) + { + $this->cache[$store] = $this->_parent->getChildren($recursive); + } + else + { + $this->cache[$store] = false; + } + } + + return $this->cache[$store]; + } + + /** + * Get the parent. + * + * @return object An array of data items on success, false on failure. + * + * @since 1.6 + */ + public function getParent() + { + if (!is_object($this->_parent)) + { + $this->getItems(); + } + + return $this->_parent; + } +} diff --git a/Sites/pages/components/com_content/models/category.php b/Sites/pages/components/com_content/models/category.php new file mode 100644 index 00000000..e660c65e --- /dev/null +++ b/Sites/pages/components/com_content/models/category.php @@ -0,0 +1,494 @@ +input->getInt('id'); + + $this->setState('category.id', $pk); + + // Load the parameters. Merge Global and Menu Item params into new object + $params = $app->getParams(); + $menuParams = new Registry; + + if ($menu = $app->getMenu()->getActive()) + { + $menuParams->loadString($menu->params); + } + + $mergedParams = clone $menuParams; + $mergedParams->merge($params); + + $this->setState('params', $mergedParams); + $user = JFactory::getUser(); + + $asset = 'com_content'; + + if ($pk) + { + $asset .= '.category.' . $pk; + } + + if ((!$user->authorise('core.edit.state', $asset)) && (!$user->authorise('core.edit', $asset))) + { + // Limit to published for people who can't edit or edit.state. + $this->setState('filter.published', 1); + } + else + { + $this->setState('filter.published', array(0, 1, 2)); + } + + // Process show_noauth parameter + if (!$params->get('show_noauth')) + { + $this->setState('filter.access', true); + } + else + { + $this->setState('filter.access', false); + } + + $itemid = $app->input->get('id', 0, 'int') . ':' . $app->input->get('Itemid', 0, 'int'); + + $value = $this->getUserStateFromRequest('com_content.category.filter.' . $itemid . '.tag', 'filter_tag', 0, 'int', false); + $this->setState('filter.tag', $value); + + // Optional filter text + $search = $app->getUserStateFromRequest('com_content.category.list.' . $itemid . '.filter-search', 'filter-search', '', 'string'); + $this->setState('list.filter', $search); + + // Filter.order + $orderCol = $app->getUserStateFromRequest('com_content.category.list.' . $itemid . '.filter_order', 'filter_order', '', 'string'); + + if (!in_array($orderCol, $this->filter_fields)) + { + $orderCol = 'a.ordering'; + } + + $this->setState('list.ordering', $orderCol); + + $listOrder = $app->getUserStateFromRequest('com_content.category.list.' . $itemid . '.filter_order_Dir', 'filter_order_Dir', '', 'cmd'); + + if (!in_array(strtoupper($listOrder), array('ASC', 'DESC', ''))) + { + $listOrder = 'ASC'; + } + + $this->setState('list.direction', $listOrder); + + $this->setState('list.start', $app->input->get('limitstart', 0, 'uint')); + + // Set limit for query. If list, use parameter. If blog, add blog parameters for limit. + if (($app->input->get('layout') === 'blog') || $params->get('layout_type') === 'blog') + { + $limit = $params->get('num_leading_articles') + $params->get('num_intro_articles') + $params->get('num_links'); + $this->setState('list.links', $params->get('num_links')); + } + else + { + $limit = $app->getUserStateFromRequest('com_content.category.list.' . $itemid . '.limit', 'limit', $params->get('display_num'), 'uint'); + } + + $this->setState('list.limit', $limit); + + // Set the depth of the category query based on parameter + $showSubcategories = $params->get('show_subcategory_content', '0'); + + if ($showSubcategories) + { + $this->setState('filter.max_category_levels', $params->get('show_subcategory_content', '1')); + $this->setState('filter.subcategories', true); + } + + $this->setState('filter.language', JLanguageMultilang::isEnabled()); + + $this->setState('layout', $app->input->getString('layout')); + + // Set the featured articles state + $this->setState('filter.featured', $params->get('show_featured')); + } + + /** + * Get the articles in the category + * + * @return mixed An array of articles or false if an error occurs. + * + * @since 1.5 + */ + public function getItems() + { + $limit = $this->getState('list.limit'); + + if ($this->_articles === null && $category = $this->getCategory()) + { + $model = JModelLegacy::getInstance('Articles', 'ContentModel', array('ignore_request' => true)); + $model->setState('params', JFactory::getApplication()->getParams()); + $model->setState('filter.category_id', $category->id); + $model->setState('filter.published', $this->getState('filter.published')); + $model->setState('filter.access', $this->getState('filter.access')); + $model->setState('filter.language', $this->getState('filter.language')); + $model->setState('filter.featured', $this->getState('filter.featured')); + $model->setState('list.ordering', $this->_buildContentOrderBy()); + $model->setState('list.start', $this->getState('list.start')); + $model->setState('list.limit', $limit); + $model->setState('list.direction', $this->getState('list.direction')); + $model->setState('list.filter', $this->getState('list.filter')); + $model->setState('filter.tag', $this->getState('filter.tag')); + + // Filter.subcategories indicates whether to include articles from subcategories in the list or blog + $model->setState('filter.subcategories', $this->getState('filter.subcategories')); + $model->setState('filter.max_category_levels', $this->getState('filter.max_category_levels')); + $model->setState('list.links', $this->getState('list.links')); + + if ($limit >= 0) + { + $this->_articles = $model->getItems(); + + if ($this->_articles === false) + { + $this->setError($model->getError()); + } + } + else + { + $this->_articles = array(); + } + + $this->_pagination = $model->getPagination(); + } + + return $this->_articles; + } + + /** + * Build the orderby for the query + * + * @return string $orderby portion of query + * + * @since 1.5 + */ + protected function _buildContentOrderBy() + { + $app = JFactory::getApplication('site'); + $db = $this->getDbo(); + $params = $this->state->params; + $itemid = $app->input->get('id', 0, 'int') . ':' . $app->input->get('Itemid', 0, 'int'); + $orderCol = $app->getUserStateFromRequest('com_content.category.list.' . $itemid . '.filter_order', 'filter_order', '', 'string'); + $orderDirn = $app->getUserStateFromRequest('com_content.category.list.' . $itemid . '.filter_order_Dir', 'filter_order_Dir', '', 'cmd'); + $orderby = ' '; + + if (!in_array($orderCol, $this->filter_fields)) + { + $orderCol = null; + } + + if (!in_array(strtoupper($orderDirn), array('ASC', 'DESC', ''))) + { + $orderDirn = 'ASC'; + } + + if ($orderCol && $orderDirn) + { + $orderby .= $db->escape($orderCol) . ' ' . $db->escape($orderDirn) . ', '; + } + + $articleOrderby = $params->get('orderby_sec', 'rdate'); + $articleOrderDate = $params->get('order_date'); + $categoryOrderby = $params->def('orderby_pri', ''); + $secondary = ContentHelperQuery::orderbySecondary($articleOrderby, $articleOrderDate) . ', '; + $primary = ContentHelperQuery::orderbyPrimary($categoryOrderby); + + $orderby .= $primary . ' ' . $secondary . ' a.created '; + + return $orderby; + } + + /** + * Method to get a JPagination object for the data set. + * + * @return JPagination A JPagination object for the data set. + * + * @since 3.0.1 + */ + public function getPagination() + { + if (empty($this->_pagination)) + { + return null; + } + + return $this->_pagination; + } + + /** + * Method to get category data for the current category + * + * @return object + * + * @since 1.5 + */ + public function getCategory() + { + if (!is_object($this->_item)) + { + if (isset($this->state->params)) + { + $params = $this->state->params; + $options = array(); + $options['countItems'] = $params->get('show_cat_num_articles', 1) || !$params->get('show_empty_categories_cat', 0); + $options['access'] = $params->get('check_access_rights', 1); + } + else + { + $options['countItems'] = 0; + } + + $categories = JCategories::getInstance('Content', $options); + $this->_item = $categories->get($this->getState('category.id', 'root')); + + // Compute selected asset permissions. + if (is_object($this->_item)) + { + $user = JFactory::getUser(); + $asset = 'com_content.category.' . $this->_item->id; + + // Check general create permission. + if ($user->authorise('core.create', $asset)) + { + $this->_item->getParams()->set('access-create', true); + } + + // TODO: Why aren't we lazy loading the children and siblings? + $this->_children = $this->_item->getChildren(); + $this->_parent = false; + + if ($this->_item->getParent()) + { + $this->_parent = $this->_item->getParent(); + } + + $this->_rightsibling = $this->_item->getSibling(); + $this->_leftsibling = $this->_item->getSibling(false); + } + else + { + $this->_children = false; + $this->_parent = false; + } + } + + return $this->_item; + } + + /** + * Get the parent category. + * + * @return mixed An array of categories or false if an error occurs. + * + * @since 1.6 + */ + public function getParent() + { + if (!is_object($this->_item)) + { + $this->getCategory(); + } + + return $this->_parent; + } + + /** + * Get the left sibling (adjacent) categories. + * + * @return mixed An array of categories or false if an error occurs. + * + * @since 1.6 + */ + public function &getLeftSibling() + { + if (!is_object($this->_item)) + { + $this->getCategory(); + } + + return $this->_leftsibling; + } + + /** + * Get the right sibling (adjacent) categories. + * + * @return mixed An array of categories or false if an error occurs. + * + * @since 1.6 + */ + public function &getRightSibling() + { + if (!is_object($this->_item)) + { + $this->getCategory(); + } + + return $this->_rightsibling; + } + + /** + * Get the child categories. + * + * @return mixed An array of categories or false if an error occurs. + * + * @since 1.6 + */ + public function &getChildren() + { + if (!is_object($this->_item)) + { + $this->getCategory(); + } + + // Order subcategories + if ($this->_children) + { + $params = $this->getState()->get('params'); + + $orderByPri = $params->get('orderby_pri'); + + if ($orderByPri === 'alpha' || $orderByPri === 'ralpha') + { + $this->_children = ArrayHelper::sortObjects($this->_children, 'title', ($orderByPri === 'alpha') ? 1 : (-1)); + } + } + + return $this->_children; + } + + /** + * Increment the hit counter for the category. + * + * @param int $pk Optional primary key of the category to increment. + * + * @return boolean True if successful; false otherwise and internal error set. + */ + public function hit($pk = 0) + { + $input = JFactory::getApplication()->input; + $hitcount = $input->getInt('hitcount', 1); + + if ($hitcount) + { + $pk = (!empty($pk)) ? $pk : (int) $this->getState('category.id'); + + $table = JTable::getInstance('Category', 'JTable'); + $table->hit($pk); + } + + return true; + } +} diff --git a/Sites/pages/components/com_content/models/featured.php b/Sites/pages/components/com_content/models/featured.php new file mode 100644 index 00000000..abb27ce4 --- /dev/null +++ b/Sites/pages/components/com_content/models/featured.php @@ -0,0 +1,171 @@ +input; + $user = JFactory::getUser(); + $app = JFactory::getApplication('site'); + + // List state information + $limitstart = $input->getUInt('limitstart', 0); + $this->setState('list.start', $limitstart); + + $params = $this->state->params; + $menuParams = new Registry; + + if ($menu = $app->getMenu()->getActive()) + { + $menuParams->loadString($menu->params); + } + + $mergedParams = clone $menuParams; + $mergedParams->merge($params); + + $this->setState('params', $mergedParams); + + $limit = $params->get('num_leading_articles') + $params->get('num_intro_articles') + $params->get('num_links'); + $this->setState('list.limit', $limit); + $this->setState('list.links', $params->get('num_links')); + + $this->setState('filter.frontpage', true); + + if ((!$user->authorise('core.edit.state', 'com_content')) && (!$user->authorise('core.edit', 'com_content'))) + { + // Filter on published for those who do not have edit or edit.state rights. + $this->setState('filter.published', 1); + } + else + { + $this->setState('filter.published', array(0, 1, 2)); + } + + // Process show_noauth parameter + if (!$params->get('show_noauth')) + { + $this->setState('filter.access', true); + } + else + { + $this->setState('filter.access', false); + } + + // Check for category selection + if ($params->get('featured_categories') && implode(',', $params->get('featured_categories')) == true) + { + $featuredCategories = $params->get('featured_categories'); + $this->setState('filter.frontpage.categories', $featuredCategories); + } + + $articleOrderby = $params->get('orderby_sec', 'rdate'); + $articleOrderDate = $params->get('order_date'); + $categoryOrderby = $params->def('orderby_pri', ''); + + $secondary = ContentHelperQuery::orderbySecondary($articleOrderby, $articleOrderDate); + $primary = ContentHelperQuery::orderbyPrimary($categoryOrderby); + + $this->setState('list.ordering', $primary . $secondary . ', a.created DESC'); + $this->setState('list.direction', ''); + } + + /** + * Method to get a list of articles. + * + * @return mixed An array of objects on success, false on failure. + */ + public function getItems() + { + $params = clone $this->getState('params'); + $limit = $params->get('num_leading_articles') + $params->get('num_intro_articles') + $params->get('num_links'); + + if ($limit > 0) + { + $this->setState('list.limit', $limit); + + return parent::getItems(); + } + + return array(); + } + + /** + * Method to get a store id based on model configuration state. + * + * This is necessary because the model is used by the component and + * different modules that might need different sets of data or different + * ordering requirements. + * + * @param string $id A prefix for the store id. + * + * @return string A store id. + */ + protected function getStoreId($id = '') + { + // Compile the store id. + $id .= $this->getState('filter.frontpage'); + + return parent::getStoreId($id); + } + + /** + * Get the list of items. + * + * @return JDatabaseQuery + */ + protected function getListQuery() + { + // Create a new query object. + $query = parent::getListQuery(); + + // Filter by categories + $featuredCategories = $this->getState('filter.frontpage.categories'); + + if (is_array($featuredCategories) && !in_array('', $featuredCategories)) + { + $query->where('a.catid IN (' . implode(',', ArrayHelper::toInteger($featuredCategories)) . ')'); + } + + return $query; + } +} diff --git a/Sites/pages/components/com_content/models/form.php b/Sites/pages/components/com_content/models/form.php new file mode 100644 index 00000000..dc62f21b --- /dev/null +++ b/Sites/pages/components/com_content/models/form.php @@ -0,0 +1,217 @@ +input->getInt('a_id'); + $this->setState('article.id', $pk); + + $this->setState('article.catid', $app->input->getInt('catid')); + + $return = $app->input->get('return', null, 'base64'); + $this->setState('return_page', base64_decode($return)); + + // Load the parameters. + $params = $app->getParams(); + $this->setState('params', $params); + + $this->setState('layout', $app->input->getString('layout')); + } + + /** + * Method to get article data. + * + * @param integer $itemId The id of the article. + * + * @return mixed Content item data object on success, false on failure. + */ + public function getItem($itemId = null) + { + $itemId = (int) (!empty($itemId)) ? $itemId : $this->getState('article.id'); + + // Get a row instance. + $table = $this->getTable(); + + // Attempt to load the row. + $return = $table->load($itemId); + + // Check for a table object error. + if ($return === false && $table->getError()) + { + $this->setError($table->getError()); + + return false; + } + + $properties = $table->getProperties(1); + $value = ArrayHelper::toObject($properties, 'JObject'); + + // Convert attrib field to Registry. + $value->params = new Registry($value->attribs); + + // Compute selected asset permissions. + $user = JFactory::getUser(); + $userId = $user->get('id'); + $asset = 'com_content.article.' . $value->id; + + // Check general edit permission first. + if ($user->authorise('core.edit', $asset)) + { + $value->params->set('access-edit', true); + } + + // Now check if edit.own is available. + elseif (!empty($userId) && $user->authorise('core.edit.own', $asset)) + { + // Check for a valid user and that they are the owner. + if ($userId == $value->created_by) + { + $value->params->set('access-edit', true); + } + } + + // Check edit state permission. + if ($itemId) + { + // Existing item + $value->params->set('access-change', $user->authorise('core.edit.state', $asset)); + } + else + { + // New item. + $catId = (int) $this->getState('article.catid'); + + if ($catId) + { + $value->params->set('access-change', $user->authorise('core.edit.state', 'com_content.category.' . $catId)); + $value->catid = $catId; + } + else + { + $value->params->set('access-change', $user->authorise('core.edit.state', 'com_content')); + } + } + + $value->articletext = $value->introtext; + + if (!empty($value->fulltext)) + { + $value->articletext .= '
          ' . $value->fulltext; + } + + // Convert the metadata field to an array. + $registry = new Registry($value->metadata); + $value->metadata = $registry->toArray(); + + if ($itemId) + { + $value->tags = new JHelperTags; + $value->tags->getTagIds($value->id, 'com_content.article'); + $value->metadata['tags'] = $value->tags; + } + + return $value; + } + + /** + * Get the return URL. + * + * @return string The return URL. + * + * @since 1.6 + */ + public function getReturnPage() + { + return base64_encode($this->getState('return_page')); + } + + /** + * Method to save the form data. + * + * @param array $data The form data. + * + * @return boolean True on success. + * + * @since 3.2 + */ + public function save($data) + { + // Associations are not edited in frontend ATM so we have to inherit them + if (JLanguageAssociations::isEnabled() && !empty($data['id']) + && $associations = JLanguageAssociations::getAssociations('com_content', '#__content', 'com_content.item', $data['id'])) + { + foreach ($associations as $tag => $associated) + { + $associations[$tag] = (int) $associated->id; + } + + $data['associations'] = $associations; + } + + return parent::save($data); + } + + /** + * Allows preprocessing of the JForm object. + * + * @param JForm $form The form object + * @param array $data The data to be merged into the form object + * @param string $group The plugin group to be executed + * + * @return void + * + * @since 3.7.0 + */ + protected function preprocessForm(JForm $form, $data, $group = 'content') + { + $params = $this->getState()->get('params'); + + if ($params && $params->get('enable_category') == 1 && $params->get('catid')) + { + $form->setFieldAttribute('catid', 'default', $params->get('catid')); + $form->setFieldAttribute('catid', 'readonly', 'true'); + } + + return parent::preprocessForm($form, $data, $group); + } +} diff --git a/Sites/pages/components/com_content/models/forms/article.xml b/Sites/pages/components/com_content/models/forms/article.xml new file mode 100644 index 00000000..a71c2ad3 --- /dev/null +++ b/Sites/pages/components/com_content/models/forms/article.xml @@ -0,0 +1,438 @@ + +
          +
          + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + +
          + + + + + + + + + + + +
          +
          + + + + + + + + + + + +
          +
          + + + + + + + + + + + + + + + + + + + + +
          + + + + + + + + + + + + + + + +
          +
          +
          diff --git a/Sites/pages/components/com_content/models/forms/filter_articles.xml b/Sites/pages/components/com_content/models/forms/filter_articles.xml new file mode 100644 index 00000000..bfb18905 --- /dev/null +++ b/Sites/pages/components/com_content/models/forms/filter_articles.xml @@ -0,0 +1,140 @@ + +
          + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          diff --git a/Sites/pages/components/com_content/router.php b/Sites/pages/components/com_content/router.php new file mode 100644 index 00000000..bb9b58bf --- /dev/null +++ b/Sites/pages/components/com_content/router.php @@ -0,0 +1,271 @@ +noIDs = (bool) $params->get('sef_ids'); + $categories = new JComponentRouterViewconfiguration('categories'); + $categories->setKey('id'); + $this->registerView($categories); + $category = new JComponentRouterViewconfiguration('category'); + $category->setKey('id')->setParent($categories, 'catid')->setNestable()->addLayout('blog'); + $this->registerView($category); + $article = new JComponentRouterViewconfiguration('article'); + $article->setKey('id')->setParent($category, 'catid'); + $this->registerView($article); + $this->registerView(new JComponentRouterViewconfiguration('archive')); + $this->registerView(new JComponentRouterViewconfiguration('featured')); + $form = new JComponentRouterViewconfiguration('form'); + $form->setKey('a_id'); + $this->registerView($form); + + parent::__construct($app, $menu); + + $this->attachRule(new JComponentRouterRulesMenu($this)); + + if ($params->get('sef_advanced', 0)) + { + $this->attachRule(new JComponentRouterRulesStandard($this)); + $this->attachRule(new JComponentRouterRulesNomenu($this)); + } + else + { + JLoader::register('ContentRouterRulesLegacy', __DIR__ . '/helpers/legacyrouter.php'); + $this->attachRule(new ContentRouterRulesLegacy($this)); + } + } + + /** + * Method to get the segment(s) for a category + * + * @param string $id ID of the category to retrieve the segments for + * @param array $query The request that is built right now + * + * @return array|string The segments of this item + */ + public function getCategorySegment($id, $query) + { + $category = JCategories::getInstance($this->getName())->get($id); + + if ($category) + { + $path = array_reverse($category->getPath(), true); + $path[0] = '1:root'; + + if ($this->noIDs) + { + foreach ($path as &$segment) + { + list($id, $segment) = explode(':', $segment, 2); + } + } + + return $path; + } + + return array(); + } + + /** + * Method to get the segment(s) for a category + * + * @param string $id ID of the category to retrieve the segments for + * @param array $query The request that is built right now + * + * @return array|string The segments of this item + */ + public function getCategoriesSegment($id, $query) + { + return $this->getCategorySegment($id, $query); + } + + /** + * Method to get the segment(s) for an article + * + * @param string $id ID of the article to retrieve the segments for + * @param array $query The request that is built right now + * + * @return array|string The segments of this item + */ + public function getArticleSegment($id, $query) + { + if (!strpos($id, ':')) + { + $db = JFactory::getDbo(); + $dbquery = $db->getQuery(true); + $dbquery->select($dbquery->qn('alias')) + ->from($dbquery->qn('#__content')) + ->where('id = ' . $dbquery->q($id)); + $db->setQuery($dbquery); + + $id .= ':' . $db->loadResult(); + } + + if ($this->noIDs) + { + list($void, $segment) = explode(':', $id, 2); + + return array($void => $segment); + } + + return array((int) $id => $id); + } + + /** + * Method to get the segment(s) for a form + * + * @param string $id ID of the article form to retrieve the segments for + * @param array $query The request that is built right now + * + * @return array|string The segments of this item + * + * @since 3.7.3 + */ + public function getFormSegment($id, $query) + { + return $this->getArticleSegment($id, $query); + } + + /** + * Method to get the id for a category + * + * @param string $segment Segment to retrieve the ID for + * @param array $query The request that is parsed right now + * + * @return mixed The id of this item or false + */ + public function getCategoryId($segment, $query) + { + if (isset($query['id'])) + { + $category = JCategories::getInstance($this->getName(), array('access' => false))->get($query['id']); + + if ($category) + { + foreach ($category->getChildren() as $child) + { + if ($this->noIDs) + { + if ($child->alias == $segment) + { + return $child->id; + } + } + else + { + if ($child->id == (int) $segment) + { + return $child->id; + } + } + } + } + } + + return false; + } + + /** + * Method to get the segment(s) for a category + * + * @param string $segment Segment to retrieve the ID for + * @param array $query The request that is parsed right now + * + * @return mixed The id of this item or false + */ + public function getCategoriesId($segment, $query) + { + return $this->getCategoryId($segment, $query); + } + + /** + * Method to get the segment(s) for an article + * + * @param string $segment Segment of the article to retrieve the ID for + * @param array $query The request that is parsed right now + * + * @return mixed The id of this item or false + */ + public function getArticleId($segment, $query) + { + if ($this->noIDs) + { + $db = JFactory::getDbo(); + $dbquery = $db->getQuery(true); + $dbquery->select($dbquery->qn('id')) + ->from($dbquery->qn('#__content')) + ->where('alias = ' . $dbquery->q($segment)) + ->where('catid = ' . $dbquery->q($query['id'])); + $db->setQuery($dbquery); + + return (int) $db->loadResult(); + } + + return (int) $segment; + } +} + +/** + * Content router functions + * + * These functions are proxys for the new router interface + * for old SEF extensions. + * + * @param array &$query An array of URL arguments + * + * @return array The URL arguments to use to assemble the subsequent URL. + * + * @deprecated 4.0 Use Class based routers instead + */ +function contentBuildRoute(&$query) +{ + $app = JFactory::getApplication(); + $router = new ContentRouter($app, $app->getMenu()); + + return $router->build($query); +} + +/** + * Parse the segments of a URL. + * + * This function is a proxy for the new router interface + * for old SEF extensions. + * + * @param array $segments The segments of the URL to parse. + * + * @return array The URL attributes to be used by the application. + * + * @since 3.3 + * @deprecated 4.0 Use Class based routers instead + */ +function contentParseRoute($segments) +{ + $app = JFactory::getApplication(); + $router = new ContentRouter($app, $app->getMenu()); + + return $router->parse($segments); +} diff --git a/Sites/pages/components/com_content/views/archive/tmpl/default.php b/Sites/pages/components/com_content/views/archive/tmpl/default.php new file mode 100644 index 00000000..b342b7ff --- /dev/null +++ b/Sites/pages/components/com_content/views/archive/tmpl/default.php @@ -0,0 +1,46 @@ + +
          +params->get('show_page_heading')) : ?> + + +
          +
          + +
          +
          + + loadTemplate('items'); ?> +
          +
          diff --git a/Sites/pages/components/com_content/views/archive/tmpl/default.xml b/Sites/pages/components/com_content/views/archive/tmpl/default.xml new file mode 100644 index 00000000..79adf17f --- /dev/null +++ b/Sites/pages/components/com_content/views/archive/tmpl/default.xml @@ -0,0 +1,299 @@ + + + + + + + + + + + +
          + + + +
          +
          + + + + + +
          + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + +
          + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + +
          +
          diff --git a/Sites/pages/components/com_content/views/archive/tmpl/default_items.php b/Sites/pages/components/com_content/views/archive/tmpl/default_items.php new file mode 100644 index 00000000..2d7ba46a --- /dev/null +++ b/Sites/pages/components/com_content/views/archive/tmpl/default_items.php @@ -0,0 +1,219 @@ +params; +?> + +
          + items as $i => $item) : ?> + params->get('info_block_position', 0); ?> +
          + + get('show_modify_date') || $params->get('show_publish_date') || $params->get('show_create_date') + || $params->get('show_hits') || $params->get('show_category') || $params->get('show_parent_category')); ?> + + + + + + event->beforeDisplayContent; ?> + get('show_intro')) : ?> +
          introtext, $params->get('introtext_limit')); ?>
          + + + + + + + event->afterDisplayContent; ?> +
          + +
          + diff --git a/Sites/pages/components/com_content/views/archive/view.html.php b/Sites/pages/components/com_content/views/archive/view.html.php new file mode 100644 index 00000000..ea25b9b2 --- /dev/null +++ b/Sites/pages/components/com_content/views/archive/view.html.php @@ -0,0 +1,207 @@ +get('State'); + $items = $this->get('Items'); + $pagination = $this->get('Pagination'); + + // Flag indicates to not add limitstart=0 to URL + $pagination->hideEmptyLimitstart = true; + + // Get the page/component configuration + $params = &$state->params; + + JPluginHelper::importPlugin('content'); + + foreach ($items as $item) + { + $item->catslug = $item->category_alias ? ($item->catid . ':' . $item->category_alias) : $item->catid; + $item->parent_slug = $item->parent_alias ? ($item->parent_id . ':' . $item->parent_alias) : $item->parent_id; + + // No link for ROOT category + if ($item->parent_alias === 'root') + { + $item->parent_slug = null; + } + + $item->event = new stdClass; + + $dispatcher = JEventDispatcher::getInstance(); + + // Old plugins: Ensure that text property is available + if (!isset($item->text)) + { + $item->text = $item->introtext; + } + + $dispatcher->trigger('onContentPrepare', array ('com_content.archive', &$item, &$item->params, 0)); + + // Old plugins: Use processed text as introtext + $item->introtext = $item->text; + + $results = $dispatcher->trigger('onContentAfterTitle', array('com_content.archive', &$item, &$item->params, 0)); + $item->event->afterDisplayTitle = trim(implode("\n", $results)); + + $results = $dispatcher->trigger('onContentBeforeDisplay', array('com_content.archive', &$item, &$item->params, 0)); + $item->event->beforeDisplayContent = trim(implode("\n", $results)); + + $results = $dispatcher->trigger('onContentAfterDisplay', array('com_content.archive', &$item, &$item->params, 0)); + $item->event->afterDisplayContent = trim(implode("\n", $results)); + } + + $form = new stdClass; + + // Month Field + $months = array( + '' => JText::_('COM_CONTENT_MONTH'), + '1' => JText::_('JANUARY_SHORT'), + '2' => JText::_('FEBRUARY_SHORT'), + '3' => JText::_('MARCH_SHORT'), + '4' => JText::_('APRIL_SHORT'), + '5' => JText::_('MAY_SHORT'), + '6' => JText::_('JUNE_SHORT'), + '7' => JText::_('JULY_SHORT'), + '8' => JText::_('AUGUST_SHORT'), + '9' => JText::_('SEPTEMBER_SHORT'), + '10' => JText::_('OCTOBER_SHORT'), + '11' => JText::_('NOVEMBER_SHORT'), + '12' => JText::_('DECEMBER_SHORT') + ); + $form->monthField = JHtml::_( + 'select.genericlist', + $months, + 'month', + array( + 'list.attr' => 'size="1" class="inputbox"', + 'list.select' => $state->get('filter.month'), + 'option.key' => null + ) + ); + + // Year Field + $this->years = $this->getModel()->getYears(); + $years = array(); + $years[] = JHtml::_('select.option', null, JText::_('JYEAR')); + + for ($i = 0, $iMax = count($this->years); $i < $iMax; $i++) + { + $years[] = JHtml::_('select.option', $this->years[$i], $this->years[$i]); + } + + $form->yearField = JHtml::_( + 'select.genericlist', + $years, + 'year', + array('list.attr' => 'size="1" class="inputbox"', 'list.select' => $state->get('filter.year')) + ); + $form->limitField = $pagination->getLimitBox(); + + // Escape strings for HTML output + $this->pageclass_sfx = htmlspecialchars($params->get('pageclass_sfx')); + + $this->filter = $state->get('list.filter'); + $this->form = &$form; + $this->items = &$items; + $this->params = &$params; + $this->user = &$user; + $this->pagination = &$pagination; + $this->pagination->setAdditionalUrlParam('month', $state->get('filter.month')); + $this->pagination->setAdditionalUrlParam('year', $state->get('filter.year')); + + $this->_prepareDocument(); + + parent::display($tpl); + } + + /** + * Prepares the document + * + * @return void + */ + protected function _prepareDocument() + { + $app = JFactory::getApplication(); + $menus = $app->getMenu(); + $title = null; + + // Because the application sets a default page title, + // we need to get it from the menu item itself + $menu = $menus->getActive(); + + if ($menu) + { + $this->params->def('page_heading', $this->params->get('page_title', $menu->title)); + } + else + { + $this->params->def('page_heading', JText::_('JGLOBAL_ARTICLES')); + } + + $title = $this->params->get('page_title', ''); + + if (empty($title)) + { + $title = $app->get('sitename'); + } + elseif ($app->get('sitename_pagetitles', 0) == 1) + { + $title = JText::sprintf('JPAGETITLE', $app->get('sitename'), $title); + } + elseif ($app->get('sitename_pagetitles', 0) == 2) + { + $title = JText::sprintf('JPAGETITLE', $title, $app->get('sitename')); + } + + $this->document->setTitle($title); + + if ($this->params->get('menu-meta_description')) + { + $this->document->setDescription($this->params->get('menu-meta_description')); + } + + if ($this->params->get('menu-meta_keywords')) + { + $this->document->setMetadata('keywords', $this->params->get('menu-meta_keywords')); + } + + if ($this->params->get('robots')) + { + $this->document->setMetadata('robots', $this->params->get('robots')); + } + } +} diff --git a/Sites/pages/components/com_content/views/article/tmpl/default.php b/Sites/pages/components/com_content/views/article/tmpl/default.php new file mode 100644 index 00000000..77c1b226 --- /dev/null +++ b/Sites/pages/components/com_content/views/article/tmpl/default.php @@ -0,0 +1,167 @@ +item->params; +$urls = json_decode($this->item->urls); +$canEdit = $params->get('access-edit'); +$user = JFactory::getUser(); +$info = $params->get('info_block_position', 0); + +// Check if associations are implemented. If they are, define the parameter. +$assocParam = (JLanguageAssociations::isEnabled() && $params->get('show_associations')); +JHtml::_('behavior.caption'); + +$currentDate = JFactory::getDate()->format('Y-m-d H:i:s'); +$isNotPublishedYet = $this->item->publish_up > $currentDate; +$isExpired = $this->item->publish_down < $currentDate && $this->item->publish_down !== JFactory::getDbo()->getNullDate(); + +?> +
          + + params->get('show_page_heading')) : ?> + + item->pagination) && $this->item->pagination && !$this->item->paginationposition && $this->item->paginationrelative) + { + echo $this->item->pagination; + } + ?> + + + get('show_modify_date') || $params->get('show_publish_date') || $params->get('show_create_date') + || $params->get('show_hits') || $params->get('show_category') || $params->get('show_parent_category') || $params->get('show_author') || $assocParam); ?> + + print) : ?> +
          + item, $params); ?> +
          +
          + + get('show_title')) : ?> + + + print) : ?> + get('show_print_icon') || $params->get('show_email_icon')) : ?> + $params, 'item' => $this->item, 'print' => false)); ?> + + + +
          + item, $params); ?> +
          + + + + + item->event->afterDisplayTitle; ?> + + + + $this->item, 'params' => $params, 'position' => 'above')); ?> + + + get('show_tags', 1) && !empty($this->item->tags->itemTags)) : ?> + item->tagLayout = new JLayoutFile('joomla.content.tags'); ?> + + item->tagLayout->render($this->item->tags->itemTags); ?> + + + + item->event->beforeDisplayContent; ?> + + urls_position) && ($urls->urls_position == '0')) || ($params->get('urls_position') == '0' && empty($urls->urls_position))) + || (empty($urls->urls_position) && (!$params->get('urls_position')))) : ?> + loadTemplate('links'); ?> + + get('access-view')) : ?> + item); ?> + item->pagination) && $this->item->pagination && !$this->item->paginationposition && !$this->item->paginationrelative) : + echo $this->item->pagination; + endif; + ?> + item->toc)) : + echo $this->item->toc; + endif; ?> +
          + item->text; ?> +
          + + + + + $this->item, 'params' => $params, 'position' => 'below')); ?> + + get('show_tags', 1) && !empty($this->item->tags->itemTags)) : ?> + item->tagLayout = new JLayoutFile('joomla.content.tags'); ?> + item->tagLayout->render($this->item->tags->itemTags); ?> + + + + item->pagination) && $this->item->pagination && $this->item->paginationposition && !$this->item->paginationrelative) : + echo $this->item->pagination; + ?> + + urls_position) && ($urls->urls_position == '1')) || ($params->get('urls_position') == '1'))) : ?> + loadTemplate('links'); ?> + + + get('show_noauth') == true && $user->get('guest')) : ?> + item); ?> + item->introtext); ?> + + get('show_readmore') && $this->item->fulltext != null) : ?> + getMenu(); ?> + getActive(); ?> + id; ?> + + setVar('return', base64_encode(ContentHelperRoute::getArticleRoute($this->item->slug, $this->item->catid, $this->item->language))); ?> +

          + + get('alternative_readmore', '') === '') : ?> + + + get('alternative_readmore'); ?> + get('show_readmore_title', 0) != 0) : ?> + item->title, $params->get('readmore_limit')); ?> + + + +

          + + + item->pagination) && $this->item->pagination && $this->item->paginationposition && $this->item->paginationrelative) : + echo $this->item->pagination; + ?> + + + item->event->afterDisplayContent; ?> +
          diff --git a/Sites/pages/components/com_content/views/article/tmpl/default.xml b/Sites/pages/components/com_content/views/article/tmpl/default.xml new file mode 100644 index 00000000..edc9f89a --- /dev/null +++ b/Sites/pages/components/com_content/views/article/tmpl/default.xml @@ -0,0 +1,325 @@ + + + + + + + + + + + +
          + + +
          +
          + + + + + +
          + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          +
          +
          diff --git a/Sites/pages/components/com_content/views/article/tmpl/default_links.php b/Sites/pages/components/com_content/views/article/tmpl/default_links.php new file mode 100644 index 00000000..ccb68444 --- /dev/null +++ b/Sites/pages/components/com_content/views/article/tmpl/default_links.php @@ -0,0 +1,79 @@ +item->urls); + +// Create shortcuts to some parameters. +$params = $this->item->params; +if ($urls && (!empty($urls->urla) || !empty($urls->urlb) || !empty($urls->urlc))) : +?> + + diff --git a/Sites/pages/components/com_content/views/article/view.html.php b/Sites/pages/components/com_content/views/article/view.html.php new file mode 100644 index 00000000..163b9ce2 --- /dev/null +++ b/Sites/pages/components/com_content/views/article/view.html.php @@ -0,0 +1,343 @@ +item = $this->get('Item'); + $this->print = $app->input->getBool('print'); + $this->state = $this->get('State'); + $this->user = $user; + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + JError::raiseWarning(500, implode("\n", $errors)); + + return false; + } + + // Create a shortcut for $item. + $item = $this->item; + $item->tagLayout = new JLayoutFile('joomla.content.tags'); + + // Add router helpers. + $item->slug = $item->alias ? ($item->id . ':' . $item->alias) : $item->id; + $item->catslug = $item->category_alias ? ($item->catid . ':' . $item->category_alias) : $item->catid; + $item->parent_slug = $item->parent_alias ? ($item->parent_id . ':' . $item->parent_alias) : $item->parent_id; + + // No link for ROOT category + if ($item->parent_alias === 'root') + { + $item->parent_slug = null; + } + + // TODO: Change based on shownoauth + $item->readmore_link = JRoute::_(ContentHelperRoute::getArticleRoute($item->slug, $item->catid, $item->language)); + + // Merge article params. If this is single-article view, menu params override article params + // Otherwise, article params override menu item params + $this->params = $this->state->get('params'); + $active = $app->getMenu()->getActive(); + $temp = clone $this->params; + + // Check to see which parameters should take priority + if ($active) + { + $currentLink = $active->link; + + // If the current view is the active item and an article view for this article, then the menu item params take priority + if (strpos($currentLink, 'view=article') && strpos($currentLink, '&id=' . (string) $item->id)) + { + // Load layout from active query (in case it is an alternative menu item) + if (isset($active->query['layout'])) + { + $this->setLayout($active->query['layout']); + } + // Check for alternative layout of article + elseif ($layout = $item->params->get('article_layout')) + { + $this->setLayout($layout); + } + + // $item->params are the article params, $temp are the menu item params + // Merge so that the menu item params take priority + $item->params->merge($temp); + } + else + { + // Current view is not a single article, so the article params take priority here + // Merge the menu item params with the article params so that the article params take priority + $temp->merge($item->params); + $item->params = $temp; + + // Check for alternative layouts (since we are not in a single-article menu item) + // Single-article menu item layout takes priority over alt layout for an article + if ($layout = $item->params->get('article_layout')) + { + $this->setLayout($layout); + } + } + } + else + { + // Merge so that article params take priority + $temp->merge($item->params); + $item->params = $temp; + + // Check for alternative layouts (since we are not in a single-article menu item) + // Single-article menu item layout takes priority over alt layout for an article + if ($layout = $item->params->get('article_layout')) + { + $this->setLayout($layout); + } + } + + $offset = $this->state->get('list.offset'); + + // Check the view access to the article (the model has already computed the values). + if ($item->params->get('access-view') == false && ($item->params->get('show_noauth', '0') == '0')) + { + $app->enqueueMessage(JText::_('JERROR_ALERTNOAUTHOR'), 'error'); + $app->setHeader('status', 403, true); + + return; + } + + /** + * Check for no 'access-view' and empty fulltext, + * - Redirect guest users to login + * - Deny access to logged users with 403 code + * NOTE: we do not recheck for no access-view + show_noauth disabled ... since it was checked above + */ + if ($item->params->get('access-view') == false && !strlen($item->fulltext)) + { + if ($this->user->get('guest')) + { + $return = base64_encode(JUri::getInstance()); + $login_url_with_return = JRoute::_('index.php?option=com_users&view=login&return=' . $return); + $app->enqueueMessage(JText::_('JERROR_ALERTNOAUTHOR'), 'notice'); + $app->redirect($login_url_with_return, 403); + } + else + { + $app->enqueueMessage(JText::_('JERROR_ALERTNOAUTHOR'), 'error'); + $app->setHeader('status', 403, true); + + return; + } + } + + /** + * NOTE: The following code (usually) sets the text to contain the fulltext, but it is the + * responsibility of the layout to check 'access-view' and only use "introtext" for guests + */ + if ($item->params->get('show_intro', '1') == '1') + { + $item->text = $item->introtext . ' ' . $item->fulltext; + } + elseif ($item->fulltext) + { + $item->text = $item->fulltext; + } + else + { + $item->text = $item->introtext; + } + + $item->tags = new JHelperTags; + $item->tags->getItemTags('com_content.article', $this->item->id); + + if ($item->params->get('show_associations')) + { + $item->associations = ContentHelperAssociation::displayAssociations($item->id); + } + + // Process the content plugins. + JPluginHelper::importPlugin('content'); + $dispatcher->trigger('onContentPrepare', array ('com_content.article', &$item, &$item->params, $offset)); + + $item->event = new stdClass; + $results = $dispatcher->trigger('onContentAfterTitle', array('com_content.article', &$item, &$item->params, $offset)); + $item->event->afterDisplayTitle = trim(implode("\n", $results)); + + $results = $dispatcher->trigger('onContentBeforeDisplay', array('com_content.article', &$item, &$item->params, $offset)); + $item->event->beforeDisplayContent = trim(implode("\n", $results)); + + $results = $dispatcher->trigger('onContentAfterDisplay', array('com_content.article', &$item, &$item->params, $offset)); + $item->event->afterDisplayContent = trim(implode("\n", $results)); + + // Escape strings for HTML output + $this->pageclass_sfx = htmlspecialchars($this->item->params->get('pageclass_sfx')); + + $this->_prepareDocument(); + + parent::display($tpl); + } + + /** + * Prepares the document. + * + * @return void + */ + protected function _prepareDocument() + { + $app = JFactory::getApplication(); + $menus = $app->getMenu(); + $pathway = $app->getPathway(); + $title = null; + + /** + * Because the application sets a default page title, + * we need to get it from the menu item itself + */ + $menu = $menus->getActive(); + + if ($menu) + { + $this->params->def('page_heading', $this->params->get('page_title', $menu->title)); + } + else + { + $this->params->def('page_heading', JText::_('JGLOBAL_ARTICLES')); + } + + $title = $this->params->get('page_title', ''); + + $id = (int) @$menu->query['id']; + + // If the menu item does not concern this article + if ($menu && (!isset($menu->query['option']) || $menu->query['option'] !== 'com_content' || $menu->query['view'] !== 'article' + || $id != $this->item->id)) + { + // If a browser page title is defined, use that, then fall back to the article title if set, then fall back to the page_title option + $title = $this->item->params->get('article_page_title', $this->item->title ?: $title); + + $path = array(array('title' => $this->item->title, 'link' => '')); + $category = JCategories::getInstance('Content')->get($this->item->catid); + + while ($category && (!isset($menu->query['option']) || $menu->query['option'] !== 'com_content' || $menu->query['view'] === 'article' + || $id != $category->id) && $category->id > 1) + { + $path[] = array('title' => $category->title, 'link' => ContentHelperRoute::getCategoryRoute($category->id)); + $category = $category->getParent(); + } + + $path = array_reverse($path); + + foreach ($path as $item) + { + $pathway->addItem($item['title'], $item['link']); + } + } + + // Check for empty title and add site name if param is set + if (empty($title)) + { + $title = $app->get('sitename'); + } + elseif ($app->get('sitename_pagetitles', 0) == 1) + { + $title = JText::sprintf('JPAGETITLE', $app->get('sitename'), $title); + } + elseif ($app->get('sitename_pagetitles', 0) == 2) + { + $title = JText::sprintf('JPAGETITLE', $title, $app->get('sitename')); + } + + if (empty($title)) + { + $title = $this->item->title; + } + + $this->document->setTitle($title); + + if ($this->item->metadesc) + { + $this->document->setDescription($this->item->metadesc); + } + elseif ($this->params->get('menu-meta_description')) + { + $this->document->setDescription($this->params->get('menu-meta_description')); + } + + if ($this->item->metakey) + { + $this->document->setMetadata('keywords', $this->item->metakey); + } + elseif ($this->params->get('menu-meta_keywords')) + { + $this->document->setMetadata('keywords', $this->params->get('menu-meta_keywords')); + } + + if ($this->params->get('robots')) + { + $this->document->setMetadata('robots', $this->params->get('robots')); + } + + if ($app->get('MetaAuthor') == '1') + { + $author = $this->item->created_by_alias ?: $this->item->author; + $this->document->setMetaData('author', $author); + } + + $mdata = $this->item->metadata->toArray(); + + foreach ($mdata as $k => $v) + { + if ($v) + { + $this->document->setMetadata($k, $v); + } + } + + // If there is a pagebreak heading or title, add it to the page title + if (!empty($this->item->page_title)) + { + $this->item->title = $this->item->title . ' - ' . $this->item->page_title; + $this->document->setTitle( + $this->item->page_title . ' - ' . JText::sprintf('PLG_CONTENT_PAGEBREAK_PAGE_NUM', $this->state->get('list.offset') + 1) + ); + } + + if ($this->print) + { + $this->document->setMetaData('robots', 'noindex, nofollow'); + } + } +} diff --git a/Sites/pages/components/com_content/views/categories/tmpl/default.php b/Sites/pages/components/com_content/views/categories/tmpl/default.php new file mode 100644 index 00000000..4ef5ef6b --- /dev/null +++ b/Sites/pages/components/com_content/views/categories/tmpl/default.php @@ -0,0 +1,42 @@ +addScriptDeclaration(" +jQuery(function($) { + $('.categories-list').find('[id^=category-btn-]').each(function(index, btn) { + var btn = $(btn); + btn.on('click', function() { + btn.find('span').toggleClass('icon-plus'); + btn.find('span').toggleClass('icon-minus'); + if (btn.attr('aria-label') === Joomla.JText._('JGLOBAL_EXPAND_CATEGORIES')) + { + btn.attr('aria-label', Joomla.JText._('JGLOBAL_COLLAPSE_CATEGORIES')); + } else { + btn.attr('aria-label', Joomla.JText._('JGLOBAL_EXPAND_CATEGORIES')); + } + }); + }); +});"); +?> +
          + loadTemplate('items'); + ?> +
          diff --git a/Sites/pages/components/com_content/views/categories/tmpl/default.xml b/Sites/pages/components/com_content/views/categories/tmpl/default.xml new file mode 100644 index 00000000..4d86270f --- /dev/null +++ b/Sites/pages/components/com_content/views/categories/tmpl/default.xml @@ -0,0 +1,770 @@ + + + + + + + + + + + +
          + +
          +
          + + + +
          + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + +
          + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          +
          + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + +
          + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + +
          + + + + + + + + + + + +
          + +
          + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          +
          + + + + + + + + + + +
          +
          +
          diff --git a/Sites/pages/components/com_content/views/categories/tmpl/default_items.php b/Sites/pages/components/com_content/views/categories/tmpl/default_items.php new file mode 100644 index 00000000..e84f5b27 --- /dev/null +++ b/Sites/pages/components/com_content/views/categories/tmpl/default_items.php @@ -0,0 +1,68 @@ +maxLevelcat != 0 && count($this->items[$this->parent->id]) > 0) : +?> + items[$this->parent->id] as $id => $item) : ?> + params->get('show_empty_categories_cat') || $item->numitems || count($item->getChildren())) : + if (!isset($this->items[$this->parent->id][$id + 1])) + { + $class = ' class="last"'; + } + ?> +
          > + + + params->get('show_description_image') && $item->getParams()->get('image')) : ?> + <?php echo htmlspecialchars($item->getParams()->get('image_alt'), ENT_COMPAT, 'UTF-8'); ?> + + params->get('show_subcat_desc_cat') == 1) : ?> + description) : ?> +
          + description, '', 'com_content.categories'); ?> +
          + + + + getChildren()) > 0 && $this->maxLevelcat > 1) : ?> +
          + items[$item->id] = $item->getChildren(); + $this->parent = $item; + $this->maxLevelcat--; + echo $this->loadTemplate('items'); + $this->parent = $item->getParent(); + $this->maxLevelcat++; + ?> +
          + +
          + + + diff --git a/Sites/pages/components/com_content/views/categories/view.html.php b/Sites/pages/components/com_content/views/categories/view.html.php new file mode 100644 index 00000000..fce1b447 --- /dev/null +++ b/Sites/pages/components/com_content/views/categories/view.html.php @@ -0,0 +1,32 @@ +category->text = $this->category->description; +$dispatcher->trigger('onContentPrepare', array($this->category->extension . '.categories', &$this->category, &$this->params, 0)); +$this->category->description = $this->category->text; + +$results = $dispatcher->trigger('onContentAfterTitle', array($this->category->extension . '.categories', &$this->category, &$this->params, 0)); +$afterDisplayTitle = trim(implode("\n", $results)); + +$results = $dispatcher->trigger('onContentBeforeDisplay', array($this->category->extension . '.categories', &$this->category, &$this->params, 0)); +$beforeDisplayContent = trim(implode("\n", $results)); + +$results = $dispatcher->trigger('onContentAfterDisplay', array($this->category->extension . '.categories', &$this->category, &$this->params, 0)); +$afterDisplayContent = trim(implode("\n", $results)); + +?> +
          + params->get('show_page_heading')) : ?> + + + + params->get('show_category_title', 1) or $this->params->get('page_subheading')) : ?> +

          escape($this->params->get('page_subheading')); ?> + params->get('show_category_title')) : ?> + category->title; ?> + +

          + + + + params->get('show_cat_tags', 1) && !empty($this->category->tags->itemTags)) : ?> + category->tagLayout = new JLayoutFile('joomla.content.tags'); ?> + category->tagLayout->render($this->category->tags->itemTags); ?> + + + params->get('show_description', 1) || $this->params->def('show_description_image', 1)) : ?> +
          + params->get('show_description_image') && $this->category->getParams()->get('image')) : ?> + <?php echo htmlspecialchars($this->category->getParams()->get('image_alt'), ENT_COMPAT, 'UTF-8'); ?> + + + params->get('show_description') && $this->category->description) : ?> + category->description, '', 'com_content.category'); ?> + + +
          + + + lead_items) && empty($this->link_items) && empty($this->intro_items)) : ?> + params->get('show_no_articles', 1)) : ?> +

          + + + + + lead_items)) : ?> +
          + lead_items as &$item) : ?> +
          + item = &$item; + echo $this->loadTemplate('item'); + ?> +
          + + +
          + + + intro_items); + $counter = 0; + ?> + + intro_items)) : ?> + intro_items as $key => &$item) : ?> + columns) + 1; ?> + + columns; ?> +
          + +
          +
          + item = &$item; + echo $this->loadTemplate('item'); + ?> +
          + + +
          + columns) or ($counter == $introcount)) : ?> +
          + + + + + link_items)) : ?> +
          + loadTemplate('links'); ?> +
          + + + maxLevel != 0 && !empty($this->children[$this->category->id])) : ?> +
          + params->get('show_category_heading_title_text', 1) == 1) : ?> +

          + + loadTemplate('children'); ?>
          + + params->def('show_pagination', 1) == 1 || ($this->params->get('show_pagination') == 2)) && ($this->pagination->get('pages.total') > 1)) : ?> + + +
          diff --git a/Sites/pages/components/com_content/views/category/tmpl/blog.xml b/Sites/pages/components/com_content/views/category/tmpl/blog.xml new file mode 100644 index 00000000..69c3ad64 --- /dev/null +++ b/Sites/pages/components/com_content/views/category/tmpl/blog.xml @@ -0,0 +1,711 @@ + + + + + + + + + + + +
          + + + +
          +
          + + + +
          + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + +
          + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + +
          + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + +
          + + + + + + + + + +
          +
          +
          diff --git a/Sites/pages/components/com_content/views/category/tmpl/blog_children.php b/Sites/pages/components/com_content/views/category/tmpl/blog_children.php new file mode 100644 index 00000000..483208eb --- /dev/null +++ b/Sites/pages/components/com_content/views/category/tmpl/blog_children.php @@ -0,0 +1,86 @@ +getAuthorisedViewLevels(); + +if ($this->maxLevel != 0 && count($this->children[$this->category->id]) > 0) : ?> + + children[$this->category->id] as $id => $child) : ?> + + access, $groups)) : ?> + params->get('show_empty_categories') || $child->numitems || count($child->getChildren())) : + if (!isset($this->children[$this->category->id][$id + 1])) : + $class = ' class="last"'; + endif; + ?> + > + + isRtl()) : ?> + + + + + + params->get('show_subcat_desc') == 1) : ?> + description) : ?> +
          + description, '', 'com_content.category'); ?> +
          + + + + maxLevel > 1 && count($child->getChildren()) > 0) : ?> +
          + children[$child->id] = $child->getChildren(); + $this->category = $child; + $this->maxLevel--; + echo $this->loadTemplate('children'); + $this->category = $child->getParent(); + $this->maxLevel++; + ?> +
          + +
      + + + + +item->params; +JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html'); +$canEdit = $this->item->params->get('access-edit'); +$info = $params->get('info_block_position', 0); + +// Check if associations are implemented. If they are, define the parameter. +$assocParam = (JLanguageAssociations::isEnabled() && $params->get('show_associations')); + +$currentDate = JFactory::getDate()->format('Y-m-d H:i:s'); +$isUnpublished = ($this->item->state == 0 || $this->item->publish_up > $currentDate) + || ($this->item->publish_down < $currentDate && $this->item->publish_down !== JFactory::getDbo()->getNullDate()); + +?> + +
      + + +item); ?> + +get('show_print_icon') || $params->get('show_email_icon')) : ?> + $params, 'item' => $this->item, 'print' => false)); ?> + + + +get('show_modify_date') || $params->get('show_publish_date') || $params->get('show_create_date') + || $params->get('show_hits') || $params->get('show_category') || $params->get('show_parent_category') || $params->get('show_author') || $assocParam); ?> + + + + $this->item, 'params' => $params, 'position' => 'above')); ?> + +get('show_tags', 1) && !empty($this->item->tags->itemTags)) : ?> + item->tags->itemTags); ?> + + +item); ?> + +get('show_intro')) : ?> + + item->event->afterDisplayTitle; ?> + + + +item->event->beforeDisplayContent; ?> + +item->introtext; ?> + + + + + $this->item, 'params' => $params, 'position' => 'below')); ?> + + get('show_tags', 1) && !empty($this->item->tags->itemTags)) : ?> + item->tags->itemTags); ?> + + + +get('show_readmore') && $this->item->readmore) : + if ($params->get('access-view')) : + $link = JRoute::_(ContentHelperRoute::getArticleRoute($this->item->slug, $this->item->catid, $this->item->language)); + else : + $menu = JFactory::getApplication()->getMenu(); + $active = $menu->getActive(); + $itemId = $active->id; + $link = new JUri(JRoute::_('index.php?option=com_users&view=login&Itemid=' . $itemId, false)); + $link->setVar('return', base64_encode(ContentHelperRoute::getArticleRoute($this->item->slug, $this->item->catid, $this->item->language))); + endif; ?> + + $this->item, 'params' => $params, 'link' => $link)); ?> + + + + +
      + + + +item->event->afterDisplayContent; ?> diff --git a/Sites/pages/components/com_content/views/category/tmpl/blog_links.php b/Sites/pages/components/com_content/views/category/tmpl/blog_links.php new file mode 100644 index 00000000..772a1f75 --- /dev/null +++ b/Sites/pages/components/com_content/views/category/tmpl/blog_links.php @@ -0,0 +1,20 @@ + + + diff --git a/Sites/pages/components/com_content/views/category/tmpl/default.php b/Sites/pages/components/com_content/views/category/tmpl/default.php new file mode 100644 index 00000000..f9235d1e --- /dev/null +++ b/Sites/pages/components/com_content/views/category/tmpl/default.php @@ -0,0 +1,23 @@ + +
      + +subtemplatename = 'articles'; +echo JLayoutHelper::render('joomla.content.category_default', $this); +?> + +
      diff --git a/Sites/pages/components/com_content/views/category/tmpl/default.xml b/Sites/pages/components/com_content/views/category/tmpl/default.xml new file mode 100644 index 00000000..5026fe92 --- /dev/null +++ b/Sites/pages/components/com_content/views/category/tmpl/default.xml @@ -0,0 +1,703 @@ + + + + + + + + + + + +
      + + + +
      +
      + + + +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      +
      + + + + + + + + + + +
      +
      +
      diff --git a/Sites/pages/components/com_content/views/category/tmpl/default_articles.php b/Sites/pages/components/com_content/views/category/tmpl/default_articles.php new file mode 100644 index 00000000..751d8a52 --- /dev/null +++ b/Sites/pages/components/com_content/views/category/tmpl/default_articles.php @@ -0,0 +1,307 @@ +items); +$listOrder = $this->escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$langFilter = false; + +// Tags filtering based on language filter +if (($this->params->get('filter_field') === 'tag') && (Multilanguage::isEnabled())) +{ + $tagfilter = ComponentHelper::getParams('com_tags')->get('tag_list_language_filter'); + + switch ($tagfilter) + { + case 'current_language' : + $langFilter = JFactory::getApplication()->getLanguage()->getTag(); + break; + + case 'all' : + $langFilter = false; + break; + + default : + $langFilter = $tagfilter; + } +} + +// Check for at least one editable article +$isEditable = false; + +if (!empty($this->items)) +{ + foreach ($this->items as $article) + { + if ($article->params->get('access-edit')) + { + $isEditable = true; + break; + } + } +} + +// For B/C we also add the css classes inline. This will be removed in 4.0. +JFactory::getDocument()->addStyleDeclaration(' +.hide { display: none; } +.table-noheader { border-collapse: collapse; } +.table-noheader thead { display: none; } +'); + +$tableClass = $this->params->get('show_headings') != 1 ? ' table-noheader' : ''; + +$nullDate = JFactory::getDbo()->getNullDate(); +$currentDate = JFactory::getDate()->format('Y-m-d H:i:s'); + +?> +
      +params->get('filter_field') !== 'hide' || $this->params->get('show_pagination_limit')) : ?> +
      + + params->get('filter_field') !== 'hide') : ?> +
      + params->get('filter_field') === 'tag') : ?> + + params->get('filter_field') === 'month') : ?> + + + + + +
      + + params->get('show_pagination_limit')) : ?> +
      + + pagination->getLimitBox(); ?> +
      + + + + + + +
      + +
      +
      + +
      +
      + + + +items)) : ?> + params->get('show_no_articles', 1)) : ?> +

      + + + + + + + + params->get('list_show_date')) : ?> + + + params->get('list_show_author')) : ?> + + + params->get('list_show_hits')) : ?> + + + params->get('list_show_votes', 0) && $this->vote) : ?> + + + params->get('list_show_ratings', 0) && $this->vote) : ?> + + + + + + + + + items as $i => $article) : ?> + items[$i]->state == 0) : ?> + + + + + + params->get('list_show_date')) : ?> + + + params->get('list_show_author', 1)) : ?> + + + params->get('list_show_hits', 1)) : ?> + + + params->get('list_show_votes', 0) && $this->vote) : ?> + + + params->get('list_show_ratings', 0) && $this->vote) : ?> + + + + + + + + +
      category->title); ?>
      + + + + + + + + + + + + + + + + + +
      + access, $this->user->getAuthorisedViewLevels())) : ?> + + escape($article->title); ?> + + params->get('show_associations')) : ?> + id); ?> + + params->get('flags', 1) && $association['language']->image) : ?> + image . '.gif', $association['language']->title_native, array('title' => $association['language']->title_native), true); ?> +    + + sef; ?> +  sef); ?>  + + + + + escape($article->title) . ' : '; + $menu = JFactory::getApplication()->getMenu(); + $active = $menu->getActive(); + $itemId = $active->id; + $link = new JUri(JRoute::_('index.php?option=com_users&view=login&Itemid=' . $itemId, false)); + $link->setVar('return', base64_encode(ContentHelperRoute::getArticleRoute($article->slug, $article->catid, $article->language))); + ?> + + + + params->get('show_associations')) : ?> + id); ?> + + params->get('flags', 1)) : ?> + image . '.gif', $association['language']->title_native, array('title' => $association['language']->title_native), true); ?> +    + + sef; ?> +  sef); ?>  + + + + + state == 0) : ?> + + + + + publish_up > $currentDate) : ?> + + + + + publish_down < $currentDate && $article->publish_down !== $nullDate) : ?> + + + + + + displayDate, + $this->escape($this->params->get('date_format', JText::_('DATE_FORMAT_LC3'))) + ); ?> + + author) || !empty($article->created_by_alias)) : ?> + author ?> + created_by_alias ?: $author; ?> + contact_link) && $this->params->get('link_author') == true) : ?> + contact_link, $author)); ?> + + + + + + + hits); ?> + + + + rating_count); ?> + + + + rating); ?> + + + params->get('access-edit')) : ?> + params); ?> + +
      + + + +category->getParams()->get('access-create')) : ?> + category, $this->category->params); ?> + + + +items)) : ?> + params->def('show_pagination', 2) == 1 || ($this->params->get('show_pagination') == 2)) && ($this->pagination->pagesTotal > 1)) : ?> + + + +
      diff --git a/Sites/pages/components/com_content/views/category/tmpl/default_children.php b/Sites/pages/components/com_content/views/category/tmpl/default_children.php new file mode 100644 index 00000000..7932e557 --- /dev/null +++ b/Sites/pages/components/com_content/views/category/tmpl/default_children.php @@ -0,0 +1,88 @@ +getAuthorisedViewLevels(); +?> + +children[$this->category->id]) > 0) : ?> + + children[$this->category->id] as $id => $child) : ?> + + access, $groups)) : ?> + params->get('show_empty_categories') || $child->getNumItems(true) || count($child->getChildren())) : + if (!isset($this->children[$this->category->id][$id + 1])) : + $class = ' class="last"'; + endif; + ?> + + > + + isRtl()) : ?> + + + + + + params->get('show_subcat_desc') == 1) : ?> + description) : ?> +
      + description, '', 'com_content.category'); ?> +
      + + + + getChildren()) > 0 && $this->maxLevel > 1) : ?> +
      + children[$child->id] = $child->getChildren(); + $this->category = $child; + $this->maxLevel--; + echo $this->loadTemplate('children'); + $this->category = $child->getParent(); + $this->maxLevel++; + ?> +
      + +
      + + + + + diff --git a/Sites/pages/components/com_content/views/category/view.feed.php b/Sites/pages/components/com_content/views/category/view.feed.php new file mode 100644 index 00000000..ac75bca2 --- /dev/null +++ b/Sites/pages/components/com_content/views/category/view.feed.php @@ -0,0 +1,71 @@ +getParams(); + $item->description = ''; + $obj = json_decode($item->images); + $introImage = isset($obj->{'image_intro'}) ? $obj->{'image_intro'} : ''; + + if (isset($introImage) && ($introImage != '')) + { + $image = preg_match('/http/', $introImage) ? $introImage : JURI::root() . $introImage; + $item->description = '

      '; + } + + $item->description .= ($params->get('feed_summary', 0) ? $item->introtext . $item->fulltext : $item->introtext); + + // Add readmore link to description if introtext is shown, show_readmore is true and fulltext exists + if (!$item->params->get('feed_summary', 0) && $item->params->get('feed_show_readmore', 0) && $item->fulltext) + { + // Compute the article slug + $item->slug = $item->alias ? ($item->id . ':' . $item->alias) : $item->id; + + // URL link to article + $link = JRoute::_( + ContentHelperRoute::getArticleRoute($item->slug, $item->catid, $item->language), + true, + $app->get('force_ssl') == 2 ? \JRoute::TLS_FORCE : \JRoute::TLS_IGNORE, + true + ); + + $item->description .= '

      ' . JText::_('COM_CONTENT_FEED_READMORE') . '

      '; + } + + $item->author = $item->created_by_alias ?: $item->author; + } +} diff --git a/Sites/pages/components/com_content/views/category/view.html.php b/Sites/pages/components/com_content/views/category/view.html.php new file mode 100644 index 00000000..ecd5f320 --- /dev/null +++ b/Sites/pages/components/com_content/views/category/view.html.php @@ -0,0 +1,287 @@ +pagination->hideEmptyLimitstart = true; + + // Prepare the data + // Get the metrics for the structural page layout. + $params = $this->params; + $numLeading = $params->def('num_leading_articles', 1); + $numIntro = $params->def('num_intro_articles', 4); + $numLinks = $params->def('num_links', 4); + $this->vote = PluginHelper::isEnabled('content', 'vote'); + + PluginHelper::importPlugin('content'); + $dispatcher = JEventDispatcher::getInstance(); + + // Compute the article slugs and prepare introtext (runs content plugins). + foreach ($this->items as $item) + { + $item->slug = $item->alias ? ($item->id . ':' . $item->alias) : $item->id; + + $item->parent_slug = $item->parent_alias ? ($item->parent_id . ':' . $item->parent_alias) : $item->parent_id; + + // No link for ROOT category + if ($item->parent_alias === 'root') + { + $item->parent_slug = null; + } + + $item->catslug = $item->category_alias ? ($item->catid . ':' . $item->category_alias) : $item->catid; + $item->event = new stdClass; + + // Old plugins: Ensure that text property is available + if (!isset($item->text)) + { + $item->text = $item->introtext; + } + + $dispatcher->trigger('onContentPrepare', array ('com_content.category', &$item, &$item->params, 0)); + + // Old plugins: Use processed text as introtext + $item->introtext = $item->text; + + $results = $dispatcher->trigger('onContentAfterTitle', array('com_content.category', &$item, &$item->params, 0)); + $item->event->afterDisplayTitle = trim(implode("\n", $results)); + + $results = $dispatcher->trigger('onContentBeforeDisplay', array('com_content.category', &$item, &$item->params, 0)); + $item->event->beforeDisplayContent = trim(implode("\n", $results)); + + $results = $dispatcher->trigger('onContentAfterDisplay', array('com_content.category', &$item, &$item->params, 0)); + $item->event->afterDisplayContent = trim(implode("\n", $results)); + } + + // For blog layouts, preprocess the breakdown of leading, intro and linked articles. + // This makes it much easier for the designer to just interrogate the arrays. + if ($params->get('layout_type') === 'blog' || $this->getLayout() === 'blog') + { + foreach ($this->items as $i => $item) + { + if ($i < $numLeading) + { + $this->lead_items[] = $item; + } + + elseif ($i >= $numLeading && $i < $numLeading + $numIntro) + { + $this->intro_items[] = $item; + } + + elseif ($i < $numLeading + $numIntro + $numLinks) + { + $this->link_items[] = $item; + } + else + { + continue; + } + } + + $this->columns = max(1, $params->def('num_columns', 1)); + + $order = $params->def('multi_column_order', 1); + + if ($order == 0 && $this->columns > 1) + { + // Call order down helper + $this->intro_items = ContentHelperQuery::orderDownColumns($this->intro_items, $this->columns); + } + } + + // Because the application sets a default page title, + // we need to get it from the menu item itself + $app = Factory::getApplication(); + $active = $app->getMenu()->getActive(); + + if ($active + && $active->component == 'com_content' + && isset($active->query['view'], $active->query['id']) + && $active->query['view'] == 'category' + && $active->query['id'] == $this->category->id) + { + $this->params->def('page_heading', $this->params->get('page_title', $active->title)); + $title = $this->params->get('page_title', $active->title); + } + else + { + $this->params->def('page_heading', $this->category->title); + $title = $this->category->title; + $this->params->set('page_title', $title); + } + + // Check for empty title and add site name if param is set + if (empty($title)) + { + $title = $app->get('sitename'); + } + elseif ($app->get('sitename_pagetitles', 0) == 1) + { + $title = JText::sprintf('JPAGETITLE', $app->get('sitename'), $title); + } + elseif ($app->get('sitename_pagetitles', 0) == 2) + { + $title = JText::sprintf('JPAGETITLE', $title, $app->get('sitename')); + } + + if (empty($title)) + { + $title = $this->category->title; + } + + $this->document->setTitle($title); + + if ($this->category->metadesc) + { + $this->document->setDescription($this->category->metadesc); + } + elseif ($this->params->get('menu-meta_description')) + { + $this->document->setDescription($this->params->get('menu-meta_description')); + } + + if ($this->category->metakey) + { + $this->document->setMetadata('keywords', $this->category->metakey); + } + elseif ($this->params->get('menu-meta_keywords')) + { + $this->document->setMetadata('keywords', $this->params->get('menu-meta_keywords')); + } + + if ($this->params->get('robots')) + { + $this->document->setMetadata('robots', $this->params->get('robots')); + } + + if (!is_object($this->category->metadata)) + { + $this->category->metadata = new Registry($this->category->metadata); + } + + if (($app->get('MetaAuthor') == '1') && $this->category->get('author', '')) + { + $this->document->setMetaData('author', $this->category->get('author', '')); + } + + $mdata = $this->category->metadata->toArray(); + + foreach ($mdata as $k => $v) + { + if ($v) + { + $this->document->setMetadata($k, $v); + } + } + + return parent::display($tpl); + } + + /** + * Prepares the document + * + * @return void + */ + protected function prepareDocument() + { + parent::prepareDocument(); + $menu = $this->menu; + $id = (int) @$menu->query['id']; + + if ($menu && (!isset($menu->query['option']) || $menu->query['option'] !== 'com_content' || $menu->query['view'] === 'article' + || $id != $this->category->id)) + { + $path = array(array('title' => $this->category->title, 'link' => '')); + $category = $this->category->getParent(); + + while ((!isset($menu->query['option']) || $menu->query['option'] !== 'com_content' || $menu->query['view'] === 'article' + || $id != $category->id) && $category->id > 1) + { + $path[] = array('title' => $category->title, 'link' => ContentHelperRoute::getCategoryRoute($category->id)); + $category = $category->getParent(); + } + + $path = array_reverse($path); + + foreach ($path as $item) + { + $this->pathway->addItem($item['title'], $item['link']); + } + } + + parent::addFeed(); + } +} diff --git a/Sites/pages/components/com_content/views/featured/tmpl/default.php b/Sites/pages/components/com_content/views/featured/tmpl/default.php new file mode 100644 index 00000000..70e8cac1 --- /dev/null +++ b/Sites/pages/components/com_content/views/featured/tmpl/default.php @@ -0,0 +1,100 @@ + +
      +params->get('show_page_heading') != 0) : ?> + + +params->get('page_subheading')) : ?> +

      + escape($this->params->get('page_subheading')); ?> +

      + + +lead_items)) : ?> +
      + lead_items as &$item) : ?> +
      + item = &$item; + echo $this->loadTemplate('item'); + ?> +
      + + +
      + +intro_items); + $counter = 0; +?> +intro_items)) : ?> + intro_items as $key => &$item) : ?> + + columns) + 1; + $row = $counter / $this->columns; + + if ($rowcount === 1) : ?> + +
      + +
      + item = &$item; + echo $this->loadTemplate('item'); + ?> +
      + + + columns) or ($counter == $introcount)) : ?> + +
      + + + + + +link_items)) : ?> +
      + loadTemplate('links'); ?> +
      + + +params->def('show_pagination', 2) == 1 || ($this->params->get('show_pagination') == 2 && $this->pagination->pagesTotal > 1)) : ?> + + + +
      diff --git a/Sites/pages/components/com_content/views/featured/tmpl/default.xml b/Sites/pages/components/com_content/views/featured/tmpl/default.xml new file mode 100644 index 00000000..790a8666 --- /dev/null +++ b/Sites/pages/components/com_content/views/featured/tmpl/default.xml @@ -0,0 +1,523 @@ + + + + + + + + + + + +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + +
      + + + + + + + + + +
      +
      +
      diff --git a/Sites/pages/components/com_content/views/featured/tmpl/default_item.php b/Sites/pages/components/com_content/views/featured/tmpl/default_item.php new file mode 100644 index 00000000..c021f9b8 --- /dev/null +++ b/Sites/pages/components/com_content/views/featured/tmpl/default_item.php @@ -0,0 +1,108 @@ +item->params; +$canEdit = $this->item->params->get('access-edit'); +$info = $this->item->params->get('info_block_position', 0); + +// Check if associations are implemented. If they are, define the parameter. +$assocParam = (JLanguageAssociations::isEnabled() && $params->get('show_associations')); + +$currentDate = JFactory::getDate()->format('Y-m-d H:i:s'); +$isExpired = $this->item->publish_down < $currentDate && $this->item->publish_down !== JFactory::getDbo()->getNullDate(); +$isNotPublishedYet = $this->item->publish_up > $currentDate; +$isUnpublished = $this->item->state == 0 || $isNotPublishedYet || $isExpired; + +?> + +
      + + +get('show_title')) : ?> +

      + get('link_titles') && $params->get('access-view')) : ?> + + + escape($this->item->title); ?> + +

      + + +item->state == 0) : ?> + + + + + + + + + +get('show_print_icon') || $params->get('show_email_icon')) : ?> + $params, 'item' => $this->item, 'print' => false)); ?> + + + +item->event->afterDisplayTitle; ?> + + +get('show_modify_date') || $params->get('show_publish_date') || $params->get('show_create_date') + || $params->get('show_hits') || $params->get('show_category') || $params->get('show_parent_category') || $params->get('show_author') || $assocParam); ?> + + + + $this->item, 'params' => $params, 'position' => 'above')); ?> + +get('show_tags', 1) && !empty($this->item->tags->itemTags)) : ?> + item->tags->itemTags); ?> + + +item); ?> + + +item->event->beforeDisplayContent; ?> + +item->introtext; ?> + + + + + $this->item, 'params' => $params, 'position' => 'below')); ?> + + get('show_tags', 1) && !empty($this->item->tags->itemTags)) : ?> + item->tags->itemTags); ?> + + + +get('show_readmore') && $this->item->readmore) : + if ($params->get('access-view')) : + $link = JRoute::_(ContentHelperRoute::getArticleRoute($this->item->slug, $this->item->catid, $this->item->language)); + else : + $menu = JFactory::getApplication()->getMenu(); + $active = $menu->getActive(); + $itemId = $active->id; + $link = new JUri(JRoute::_('index.php?option=com_users&view=login&Itemid=' . $itemId, false)); + $link->setVar('return', base64_encode(ContentHelperRoute::getArticleRoute($this->item->slug, $this->item->catid, $this->item->language))); + endif; ?> + + $this->item, 'params' => $params, 'link' => $link)); ?> + + + + +
      + + + +item->event->afterDisplayContent; ?> diff --git a/Sites/pages/components/com_content/views/featured/tmpl/default_links.php b/Sites/pages/components/com_content/views/featured/tmpl/default_links.php new file mode 100644 index 00000000..b396de46 --- /dev/null +++ b/Sites/pages/components/com_content/views/featured/tmpl/default_links.php @@ -0,0 +1,19 @@ + + diff --git a/Sites/pages/components/com_content/views/featured/view.feed.php b/Sites/pages/components/com_content/views/featured/view.feed.php new file mode 100644 index 00000000..ea09ccbd --- /dev/null +++ b/Sites/pages/components/com_content/views/featured/view.feed.php @@ -0,0 +1,110 @@ +getParams(); + $feedEmail = $app->get('feed_email', 'none'); + $siteEmail = $app->get('mailfrom'); + $doc->link = JRoute::_('index.php?option=com_content&view=featured'); + + // Get some data from the model + $app->input->set('limit', $app->get('feed_limit')); + $categories = JCategories::getInstance('Content'); + $rows = $this->get('Items'); + + foreach ($rows as $row) + { + // Strip html from feed item title + $title = $this->escape($row->title); + $title = html_entity_decode($title, ENT_COMPAT, 'UTF-8'); + + // Compute the article slug + $row->slug = $row->alias ? ($row->id . ':' . $row->alias) : $row->id; + + // URL link to article + $link = ContentHelperRoute::getArticleRoute($row->slug, $row->catid, $row->language); + + $description = ''; + $obj = json_decode($row->images); + $introImage = isset($obj->{'image_intro'}) ? $obj->{'image_intro'} : ''; + + if (isset($introImage) && ($introImage != '')) + { + $image = preg_match('/http/', $introImage) ? $introImage : JURI::root() . $introImage; + $description = '

      '; + } + + $description .= ($params->get('feed_summary', 0) ? $row->introtext . $row->fulltext : $row->introtext); + $author = $row->created_by_alias ?: $row->author; + + // Load individual item creator class + $item = new JFeedItem; + $item->title = $title; + $item->link = \JRoute::_($link); + $item->date = $row->publish_up; + $item->category = array(); + + // All featured articles are categorized as "Featured" + $item->category[] = JText::_('JFEATURED'); + + for ($item_category = $categories->get($row->catid); $item_category !== null; $item_category = $item_category->getParent()) + { + // Only add non-root categories + if ($item_category->id > 1) + { + $item->category[] = $item_category->title; + } + } + + $item->author = $author; + + if ($feedEmail === 'site') + { + $item->authorEmail = $siteEmail; + } + elseif ($feedEmail === 'author') + { + $item->authorEmail = $row->author_email; + } + + // Add readmore link to description if introtext is shown, show_readmore is true and fulltext exists + if (!$params->get('feed_summary', 0) && $params->get('feed_show_readmore', 0) && $row->fulltext) + { + $link = \JRoute::_($link, true, $app->get('force_ssl') == 2 ? \JRoute::TLS_FORCE : \JRoute::TLS_IGNORE, true); + $description .= '

      ' . JText::_('COM_CONTENT_FEED_READMORE') . '

      '; + } + + // Load item description and add div + $item->description = '
      ' . $description . '
      '; + + // Loads item info into rss array + $doc->addItem($item); + } + } +} diff --git a/Sites/pages/components/com_content/views/featured/view.html.php b/Sites/pages/components/com_content/views/featured/view.html.php new file mode 100644 index 00000000..fb6fabf4 --- /dev/null +++ b/Sites/pages/components/com_content/views/featured/view.html.php @@ -0,0 +1,233 @@ +get('State'); + $items = $this->get('Items'); + $pagination = $this->get('Pagination'); + + // Flag indicates to not add limitstart=0 to URL + $pagination->hideEmptyLimitstart = true; + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + JError::raiseWarning(500, implode("\n", $errors)); + + return false; + } + + $params = &$state->params; + + // PREPARE THE DATA + + // Get the metrics for the structural page layout. + $numLeading = (int) $params->def('num_leading_articles', 1); + $numIntro = (int) $params->def('num_intro_articles', 4); + + JPluginHelper::importPlugin('content'); + + // Compute the article slugs and prepare introtext (runs content plugins). + foreach ($items as &$item) + { + $item->slug = $item->alias ? ($item->id . ':' . $item->alias) : $item->id; + $item->catslug = $item->category_alias ? ($item->catid . ':' . $item->category_alias) : $item->catid; + $item->parent_slug = $item->parent_alias ? ($item->parent_id . ':' . $item->parent_alias) : $item->parent_id; + + // No link for ROOT category + if ($item->parent_alias === 'root') + { + $item->parent_slug = null; + } + + $item->event = new stdClass; + $dispatcher = JEventDispatcher::getInstance(); + + // Old plugins: Ensure that text property is available + if (!isset($item->text)) + { + $item->text = $item->introtext; + } + + $dispatcher->trigger('onContentPrepare', array ('com_content.featured', &$item, &$item->params, 0)); + + // Old plugins: Use processed text as introtext + $item->introtext = $item->text; + + $results = $dispatcher->trigger('onContentAfterTitle', array('com_content.featured', &$item, &$item->params, 0)); + $item->event->afterDisplayTitle = trim(implode("\n", $results)); + + $results = $dispatcher->trigger('onContentBeforeDisplay', array('com_content.featured', &$item, &$item->params, 0)); + $item->event->beforeDisplayContent = trim(implode("\n", $results)); + + $results = $dispatcher->trigger('onContentAfterDisplay', array('com_content.featured', &$item, &$item->params, 0)); + $item->event->afterDisplayContent = trim(implode("\n", $results)); + } + + // Preprocess the breakdown of leading, intro and linked articles. + // This makes it much easier for the designer to just interogate the arrays. + $max = count($items); + + // The first group is the leading articles. + $limit = $numLeading; + + for ($i = 0; $i < $limit && $i < $max; $i++) + { + $this->lead_items[$i] = &$items[$i]; + } + + // The second group is the intro articles. + $limit = $numLeading + $numIntro; + + // Order articles across, then down (or single column mode) + for ($i = $numLeading; $i < $limit && $i < $max; $i++) + { + $this->intro_items[$i] = &$items[$i]; + } + + $this->columns = max(1, $params->def('num_columns', 1)); + $order = $params->def('multi_column_order', 1); + + if ($order == 0 && $this->columns > 1) + { + // Call order down helper + $this->intro_items = ContentHelperQuery::orderDownColumns($this->intro_items, $this->columns); + } + + // The remainder are the links. + for ($i = $numLeading + $numIntro; $i < $max; $i++) + { + $this->link_items[$i] = &$items[$i]; + } + + // Escape strings for HTML output + $this->pageclass_sfx = htmlspecialchars($params->get('pageclass_sfx')); + + $this->params = &$params; + $this->items = &$items; + $this->pagination = &$pagination; + $this->user = &$user; + $this->db = JFactory::getDbo(); + + $this->_prepareDocument(); + + parent::display($tpl); + } + + /** + * Prepares the document. + * + * @return void + */ + protected function _prepareDocument() + { + $app = JFactory::getApplication(); + $menus = $app->getMenu(); + $title = null; + + // Because the application sets a default page title, + // we need to get it from the menu item itself + $menu = $menus->getActive(); + + if ($menu) + { + $this->params->def('page_heading', $this->params->get('page_title', $menu->title)); + } + else + { + $this->params->def('page_heading', JText::_('JGLOBAL_ARTICLES')); + } + + $title = $this->params->get('page_title', ''); + + if (empty($title)) + { + $title = $app->get('sitename'); + } + elseif ($app->get('sitename_pagetitles', 0) == 1) + { + $title = JText::sprintf('JPAGETITLE', $app->get('sitename'), $title); + } + elseif ($app->get('sitename_pagetitles', 0) == 2) + { + $title = JText::sprintf('JPAGETITLE', $title, $app->get('sitename')); + } + + $this->document->setTitle($title); + + if ($this->params->get('menu-meta_description')) + { + $this->document->setDescription($this->params->get('menu-meta_description')); + } + + if ($this->params->get('menu-meta_keywords')) + { + $this->document->setMetadata('keywords', $this->params->get('menu-meta_keywords')); + } + + if ($this->params->get('robots')) + { + $this->document->setMetadata('robots', $this->params->get('robots')); + } + + // Add feed links + if ($this->params->get('show_feed_link', 1)) + { + $link = '&format=feed&limitstart='; + $attribs = array('type' => 'application/rss+xml', 'title' => 'RSS 2.0'); + $this->document->addHeadLink(JRoute::_($link . '&type=rss'), 'alternate', 'rel', $attribs); + $attribs = array('type' => 'application/atom+xml', 'title' => 'Atom 1.0'); + $this->document->addHeadLink(JRoute::_($link . '&type=atom'), 'alternate', 'rel', $attribs); + } + } +} diff --git a/Sites/pages/components/com_content/views/form/tmpl/edit.php b/Sites/pages/components/com_content/views/form/tmpl/edit.php new file mode 100644 index 00000000..074d6983 --- /dev/null +++ b/Sites/pages/components/com_content/views/form/tmpl/edit.php @@ -0,0 +1,171 @@ + 0)); +JHtml::_('formbehavior.chosen', '#jform_tags', null, array('placeholder_text_multiple' => JText::_('JGLOBAL_TYPE_OR_SELECT_SOME_TAGS'))); +JHtml::_('formbehavior.chosen', 'select'); +$this->tab_name = 'com-content-form'; +$this->ignore_fieldsets = array('image-intro', 'image-full', 'jmetadata', 'item_associations'); + +// Create shortcut to parameters. +$params = $this->state->get('params'); + +// This checks if the editor config options have ever been saved. If they haven't they will fall back to the original settings. +$editoroptions = isset($params->show_publishing_options); + +if (!$editoroptions) +{ + $params->show_urls_images_frontend = '0'; +} + +JFactory::getDocument()->addScriptDeclaration(" + Joomla.submitbutton = function(task) + { + if (task == 'article.cancel' || document.formvalidator.isValid(document.getElementById('adminForm'))) + { + " . $this->form->getField('articletext')->save() . " + Joomla.submitform(task); + } + } +"); +?> +
      + get('show_page_heading')) : ?> + + + +
      +
      + tab_name, array('active' => 'editor')); ?> + + tab_name, 'editor', JText::_('COM_CONTENT_ARTICLE_CONTENT')); ?> + form->renderField('title'); ?> + + item->id)) : ?> + form->renderField('alias'); ?> + + + form->getInput('articletext'); ?> + + captchaEnabled) : ?> + form->renderField('captcha'); ?> + + + + get('show_urls_images_frontend')) : ?> + tab_name, 'images', JText::_('COM_CONTENT_IMAGES_AND_URLS')); ?> + form->renderField('image_intro', 'images'); ?> + form->renderField('image_intro_alt', 'images'); ?> + form->renderField('image_intro_caption', 'images'); ?> + form->renderField('float_intro', 'images'); ?> + form->renderField('image_fulltext', 'images'); ?> + form->renderField('image_fulltext_alt', 'images'); ?> + form->renderField('image_fulltext_caption', 'images'); ?> + form->renderField('float_fulltext', 'images'); ?> + form->renderField('urla', 'urls'); ?> + form->renderField('urlatext', 'urls'); ?> +
      +
      + form->getInput('targeta', 'urls'); ?> +
      +
      + form->renderField('urlb', 'urls'); ?> + form->renderField('urlbtext', 'urls'); ?> +
      +
      + form->getInput('targetb', 'urls'); ?> +
      +
      + form->renderField('urlc', 'urls'); ?> + form->renderField('urlctext', 'urls'); ?> +
      +
      + form->getInput('targetc', 'urls'); ?> +
      +
      + + + + + + tab_name, 'publishing', JText::_('COM_CONTENT_PUBLISHING')); ?> + form->renderField('catid'); ?> + form->renderField('tags'); ?> + form->renderField('note'); ?> + get('save_history', 0)) : ?> + form->renderField('version_note'); ?> + + get('show_publishing_options', 1) == 1) : ?> + form->renderField('created_by_alias'); ?> + + item->params->get('access-change')) : ?> + form->renderField('state'); ?> + form->renderField('featured'); ?> + get('show_publishing_options', 1) == 1) : ?> + form->renderField('publish_up'); ?> + form->renderField('publish_down'); ?> + + + form->renderField('access'); ?> + item->id)) : ?> +
      +
      +
      +
      + +
      +
      + + + + tab_name, 'language', JText::_('JFIELD_LANGUAGE_LABEL')); ?> + form->renderField('language'); ?> + + + get('show_publishing_options', 1) == 1) : ?> + tab_name, 'metadata', JText::_('COM_CONTENT_METADATA')); ?> + form->renderField('metadesc'); ?> + form->renderField('metakey'); ?> + + + + + + + + +
      +
      +
      + +
      +
      + +
      + get('save_history', 0) && $this->item->id) : ?> +
      + form->getInput('contenthistory'); ?> +
      + +
      +
      +
      diff --git a/Sites/pages/components/com_content/views/form/tmpl/edit.xml b/Sites/pages/components/com_content/views/form/tmpl/edit.xml new file mode 100644 index 00000000..cf67295e --- /dev/null +++ b/Sites/pages/components/com_content/views/form/tmpl/edit.xml @@ -0,0 +1,72 @@ + + + + + + + + + +
      + + + + + + + + + + + + + + + + + + + +
      +
      +
      diff --git a/Sites/pages/components/com_content/views/form/view.html.php b/Sites/pages/components/com_content/views/form/view.html.php new file mode 100644 index 00000000..68a31825 --- /dev/null +++ b/Sites/pages/components/com_content/views/form/view.html.php @@ -0,0 +1,191 @@ +state = $this->get('State'); + $this->item = $this->get('Item'); + $this->form = $this->get('Form'); + $this->return_page = $this->get('ReturnPage'); + + if (empty($this->item->id)) + { + $catid = $this->state->params->get('catid'); + + if ($this->state->params->get('enable_category') == 1 && $catid) + { + $authorised = $user->authorise('core.create', 'com_content.category.' . $catid); + } + else + { + $authorised = $user->authorise('core.create', 'com_content') || count($user->getAuthorisedCategories('com_content', 'core.create')); + } + } + else + { + $authorised = $this->item->params->get('access-edit'); + } + + if ($authorised !== true) + { + $app->enqueueMessage(JText::_('JERROR_ALERTNOAUTHOR'), 'error'); + $app->setHeader('status', 403, true); + + return false; + } + + $this->item->tags = new JHelperTags; + + if (!empty($this->item->id)) + { + $this->item->tags->getItemTags('com_content.article', $this->item->id); + + $this->item->images = json_decode($this->item->images); + $this->item->urls = json_decode($this->item->urls); + + $tmp = new stdClass; + $tmp->images = $this->item->images; + $tmp->urls = $this->item->urls; + $this->form->bind($tmp); + } + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + JError::raiseWarning(500, implode("\n", $errors)); + + return false; + } + + // Create a shortcut to the parameters. + $params = &$this->state->params; + + // Escape strings for HTML output + $this->pageclass_sfx = htmlspecialchars($params->get('pageclass_sfx')); + + $this->params = $params; + + // Override global params with article specific params + $this->params->merge($this->item->params); + $this->user = $user; + + // Propose current language as default when creating new article + if (empty($this->item->id) && JLanguageMultilang::isEnabled()) + { + $lang = JFactory::getLanguage()->getTag(); + $this->form->setFieldAttribute('language', 'default', $lang); + } + + $captchaSet = $params->get('captcha', JFactory::getApplication()->get('captcha', '0')); + + foreach (JPluginHelper::getPlugin('captcha') as $plugin) + { + if ($captchaSet === $plugin->name) + { + $this->captchaEnabled = true; + break; + } + } + + $this->_prepareDocument(); + parent::display($tpl); + } + + /** + * Prepares the document + * + * @return void + */ + protected function _prepareDocument() + { + $app = JFactory::getApplication(); + $menus = $app->getMenu(); + $title = null; + + // Because the application sets a default page title, + // we need to get it from the menu item itself + $menu = $menus->getActive(); + + if ($menu) + { + $this->params->def('page_heading', $this->params->get('page_title', $menu->title)); + } + else + { + $this->params->def('page_heading', JText::_('COM_CONTENT_FORM_EDIT_ARTICLE')); + } + + $title = $this->params->def('page_title', JText::_('COM_CONTENT_FORM_EDIT_ARTICLE')); + + if ($app->get('sitename_pagetitles', 0) == 1) + { + $title = JText::sprintf('JPAGETITLE', $app->get('sitename'), $title); + } + elseif ($app->get('sitename_pagetitles', 0) == 2) + { + $title = JText::sprintf('JPAGETITLE', $title, $app->get('sitename')); + } + + $this->document->setTitle($title); + + $pathway = $app->getPathWay(); + $pathway->addItem($title, ''); + + if ($this->params->get('menu-meta_description')) + { + $this->document->setDescription($this->params->get('menu-meta_description')); + } + + if ($this->params->get('menu-meta_keywords')) + { + $this->document->setMetadata('keywords', $this->params->get('menu-meta_keywords')); + } + + if ($this->params->get('robots')) + { + $this->document->setMetadata('robots', $this->params->get('robots')); + } + } +} diff --git a/Sites/pages/components/com_contenthistory/contenthistory.php b/Sites/pages/components/com_contenthistory/contenthistory.php new file mode 100644 index 00000000..6826e355 --- /dev/null +++ b/Sites/pages/components/com_contenthistory/contenthistory.php @@ -0,0 +1,18 @@ +load('com_contenthistory', JPATH_ADMINISTRATOR, null, false, true) +|| $lang->load('com_contenthistory', JPATH_SITE, null, false, true); + +// Hand processing over to the admin base file +require_once JPATH_COMPONENT_ADMINISTRATOR . '/contenthistory.php'; diff --git a/Sites/pages/components/com_fields/controller.php b/Sites/pages/components/com_fields/controller.php new file mode 100644 index 00000000..49cfe411 --- /dev/null +++ b/Sites/pages/components/com_fields/controller.php @@ -0,0 +1,43 @@ +input = JFactory::getApplication()->input; + + // Frontpage Editor Fields Button proxying: + if ($this->input->get('view') === 'fields' && $this->input->get('layout') === 'modal') + { + // Load the backend language file. + $lang = JFactory::getLanguage(); + $lang->load('com_fields', JPATH_ADMINISTRATOR); + + $config['base_path'] = JPATH_COMPONENT_ADMINISTRATOR; + } + + parent::__construct($config); + } +} diff --git a/Sites/pages/components/com_fields/fields.php b/Sites/pages/components/com_fields/fields.php new file mode 100644 index 00000000..fd81e9a8 --- /dev/null +++ b/Sites/pages/components/com_fields/fields.php @@ -0,0 +1,30 @@ +input; +$context = JFactory::getApplication()->getUserStateFromRequest('com_fields.fields.context', 'context', 'com_content.article', 'CMD'); +$parts = FieldsHelper::extract($context); + +if ($input->get('view') === 'fields' && $input->get('layout') === 'modal') +{ + if (!JFactory::getUser()->authorise('core.create', $parts[0]) + || !JFactory::getUser()->authorise('core.edit', $parts[0])) + { + JFactory::getApplication()->enqueueMessage(JText::_('JERROR_ALERTNOAUTHOR'), 'error'); + + return; + } +} + +$controller = JControllerLegacy::getInstance('Fields'); +$controller->execute($input->get('task')); +$controller->redirect(); diff --git a/Sites/pages/components/com_fields/layouts/field/render.php b/Sites/pages/components/com_fields/layouts/field/render.php new file mode 100644 index 00000000..c36e53c4 --- /dev/null +++ b/Sites/pages/components/com_fields/layouts/field/render.php @@ -0,0 +1,31 @@ +label); +$value = $field->value; +$showLabel = $field->params->get('showlabel'); +$labelClass = $field->params->get('label_render_class'); + +if ($value == '') +{ + return; +} + +?> + + : + + diff --git a/Sites/pages/components/com_fields/layouts/fields/render.php b/Sites/pages/components/com_fields/layouts/fields/render.php new file mode 100644 index 00000000..88f866e8 --- /dev/null +++ b/Sites/pages/components/com_fields/layouts/fields/render.php @@ -0,0 +1,83 @@ +jcfields ?: FieldsHelper::getFields($context, $item, true); +} + +if (empty($fields)) +{ + return; +} + +$output = array(); + +foreach ($fields as $field) +{ + // If the value is empty do nothing + if (!isset($field->value) || trim($field->value) === '') + { + continue; + } + + $class = $field->params->get('render_class'); + $layout = $field->params->get('layout', 'render'); + $content = FieldsHelper::render($context, 'field.' . $layout, array('field' => $field)); + + // If the content is empty do nothing + if (trim($content) === '') + { + continue; + } + + $output[] = '
      ' . $content . '
      '; +} + +if (empty($output)) +{ + return; +} + +?> +
      + +
      diff --git a/Sites/pages/components/com_fields/models/forms/filter_fields.xml b/Sites/pages/components/com_fields/models/forms/filter_fields.xml new file mode 100644 index 00000000..ac01ad9e --- /dev/null +++ b/Sites/pages/components/com_fields/models/forms/filter_fields.xml @@ -0,0 +1,103 @@ + +
      +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      diff --git a/Sites/pages/components/com_finder/controller.php b/Sites/pages/components/com_finder/controller.php new file mode 100644 index 00000000..0594302d --- /dev/null +++ b/Sites/pages/components/com_finder/controller.php @@ -0,0 +1,57 @@ +input; + $cachable = true; + + // Load plugin language files. + FinderHelperLanguage::loadPluginLanguage(); + + // Set the default view name and format from the Request. + $viewName = $input->get('view', 'search', 'word'); + $input->set('view', $viewName); + + // Don't cache view for search queries + if ($input->get('q', null, 'string') || $input->get('f', null, 'int') || $input->get('t', null, 'array')) + { + $cachable = false; + } + + $safeurlparams = array( + 'f' => 'INT', + 'lang' => 'CMD' + ); + + return parent::display($cachable, $safeurlparams); + } +} diff --git a/Sites/pages/components/com_finder/controllers/suggestions.json.php b/Sites/pages/components/com_finder/controllers/suggestions.json.php new file mode 100644 index 00000000..c6d064e7 --- /dev/null +++ b/Sites/pages/components/com_finder/controllers/suggestions.json.php @@ -0,0 +1,101 @@ +mimeType = 'application/json'; + + // Ensure caching is disabled as it depends on the query param in the model + $app->allowCache(false); + + $suggestions = $this->getSuggestions(); + + // Send the response. + $app->setHeader('Content-Type', $app->mimeType . '; charset=' . $app->charSet); + $app->sendHeaders(); + echo '{ "suggestions": ' . json_encode($suggestions) . ' }'; + $app->close(); + } + + /** + * Method to find search query suggestions. Uses Mootools and autocompleter.js + * + * @param boolean $cachable If true, the view output will be cached + * @param array $urlparams An array of safe URL parameters and their variable types, for valid values see {@link JFilterInput::clean()}. + * + * @return void + * + * @since 2.5 + * @deprecated 3.4 + */ + public function display($cachable = false, $urlparams = false) + { + /** @var \Joomla\CMS\Application\CMSApplication $app */ + $app = JFactory::getApplication(); + $app->mimeType = 'application/json'; + + // Ensure caching is disabled as it depends on the query param in the model + $app->allowCache(false); + + $suggestions = $this->getSuggestions(); + + // Send the response. + $app->setHeader('Content-Type', $app->mimeType . '; charset=' . $app->charSet); + $app->sendHeaders(); + echo json_encode($suggestions); + $app->close(); + } + + /** + * Method to retrieve the data from the database + * + * @return array The suggested words + * + * @since 3.4 + */ + protected function getSuggestions() + { + $return = array(); + + $params = JComponentHelper::getParams('com_finder'); + + if ($params->get('show_autosuggest', 1)) + { + // Get the suggestions. + $model = $this->getModel('Suggestions', 'FinderModel'); + $return = $model->getItems(); + } + + // Check the data. + if (empty($return)) + { + $return = array(); + } + + return $return; + } +} diff --git a/Sites/pages/components/com_finder/finder.php b/Sites/pages/components/com_finder/finder.php new file mode 100644 index 00000000..289ab951 --- /dev/null +++ b/Sites/pages/components/com_finder/finder.php @@ -0,0 +1,16 @@ +execute(JFactory::getApplication()->input->get('task')); +$controller->redirect(); diff --git a/Sites/pages/components/com_finder/helpers/html/filter.php b/Sites/pages/components/com_finder/helpers/html/filter.php new file mode 100644 index 00000000..fc6c0727 --- /dev/null +++ b/Sites/pages/components/com_finder/helpers/html/filter.php @@ -0,0 +1,490 @@ +getQuery(true); + $user = JFactory::getUser(); + $groups = implode(',', $user->getAuthorisedViewLevels()); + $html = ''; + $filter = null; + + // Get the configuration options. + $filterId = array_key_exists('filter_id', $options) ? $options['filter_id'] : null; + $activeNodes = array_key_exists('selected_nodes', $options) ? $options['selected_nodes'] : array(); + $classSuffix = array_key_exists('class_suffix', $options) ? $options['class_suffix'] : ''; + + // Load the predefined filter if specified. + if (!empty($filterId)) + { + $query->select('f.data, f.params') + ->from($db->quoteName('#__finder_filters') . ' AS f') + ->where('f.filter_id = ' . (int) $filterId); + + // Load the filter data. + $db->setQuery($query); + + try + { + $filter = $db->loadObject(); + } + catch (RuntimeException $e) + { + return null; + } + + // Initialize the filter parameters. + if ($filter) + { + $filter->params = new Registry($filter->params); + } + } + + // Build the query to get the branch data and the number of child nodes. + $query->clear() + ->select('t.*, count(c.id) AS children') + ->from($db->quoteName('#__finder_taxonomy') . ' AS t') + ->join('INNER', $db->quoteName('#__finder_taxonomy') . ' AS c ON c.parent_id = t.id') + ->where('t.parent_id = 1') + ->where('t.state = 1') + ->where('t.access IN (' . $groups . ')') + ->group('t.id, t.parent_id, t.state, t.access, t.ordering, t.title, c.parent_id') + ->order('t.ordering, t.title'); + + // Limit the branch children to a predefined filter. + if ($filter) + { + $query->where('c.id IN(' . $filter->data . ')'); + } + + // Load the branches. + $db->setQuery($query); + + try + { + $branches = $db->loadObjectList('id'); + } + catch (RuntimeException $e) + { + return null; + } + + // Check that we have at least one branch. + if (count($branches) === 0) + { + return null; + } + + $branch_keys = array_keys($branches); + $html .= JHtml::_('bootstrap.startAccordion', 'accordion', array('parent' => true, 'active' => 'accordion-' . $branch_keys[0]) + ); + + // Load plugin language files. + FinderHelperLanguage::loadPluginLanguage(); + + // Iterate through the branches and build the branch groups. + foreach ($branches as $bk => $bv) + { + // If the multi-lang plugin is enabled then drop the language branch. + if ($bv->title === 'Language' && JLanguageMultilang::isEnabled()) + { + continue; + } + + // Build the query to get the child nodes for this branch. + $query->clear() + ->select('t.*') + ->from($db->quoteName('#__finder_taxonomy') . ' AS t') + ->where('t.parent_id = ' . (int) $bk) + ->where('t.state = 1') + ->where('t.access IN (' . $groups . ')') + ->order('t.ordering, t.title'); + + // Self-join to get the parent title. + $query->select('e.title AS parent_title') + ->join('LEFT', $db->quoteName('#__finder_taxonomy', 'e') . ' ON ' . $db->quoteName('e.id') . ' = ' . $db->quoteName('t.parent_id')); + + // Load the branches. + $db->setQuery($query); + + try + { + $nodes = $db->loadObjectList('id'); + } + catch (RuntimeException $e) + { + return null; + } + + // Translate node titles if possible. + $lang = JFactory::getLanguage(); + + foreach ($nodes as $nk => $nv) + { + if (trim($nv->parent_title, '**') === 'Language') + { + $title = FinderHelperLanguage::branchLanguageTitle($nv->title); + } + else + { + $key = FinderHelperLanguage::branchPlural($nv->title); + $title = $lang->hasKey($key) ? JText::_($key) : $nv->title; + } + + $nodes[$nk]->title = $title; + } + + // Adding slides + $html .= JHtml::_('bootstrap.addSlide', + 'accordion', + JText::sprintf('COM_FINDER_FILTER_BRANCH_LABEL', + JText::_(FinderHelperLanguage::branchSingular($bv->title)) . ' - ' . count($nodes) + ), + 'accordion-' . $bk + ); + + // Populate the toggle button. + $html .= '
      '; + + // Populate the group with nodes. + foreach ($nodes as $nk => $nv) + { + // Determine if the node should be checked. + $checked = in_array($nk, $activeNodes) ? ' checked="checked"' : ''; + + // Build a node. + $html .= '
      '; + $html .= '
      '; + $html .= ''; + $html .= '
      '; + $html .= '
      '; + } + + $html .= JHtml::_('bootstrap.endSlide'); + } + + $html .= JHtml::_('bootstrap.endAccordion'); + + return $html; + } + + /** + * Method to generate filters using select box dropdown controls. + * + * @param FinderIndexerQuery $idxQuery A FinderIndexerQuery object. + * @param array $options An array of options. + * + * @return mixed A rendered HTML widget on success, null otherwise. + * + * @since 2.5 + */ + public static function select($idxQuery, $options) + { + $user = JFactory::getUser(); + $groups = implode(',', $user->getAuthorisedViewLevels()); + $filter = null; + + // Get the configuration options. + $classSuffix = $options->get('class_suffix', null); + $showDates = $options->get('show_date_filters', false); + + // Try to load the results from cache. + $cache = JFactory::getCache('com_finder', ''); + $cacheId = 'filter_select_' . serialize(array($idxQuery->filter, $options, $groups, JFactory::getLanguage()->getTag())); + + // Check the cached results. + if ($cache->contains($cacheId)) + { + $branches = $cache->get($cacheId); + } + else + { + $db = JFactory::getDbo(); + $query = $db->getQuery(true); + + // Load the predefined filter if specified. + if (!empty($idxQuery->filter)) + { + $query->select('f.data, ' . $db->quoteName('f.params')) + ->from($db->quoteName('#__finder_filters') . ' AS f') + ->where('f.filter_id = ' . (int) $idxQuery->filter); + + // Load the filter data. + $db->setQuery($query); + + try + { + $filter = $db->loadObject(); + } + catch (RuntimeException $e) + { + return null; + } + + // Initialize the filter parameters. + if ($filter) + { + $filter->params = new Registry($filter->params); + } + } + + // Build the query to get the branch data and the number of child nodes. + $query->clear() + ->select('t.*, count(c.id) AS children') + ->from($db->quoteName('#__finder_taxonomy') . ' AS t') + ->join('INNER', $db->quoteName('#__finder_taxonomy') . ' AS c ON c.parent_id = t.id') + ->where('t.parent_id = 1') + ->where('t.state = 1') + ->where('t.access IN (' . $groups . ')') + ->where('c.state = 1') + ->where('c.access IN (' . $groups . ')') + ->group($db->quoteName('t.id')) + ->order('t.ordering, t.title'); + + // Limit the branch children to a predefined filter. + if (!empty($filter->data)) + { + $query->where('c.id IN(' . $filter->data . ')'); + } + + // Load the branches. + $db->setQuery($query); + + try + { + $branches = $db->loadObjectList('id'); + } + catch (RuntimeException $e) + { + return null; + } + + // Check that we have at least one branch. + if (count($branches) === 0) + { + return null; + } + + // Iterate through the branches and build the branch groups. + foreach ($branches as $bk => $bv) + { + // If the multi-lang plugin is enabled then drop the language branch. + if ($bv->title === 'Language' && JLanguageMultilang::isEnabled()) + { + continue; + } + + // Build the query to get the child nodes for this branch. + $query->clear() + ->select('t.*') + ->from($db->quoteName('#__finder_taxonomy') . ' AS t') + ->where('t.parent_id = ' . (int) $bk) + ->where('t.state = 1') + ->where('t.access IN (' . $groups . ')') + ->order('t.ordering, t.title'); + + // Self-join to get the parent title. + $query->select('e.title AS parent_title') + ->join('LEFT', $db->quoteName('#__finder_taxonomy', 'e') . ' ON ' . $db->quoteName('e.id') . ' = ' . $db->quoteName('t.parent_id')); + + // Limit the nodes to a predefined filter. + if (!empty($filter->data)) + { + $query->where('t.id IN(' . $filter->data . ')'); + } + + // Load the branches. + $db->setQuery($query); + + try + { + $branches[$bk]->nodes = $db->loadObjectList('id'); + } + catch (RuntimeException $e) + { + return null; + } + + // Translate branch nodes if possible. + $language = JFactory::getLanguage(); + + foreach ($branches[$bk]->nodes as $node_id => $node) + { + if (trim($node->parent_title, '**') === 'Language') + { + $title = FinderHelperLanguage::branchLanguageTitle($node->title); + } + else + { + $key = FinderHelperLanguage::branchPlural($node->title); + $title = $language->hasKey($key) ? JText::_($key) : $node->title; + } + + $branches[$bk]->nodes[$node_id]->title = $title; + } + + // Add the Search All option to the branch. + array_unshift($branches[$bk]->nodes, array('id' => null, 'title' => JText::_('COM_FINDER_FILTER_SELECT_ALL_LABEL'))); + } + + // Store the data in cache. + $cache->store($branches, $cacheId); + } + + $html = ''; + + // Add the dates if enabled. + if ($showDates) + { + $html .= JHtml::_('filter.dates', $idxQuery, $options); + } + + $html .= '
      '; + + // Iterate through all branches and build code. + foreach ($branches as $bk => $bv) + { + // If the multi-lang plugin is enabled then drop the language branch. + if ($bv->title === 'Language' && JLanguageMultilang::isEnabled()) + { + continue; + } + + $active = null; + + // Check if the branch is in the filter. + if (array_key_exists($bv->title, $idxQuery->filters)) + { + // Get the request filters. + $temp = JFactory::getApplication()->input->request->get('t', array(), 'array'); + + // Search for active nodes in the branch and get the active node. + $active = array_intersect($temp, $idxQuery->filters[$bv->title]); + $active = count($active) === 1 ? array_shift($active) : null; + } + + // Build a node. + $html .= '
      '; + $html .= ''; + $html .= '
      '; + $html .= JHtml::_( + 'select.genericlist', + $branches[$bk]->nodes, 't[]', 'class="inputbox advancedSelect"', 'id', 'title', $active, + 'tax-' . JFilterOutput::stringURLSafe($bv->title) + ); + $html .= '
      '; + } + + $html .= '
      '; + + return $html; + } + + /** + * Method to generate fields for filtering dates + * + * @param FinderIndexerQuery $idxQuery A FinderIndexerQuery object. + * @param array $options An array of options. + * + * @return mixed A rendered HTML widget on success, null otherwise. + * + * @since 2.5 + */ + public static function dates($idxQuery, $options) + { + $html = ''; + + // Get the configuration options. + $classSuffix = $options->get('class_suffix', null); + $loadMedia = $options->get('load_media', true); + $showDates = $options->get('show_date_filters', false); + + if (!empty($showDates)) + { + // Build the date operators options. + $operators = array(); + $operators[] = JHtml::_('select.option', 'before', JText::_('COM_FINDER_FILTER_DATE_BEFORE')); + $operators[] = JHtml::_('select.option', 'exact', JText::_('COM_FINDER_FILTER_DATE_EXACTLY')); + $operators[] = JHtml::_('select.option', 'after', JText::_('COM_FINDER_FILTER_DATE_AFTER')); + + // Load the CSS/JS resources. + if ($loadMedia) + { + JHtml::_('stylesheet', 'com_finder/dates.css', array('version' => 'auto', 'relative' => true)); + } + + // Open the widget. + $html .= '
        '; + + // Start date filter. + $attribs['class'] = 'input-medium'; + $html .= '
      • '; + $html .= ''; + $html .= '
        '; + $html .= JHtml::_( + 'select.genericlist', + $operators, 'w1', 'class="inputbox filter-date-operator advancedSelect"', 'value', 'text', $idxQuery->when1, 'finder-filter-w1' + ); + $html .= JHtml::_('calendar', $idxQuery->date1, 'd1', 'filter_date1', '%Y-%m-%d', $attribs); + $html .= '
      • '; + + // End date filter. + $html .= '
      • '; + $html .= ''; + $html .= '
        '; + $html .= JHtml::_( + 'select.genericlist', + $operators, 'w2', 'class="inputbox filter-date-operator advancedSelect"', 'value', 'text', $idxQuery->when2, 'finder-filter-w2' + ); + $html .= JHtml::_('calendar', $idxQuery->date2, 'd2', 'filter_date2', '%Y-%m-%d', $attribs); + $html .= '
      • '; + + // Close the widget. + $html .= '
      '; + } + + return $html; + } +} diff --git a/Sites/pages/components/com_finder/helpers/html/query.php b/Sites/pages/components/com_finder/helpers/html/query.php new file mode 100644 index 00000000..d49aa4cf --- /dev/null +++ b/Sites/pages/components/com_finder/helpers/html/query.php @@ -0,0 +1,166 @@ +included as $token) + { + if ($token->required && (!isset($token->derived) || $token->derived == false)) + { + $parts[] = '' . JText::sprintf('COM_FINDER_QUERY_TOKEN_REQUIRED', $token->term) . ''; + } + } + + // Process the optional tokens. + foreach ($query->included as $token) + { + if (!$token->required && (!isset($token->derived) || $token->derived == false)) + { + $parts[] = '' . JText::sprintf('COM_FINDER_QUERY_TOKEN_OPTIONAL', $token->term) . ''; + } + } + + // Process the excluded tokens. + foreach ($query->excluded as $token) + { + if (!isset($token->derived) || $token->derived === false) + { + $parts[] = '' . JText::sprintf('COM_FINDER_QUERY_TOKEN_EXCLUDED', $token->term) . ''; + } + } + + // Process the start date. + if ($query->date1) + { + $date = JFactory::getDate($query->date1)->format(JText::_('DATE_FORMAT_LC')); + $datecondition = JText::_('COM_FINDER_QUERY_DATE_CONDITION_' . strtoupper($query->when1)); + $parts[] = '' . JText::sprintf('COM_FINDER_QUERY_START_DATE', $datecondition, $date) . ''; + } + + // Process the end date. + if ($query->date2) + { + $date = JFactory::getDate($query->date2)->format(JText::_('DATE_FORMAT_LC')); + $datecondition = JText::_('COM_FINDER_QUERY_DATE_CONDITION_' . strtoupper($query->when2)); + $parts[] = '' . JText::sprintf('COM_FINDER_QUERY_END_DATE', $datecondition, $date) . ''; + } + + // Process the taxonomy filters. + if (!empty($query->filters)) + { + // Get the filters in the request. + $t = JFactory::getApplication()->input->request->get('t', array(), 'array'); + + // Process the taxonomy branches. + foreach ($query->filters as $branch => $nodes) + { + // Process the taxonomy nodes. + $lang = JFactory::getLanguage(); + + foreach ($nodes as $title => $id) + { + // Translate the title for Types + $key = FinderHelperLanguage::branchPlural($title); + + if ($lang->hasKey($key)) + { + $title = JText::_($key); + } + + // Don't include the node if it is not in the request. + if (!in_array($id, $t)) + { + continue; + } + + // Add the node to the explanation. + $parts[] = '' + . JText::sprintf('COM_FINDER_QUERY_TAXONOMY_NODE', $title, JText::_(FinderHelperLanguage::branchSingular($branch))) + . ''; + } + } + } + + // Build the interpreted query. + return count($parts) ? JText::sprintf('COM_FINDER_QUERY_TOKEN_INTERPRETED', implode(JText::_('COM_FINDER_QUERY_TOKEN_GLUE'), $parts)) : null; + } + + /** + * Method to get the suggested search query. + * + * @param FinderIndexerQuery $query A FinderIndexerQuery object. + * + * @return mixed String if there is a suggestion, false otherwise. + * + * @since 2.5 + */ + public static function suggested(FinderIndexerQuery $query) + { + $suggested = false; + + // Check if the query input is empty. + if (empty($query->input)) + { + return $suggested; + } + + // Check if there were any ignored or included keywords. + if (count($query->ignored) || count($query->included)) + { + $suggested = $query->input; + + // Replace the ignored keyword suggestions. + foreach (array_reverse($query->ignored) as $token) + { + if (isset($token->suggestion)) + { + $suggested = str_ireplace($token->term, $token->suggestion, $suggested); + } + } + + // Replace the included keyword suggestions. + foreach (array_reverse($query->included) as $token) + { + if (isset($token->suggestion)) + { + $suggested = str_ireplace($token->term, $token->suggestion, $suggested); + } + } + + // Check if we made any changes. + if ($suggested == $query->input) + { + $suggested = false; + } + } + + return $suggested; + } +} diff --git a/Sites/pages/components/com_finder/helpers/route.php b/Sites/pages/components/com_finder/helpers/route.php new file mode 100644 index 00000000..bdf177c4 --- /dev/null +++ b/Sites/pages/components/com_finder/helpers/route.php @@ -0,0 +1,159 @@ + 'search', 'q' => $q, 'f' => $f); + $item = self::getItemid($query); + + // Get the base route. + $uri = clone JUri::getInstance('index.php?option=com_finder&view=search'); + + // Add the pre-defined search filter if present. + if ($f !== null) + { + $uri->setVar('f', $f); + } + + // Add the search query string if present. + if ($q !== null) + { + $uri->setVar('q', $q); + } + + // Add the menu item id if present. + if ($item !== null) + { + $uri->setVar('Itemid', $item); + } + + return $uri->toString(array('path', 'query')); + } + + /** + * Method to get the route for an advanced search page. + * + * @param integer $f The search filter id. [optional] + * @param string $q The search query string. [optional] + * + * @return string The advanced search route. + * + * @since 2.5 + */ + public static function getAdvancedRoute($f = null, $q = null) + { + // Get the menu item id. + $query = array('view' => 'advanced', 'q' => $q, 'f' => $f); + $item = self::getItemid($query); + + // Get the base route. + $uri = clone JUri::getInstance('index.php?option=com_finder&view=advanced'); + + // Add the pre-defined search filter if present. + if ($q !== null) + { + $uri->setVar('f', $f); + } + + // Add the search query string if present. + if ($q !== null) + { + $uri->setVar('q', $q); + } + + // Add the menu item id if present. + if ($item !== null) + { + $uri->setVar('Itemid', $item); + } + + return $uri->toString(array('path', 'query')); + } + + /** + * Method to get the most appropriate menu item for the route based on the + * supplied query needles. + * + * @param array $query An array of URL parameters. + * + * @return mixed An integer on success, null otherwise. + * + * @since 2.5 + */ + public static function getItemid($query) + { + static $items, $active; + + // Get the menu items for com_finder. + if (!$items || !$active) + { + $app = JFactory::getApplication('site'); + $com = JComponentHelper::getComponent('com_finder'); + $menu = $app->getMenu(); + $active = $menu->getActive(); + $items = $menu->getItems('component_id', $com->id); + $items = is_array($items) ? $items : array(); + } + + // Try to match the active view and filter. + if ($active && @$active->query['view'] == @$query['view'] && @$active->query['f'] == @$query['f']) + { + return $active->id; + } + + // Try to match the view, query, and filter. + foreach ($items as $item) + { + if (@$item->query['view'] == @$query['view'] && @$item->query['q'] == @$query['q'] && @$item->query['f'] == @$query['f']) + { + return $item->id; + } + } + + // Try to match the view and filter. + foreach ($items as $item) + { + if (@$item->query['view'] == @$query['view'] && @$item->query['f'] == @$query['f']) + { + return $item->id; + } + } + + // Try to match the view. + foreach ($items as $item) + { + if (@$item->query['view'] == @$query['view']) + { + return $item->id; + } + } + + return null; + } +} diff --git a/Sites/pages/components/com_finder/models/search.php b/Sites/pages/components/com_finder/models/search.php new file mode 100644 index 00000000..f03bb88f --- /dev/null +++ b/Sites/pages/components/com_finder/models/search.php @@ -0,0 +1,1231 @@ +query->search)) + { + return null; + } + + // Check if we should return results. + if (empty($this->includedTerms) && (empty($this->query->filters) || !$this->query->empty)) + { + return null; + } + + // Get the store id. + $store = $this->getStoreId('getResults'); + + // Use the cached data if possible. + if ($this->retrieve($store)) + { + return $this->retrieve($store); + } + + // Get the row data. + $items = $this->getResultsData(); + + // Check the data. + if (empty($items)) + { + return null; + } + + // Create the query to get the search results. + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select($db->quoteName('link_id') . ', ' . $db->quoteName('object')) + ->from($db->quoteName('#__finder_links')) + ->where($db->quoteName('link_id') . ' IN (' . implode(',', array_keys($items)) . ')'); + + // Load the results from the database. + $db->setQuery($query); + $rows = $db->loadObjectList('link_id'); + + // Set up our results container. + $results = $items; + + // Convert the rows to result objects. + foreach ($rows as $rk => $row) + { + // Build the result object. + $result = unserialize($row->object); + $result->weight = $results[$rk]; + $result->link_id = $rk; + + // Add the result back to the stack. + $results[$rk] = $result; + } + + // Switch to a non-associative array. + $results = array_values($results); + + // Push the results into cache. + $this->store($store, $results); + + // Return the results. + return $this->retrieve($store); + } + + /** + * Method to get the total number of results. + * + * @return integer The total number of results. + * + * @since 2.5 + * @throws Exception on database error. + */ + public function getTotal() + { + // Check if the search query is valid. + if (empty($this->query->search)) + { + return null; + } + + // Check if we should return results. + if (empty($this->includedTerms) && (empty($this->query->filters) || !$this->query->empty)) + { + return null; + } + + // Get the store id. + $store = $this->getStoreId('getTotal'); + + // Use the cached data if possible. + if ($this->retrieve($store)) + { + return $this->retrieve($store); + } + + // Get the results total. + $total = $this->getResultsTotal(); + + // Push the total into cache. + $this->store($store, $total); + + // Return the total. + return $this->retrieve($store); + } + + /** + * Method to get the query object. + * + * @return FinderIndexerQuery A query object. + * + * @since 2.5 + */ + public function getQuery() + { + // Return the query object. + return $this->query; + } + + /** + * Method to build a database query to load the list data. + * + * @return JDatabaseQuery A database query. + * + * @since 2.5 + */ + protected function getListQuery() + { + // Get the store id. + $store = $this->getStoreId('getListQuery'); + + // Use the cached data if possible. + if ($this->retrieve($store, false)) + { + return clone $this->retrieve($store, false); + } + + // Set variables + $user = JFactory::getUser(); + $groups = implode(',', $user->getAuthorisedViewLevels()); + + // Create a new query object. + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select('l.link_id') + ->from($db->quoteName('#__finder_links') . ' AS l') + ->where('l.access IN (' . $groups . ')') + ->where('l.state = 1') + ->where('l.published = 1'); + + // Get the null date and the current date, minus seconds. + $nullDate = $db->quote($db->getNullDate()); + $nowDate = $db->quote(substr_replace(JFactory::getDate()->toSql(), '00', -2)); + + // Add the publish up and publish down filters. + $query->where('(l.publish_start_date = ' . $nullDate . ' OR l.publish_start_date <= ' . $nowDate . ')') + ->where('(l.publish_end_date = ' . $nullDate . ' OR l.publish_end_date >= ' . $nowDate . ')'); + + /* + * Add the taxonomy filters to the query. We have to join the taxonomy + * map table for each group so that we can use AND clauses across + * groups. Within each group there can be an array of values that will + * use OR clauses. + */ + if (!empty($this->query->filters)) + { + // Convert the associative array to a numerically indexed array. + $groups = array_values($this->query->filters); + + // Iterate through each taxonomy group and add the join and where. + for ($i = 0, $c = count($groups); $i < $c; $i++) + { + // We use the offset because each join needs a unique alias. + $query->join('INNER', $db->quoteName('#__finder_taxonomy_map') . ' AS t' . $i . ' ON t' . $i . '.link_id = l.link_id') + ->where('t' . $i . '.node_id IN (' . implode(',', $groups[$i]) . ')'); + } + } + + // Add the start date filter to the query. + if (!empty($this->query->date1)) + { + // Escape the date. + $date1 = $db->quote($this->query->date1); + + // Add the appropriate WHERE condition. + if ($this->query->when1 === 'before') + { + $query->where($db->quoteName('l.start_date') . ' <= ' . $date1); + } + elseif ($this->query->when1 === 'after') + { + $query->where($db->quoteName('l.start_date') . ' >= ' . $date1); + } + else + { + $query->where($db->quoteName('l.start_date') . ' = ' . $date1); + } + } + + // Add the end date filter to the query. + if (!empty($this->query->date2)) + { + // Escape the date. + $date2 = $db->quote($this->query->date2); + + // Add the appropriate WHERE condition. + if ($this->query->when2 === 'before') + { + $query->where($db->quoteName('l.start_date') . ' <= ' . $date2); + } + elseif ($this->query->when2 === 'after') + { + $query->where($db->quoteName('l.start_date') . ' >= ' . $date2); + } + else + { + $query->where($db->quoteName('l.start_date') . ' = ' . $date2); + } + } + + // Filter by language + if ($this->getState('filter.language')) + { + $query->where('l.language IN (' . $db->quote(JFactory::getLanguage()->getTag()) . ', ' . $db->quote('*') . ')'); + } + + // Push the data into cache. + $this->store($store, $query, false); + + // Return a copy of the query object. + return clone $this->retrieve($store, false); + } + + /** + * Method to get the total number of results for the search query. + * + * @return integer The results total. + * + * @since 2.5 + * @throws Exception on database error. + */ + protected function getResultsTotal() + { + // Get the store id. + $store = $this->getStoreId('getResultsTotal', false); + + // Use the cached data if possible. + if ($this->retrieve($store)) + { + return $this->retrieve($store); + } + + // Get the base query and add the ordering information. + $base = $this->getListQuery(); + $base->select('0 AS ordering'); + + // Get the maximum number of results. + $limit = (int) $this->getState('match.limit'); + + /* + * If there are no optional or required search terms in the query, + * we can get the result total in one relatively simple database query. + */ + if (empty($this->includedTerms)) + { + // Adjust the query to join on the appropriate mapping table. + $query = clone $base; + $query->clear('select') + ->select('COUNT(DISTINCT l.link_id)'); + + // Get the total from the database. + $this->_db->setQuery($query); + $total = $this->_db->loadResult(); + + // Push the total into cache. + $this->store($store, min($total, $limit)); + + // Return the total. + return $this->retrieve($store); + } + + /* + * If there are optional or required search terms in the query, the + * process of getting the result total is more complicated. + */ + $start = 0; + $items = array(); + $sorted = array(); + $maps = array(); + $excluded = $this->getExcludedLinkIds(); + + /* + * Iterate through the included search terms and group them by mapping + * table suffix. This ensures that we never have to do more than 16 + * queries to get a batch. This may seem like a lot but it is rarely + * anywhere near 16 because of the improved mapping algorithm. + */ + foreach ($this->includedTerms as $token => $ids) + { + // Get the mapping table suffix. + $suffix = StringHelper::substr(md5(StringHelper::substr($token, 0, 1)), 0, 1); + + // Initialize the mapping group. + if (!array_key_exists($suffix, $maps)) + { + $maps[$suffix] = array(); + } + + // Add the terms to the mapping group. + $maps[$suffix] = array_merge($maps[$suffix], $ids); + } + + /* + * When the query contains search terms we need to find and process the + * result total iteratively using a do-while loop. + */ + do + { + // Create a container for the fetched results. + $results = array(); + $more = false; + + /* + * Iterate through the mapping groups and load the total from each + * mapping table. + */ + foreach ($maps as $suffix => $ids) + { + // Create a storage key for this set. + $setId = $this->getStoreId('getResultsTotal:' . serialize(array_values($ids)) . ':' . $start . ':' . $limit); + + // Use the cached data if possible. + if ($this->retrieve($setId)) + { + $temp = $this->retrieve($setId); + } + // Load the data from the database. + else + { + // Adjust the query to join on the appropriate mapping table. + $query = clone $base; + $query->join('INNER', '#__finder_links_terms' . $suffix . ' AS m ON m.link_id = l.link_id') + ->where('m.term_id IN (' . implode(',', $ids) . ')'); + + // Load the results from the database. + $this->_db->setQuery($query, $start, $limit); + $temp = $this->_db->loadObjectList(); + + // Set the more flag to true if any of the sets equal the limit. + $more = count($temp) === $limit; + + // We loaded the data unkeyed but we need it to be keyed for later. + $junk = $temp; + $temp = array(); + + // Convert to an associative array. + for ($i = 0, $c = count($junk); $i < $c; $i++) + { + $temp[$junk[$i]->link_id] = $junk[$i]; + } + + // Store this set in cache. + $this->store($setId, $temp); + } + + // Merge the results. + $results = array_merge($results, $temp); + } + + // Check if there are any excluded terms to deal with. + if (count($excluded)) + { + // Remove any results that match excluded terms. + for ($i = 0, $c = count($results); $i < $c; $i++) + { + if (in_array($results[$i]->link_id, $excluded)) + { + unset($results[$i]); + } + } + + // Reset the array keys. + $results = array_values($results); + } + + // Iterate through the set to extract the unique items. + for ($i = 0, $c = count($results); $i < $c; $i++) + { + if (!isset($sorted[$results[$i]->link_id])) + { + $sorted[$results[$i]->link_id] = $results[$i]->ordering; + } + } + + /* + * If the query contains just optional search terms and we have + * enough items for the page, we can stop here. + */ + if (empty($this->requiredTerms)) + { + // If we need more items and they're available, make another pass. + if ($more && count($sorted) < $limit) + { + // Increment the batch starting point and continue. + $start += $limit; + continue; + } + + // Push the total into cache. + $this->store($store, min(count($sorted), $limit)); + + // Return the total. + return $this->retrieve($store); + } + + /* + * The query contains required search terms so we have to iterate + * over the items and remove any items that do not match all of the + * required search terms. This is one of the most expensive steps + * because a required token could theoretically eliminate all of + * current terms which means we would have to loop through all of + * the possibilities. + */ + foreach ($this->requiredTerms as $token => $required) + { + // Create a storage key for this set. + $setId = $this->getStoreId('getResultsTotal:required:' . serialize(array_values($required)) . ':' . $start . ':' . $limit); + + // Use the cached data if possible. + if ($this->retrieve($setId)) + { + $reqTemp = $this->retrieve($setId); + } + // Check if the token was matched. + elseif (empty($required)) + { + return null; + } + // Load the data from the database. + else + { + // Setup containers in case we have to make multiple passes. + $reqStart = 0; + $reqTemp = array(); + + do + { + // Get the map table suffix. + $suffix = StringHelper::substr(md5(StringHelper::substr($token, 0, 1)), 0, 1); + + // Adjust the query to join on the appropriate mapping table. + $query = clone $base; + $query->join('INNER', '#__finder_links_terms' . $suffix . ' AS m ON m.link_id = l.link_id') + ->where('m.term_id IN (' . implode(',', $required) . ')'); + + // Load the results from the database. + $this->_db->setQuery($query, $reqStart, $limit); + $temp = $this->_db->loadObjectList('link_id'); + + // Set the required token more flag to true if the set equal the limit. + $reqMore = count($temp) === $limit; + + // Merge the matching set for this token. + $reqTemp += $temp; + + // Increment the term offset. + $reqStart += $limit; + } + while ($reqMore === true); + + // Store this set in cache. + $this->store($setId, $reqTemp); + } + + // Remove any items that do not match the required term. + $sorted = array_intersect_key($sorted, $reqTemp); + } + + // If we need more items and they're available, make another pass. + if ($more && count($sorted) < $limit) + { + // Increment the batch starting point. + $start += $limit; + + // Merge the found items. + $items += $sorted; + + continue; + } + + // Otherwise, end the loop. + { + // Merge the found items. + $items += $sorted; + + $more = false; + } + // End do-while loop. + } + while ($more === true); + + // Set the total. + $total = count($items); + $total = min($total, $limit); + + // Push the total into cache. + $this->store($store, $total); + + // Return the total. + return $this->retrieve($store); + } + + /** + * Method to get the results for the search query. + * + * @return array An array of result data objects. + * + * @since 2.5 + * @throws Exception on database error. + */ + protected function getResultsData() + { + // Get the store id. + $store = $this->getStoreId('getResultsData', false); + + // Use the cached data if possible. + if ($this->retrieve($store)) + { + return $this->retrieve($store); + } + + // Get the result ordering and direction. + $ordering = $this->getState('list.ordering', 'l.start_date'); + $direction = $this->getState('list.direction', 'DESC'); + + // Get the base query and add the ordering information. + $base = $this->getListQuery(); + $base->select($this->_db->escape($ordering) . ' AS ordering'); + $base->order($this->_db->escape($ordering) . ' ' . $this->_db->escape($direction)); + + /* + * If there are no optional or required search terms in the query, we + * can get the results in one relatively simple database query. + */ + if (empty($this->includedTerms)) + { + // Get the results from the database. + $this->_db->setQuery($base, (int) $this->getState('list.start'), (int) $this->getState('list.limit')); + $return = $this->_db->loadObjectList('link_id'); + + // Get a new store id because this data is page specific. + $store = $this->getStoreId('getResultsData', true); + + // Push the results into cache. + $this->store($store, $return); + + // Return the results. + return $this->retrieve($store); + } + + /* + * If there are optional or required search terms in the query, the + * process of getting the results is more complicated. + */ + $start = 0; + $limit = (int) $this->getState('match.limit'); + $items = array(); + $sorted = array(); + $maps = array(); + $excluded = $this->getExcludedLinkIds(); + + /* + * Iterate through the included search terms and group them by mapping + * table suffix. This ensures that we never have to do more than 16 + * queries to get a batch. This may seem like a lot but it is rarely + * anywhere near 16 because of the improved mapping algorithm. + */ + foreach ($this->includedTerms as $token => $ids) + { + // Get the mapping table suffix. + $suffix = StringHelper::substr(md5(StringHelper::substr($token, 0, 1)), 0, 1); + + // Initialize the mapping group. + if (!array_key_exists($suffix, $maps)) + { + $maps[$suffix] = array(); + } + + // Add the terms to the mapping group. + $maps[$suffix] = array_merge($maps[$suffix], $ids); + } + + /* + * When the query contains search terms we need to find and process the + * results iteratively using a do-while loop. + */ + do + { + // Create a container for the fetched results. + $results = array(); + $more = false; + + /* + * Iterate through the mapping groups and load the results from each + * mapping table. + */ + foreach ($maps as $suffix => $ids) + { + // Create a storage key for this set. + $setId = $this->getStoreId('getResultsData:' . serialize(array_values($ids)) . ':' . $start . ':' . $limit); + + // Use the cached data if possible. + if ($this->retrieve($setId)) + { + $temp = $this->retrieve($setId); + } + // Load the data from the database. + else + { + // Adjust the query to join on the appropriate mapping table. + $query = clone $base; + $query->join('INNER', $this->_db->quoteName('#__finder_links_terms' . $suffix) . ' AS m ON m.link_id = l.link_id') + ->where('m.term_id IN (' . implode(',', $ids) . ')'); + + // Load the results from the database. + $this->_db->setQuery($query, $start, $limit); + $temp = $this->_db->loadObjectList('link_id'); + + // Store this set in cache. + $this->store($setId, $temp); + + // The data is keyed by link_id to ease caching, we don't need it till later. + $temp = array_values($temp); + } + + // Set the more flag to true if any of the sets equal the limit. + $more = count($temp) === $limit; + + // Merge the results. + $results = array_merge($results, $temp); + } + + // Check if there are any excluded terms to deal with. + if (count($excluded)) + { + // Remove any results that match excluded terms. + for ($i = 0, $c = count($results); $i < $c; $i++) + { + if (in_array($results[$i]->link_id, $excluded)) + { + unset($results[$i]); + } + } + + // Reset the array keys. + $results = array_values($results); + } + + /* + * If we are ordering by relevance we have to add up the relevance + * scores that are contained in the ordering field. + */ + if ($ordering === 'm.weight') + { + // Iterate through the set to extract the unique items. + for ($i = 0, $c = count($results); $i < $c; $i++) + { + // Add the total weights for all included search terms. + if (isset($sorted[$results[$i]->link_id])) + { + $sorted[$results[$i]->link_id] += (float) $results[$i]->ordering; + } + else + { + $sorted[$results[$i]->link_id] = (float) $results[$i]->ordering; + } + } + } + /* + * If we are ordering by start date we have to add convert the + * dates to unix timestamps. + */ + elseif ($ordering === 'l.start_date') + { + // Iterate through the set to extract the unique items. + for ($i = 0, $c = count($results); $i < $c; $i++) + { + if (!isset($sorted[$results[$i]->link_id])) + { + $sorted[$results[$i]->link_id] = strtotime($results[$i]->ordering); + } + } + } + /* + * If we are not ordering by relevance or date, we just have to add + * the unique items to the set. + */ + else + { + // Iterate through the set to extract the unique items. + for ($i = 0, $c = count($results); $i < $c; $i++) + { + if (!isset($sorted[$results[$i]->link_id])) + { + $sorted[$results[$i]->link_id] = $results[$i]->ordering; + } + } + } + + // Sort the results. + natcasesort($items); + + if ($direction === 'DESC') + { + $items = array_reverse($items, true); + } + + /* + * If the query contains just optional search terms and we have + * enough items for the page, we can stop here. + */ + if (empty($this->requiredTerms)) + { + // If we need more items and they're available, make another pass. + if ($more && count($sorted) < ($this->getState('list.start') + $this->getState('list.limit'))) + { + // Increment the batch starting point and continue. + $start += $limit; + continue; + } + + // Push the results into cache. + $this->store($store, $sorted); + + // Return the requested set. + return array_slice($this->retrieve($store), (int) $this->getState('list.start'), (int) $this->getState('list.limit'), true); + } + + /* + * The query contains required search terms so we have to iterate + * over the items and remove any items that do not match all of the + * required search terms. This is one of the most expensive steps + * because a required token could theoretically eliminate all of + * current terms which means we would have to loop through all of + * the possibilities. + */ + foreach ($this->requiredTerms as $token => $required) + { + // Create a storage key for this set. + $setId = $this->getStoreId('getResultsData:required:' . serialize(array_values($required)) . ':' . $start . ':' . $limit); + + // Use the cached data if possible. + if ($this->retrieve($setId)) + { + $reqTemp = $this->retrieve($setId); + } + // Check if the token was matched. + elseif (empty($required)) + { + return null; + } + // Load the data from the database. + else + { + // Setup containers in case we have to make multiple passes. + $reqStart = 0; + $reqTemp = array(); + + do + { + // Get the map table suffix. + $suffix = StringHelper::substr(md5(StringHelper::substr($token, 0, 1)), 0, 1); + + // Adjust the query to join on the appropriate mapping table. + $query = clone $base; + $query->join('INNER', $this->_db->quoteName('#__finder_links_terms' . $suffix) . ' AS m ON m.link_id = l.link_id') + ->where('m.term_id IN (' . implode(',', $required) . ')'); + + // Load the results from the database. + $this->_db->setQuery($query, $reqStart, $limit); + $temp = $this->_db->loadObjectList('link_id'); + + // Set the required token more flag to true if the set equal the limit. + $reqMore = count($temp) === $limit; + + // Merge the matching set for this token. + $reqTemp += $temp; + + // Increment the term offset. + $reqStart += $limit; + } + while ($reqMore === true); + + // Store this set in cache. + $this->store($setId, $reqTemp); + } + + // Remove any items that do not match the required term. + $sorted = array_intersect_key($sorted, $reqTemp); + } + + // If we need more items and they're available, make another pass. + if ($more && count($sorted) < ($this->getState('list.start') + $this->getState('list.limit'))) + { + // Increment the batch starting point. + $start += $limit; + + // Merge the found items. + $items = array_merge($items, $sorted); + + continue; + } + // Otherwise, end the loop. + else + { + // Set the found items. + $items = $sorted; + + $more = false; + } + + // End do-while loop. + } + while ($more === true); + + // Push the results into cache. + $this->store($store, $items); + + // Return the requested set. + return array_slice($this->retrieve($store), (int) $this->getState('list.start'), (int) $this->getState('list.limit'), true); + } + + /** + * Method to get an array of link ids that match excluded terms. + * + * @return array An array of links ids. + * + * @since 2.5 + * @throws Exception on database error. + */ + protected function getExcludedLinkIds() + { + // Check if the search query has excluded terms. + if (empty($this->excludedTerms)) + { + return array(); + } + + // Get the store id. + $store = $this->getStoreId('getExcludedLinkIds', false); + + // Use the cached data if possible. + if ($this->retrieve($store)) + { + return $this->retrieve($store); + } + + // Initialize containers. + $links = array(); + $maps = array(); + + /* + * Iterate through the excluded search terms and group them by mapping + * table suffix. This ensures that we never have to do more than 16 + * queries to get a batch. This may seem like a lot but it is rarely + * anywhere near 16 because of the improved mapping algorithm. + */ + foreach ($this->excludedTerms as $token => $id) + { + // Get the mapping table suffix. + $suffix = StringHelper::substr(md5(StringHelper::substr($token, 0, 1)), 0, 1); + + // Initialize the mapping group. + if (!array_key_exists($suffix, $maps)) + { + $maps[$suffix] = array(); + } + + // Add the terms to the mapping group. + $maps[$suffix][] = (int) $id; + } + + /* + * Iterate through the mapping groups and load the excluded links ids + * from each mapping table. + */ + + // Create a new query object. + $db = $this->getDbo(); + $query = $db->getQuery(true); + + foreach ($maps as $suffix => $ids) + { + // Create the query to get the links ids. + $query->clear() + ->select('link_id') + ->from($db->quoteName('#__finder_links_terms' . $suffix)) + ->where($db->quoteName('term_id') . ' IN (' . implode(',', $ids) . ')') + ->group($db->quoteName('link_id')); + + // Load the link ids from the database. + $db->setQuery($query); + $temp = $db->loadColumn(); + + // Merge the link ids. + $links = array_merge($links, $temp); + } + + // Sanitize the link ids. + $links = array_unique($links); + $links = ArrayHelper::toInteger($links); + + // Push the link ids into cache. + $this->store($store, $links); + + return $links; + } + + /** + * Method to get a store id based on model the configuration state. + * + * This is necessary because the model is used by the component and + * different modules that might need different sets of data or different + * ordering requirements. + * + * @param string $id An identifier string to generate the store id. [optional] + * @param boolean $page True to store the data paged, false to store all data. [optional] + * + * @return string A store id. + * + * @since 2.5 + */ + protected function getStoreId($id = '', $page = true) + { + // Get the query object. + $query = $this->getQuery(); + + // Add the search query state. + $id .= ':' . $query->input; + $id .= ':' . $query->language; + $id .= ':' . $query->filter; + $id .= ':' . serialize($query->filters); + $id .= ':' . $query->date1; + $id .= ':' . $query->date2; + $id .= ':' . $query->when1; + $id .= ':' . $query->when2; + + if ($page) + { + // Add the list state for page specific data. + $id .= ':' . $this->getState('list.start'); + $id .= ':' . $this->getState('list.limit'); + $id .= ':' . $this->getState('list.ordering'); + $id .= ':' . $this->getState('list.direction'); + } + + return parent::getStoreId($id); + } + + /** + * Method to auto-populate the model state. Calling getState in this method will result in recursion. + * + * @param string $ordering An optional ordering field. [optional] + * @param string $direction An optional direction. [optional] + * + * @return void + * + * @since 2.5 + */ + protected function populateState($ordering = null, $direction = null) + { + // Get the configuration options. + $app = JFactory::getApplication(); + $input = $app->input; + $params = $app->getParams(); + $user = JFactory::getUser(); + + $this->setState('filter.language', JLanguageMultilang::isEnabled()); + + // Setup the stemmer. + if ($params->get('stem', 1) && $params->get('stemmer', 'porter_en')) + { + FinderIndexerHelper::$stemmer = FinderIndexerStemmer::getInstance($params->get('stemmer', 'porter_en')); + } + + $request = $input->request; + $options = array(); + + // Get the empty query setting. + $options['empty'] = $params->get('allow_empty_query', 0); + + // Get the static taxonomy filters. + $options['filter'] = $request->getInt('f', $params->get('f', '')); + + // Get the dynamic taxonomy filters. + $options['filters'] = $request->get('t', $params->get('t', array()), '', 'array'); + + // Get the query string. + $options['input'] = $request->getString('q', $params->get('q', '')); + + // Get the query language. + $options['language'] = $request->getCmd('l', $params->get('l', '')); + + // Get the start date and start date modifier filters. + $options['date1'] = $request->getString('d1', $params->get('d1', '')); + $options['when1'] = $request->getString('w1', $params->get('w1', '')); + + // Get the end date and end date modifier filters. + $options['date2'] = $request->getString('d2', $params->get('d2', '')); + $options['when2'] = $request->getString('w2', $params->get('w2', '')); + + // Load the query object. + $this->query = new FinderIndexerQuery($options); + + // Load the query token data. + $this->excludedTerms = $this->query->getExcludedTermIds(); + $this->includedTerms = $this->query->getIncludedTermIds(); + $this->requiredTerms = $this->query->getRequiredTermIds(); + + // Load the list state. + $this->setState('list.start', $input->get('limitstart', 0, 'uint')); + $this->setState('list.limit', $input->get('limit', $app->get('list_limit', 20), 'uint')); + + /** + * Load the sort ordering. + * Currently this is 'hard' coded via menu item parameter but may not satisfy a users need. + * More flexibility was way more user friendly. So we allow the user to pass a custom value + * from the pool of fields that are indexed like the 'title' field. + * Also, we allow this parameter to be passed in either case (lower/upper). + */ + $order = $input->getWord('filter_order', $params->get('sort_order', 'relevance')); + $order = StringHelper::strtolower($order); + + switch ($order) + { + case 'date': + $this->setState('list.ordering', 'l.start_date'); + break; + + case 'price': + $this->setState('list.ordering', 'l.list_price'); + break; + + case ($order === 'relevance' && !empty($this->includedTerms)) : + $this->setState('list.ordering', 'm.weight'); + break; + + // Custom field that is indexed and might be required for ordering + case 'title': + $this->setState('list.ordering', 'l.title'); + break; + + default: + $this->setState('list.ordering', 'l.link_id'); + break; + } + + /** + * Load the sort direction. + * Currently this is 'hard' coded via menu item parameter but may not satisfy a users need. + * More flexibility was way more user friendly. So we allow to be inverted. + * Also, we allow this parameter to be passed in either case (lower/upper). + */ + $dirn = $input->getWord('filter_order_Dir', $params->get('sort_direction', 'desc')); + $dirn = StringHelper::strtolower($dirn); + + switch ($dirn) + { + case 'asc': + $this->setState('list.direction', 'ASC'); + break; + + default: + case 'desc': + $this->setState('list.direction', 'DESC'); + break; + } + + // Set the match limit. + $this->setState('match.limit', 1000); + + // Load the parameters. + $this->setState('params', $params); + + // Load the user state. + $this->setState('user.id', (int) $user->get('id')); + $this->setState('user.groups', $user->getAuthorisedViewLevels()); + } + + /** + * Method to retrieve data from cache. + * + * @param string $id The cache store id. + * @param boolean $persistent Flag to enable the use of external cache. [optional] + * + * @return mixed The cached data if found, null otherwise. + * + * @since 2.5 + */ + protected function retrieve($id, $persistent = true) + { + $data = null; + + // Use the internal cache if possible. + if (isset($this->cache[$id])) + { + return $this->cache[$id]; + } + + // Use the external cache if data is persistent. + if ($persistent) + { + $data = JFactory::getCache($this->context, 'output')->get($id); + $data = $data ? unserialize($data) : null; + } + + // Store the data in internal cache. + if ($data) + { + $this->cache[$id] = $data; + } + + return $data; + } + + /** + * Method to store data in cache. + * + * @param string $id The cache store id. + * @param mixed $data The data to cache. + * @param boolean $persistent Flag to enable the use of external cache. [optional] + * + * @return boolean True on success, false on failure. + * + * @since 2.5 + */ + protected function store($id, $data, $persistent = true) + { + // Store the data in internal cache. + $this->cache[$id] = $data; + + // Store the data in external cache if data is persistent. + if ($persistent) + { + return JFactory::getCache($this->context, 'output')->store(serialize($data), $id); + } + + return true; + } +} diff --git a/Sites/pages/components/com_finder/models/suggestions.php b/Sites/pages/components/com_finder/models/suggestions.php new file mode 100644 index 00000000..f4fb2c27 --- /dev/null +++ b/Sites/pages/components/com_finder/models/suggestions.php @@ -0,0 +1,182 @@ + $v) + { + $items[$k] = $v->term; + } + + return $items; + } + + /** + * Method to build a database query to load the list data. + * + * @return JDatabaseQuery A database query + * + * @since 2.5 + */ + protected function getListQuery() + { + $user = JFactory::getUser(); + $groups = \Joomla\Utilities\ArrayHelper::toInteger($user->getAuthorisedViewLevels()); + + // Create a new query object. + $db = $this->getDbo(); + $termIdQuery = $db->getQuery(true); + $termQuery = $db->getQuery(true); + + // Limit term count to a reasonable number of results to reduce main query join size + $termIdQuery->select('ti.term_id') + ->from($db->quoteName('#__finder_terms', 'ti')) + ->where('ti.term LIKE ' . $db->quote($db->escape($this->getState('input'), true) . '%', false)) + ->where('ti.common = 0') + ->where('ti.language IN (' . $db->quote($this->getState('language')) . ', ' . $db->quote('*') . ')') + ->order('ti.links DESC') + ->order('ti.weight DESC'); + + $termIds = $db->setQuery($termIdQuery, 0, 100)->loadColumn(); + + // Early return on term mismatch + if (!count($termIds)) + { + return $termIdQuery; + } + + $termIdString = implode(',', $termIds); + + // Select required fields + $termQuery->select('DISTINCT(t.term)') + ->from($db->quoteName('#__finder_terms') . ' AS t') + ->where('t.term_id IN (' . $termIdString . ')') + ->order('t.links DESC') + ->order('t.weight DESC'); + + // Determine the relevant mapping table suffix by inverting the logic from drivers + $mappingTableSuffix = StringHelper::substr(md5(StringHelper::substr($this->getState('input'), 0, 1)), 0, 1); + + // Join mapping table for term <-> link relation + $mappingTable = $db->quoteName('#__finder_links_terms' . $mappingTableSuffix); + $termQuery->join('INNER', $mappingTable . ' AS tm ON tm.term_id = t.term_id'); + + // Join links table + $termQuery->join('INNER', $db->quoteName('#__finder_links') . ' AS l ON (tm.link_id = l.link_id)') + ->where('l.access IN (' . implode(',', $groups) . ')') + ->where('l.state = 1') + ->where('l.published = 1'); + + return $termQuery; + } + + /** + * Method to get a store id based on model the configuration state. + * + * This is necessary because the model is used by the component and + * different modules that might need different sets of data or different + * ordering requirements. + * + * @param string $id An identifier string to generate the store id. [optional] + * + * @return string A store id. + * + * @since 2.5 + */ + protected function getStoreId($id = '') + { + // Add the search query state. + $id .= ':' . $this->getState('input'); + $id .= ':' . $this->getState('language'); + + // Add the list state. + $id .= ':' . $this->getState('list.start'); + $id .= ':' . $this->getState('list.limit'); + + return parent::getStoreId($id); + } + + /** + * Method to auto-populate the model state. Calling getState in this method will result in recursion. + * + * @param string $ordering An optional ordering field. + * @param string $direction An optional direction (asc|desc). + * + * @return void + * + * @since 2.5 + */ + protected function populateState($ordering = null, $direction = null) + { + // Get the configuration options. + $app = JFactory::getApplication(); + $input = $app->input; + $params = JComponentHelper::getParams('com_finder'); + $user = JFactory::getUser(); + + // Get the query input. + $this->setState('input', $input->request->get('q', '', 'string')); + + // Set the query language + if (JLanguageMultilang::isEnabled()) + { + $lang = JFactory::getLanguage()->getTag(); + } + else + { + $lang = FinderIndexerHelper::getDefaultLanguage(); + } + + $lang = FinderIndexerHelper::getPrimaryLanguage($lang); + $this->setState('language', $lang); + + // Load the list state. + $this->setState('list.start', 0); + $this->setState('list.limit', 10); + + // Load the parameters. + $this->setState('params', $params); + + // Load the user state. + $this->setState('user.id', (int) $user->get('id')); + } +} diff --git a/Sites/pages/components/com_finder/router.php b/Sites/pages/components/com_finder/router.php new file mode 100644 index 00000000..5e7d56ca --- /dev/null +++ b/Sites/pages/components/com_finder/router.php @@ -0,0 +1,162 @@ +menu->getItem($query['Itemid']); + + // Check if the view matches. + if ($item && isset($item->query['view']) && isset($query['view']) && $item->query['view'] === $query['view']) + { + unset($query['view']); + } + + // Check if the search query filter matches. + if ($item && isset($item->query['f']) && isset($query['f']) && $item->query['f'] === $query['f']) + { + unset($query['f']); + } + + // Check if the search query string matches. + if ($item && isset($item->query['q']) && isset($query['q']) && $item->query['q'] === $query['q']) + { + unset($query['q']); + } + + return $segments; + } + + /* + * Lastly, handle a route with no menu item id. Fortunately, we only need + * to deal with the view as the other route variables are supposed to stay + * in the query string. + */ + if (isset($query['view'])) + { + // Add the view to the segments. + $segments[] = $query['view']; + unset($query['view']); + } + + $total = count($segments); + + for ($i = 0; $i < $total; $i++) + { + $segments[$i] = str_replace(':', '-', $segments[$i]); + } + + return $segments; + } + + /** + * Parse the segments of a URL. + * + * @param array &$segments The segments of the URL to parse. + * + * @return array The URL attributes to be used by the application. + * + * @since 3.3 + */ + public function parse(&$segments) + { + $total = count($segments); + $vars = array(); + + for ($i = 0; $i < $total; $i++) + { + $segments[$i] = preg_replace('/-/', ':', $segments[$i], 1); + } + + // Check if the view segment is set and it equals search or advanced. + if (isset($segments[0]) && ($segments[0] === 'search' || $segments[0] === 'advanced')) + { + $vars['view'] = $segments[0]; + } + + return $vars; + } +} + +/** + * Finder router functions + * + * These functions are proxys for the new router interface + * for old SEF extensions. + * + * @param array &$query An array of URL arguments + * + * @return array The URL arguments to use to assemble the subsequent URL. + * + * @deprecated 4.0 Use Class based routers instead + */ +function FinderBuildRoute(&$query) +{ + $router = new FinderRouter; + + return $router->build($query); +} + +/** + * Finder router functions + * + * These functions are proxys for the new router interface + * for old SEF extensions. + * + * @param array $segments The segments of the URL to parse. + * + * @return array The URL attributes to be used by the application. + * + * @deprecated 4.0 Use Class based routers instead + */ +function FinderParseRoute($segments) +{ + $router = new FinderRouter; + + return $router->parse($segments); +} diff --git a/Sites/pages/components/com_finder/views/search/tmpl/default.php b/Sites/pages/components/com_finder/views/search/tmpl/default.php new file mode 100644 index 00000000..58e9a2e4 --- /dev/null +++ b/Sites/pages/components/com_finder/views/search/tmpl/default.php @@ -0,0 +1,39 @@ + 'auto', 'relative' => true)); + +?> +
      + params->get('show_page_heading')) : ?> +

      + escape($this->params->get('page_heading'))) : ?> + escape($this->params->get('page_heading')); ?> + + escape($this->params->get('page_title')); ?> + +

      + + params->get('show_search_form', 1)) : ?> +
      + loadTemplate('form'); ?> +
      + + + query->search === true) : ?> +
      + loadTemplate('results'); ?> +
      + +
      diff --git a/Sites/pages/components/com_finder/views/search/tmpl/default.xml b/Sites/pages/components/com_finder/views/search/tmpl/default.xml new file mode 100644 index 00000000..7e13ae76 --- /dev/null +++ b/Sites/pages/components/com_finder/views/search/tmpl/default.xml @@ -0,0 +1,217 @@ + + + + + + + + + + +
      + + +
      +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + +
      +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      +
      + + + + + +
      +
      +
      diff --git a/Sites/pages/components/com_finder/views/search/tmpl/default_form.php b/Sites/pages/components/com_finder/views/search/tmpl/default_form.php new file mode 100644 index 00000000..224b894c --- /dev/null +++ b/Sites/pages/components/com_finder/views/search/tmpl/default_form.php @@ -0,0 +1,109 @@ +params->get('show_advanced', 1) || $this->params->get('show_autosuggest', 1)) +{ + JHtml::_('jquery.framework'); + + $script = " +jQuery(function() {"; + + if ($this->params->get('show_advanced', 1)) + { + /* + * This segment of code disables select boxes that have no value when the + * form is submitted so that the URL doesn't get blown up with null values. + */ + $script .= " + jQuery('#finder-search').on('submit', function(e){ + e.stopPropagation(); + // Disable select boxes with no value selected. + jQuery('#advancedSearch').find('select').each(function(index, el) { + var el = jQuery(el); + if(!el.val()){ + el.attr('disabled', 'disabled'); + } + }); + });"; + } + + /* + * This segment of code sets up the autocompleter. + */ + if ($this->params->get('show_autosuggest', 1)) + { + JHtml::_('script', 'jui/jquery.autocomplete.min.js', array('version' => 'auto', 'relative' => true)); + + $script .= " + var suggest = jQuery('#q').autocomplete({ + serviceUrl: '" . JRoute::_('index.php?option=com_finder&task=suggestions.suggest&format=json&tmpl=component') . "', + paramName: 'q', + minChars: 1, + maxHeight: 400, + width: 300, + zIndex: 9999, + deferRequestBy: 500 + });"; + } + + $script .= " +});"; + + JFactory::getDocument()->addScriptDeclaration($script); +} + +?> + diff --git a/Sites/pages/components/com_finder/views/search/tmpl/default_result.php b/Sites/pages/components/com_finder/views/search/tmpl/default_result.php new file mode 100644 index 00000000..d69610d8 --- /dev/null +++ b/Sites/pages/components/com_finder/views/search/tmpl/default_result.php @@ -0,0 +1,77 @@ +result->mime) ? 'mime-' . $this->result->mime : null; + +$show_description = $this->params->get('show_description', 1); + +if ($show_description) +{ + // Calculate number of characters to display around the result + $term_length = StringHelper::strlen($this->query->input); + $desc_length = $this->params->get('description_length', 255); + $pad_length = $term_length < $desc_length ? (int) floor(($desc_length - $term_length) / 2) : 0; + + // Make sure we highlight term both in introtext and fulltext + if (!empty($this->result->summary) && !empty($this->result->body)) + { + $full_description = FinderIndexerHelper::parse($this->result->summary . $this->result->body); + } + else + { + $full_description = $this->result->description; + } + + // Find the position of the search term + $pos = $term_length ? StringHelper::strpos(StringHelper::strtolower($full_description), StringHelper::strtolower($this->query->input)) : false; + + // Find a potential start point + $start = ($pos && $pos > $pad_length) ? $pos - $pad_length : 0; + + // Find a space between $start and $pos, start right after it. + $space = StringHelper::strpos($full_description, ' ', $start > 0 ? $start - 1 : 0); + $start = ($space && $space < $pos) ? $space + 1 : $start; + + $description = JHtml::_('string.truncate', StringHelper::substr($full_description, $start), $desc_length, true); +} + +$route = $this->result->route; + +// Get the route with highlighting information. +if (!empty($this->query->highlight) + && empty($this->result->mime) + && $this->params->get('highlight_terms', 1) + && JPluginHelper::isEnabled('system', 'highlight')) +{ + $route .= '&highlight=' . base64_encode(json_encode($this->query->highlight)); +} + +?> +
    • +

      + + result->title; ?> + +

      + +

      + +

      + + params->get('show_url', 1)) : ?> +
      + baseUrl, JRoute::_($this->result->route); ?> +
      + +
    • diff --git a/Sites/pages/components/com_finder/views/search/tmpl/default_results.php b/Sites/pages/components/com_finder/views/search/tmpl/default_results.php new file mode 100644 index 00000000..fabee990 --- /dev/null +++ b/Sites/pages/components/com_finder/views/search/tmpl/default_results.php @@ -0,0 +1,69 @@ + + +suggested && $this->params->get('show_suggested_query', 1)) || ($this->explained && $this->params->get('show_explained_query', 1))) : ?> +
      + + suggested && $this->params->get('show_suggested_query', 1)) : ?> + + query->toUri()); ?> + setVar('q', $this->suggested); ?> + + toString(array('path', 'query'))); ?> + ' . $this->escape($this->suggested) . ''; ?> + + explained && $this->params->get('show_explained_query', 1)) : ?> + + explained; ?> + +
      + + +total === 0) || ($this->total === null)) : ?> +
      +

      + getLanguageFilter() ? '_MULTILANG' : ''; ?> +

      escape($this->query->input)); ?>

      +
      + + + + +query->highlight) && $this->params->get('highlight_terms', 1)) : ?> + query->highlight); ?> + + +
      +
        + baseUrl = JUri::getInstance()->toString(array('scheme', 'host', 'port')); ?> + results as $result) : ?> + result = &$result; ?> + getLayoutFile($this->result->layout); ?> + loadTemplate($layout); ?> + +
      +
      + +
      + +
      + + pagination->get('limitstart') + 1; ?> + pagination->get('total'); ?> + pagination->get('limit') * $this->pagination->get('pages.current'); ?> + $total ? $total : $limit); ?> + +
      +
      diff --git a/Sites/pages/components/com_finder/views/search/view.feed.php b/Sites/pages/components/com_finder/views/search/view.feed.php new file mode 100644 index 00000000..9dadf4e2 --- /dev/null +++ b/Sites/pages/components/com_finder/views/search/view.feed.php @@ -0,0 +1,105 @@ +input->set('limit', $app->get('feed_limit')); + + // Get view data. + $state = $this->get('State'); + $params = $state->get('params'); + $query = $this->get('Query'); + $results = $this->get('Results'); + + // Push out the query data. + JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html'); + $explained = JHtml::_('query.explained', $query); + + // Set the document title. + $title = $params->get('page_title', ''); + + if (empty($title)) + { + $title = $app->get('sitename'); + } + elseif ($app->get('sitename_pagetitles', 0) == 1) + { + $title = JText::sprintf('JPAGETITLE', $app->get('sitename'), $title); + } + elseif ($app->get('sitename_pagetitles', 0) == 2) + { + $title = JText::sprintf('JPAGETITLE', $title, $app->get('sitename')); + } + + $this->document->setTitle($title); + + // Configure the document description. + if (!empty($explained)) + { + $this->document->setDescription(html_entity_decode(strip_tags($explained), ENT_QUOTES, 'UTF-8')); + } + + // Set the document link. + $this->document->link = JRoute::_($query->toUri()); + + // If we don't have any results, we are done. + if (empty($results)) + { + return; + } + + // Convert the results to feed entries. + foreach ($results as $result) + { + // Convert the result to a feed entry. + $item = new JFeedItem; + $item->title = $result->title; + $item->link = JRoute::_($result->route); + $item->description = $result->description; + + // Use Unix date to cope for non-english languages + $item->date = (int) $result->start_date ? JHtml::_('date', $result->start_date, 'U') : $result->indexdate; + + // Get the taxonomy data. + $taxonomy = $result->getTaxonomy(); + + // Add the category to the feed if available. + if (isset($taxonomy['Category'])) + { + $node = array_pop($taxonomy['Category']); + $item->category = $node->title; + } + + // Loads item info into RSS array + $this->document->addItem($item); + } + } +} diff --git a/Sites/pages/components/com_finder/views/search/view.html.php b/Sites/pages/components/com_finder/views/search/view.html.php new file mode 100644 index 00000000..fdbb1d2d --- /dev/null +++ b/Sites/pages/components/com_finder/views/search/view.html.php @@ -0,0 +1,311 @@ +getParams(); + + // Get view data. + $state = $this->get('State'); + $query = $this->get('Query'); + JDEBUG ? JProfiler::getInstance('Application')->mark('afterFinderQuery') : null; + $results = $this->get('Results'); + JDEBUG ? JProfiler::getInstance('Application')->mark('afterFinderResults') : null; + $total = $this->get('Total'); + JDEBUG ? JProfiler::getInstance('Application')->mark('afterFinderTotal') : null; + $pagination = $this->get('Pagination'); + JDEBUG ? JProfiler::getInstance('Application')->mark('afterFinderPagination') : null; + + // Flag indicates to not add limitstart=0 to URL + $pagination->hideEmptyLimitstart = true; + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + JError::raiseError(500, implode("\n", $errors)); + + return false; + } + + // Configure the pathway. + if (!empty($query->input)) + { + $app->getPathway()->addItem($this->escape($query->input)); + } + + // Push out the view data. + $this->state = &$state; + $this->params = &$params; + $this->query = &$query; + $this->results = &$results; + $this->total = &$total; + $this->pagination = &$pagination; + + // Check for a double quote in the query string. + if (strpos($this->query->input, '"')) + { + // Get the application router. + $router = &$app::getRouter(); + + // Fix the q variable in the URL. + if ($router->getVar('q') !== $this->query->input) + { + $router->setVar('q', $this->query->input); + } + } + + // Log the search + SearchHelper::logSearch($this->query->input, 'com_finder'); + + // Push out the query data. + JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html'); + $this->suggested = JHtml::_('query.suggested', $query); + $this->explained = JHtml::_('query.explained', $query); + + // Escape strings for HTML output + $this->pageclass_sfx = htmlspecialchars($params->get('pageclass_sfx')); + + // Check for layout override only if this is not the active menu item + // If it is the active menu item, then the view and category id will match + $active = $app->getMenu()->getActive(); + + if (isset($active->query['layout'])) + { + // We need to set the layout in case this is an alternative menu item (with an alternative layout) + $this->setLayout($active->query['layout']); + } + + $this->prepareDocument($query); + + JDEBUG ? JProfiler::getInstance('Application')->mark('beforeFinderLayout') : null; + + parent::display($tpl); + + JDEBUG ? JProfiler::getInstance('Application')->mark('afterFinderLayout') : null; + } + + /** + * Method to get hidden input fields for a get form so that control variables + * are not lost upon form submission + * + * @return string A string of hidden input form fields + * + * @since 2.5 + */ + protected function getFields() + { + $fields = null; + + // Get the URI. + $uri = JUri::getInstance(JRoute::_($this->query->toUri())); + $uri->delVar('q'); + $uri->delVar('o'); + $uri->delVar('t'); + $uri->delVar('d1'); + $uri->delVar('d2'); + $uri->delVar('w1'); + $uri->delVar('w2'); + $elements = $uri->getQuery(true); + + // Create hidden input elements for each part of the URI. + foreach ($elements as $n => $v) + { + if (is_scalar($v)) + { + $fields .= ''; + } + } + + return $fields; + } + + /** + * Method to get the layout file for a search result object. + * + * @param string $layout The layout file to check. [optional] + * + * @return string The layout file to use. + * + * @since 2.5 + */ + protected function getLayoutFile($layout = null) + { + // Create and sanitize the file name. + $file = $this->_layout . '_' . preg_replace('/[^A-Z0-9_\.-]/i', '', $layout); + + // Check if the file exists. + jimport('joomla.filesystem.path'); + $filetofind = $this->_createFileName('template', array('name' => $file)); + $exists = JPath::find($this->_path['template'], $filetofind); + + return ($exists ? $layout : 'result'); + } + + /** + * Prepares the document + * + * @param FinderIndexerQuery $query The search query + * + * @return void + * + * @since 2.5 + */ + protected function prepareDocument($query) + { + $app = JFactory::getApplication(); + $menus = $app->getMenu(); + $title = null; + + // Because the application sets a default page title, + // we need to get it from the menu item itself + $menu = $menus->getActive(); + + if ($menu) + { + $this->params->def('page_heading', $this->params->get('page_title', $menu->title)); + } + else + { + $this->params->def('page_heading', JText::_('COM_FINDER_DEFAULT_PAGE_TITLE')); + } + + $title = $this->params->get('page_title', ''); + + if (empty($title)) + { + $title = $app->get('sitename'); + } + elseif ($app->get('sitename_pagetitles', 0) == 1) + { + $title = JText::sprintf('JPAGETITLE', $app->get('sitename'), $title); + } + elseif ($app->get('sitename_pagetitles', 0) == 2) + { + $title = JText::sprintf('JPAGETITLE', $title, $app->get('sitename')); + } + + $this->document->setTitle($title); + + if ($layout = $this->params->get('article_layout')) + { + $this->setLayout($layout); + } + + // Configure the document meta-description. + if (!empty($this->explained)) + { + $explained = $this->escape(html_entity_decode(strip_tags($this->explained), ENT_QUOTES, 'UTF-8')); + $this->document->setDescription($explained); + } + elseif ($this->params->get('menu-meta_description')) + { + $this->document->setDescription($this->params->get('menu-meta_description')); + } + + // Configure the document meta-keywords. + if (!empty($query->highlight)) + { + $this->document->setMetaData('keywords', implode(', ', $query->highlight)); + } + elseif ($this->params->get('menu-meta_keywords')) + { + $this->document->setMetadata('keywords', $this->params->get('menu-meta_keywords')); + } + + if ($this->params->get('robots')) + { + $this->document->setMetadata('robots', $this->params->get('robots')); + } + + // Add feed link to the document head. + if ($this->params->get('show_feed_link', 1) == 1) + { + // Add the RSS link. + $props = array('type' => 'application/rss+xml', 'title' => 'RSS 2.0'); + $route = JRoute::_($this->query->toUri() . '&format=feed&type=rss'); + $this->document->addHeadLink($route, 'alternate', 'rel', $props); + + // Add the ATOM link. + $props = array('type' => 'application/atom+xml', 'title' => 'Atom 1.0'); + $route = JRoute::_($this->query->toUri() . '&format=feed&type=atom'); + $this->document->addHeadLink($route, 'alternate', 'rel', $props); + } + } +} diff --git a/Sites/pages/components/com_finder/views/search/view.opensearch.php b/Sites/pages/components/com_finder/views/search/view.opensearch.php new file mode 100644 index 00000000..c994fe84 --- /dev/null +++ b/Sites/pages/components/com_finder/views/search/view.opensearch.php @@ -0,0 +1,53 @@ +setShortName($params->get('opensearch_name', $app->get('sitename'))); + $doc->setDescription($params->get('opensearch_description', $app->get('MetaDesc'))); + + // Add the URL for the search + $searchUri = JUri::base() . 'index.php?option=com_finder&q={searchTerms}'; + + // Find the menu item for the search + $menu = $app->getMenu(); + $items = $menu->getItems('link', 'index.php?option=com_finder&view=search'); + + if (isset($items[0])) + { + $searchUri .= '&Itemid=' . $items[0]->id; + } + + $htmlSearch = new JOpenSearchUrl; + $htmlSearch->template = JRoute::_($searchUri); + $doc->addUrl($htmlSearch); + } +} diff --git a/Sites/pages/components/com_mailto/controller.php b/Sites/pages/components/com_mailto/controller.php new file mode 100644 index 00000000..49ba6837 --- /dev/null +++ b/Sites/pages/components/com_mailto/controller.php @@ -0,0 +1,169 @@ +input->set('view', 'mailto'); + $this->display(); + } + + /** + * Send the message and display a notice + * + * @return void + * + * @since 1.5 + */ + public function send() + { + // Check for request forgeries + $this->checkToken(); + + $app = JFactory::getApplication(); + $model = $this->getModel('mailto'); + $data = $model->getData(); + + // Validate the posted data. + $form = $model->getForm(); + + if (!$form) + { + JError::raiseError(500, $model->getError()); + + return false; + } + + if (!$model->validate($form, $data)) + { + $errors = $model->getErrors(); + + foreach ($errors as $error) + { + $errorMessage = $error; + + if ($error instanceof Exception) + { + $errorMessage = $error->getMessage(); + } + + $app->enqueueMessage($errorMessage, 'error'); + } + + return $this->mailto(); + } + + // An array of email headers we do not want to allow as input + $headers = array ( + 'Content-Type:', + 'MIME-Version:', + 'Content-Transfer-Encoding:', + 'bcc:', + 'cc:' + ); + + /* + * Here is the meat and potatoes of the header injection test. We + * iterate over the array of form input and check for header strings. + * If we find one, send an unauthorized header and die. + */ + foreach ($data as $key => $value) + { + foreach ($headers as $header) + { + if (is_string($value) && strpos($value, $header) !== false) + { + JError::raiseError(403, ''); + } + } + } + + /* + * Free up memory + */ + unset($headers, $fields); + + $siteName = $app->get('sitename'); + $link = MailtoHelper::validateHash($this->input->post->get('link', '', 'post')); + + // Verify that this is a local link + if (!$link || !JUri::isInternal($link)) + { + // Non-local url... + JError::raiseNotice(500, JText::_('COM_MAILTO_EMAIL_NOT_SENT')); + + return $this->mailto(); + } + + $subject_default = JText::sprintf('COM_MAILTO_SENT_BY', $data['sender']); + $subject = $data['subject'] !== '' ? $data['subject'] : $subject_default; + + // Check for a valid to address + $error = false; + + if (!$data['emailto'] || !JMailHelper::isEmailAddress($data['emailto'])) + { + $error = JText::sprintf('COM_MAILTO_EMAIL_INVALID', $data['emailto']); + + JError::raiseWarning(0, $error); + } + + // Check for a valid from address + if (!$data['emailfrom'] || !JMailHelper::isEmailAddress($data['emailfrom'])) + { + $error = JText::sprintf('COM_MAILTO_EMAIL_INVALID', $data['emailfrom']); + + JError::raiseWarning(0, $error); + } + + if ($error) + { + return $this->mailto(); + } + + // Build the message to send + $msg = JText::_('COM_MAILTO_EMAIL_MSG'); + $body = sprintf($msg, $siteName, $data['sender'], $data['emailfrom'], $link); + + // Clean the email data + $subject = JMailHelper::cleanSubject($subject); + $body = JMailHelper::cleanBody($body); + + // To send we need to use punycode. + $data['emailfrom'] = JStringPunycode::emailToPunycode($data['emailfrom']); + $data['emailfrom'] = JMailHelper::cleanAddress($data['emailfrom']); + $data['emailto'] = JStringPunycode::emailToPunycode($data['emailto']); + + // Send the email + if (JFactory::getMailer()->sendMail($data['emailfrom'], $data['sender'], $data['emailto'], $subject, $body) !== true) + { + JError::raiseNotice(500, JText::_('COM_MAILTO_EMAIL_NOT_SENT')); + + return $this->mailto(); + } + + $this->input->set('view', 'sent'); + $this->display(); + } +} diff --git a/Sites/pages/components/com_mailto/helpers/mailto.php b/Sites/pages/components/com_mailto/helpers/mailto.php new file mode 100644 index 00000000..21a23739 --- /dev/null +++ b/Sites/pages/components/com_mailto/helpers/mailto.php @@ -0,0 +1,103 @@ +get('com_mailto.links', array()); + + if (!isset($mailto_links[$hash])) + { + $mailto_links[$hash] = new stdClass; + } + + $mailto_links[$hash]->link = $url; + $mailto_links[$hash]->expiry = time(); + $session->set('com_mailto.links', $mailto_links); + + return $hash; + } + + /** + * Checks if a URL is a Flash file + * + * @param string $hash File hash + * + * @return URL + */ + public static function validateHash($hash) + { + $retval = false; + $session = JFactory::getSession(); + + self::cleanHashes(); + $mailto_links = $session->get('com_mailto.links', array()); + + if (isset($mailto_links[$hash])) + { + $retval = $mailto_links[$hash]->link; + } + + return $retval; + } + + /** + * Cleans out old hashes + * + * @param integer $lifetime How old are the hashes we want to remove + * + * @return void + * + * @since 1.6.1 + */ + public static function cleanHashes($lifetime = 1440) + { + // Flag for if we've cleaned on this cycle + static $cleaned = false; + + if (!$cleaned) + { + $past = time() - $lifetime; + $session = JFactory::getSession(); + $mailto_links = $session->get('com_mailto.links', array()); + + foreach ($mailto_links as $index => $link) + { + if ($link->expiry < $past) + { + unset($mailto_links[$index]); + } + } + + $session->set('com_mailto.links', $mailto_links); + $cleaned = true; + } + } +} diff --git a/Sites/pages/components/com_mailto/mailto.php b/Sites/pages/components/com_mailto/mailto.php new file mode 100644 index 00000000..0b519d41 --- /dev/null +++ b/Sites/pages/components/com_mailto/mailto.php @@ -0,0 +1,16 @@ +registerDefaultTask('mailto'); +$controller->execute(JFactory::getApplication()->input->get('task')); diff --git a/Sites/pages/components/com_mailto/mailto.xml b/Sites/pages/components/com_mailto/mailto.xml new file mode 100644 index 00000000..65da4c6b --- /dev/null +++ b/Sites/pages/components/com_mailto/mailto.xml @@ -0,0 +1,29 @@ + + + com_mailto + Joomla! Project + April 2006 + (C) 2005 - 2020 Open Source Matters. All rights reserved. + GNU General Public License version 2 or later; see LICENSE.txt + admin@joomla.org + www.joomla.org + 3.0.0 + COM_MAILTO_XML_DESCRIPTION + + controller.php + index.html + mailto.php + views + + + language/en-GB.com_mailto.ini + + + + index.html + + + language/en-GB.com_mailto.sys.ini + + + diff --git a/Sites/pages/components/com_mailto/models/forms/mailto.xml b/Sites/pages/components/com_mailto/models/forms/mailto.xml new file mode 100644 index 00000000..0469129f --- /dev/null +++ b/Sites/pages/components/com_mailto/models/forms/mailto.xml @@ -0,0 +1,51 @@ + +
      +
      + + + + + + + + + +
      +
      diff --git a/Sites/pages/components/com_mailto/models/mailto.php b/Sites/pages/components/com_mailto/models/mailto.php new file mode 100644 index 00000000..5dc119f8 --- /dev/null +++ b/Sites/pages/components/com_mailto/models/mailto.php @@ -0,0 +1,105 @@ +loadForm('com_mailto.mailto', 'mailto', array('load_data' => $loadData)); + + if (empty($form)) + { + return false; + } + + return $form; + } + + /** + * Method to get the data that should be injected in the form. + * + * @return array The default data is an empty array. + * + * @since 3.8.9 + */ + protected function loadFormData() + { + $user = JFactory::getUser(); + $app = JFactory::getApplication(); + $data = $app->getUserState('mailto.mailto.form.data', array()); + + $data['link'] = urldecode($app->input->get('link', '', 'BASE64')); + + if ($data['link'] == '') + { + JError::raiseError(403, JText::_('COM_MAILTO_LINK_IS_MISSING')); + + return false; + } + + // Load with previous data, if it exists + $data['sender'] = $app->input->post->getString('sender', ''); + $data['subject'] = $app->input->post->getString('subject', ''); + $data['emailfrom'] = JStringPunycode::emailToPunycode($app->input->post->getString('emailfrom', '')); + $data['emailto'] = JStringPunycode::emailToPunycode($app->input->post->getString('emailto', '')); + + if (!$user->guest) + { + $data['sender'] = $user->name; + $data['emailfrom'] = $user->email; + } + + $app->setUserState('mailto.mailto.form.data', $data); + + $this->preprocessData('com_mailto.mailto', $data); + + return $data; + } + + /** + * Get the request data + * + * @return array The requested data + * + * @since 3.8.9 + */ + public function getData() + { + $input = JFactory::getApplication()->input; + + $data['emailto'] = $input->get('emailto', '', 'string'); + $data['sender'] = $input->get('sender', '', 'string'); + $data['emailfrom'] = $input->get('emailfrom', '', 'string'); + $data['subject'] = $input->get('subject', '', 'string'); + $data['consentbox'] = $input->get('consentbox', '', 'string'); + + return $data; + } +} diff --git a/Sites/pages/components/com_mailto/views/mailto/tmpl/default.php b/Sites/pages/components/com_mailto/views/mailto/tmpl/default.php new file mode 100644 index 00000000..94a5446a --- /dev/null +++ b/Sites/pages/components/com_mailto/views/mailto/tmpl/default.php @@ -0,0 +1,52 @@ + +
      +

      + +

      + +
      +
      + form->getFieldset('') as $field) : ?> + hidden) : ?> + renderField(); ?> + + +
      +
      + + +
      +
      +
      + + + + + + +
      +
      diff --git a/Sites/pages/components/com_mailto/views/mailto/view.html.php b/Sites/pages/components/com_mailto/views/mailto/view.html.php new file mode 100644 index 00000000..9e42890d --- /dev/null +++ b/Sites/pages/components/com_mailto/views/mailto/view.html.php @@ -0,0 +1,35 @@ +form = $this->get('Form'); + $this->link = urldecode(JFactory::getApplication()->input->get('link', '', 'BASE64')); + + return parent::display($tpl); + } +} diff --git a/Sites/pages/components/com_mailto/views/sent/tmpl/default.php b/Sites/pages/components/com_mailto/views/sent/tmpl/default.php new file mode 100644 index 00000000..226e6bb0 --- /dev/null +++ b/Sites/pages/components/com_mailto/views/sent/tmpl/default.php @@ -0,0 +1,22 @@ + +
      +
      + + + +
      +

      + +

      +
      diff --git a/Sites/pages/components/com_mailto/views/sent/view.html.php b/Sites/pages/components/com_mailto/views/sent/view.html.php new file mode 100644 index 00000000..12b0b91a --- /dev/null +++ b/Sites/pages/components/com_mailto/views/sent/view.html.php @@ -0,0 +1,19 @@ +load('com_media', JPATH_ADMINISTRATOR, null, false, true) +|| $lang->load('com_media', JPATH_SITE, null, false, true); + +// Hand processing over to the admin base file +require_once JPATH_COMPONENT_ADMINISTRATOR . '/media.php'; diff --git a/Sites/pages/components/com_menus/controller.php b/Sites/pages/components/com_menus/controller.php new file mode 100644 index 00000000..1bb08409 --- /dev/null +++ b/Sites/pages/components/com_menus/controller.php @@ -0,0 +1,41 @@ +input = JFactory::getApplication()->input; + + // Menus frontpage Editor Menu proxying: + if ($this->input->get('view') === 'items' && $this->input->get('layout') === 'modal') + { + JHtml::_('stylesheet', 'system/adminlist.css', array(), true); + $config['base_path'] = JPATH_COMPONENT_ADMINISTRATOR; + } + + parent::__construct($config); + } +} diff --git a/Sites/pages/components/com_menus/menus.php b/Sites/pages/components/com_menus/menus.php new file mode 100644 index 00000000..29f66409 --- /dev/null +++ b/Sites/pages/components/com_menus/menus.php @@ -0,0 +1,31 @@ +input->get('view') === 'items' && $app->input->get('layout') === 'modal') +{ + if (!JFactory::getUser()->authorise('core.create', 'com_menus')) + { + $app->enqueueMessage(JText::_('JERROR_ALERTNOAUTHOR'), 'warning'); + + return; + } +} + +$lang->load('com_menus', JPATH_ADMINISTRATOR); + +// Trigger the controller +$controller = JControllerLegacy::getInstance('Menus'); +$controller->execute($app->input->get('task')); +$controller->redirect(); diff --git a/Sites/pages/components/com_menus/models/forms/filter_items.xml b/Sites/pages/components/com_menus/models/forms/filter_items.xml new file mode 100644 index 00000000..b961df85 --- /dev/null +++ b/Sites/pages/components/com_menus/models/forms/filter_items.xml @@ -0,0 +1,117 @@ + +
      +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Sites/pages/components/com_modules/controller.php b/Sites/pages/components/com_modules/controller.php new file mode 100644 index 00000000..6e4d1038 --- /dev/null +++ b/Sites/pages/components/com_modules/controller.php @@ -0,0 +1,41 @@ +input = JFactory::getApplication()->input; + + // Modules frontpage Editor Module proxying: + if ($this->input->get('view') === 'modules' && $this->input->get('layout') === 'modal') + { + JHtml::_('stylesheet', 'system/adminlist.css', array('version' => 'auto', 'relative' => true)); + $config['base_path'] = JPATH_COMPONENT_ADMINISTRATOR; + } + + parent::__construct($config); + } +} diff --git a/Sites/pages/components/com_modules/models/forms/filter_modules.xml b/Sites/pages/components/com_modules/models/forms/filter_modules.xml new file mode 100644 index 00000000..a25bab10 --- /dev/null +++ b/Sites/pages/components/com_modules/models/forms/filter_modules.xml @@ -0,0 +1,82 @@ + +
      +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Sites/pages/components/com_modules/modules.php b/Sites/pages/components/com_modules/modules.php new file mode 100644 index 00000000..d6cbfdcf --- /dev/null +++ b/Sites/pages/components/com_modules/modules.php @@ -0,0 +1,36 @@ +load('com_modules', JPATH_ADMINISTRATOR); + +if ($app->input->get('view') === 'modules' && $app->input->get('layout') === 'modal') +{ + if (!JFactory::getUser()->authorise('core.create', 'com_modules')) + { + $app->enqueueMessage(JText::_('JERROR_ALERTNOAUTHOR'), 'warning'); + + return; + } +} + +if ($app->input->get('task') === 'module.orderPosition') +{ + $config['base_path'] = JPATH_COMPONENT_ADMINISTRATOR; +} + +// Trigger the controller +$controller = JControllerLegacy::getInstance('Modules', $config); +$controller->execute($app->input->get('task')); +$controller->redirect(); diff --git a/Sites/pages/components/com_newsfeeds/controller.php b/Sites/pages/components/com_newsfeeds/controller.php new file mode 100644 index 00000000..e336d4c8 --- /dev/null +++ b/Sites/pages/components/com_newsfeeds/controller.php @@ -0,0 +1,49 @@ +input->get('view', 'categories'); + $this->input->set('view', $vName); + + $user = JFactory::getUser(); + + if ($user->get('id') || ($this->input->getMethod() === 'POST' && $vName === 'category')) + { + $cachable = false; + } + + $safeurlparams = array('id' => 'INT', 'limit' => 'UINT', 'limitstart' => 'UINT', + 'filter_order' => 'CMD', 'filter_order_Dir' => 'CMD', 'lang' => 'CMD'); + + parent::display($cachable, $safeurlparams); + } +} diff --git a/Sites/pages/components/com_newsfeeds/helpers/association.php b/Sites/pages/components/com_newsfeeds/helpers/association.php new file mode 100644 index 00000000..57b935af --- /dev/null +++ b/Sites/pages/components/com_newsfeeds/helpers/association.php @@ -0,0 +1,63 @@ +input; + $view = $view === null ? $jinput->get('view') : $view; + $id = empty($id) ? $jinput->getInt('id') : $id; + + if ($view === 'newsfeed') + { + if ($id) + { + $associations = JLanguageAssociations::getAssociations('com_newsfeeds', '#__newsfeeds', 'com_newsfeeds.item', $id); + + $return = array(); + + foreach ($associations as $tag => $item) + { + $return[$tag] = NewsfeedsHelperRoute::getNewsfeedRoute($item->id, (int) $item->catid, $item->language); + } + + return $return; + } + } + + if ($view === 'category' || $view === 'categories') + { + return self::getCategoryAssociations($id, 'com_newsfeeds'); + } + + return array(); + } +} diff --git a/Sites/pages/components/com_newsfeeds/helpers/category.php b/Sites/pages/components/com_newsfeeds/helpers/category.php new file mode 100644 index 00000000..19dd1d1a --- /dev/null +++ b/Sites/pages/components/com_newsfeeds/helpers/category.php @@ -0,0 +1,31 @@ +router = $router; + } + + /** + * Preprocess the route for the com_newsfeeds component + * + * @param array &$query An array of URL arguments + * + * @return void + * + * @since 3.6 + * @deprecated 4.0 + */ + public function preprocess(&$query) + { + } + + /** + * Build the route for the com_newsfeeds component + * + * @param array &$query An array of URL arguments + * @param array &$segments The URL arguments to use to assemble the subsequent URL. + * + * @return void + * + * @since 3.6 + * @deprecated 4.0 + */ + public function build(&$query, &$segments) + { + // Get a menu item based on Itemid or currently active + $params = JComponentHelper::getParams('com_newsfeeds'); + $advanced = $params->get('sef_advanced_link', 0); + + if (empty($query['Itemid'])) + { + $menuItem = $this->router->menu->getActive(); + } + else + { + $menuItem = $this->router->menu->getItem($query['Itemid']); + } + + $mView = empty($menuItem->query['view']) ? null : $menuItem->query['view']; + $mId = empty($menuItem->query['id']) ? null : $menuItem->query['id']; + + if (isset($query['view'])) + { + $view = $query['view']; + + if (empty($menuItem) || $menuItem->component !== 'com_newsfeeds' || empty($query['Itemid'])) + { + $segments[] = $query['view']; + } + + unset($query['view']); + } + + // Are we dealing with a newsfeed that is attached to a menu item? + if (isset($query['view'], $query['id']) && $mView == $query['view'] && $mId == (int) $query['id']) + { + unset($query['view'], $query['catid'], $query['id']); + + return; + } + + if (isset($view) && ($view === 'category' || $view === 'newsfeed')) + { + if ($mId != (int) $query['id'] || $mView != $view) + { + if ($view === 'newsfeed' && isset($query['catid'])) + { + $catid = $query['catid']; + } + elseif (isset($query['id'])) + { + $catid = $query['id']; + } + + $menuCatid = $mId; + $categories = JCategories::getInstance('Newsfeeds'); + $category = $categories->get($catid); + + if ($category) + { + $path = $category->getPath(); + $path = array_reverse($path); + + $array = array(); + + foreach ($path as $id) + { + if ((int) $id === (int) $menuCatid) + { + break; + } + + if ($advanced) + { + list($tmp, $id) = explode(':', $id, 2); + } + + $array[] = $id; + } + + $segments = array_merge($segments, array_reverse($array)); + } + + if ($view === 'newsfeed') + { + if ($advanced) + { + list($tmp, $id) = explode(':', $query['id'], 2); + } + else + { + $id = $query['id']; + } + + $segments[] = $id; + } + } + + unset($query['id'], $query['catid']); + } + + if (isset($query['layout'])) + { + if (!empty($query['Itemid']) && isset($menuItem->query['layout'])) + { + if ($query['layout'] == $menuItem->query['layout']) + { + unset($query['layout']); + } + } + else + { + if ($query['layout'] === 'default') + { + unset($query['layout']); + } + } + } + + $total = count($segments); + + for ($i = 0; $i < $total; $i++) + { + $segments[$i] = str_replace(':', '-', $segments[$i]); + } + } + + /** + * Parse the segments of a URL. + * + * @param array &$segments The segments of the URL to parse. + * @param array &$vars The URL attributes to be used by the application. + * + * @return void + * + * @since 3.6 + * @deprecated 4.0 + */ + public function parse(&$segments, &$vars) + { + $total = count($segments); + + for ($i = 0; $i < $total; $i++) + { + $segments[$i] = preg_replace('/-/', ':', $segments[$i], 1); + } + + // Get the active menu item. + $item = $this->router->menu->getActive(); + $params = JComponentHelper::getParams('com_newsfeeds'); + $advanced = $params->get('sef_advanced_link', 0); + + // Count route segments + $count = count($segments); + + // Standard routing for newsfeeds. + if (!isset($item)) + { + $vars['view'] = $segments[0]; + $vars['id'] = $segments[$count - 1]; + + return; + } + + // From the categories view, we can only jump to a category. + $id = (isset($item->query['id']) && $item->query['id'] > 1) ? $item->query['id'] : 'root'; + $categories = JCategories::getInstance('Newsfeeds')->get($id)->getChildren(); + $vars['catid'] = $id; + $vars['id'] = $id; + $found = 0; + + foreach ($segments as $segment) + { + $segment = $advanced ? str_replace(':', '-', $segment) : $segment; + + foreach ($categories as $category) + { + if ($category->slug == $segment || $category->alias == $segment) + { + $vars['id'] = $category->id; + $vars['catid'] = $category->id; + $vars['view'] = 'category'; + $categories = $category->getChildren(); + $found = 1; + break; + } + } + + if ($found == 0) + { + if ($advanced) + { + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->select($db->quoteName('id')) + ->from('#__newsfeeds') + ->where($db->quoteName('catid') . ' = ' . (int) $vars['catid']) + ->where($db->quoteName('alias') . ' = ' . $db->quote($segment)); + $db->setQuery($query); + $nid = $db->loadResult(); + } + else + { + $nid = $segment; + } + + $vars['id'] = $nid; + $vars['view'] = 'newsfeed'; + } + + $found = 0; + } + } +} diff --git a/Sites/pages/components/com_newsfeeds/helpers/route.php b/Sites/pages/components/com_newsfeeds/helpers/route.php new file mode 100644 index 00000000..03d72a3f --- /dev/null +++ b/Sites/pages/components/com_newsfeeds/helpers/route.php @@ -0,0 +1,82 @@ + 1) + { + $link .= '&catid=' . $catid; + } + + if ($language && $language !== '*' && JLanguageMultilang::isEnabled()) + { + $link .= '&lang=' . $language; + } + + return $link; + } + + /** + * getCategoryRoute + * + * @param int $catid category id + * @param int $language language + * + * @return string + */ + public static function getCategoryRoute($catid, $language = 0) + { + if ($catid instanceof JCategoryNode) + { + $id = $catid->id; + } + else + { + $id = (int) $catid; + } + + if ($id < 1) + { + $link = ''; + } + else + { + // Create the link + $link = 'index.php?option=com_newsfeeds&view=category&id=' . $id; + + if ($language && $language !== '*' && JLanguageMultilang::isEnabled()) + { + $link .= '&lang=' . $language; + } + } + + return $link; + } +} diff --git a/Sites/pages/components/com_newsfeeds/models/categories.php b/Sites/pages/components/com_newsfeeds/models/categories.php new file mode 100644 index 00000000..214644bf --- /dev/null +++ b/Sites/pages/components/com_newsfeeds/models/categories.php @@ -0,0 +1,142 @@ +setState('filter.extension', $this->_extension); + + // Get the parent id if defined. + $parentId = $app->input->getInt('id'); + $this->setState('filter.parentId', $parentId); + + $params = $app->getParams(); + $this->setState('params', $params); + + $this->setState('filter.published', 1); + $this->setState('filter.access', true); + } + + /** + * Method to get a store id based on model configuration state. + * + * This is necessary because the model is used by the component and + * different modules that might need different sets of data or different + * ordering requirements. + * + * @param string $id A prefix for the store id. + * + * @return string A store id. + */ + protected function getStoreId($id = '') + { + // Compile the store id. + $id .= ':' . $this->getState('filter.extension'); + $id .= ':' . $this->getState('filter.published'); + $id .= ':' . $this->getState('filter.access'); + $id .= ':' . $this->getState('filter.parentId'); + + return parent::getStoreId($id); + } + + /** + * redefine the function an add some properties to make the styling more easy + * + * @return mixed An array of data items on success, false on failure. + */ + public function getItems() + { + if ($this->_items === null) + { + $app = JFactory::getApplication(); + $menu = $app->getMenu(); + $active = $menu->getActive(); + $params = new Registry; + + if ($active) + { + $params->loadString($active->params); + } + + $options = array(); + $options['countItems'] = $params->get('show_cat_items_cat', 1) || !$params->get('show_empty_categories_cat', 0); + $categories = JCategories::getInstance('Newsfeeds', $options); + $this->_parent = $categories->get($this->getState('filter.parentId', 'root')); + + if (is_object($this->_parent)) + { + $this->_items = $this->_parent->getChildren(); + } + else + { + $this->_items = false; + } + } + + return $this->_items; + } + + /** + * get the Parent + * + * @return null + */ + public function getParent() + { + if (!is_object($this->_parent)) + { + $this->getItems(); + } + + return $this->_parent; + } +} diff --git a/Sites/pages/components/com_newsfeeds/models/category.php b/Sites/pages/components/com_newsfeeds/models/category.php new file mode 100644 index 00000000..89f9d3fa --- /dev/null +++ b/Sites/pages/components/com_newsfeeds/models/category.php @@ -0,0 +1,377 @@ +_params)) + { + $params = new Registry; + $item->params = $params; + $params->loadString($item->params); + } + + // Some contexts may not use tags data at all, so we allow callers to disable loading tag data + if ($this->getState('load_tags', true)) + { + $item->tags = new JHelperTags; + $item->tags->getItemTags('com_newsfeeds.newsfeed', $item->id); + } + } + + return $items; + } + + /** + * Method to build an SQL query to load the list data. + * + * @return string An SQL query + * + * @since 1.6 + */ + protected function getListQuery() + { + $user = JFactory::getUser(); + $groups = implode(',', $user->getAuthorisedViewLevels()); + + // Create a new query object. + $db = $this->getDbo(); + $query = $db->getQuery(true); + + // Select required fields from the categories. + $query->select($this->getState('list.select', 'a.*')) + ->from($db->quoteName('#__newsfeeds') . ' AS a') + ->where('a.access IN (' . $groups . ')'); + + // Filter by category. + if ($categoryId = $this->getState('category.id')) + { + $query->where('a.catid = ' . (int) $categoryId) + ->join('LEFT', '#__categories AS c ON c.id = a.catid') + ->where('c.access IN (' . $groups . ')'); + } + + // Filter by state + $state = $this->getState('filter.published'); + + if (is_numeric($state)) + { + $query->where('a.published = ' . (int) $state); + } + else + { + $query->where('(a.published IN (0,1,2))'); + } + + // Filter by start and end dates. + $nullDate = $db->quote($db->getNullDate()); + $date = JFactory::getDate(); + $nowDate = $db->quote($date->format($db->getDateFormat())); + + if ($this->getState('filter.publish_date')) + { + $query->where('(a.publish_up = ' . $nullDate . ' OR a.publish_up <= ' . $nowDate . ')') + ->where('(a.publish_down = ' . $nullDate . ' OR a.publish_down >= ' . $nowDate . ')'); + } + + // Filter by search in title + $search = $this->getState('list.filter'); + + if (!empty($search)) + { + $search = $db->quote('%' . $db->escape($search, true) . '%'); + $query->where('(a.name LIKE ' . $search . ')'); + } + + // Filter by language + if ($this->getState('filter.language')) + { + $query->where('a.language in (' . $db->quote(JFactory::getLanguage()->getTag()) . ',' . $db->quote('*') . ')'); + } + + // Add the list ordering clause. + $query->order($db->escape($this->getState('list.ordering', 'a.ordering')) . ' ' . $db->escape($this->getState('list.direction', 'ASC'))); + + return $query; + } + + /** + * Method to auto-populate the model state. + * + * Note. Calling getState in this method will result in recursion. + * + * @param string $ordering An optional ordering field + * @param string $direction An optional direction [asc|desc] + * + * @return void + * + * @since 1.6 + * + * @throws Exception + */ + protected function populateState($ordering = null, $direction = null) + { + $app = JFactory::getApplication(); + $params = JComponentHelper::getParams('com_newsfeeds'); + + // List state information + $limit = $app->getUserStateFromRequest('global.list.limit', 'limit', $app->get('list_limit'), 'uint'); + $this->setState('list.limit', $limit); + + $limitstart = $app->input->get('limitstart', 0, 'uint'); + $this->setState('list.start', $limitstart); + + // Optional filter text + $this->setState('list.filter', $app->input->getString('filter-search')); + + $orderCol = $app->input->get('filter_order', 'ordering'); + + if (!in_array($orderCol, $this->filter_fields)) + { + $orderCol = 'ordering'; + } + + $this->setState('list.ordering', $orderCol); + + $listOrder = $app->input->get('filter_order_Dir', 'ASC'); + + if (!in_array(strtoupper($listOrder), array('ASC', 'DESC', ''))) + { + $listOrder = 'ASC'; + } + + $this->setState('list.direction', $listOrder); + + $id = $app->input->get('id', 0, 'int'); + $this->setState('category.id', $id); + + $user = JFactory::getUser(); + + if ((!$user->authorise('core.edit.state', 'com_newsfeeds')) && (!$user->authorise('core.edit', 'com_newsfeeds'))) + { + // Limit to published for people who can't edit or edit.state. + $this->setState('filter.published', 1); + + // Filter by start and end dates. + $this->setState('filter.publish_date', true); + } + + $this->setState('filter.language', JLanguageMultilang::isEnabled()); + + // Load the parameters. + $this->setState('params', $params); + } + + /** + * Method to get category data for the current category + * + * @return object + * + * @since 1.5 + */ + public function getCategory() + { + if (!is_object($this->_item)) + { + $app = JFactory::getApplication(); + $menu = $app->getMenu(); + $active = $menu->getActive(); + $params = new Registry; + + if ($active) + { + $params->loadString($active->params); + } + + $options = array(); + $options['countItems'] = $params->get('show_cat_items', 1) || $params->get('show_empty_categories', 0); + $categories = JCategories::getInstance('Newsfeeds', $options); + $this->_item = $categories->get($this->getState('category.id', 'root')); + + if (is_object($this->_item)) + { + $this->_children = $this->_item->getChildren(); + $this->_parent = false; + + if ($this->_item->getParent()) + { + $this->_parent = $this->_item->getParent(); + } + + $this->_rightsibling = $this->_item->getSibling(); + $this->_leftsibling = $this->_item->getSibling(false); + } + else + { + $this->_children = false; + $this->_parent = false; + } + } + + return $this->_item; + } + + /** + * Get the parent category. + * + * @return mixed An array of categories or false if an error occurs. + */ + public function getParent() + { + if (!is_object($this->_item)) + { + $this->getCategory(); + } + + return $this->_parent; + } + + /** + * Get the sibling (adjacent) categories. + * + * @return mixed An array of categories or false if an error occurs. + */ + public function &getLeftSibling() + { + if (!is_object($this->_item)) + { + $this->getCategory(); + } + + return $this->_leftsibling; + } + + /** + * Get the sibling (adjacent) categories. + * + * @return mixed An array of categories or false if an error occurs. + */ + public function &getRightSibling() + { + if (!is_object($this->_item)) + { + $this->getCategory(); + } + + return $this->_rightsibling; + } + + /** + * Get the child categories. + * + * @return mixed An array of categories or false if an error occurs. + */ + public function &getChildren() + { + if (!is_object($this->_item)) + { + $this->getCategory(); + } + + return $this->_children; + } + + /** + * Increment the hit counter for the category. + * + * @param int $pk Optional primary key of the category to increment. + * + * @return boolean True if successful; false otherwise and internal error set. + */ + public function hit($pk = 0) + { + $input = JFactory::getApplication()->input; + $hitcount = $input->getInt('hitcount', 1); + + if ($hitcount) + { + $pk = (!empty($pk)) ? $pk : (int) $this->getState('category.id'); + $table = JTable::getInstance('Category', 'JTable'); + $table->hit($pk); + } + + return true; + } +} diff --git a/Sites/pages/components/com_newsfeeds/models/newsfeed.php b/Sites/pages/components/com_newsfeeds/models/newsfeed.php new file mode 100644 index 00000000..7bb57a56 --- /dev/null +++ b/Sites/pages/components/com_newsfeeds/models/newsfeed.php @@ -0,0 +1,193 @@ +input->getInt('id'); + $this->setState('newsfeed.id', $pk); + + $offset = $app->input->get('limitstart', 0, 'uint'); + $this->setState('list.offset', $offset); + + // Load the parameters. + $params = $app->getParams(); + $this->setState('params', $params); + + $user = JFactory::getUser(); + + if ((!$user->authorise('core.edit.state', 'com_newsfeeds')) && (!$user->authorise('core.edit', 'com_newsfeeds'))) + { + $this->setState('filter.published', 1); + $this->setState('filter.archived', 2); + } + } + + /** + * Method to get newsfeed data. + * + * @param integer $pk The id of the newsfeed. + * + * @return mixed Menu item data object on success, false on failure. + * + * @since 1.6 + */ + public function &getItem($pk = null) + { + $pk = (!empty($pk)) ? $pk : (int) $this->getState('newsfeed.id'); + + if ($this->_item === null) + { + $this->_item = array(); + } + + if (!isset($this->_item[$pk])) + { + try + { + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select($this->getState('item.select', 'a.*')) + ->from('#__newsfeeds AS a'); + + // Join on category table. + $query->select('c.title AS category_title, c.alias AS category_alias, c.access AS category_access') + ->join('LEFT', '#__categories AS c on c.id = a.catid'); + + // Join on user table. + $query->select('u.name AS author') + ->join('LEFT', '#__users AS u on u.id = a.created_by'); + + // Join over the categories to get parent category titles + $query->select('parent.title as parent_title, parent.id as parent_id, parent.path as parent_route, parent.alias as parent_alias') + ->join('LEFT', '#__categories as parent ON parent.id = c.parent_id') + + ->where('a.id = ' . (int) $pk); + + // Filter by start and end dates. + $nullDate = $db->quote($db->getNullDate()); + $nowDate = $db->quote(JFactory::getDate()->toSql()); + + // Filter by published state. + $published = $this->getState('filter.published'); + $archived = $this->getState('filter.archived'); + + if (is_numeric($published)) + { + $query->where('(a.published = ' . (int) $published . ' OR a.published =' . (int) $archived . ')') + ->where('(a.publish_up = ' . $nullDate . ' OR a.publish_up <= ' . $nowDate . ')') + ->where('(a.publish_down = ' . $nullDate . ' OR a.publish_down >= ' . $nowDate . ')') + ->where('(c.published = ' . (int) $published . ' OR c.published =' . (int) $archived . ')'); + } + + $db->setQuery($query); + + $data = $db->loadObject(); + + if (empty($data)) + { + JError::raiseError(404, JText::_('COM_NEWSFEEDS_ERROR_FEED_NOT_FOUND')); + } + + // Check for published state if filter set. + + if ((is_numeric($published) || is_numeric($archived)) && $data->published != $published && $data->published != $archived) + { + JError::raiseError(404, JText::_('COM_NEWSFEEDS_ERROR_FEED_NOT_FOUND')); + } + + // Convert parameter fields to objects. + $registry = new Registry($data->params); + $data->params = clone $this->getState('params'); + $data->params->merge($registry); + + $data->metadata = new Registry($data->metadata); + + // Compute access permissions. + + if ($access = $this->getState('filter.access')) + { + // If the access filter has been set, we already know this user can view. + $data->params->set('access-view', true); + } + else + { + // If no access filter is set, the layout takes some responsibility for display of limited information. + $user = JFactory::getUser(); + $groups = $user->getAuthorisedViewLevels(); + $data->params->set('access-view', in_array($data->access, $groups) && in_array($data->category_access, $groups)); + } + + $this->_item[$pk] = $data; + } + catch (Exception $e) + { + $this->setError($e); + $this->_item[$pk] = false; + } + } + + return $this->_item[$pk]; + } + + /** + * Increment the hit counter for the newsfeed. + * + * @param int $pk Optional primary key of the item to increment. + * + * @return boolean True if successful; false otherwise and internal error set. + * + * @since 3.0 + */ + public function hit($pk = 0) + { + $input = JFactory::getApplication()->input; + $hitcount = $input->getInt('hitcount', 1); + + if ($hitcount) + { + $pk = (!empty($pk)) ? $pk : (int) $this->getState('newsfeed.id'); + + $table = JTable::getInstance('Newsfeed', 'NewsfeedsTable'); + $table->hit($pk); + } + + return true; + } +} diff --git a/Sites/pages/components/com_newsfeeds/newsfeeds.php b/Sites/pages/components/com_newsfeeds/newsfeeds.php new file mode 100644 index 00000000..daf91cec --- /dev/null +++ b/Sites/pages/components/com_newsfeeds/newsfeeds.php @@ -0,0 +1,17 @@ +execute(JFactory::getApplication()->input->get('task')); +$controller->redirect(); diff --git a/Sites/pages/components/com_newsfeeds/router.php b/Sites/pages/components/com_newsfeeds/router.php new file mode 100644 index 00000000..4df4e158 --- /dev/null +++ b/Sites/pages/components/com_newsfeeds/router.php @@ -0,0 +1,247 @@ +noIDs = (bool) $params->get('sef_ids'); + $categories = new JComponentRouterViewconfiguration('categories'); + $categories->setKey('id'); + $this->registerView($categories); + $category = new JComponentRouterViewconfiguration('category'); + $category->setKey('id')->setParent($categories, 'catid')->setNestable(); + $this->registerView($category); + $newsfeed = new JComponentRouterViewconfiguration('newsfeed'); + $newsfeed->setKey('id')->setParent($category, 'catid'); + $this->registerView($newsfeed); + + parent::__construct($app, $menu); + + $this->attachRule(new JComponentRouterRulesMenu($this)); + + if ($params->get('sef_advanced', 0)) + { + $this->attachRule(new JComponentRouterRulesStandard($this)); + $this->attachRule(new JComponentRouterRulesNomenu($this)); + } + else + { + JLoader::register('NewsfeedsRouterRulesLegacy', __DIR__ . '/helpers/legacyrouter.php'); + $this->attachRule(new NewsfeedsRouterRulesLegacy($this)); + } + } + + /** + * Method to get the segment(s) for a category + * + * @param string $id ID of the category to retrieve the segments for + * @param array $query The request that is built right now + * + * @return array|string The segments of this item + */ + public function getCategorySegment($id, $query) + { + $category = JCategories::getInstance($this->getName())->get($id); + + if ($category) + { + $path = array_reverse($category->getPath(), true); + $path[0] = '1:root'; + + if ($this->noIDs) + { + foreach ($path as &$segment) + { + list($id, $segment) = explode(':', $segment, 2); + } + } + + return $path; + } + + return array(); + } + + /** + * Method to get the segment(s) for a category + * + * @param string $id ID of the category to retrieve the segments for + * @param array $query The request that is built right now + * + * @return array|string The segments of this item + */ + public function getCategoriesSegment($id, $query) + { + return $this->getCategorySegment($id, $query); + } + + /** + * Method to get the segment(s) for a newsfeed + * + * @param string $id ID of the newsfeed to retrieve the segments for + * @param array $query The request that is built right now + * + * @return array|string The segments of this item + */ + public function getNewsfeedSegment($id, $query) + { + if (!strpos($id, ':')) + { + $db = JFactory::getDbo(); + $dbquery = $db->getQuery(true); + $dbquery->select($dbquery->qn('alias')) + ->from($dbquery->qn('#__newsfeeds')) + ->where('id = ' . $dbquery->q((int) $id)); + $db->setQuery($dbquery); + + $id .= ':' . $db->loadResult(); + } + + if ($this->noIDs) + { + list($void, $segment) = explode(':', $id, 2); + + return array($void => $segment); + } + + return array((int) $id => $id); + } + + /** + * Method to get the id for a category + * + * @param string $segment Segment to retrieve the ID for + * @param array $query The request that is parsed right now + * + * @return mixed The id of this item or false + */ + public function getCategoryId($segment, $query) + { + if (isset($query['id'])) + { + $category = JCategories::getInstance($this->getName(), array('access' => false))->get($query['id']); + + if ($category) + { + foreach ($category->getChildren() as $child) + { + if ($this->noIDs) + { + if ($child->alias === $segment) + { + return $child->id; + } + } + else + { + if ($child->id == (int) $segment) + { + return $child->id; + } + } + } + } + } + + return false; + } + + /** + * Method to get the segment(s) for a category + * + * @param string $segment Segment to retrieve the ID for + * @param array $query The request that is parsed right now + * + * @return mixed The id of this item or false + */ + public function getCategoriesId($segment, $query) + { + return $this->getCategoryId($segment, $query); + } + + /** + * Method to get the segment(s) for a newsfeed + * + * @param string $segment Segment of the newsfeed to retrieve the ID for + * @param array $query The request that is parsed right now + * + * @return mixed The id of this item or false + */ + public function getNewsfeedId($segment, $query) + { + if ($this->noIDs) + { + $db = JFactory::getDbo(); + $dbquery = $db->getQuery(true); + $dbquery->select($dbquery->qn('id')) + ->from($dbquery->qn('#__newsfeeds')) + ->where('alias = ' . $dbquery->q($segment)) + ->where('catid = ' . $dbquery->q($query['id'])); + $db->setQuery($dbquery); + + return (int) $db->loadResult(); + } + + return (int) $segment; + } +} + +/** + * newsfeedsBuildRoute + * + * These functions are proxys for the new router interface + * for old SEF extensions. + * + * @param array &$query The segments of the URL to parse. + * + * @return array + * + * @deprecated 4.0 Use Class based routers instead + */ +function newsfeedsBuildRoute(&$query) +{ + $app = JFactory::getApplication(); + $router = new NewsfeedsRouter($app, $app->getMenu()); + + return $router->build($query); +} + +/** + * newsfeedsParseRoute + * + * @param array $segments The segments of the URL to parse. + * + * @return array + * + * @deprecated 4.0 Use Class based routers instead + */ +function newsfeedsParseRoute($segments) +{ + $app = JFactory::getApplication(); + $router = new NewsfeedsRouter($app, $app->getMenu()); + + return $router->parse($segments); +} diff --git a/Sites/pages/components/com_newsfeeds/views/categories/tmpl/default.php b/Sites/pages/components/com_newsfeeds/views/categories/tmpl/default.php new file mode 100644 index 00000000..ddf14081 --- /dev/null +++ b/Sites/pages/components/com_newsfeeds/views/categories/tmpl/default.php @@ -0,0 +1,41 @@ +addScriptDeclaration(" +jQuery(function($) { + $('.categories-list').find('[id^=category-btn-]').each(function(index, btn) { + var btn = $(btn); + btn.on('click', function() { + btn.find('span').toggleClass('icon-plus'); + btn.find('span').toggleClass('icon-minus'); + if (btn.attr('aria-label') === Joomla.JText._('JGLOBAL_EXPAND_CATEGORIES')) + { + btn.attr('aria-label', Joomla.JText._('JGLOBAL_COLLAPSE_CATEGORIES')); + } else { + btn.attr('aria-label', Joomla.JText._('JGLOBAL_EXPAND_CATEGORIES')); + } + }); + }); +});"); + +?> +
      + + loadTemplate('items'); ?> +
      diff --git a/Sites/pages/components/com_newsfeeds/views/categories/tmpl/default.xml b/Sites/pages/components/com_newsfeeds/views/categories/tmpl/default.xml new file mode 100644 index 00000000..90b6712b --- /dev/null +++ b/Sites/pages/components/com_newsfeeds/views/categories/tmpl/default.xml @@ -0,0 +1,350 @@ + + + + + + + + + + + +
      + +
      +
      + + + +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      +
      + + + + + + + + + + + + + + + + + +
      + +
      +
      diff --git a/Sites/pages/components/com_newsfeeds/views/categories/tmpl/default_items.php b/Sites/pages/components/com_newsfeeds/views/categories/tmpl/default_items.php new file mode 100644 index 00000000..b3a09706 --- /dev/null +++ b/Sites/pages/components/com_newsfeeds/views/categories/tmpl/default_items.php @@ -0,0 +1,61 @@ + + +maxLevelcat != 0 && count($this->items[$this->parent->id]) > 0) : ?> + items[$this->parent->id] as $id => $item) : ?> + params->get('show_empty_categories_cat') || $item->numitems || count($item->getChildren())) : ?> + items[$this->parent->id][$id + 1])) : ?> + + + > + + + params->get('show_subcat_desc_cat') == 1) : ?> + description) : ?> +
      + description, '', 'com_newsfeeds.categories'); ?> +
      + + + getChildren()) > 0 && $this->maxLevelcat > 1) : ?> +
      + items[$item->id] = $item->getChildren(); ?> + parent = $item; ?> + maxLevelcat--; ?> + loadTemplate('items'); ?> + parent = $item->getParent(); ?> + maxLevelcat++; ?> +
      + +
      + + + diff --git a/Sites/pages/components/com_newsfeeds/views/categories/view.html.php b/Sites/pages/components/com_newsfeeds/views/categories/view.html.php new file mode 100644 index 00000000..548640e6 --- /dev/null +++ b/Sites/pages/components/com_newsfeeds/views/categories/view.html.php @@ -0,0 +1,32 @@ +params->get('pageclass_sfx'); + +?> +
      + params->get('show_page_heading')) : ?> +

      + escape($this->params->get('page_heading')); ?> +

      + + params->get('show_category_title', 1)) : ?> +

      + category->title, '', 'com_newsfeeds.category.title'); ?> +

      + + params->get('show_tags', 1) && !empty($this->category->tags->itemTags)) : ?> + category->tagLayout = new JLayoutFile('joomla.content.tags'); ?> + category->tagLayout->render($this->category->tags->itemTags); ?> + + params->get('show_description', 1) || $this->params->def('show_description_image', 1)) : ?> +
      + params->get('show_description_image') && $this->category->getParams()->get('image')) : ?> + + + params->get('show_description') && $this->category->description) : ?> + category->description, '', 'com_newsfeeds.category'); ?> + +
      +
      + + loadTemplate('items'); ?> + maxLevel != 0 && !empty($this->children[$this->category->id])) : ?> +
      +

      + +

      + loadTemplate('children'); ?> +
      + +
      diff --git a/Sites/pages/components/com_newsfeeds/views/category/tmpl/default.xml b/Sites/pages/components/com_newsfeeds/views/category/tmpl/default.xml new file mode 100644 index 00000000..617a5789 --- /dev/null +++ b/Sites/pages/components/com_newsfeeds/views/category/tmpl/default.xml @@ -0,0 +1,290 @@ + + + + + + + + + + + +
      + +
      +
      + + + +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + +
      +
      +
      diff --git a/Sites/pages/components/com_newsfeeds/views/category/tmpl/default_children.php b/Sites/pages/components/com_newsfeeds/views/category/tmpl/default_children.php new file mode 100644 index 00000000..d5423ca4 --- /dev/null +++ b/Sites/pages/components/com_newsfeeds/views/category/tmpl/default_children.php @@ -0,0 +1,57 @@ + + +maxLevel != 0 && count($this->children[$this->category->id]) > 0) : ?> +
        + children[$this->category->id] as $id => $child) : ?> + params->get('show_empty_categories') || $child->numitems || count($child->getChildren())) : ?> + children[$this->category->id][$id + 1])) : ?> + + + > + + + + escape($child->title); ?> + + + params->get('show_subcat_desc') == 1) : ?> + description) : ?> +
        + description, '', 'com_newsfeeds.category'); ?> +
        + + + params->get('show_cat_items') == 1) : ?> +
        +
        + +
        +
        + numitems; ?> +
        +
        + + getChildren()) > 0) : ?> + children[$child->id] = $child->getChildren(); ?> + category = $child; ?> + maxLevel--; ?> + loadTemplate('children'); ?> + category = $child->getParent(); ?> + maxLevel++; ?> + + + + +
      +items); +$listOrder = $this->escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); + +?> +items)) : ?> +

      + +
      + params->get('filter_field') !== 'hide' || $this->params->get('show_pagination_limit')) : ?> +
      + params->get('filter_field') !== 'hide' && $this->params->get('filter_field') == '1') : ?> +
      + + +
      + + params->get('show_pagination_limit')) : ?> +
      + + pagination->getLimitBox(); ?> +
      + +
      + +
        + items as $i => $item) : ?> + items[$i]->published == 0) : ?> +
      • + +
      • + + params->get('show_articles')) : ?> + + numarticles); ?> + + + + + + items[$i]->published == 0) : ?> + + + + +
        + params->get('show_link')) : ?> + link); ?> + + + + + +
        + +
      • + +
      + + items)) : ?> + params->def('show_pagination', 2) == 1 || ($this->params->get('show_pagination') == 2)) && ($this->pagination->pagesTotal > 1)) : ?> + + + +
      + diff --git a/Sites/pages/components/com_newsfeeds/views/category/view.html.php b/Sites/pages/components/com_newsfeeds/views/category/view.html.php new file mode 100644 index 00000000..7a5302d1 --- /dev/null +++ b/Sites/pages/components/com_newsfeeds/views/category/view.html.php @@ -0,0 +1,99 @@ +commonCategoryDisplay(); + + // Flag indicates to not add limitstart=0 to URL + $this->pagination->hideEmptyLimitstart = true; + + // Prepare the data. + // Compute the newsfeed slug. + foreach ($this->items as $item) + { + $item->slug = $item->alias ? ($item->id . ':' . $item->alias) : $item->id; + $temp = $item->params; + $item->params = clone $this->params; + $item->params->merge($temp); + } + + return parent::display($tpl); + } + + /** + * Prepares the document + * + * @return void + */ + protected function prepareDocument() + { + parent::prepareDocument(); + + $menu = $this->menu; + $id = (int) @$menu->query['id']; + + if ($menu && (!isset($menu->query['option']) || $menu->query['option'] !== 'com_newsfeeds' || $menu->query['view'] === 'newsfeed' + || $id != $this->category->id)) + { + $path = array(array('title' => $this->category->title, 'link' => '')); + $category = $this->category->getParent(); + + while ((!isset($menu->query['option']) || $menu->query['option'] !== 'com_newsfeeds' || $menu->query['view'] === 'newsfeed' + || $id != $category->id) && $category->id > 1) + { + $path[] = array('title' => $category->title, 'link' => NewsfeedsHelperRoute::getCategoryRoute($category->id)); + $category = $category->getParent(); + } + + $path = array_reverse($path); + + foreach ($path as $item) + { + $this->pathway->addItem($item['title'], $item['link']); + } + } + } +} diff --git a/Sites/pages/components/com_newsfeeds/views/newsfeed/tmpl/default.php b/Sites/pages/components/com_newsfeeds/views/newsfeed/tmpl/default.php new file mode 100644 index 00000000..e9b04a47 --- /dev/null +++ b/Sites/pages/components/com_newsfeeds/views/newsfeed/tmpl/default.php @@ -0,0 +1,121 @@ + +msg)) : ?> + msg; ?> + + + newsfeed->rtl; ?> + + isRtl(); ?> + + + + + + + + + + + + + + item->images); ?> +
      + params->get('display_num')) : ?> +

      + escape($this->params->get('page_heading')); ?> +

      + +

      + item->published == 0) : ?> + + + + item->name); ?> + +

      + params->get('show_tags', 1)) : ?> + item->tagLayout = new JLayoutFile('joomla.content.tags'); ?> + item->tagLayout->render($this->item->tags->itemTags); ?> + + + image_first) && !empty($images->image_first)) : ?> + float_first) ? $this->params->get('float_first') : $images->float_first; ?> +
      + image_first_caption) : ?> + image_first_caption, ENT_COMPAT, 'UTF-8') . '"'; ?> + + src="image_first, ENT_COMPAT, 'UTF-8'); ?>" alt="image_first_alt, ENT_COMPAT, 'UTF-8'); ?>" /> +
      + + image_second) && !empty($images->image_second)) : ?> + float_second) ? $this->params->get('float_second') : $images->float_second; ?> +
      + image_second_caption) : ?> + image_second_caption) . '"'; ?> + + src="image_second, ENT_COMPAT, 'UTF-8'); ?>" alt="image_second_alt, ENT_COMPAT, 'UTF-8'); ?>" /> +
      + + + item->description; ?> + + params->get('show_feed_description')) : ?> +
      + rssDoc->description); ?> +
      + + + rssDoc->image && $this->params->get('show_feed_image')) : ?> +
      + <?php echo $this->rssDoc->image->title; ?> +
      + + + rssDoc[0])) : ?> +
        + item->numarticles; $i++) : ?> + rssDoc[$i])) : ?> + + + rssDoc[$i]->uri || !$this->rssDoc[$i]->isPermaLink ? trim($this->rssDoc[$i]->uri) : trim($this->rssDoc[$i]->guid); ?> + item->link : $uri; ?> + rssDoc[$i]->content !== '' ? trim($this->rssDoc[$i]->content) : ''; ?> +
      1. + + + + + + params->get('show_item_description') && $text !== '') : ?> +
        + params->get('show_feed_image', 0) == 0) : ?> + + + params->get('feed_character_count')); ?> + +
        + +
      2. + +
      + +
      + diff --git a/Sites/pages/components/com_newsfeeds/views/newsfeed/tmpl/default.xml b/Sites/pages/components/com_newsfeeds/views/newsfeed/tmpl/default.xml new file mode 100644 index 00000000..f741e8c0 --- /dev/null +++ b/Sites/pages/components/com_newsfeeds/views/newsfeed/tmpl/default.xml @@ -0,0 +1,107 @@ + + + + + + + + + + + +
      + + +
      +
      + + + + + +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      +
      +
      diff --git a/Sites/pages/components/com_newsfeeds/views/newsfeed/view.html.php b/Sites/pages/components/com_newsfeeds/views/newsfeed/view.html.php new file mode 100644 index 00000000..9e3a1565 --- /dev/null +++ b/Sites/pages/components/com_newsfeeds/views/newsfeed/view.html.php @@ -0,0 +1,322 @@ +input->getBool('print'); + + // Get model data. + $state = $this->get('State'); + $item = $this->get('Item'); + + // Check for errors. + // @TODO: Maybe this could go into JComponentHelper::raiseErrors($this->get('Errors')) + if (count($errors = $this->get('Errors'))) + { + JError::raiseWarning(500, implode("\n", $errors)); + + return false; + } + + // Add router helpers. + $item->slug = $item->alias ? ($item->id . ':' . $item->alias) : $item->id; + $item->catslug = $item->category_alias ? ($item->catid . ':' . $item->category_alias) : $item->catid; + $item->parent_slug = $item->category_alias ? ($item->parent_id . ':' . $item->parent_alias) : $item->parent_id; + + // Merge newsfeed params. If this is single-newsfeed view, menu params override newsfeed params + // Otherwise, newsfeed params override menu item params + $params = $state->get('params'); + $newsfeed_params = clone $item->params; + $active = $app->getMenu()->getActive(); + $temp = clone $params; + + // Check to see which parameters should take priority + if ($active) + { + $currentLink = $active->link; + + // If the current view is the active item and a newsfeed view for this feed, then the menu item params take priority + if (strpos($currentLink, 'view=newsfeed') && strpos($currentLink, '&id=' . (string) $item->id)) + { + // $item->params are the newsfeed params, $temp are the menu item params + // Merge so that the menu item params take priority + $newsfeed_params->merge($temp); + $item->params = $newsfeed_params; + + // Load layout from active query (in case it is an alternative menu item) + if (isset($active->query['layout'])) + { + $this->setLayout($active->query['layout']); + } + } + else + { + // Current view is not a single newsfeed, so the newsfeed params take priority here + // Merge the menu item params with the newsfeed params so that the newsfeed params take priority + $temp->merge($newsfeed_params); + $item->params = $temp; + + // Check for alternative layouts (since we are not in a single-newsfeed menu item) + if ($layout = $item->params->get('newsfeed_layout')) + { + $this->setLayout($layout); + } + } + } + else + { + // Merge so that newsfeed params take priority + $temp->merge($newsfeed_params); + $item->params = $temp; + + // Check for alternative layouts (since we are not in a single-newsfeed menu item) + if ($layout = $item->params->get('newsfeed_layout')) + { + $this->setLayout($layout); + } + } + + // Check the access to the newsfeed + $levels = $user->getAuthorisedViewLevels(); + + if (!in_array($item->access, $levels) || (in_array($item->access, $levels) && (!in_array($item->category_access, $levels)))) + { + $app->enqueueMessage(JText::_('JERROR_ALERTNOAUTHOR'), 'error'); + $app->setHeader('status', 403, true); + + return; + } + + // Get the current menu item + $params = $app->getParams(); + + // Get the newsfeed + $newsfeed = $item; + + $params->merge($item->params); + + try + { + $feed = new JFeedFactory; + $this->rssDoc = $feed->getFeed($newsfeed->link); + } + catch (InvalidArgumentException $e) + { + $msg = JText::_('COM_NEWSFEEDS_ERRORS_FEED_NOT_RETRIEVED'); + } + catch (RunTimeException $e) + { + $msg = JText::_('COM_NEWSFEEDS_ERRORS_FEED_NOT_RETRIEVED'); + } + + if (empty($this->rssDoc)) + { + $msg = JText::_('COM_NEWSFEEDS_ERRORS_FEED_NOT_RETRIEVED'); + } + + $feed_display_order = $params->get('feed_display_order', 'des'); + + if ($feed_display_order === 'asc') + { + $this->rssDoc->reverseItems(); + } + + // Escape strings for HTML output + $this->pageclass_sfx = htmlspecialchars($params->get('pageclass_sfx')); + + $this->params = $params; + $this->newsfeed = $newsfeed; + $this->state = $state; + $this->item = $item; + $this->user = $user; + + if (!empty($msg)) + { + $this->msg = $msg; + } + + $this->print = $print; + + $item->tags = new JHelperTags; + $item->tags->getItemTags('com_newsfeeds.newsfeed', $item->id); + + // Increment the hit counter of the newsfeed. + $model = $this->getModel(); + $model->hit(); + + $this->_prepareDocument(); + + return parent::display($tpl); + } + + /** + * Prepares the document + * + * @return void + * + * @since 1.6 + */ + protected function _prepareDocument() + { + $app = JFactory::getApplication(); + $menus = $app->getMenu(); + $pathway = $app->getPathway(); + $title = null; + + // Because the application sets a default page title, + // we need to get it from the menu item itself + $menu = $menus->getActive(); + + if ($menu) + { + $this->params->def('page_heading', $this->params->get('page_title', $menu->title)); + } + else + { + $this->params->def('page_heading', JText::_('COM_NEWSFEEDS_DEFAULT_PAGE_TITLE')); + } + + $title = $this->params->get('page_title', ''); + + $id = (int) @$menu->query['id']; + + // If the menu item does not concern this newsfeed + if ($menu && (!isset($menu->query['option']) || $menu->query['option'] !== 'com_newsfeeds' || $menu->query['view'] !== 'newsfeed' + || $id != $this->item->id)) + { + // If this is not a single newsfeed menu item, set the page title to the newsfeed title + if ($this->item->name) + { + $title = $this->item->name; + } + + $path = array(array('title' => $this->item->name, 'link' => '')); + $category = JCategories::getInstance('Newsfeeds')->get($this->item->catid); + + while ((!isset($menu->query['option']) || $menu->query['option'] !== 'com_newsfeeds' || $menu->query['view'] === 'newsfeed' + || $id != $category->id) && $category->id > 1) + { + $path[] = array('title' => $category->title, 'link' => NewsfeedsHelperRoute::getCategoryRoute($category->id)); + $category = $category->getParent(); + } + + $path = array_reverse($path); + + foreach ($path as $item) + { + $pathway->addItem($item['title'], $item['link']); + } + } + + if (empty($title)) + { + $title = $app->get('sitename'); + } + elseif ($app->get('sitename_pagetitles', 0) == 1) + { + $title = JText::sprintf('JPAGETITLE', $app->get('sitename'), $title); + } + elseif ($app->get('sitename_pagetitles', 0) == 2) + { + $title = JText::sprintf('JPAGETITLE', $title, $app->get('sitename')); + } + + if (empty($title)) + { + $title = $this->item->name; + } + + $this->document->setTitle($title); + + if ($this->item->metadesc) + { + $this->document->setDescription($this->item->metadesc); + } + elseif ($this->params->get('menu-meta_description')) + { + $this->document->setDescription($this->params->get('menu-meta_description')); + } + + if ($this->item->metakey) + { + $this->document->setMetadata('keywords', $this->item->metakey); + } + elseif ($this->params->get('menu-meta_keywords')) + { + $this->document->setMetadata('keywords', $this->params->get('menu-meta_keywords')); + } + + if ($this->params->get('robots')) + { + $this->document->setMetadata('robots', $this->params->get('robots')); + } + + if ($app->get('MetaTitle') == '1') + { + $this->document->setMetaData('title', $this->item->name); + } + + if ($app->get('MetaAuthor') == '1') + { + $this->document->setMetaData('author', $this->item->author); + } + + $mdata = $this->item->metadata->toArray(); + + foreach ($mdata as $k => $v) + { + if ($v) + { + $this->document->setMetadata($k, $v); + } + } + } +} diff --git a/Sites/pages/components/com_pages/class/locator/extension.php b/Sites/pages/components/com_pages/class/locator/extension.php new file mode 100644 index 00000000..4210bbb3 --- /dev/null +++ b/Sites/pages/components/com_pages/class/locator/extension.php @@ -0,0 +1,69 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesClassLocatorExtension extends KClassLocatorAbstract +{ + protected static $_name = 'ext'; + + public function locate($classname, $basepath = null) + { + if (substr($classname, 0, 3) === 'Ext') + { + $result = false; + + $word = strtolower(preg_replace('/(?<=\\w)([A-Z])/', ' \\1', $classname)); + $parts = explode(' ', $word); + + array_shift($parts); + $package = array_shift($parts); + $namespace = ucfirst($package); + + if(count($parts)) { + $file = array_pop($parts); + } else { + $file = $package; + } + + $path = ''; + if (!empty($parts)) { + $path = implode('/', $parts) . '/'; + } + + $paths = []; + + //Namespace paths + if($basepath = $this->getNamespace($namespace)) + { + $paths[] = $basepath.'/'.$path . $file.'.php'; + $paths[] = $basepath.'/'.$path . $file.'/'.$file.'.php'; + } + + ///Fallback paths (unused) + if($basepath = $this->getNamespace('\\')) + { + $paths[] = $basepath.'/'.strtolower($namespace) .'/'.$path . $file.'.php'; + $paths[] = $basepath.'/'.strtolower($namespace) .'/'.$path . $file.'/'.$file.'.php'; + } + + foreach($paths as $path) + { + if(is_file($path)) + { + $result = $path; + break; + } + } + + return $result; + } + + return false; + + } +} diff --git a/Sites/pages/components/com_pages/config.php b/Sites/pages/components/com_pages/config.php new file mode 100644 index 00000000..d58a0596 --- /dev/null +++ b/Sites/pages/components/com_pages/config.php @@ -0,0 +1,128 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesConfig extends KObject implements KObjectSingleton +{ + protected $_site_path; + + public function __construct(KObjectConfig $config) + { + parent::__construct($config); + + $this->_site_path = $config->site_path; + + //Load the site specific options + $this->_loadOptions(); + } + + protected function _initialize(KObjectConfig $config) + { + $config->append(array( + 'site_path' => Koowa::getInstance()->getRootPath().'/joomlatools-pages' + ))->append(array( + 'page_cache' => true, + 'page_cache_path' => $config->site_path.'/cache/pages', + 'page_cache_validation' => true, + + 'data_namespaces' => array(), + 'data_cache' => true, + 'data_cache_path' => $config->site_path ? $config->site_path.'/cache/data' : false, + 'data_cache_validation' => true, + + 'template_cache' => true, + 'template_cache_path' => $config->site_path ? $config->site_path.'/cache/templates' : false, + 'template_cache_validation' => true, + + 'http_cache' => false, + 'http_cache_path' => $config->site_path ? $config->site_path.'/cache/responses': false, + 'http_cache_time' => false, + 'http_cache_time_browser' => null, + 'http_cache_validation' => true, + 'http_cache_control' => array(), + 'http_cache_control_private' => array('private', 'no-cache'), + + 'http_static_cache' => getenv('PAGES_STATIC_ROOT') ? true : false, + 'http_static_cache_path' => getenv('PAGES_STATIC_ROOT') ? getenv('PAGES_STATIC_ROOT') : false, + + 'http_resource_cache' => JFactory::getConfig()->get('caching'), + 'http_resource_cache_path' => $config->site_path ? $config->site_path.'/cache/resources' : false, + 'http_resource_cache_debug' => (JDEBUG ? true : false), + + 'collections' => array(), + 'redirects' => array(), + 'page' => array(), + 'sites' => array('[*]' => JPATH_ROOT.'/joomlatools-pages'), + 'headers' => array(), + + 'composer_path' => $config->site_path.'/vendor', + )); + } + + public function getSitePath($path = null) + { + //If the site path is empty do not try to return a path + if($this->_site_path && $path) { + $result = $this->_site_path.'/'.$path; + } else { + $result = $this->_site_path; + } + + return $result; + } + + public function get($option, $default = null) + { + return $this->getConfig()->get($option, $default); + } + + public function getOptions() + { + return KObjectConfig::unbox($this->getConfig()); + } + + protected function _loadOptions() + { + $options = array(); + + //Load site config + if($path = $this->getSitePath()) + { + //Get the defaults + $options = KObjectConfig::unbox($this->getConfig()); + + //Load default config options + if(file_exists(JPATH_CONFIGURATION.'/configuration-pages.php')) + { + $config = (array) include JPATH_CONFIGURATION.'/configuration-pages.php'; + $options = array_replace_recursive($options, $config); + } + + //Register the composer class locator + if(isset($options['composer_path']) && file_exists($options['composer_path'])) + { + $this->getObject('manager')->getClassLoader()->registerLocator( + new KClassLocatorComposer(array( + 'vendor_path' => $options['composer_path'] + ) + )); + } + + //Load site config options + if(file_exists($path.'/config.php')) + { + $config = $this->getObject('object.config.factory')->fromFile($path.'/config.php', false); + $options = array_replace_recursive($options, $config); + } + + $this->getConfig()->merge($options); + } + + return $options; + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/controller/abstract.php b/Sites/pages/components/com_pages/controller/abstract.php new file mode 100644 index 00000000..98e23550 --- /dev/null +++ b/Sites/pages/components/com_pages/controller/abstract.php @@ -0,0 +1,127 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesControllerAbstract extends KControllerModel +{ + use ComPagesPageTrait; + + public function __construct(KObjectConfig $config) + { + parent::__construct($config); + + $this->setPage($config->page); + $this->setModel($config->model); + } + + protected function _initialize(KObjectConfig $config) + { + $config->append([ + 'page' => 'com://site/pages.page', + 'model' => 'com://site/pages.model.pages', + ]); + + parent::_initialize($config); + } + + public function getFormats() + { + return array($this->getRequest()->getFormat()); + } + + public function getView() + { + if(!$this->_view instanceof KViewInterface) + { + //Get the view + $view = KControllerView::getView(); + + //Set the model in the view + $view->setModel($this->getModel()); + } + + return parent::getView(); + } + + public function getModel() + { + if(!$this->_model instanceof KModelInterface) + { + //Get the model + $model = parent::getModel(); + + //Set the folder to the active page path if no folder is defined + if($model->getState()->folder === null) { + $model->getState()->folder = $this->getPage()->path; + } + } + + return $this->_model; + } + + protected function _actionRender(KControllerContextInterface $context) + { + if(!$context->response->isError()) + { + if($route = $context->router->generate($this->getPage())) + { + $location = $context->router->qualify($route); + + /** + * If Content-Location is included in a 2xx (Successful) response message and its value refers (after + * conversion to absolute form) to a URI that is the same as the effective request URI, then the recipient + * MAY consider the payload to be a current representation of that resource at the time indicated by the + * message origination date + * + * See: https://tools.ietf.org/html/rfc7231#section-3.1.4.2 + */ + $context->response->headers->set('Content-Location', $location); + } + } + + return parent::_actionRender($context); + } + + + protected function _actionBrowse(KControllerContextInterface $context) + { + $entity = $this->getModel()->fetch(); + return $entity; + } + + protected function _actionRead(KControllerContextInterface $context) + { + if(!$context->result instanceof KModelEntityInterface) + { + if($this->getModel()->getState()->isUnique()) + { + $entity = $this->getModel()->fetch(); + + if(!count($entity)) { + throw new KControllerExceptionResourceNotFound('Resource Not Found'); + } + } + else $entity = $this->getModel()->create(); + } + else $entity = $context->result; + + return $entity; + } + + public function getContext() + { + $context = new ComPagesControllerContext(); + $context->setSubject($this); + $context->setRequest($this->getRequest()); + $context->setResponse($this->getResponse()); + $context->setUser($this->getUser()); + $context->setPage($this->getPage()); + + return $context; + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/controller/behavior/breadcrumbable.php b/Sites/pages/components/com_pages/controller/behavior/breadcrumbable.php new file mode 100644 index 00000000..8761d31a --- /dev/null +++ b/Sites/pages/components/com_pages/controller/behavior/breadcrumbable.php @@ -0,0 +1,59 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesControllerBehaviorBreadcrumbable extends KControllerBehaviorAbstract +{ + protected function _beforeRender(KControllerContextInterface $context) + { + if($context->request->getFormat() == 'html') + { + //Set the path in the pathway to allow for module injection + $page_route = $this->getObject('dispatcher')->getRoute()->getPath(false); + + if($menu = JFactory::getApplication()->getMenu()->getActive()) { + $menu_route = $menu->route; + } else { + $menu_route = ''; + } + + if($path = ltrim(str_replace($menu_route, '', $page_route), '/')) + { + $pathway = JFactory::getApplication()->getPathway(); + $router = $this->getObject('router'); + + $segments = array(); + foreach(explode('/', $path) as $segment) + { + $segments[] = $segment; + + if($route = $router->generate('pages:'.implode('/', $segments))) + { + $page = $route->getPage(); + + if(!$page->name) { + $name = ucwords(str_replace(array('_', '-'), ' ', $page->slug)); + } else { + $name = ucfirst($page->name); + } + + $route = $router->qualify($route); + $url = $route->toString(KHttpUrl::PATH); + + $pathway->addItem($name, (string) $url); + } + } + } + } + } + + public function isSupported() + { + return $this->getMixer()->isDispatched() && $this->getObject('dispatcher')->getRoute(); + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/controller/behavior/processable.php b/Sites/pages/components/com_pages/controller/behavior/processable.php new file mode 100644 index 00000000..5c3284cf --- /dev/null +++ b/Sites/pages/components/com_pages/controller/behavior/processable.php @@ -0,0 +1,60 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesControllerBehaviorProcessable extends KControllerBehaviorAbstract +{ + public function processData($data, $processors, $channel = 'form') + { + foreach($processors as $identifier) + { + if(is_array($identifier)) { + $processor = $this->getProcessor(key($identifier), current($identifier)); + } else { + $processor = $this->getProcessor($identifier); + } + + $processor->setChannel($channel)->processData($data); + } + } + + public function getProcessor($processor, $config = array()) + { + //Create the complete identifier if a partial identifier was passed + if (is_string($processor) && strpos($processor, '.') === false) + { + $identifier = $this->getIdentifier()->toArray(); + $identifier['path'] = array('controller', 'processor'); + $identifier['name'] = $processor; + + $identifier = $this->getIdentifier($identifier); + } + else $identifier = $this->getIdentifier($processor); + + $config['request'] = $this->getRequest(); + + $processor = $this->getObject($identifier, $config); + + if (!($processor instanceof ComPagesControllerProcessorInterface)) + { + throw new UnexpectedValueException( + "Processor $identifier does not implement ComPagesControllerProcessorInterface" + ); + } + + return $processor; + } + + public function isSupported() + { + $mixer = $this->getMixer(); + $request = $mixer->getRequest(); + + return $mixer->isDispatched() && $request->isFormSubmit(); + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/controller/behavior/validatable.php b/Sites/pages/components/com_pages/controller/behavior/validatable.php new file mode 100644 index 00000000..13e370e1 --- /dev/null +++ b/Sites/pages/components/com_pages/controller/behavior/validatable.php @@ -0,0 +1,149 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesControllerBehaviorValidatable extends KControllerBehaviorAbstract +{ + protected function _beforeSubmit(KControllerContextInterface $context) + { + if($context->page && $context->page->isSubmittable()) + { + $schema = (array)KObjectConfig::unbox($context->page->form->schema); + + //Validate the request data based on the schema definition + $this->_validateData($context->request, $schema); + + //Check required attributes are present + $this->_validateRequired($context->request, $schema); + } + } + + protected function _beforeAdd(KControllerContextInterface $context) + { + if($context->page && $context->page->isEditable()) + { + $schema = (array)KObjectConfig::unbox($context->page->collection->schema); + + //Santize the request + $this->_sanitizeRequest($context->request, $schema); + + //Validate the request data based on the schema definition + $this->_validateData($context->request, $schema); + + //Check required attributes are present + $this->_validateRequired($context->request, $schema); + + //Do not allow identity key to be in the request data + $this->_validateIdentityKey($context->request); + } + } + + protected function _beforeEdit(KControllerContextInterface $context) + { + if($context->page && $context->page->isEditable()) + { + $schema = (array) KObjectConfig::unbox($context->page->collection->schema); + + //Santize the request + $this->_sanitizeRequest($context->request, $schema); + + //Validate the request data based on the schema definition + $this->_validateData($context->request, $schema); + + //Do not allow identity key to be in the request data + $this->_validateIdentityKey($context->request); + } + } + + protected function _beforeDelete(KControllerContextInterface $context) + { + if($context->page && $context->page->isEditable()) + { + $schema = (array) KObjectConfig::unbox($context->page->collection->schema); + + //Santize the request + $this->_sanitizeRequest($context->request, $schema); + + //Validate the request data based on the schema definition + $this->_validateData($context->request, $schema); + + //Do not allow identity key to be in the request data + $this->_validateIdentityKey($context->request); + } + } + + protected function _sanitizeRequest(KControllerRequestInterface $request, array $schema) + { + //Remove internal model states from query + foreach($this->getModel()->getState() as $state) + { + if($state->internal) { + $request->query->remove($state->name); + } + } + + //Add request query parameters that are defined in the schema (overriding existing values) + foreach(array_diff_key($request->query->toArray(), $schema) as $key => $value) { + $request->data->set($key, $value, true); + } + + //Remove request data that is not defined in schema + foreach(array_diff_key($request->data->toArray(), $schema) as $key => $value) { + $request->data->remove($key); + } + } + + protected function _validateData(KControllerRequestInterface $request, array $schema) + { + //Check if attributes are valid + foreach($schema as $field => $constraints) + { + $filters = array_diff((array) $constraints, ['required', 'unique']); + + if($request->data->has($field)) + { + $value = $request->data->get($field, 'raw'); + + $chain = $this->getObject('filter.factory')->createChain($filters); + if(!$chain->validate($value)) { + throw new ComPagesControllerExceptionRequestInvalid(sprintf('%s is not valid', ucfirst($field))); + } + + //Santize data just in case + $request->data->set($field, $chain->sanitize($value)); + } + } + } + + protected function _validateRequired(KControllerRequestInterface $request, array $schema) + { + foreach ($schema as $field => $constraints) + { + $constraints = (array)$constraints; + + //Check if field is required + if (in_array('required', $constraints)) + { + if (!$request->data->has($field) || empty($request->data->get($field, 'raw'))) { + throw new ComPagesControllerExceptionRequestInvalid(sprintf('%s is required', ucfirst($field))); + } + } + } + } + + protected function _validateIdentityKey(KControllerRequestInterface $request) + { + //Check for identity key + if($identity_key = $this->getModel()->getIdentityKey()) + { + if($request->data->has($identity_key)) { + throw new ComPagesControllerExceptionRequestInvalid(sprintf('%s is an identity key', ucfirst($identity_key))); + } + } + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/controller/collection.php b/Sites/pages/components/com_pages/controller/collection.php new file mode 100644 index 00000000..44b5ff91 --- /dev/null +++ b/Sites/pages/components/com_pages/controller/collection.php @@ -0,0 +1,180 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesControllerCollection extends ComPagesControllerPage +{ + protected function _initialize(KObjectConfig $config) + { + $config->append(array( + 'behaviors' => ['validatable'], + )); + + parent::_initialize($config); + } + + public function setModel($model) + { + //Create the collection model + $model = $this->getObject('model.factory') + ->createModel($this->getPage()->path, $this->getRequest()->query->toArray(), false); + + return parent::setModel($model); + } + + protected function _actionRender(KControllerContextInterface $context) + { + $result = false; + + $path = $context->request->getUrl()->getPath(true); + + //Check if we are rendering an empty form + if(end($path) == 'new') { + $action = 'read'; + } else { + $action = $this->getView()->isCollection() ? 'browse' : 'read'; + } + + //Execute the action + if($result = $this->execute($action, $context) !== false) + { + if(!is_string($result) && !(is_object($result) && method_exists($result, '__toString'))) { + $result = parent::_actionRender($context); + } + } + + return $result; + } + + protected function _actionAdd(KControllerContextInterface $context) + { + if(!$context->result instanceof KModelEntityInterface) { + $entity = $this->getModel()->create($context->request->data->toArray()); + } else { + $entity = $context->result; + } + + //Set the entity state + $entity->save(); + + //Persist the entity + $result = $this->getModel()->persist(); + + //Only throw an error if the action explicitly failed. + if($result === ComPagesModelInterface::PERSIST_FAILURE) + { + $error = $entity->getStatusMessage(); + throw new KControllerExceptionActionFailed($error ? $error : 'Add Action Failed'); + } + + //Set entity new identity in the state (to make it unique) + if(!$this->getModel()->getState()->isUnique()) + { + foreach($this->getModel()->getPrimaryKey() as $key){ + $this->getModel()->getState()->set($key, $entity->getProperty($key)); + } + } + + //Generate the location for the resource + $query = array(); + foreach($this->getModel()->getPrimaryKey() as $key){ + $query[$key] = $entity->getProperty($key); + } + + $route = $context->router->generate($this->getPage(), $query); + $location = $context->router->qualify($route); + + //See: https://tools.ietf.org/html/rfc7231#page-52 + $context->response->setStatus(KHttpResponse::CREATED); + $context->response->headers->set('Location', $location); + + /* + * The Content-Location contains the new representation of that resource, thereby distinguishing it + * from representations that might only report about the action (e.g., "It worked!"). This allows + * authoring applications to update their local copies without the need for a subsequent GET request. + * + * See: https://tools.ietf.org/html/rfc7231#section-3.1.4.2 + */ + $context->response->headers->set('Content-Location', $location); + + return $entity; + } + + protected function _actionEdit(KControllerContextInterface $context) + { + if(!$context->result instanceof KModelEntityInterface) { + $entities = $this->getModel()->fetch(); + } else { + $entities = $context->result; + } + + if(count($entities) && $this->getModel()->isAtomic()) + { + foreach($entities as $entity) { + $entity->setProperties($context->request->data->toArray()); + } + + //Set the entity state + $entities->save(); + + //Persist the entity + $result = $this->getModel()->persist(); + + if($result === ComPagesModelInterface::PERSIST_NOCHANGE) { + $context->response->setStatus(KHttpResponse::NO_CONTENT); + } + + //Only throw an error if the action explicitly failed. + if($result === ComPagesModelInterface::PERSIST_FAILURE) + { + $error = $entity->getStatusMessage(); + throw new KControllerExceptionActionFailed($error ? $error : 'Edit Action Failed'); + } + } + else throw new KControllerExceptionResourceNotFound('Resource Not Found'); + + return $entities; + } + + protected function _actionDelete(KControllerContextInterface $context) + { + if(!$context->result instanceof KModelEntityInterface) { + $entities = $this->getModel()->fetch(); + } else { + $entities = $context->result; + } + + //Do not allow deleting a whole collection + if(count($entities) && $this->getModel()->isAtomic()) + { + foreach($entities as $entity) { + $entity->setProperties($context->request->data->toArray()); + } + + //Set the entity state + $entities->delete(); + + //Persist the entity + $result = $this->getModel()->persist(); + + if($result === ComPagesModelInterface::PERSIST_SUCCESS) { + $context->response->setStatus(KHttpResponse::NO_CONTENT); + } + + //Only throw an error if the action explicitly failed. + if($result === ComPagesModelInterface::PERSIST_FAILURE) + { + $error = $entities->getStatusMessage(); + throw new KControllerExceptionActionFailed($error ? $error : 'Delete Action Failed'); + } + } + else throw new KControllerExceptionResourceNotFound('Resource Not Found'); + + return $entities; + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/controller/context/context.php b/Sites/pages/components/com_pages/controller/context/context.php new file mode 100644 index 00000000..6ef635c1 --- /dev/null +++ b/Sites/pages/components/com_pages/controller/context/context.php @@ -0,0 +1,21 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesControllerContext extends KControllerContext implements ComPagesControllerContextInterface +{ + public function getPage() + { + return KObjectConfig::get('page'); + } + + public function setPage(ComPagesPageInterface $page) + { + return KObjectConfig::set('page', $page); + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/controller/context/interface.php b/Sites/pages/components/com_pages/controller/context/interface.php new file mode 100644 index 00000000..8ddae728 --- /dev/null +++ b/Sites/pages/components/com_pages/controller/context/interface.php @@ -0,0 +1,13 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +interface ComPagesControllerContextInterface extends KControllerContextInterface +{ + public function getPage(); +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/controller/decorator.php b/Sites/pages/components/com_pages/controller/decorator.php new file mode 100644 index 00000000..e0dc01fe --- /dev/null +++ b/Sites/pages/components/com_pages/controller/decorator.php @@ -0,0 +1,13 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesControllerDecorator extends ComPagesControllerAbstract +{ + +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/controller/exception/requestblocked.php b/Sites/pages/components/com_pages/controller/exception/requestblocked.php new file mode 100644 index 00000000..c02c3c2f --- /dev/null +++ b/Sites/pages/components/com_pages/controller/exception/requestblocked.php @@ -0,0 +1,11 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + + +class ComPagesControllerExceptionRequestBlocked extends KHttpExceptionForbidden implements KControllerException, ComPagesControllerExceptionSpam {} diff --git a/Sites/pages/components/com_pages/controller/exception/requestinvalid.php b/Sites/pages/components/com_pages/controller/exception/requestinvalid.php new file mode 100644 index 00000000..19c85380 --- /dev/null +++ b/Sites/pages/components/com_pages/controller/exception/requestinvalid.php @@ -0,0 +1,11 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + + +class ComPagesControllerExceptionRequestInvalid extends KControllerExceptionRequestInvalid implements ComPagesControllerExceptionSpam {} diff --git a/Sites/pages/components/com_pages/controller/exception/spam.php b/Sites/pages/components/com_pages/controller/exception/spam.php new file mode 100644 index 00000000..efb5c552 --- /dev/null +++ b/Sites/pages/components/com_pages/controller/exception/spam.php @@ -0,0 +1,11 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + + +interface ComPagesControllerExceptionSpam {} diff --git a/Sites/pages/components/com_pages/controller/form.php b/Sites/pages/components/com_pages/controller/form.php new file mode 100644 index 00000000..4aa632fe --- /dev/null +++ b/Sites/pages/components/com_pages/controller/form.php @@ -0,0 +1,51 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesControllerForm extends ComPagesControllerPage +{ + protected function _initialize(KObjectConfig $config) + { + $config->append(array( + 'behaviors' => ['processable', 'validatable'], + )); + + parent::_initialize($config); + } + + public function __construct(KObjectConfig $config) + { + parent::__construct($config); + + //Setup callbacks + $this->addCommandCallback('after.submit' , '_processData'); + } + + protected function _processData(KControllerContextInterface $context) + { + $page = $this->getPage(); + + $channel = $page->form->name ?? $page->slug; + $processors = (array) KObjectConfig::unbox($page->form->processors); + + $this->processData($context->request->data->toArray(), $processors, $channel); + } + + protected function _actionSubmit(KControllerContextInterface $context) + { + if($redirect = $this->getPage()->form->redirect) + { + if(substr($redirect, 0, 4) !== 'http') { + $redirect = $this->getView()->getRoute($redirect); + } + + $this->getResponse()->setRedirect($redirect); + } + else $context->response->setStatus(KHttpResponse::RESET_CONTENT); + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/controller/page.php b/Sites/pages/components/com_pages/controller/page.php new file mode 100644 index 00000000..1451752a --- /dev/null +++ b/Sites/pages/components/com_pages/controller/page.php @@ -0,0 +1,20 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesControllerPage extends ComPagesControllerAbstract +{ + protected function _initialize(KObjectConfig $config) + { + $config->append(array( + 'behaviors' => ['breadcrumbable'], + )); + + parent::_initialize($config); + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/controller/permission/abstract.php b/Sites/pages/components/com_pages/controller/permission/abstract.php new file mode 100644 index 00000000..6fcaefbf --- /dev/null +++ b/Sites/pages/components/com_pages/controller/permission/abstract.php @@ -0,0 +1,71 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesControllerPermissionAbstract extends ComKoowaControllerPermissionAbstract +{ + public function canRead() + { + $path = $this->getPage()->path; + + if(!$this->canAccess($path)) { + return false; + } + + return parent::canRead(); + } + + public function canBrowse() + { + $path = $this->getPage()->path; + + if(!$this->canAccess($path)) { + return false; + } + + return parent::canRead(); + } + + public function canAccess($path) + { + $result = true; + + if($path) + { + $page = $this->getObject('page.registry')->getPage($path); + + //Check groups + if(isset($page->access->groups)) + { + $groups = $this->getObject('com://site/pages.database.table.groups') + ->select($this->getObject('user')->getGroups(), KDatabase::FETCH_ARRAY_LIST); + + $groups = array_map('strtolower', array_column($groups, 'title')); + + if(!array_intersect($groups, KObjectConfig::unbox($page->access->groups))) { + $result = false; + } + } + + //Check roles + if($result && isset($page->access->roles)) + { + $roles = $this->getObject('com://site/pages.database.table.roles') + ->select($this->getObject('user')->getRoles(), KDatabase::FETCH_ARRAY_LIST); + + $roles = array_map('strtolower', array_column($roles, 'title')); + + if(!array_intersect($roles, KObjectConfig::unbox($page->access->roles))) { + $result = false; + } + } + } + + return $result; + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/controller/permission/collection.php b/Sites/pages/components/com_pages/controller/permission/collection.php new file mode 100644 index 00000000..62553b85 --- /dev/null +++ b/Sites/pages/components/com_pages/controller/permission/collection.php @@ -0,0 +1,57 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesControllerPermissionCollection extends ComPagesControllerPermissionPage +{ + public function canAdd() + { + if(!$this->getPage()->isEditable()) { + return false; + } + + $path = $this->getPage()->path; + + if(!$this->canAccess($path)) { + return false; + } + + return true; + } + + + public function canEdit() + { + if(!$this->getPage()->isEditable()) { + return false; + } + + $path = $this->getPage()->path; + + if(!$this->canAccess($path)) { + return false; + } + + return true; + } + + public function canDelete() + { + if(!$this->getPage()->isEditable()) { + return false; + } + + $path = $this->getPage()->path; + + if(!$this->canAccess($path)) { + return false; + } + + return true; + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/controller/permission/decorator.php b/Sites/pages/components/com_pages/controller/permission/decorator.php new file mode 100644 index 00000000..dda56acd --- /dev/null +++ b/Sites/pages/components/com_pages/controller/permission/decorator.php @@ -0,0 +1,13 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesControllerPermissionDecorator extends ComPagesControllerPermissionAbstract +{ + +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/controller/permission/form.php b/Sites/pages/components/com_pages/controller/permission/form.php new file mode 100644 index 00000000..1f293706 --- /dev/null +++ b/Sites/pages/components/com_pages/controller/permission/form.php @@ -0,0 +1,26 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesControllerPermissionForm extends ComPagesControllerPermissionPage +{ + public function canSubmit() + { + if(!$this->getPage()->isSubmittable()) { + return false; + } + + $path = $this->getPage()->path; + + if(!$this->canAccess($path)) { + return false; + } + + return true; + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/controller/permission/page.php b/Sites/pages/components/com_pages/controller/permission/page.php new file mode 100644 index 00000000..ba65e02f --- /dev/null +++ b/Sites/pages/components/com_pages/controller/permission/page.php @@ -0,0 +1,13 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesControllerPermissionPage extends ComPagesControllerPermissionAbstract +{ + +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/controller/processor/abstract.php b/Sites/pages/components/com_pages/controller/processor/abstract.php new file mode 100644 index 00000000..71582f5a --- /dev/null +++ b/Sites/pages/components/com_pages/controller/processor/abstract.php @@ -0,0 +1,63 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +abstract class ComPagesControllerProcessorAbstract extends KObject implements ComPagesControllerProcessorInterface +{ + protected $_channel; + + private $__request; + + public function __construct(KObjectConfig $config) + { + parent::__construct($config); + + $this->setChannel($config->channel); + + $this->setRequest($config->request); + } + + protected function _initialize(KObjectConfig $config) + { + $config->append([ + 'request' => null, + 'channel' => 'form' + ]); + + parent::_initialize($config); + } + + public function setChannel($name) + { + $this->_channel = $name; + return $this; + } + + public function getChannel() + { + return $this->_channel; + } + + public function setRequest(KControllerRequestInterface $request) + { + $this->__request = $request; + return $this; + } + + public function getRequest() + { + return $this->__request; + } + + public function __clone() + { + parent::__clone(); + + $this->__request = clone $this->__request; + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/controller/processor/csv.php b/Sites/pages/components/com_pages/controller/processor/csv.php new file mode 100644 index 00000000..ad6980b5 --- /dev/null +++ b/Sites/pages/components/com_pages/controller/processor/csv.php @@ -0,0 +1,81 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesControllerProcessorCsv extends ComPagesControllerProcessorAbstract +{ + const ENCLOSURE = '"'; + const DELIMITER = ','; + const ESCAPE_CHAR = '\\'; + + protected function _initialize(KObjectConfig $config) + { + $config->append([ + 'path' => $this->getObject('com://site/pages.config')->getSitePath('logs'), + ]); + + parent::_initialize($config); + } + + public function getFile() + { + return $this->getConfig()->path . '/' . $this->getChannel() . '.csv'; + } + + public function processData(array $data) + { + $file = $this->getFile(); + + $fields = array(); + foreach ($data as $key => $value) + { + //Cast objects to string + if (is_object($value)) + { + if (method_exists($value, '__toString')) { + $value = (string)$value; + } else { + $value = null; + } + } + + //Implode array's + if (is_array($value)) + { + if (is_numeric(key($value))) { + $value = implode(',', $value); + } else { + $value = json_encode($value); + } + } + + $fields[$key] = $value; + } + + //Write the header + if (!file_exists($file) && !is_numeric(key($fields))) { + $this->_writeCsvFile($file, array_keys($fields)); + } + + //Write the data + $this->_writeCsvFile($file, $fields); + } + + protected function _writeCsvFile($file, $data) + { + if(!$fp = fopen($file, 'a')) { + throw new RuntimeException(sprintf('Could not open CSV file for writing: %s', $file)); + } + + if(!fputcsv($fp, $data, static::DELIMITER, static::ENCLOSURE, static::ESCAPE_CHAR)) { + throw new RuntimeException(sprintf('Could not write to CSV file: %s', $file)); + } + + fclose($fp); + } +} diff --git a/Sites/pages/components/com_pages/controller/processor/database.php b/Sites/pages/components/com_pages/controller/processor/database.php new file mode 100644 index 00000000..6bbb59f2 --- /dev/null +++ b/Sites/pages/components/com_pages/controller/processor/database.php @@ -0,0 +1,61 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesControllerProcessorDatabase extends ComPagesControllerProcessorAbstract +{ + protected $_table; + + public function __construct(KObjectConfig $config) + { + parent::__construct($config); + + $this->_table = $config->table; + } + + protected function _initialize(KObjectConfig $config) + { + $config->append([ + 'table' => '', + ]); + + parent::_initialize($config); + } + + + public function getTable() + { + if(!($this->_table instanceof KDatabaseTableInterface)) + { + //Make sure we have a table identifier + if(!($this->_table instanceof KObjectIdentifier)) + { + if(is_string($this->_table) && strpos($this->_table, '.') !== false ) { + $this->_table = $this->getObject($this->_table); + } else { + $this->_table = $this->getObject('com://site/pages.database.table.default', array('name' => $this->_table)); + } + } + + if(!$this->_table instanceof KDatabaseTableInterface) + { + throw new UnexpectedValueException( + 'Table: '.get_class($this->_table).' does not implement KDatabaseTableInterface' + ); + } + } + + return $this->_table; + } + + public function processData(array $data) + { + $table = $this->getTable(); + $table->insert($table->createRow(['data' => $data])); + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/controller/processor/email.php b/Sites/pages/components/com_pages/controller/processor/email.php new file mode 100644 index 00000000..67e23c2d --- /dev/null +++ b/Sites/pages/components/com_pages/controller/processor/email.php @@ -0,0 +1,184 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesControllerProcessorEmail extends ComPagesControllerProcessorAbstract +{ + protected function _initialize(KObjectConfig $config) + { + $config->append([ + 'html' => true, + 'sender' => null, + 'recipients' => [], + 'title' => '', + 'subject' => '', + ]); + + parent::_initialize($config); + } + + public function processData(array $data) + { + $mailer = JFactory::getMailer(); + + if($this->getConfig()->html) { + $mailer->isHtml(true); + } + + if($this->getConfig()->sender) { + $mailer->setSender($this->getConfig()->sender); + } + + //Set the reply to + if($email = $this->getEmail($data)) + { + $name = $this->getName($data); + $mailer->addReplyTo($email, $name); + } + + //Add the recipients + $recipients = (array) $this->getRecipients(); + foreach($recipients as $recipient) { + $mailer->addRecipient($recipient); + } + + //Set the subject + $subject = $this->getSubject(); + $mailer->setSubject($subject); + + //Set the body + $body = $this->getMessage($data); + $mailer->setBody($body); + + //Send the mail + if(!$mailer->send()) { + throw new RuntimeException($mailer->ErrorInfo); + } + } + + public function getTitle() + { + return $this->getConfig()->subject ?? sprintf('%s form', ucfirst($this->getChannel())); + } + + public function getSubject() + { + return $this->getConfig()->subject ?? sprintf('New %s form submission', ucfirst($this->getChannel())); + } + + public function getRecipients() + { + return count($this->getConfig()->recipients) ? $this->getConfig()->recipients : (array) JFactory::getConfig()->get('mailfrom'); + } + + public function getEmail($data) + { + return $data['email'] ?? ''; + } + + public function getName($data) + { + $name = $data['name'] ?? ''; + + if(isset($data['firstName']) && isset($data['lastName'])) { + $name = $data['firstName'].' '.$data['lastName']; + } + + return $name; + } + + public function getMessage($data) + { + $title = $this->getTitle(); + $content = array(); + + foreach($data as $key => $value) + { + $content[] = sprintf('

      %s

      ', implode(' ', array_map('ucfirst', KStringInflector::explode(ucfirst($key))))); + $content[] = sprintf('

      %s

      ', is_array($value) ? implode(', ', $value) : $value); + } + + $content = implode("\n", $content); + + //Using http://emailframe.work hybrid layout + $message = << + + + +$title + + + +
      + + + + + + + +
      + + + + + +
      +

      $title

      + $content +
      + +
      +
      + + +MESSAGE; + + return $message; + } +} diff --git a/Sites/pages/components/com_pages/controller/processor/interface.php b/Sites/pages/components/com_pages/controller/processor/interface.php new file mode 100644 index 00000000..e7bf5885 --- /dev/null +++ b/Sites/pages/components/com_pages/controller/processor/interface.php @@ -0,0 +1,19 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +interface ComPagesControllerProcessorInterface +{ + public function processData(array $data); + + public function setChannel($name); + public function getChannel(); + + public function setRequest(KControllerRequestInterface $request); + public function getRequest(); +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/controller/processor/webhook.php b/Sites/pages/components/com_pages/controller/processor/webhook.php new file mode 100644 index 00000000..5c99a9ce --- /dev/null +++ b/Sites/pages/components/com_pages/controller/processor/webhook.php @@ -0,0 +1,78 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesControllerProcessorWebhook extends ComPagesControllerProcessorAbstract +{ + protected function _initialize(KObjectConfig $config) + { + $config->append([ + 'method' => KHttpRequest::POST, + 'url' => '', + 'headers' => [], + 'format' => null, + ]); + + parent::_initialize($config); + } + + public function processData(array $data) + { + $data = $this->getPayload($data); + + $request = $this->getObject('http.request') + ->setMethod($this->getMethod()) + ->setUrl($this->getUrl()); + + //Set the content + if(is_array($data)) + { + $content = http_build_query($data, '', '&'); + $request->setContent($content, 'application/x-www-form-urlencoded'); + } + else $request->setContent((string) $data, $data->getMediaType()); + + //Add the headers + $request->getHeaders()->add($this->getHeaders(), true); + + //Send content + return $this->getObject('lib:http.client')->send($request); + } + + public function getUrl() + { + return $this->getConfig()->url; + } + + public function getMethod() + { + return $this->getConfig()->method; + } + + public function getHeaders() + { + $headers = KObjectConfig::unbox($this->getConfig()->headers); + $headers['Origin'] = $this->getRequest()->getOrigin(); + + return $headers; + } + + public function getPayload(array $data) + { + if($format = $this->getConfig()->format) + { + $factory = $this->getObject('object.config.factory'); + + if($factory->isRegistered($format)) { + $data = $factory->createFormat($format, $data); + } + } + + return $data; + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/data/locator.php b/Sites/pages/components/com_pages/data/locator.php new file mode 100644 index 00000000..111b473c --- /dev/null +++ b/Sites/pages/components/com_pages/data/locator.php @@ -0,0 +1,45 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesDataLocator extends KTemplateLocatorFile +{ + protected static $_name = 'data'; + + protected function _initialize(KObjectConfig $config) + { + $config->append([ + 'base_path' => $this->getObject('com://site/pages.config')->getSitePath('data'), + ]); + + parent::_initialize($config); + } + + public function setBasePath($path) + { + $this->_base_path = rtrim($path, '/'); + return $this; + } + + public function locate($url) + { + $base_path = $this->getBasePath(); + + if(!isset($this->_locations[$base_path.'/'.$url])) + { + $info = array( + 'url' => $url, + 'path' => '', + ); + + $this->_locations[$base_path.'/'.$url] = $this->find($info); + } + + return $this->_locations[$base_path.'/'.$url]; + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/data/object.php b/Sites/pages/components/com_pages/data/object.php new file mode 100644 index 00000000..919d4466 --- /dev/null +++ b/Sites/pages/components/com_pages/data/object.php @@ -0,0 +1,168 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesDataObject extends ComPagesObjectConfig +{ + public function shuffle() + { + $data = $this->toArray(); + shuffle($data); + + return new self($data); + } + + public function slice($offset, $length = NULL) + { + $data = $this->toArray(); + $data = array_slice($data, $offset, $length); + + return new self($data); + } + + public function flatten($key_as_property = null) + { + $data = array(); + + foreach( $this->toArray() as $key => $values) + { + if(is_array($values)) + { + if (is_string($key_as_property) && !is_numeric($key)) + { + // Keep current key as a property of the data object + foreach ($values as &$value) { + $value[$key_as_property] = $key; + } + } + + $data = array_merge($data, $values); + } + else $data[] = $values; + } + + return new self($data); + } + + public function filter($key, $value = null, $exclude = false) + { + $data = $this->toArray(); + + if(isset($data[$key])) { + $data = array($data); + } + + //Filter the array + $data = array_filter($data, function($v) use ($key, $value, $exclude) + { + if($value !== null && isset($v[$key])) + { + if(is_array($value) && is_array($v[$key])) + { + if($exclude) { + return (bool) array_diff_assoc($value, $v[$key]); + } else { + return (bool) !array_diff_assoc($value, $v[$key]); + } + + } + else + { + if($exclude) { + return ($v[$key] !== $value); + } else { + return ($v[$key] === $value); + } + } + } + else + { + if($exclude) { + return !isset($v[$key]); + } else { + return isset($v[$key]); + } + + } + }); + + //Reset the numeric keys + if (is_numeric(key($data))) { + $data = array_values($data); + } + + //Do no return an array if we only found a single scalar result + if(count($data) == 1 && isset($data[0])) { + $data = $data[0]; + } + + return is_array($data) ? new self($data) : $data; + } + + public function find($key) + { + $data = $this->toArray(); + + $array = new RecursiveArrayIterator($data); + $iterator = new RecursiveIteratorIterator($array, \RecursiveIteratorIterator::SELF_FIRST); + + $result = array(); + foreach ($iterator as $k => $v) + { + if($key === $k) + { + if(is_array($v) && is_numeric(key($v))) { + $result = array_merge($result, $v); + } else { + $result[] = $v; + } + } + } + + //Do no return an array if we only found one result + if(count($result) == 1 && isset($result[0])) { + $result = $result[0]; + } + + return is_array($result) ? new self($result) : $result; + } + + public function toString() + { + $data = $this->toArray(); + + if(is_array($data)) + { + if(!isset($data['@value'])) { + $data = $this->toJson()->toString(); + } else { + $data = $data['@value']; + } + } + + return $data; + } + + public function toHtml() + { + $html = new ComPagesObjectConfigHtml($this); + return $html->toDom(); + } + + public function toXml() + { + $html = new ComPagesObjectConfigXml($this); + return $html->toDom(); + } + + public function toJson() + { + $html = new ComPagesObjectConfigJson($this); + return $html; + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/data/registry.php b/Sites/pages/components/com_pages/data/registry.php new file mode 100644 index 00000000..5f27fec9 --- /dev/null +++ b/Sites/pages/components/com_pages/data/registry.php @@ -0,0 +1,374 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +final class ComPagesDataRegistry extends KObject implements KObjectSingleton +{ + private $__http; + private $__data = array(); + private $__locator = null; + private $__namespaces = array(); + private $__hashes = array(); + + public function __construct(KObjectConfig $config) + { + parent::__construct($config); + + //Create the locator + $this->__locator = $this->getObject('com://site/pages.data.locator'); + + //Set the namespaces + $this->__namespaces = KObjectConfig::unbox($config->namespaces); + + //Set http client + $this->__http = $config->http; + } + + protected function _initialize(KObjectConfig $config) + { + $config->append([ + 'http' => 'com://site/pages.http.cache', + 'cache' => JDEBUG ? false : true, + 'cache_path' => $this->getObject('com://site/pages.config')->getSitePath('cache'), + 'cache_validation' => true, + 'namespaces' => array(), + ]); + + parent::_initialize($config); + } + + public function getLocator() + { + return $this->__locator; + } + + public function getNamespaces() + { + return $this->__namespaces; + } + + public function getHash($path = null) + { + $path = $path ?? $this->getLocator()->getBasePath(); + + $size = function($path) use(&$size) + { + $result = array(); + + if (is_dir($path)) + { + $files = array_diff(scandir($path), array('.', '..', '.DS_Store')); + + foreach ($files as $file) + { + if (is_dir($path.'/'.$file)) { + $result[$file] = $size($path .'/'.$file); + } else { + $result[$file] = sprintf('%u', filesize($path .'/'.$file)); + } + } + } + else $result[basename($path)] = sprintf('%u', filesize($path)); + + return $result; + }; + + if(!isset($this->__hashes[$path])) + { + if($file = $this->getLocator()->locate($path)) { + $this->__hashes[$path] = hash('crc32b', serialize( $size($file))); + } else { + $this->__hashes[$path] = false; + } + } + + return $this->__hashes[$path]; + } + + public function fromUrl($url, $cache = true) + { + if (!isset($this->__data[$url])) + { + $http = $this->_getHttpClient(); + $headers['Cache-Control'] = $this->_getCacheControl($cache); + + try + { + $data = $http->get($url, $headers); + } + catch(KHttpException $e) + { + //Re-throw exception if in debug mode + if($http->isDebug()) { + throw $e; + } else { + $data = null; + } + } + + $class = $this->getObject('manager')->getClass('com://site/pages.data.object'); + $data = new $class($data); + + $this->__data[$url] = $data; + } + else $data = $this->__data[$url]; + + return $data; + } + + public function fromPath($path) + { + if(!isset($this->__data[$path])) + { + //Find path and base_path + if ($namespace = parse_url($path, PHP_URL_SCHEME)) + { + $file_path = str_replace($namespace . '://', '', $path); + $base_path = $this->__namespaces[$namespace]; + } + else + { + $file_path = $path; + $base_path = $this->getLocator()->getConfig()->base_path; + } + + $this->getLocator()->setBasePath($base_path); + + //Load the data and cache it + $segments = explode('/', $file_path); + $root_path = array_shift($segments); + $key = crc32($base_path . $root_path); + + if (!isset($this->__data[$key])) + { + $data = $this->loadCache($root_path, false); + $this->__data[$key] = $data; + } + else $data = $this->__data[$key]; + + //Find the specific data segment + foreach ($segments as $segment) + { + if (!isset($data[$segment])) + { + $data = array(); + break; + } + else $data = $data[$segment]; + } + + $class = $this->getObject('manager')->getClass('com://site/pages.data.object'); + $data = new $class($data); + + $this->__data[$path] = $data; + } + else $data = $this->__data[$path]; + + return $data; + } + + private function __fromPath($path) + { + //Locate the data file + if (!$file = $this->getLocator()->locate($path)) { + throw new InvalidArgumentException(sprintf('The data path "%s" does not exist.', $path)); + } + + if(is_dir($file)) { + $result = $this->__fromDirectory($file); + } else { + $result = $this->__fromFile($file); + } + + return $result; + } + + private function __fromFile($file) + { + return $this->getObject('object.config.factory')->fromFile($file, false); + } + + private function __fromDirectory($path) + { + $data = array(); + $nodes = array(); + + $basepath = $this->getLocator()->getBasePath(); + $basepath = ltrim(str_replace($basepath, '', $path), '/'); + + //List + foreach (new DirectoryIterator($path) as $node) + { + if(strpos($node->getFilename(), '.order.') !== false) { + $nodes = array_merge($this->__fromFile((string)$node->getFileInfo()), $nodes); + } + + if (!in_array($node->getFilename()[0], array('.', '_'))) { + $nodes[] = $node->getFilename(); + } + } + + $nodes = array_unique($nodes); + + //Files + $files = array(); + $dirs = array(); + foreach($nodes as $node) + { + $info = pathinfo($node); + + if(isset($info['extension'])) { + $files[$info['filename']] = $basepath.'/'.$node; + } else { + $dirs[$node] = $basepath.'/'.$node; + } + } + + foreach($files as $name => $file) + { + if($name !== basename(dirname($file))) { + $data[$name] = $this->__fromPath($file); + } else { + $data = $this->__fromPath($file); + } + } + + foreach($dirs as $name => $dir) { + $data[$name] = $this->__fromPath($dir); + } + + return $data; + } + + public function loadCache($path, $refresh = true) + { + $file = $this->getLocator()->getBasePath().'/'.$path; + + if ($refresh || !$cache = $this->isCached($file)) + { + $data = $this->__fromPath($path); + + $result = array(); + $result['data'] = $data; + + //Calculate the hash + if($this->getConfig()->cache && $this->getConfig()->cache_validation) { + $result['hash'] = $this->getHash($path); + } + + $this->storeCache($file, $result); + } + else + { + if (!$result = require($cache)) { + throw new RuntimeException(sprintf('The data "%s" cannot be loaded from cache.', $cache)); + } + + //Check if the cache is still valid, if not refresh it + if($this->getConfig()->cache_validation && $result['hash'] != $this->getHash($path)) { + $this->loadCache($path, true); + } + + $data = $result['data']; + } + + return $data; + } + + public function storeCache($file, $data) + { + if($this->getConfig()->cache) + { + $path = $this->getConfig()->cache_path; + + if(!is_dir($path) && (false === @mkdir($path, 0777, true) && !is_dir($path))) { + throw new RuntimeException(sprintf('The data cache path "%s" does not exist', $path)); + } + + if(!is_writable($path)) { + throw new RuntimeException(sprintf('The data cache path "%s" is not writable', $path)); + } + + if(!is_string($data)) + { + $result = 'getConfig()->cache_path.'/data_'.$hash.'.php'; + + if(@file_put_contents($file, $result) === false) { + throw new RuntimeException(sprintf('The data cannot be cached in "%s"', $file)); + } + + //Override default permissions for cache files + @chmod($file, 0666 & ~umask()); + + return $file; + } + + return false; + } + + public function isCached($file) + { + $result = false; + + if($this->getConfig()->cache) + { + $hash = crc32($file.PHP_VERSION); + $cache = $this->getConfig()->cache_path.'/data_'.$hash.'.php'; + $result = is_file($cache) ? $cache : false; + } + + return $result; + } + + public function _getHttpClient() + { + if(!($this->__http instanceof KHttpClientInterface)) + { + $this->__http = $this->getObject($this->__http); + + if(!$this->__http instanceof KHttpClientInterface) + { + throw new UnexpectedValueException( + 'Http client: '.get_class($this->__http).' does not implement KHttpClientInterface' + ); + } + } + + return $this->__http; + } + + protected function _getCacheControl($cache) + { + $cache_control = array(); + + if($cache !== true) + { + if($cache !== false) + { + //Convert max_age to seconds + if(!is_numeric($cache)) + { + if($max_age = strtotime($cache)) { + $max_age = $max_age - strtotime('now'); + } + } + else $max_age = $cache; + + $cache_control = ['max-age' => (int) $max_age]; + } + else $cache_control = ['no-store']; + } + + return $cache_control; + } +} diff --git a/Sites/pages/components/com_pages/database/table/abstract.php b/Sites/pages/components/com_pages/database/table/abstract.php new file mode 100644 index 00000000..d35774f1 --- /dev/null +++ b/Sites/pages/components/com_pages/database/table/abstract.php @@ -0,0 +1,30 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +abstract class ComPagesDatabaseTableAbstract extends KDatabaseTableAbstract +{ + public function __construct(KObjectConfig $config) + { + parent::__construct($config); + + //Reset identity column only re-adding it for an auto increment primary key + $this->_identity_column = null; + unset($this->_column_map['id']); + + foreach ($this->getColumns(true) as $column) + { + if ($column->autoinc) + { + $this->_identity_column = $column->name; + $this->_column_map['id'] = $column->name; + break; + } + } + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/database/table/default.php b/Sites/pages/components/com_pages/database/table/default.php new file mode 100644 index 00000000..b6a29ed1 --- /dev/null +++ b/Sites/pages/components/com_pages/database/table/default.php @@ -0,0 +1,13 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +final class ComPagesDatabaseTableDefault extends ComPagesDatabaseTableAbstract +{ + +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/database/table/groups.php b/Sites/pages/components/com_pages/database/table/groups.php new file mode 100644 index 00000000..b3c9a93c --- /dev/null +++ b/Sites/pages/components/com_pages/database/table/groups.php @@ -0,0 +1,20 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesDatabaseTableGroups extends KDatabaseTableAbstract +{ + protected function _initialize(KObjectConfig $config) + { + $config->append([ + 'name' => defined('JOOMLATOOLS_PLATFORM') ? 'users_groups' : 'usergroups' + ]); + + parent::_initialize($config); + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/database/table/roles.php b/Sites/pages/components/com_pages/database/table/roles.php new file mode 100644 index 00000000..eadcdcde --- /dev/null +++ b/Sites/pages/components/com_pages/database/table/roles.php @@ -0,0 +1,20 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesDatabaseTableRoles extends KDatabaseTableAbstract +{ + protected function _initialize(KObjectConfig $config) + { + $config->append([ + 'name' => defined('JOOMLATOOLS_PLATFORM') ? 'users_roles' : 'viewlevels' + ]); + + parent::_initialize($config); + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/dispatcher/behavior/cacheable.php b/Sites/pages/components/com_pages/dispatcher/behavior/cacheable.php new file mode 100644 index 00000000..f349bebb --- /dev/null +++ b/Sites/pages/components/com_pages/dispatcher/behavior/cacheable.php @@ -0,0 +1,576 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesDispatcherBehaviorCacheable extends KDispatcherBehaviorCacheable +{ + private $__validators; + + /** + * Cache HIT status codes + * + * The page was found in the cache. It has been served from the cache + */ + const CACHE_HIT = 'HIT'; + + //The page was validated, eg HIT, REVALIDATED + const CACHE_REVALIDATED = 'REVALIDATED'; + + //The page was served from the static cache, eg HIT, STATIC + const CACHE_STATIC = 'STATIC'; + + /** + * Cache MISS status codes + * + * The page has been generated + */ + const CACHE_MISS = 'MISS'; + + //The page was found in cache but has since expired. + const CACHE_EXPIRED = 'EXPIRED'; + + //The page was found in cache but has since been modified. + const CACHE_MODIFIED = 'MODIFIED'; + + //The page was found in cache and has been regenerated + const CACHE_REGENERATED = 'REGENERATED'; + + //The page was found in cache and the generated page is identical + const CACHE_IDENTICAL = 'IDENTICAL'; + + /** + * Cache Dynamic status codes + * + * The page settings don't allow the resource to be cached. + */ + const CACHE_DYNAMIC = 'DYNAMIC'; + + //The page was removed from the cache, eg DYNAMIC, PURGED + const CACHE_PURGED = 'PURGED'; + + protected function _initialize(KObjectConfig $config) + { + $config->append(array( + 'priority' => self::PRIORITY_LOWEST, + 'cache' => false, + 'cache_path' => $this->getObject('com://site/pages.config')->getSitePath('cache'), + 'cache_time' => false, //static + 'cache_time_shared' => false, //static + )); + + parent::_initialize($config); + } + + protected function _actionValidate(KDispatcherContextInterface $context) + { + if($this->isValidatable()) + { + $fresh = false; + $validators = array(); + + $response = clone $this->getResponse(); + + //Initialise the response object + if($this->loadCache() && $response->isCacheable()) + { + $cache = $this->loadCache(); + + //Get the validators from the cache + $validators = $cache['validators']; + + $response + ->setStatus($cache['status']) + ->setHeaders($cache['headers']) + ->setContent($cache['content']); + + $response->headers->set('Cache-Status', self::CACHE_HIT); + } + else + { + //Get validators from request + if($etag = $context->request->getEtag()) + { + $validators = $this->_decodeEtag($etag); + $response->setEtag($etag); + } + } + + //Check if the cache is valid + $valid = $this->validateCache($validators); + + //Check if response is stale + $stale = $response->isStale(); + + //Check the if the cache is fresh + if($this->isRefreshable() && !in_array('must-revalidate', $response->getCacheControl())) { + $fresh = ($valid === true || $stale !== true); + } else { + $fresh = ($valid !== false && $stale !== true); + } + + if($validators && $fresh) + { + //Refresh response if valid + if($valid === true) + { + $response->setDate(new DateTime('now')); + $response->headers->set('Age', null); + $response->headers->set('Cache-Status', self::CACHE_REVALIDATED, false); + $response->headers->set('Content-Location', (string) $this->getContentLocation()); + } + else $response->headers->set('Age', max(time() - $response->getDate()->format('U'), 0)); + + //Refresh cache if cacheable + if($this->loadCache() && $response->isCacheable()) + { + $cache['headers'] = $response->headers->toArray(); + $this->storeCache($cache); + } + + // Send the request if nothing has been send yet, or terminate otherwise + if(!headers_sent()) { + $response->send(); + } else { + $response->terminate(); + } + } + else + { + $context->response->headers->set('Cache-Status', self::CACHE_MISS); + + if($this->loadCache()) + { + if($valid === false) { + $context->response->headers->set('Cache-Status', self::CACHE_MODIFIED, false); + } elseif($stale) { + $context->response->headers->set('Cache-Status', self::CACHE_EXPIRED, false); + } + } + } + } + else + { + $context->response->headers->set('Cache-Status', self::CACHE_MISS); + + /* + * Force refresh validators (in case they are calculated from cache) + * + * The "no-cache" request directive indicates that a cache MUST NOT use a stored response to + * satisfy the request without successful validation on the origin server. + * + * See: https://tools.ietf.org/html/rfc7234#section-5.2.1.4 + */ + if($cache = $this->loadCache()) + { + $this->validateCache($cache['validators'], true); //ensure etag is regenerated + $context->response->headers->set('Cache-Status', self::CACHE_REGENERATED, false); + } + } + } + + protected function _actionCache(KDispatcherContextInterface $context) + { + $result = false; + $response = $context->getResponse(); + + if($response->isCacheable() && $response->isSuccess()) + { + //Reset the date and last-modified + $response->setDate(new DateTime('now')); + $response->setLastModified($response->getDate()); + + //If the cache exists and it has not been modified do not reset the Last-Modified date + if($cache = $this->loadCache() && $this->isIdentical()) { + $response->setLastModified(new DateTime($cache['headers']['Last-Modified'])); + } + + $data = array( + 'id' => $this->getContentLocation()->toString(KHttpUrl::PATH + KHttpUrl::QUERY), + 'url' => rtrim((string) $this->getContentLocation(), '/'), + 'validators' => $this->getCacheValidators(), + 'status' => !$response->isNotModified() ? $response->getStatusCode() : '200', + 'token' => $this->getCacheToken(), + 'format' => $response->getFormat(), + 'headers' => $response->headers->toArray(), + 'content' => (string) $response->getContent(), + 'language' => $this->getRoute()->getPage()->language, + ); + + $result = $this->storeCache($data); + } + + return $result; + } + + protected function _actionPurge(KDispatcherContextInterface $context) + { + $result = false; + + $context->getResponse()->headers->set('Cache-Status', self::CACHE_DYNAMIC); + + if($result = $this->deleteCache()) { + $context->getResponse()->headers->set('Cache-Status', self::CACHE_PURGED, false); + } + + return $result; + } + + protected function _beforeDispatch(KDispatcherContextInterface $context) + { + if($this->isCacheable()) + { + //Set the max age if defined in for the page + $page_time = $this->getPage()->process->get('cache', true); + $page_time = is_string($page_time) ? strtotime($page_time) - strtotime('now') : $page_time; + + if(is_int($page_time)) + { + $cache_time = $this->getConfig()->cache_time; + + if($cache_time !== false) + { + $cache_time = !is_numeric($cache_time) ? strtotime($cache_time) : $cache_time; + $max = $cache_time < $page_time ? $cache_time : $page_time; + + $context->response->setMaxAge($max, $page_time); + } + else $context->response->setMaxAge($page_time); + + $context->response->headers->set('Cache-Control', ['must-revalidate'], false); + } + + $this->validate(); + } + else $this->purge(); + } + + protected function _beforeSend(KDispatcherContextInterface $context) + { + //Get the response from the context + $response = $context->getResponse(); + + if($this->isCacheable()) + { + //Set the content collections + if($models = $this->getObject('model.factory')->getModels()) + { + $collections = array(); + foreach($models as $model) { + $collections[] = $model->getType(); + } + + $collections = array_unique($collections); + $response->headers->set('Content-Collections', implode(',', $collections)); + } + + //Set the weak etag + $validators = $this->getCacheValidators(); + $response->setEtag($this->_encodeEtag($validators), true); + + if($this->isIdentical()) { + $context->getResponse()->headers->set('Cache-Status', self::CACHE_IDENTICAL, false); + } + + } + else $response->headers->set('Cache-Control', ['no-store']); + } + + protected function _beforeTerminate(KDispatcherContextInterface $context) + { + $response = $context->response; + + //Store the response in the cache, only is the dispatcher is not being decorated + if($this->isCacheable() && $response->isCacheable() && !$this->isDecorated()) { + $this->cache(); + } + } + + public function getCacheValidators($refresh = false) + { + if(!isset($this->__validators) || $refresh) + { + $validators = array(); + + //Add hash (ensure the etag is unique) + $validators['hash'] = $this->getHash(); + + //Add user + $validators['user'] = $this->getUser()->getId(); + + //Add page + if($route = $this->getRoute()) + { + $validators['page'] = [ + 'path' => $route->getPage()->path, + 'hash' => $route->getPage()->hash + ]; + } + + //Add collections + foreach($this->getObject('model.factory')->getModels() as $model) + { + if($model->hash() !== false) + { + $validators['collections'][] = [ + 'hash' => $model->hash(), + 'name' => $model->getName(), + 'state' => $model->getHashState() + ]; + } + } + + $this->__validators = $validators; + } + + return $this->__validators; + } + + public function getCacheToken() + { + if($cache = $this->loadCache()) { + $token = $cache['token']; + } else { + $token = bin2hex(random_bytes('16')); + } + + return $token; + } + + public function getContentLocation() + { + /** + * Get content location + * + * If Content-Location is included in a 2xx (Successful) response message and its value refers (after + * conversion to absolute form) to a URI that is the same as the effective request URI, then the recipient + * MAY consider the payload to be a current representation of that resource at the time indicated by the + * message origination date. For a GET (Section 4.3.1) or HEAD (Section 4.3.2) request, this is the same + * as the default semantics when no Content-Location is provided by the server. + * + * See: https://tools.ietf.org/html/rfc7231#section-3.1.4.2 + */ + if(!$location = $this->getResponse()->headers->get('Content-Location')) + { + $location = $this->getRequest()->getUrl() + ->toString(KHttpUrl::SCHEME + KHttpUrl::HOST + KHttpUrl::PATH + KHttpUrl::QUERY); + } + + + return $this->getObject('http.url', ['url' => $location]); + } + + public function locateCache($url = null) + { + $key = $url ?? $this->getContentLocation()->toString(KHttpUrl::PATH + KHttpUrl::QUERY); + $file = $this->getConfig()->cache_path . '/response_' . crc32($key) . '.php'; + + return $file; + } + + public function loadCache() + { + static $data; + + if(!isset($data) && $this->getConfig()->cache) + { + $file = $this->locateCache(); + if (is_file($file)) + { + try { + $data = include($file); + } catch(Error $e) { + unlink($file); + } + } + } + + return $data ?? array(); + } + + public function validateCache($validators, $refresh = false) + { + static $hashes; + + $valid = false; + + if(is_array($validators) && !empty($validators)) + { + $valid = true; + + //Validate page + $page = $this->getPage($validators['page']['path']); + if($validators['page']['hash'] != $page->hash) { + $valid = false; + } + + //Validate user + $user = $this->getUser(); + if($valid && $validators['user'] != $user->getId()) { + $valid = false; + } + + //Validate collections + if($valid && isset($validators['collections'])) + { + foreach($validators['collections'] as $key => $model) + { + //Provide BC for cache validators + if(!is_numeric($key)) + { + $hash = $model; + $name = $key; + $state = array(); + } + else + { + $hash = $model['hash']; + $state = $model['state']; + $name = $model['name']; + } + + $identifier = hash('crc32b', $name.'.-'.$hash); + if(!isset($hashes[$identifier])) + { + $hashes[$identifier] = $this->getObject('model.factory') + ->createModel($name, $state) + ->hash($refresh); + } + + //If the collection has a hash validate it + if($hash) + { + if($hash != $hashes[$identifier]) { + $valid = false; + } + } + else $valid = null; + + //One of the collections is invalid + if($valid !== true) { + break; + } + } + } + } + + return $valid; + } + + public function storeCache($data) + { + if($this->getConfig()->cache) + { + $url = (string) $this->getContentLocation(); + $path = $this->getConfig()->cache_path; + + if(!is_dir($path) && (false === @mkdir($path, 0777, true) && !is_dir($path))) { + throw new RuntimeException(sprintf('The document cache path "%s" does not exist', $path)); + } + + if(!is_writable($path)) { + throw new RuntimeException(sprintf('The document cache path "%s" is not writable', $path)); + } + + if(!is_string($data)) + { + $result = 'locateCache(); + + if(@file_put_contents($file, $result) === false) { + throw new RuntimeException(sprintf('The document cannot be cached in "%s"', $file)); + } + + //Override default permissions for cache files + @chmod($file, 0666 & ~umask()); + + return $file; + } + + return false; + } + + public function deleteCache() + { + $result = false; + + $file = $this->locateCache(); + + if (is_file($file)) { + $result = unlink($file); + } + + return $result; + } + + public function isCacheable($strict = true) + { + $result = parent::isCacheable(); + + if($result && $strict) + { + //Check if the current page is cacheable + if($page = $this->getPage()) { + $result = (bool)$page->process->get('cache', true); + } else { + $result = false; + } + + //Failsafe in case an error got cached + if($cache = $this->loadCache()) { + $result = $cache['status'] >= 400 ? false : true; + } + } + + return $result; + } + + public function isValidatable() + { + //Can only validate cache if cacheable and the request allows for cache re-use + return $this->isCacheable() && !in_array('no-cache', $this->getRequest()->getCacheControl()); + } + + public function isRefreshable() + { + //Can only refresh cache if cacheable and the request allows for cache re-refreshing + return $this->isCacheable() && !in_array('must-revalidate', $this->getRequest()->getCacheControl()); + } + + public function isIdentical() + { + if(!$etag = $this->getRequest()->getEtag()) + { + if($cache = $this->loadCache()){ + $etag = $cache['headers']['Etag'] ?? null; + } + } + + return $etag == $this->getResponse()->getEtag(); + } + + protected function _encodeEtag(array $validators) + { + $data = json_encode($validators); + $etag = base64_encode(gzdeflate($data)); + + return $etag; + } + + protected function _decodeEtag($etag) + { + $validators = array(); + if($etag && $data = base64_decode($etag)) { + $validators = json_decode(gzinflate($data), true); + } + + return $validators; + } +} diff --git a/Sites/pages/components/com_pages/dispatcher/behavior/decoratable.php b/Sites/pages/components/com_pages/dispatcher/behavior/decoratable.php new file mode 100644 index 00000000..3989ee9d --- /dev/null +++ b/Sites/pages/components/com_pages/dispatcher/behavior/decoratable.php @@ -0,0 +1,106 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesDispatcherBehaviorDecoratable extends ComKoowaDispatcherBehaviorDecoratable +{ + protected function _beforeSend(KDispatcherContextInterface $context) + { + $response = $context->getResponse(); + $request = $context->getRequest(); + + if(!$response->isDownloadable() && !$response->isRedirect() && $request->getFormat() == 'html') + { + $decorator = $this->getDecorator(); + + //Set metadata in Joomla document + if($decorator == 'joomla') + { + //Set the title + if($title = $this->getController()->getView()->getTitle()) { + JFactory::getDocument()->setTitle($title); + } + + //Set the direction + if($direction = $this->getController()->getView()->getDirection()) { + JFactory::getDocument()->setDirection($direction); + } + + //Set the language + if($language = $this->getController()->getView()->getLanguage()) { + JFactory::getDocument()->setLanguage($language); + } + } + + $controller = $this->getObject('com:koowa.controller.page', array('response' => $response)); + + //Configure the page view + $controller->getView() + ->setDecorator($decorator) + ->setLayout($this->getLayout()); + + //Set the result in the response + $response->setContent($controller->render()); + } + } + + public function getLayout() + { + $result = 'joomla'; + + if(JDEBUG && $this->getResponse()->isError()) { + $result = 'koowa'; + } + + return $result; + } + + public function getDecorator() + { + $result = null; + + if($this->getRequest()->getFormat() == 'html') + { + $result = 'joomla'; + + if($content = $this->getResponse()->getContent()) + { + //Do not decorate if we are outputting a html document + if(!preg_match('##siU', $content)) { + $result = 'joomla'; + } else { + $result = 'koowa'; + } + } + } + + if(JDEBUG && $this->getResponse()->isError()) { + $result = 'koowa'; + } + + return $result; + } + + public function isDecorated() + { + return (bool) ($this->getDecorator() == 'joomla'); + } + + public function isSupported() + { + $mixer = $this->getMixer(); + $request = $mixer->getRequest(); + + // Support HTML GET requests and also form submits (so we can render errors on POST) + if(($request->isFormSubmit() || $request->isGet()) && $request->getFormat() == 'html') { + return true; + } + + return false; + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/dispatcher/behavior/redirectable.php b/Sites/pages/components/com_pages/dispatcher/behavior/redirectable.php new file mode 100644 index 00000000..9179f997 --- /dev/null +++ b/Sites/pages/components/com_pages/dispatcher/behavior/redirectable.php @@ -0,0 +1,65 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesDispatcherBehaviorRedirectable extends KControllerBehaviorAbstract +{ + protected function _initialize(KObjectConfig $config) + { + $config->append(array( + 'priority' => self::PRIORITY_HIGH, + )); + + parent::_initialize($config); + } + + protected function _beforeDispatch(KDispatcherContextInterface $context) + { + $router = $this->getObject('com://site/pages.dispatcher.router.redirect', ['request' => $context->request]); + + if(false !== $route = $router->resolve()) + { + if($route->toString(KHttpUrl::AUTHORITY)) + { + //External redierct: 301 permanent + $status = KHttpResponse::MOVED_PERMANENTLY; + } + else + { + //Internal redirect: 307 temporary + $status = KHttpResponse::TEMPORARY_REDIRECT; + } + + //Qualify the route + $url = $router->qualify($route); + + //Set the location header + $context->getResponse()->getHeaders()->set('Location', $url); + $context->getResponse()->setStatus($status); + + //Purge the cache + $dispatcher = $this->getObject('com://site/pages.dispatcher.http'); + if($dispatcher->isCacheable()) { + $dispatcher->purge(); + } + + $context->getSubject()->send(); + } + } + + protected function _beforeSend(KDispatcherContextInterface $context) + { + $response = $context->response; + $request = $context->request; + + //If we are submitting a form and there is no redirect defined use the url of the page. + if($request->isFormSubmit() && $request->getReferrer() && $response->isSuccess()) { + $response->setRedirect($request->getUrl()); + } + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/dispatcher/behavior/validatable.php b/Sites/pages/components/com_pages/dispatcher/behavior/validatable.php new file mode 100644 index 00000000..7bf19e6c --- /dev/null +++ b/Sites/pages/components/com_pages/dispatcher/behavior/validatable.php @@ -0,0 +1,56 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesDispatcherBehaviorValidatable extends KControllerBehaviorAbstract +{ + protected function _beforeDispatch(KDispatcherContextInterface $context) + { + if(!$context->request->isSafe()) + { + //Validate the content type + $content_types = array('application/json', 'application/x-www-form-urlencoded'); + if(!in_array($context->request->getContentType(), $content_types)) { + throw new KHttpExceptionUnsupportedMediaType(); + } + + if($page = $context->page) + { + //Validate the honeypot + if($page->isSubmittable()) + { + if($honeypot = $page->form->honeypot) + { + if($context->request->data->get($honeypot, 'raw')) { + throw new ComPagesControllerExceptionRequestBlocked('Spam attempt blocked'); + } else { + $context->request->data->remove($honeypot); + } + } + } + } + } + } + + protected function _beforePut(KDispatcherContextInterface $context) + { + if($page = $context->page) + { + //Check constraints + if($page->isEditable()) + { + foreach($page->collection->schema as $name => $constraints) + { + if(!$context->request->data->has($name)) { + throw new ComPagesControllerExceptionRequestInvalid(sprintf('%s is required', ucfirst($name))); + } + } + } + } + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/dispatcher/context/context.php b/Sites/pages/components/com_pages/dispatcher/context/context.php new file mode 100644 index 00000000..99a76139 --- /dev/null +++ b/Sites/pages/components/com_pages/dispatcher/context/context.php @@ -0,0 +1,31 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesDispatcherContext extends KDispatcherContext implements ComPagesDispatcherContextInterface +{ + public function getRouter() + { + return KObjectConfig::get('router'); + } + + public function setRouter(ComPagesDispatcherRouterInterface $router) + { + return KObjectConfig::set('router', $router); + } + + public function getPage() + { + return KObjectConfig::get('page'); + } + + public function setPage(ComPagesPageEntity $page) + { + return KObjectConfig::set('page', $page); + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/dispatcher/context/interface.php b/Sites/pages/components/com_pages/dispatcher/context/interface.php new file mode 100644 index 00000000..4a40b017 --- /dev/null +++ b/Sites/pages/components/com_pages/dispatcher/context/interface.php @@ -0,0 +1,15 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +interface ComPagesDispatcherContextInterface extends KDispatcherContextInterface +{ + public function getRouter(); + + public function getPage(); +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/dispatcher/http.php b/Sites/pages/components/com_pages/dispatcher/http.php new file mode 100644 index 00000000..260c29de --- /dev/null +++ b/Sites/pages/components/com_pages/dispatcher/http.php @@ -0,0 +1,273 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesDispatcherHttp extends ComKoowaDispatcherHttp +{ + use ComPagesPageTrait; + + private $__router; + private $__route; + + public function __construct( KObjectConfig $config) + { + parent::__construct($config); + + $this->__router = $config->router; + + //Set the page + $this->setPage($config->page); + } + + protected function _initialize(KObjectConfig $config) + { + $config->append([ + 'behaviors' => [ + 'redirectable', + 'cacheable', + 'validatable' + ], + 'page' => 'com://site/pages.page', + 'router' => 'com://site/pages.dispatcher.router', + ]); + + parent::_initialize($config); + } + + public function setRouter(ComPagesDispatcherRouterInterface $router) + { + $this->__router = $router; + return $this; + } + + public function getRouter() + { + if(!$this->__router instanceof ComPagesDispatcherRouterInterface) + { + $this->__router = $this->getObject($this->__router, array( + 'request' => $this->getRequest(), + )); + + if(!$this->__router instanceof ComPagesDispatcherRouterInterface) + { + throw new UnexpectedValueException( + 'Router: '.get_class($this->__router).' does not implement ComPagesDispatcherRouterInterface' + ); + } + } + + return $this->__router; + } + + public function getRoute() + { + $result = false; + + if(!isset($this->__route) && $this->getObject('com://site/pages.config')->getSitePath() !== false) + { + $base = $this->getRequest()->getBasePath(); + $url = urldecode($this->getRequest()->getUrl()->getPath()); + + //Strip script name if request is rewritten + if(!isset($_SERVER['PAGES_PATH'])) { + $path = str_replace(array($base, basename($_SERVER['SCRIPT_NAME'])), '', $url); + } else { + $path = str_replace($base, '', $url); + } + + $path = trim($path, '/'); + $query = $this->getRequest()->getUrl()->getQuery(true); + + if($route = $this->getRouter()->resolve('pages:'.$path, $query)) { + $this->getPage()->setProperties($route->getPage()); + } + + $this->__route = $route; + } + + if(is_object($this->__route)) { + $result = clone $this->__route; + } + + return $result; + } + + public function getHttpMethods() + { + $methods = array('head', 'options'); + + if($page = $this->getPage()) + { + if($page->isSubmittable()) + { + //Do not allow get on empty forms or collection, only used as API endpoints + if($page->getContent() || $page->layout) { + $methods[] = 'get'; + } + } + else $methods[] = 'get'; + + if($page->isSubmittable()) { + $methods[] = 'post'; + } + + if($page->isEditable()) + { + $methods[] = 'post'; + $methods[] = 'put'; + $methods[] = 'patch'; + $methods[] = 'delete'; + } + } + + return $methods; + } + + public function getHttpFormats() + { + $formats = array(); + + if($page = $this->getPage()) + { + $formats = (array) $page->format; + + if($collection = $page->isCollection()) + { + if(isset($collection['format'])) { + $formats = array_merge($formats, (array) $collection['format']); + } + } + } + + return array_unique($formats); + } + + protected function _beforeDispatch(KDispatcherContextInterface $context) + { + //Throw 404 if the site was not found + if(false === $this->getObject('com://site/pages.config')->getSitePath()) { + throw new KHttpExceptionNotFound('Site Not Found'); + } + + //Throw 404 if the page was not found + if(false === $route = $this->getRoute()) { + throw new KHttpExceptionNotFound('Page Not Found'); + } + + //Set the query in the request + $context->request->setQuery($route->query); + + //Throw 415 if the media type is not allowed + $format = strtolower($context->request->getFormat()); + if (!in_array($format, $this->getHttpFormats())) + { + $accept = $context->request->getAccept(); + + //Use default if no accept header or accept includes */* + if(empty($accept) || array_key_exists('*/*', $accept)) { + $context->request->setFormat($context->page->format); + } else { + throw new KHttpExceptionNotAcceptable('Format not supported'); + } + } + } + + protected function _actionDispatch(KDispatcherContextInterface $context) + { + //Set the controller + $this->setController($context->page->getType(), ['page' => $context->page]); + + //Throw 405 if the method is not allowed + $method = strtolower($context->request->getMethod()); + if (!in_array($method, $this->getHttpMethods())) { + throw new KDispatcherExceptionMethodNotAllowed('Method not allowed'); + } + + //Execute the component method + $this->execute($method, $context); + + KDispatcherAbstract::_actionDispatch($context); + } + + protected function _actionGet(KDispatcherContextInterface $context) + { + if($collection = $context->page->isCollection()) + { + if(isset($collection['state']) && isset($collection['state']['limit'])) + { + $this->getConfig()->limit->default = $collection['state']['limit']; + $this->getConfig()->limit->max = $collection['state']['limit']; + } + } + + return parent::_actionGet($context); + } + + protected function _actionPost(KDispatcherContextInterface $context) + { + if(!$context->page->isForm()) + { + if(!$context->request->data->has('_action')) + { + $action = $this->getController()->getModel()->isAtomic() ? 'edit' : 'add'; + $context->request->data->set('_action', $action); + } + + $result = parent::_actionPost($context); + + } + else $result = $this->getController()->execute('submit', $context); + + return $result; + } + + protected function _beforeSend(KDispatcherContextInterface $context) + { + //Add a (self-referential) canonical URL (only to GET and HEAD requests) + if($context->page && $context->request->isCacheable()) + { + if(!$context->page->canonical && $this->getRoute()) + { + $route = $context->router->generate($this->getRoute()); + $context->page->canonical = (string) $context->router->qualify($route); + } + + $this->getResponse()->getHeaders()->set('Link', array($context->page->canonical => array('rel' => 'canonical'))); + + //Add X-Robots-Tag + if($context->page->metadata->has('robots')) + { + $tags = KObjectConfig::unbox($context->page->metadata->robots); + $this->getResponse()->getHeaders()->set('X-Robots-Tag', $tags); + } + } + } + + protected function _actionSend(KDispatcherContextInterface $context) + { + //Do not send the response if it was already send + if(!headers_sent()) { + parent::_actionSend($context); + } else { + $this->terminate($context); + } + } + + public function getContext() + { + $context = new ComPagesDispatcherContext(); + $context->setSubject($this); + $context->setRequest($this->getRequest()); + $context->setResponse($this->getResponse()); + $context->setUser($this->getUser()); + $context->setRouter($this->getRouter()); + $context->setPage($this->getPage()); + + return $context; + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/dispatcher/router/abstract.php b/Sites/pages/components/com_pages/dispatcher/router/abstract.php new file mode 100644 index 00000000..3596664f --- /dev/null +++ b/Sites/pages/components/com_pages/dispatcher/router/abstract.php @@ -0,0 +1,302 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +/** + * Abstract Dispatcher Router + * + * The router add resolvers to a double linked list to allow. The order in which resolvers are called depends on the + * process, when resolving resolvers are called in LIFO order, when generating the resolvers are called in FIFO order. + * + * @author Johan Janssens + * @package Koowa\Library\Dispatcher\Router + */ +abstract class ComPagesDispatcherRouterAbstract extends KObject implements ComPagesDispatcherRouterInterface, KObjectMultiton +{ + /** + * Request object + * + * @var KControllerRequestInterface + */ + private $__request; + + /** + * The route resolver stack + * + * @var SplDoublyLinkedList + */ + private $__resolvers; + + /** + * Constructor + * + * @param KObjectConfig $config Configuration options + */ + public function __construct(KObjectConfig $config) + { + parent::__construct($config); + + $this->setRequest($config->request); + + //Create the resolver queue + $this->__resolvers = new SplDoublyLinkedList(); + + //Attach the router resolvers + $resolvers = (array) KObjectConfig::unbox($config->resolvers); + + foreach ($resolvers as $key => $value) + { + if (is_numeric($key)) { + $this->attachResolver($value); + } else { + $this->attachResolver($key, $value); + } + } + } + + /** + * Initializes the options for the object + * + * Called from {@link __construct()} as a first step of object instantiation. + * + * @param KObjectConfig $config An optional ObjectConfig object with configuration options. + * @return void + */ + protected function _initialize(KObjectConfig $config) + { + $config->append(array( + 'request' => null, + 'route' => 'default', + 'resolvers' => [], + )); + + parent::_initialize($config); + } + + /** + * Resolve a route + * + * @param string|ComPagesDispatcherRouterRouteInterface|KObjectInterface $route The route to resolve + * @param array $parameters Route parameters + * @return false| ComPagesDispatcherRouterInterface Returns the matched route or false if no match was found + */ + public function resolve($route, array $parameters = array()) + { + $route = $this->getRoute($route, $parameters); + + if(!$route->isResolved()) + { + $this->__resolvers->setIteratorMode(SplDoublyLinkedList::IT_MODE_LIFO | SplDoublyLinkedList::IT_MODE_KEEP); + + foreach($this->__resolvers as $resolver) { + $resolver->resolve($route, $parameters); + } + } + + return $route->isResolved() ? $route : false; + } + + /** + * Generate a route + * + * @param string|ComPagesDispatcherRouterRouteInterface|KObjectInterface $route The route to resolve + * @param array $parameters Route parameters + * @return false|KHttpUrlInterface Returns the generated route + */ + public function generate($route, array $parameters = array()) + { + $route = $this->getRoute($route, $parameters); + + if(!$route->isGenerated()) + { + $this->__resolvers->setIteratorMode(SplDoublyLinkedList::IT_MODE_FIFO | SplDoublyLinkedList::IT_MODE_KEEP); + + foreach($this->__resolvers as $resolver) { + $resolver->generate($route, $parameters); + } + } + + return $route->isGenerated() ? $route : false; + } + + /** + * Qualify a route + * + * Replace the url authority with the authority of the request url + * @param ComPagesDispatcherRouterRouteInterface $route The route to qualify + * @param bool $replace If the url is already qualified replace the authority + * @return string + */ + public function qualify(ComPagesDispatcherRouterRouteInterface $route, $replace = false) + { + $url = clone $route; + + if($replace || !$route->isAbsolute()) + { + $request = $this->getRequest(); + + //Qualify the url + $url->setUrl($request->getUrl()->toString(KHttpUrl::AUTHORITY)); + + $base = $request->getBasePath(); + $path = trim($url->getPath(), '/'); + + //Add script name (index.php) if request is not rewritten + if(!isset($_SERVER['PAGES_PATH'])) { + $url->setPath($base . '/'. basename($_SERVER['SCRIPT_NAME']).'/' . $path); + } else { + $url->setPath($base.'/'.$path); + } + } + + return $url; + } + + /** + * Get a route + * + * @param string|ComPagesDispatcherRouterRouteInterface $route The route to compile + * @param array $parameters Route parameters + * @return ComPagesDispatcherRouterRouteInterface + */ + public function getRoute($route, array $parameters = array()) + { + if(!$route instanceof ComPagesDispatcherRouterRouteInterface) + { + $name = $this->getConfig()->route; + + if(is_string($name) && strpos($name, '.') === false ) + { + $identifier = $this->getIdentifier()->toArray(); + $identifier['path'] = ['dispatcher', 'router', 'route']; + $identifier['name'] = $name; + + $identifier = $this->getIdentifier($identifier); + } + else $identifier = $this->getIdentifier($name); + + $route = $this->getObject($identifier, ['url' => $route, 'query' => $parameters]); + + if(!$route instanceof ComPagesDispatcherRouterRouteInterface) + { + throw new UnexpectedValueException( + 'Route: '.get_class($route).' does not implement ComPagesDispatcherRouterRouteInterface' + ); + } + } + else + { + $route = clone $route; + $route->setQuery($parameters, true); + } + + return $route; + } + + /** + * Get a route resolver + * + * @param mixed $resolver KObjectIdentifier object or valid identifier string + * @param array $config An optional associative array of configuration settings + * @throws UnexpectedValueException + * @return ComPagesDispatcherRouterResolverInterface + */ + public function getResolver($resolver, $config = array()) + { + if(is_string($resolver) && strpos($resolver, '.') === false ) + { + $identifier = $this->getIdentifier()->toArray(); + $identifier['path'] = ['dispatcher', 'router', 'resolver']; + $identifier['name'] = $resolver; + + $identifier = $this->getIdentifier($identifier); + } + else $identifier = $this->getIdentifier($resolver); + + $resolver = $this->getObject($identifier, $config); + + if (!($resolver instanceof ComPagesDispatcherRouterResolverInterface)) + { + throw new UnexpectedValueException( + "Resolver $identifier does not implement ComPagesDispatcherRouterResolverInterface" + ); + } + + return $resolver; + } + + /** + * Get the list of attached resolvers + * + * @return array + */ + public function getResolvers() + { + return iterator_to_array($this->__resolvers); + } + + /** + * Attach a route resolver + * + * @param mixed $resolver An object that implements ObjectInterface, ObjectIdentifier object + * or valid identifier string + * @param array $config An optional associative array of configuration settings + * @param bool $prepend If true, the resolver will be prepended instead of appended. + * @return ComPagesDispatcherRouterAbstract + */ + public function attachResolver($resolver, $config = array(), $prepend = false) + { + if (!($resolver instanceof ComPagesDispatcherRouterResolverInterface)) { + $resolver = $this->getResolver($resolver, $config); + } + + //Enqueue the router resolver + if($prepend) { + $this->__resolvers->unshift($resolver); + } else { + $this->__resolvers->push($resolver); + } + + return $this; + } + + /** + * Set the request object + * + * @param KControllerRequestInterface $request A request object + * @return ComPagesDispatcherRouterAbstract + */ + public function setRequest(KControllerRequestInterface $request) + { + $this->__request = $request; + return $this; + } + + /** + * Get the request object + * + * @return KControllerRequestInterface + */ + public function getRequest() + { + return $this->__request; + } + + /** + * Deep clone of this instance + * + * @return void + */ + public function __clone() + { + parent::__clone(); + + $this->__request = clone $this->__request; + $this->__resolvers = clone $this->__resolvers; + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/dispatcher/router/interface.php b/Sites/pages/components/com_pages/dispatcher/router/interface.php new file mode 100644 index 00000000..a41e8b79 --- /dev/null +++ b/Sites/pages/components/com_pages/dispatcher/router/interface.php @@ -0,0 +1,99 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +/** + * Dispatcher Router Interface + * + * Provides route building and parsing functionality + * + * @author Johan Janssens + * @package Koowa\Library\Dispatcher\Router + */ +interface ComPagesDispatcherRouterInterface +{ + /** + * Resolve a route + * + * @param string|ComPagesDispatcherRouterRouteInterface|KObjectInterface $route The route to resolve + * @param array $parameters Route parameters + * @return false| ComPagesDispatcherRouterInterface Returns the matched route or false if no match was found + */ + public function resolve($route, array $parameters = array()); + + /** + * Generate a route + * + * @param string|ComPagesDispatcherRouterRouteInterface|KObjectInterface $route The route to resolve + * @param array $parameters Route parameters + * @return false|KHttpUrlInterface Returns the generated route + */ + public function generate($route, array $parameters = array()); + + /** + * Qualify a route + * + * Replace the url authority with the authority of the request url + * @param ComPagesDispatcherRouterRouteInterface $route The route to qualify + * @param bool $replace If the url is already qualified replace the authority + * @return string + */ + public function qualify(ComPagesDispatcherRouterRouteInterface $route, $replace = false); + + /** + * Get a route resolver + * + * @param mixed $resolver KObjectIdentifier object or valid identifier string + * @param array $config An optional associative array of configuration settings + * @throws UnexpectedValueException + * @return ComPagesDispatcherRouterAbstract + */ + public function getResolver($resolver, $config = array()); + + /** + * Get the list of attached resolvers + * + * @return array + */ + public function getResolvers(); + + /** + * Attach a route resolver + * + * @param mixed $resolver An object that implements ObjectInterface, ObjectIdentifier object + * or valid identifier string + * @param array $config An optional associative array of configuration settings + * @param bool $prepend If true, the resolver will be prepended instead of appended. + * @return ComPagesDispatcherRouterAbstract + */ + public function attachResolver($resolver, $config = array(), $prepend = false); + + /** + * Get a route + * + * @param string|ComPagesDispatcherRouterRouteInterface $route The route to resolve + * @param array $parameters Route parameters + * @return ComPagesDispatcherRouterRouteInterface + */ + public function getRoute($route, array $parameters = array()); + + /** + * Set the request object + * + * @param KControllerRequestInterface $request A request object + * @return ComPagesDispatcherRouterInterface + */ + public function setRequest(KControllerRequestInterface $request); + + /** + * Get the request object + * + * @return KControllerRequestInterface + */ + public function getRequest(); +} diff --git a/Sites/pages/components/com_pages/dispatcher/router/pages.php b/Sites/pages/components/com_pages/dispatcher/router/pages.php new file mode 100644 index 00000000..bc9edc80 --- /dev/null +++ b/Sites/pages/components/com_pages/dispatcher/router/pages.php @@ -0,0 +1,36 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesDispatcherRouterPages extends ComPagesDispatcherRouterAbstract +{ + protected function _initialize(KObjectConfig $config) + { + $config->append([ + 'route' => 'page', + 'routes' => $this->getObject('page.registry')->getRoutes(), + ])->append(([ + 'resolvers' => [ + 'state', + 'pagination', + 'regex' => ['routes' => $config->routes], + ] + ])); + + parent::_initialize($config); + } + + public function getRoute($route, array $parameters = array()) + { + if($route instanceof ComPagesModelEntityPage) { + $route = 'pages:'.$route->path; + } + + return parent::getRoute($route, $parameters); + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/dispatcher/router/redirect.php b/Sites/pages/components/com_pages/dispatcher/router/redirect.php new file mode 100644 index 00000000..fd3ce87e --- /dev/null +++ b/Sites/pages/components/com_pages/dispatcher/router/redirect.php @@ -0,0 +1,44 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesDispatcherRouterRedirect extends ComPagesDispatcherRouterAbstract +{ + protected function _initialize(KObjectConfig $config) + { + $config->append([ + 'routes' => $this->getObject('page.registry')->getRedirects(), + ])->append([ + 'resolvers' => [ + 'regex' => ['routes' => $config->routes] + ] + ]); + + parent::_initialize($config); + } + + public function resolve($route = null, array $parameters = array()) + { + if(!$route) + { + $base = $this->getRequest()->getBasePath(); + $url = urldecode( $this->getRequest()->getUrl()->getPath()); + + //Strip script name if request is not rewritten (allow to redirect /index.php/) + if(!isset($_SERVER['PAGES_PATH'])) { + $route = str_replace(array($base, basename($_SERVER['SCRIPT_NAME'])), '', $url); + } else { + $route = str_replace($base, '', $url); + } + + $route = trim($route, '/'); + } + + return parent::resolve($route, $parameters); + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/dispatcher/router/resolver/abstract.php b/Sites/pages/components/com_pages/dispatcher/router/resolver/abstract.php new file mode 100644 index 00000000..21fc89e9 --- /dev/null +++ b/Sites/pages/components/com_pages/dispatcher/router/resolver/abstract.php @@ -0,0 +1,42 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + + +/** + * Abstract Dispatcher Route Resolver + * + * @author Johan Janssens + * @package Koowa\Library\Dispatcher\Router\Resolver + */ +abstract class ComPagesDispatcherRouterResolverAbstract extends KObject implements ComPagesDispatcherRouterResolverInterface +{ + /** + * Resolve the route + * + * @param ComPagesDispatcherRouterInterface $route The route to resolve + * @return bool + */ + public function resolve(ComPagesDispatcherRouterRouteInterface $route) + { + $route->setResolved(); + return true; + } + + /** + * Reversed routing + * + * @param ComPagesDispatcherRouterInterface $route The route to generate + * @return bool + */ + public function generate(ComPagesDispatcherRouterRouteInterface $route) + { + $route->setGenerated(); + return true; + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/dispatcher/router/resolver/default.php b/Sites/pages/components/com_pages/dispatcher/router/resolver/default.php new file mode 100644 index 00000000..ba360013 --- /dev/null +++ b/Sites/pages/components/com_pages/dispatcher/router/resolver/default.php @@ -0,0 +1,16 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +/** + * Default Dispatcher Route Resolver + * + * @author Johan Janssens + * @package Koowa\Library\Dispatcher\Router\Resolver + */ +final class ComPagesDispatcherRouterResolverDefault extends ComPagesDispatcherRouterResolverRegex { } \ No newline at end of file diff --git a/Sites/pages/components/com_pages/dispatcher/router/resolver/interface.php b/Sites/pages/components/com_pages/dispatcher/router/resolver/interface.php new file mode 100644 index 00000000..7d0a0f0e --- /dev/null +++ b/Sites/pages/components/com_pages/dispatcher/router/resolver/interface.php @@ -0,0 +1,35 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +/** + * Dispatcher Route Resolver Interface + * + * Provides route building and parsing functionality + * + * @author Johan Janssens + * @package Koowa\Library\Dispatcher\Router\Resolver + */ +interface ComPagesDispatcherRouterResolverInterface +{ + /** + * Resolve the route + * + * @param ComPagesDispatcherRouterInterface $route The route to resolve + * @return bool + */ + public function resolve(ComPagesDispatcherRouterRouteInterface $route); + + /** + * Reversed routing + * + * @param ComPagesDispatcherRouterInterface $route The route to generate + * @return bool + */ + public function generate(ComPagesDispatcherRouterRouteInterface $route); +} diff --git a/Sites/pages/components/com_pages/dispatcher/router/resolver/pagination.php b/Sites/pages/components/com_pages/dispatcher/router/resolver/pagination.php new file mode 100644 index 00000000..3d05c224 --- /dev/null +++ b/Sites/pages/components/com_pages/dispatcher/router/resolver/pagination.php @@ -0,0 +1,131 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +/** + * Pagination Dispatcher Route Resolver + * + * @author Johan Janssens + * @package Koowa\Library\Dispatcher\Router\Resolver + */ +class ComPagesDispatcherRouterResolverPagination extends ComPagesDispatcherRouterResolverAbstract +{ + public function resolve(ComPagesDispatcherRouterRouteInterface $route) + { + $state = $this->_getState($route); + + //Get the state + if($page = $route->getPage()) + { + if(($collection = $page->isCollection()) && isset($collection['state'])) { + $state = $collection['state']; + } + } + + if($route->getFormat() == 'json') + { + if(isset($route->query['page'])) + { + $page = $route->query['page']; + + if(isset($page['number']) && $state['limit']) { + $route->query['offset'] = ($page['number'] - 1) * (int) $state['limit']; + } + + if(isset($page['limit'])) { + $route->query['limit'] = (int) $page['limit']; + } + + if(isset($page['offset'])) { + $route->query['offset'] = (int) $page['offset']; + } + + if(isset($page['total'])) { + $route->query['total'] = (int) $page['total']; + } + + unset($route->query['page']); + } + } + else + { + if(isset($route->query['page'])) + { + $page = $route->query['page']; + + if($page && $state['limit']) { + $route->query['offset'] = ($page - 1) * (int) $state['limit']; + } + + unset($route->query['page']); + } + } + } + + public function generate(ComPagesDispatcherRouterRouteInterface $route) + { + $page = array(); + $state = $this->_getState($route); + + if($route->getFormat() == 'json') + { + if (isset($route->query['offset'])) { + $page['offset'] = $route->query['offset']; + unset($route->query['offset']); + } + + if (isset($route->query['limit'])) { + $page['limit'] = $route->query['limit']; + unset($route->query['offset']); + } + + if (isset($route->query['total'])) { + $page['total'] = $route->query['total']; + unset($route->query['total']); + } + + if (isset($state['limit']) && isset($page['offset'])) + { + if($state['limit']) { + $page['number'] = ceil($page['offset'] / $state['limit']) + 1; + } + + unset($page['offset']); + } + + $route->query['page'] = $page; + } + else + { + if (isset($state['limit']) && isset($route->query['offset'])) + { + $page = ceil($route->query['offset'] / $state['limit']) + 1; + + if($page > 1) { + $route->query['page'] = $page; + } + + unset($route->query['offset']); + } + } + } + + protected function _getState(ComPagesDispatcherRouterRoutePage $route) + { + $state = array(); + + if($page = $route->getPage()) + { + if(($collection = $page->isCollection()) && isset($collection['state'])) { + $state = $collection['state']; + } + } + + return $state; + } +} diff --git a/Sites/pages/components/com_pages/dispatcher/router/resolver/regex.php b/Sites/pages/components/com_pages/dispatcher/router/resolver/regex.php new file mode 100644 index 00000000..55228809 --- /dev/null +++ b/Sites/pages/components/com_pages/dispatcher/router/resolver/regex.php @@ -0,0 +1,366 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + + +/** + * Regex Dispatcher Route Resolver + * + * Inspired by Altorouter: https://github.com/dannyvankooten/AltoRouter + * + * @author Johan Janssens + * @package Koowa\Library\Dispatcher\Router\Resolver + */ +class ComPagesDispatcherRouterResolverRegex extends ComPagesDispatcherRouterResolverAbstract +{ + /** + * Static routes + * + * @var array + */ + private $__static_routes = array(); + + /** + * Dynamic routes + * + * @var array + */ + private $__dynamic_routes = array(); + + /** + * Array of default match types (regex helpers) + * + * @var array + */ + protected $_match_types; + + /** + * Constructor + * + * @param KObjectConfig $config Configuration options + */ + public function __construct(KObjectConfig $config) + { + parent::__construct($config); + + // The match types + $this->_match_types = $config->types; + + //Add the routes + $this->addRoutes($config->routes); + } + + /** + * Initializes the options for the object + * + * Called from {@link __construct()} as a first step of object instantiation. + * + * @param KObjectConfig $config Configuration options + * @return void + */ + protected function _initialize(KObjectConfig $config) + { + $config->append(array( + 'routes' => array(), + 'types' => [ + 'email' => '\S+@\S+', + 'month' => '(0?[1-9]|1[012])', + 'year' => '(19|20)\d{2}', + 'lang' => '[a-z]{2,3}(-[A-Z]{2,3}){0,1}', + 'digit' => '[0-9]++', + '*digit' => '[0-9]+(,[0-9]+)*', + 'alnum' => '[0-9A-Za-z]++', + '*alnum' => '[0-9A-Za-z]+(,[0-9A-Za-z]+)*', + 'alpha' => '[A-Za-z]++', + '*alpha' => '[A-Za-z]+(,[A-Za-z]+)*', + '*' => '.+?', + '**' => '.++', + '' => '[^/\.]++', + ], + )); + + parent::_initialize($config); + } + + /** + * Add a route for matching + * + * @param string $regex The route regex You can use multiple pre-set regex filters, like [digit:id] + * @param string $path The path this route should point to. + * @return ComPagesDispatcherRouterResolverInterface + */ + public function addRoute($regex, $path) + { + $regex = trim($regex, '/'); + $path = rtrim($path, '/'); + + if(strpos($regex, '[') !== false) { + $this->__dynamic_routes[$regex] = $path; + } else { + $this->__static_routes[$regex] = $path; + } + + return $this; + } + + /** + * Add routes for matching + * + * @param array $routes The routes to be added + * @return ComPagesDispatcherRouterResolverInterface + */ + public function addRoutes($routes) + { + foreach((array)KObjectConfig::unbox($routes) as $path => $routes) + { + foreach((array) $routes as $regex) + { + if (is_numeric($path)) { + $this->addRoute($regex, $regex); + } else { + $this->addRoute($regex, $path); + } + } + } + + return $this; + } + + /** + * Resolve the route + * + * @param ComPagesDispatcherRouterInterface $route The route to resolve + * @return bool + */ + public function resolve(ComPagesDispatcherRouterRouteInterface $route) + { + $result = false; + $path = ltrim($route->getPath(), '/'); + + //Check if we have a static route + if(!isset($this->__static_routes[$path])) + { + //Match against the dynamic routes + foreach($this->__dynamic_routes as $regex => $target) + { + //If regex doesn't start at offset 0 compare longest non-param string with path + if($regex[0] !== '[') + { + $pos = strpos($regex, '/[') ?? strpos($regex, '.['); + + if (substr_compare($path, $regex, 0, $pos) !== 0) { + continue; + } + } + + //Try to parse the route + if (false !== $this->_parseRoute($regex, $route)) + { + $result = $this->__dynamic_routes[$regex]; + break; + } + } + } + else + { + $result = $this->__static_routes[$path]; + + //Move matched route to the top of the stack for reverse lookups + $this->__static_routes = array($path => $result) + $this->__static_routes; + } + + if($result !== false) { + $this->_buildRoute($result, $route); + } + + return $result !== false ? parent::resolve($route) : false; + } + + /** + * Reversed routing + * + * Generate the URL for a route. Replace regexes with supplied parameters + * + * @param ComPagesDispatcherRouterInterface $route The route to generate + * @return bool + */ + public function generate(ComPagesDispatcherRouterRouteInterface $route) + { + $generated = false; + $path = ltrim($route->getPath(), '/'); + + //Dynamic routes + if($routes = array_keys($this->__dynamic_routes, $path)) + { + foreach($routes as $regex) + { + //Generate the dynamic route + if($this->_buildRoute($regex, $route)) { + $generated = true; break; + } + } + } + + //Static routes + if(!$generated) + { + $routes = array_flip(array_reverse($this->__static_routes, true)); + + if(isset($routes[$path])) + { + if($this->_buildRoute($routes[$path], $route)) { + $generated = true; + } + } + } + + return $generated ? parent::generate($route) : false; + } + + /** + * Parse a route + * + * @param string $regex The route regex You can use multiple pre-set regex filters, like [digit:id] + * @param ComPagesDispatcherRouterInterface $route The route to parse + * @return bool + */ + protected function _parseRoute($regex, ComPagesDispatcherRouterRouteInterface $route) + { + $result = false; + + $query = array(); + $path = ltrim($route->getPath(), '/'); + + if(strpos($regex, '[') !== false) + { + //Compile the regex for the route + if (preg_match_all('`(/|\.|)\[([^:\]]*+)(?::([^:\]]*+))?\](\?|)`', $regex, $matches, PREG_SET_ORDER)) + { + foreach ($matches as $match) + { + list($block, $pre, $type, $param, $optional) = $match; + + if (isset($this->_match_types[$type])) { + $type = $this->_match_types[$type]; + } + + if ($pre === '.') { + $pre = '\.'; + } + + $optional = $optional !== '' ? '?' : null; + + //Older versions of PCRE require the 'P' in (?P) + $pattern = '(?:' + . ($pre !== '' ? $pre : null) + . '(' + . ($param !== '' ? "?P<$param>" : null) + . $type + . ')' + . $optional + . ')' + . $optional; + + $regex = str_replace($block, $pattern, $regex); + } + } + + + //Try to match + if (preg_match("`^$regex$`u", $path, $query) === 1) + { + foreach ((array)$query as $key => $value) + { + if (!is_numeric($key)) + { + if(strpos($value, ',') !== false) { + $query[$key] = explode(',', $value); + } + } + else unset($query[$key]); + } + + $route->setParameters($query); + $result = true; + } + } + + return $result; + } + + /** + * Build a route + * + * @param string $route The route regex You can use multiple pre-set regex filters, like [digit:id] + * @param ComPagesDispatcherRouterInterface $route The route to build + * @return false + */ + protected function _buildRoute($regex, ComPagesDispatcherRouterRouteInterface $route) + { + $result = true; + $replaced = array(); + $regex = ltrim($regex, '/'); + + if(strpos($regex, '[') !== false) + { + //Prepend base path to route url again + if (preg_match_all('`(/|\.|)\[([^:\]]*+)(?::([^:\]]*+))?\](\?|)`', $regex, $matches, PREG_SET_ORDER)) + { + foreach ($matches as $index => $match) + { + list($block, $pre, $type, $param, $optional) = $match; + + if ($pre) { + $block = substr($block, 1); + } + + if(isset($route->query[$param])) + { + if(is_array($route->query[$param])) { + $value= implode(',', $route->query[$param]); + } else { + $value = $route->query[$param]; + } + + //Part is found, replace for param value + $regex = str_replace($block, $value, $regex); + + //Store replaced param + $replaced[] = $param; + } + else + { + //Only strip preceeding slash if it's not at the base + if($optional) { + $regex = str_replace($pre . $block, '', $regex); + } else { + $result = false; break; + } + } + } + } + } + + //Only update the route if it was build successfully + if($result !== false) + { + foreach($replaced as $param) { + unset($route->query[$param]); + } + + if(strpos($regex, '://') !== false) + { + $route-> path = ''; //Reset the path + $route->setUrl($regex); + } + else $route->setPath('/'.ltrim($regex, '/')); + } + + return $result; + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/dispatcher/router/resolver/state.php b/Sites/pages/components/com_pages/dispatcher/router/resolver/state.php new file mode 100644 index 00000000..f3405330 --- /dev/null +++ b/Sites/pages/components/com_pages/dispatcher/router/resolver/state.php @@ -0,0 +1,45 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +/** + * State Dispatcher Route Resolver + * + * @author Johan Janssens + * @package Koowa\Library\Dispatcher\Router\Resolver + */ +class ComPagesDispatcherRouterResolverState extends ComPagesDispatcherRouterResolverAbstract +{ + public function resolve(ComPagesDispatcherRouterRouteInterface $route) + { + //Remove any query parameters that are not states from the resolved route + if($page = $route->getPage()) + { + if($page->isCollection()) + { + $state = $this->getObject('model.factory') + ->createModel($page->path, $route->query) + ->getState(); + + $route->query = array_intersect_key($route->query, $state->toArray()); + } + else $route->query = $route->getParameters(); + } + } + + public function generate(ComPagesDispatcherRouterRouteInterface $route) + { + if($page = $route->getPage()) + { + //Remove any hardcoded states from the generated route + if(($collection = $page->isCollection()) && isset($collection['state'])) { + $route->query = array_diff_key($route->query, $collection['state']); + } + } + } +} diff --git a/Sites/pages/components/com_pages/dispatcher/router/route/abstract.php b/Sites/pages/components/com_pages/dispatcher/router/route/abstract.php new file mode 100644 index 00000000..2598b0a7 --- /dev/null +++ b/Sites/pages/components/com_pages/dispatcher/router/route/abstract.php @@ -0,0 +1,185 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +/** + * Abstract Router Route + * + * @author Johan Janssens + * @package Koowa\Library\Dispatcher\Router\Route + */ +abstract class ComPagesDispatcherRouterRouteAbstract extends KHttpUrl implements ComPagesDispatcherRouterRouteInterface +{ + /** + * The status + * + * Available entity status values are defined as STATUS_ constants + * + * @var integer + */ + protected $__status = null; + + + /** + * The route paramaters + * + * @var array + */ + protected $__parameters = array(); + + /** + * Constructor + * + * @param KObjectConfig $config An optional KObjectConfig object with configuration options + */ + public function __construct(KObjectConfig $config) + { + parent::__construct($config); + + //Set the url + $this->setQuery(KObjectConfig::unbox($config->query), true); + } + + /** + * Initializes the options for the object + * + * Called from {@link __construct()} as a first step of object instantiation + * + * @param KObjectConfig $config An optional KObjectConfig object with configuration options + * @return void + */ + protected function _initialize(KObjectConfig $config) + { + $config->append(array( + 'query' => array(), + )); + + parent::_initialize($config); + } + + /** + * Get a route parameter + * + * @param string $name The parameter name + * @param mixed $default The parameter default value + * @return mixed + */ + public function get($name, $default = null) + { + return $this->has($name) ? $this->query[$name] : $default; + } + + /** + * Check if a parameter exists + * + * @param string $name The parameter name + * @return bool + */ + public function has($name) + { + return isset($this->query[$name]); + } + + /** + * Set the route parameters + * + * @param array $parameters An associative array of route parameters + * @return $this + */ + public function setParameters($parameters) + { + $this->__parameters = $parameters; + + //Merge the parameters into the query + $this->setQuery($parameters, true); + + return $this; + } + + /** + * Get the route parameters + * + * @return array + */ + public function getParameters() + { + return $this->__parameters; + } + + /** + * Get the route state + * + * @return array + */ + public function getState() + { + return array(); + } + + /** + * Get the format + * + * @return string + */ + public function getFormat() + { + return pathinfo($this->getPath(), PATHINFO_EXTENSION); + } + + /** + * Mark the route as resolved + * + * @return ComPagesDispatcherRouterRouteInterface + */ + public function setResolved() + { + $this->__status = self::STATUS_RESOLVED; + return $this; + } + + /** + * Mark the route as generated + * + * @return ComPagesDispatcherRouterRouteInterface + */ + public function setGenerated() + { + $this->__status = self::STATUS_GENERATED; + return $this; + } + + /** + * Test if the route has been resolved + * + * @return bool + */ + public function isResolved() + { + return (bool) ($this->__status == self::STATUS_RESOLVED); + } + + /** + * Test if the route has been generated + * + * @return bool + */ + public function isGenerated() + { + return (bool) ($this->__status == self::STATUS_GENERATED); + } + + /** + * Test if the route is absolute + * + * @return bool + */ + public function isAbsolute() + { + return (bool) ($this->scheme && $this->host); + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/dispatcher/router/route/default.php b/Sites/pages/components/com_pages/dispatcher/router/route/default.php new file mode 100644 index 00000000..e9d88185 --- /dev/null +++ b/Sites/pages/components/com_pages/dispatcher/router/route/default.php @@ -0,0 +1,16 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +/** + * Default Router Route + * + * @author Johan Janssens + * @package Koowa\Library\Dispatcher\Router\Route + */ +final class ComPagesDispatcherRouterRouteDefault extends ComPagesDispatcherRouterRouteAbstract { } \ No newline at end of file diff --git a/Sites/pages/components/com_pages/dispatcher/router/route/interface.php b/Sites/pages/components/com_pages/dispatcher/router/route/interface.php new file mode 100644 index 00000000..30752215 --- /dev/null +++ b/Sites/pages/components/com_pages/dispatcher/router/route/interface.php @@ -0,0 +1,101 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +/** + * Dispatcher Router Route Interface + * + * @author Johan Janssens + * @package Koowa\Library\Dispatcher\Router\Route + */ +interface ComPagesDispatcherRouterRouteInterface extends KHttpUrlInterface +{ + const STATUS_RESOLVED = 1; + const STATUS_GENERATED = 2; + + /** + * Get a route parameter + * + * @param string $name The parameter name + * @param mixed $default The parameter default value + * @return mixed + */ + public function get($name, $default = null); + + /** + * Check if a route parameter exists + * + * @param string $name The parameter name + * @return bool + */ + public function has($name); + + /** + * Set the route parameters + * + * @param array $parameters An associative array of route parameters + * @return $this + */ + public function setParameters($parameters); + + /** + * Get the route parameters + * + * @return array + */ + public function getParameters(); + + /** + * Get the route state + * + * @return array + */ + public function getState(); + + /** + * Get the format + * + * @return string + */ + public function getFormat(); + + /** + * Mark the route as resolved + * + * @return ComPagesDispatcherRouterRouteInterface + */ + public function setResolved(); + + /** + * Mark the route as generated + * + * @return ComPagesDispatcherRouterRouteInterface + */ + public function setGenerated(); + + /** + * Test if the route has been resolved + * + * @return bool + */ + public function isResolved(); + + /** + * Test if the route has been generated + * + * @return bool + */ + public function isGenerated(); + + /** + * Test if the route is absolute + * + * @return bool + */ + public function isAbsolute(); +} diff --git a/Sites/pages/components/com_pages/dispatcher/router/route/page.php b/Sites/pages/components/com_pages/dispatcher/router/route/page.php new file mode 100644 index 00000000..a9746b33 --- /dev/null +++ b/Sites/pages/components/com_pages/dispatcher/router/route/page.php @@ -0,0 +1,62 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +/** + * Router Page Route + * + * @author Johan Janssens + * @package Koowa\Library\Dispatcher\Router\Route + */ +class ComPagesDispatcherRouterRoutePage extends ComPagesDispatcherRouterRouteAbstract +{ + protected $__page = null; + + public function getPage() + { + if(is_string($this->__page)) { + $this->__page = $this->getObject('page.registry')->getPageEntity($this->__page); + } + + return $this->__page; + } + + public function getState() + { + $state = array(); + + if($page = $this->getPage()) + { + if(($collection = $page->isCollection()) && isset($collection['state'])) { + $state = $collection['state']; + } + } + + return $state; + } + + public function setPath($path) + { + parent::setPath($path); + + //A resolved route can only receive a path to be resolved, do not change it + if(!$this->isResolved() && $this->getObject('page.registry')->isPage($path)) { + $this->__page = trim($this->getPath(), '/'); + } + } + + public function setGenerated() + { + parent::setGenerated(); + + //Remove any hardcoded states from the generated route + $this->query = array_diff_key($this->query, $this->getState()); + + return $this; + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/dispatcher/router/router.php b/Sites/pages/components/com_pages/dispatcher/router/router.php new file mode 100644 index 00000000..e52b8496 --- /dev/null +++ b/Sites/pages/components/com_pages/dispatcher/router/router.php @@ -0,0 +1,124 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +/** + * Dispatcher Router Singleton + * + * Force the router object to a singleton with identifier alias 'router'. + * + * @author Johan Janssens + * @package Koowa\Library\Dispatcher\Router + */ +class ComPagesDispatcherRouter extends ComPagesDispatcherRouterAbstract implements KObjectSingleton +{ + /** + * The routers + * + * @var array + */ + private $__routers; + + public function __construct(KObjectConfig $config) + { + parent::__construct($config); + + //Add a global object alias + $this->getObject('manager')->registerAlias($this->getIdentifier(), 'router'); + } + + /** + * Resolve a route + * + * Proxy to the specific component router + * + * @param string|ComPagesDispatcherRouterRouteInterface|KObjectInterface $route The route to resolve + * @param array $parameters Route parameters + * @return false| ComPagesDispatcherRouterInterface Returns the matched route or false if no match was found + */ + public function resolve($route, array $parameters = array()) + { + $result = false; + + //Find router package + if($route instanceof KObjectInterface) + { + if($route instanceof ComPagesDispatcherRouterRouteInterface) { + $package = $route->getScheme(); + } else { + $package = $route->getIdentifier()->getPackage(); + } + } + else + { + $parts = explode(':', $route); + $package = $parts[0]; + } + + //Get router instance + if(!isset($this->__routers[$package])) + { + $identifier = 'com://site/'.$package.'.dispatcher.router.'.$package; + + $config = [ + 'request' => $this->getRequest(), + 'resolvers' => $this->getResolvers() + ]; + + $router = $this->getObject($identifier, $config); + + $this->__routers[$package] = $router; + } + else $router = $this->__routers[$package]; + + return $router->resolve($route, $parameters); + } + + /** + * Generate a route + * + * Proxy to the specific component router + * + * @param string|ComPagesDispatcherRouterRouteInterface|KObjectInterface $route The route to resolve + * @param array $parameters Route parameters + * @return false|KHttpUrlInterface Returns the generated route + */ + public function generate($route, array $parameters = array()) + { + $result = false; + + //Find router package + if($route instanceof KObjectInterface) + { + if($route instanceof ComPagesDispatcherRouterRouteInterface) { + $package = $route->getScheme(); + } else { + $package = $route->getIdentifier()->getPackage(); + } + } + else $package = parse_url($route, PHP_URL_SCHEME); + + //Get router instance + if(!isset($this->__routers[$package])) + { + $identifier = 'com://site/'.$package.'.dispatcher.router.'.$package; + + $config = [ + 'request' => $this->getRequest(), + 'resolvers' => $this->getResolvers() + ]; + + $router = $this->getObject($identifier, $config); + + $this->__routers[$package] = $router; + } + else $router = $this->__routers[$package]; + + return $router->generate($route, $parameters); + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/dispatcher/router/site.php b/Sites/pages/components/com_pages/dispatcher/router/site.php new file mode 100644 index 00000000..d9ffe6c7 --- /dev/null +++ b/Sites/pages/components/com_pages/dispatcher/router/site.php @@ -0,0 +1,33 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesDispatcherRouterSite extends ComPagesDispatcherRouterAbstract +{ + protected function _initialize(KObjectConfig $config) + { + $config->append([ + 'routes' => [], + ])->append(([ + 'resolvers' => [ + 'regex' => ['routes' => $config->routes] + ] + ])); + + parent::_initialize($config); + } + + public function resolve($route = null, array $parameters = array()) + { + if(!$route) { + $route = trim($this->getRequest()->getUrl()->toString(KHttpUrl::HOST + KHttpUrl::PATH), '/'); + } + + return parent::resolve($route, $parameters); + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/event/subscriber/abstract.php b/Sites/pages/components/com_pages/event/subscriber/abstract.php new file mode 100644 index 00000000..068e4691 --- /dev/null +++ b/Sites/pages/components/com_pages/event/subscriber/abstract.php @@ -0,0 +1,14 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +abstract class ComPagesEventSubscriberAbstract extends KEventSubscriberAbstract +{ + +} + diff --git a/Sites/pages/components/com_pages/event/subscriber/bootstrapper.php b/Sites/pages/components/com_pages/event/subscriber/bootstrapper.php new file mode 100644 index 00000000..17d92e48 --- /dev/null +++ b/Sites/pages/components/com_pages/event/subscriber/bootstrapper.php @@ -0,0 +1,182 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesEventSubscriberBootstrapper extends ComPagesEventSubscriberAbstract +{ + protected function _initialize(KObjectConfig $config) + { + $config->append(array( + 'priority' => KEvent::PRIORITY_HIGH + )); + + parent::_initialize($config); + } + + public function onAfterKoowaBootstrap(KEventInterface $event) + { + $request = $this->getObject('request'); + $router = $this->getObject('com://site/pages.dispatcher.router.site', ['request' => $request]); + + if(false !== $route = $router->resolve()) + { + define('PAGES_SITE_ROOT', $route->getPath()); + + //Set PAGES_PATH based on Joomla configuration + if(JFactory::getApplication()->getCfg('sef_rewrite')) { + $_SERVER['PAGES_PATH'] = JFactory::getApplication()->getCfg('live_site') ?? '/'; + } + + //Set the site path in the config + $config = $this->getObject('com://site/pages.config', ['site_path' => $route->getPath()]); + + //Get the config options + $options = $config->getOptions(); + + //Bootstrap the site configuration (before extensions to allow overriding) + $this->_bootstrapSite($config->getSitePath(), $options); + + //Bootstrap the extensions + $this->_bootstrapExtensions($config->getSitePath('extensions'), $options); + + } + else $this->getObject('com://site/pages.config', ['site_path' => false]); + } + + public function onBeforeDispatcherDispatch(KEventInterface $event) + { + $config = $this->getObject('com://site/pages.config')->getOptions(); + + //Configure the Joomla template + if(isset($config['template']) || isset($config['template_config'])) + { + if(isset($config['template'])) { + $template = $config['template']; + } else { + $template = JFactory::getApplication()->getTemplate(); + } + + if(isset($config['template_config']) && is_array($config['template_config'])) + { + $params = JFactory::getApplication()->getTemplate(true)->params; + + foreach($config['template_config'] as $name => $value) { + $params->set($name, $value); + } + } + + JFactory::getApplication()->setTemplate($template, $params); + } + } + + protected function _bootstrapSite($path, $config = array()) + { + //Load config options + $directory = $this->getObject('object.bootstrapper')->getComponentPath('pages'); + + //Include autoloader + include $directory.'/resources/vendor/autoload.php'; + + //Set config options + $options = include $directory.'/resources/config/site.php'; + + //Set config options + foreach($options['identifiers'] as $identifier => $values) { + $this->getConfig($identifier)->append($values); + } + + //Set config options + foreach($options['extensions'] as $identifier => $values) { + $this->getConfig($identifier)->append($values); + } + } + + protected function _bootstrapExtensions($path, $config = array()) + { + //Register 'ext:[package]' locations + if($directories = glob($path.'/*', GLOB_ONLYDIR)) + { + //Register 'ext' fallback location + $locator = new ComPagesClassLocatorExtension(); + + //Register the extension locator + $this->getObject('manager')->getClassLoader()->registerLocator($locator); + $this->getObject('manager')->registerLocator('com://site/pages.object.locator.extension'); + + $filters = array(); + $functions = array(); + + foreach ($directories as $directory) + { + //The extension name + $name = strtolower(basename($directory)); + + //Register the extension namespace + $locator->registerNamespace(ucfirst($name), $directory); + + //Register event subscribers + foreach (glob($directory.'/subscriber/[!_]*.php') as $filename) + { + $this->getObject('event.subscriber.factory') + ->registerSubscriber('ext:'.$name.'.subscriber.'.basename($filename, '.php')); + } + + //Find template functions + foreach (glob($directory.'/template/function/[!_]*.php') as $filename) { + $functions[basename($filename, '.php')] = $filename; + } + + //Include autoloader + if(file_exists($directory.'/resources/vendor/autoload.php')) { + include $directory.'/resources/vendor/autoload.php'; + } + + //Set config options + if(file_exists($directory.'/config.php')) + { + $identifiers = include $directory.'/config.php'; + + if(is_array($identifiers)) + { + foreach($identifiers as $identifier => $values) { + $this->getConfig($identifier)->append($values); + } + } + } + } + + //Register template functions + if($functions) { + $this->getConfig('com://site/pages.template.default')->merge(['functions' => $functions]); + } + } + + //Register 'ext:pages' aliases + if(file_exists($path.'/pages')) + { + $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path.'/pages')); + + foreach($iterator as $file) + { + if ($file->isFile() && $file->getExtension() == 'php' && $file->getFileName() !== 'config.php') + { + $segments = explode('/', $iterator->getSubPathName()); + $segments[] = basename(array_pop($segments), '.php'); + + //Create the identifier path + file + $path = implode('.', $segments); + + $this->getObject('manager')->registerAlias( + 'ext:pages.'.$path, + 'com://site/pages.'.$path + ); + } + } + } + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/event/subscriber/dispatcher.php b/Sites/pages/components/com_pages/event/subscriber/dispatcher.php new file mode 100644 index 00000000..7bd8e27d --- /dev/null +++ b/Sites/pages/components/com_pages/event/subscriber/dispatcher.php @@ -0,0 +1,262 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesEventSubscriberDispatcher extends ComPagesEventSubscriberAbstract +{ + use ComKoowaEventTrait; + + protected function _initialize(KObjectConfig $config) + { + $config->append(array( + 'priority' => KEvent::PRIORITY_HIGH + )); + + parent::_initialize($config); + } + + public function onAfterKoowaBootstrap() + { + $this->attachEventHandler('onAfterModuleList', 'filterTemplateModules'); + } + + public function isEnabled() + { + $result = parent::isEnabled(); + + //Disable dispatcher if directly routing to a component + if(isset($_REQUEST['option']) && substr($_REQUEST['option'], 0, 4) == 'com_') { + $result = false; + } + + return $result; + } + + public function onAfterApplicationInitialise(KEventInterface $event) + { + $dispatcher = $this->getObject('com://site/pages.dispatcher.http'); + $application = JFactory::getApplication(); + + //Turn off sh404sef for com_pages + if(JComponentHelper::isEnabled('com_sh404sef')) + { + //Tun route parsing + $application->getRouter()->attachParseRule(function($router, $url) use ($dispatcher) + { + if(class_exists('Sh404sefClassRouterInternal')) + { + if($dispatcher->getRoute()) + { + $page = $dispatcher->getPage(); + + if($page->path && !$page->isDecorator()) { + Sh404sefClassRouterInternal::$parsedWithJoomlaRouter = true; + } + } + } + + }, JRouter::PROCESS_BEFORE); + + //Tun off route building + $application->getRouter()->attachBuildRule(function($router, $url) use ($dispatcher) + { + if(class_exists('Sh404sefFactory')) { + Sh404sefFactory::getConfig()->useJoomlaRouter[] = 'pages'; + } + + }, JRouter::PROCESS_BEFORE); + } + + //Authenticate anonymous requests and inject form token dynamically + if($dispatcher->getRequest()->isPost() && $dispatcher->isCacheable()) + { + if($cache = $dispatcher->loadCache()) + { + if($application->input->request->get($cache['token'])) { + $application->input->post->set(JSession::getFormToken(), '1'); + } + } + } + } + + public function onAfterApplicationRoute(KEventInterface $event) + { + $dispatcher = $this->getObject('com://site/pages.dispatcher.http'); + + //Get the page + if($dispatcher->getRoute()) + { + $page = $dispatcher->getPage(); + $menu = JFactory::getApplication()->getMenu()->getActive(); + + if($this->getObject('request')->isSafe()) + { + /** + * Route safe requests to pages under the following conditions: + * + * - Joomla fell back to the default menu item because the page route couldn't be resolved + * - The Joomla menu item isn't being decorated + */ + + if($menu && $menu->home && !empty($page->path)) { + $event->getTarget()->input->set('option', 'com_pages'); + } elseif(!$page->isDecorator()) { + $event->getTarget()->input->set('option', 'com_pages'); + } + } + else + { + /** + * Route none-safe requests to pages under the following conditions: + * + * - Page is a form + * - Joomla fell back to the default menu item because the page route couldn't be resolved + */ + if($page->isForm() || ($menu && $menu->home && !empty($page->path))) { + $event->getTarget()->input->set('option', 'com_pages'); + } + } + + /* + * Configure the template + * + * - Set a specific template by name + * - Set the template parameters + */ + if($page->process->has('template')) + { + if($page->process->template->has('name')) { + $template = $page->process->template->name; + } else { + $template = JFactory::getApplication()->getTemplate(); + } + + $params = JFactory::getApplication()->getTemplate(true)->params; + + if($page->process->template->has('config')) + { + foreach($page->process->template->config as $name => $value) { + $params->set($name, $value); + } + } + + JFactory::getApplication()->setTemplate($template, $params); + } + } + else + { + //Purge the cache if it exists + if($dispatcher->isCacheable() && $dispatcher->loadCache()) + { + $dispatcher->purge(); + + //Manually set the cache status + JFactory::getApplication()->setHeader('Cache-Status', 'DYNAMIC, PURGED'); + } + } + } + + public function onAfterApplicationRender(KEventInterface $event) + { + if(!headers_sent()) + { + header_register_callback( function() { + header_remove('Expires'); + }); + } + } + + public function onAfterApplicationRespond(KEventInterface $event) + { + $dispatcher = $this->getObject('com://site/pages.dispatcher.http'); + + //Cache and cleanup Joomla output if routing to a page + if($dispatcher->getRoute()) + { + $headers = array(); + foreach (headers_list() as $header) + { + $parts = explode(':', $header, 2); + $headers[trim($parts[0])] = trim($parts[1]); + } + + //Remove the Expires header + unset($headers['Expires']); + + //Do not cache if Joomla is running in debug mode + if(!JDEBUG && $dispatcher->isCacheable() && $dispatcher->isDecorated()) + { + $content = $event->getTarget()->getBody(); + + //Replace the session based form and csrf token with a fixed token + $token = $dispatcher->getCacheToken(); + + $search = '##'; + $replacement = ''; + + $content = preg_replace($search, $replacement, $content); + + //Search for a csrf token in the content and refresh it + $search = '#"csrf.token": "[0-9a-f]{32}"#'; + $replacement = '"csrf.token": "' . $token . '"'; + + $content = preg_replace($search, $replacement, $content); + + $dispatcher->getResponse()->setHeaders($headers); + $dispatcher->getResponse()->setContent($content); + + $dispatcher->cache(); + } + } + } + + public function filterTemplateModules(&$modules) + { + $dispatcher = $this->getObject('com://site/pages.dispatcher.http'); + + if($dispatcher->getRoute()) + { + $page = $dispatcher->getPage(); + + if($page->has('process/template/modules')) + { + if(count($page->get('process/template/modules'))) + { + foreach ($page->get('process/template/modules') as $key => $module) + { + $include = array(); + $exclude = array(); + + foreach ($page->process->template->get('modules') as $id) + { + if ($id[0] == '-' || $id < 0) { + $exclude[] = substr($id, 1); + } else { + $include[] = $id; + } + } + + if ($include) + { + if (!in_array($module->title, $include) && !in_array($module->id, $include)) { + unset($modules[$key]); + } + } + else + { + if (in_array($module->title, $exclude) || in_array($module->id, $exclude)) { + unset($modules[$key]); + } + } + } + } + else $modules = array(); + } + } + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/event/subscriber/exception.php b/Sites/pages/components/com_pages/event/subscriber/exception.php new file mode 100644 index 00000000..9e6aa69d --- /dev/null +++ b/Sites/pages/components/com_pages/event/subscriber/exception.php @@ -0,0 +1,77 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesEventSubscriberException extends ComPagesEventSubscriberAbstract +{ + public function isEnabled() + { + $result = parent::isEnabled(); + + //Disable error handler if directly routing to a component + if(isset($_REQUEST['option']) && substr($_REQUEST['option'], 0, 4) == 'com_') { + $result = false; + } + + return $result; + } + + public function onAfterKoowaBootstrap(KEventInterface $event) + { + //Catch all Joomla exceptions + if(!defined('JOOMLATOOLS_PLATFORM')) { + JError::setErrorHandling(E_ERROR, 'callback', array($this, 'handleException')); + } + } + + public function onException(KEvent $event) + { + $dispatcher = $this->getObject('com://site/pages.dispatcher.http'); + $exception = $event->exception; + + //Purge cache + if($exception->getCode() == KHttpResponse::NOT_FOUND) + { + if($dispatcher->isCacheable()) { + $dispatcher->purge(); + } + } + + if(!JDEBUG && $this->getObject('request')->getFormat() == 'html') + { + //If the error code does not correspond to a status message, use 500 + $code = $exception->getCode(); + if(!isset(KHttpResponse::$status_messages[$code])) { + $code = '500'; + } + + foreach([(int) $code, '500'] as $code) + { + if($page = $dispatcher->getPage($code)) + { + $dispatcher->getPage()->setProperties($page); + + //Set status code (before rendering the error) + $dispatcher->getResponse()->setStatus($code); + + //Render the error + $content = $dispatcher->getController()->render($exception); + + //Set error in the response + $dispatcher->getResponse()->setContent($content); + $dispatcher->send(); + } + } + } + } + + public function handleException(\Exception $exception) + { + $this->getObject('exception.handler')->handleException($exception); + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/event/subscriber/pagedecorator.php b/Sites/pages/components/com_pages/event/subscriber/pagedecorator.php new file mode 100644 index 00000000..b4e87d73 --- /dev/null +++ b/Sites/pages/components/com_pages/event/subscriber/pagedecorator.php @@ -0,0 +1,108 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesEventSubscriberPagedecorator extends ComPagesEventSubscriberAbstract +{ + protected $_dispatcher; + + protected function _initialize(KObjectConfig $config) + { + $config->append(array( + 'priority' => KEvent::PRIORITY_HIGH + )); + + parent::_initialize($config); + } + + public function onAfterApplicationRoute(KEventInterface $event) + { + //Try to validate the cache + if($dispatcher = $this->getDispatcher()) + { + if($dispatcher->isCacheable()) { + $dispatcher->validate(); + } + } + } + + public function onAfterApplicationDispatch(KEventInterface $event) + { + if($dispatcher = $this->getDispatcher()) + { + $buffer = JFactory::getDocument()->getBuffer('component'); + + ob_start(); + + $dispatcher->getResponse()->setContent(''); + $dispatcher->dispatch(); + + $result = ob_get_clean(); + + //Replace the component placeholder + $result = str_replace('', $buffer, $result); + + JFactory::getDocument()->setBuffer($result, 'component'); + } + } + + public function getDispatcher() + { + $menu = JFactory::getApplication()->getMenu()->getActive(); + + $component = $menu ? $menu->component : ''; + $menu_route = $menu ? $menu->route : ''; + + //Only decorate GET requests that are not routing to com_pages + if(is_null($this->_dispatcher) && $this->getObject('request')->isGet() && $component != 'com_pages') + { + $page_route = $route = $this->getObject('com://site/pages.dispatcher.http')->getRoute(); + + if($page_route) + { + $this->_dispatcher = false; + $page_route = $page_route->getPath(false); + + $base = trim(dirname($menu_route), '.'); + $route = trim(str_replace($base, '', $page_route), '/'); + + $page = $base ? $base.'/'.$route : $route; + + $level = 0; + while($page && !$this->getObject('page.registry')->isPage($page)) + { + if($route = trim(dirname($route), '.')) + { + $page = $base ? $base.'/'.$route : $route; + $level++; + } + else $page = false; + } + + if($page !== false) + { + $decorate = $this->getObject('page.registry') + ->getPage($page) + ->process->get('decorate', false); + + if($decorate === true || (is_int($decorate) && ($decorate >= $level))) + { + $dispatcher = $this->getObject('com://site/pages.dispatcher.http', ['controller' => 'decorator']); + + $dispatcher->getResponse()->getHeaders()->set('Content-Location', clone $dispatcher->getRequest()->getUrl()); + $dispatcher->getRequest()->getUrl()->setPath('/'.$page); + + $this->_dispatcher = $dispatcher; + } + } + } + } + + return $this->_dispatcher; + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/event/subscriber/prefetcher.php b/Sites/pages/components/com_pages/event/subscriber/prefetcher.php new file mode 100644 index 00000000..9947b20f --- /dev/null +++ b/Sites/pages/components/com_pages/event/subscriber/prefetcher.php @@ -0,0 +1,53 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesEventSubscriberPrefetcher extends ComPagesEventSubscriberAbstract +{ + protected function _initialize(KObjectConfig $config) + { + $config->append(array( + 'options' => [ + 'selector' => 'a.prefetch', + 'onload' => true, + 'onhover' => true, + 'debug' => JDEBUG + ], + )); + + parent::_initialize($config); + } + + public function onBeforeDispatcherSend(KEventInterface $event) + { + $content = $event->getTarget()->getResponse()->getContent(); + + if($event->getTarget()->getRequest()->getFormat() == 'html' && $event->getTarget()->isCacheable(true)) + { + $page = $event->getTarget()->getPage(); + $prefetch = $page->get('process/prefetch', $this->getObject('com://site/pages.config')->get('http_static_cache', false)); + + if($prefetch !== false) + { + $template = $event->getTarget()->getController()->getView()->getTemplate(); + + if(is_scalar($prefetch)) + { + $config = $this->getConfig()->options; + $config->selector = is_string($prefetch) ? $prefetch : 'a.prefetch'; + } + else $config = $prefetch->append($this->getConfig()->options); + + $prefetcher = $template->helper('behavior.prefetcher', $config); + $template->getFilter('asset')->filter($prefetcher); + + $event->getTarget()->getResponse()->setContent($content.$prefetcher); + } + } + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/event/subscriber/staticcache.php b/Sites/pages/components/com_pages/event/subscriber/staticcache.php new file mode 100644 index 00000000..f2719931 --- /dev/null +++ b/Sites/pages/components/com_pages/event/subscriber/staticcache.php @@ -0,0 +1,116 @@ +append(array( + 'enabled' => false, + 'cache_path' => false, + )); + + parent::_initialize($config); + } + + public function onAfterDispatcherCache(KEventInterface $event) + { + $dispatcher = $event->getTarget(); + $response = $dispatcher->getResponse(); + + //Only cache static pages without a query string + if($event->result && !$dispatcher->getContentLocation()->getQuery() && $this->getConfig()->cache_path) + { + $file = $this->getFilePath($dispatcher); + $dir = dirname($file); + + //Only cache statically if must not revalidate + if($file && !in_array('must-revalidate', $response->getCacheControl())) + { + // Cache needs to be regenerated OR cache doesn't exist yet + $regenerate = !$dispatcher->isIdentical() || !file_exists($file); + + //Re-generated the static cache + if($regenerate && $content = $response->getContent()) + { + if(!is_dir($dir) && (false === @mkdir($dir, 0777, true))) { + throw new RuntimeException(sprintf('The cache path "%s" does not exist', $dir)); + } + + if(!is_writable($dir)) { + throw new RuntimeException(sprintf('The cache path "%s" is not writable', $dir)); + } + + if(@file_put_contents($file, $content) === false) { + throw new RuntimeException(sprintf('The file cannot be cached in "%s"', $file)); + } + + //Override default permissions for cache files + @chmod($file, 0666 & ~umask()); + } + } + else + { + //Purge the static cache + if(file_exists($file)) + { + unlink($file); + + //Delete the folder if its empty + $dir = dirname($file); + if(!(new \FilesystemIterator($dir))->valid()) { + rmdir($dir); + } + } + } + } + } + + public function onAfterDispatcherPurge(KEventInterface $event) + { + $file = $this->getFilePath($event->getTarget()); + + //Purge the static cache + if(file_exists($file)) + { + unlink($file); + + //Delete the folder if its empty + $dir = dirname($file); + if(!(new \FilesystemIterator($dir))->valid()) { + rmdir($dir); + } + } + } + + public function getCachePath() + { + return $this->getConfig()->cache_path; + } + + public function getFilePath(ComPagesDispatcherHttp $dispatcher) + { + $path = $dispatcher->getContentLocation()->getPath(true); + $filename = array_pop($path); + $format = pathinfo($filename, PATHINFO_EXTENSION); + + //Create the filename + if(empty($filename)) { + $filename = 'index'; + } + + if(empty($format)) { + $filename .= '.'. $dispatcher->getRequest()->getFormat(); + } + + //Create the directory + if($dir = trim(implode('/', $path), '/')) { + $dir = $this->getCachePath().'/'.$dir; + } else { + $dir = $this->getCachePath(); + } + + $file = $dir.'/'.$filename; + + return $file; + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/http/cache.php b/Sites/pages/components/com_pages/http/cache.php new file mode 100644 index 00000000..02519c88 --- /dev/null +++ b/Sites/pages/components/com_pages/http/cache.php @@ -0,0 +1,214 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +/** + * Http Resource Cache + * + * This class implement a simple http resource cache + * + * @author Johan Janssens + */ +class ComPagesHttpCache extends KHttpClient +{ + protected function _initialize(KObjectConfig $config) + { + $config->append([ + 'cache' => false, + 'cache_path' => $this->getObject('com://site/pages.config')->getSitePath('cache'), + 'debug' => JDEBUG ? true : false, + + ]); + + parent::_initialize($config); + } + + public function send(KHttpRequestInterface $request) + { + //Send the request + if($this->isCacheable($request)) + { + $valid = false; + $url = $request->getUrl(); + + //Load cache + if($cache = $this->loadCache($url)) + { + $cache = $this->getObject('http.response') + ->setStatus($cache['status']) + ->setHeaders($cache['headers']) + ->setContent($cache['content']); + + //Check if cache is valid + $valid = $this->isValid($request, $cache); + + //Cache Validation + //See: https://tools.ietf.org/html/rfc7234#section-4.3 + if(!$valid && $cache->isValidateable()) + { + if($cache->getHeaders()->has('ETag')) { + $request->getHeaders()->set('If-None-Match', $cache->getHeaders()->get('ETag')); + } + + if($cache->getHeaders()->has('Last-Modified')) { + $request->getHeaders()->set('If-Modified-Since', $cache->getHeaders()->get('Last-Modified')); + } + } + } + + //Revalidate the cache + if(!$valid) + { + $response = parent::send($request); + + if($cache && ($response->isError() || $response->isNotModified())) + { + $response = $cache; + + //Refresh the cache + $response->setDate(new DateTime('now')); + } + + //Store response + if($request->isGet()) + { + $this->storeCache($url, [ + 'url' => rtrim((string) $url, '/'), + 'status' => $response->getStatusCode(), + 'format' => $response->getFormat(), + 'headers' => $response->getHeaders()->toArray(), + 'content' => $response->getContent() + ]); + } + } + else $response = $cache; + } + else + { + $response = parent::send($request); + + //Cache Invalidation + //See: https://tools.ietf.org/html/rfc7234#section-4.4 + if(!$request->isSafe() && !$response->isError()) { + $this->deleteCache($request->getUrl()); + } + } + + return $response; + } + + public function locateCache($url) + { + $key = crc32((string)$url); + $file = $this->getConfig()->cache_path.'/resource_'.$key.'.php'; + + return $file; + } + + public function loadCache($url) + { + if($this->getConfig()->cache) + { + $file = $this->locateCache($url); + if (is_file($file)) + { + if (!$data = include($file)) { + unlink($file); + } + } + } + + return $data ?? array(); + } + + public function storeCache($url, $data) + { + if($this->getConfig()->cache) + { + $path = $this->getConfig()->cache_path; + + if(!is_dir($path) && (false === @mkdir($path, 0777, true) && !is_dir($path))) { + throw new RuntimeException(sprintf('The resource cache path "%s" does not exist', $path)); + } + + if(!is_writable($path)) { + throw new RuntimeException(sprintf('The resource cache path "%s" is not writable', $path)); + } + + if(!is_string($data)) + { + //Do not cache userinfo + $location = KHttpUrl::fromString($url)->toString(KHttpUrl::FULL ^ KHttpUrl::USERINFO); + + $result = 'locateCache($url); + + if(@file_put_contents($file, $result) === false) { + throw new RuntimeException(sprintf('The url cannot be cached in "%s"', $file)); + } + + //Override default permissions for cache files + @chmod($file, 0666 & ~umask()); + + return $file; + } + + return false; + } + + public function deleteCache($url) + { + $result = false; + + $file = $this->locateCache($url); + + if (is_file($file)) { + $result = unlink($file); + } + + return $result; + } + + public function isCacheable(KHttpRequestInterface $request) + { + return $this->getConfig()->cache && $request->isCacheable(); + } + + public function isValid(KHttpRequestInterface $request, KHttpResponseInterface $response) + { + if($this->isStale($request, $response) || in_array('no-cache', $request->getCacheControl())) { + $valid = false; + } else { + $valid = true; + } + + return $valid; + } + + public function isStale(KHttpRequestInterface $request, KHttpResponseInterface $response) + { + $stale = false; + $cache_control = $request->getCacheControl(); + + if(isset($cache_control['max-age'])) + { + $max_age = (int) $cache_control['max-age']; + $stale = ($max_age - $response->getAge()) <= 0; + } + + return $stale; + } + + public function isDebug() + { + return (bool) $this->getConfig()->debug; + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/model/behavior/filterable.php b/Sites/pages/components/com_pages/model/behavior/filterable.php new file mode 100644 index 00000000..c0e5c243 --- /dev/null +++ b/Sites/pages/components/com_pages/model/behavior/filterable.php @@ -0,0 +1,289 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesModelBehaviorFilterable extends ComPagesModelBehaviorQueryable +{ + protected $_filters; + + public function onMixin(KObjectMixable $mixer) + { + parent::onMixin($mixer); + + $mixer->getState() + ->insert('filter', 'string'); + } + + protected function _beforeFetch(KModelContextInterface $context) + { + if($filters = $context->state->filter) + { + if(!is_array($filters)) + { + if($matches = preg_split('#\b(and|or)\b#', $filters, null, PREG_SPLIT_DELIM_CAPTURE)) + { + array_unshift($matches, 'and'); + $matches = array_chunk($matches, 2); + + foreach($matches as $match) + { + $combination = strtoupper($match[0]); + $expression = $match[1]; + + if($filter = preg_split('#^(\w+)\s+([eq|neq|gt|gte|lt|lte|in|nin]+)\s+(.+)\s*$#i', trim($expression), null, PREG_SPLIT_DELIM_CAPTURE)) + { + $attribute = $filter[1]; + $operation = $filter[2]; + $values = $filter[3]; + + $this->_filters[] = [ + 'attribute' => $attribute, + 'operation' => $operation, + 'values' => array_unique(explode(',', $values)), + 'combination' => $combination + ]; + } + } + } + } + else + { + foreach ($filters as $attribute => $values) + { + //Multiple constraints on the same attribute + foreach((array) $values as $key => $v) + { + //With one level nesting + foreach((array) $v as $value) + { + // Parse filter value for possible operator + if (preg_match('#^([eq|neq|gt|gte|lt|lte|in|nin]+):(.+)\s*$#i', $value, $matches)) + { + $this->_filters[] = [ + 'attribute' => $attribute, + 'key' => !is_numeric($key) ? $key : null, + 'operation' => $matches[1], + 'values' => array_unique(explode(',', $matches[2])), + 'combination' => 'AND' + ]; + } + else + { + $this->_filters[] = [ + 'attribute' => $attribute, + 'key' => !is_numeric($key) ? $key : null, + 'operation' => 'eq', + 'values' => array_unique(explode(',', $value)), + 'combination' => 'AND' + ]; + } + } + } + } + } + + if($this->_filters) { + return parent::_beforeFetch($context); + } + } + } + + protected function _queryArray(array $data, KModelStateInterface $state) + { + $result = array(); + $items = $data; + + foreach($this->_filters as $filter) + { + $filtered = array_filter($items, function ($item) use ($filter) + { + $attribute = $filter['attribute']; + + if(isset($item[$attribute])) + { + $item_value = $item[$attribute]; + + //Handle one dimensional assiociate array values + if(isset($filter['key'])) + { + $key = $filter['key']; + + if(isset($item_value[$key])) { + $item_value = $item_value[$key]; + } else { + $item_value = null; + } + } + } + else $item_value = null; + + foreach ((array)$filter['values'] as $value) + { + if(strtotime($value) && strtotime($item_value)) + { + $value = strtotime($value); + $item_value = strtotime($item_value); + } + + //Convert boolean strings + if(strtolower($value) == 'false') { + $value = false; + } + + if(strtolower($value) == 'true') { + $value = true; + } + + //Equal + if ($filter['operation'] == 'eq') + { + if (strtolower($value) == "null" || is_null($value)) + { + if (is_null($item_value)) { + return true; + } + } + else + { + if ($item_value == $value) { + return true; + } + } + } //Not Equal + elseif ($filter['operation'] == 'neq') + { + if (strtolower($value) == "null" || is_null($value)) + { + if (!is_null($item_value)) { + return true; + } + } + else + { + if($item_value != $value) { + return true; + } + } + } + //Greater Than + elseif ($filter['operation'] == 'gt' && $item_value > $value) { + return true; + } + //Greater Or Equal To + elseif ($filter['operation'] == 'gte' && $item_value >= $value) { + return true; + } + //Less Then + elseif ($filter['operation'] == 'lt' && $item_value < $value) { + return true; + } + //Less Or Equal To + elseif ($filter['operation'] == 'lte' && $item_value <= $value) { + return true; + } + //In + elseif ($filter['operation'] == 'in') + { + if(is_array($item_value) && in_array($value, $item_value)) { + return true; + } + } + //Not In + elseif ($filter['operation'] == 'nin') + { + if(!is_array($item_value) || !in_array($value, $item_value)) { + return true; + }; + } + } + }); + + if($filter['combination'] == 'AND') + { + $items = $filtered; + $result = $filtered; + } + + if($filter['combination'] == 'OR') + { + $items = $data; + $result = $result + $filtered; + } + } + + return $result; + } + + protected function _queryDatabase(KDatabaseQuerySelect $query, KModelStateInterface $state) + { + $table = $this->getTable(); + foreach ($this->_filters as $filter) + { + if (isset($filter['values'])) + { + $combination = $filter['combination']; + $column = $table->mapColumns($filter['attribute']); + + foreach ((array)$filter['values'] as $key => $value) + { + $parameter = $column . $key; + + //Equal + if ($filter['operation'] == 'eq') + { + if (strtolower($value) == "null" || is_null($value)) { + $expression = 'tbl.' . $column . ' IS NULL'; + } else { + $expression = 'tbl.' . $column . ' = :' . $parameter; + } + } //Not Equal + elseif ($filter['operation'] == 'neq') + { + if (strtolower($value) == "null" || is_null($value)) { + $expression = 'tbl.' . $column . ' IS NOT NULL'; + } else { + $expression = 'tbl.' . $column . ' != :' . $parameter; + } + } //Greater Than + elseif ($filter['operation'] == 'gt') { + $expression = 'tbl.' . $column . ' > :' . $parameter; + } //Greater Or Equal To + elseif ($filter['operation'] == 'gte') { + $expression = 'tbl.' . $column . ' >= :' . $parameter; + } //Less Then + elseif ($filter['operation'] == 'lt') { + $expression = 'tbl.' . $column . ' < :' . $parameter; + } //Less Or Equal To + elseif ($filter['operation'] == 'lte') { + $expression = 'tbl.' . $column . ' <= :' . $parameter; + } + //In + elseif ($filter['operation'] == 'in') { + continue; //not supported for now + } + //Not In + elseif ($filter['operation'] == 'nin') { + continue; //not supported for now + } + + //Convert to date if value is + if(strtotime($value)) { + $value = gmdate('Y-m-d H:i:s', strtotime($value)); + } + + $query->where($expression, $combination)->bind(array($parameter => $value)); + + //Multiple values for the same filter are OR + $combination = 'OR'; + } + } + } + + return $query; + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/model/behavior/paginatable.php b/Sites/pages/components/com_pages/model/behavior/paginatable.php new file mode 100644 index 00000000..45881fc0 --- /dev/null +++ b/Sites/pages/components/com_pages/model/behavior/paginatable.php @@ -0,0 +1,104 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesModelBehaviorPaginatable extends ComPagesModelBehaviorQueryable +{ + protected function _initialize(KObjectConfig $config) + { + $config->append([ + 'priority' => self::PRIORITY_LOW, + 'filter' => false, + ]); + + parent::_initialize($config); + } + + public function onMixin(KObjectMixable $mixer) + { + parent::onMixin($mixer); + + $mixer->getState() + ->insert('limit', 'int') + ->insert('offset', 'int') + ->insert('total', 'int'); + + } + + public function isPaginatable() + { + return !$this->isAtomic(); + } + + public function getPaginator() + { + $paginator = new KModelPaginator(array( + 'offset' => (int)$this->getState()->offset, + 'limit' => (int)$this->getState()->limit, + 'total' => (int)$this->getState()->total, + )); + + return $paginator; + } + + protected function _beforeFetch(KModelContextInterface $context) + { + $state = $context->state; + + if(is_null($state->total) || $state->total > $this->count()) { + $state->total = $this->count(); + } + + if ($state->limit) + { + $limit = $state->limit; + $offset = $state->offset; + $total = $state->total; + + if ($offset !== 0 && $total !== 0) + { + // Recalculate the offset if it is set to the middle of a page. + if ($offset % $limit !== 0) { + $offset -= ($offset % $limit); + } + + // Recalculate the offset if it is higher than the total + if ($offset >= $total) { + $offset = floor(($total - 1) / $limit) * $limit; + } + + $state->offset = $offset; + } + + return parent::_beforeFetch($context); + } + } + + protected function _afterReset(KModelContextInterface $context) + { + $modified = (array) KObjectConfig::unbox($context->modified); + if (in_array('limit', $modified)) + { + $limit = $context->state->limit; + + if ($limit) { + $context->state->offset = floor($context->state->offset / $limit) * $limit; + } + } + } + + protected function _queryArray(array $data, KModelStateInterface $state) + { + return array_slice($data, $state->offset, $state->limit); + } + + protected function _queryDatabase(KDatabaseQuerySelect $query, KModelStateInterface $state) + { + return $query->limit($state->limit, $state->offset); + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/model/behavior/queryable.php b/Sites/pages/components/com_pages/model/behavior/queryable.php new file mode 100644 index 00000000..04ee7838 --- /dev/null +++ b/Sites/pages/components/com_pages/model/behavior/queryable.php @@ -0,0 +1,57 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +abstract class ComPagesModelBehaviorQueryable extends KModelBehaviorAbstract +{ + protected function _initialize(KObjectConfig $config) + { + $config->append(array( + 'filter' => true + )); + + parent::_initialize($config); + } + + protected function _beforeFetch(KModelContextInterface $context) + { + $state = $context->state; + + if(!$state->isUnique() && $context instanceof ComPagesModelContextCollection) + { + if(is_array($context->data)) { + $context->data = $this->_queryArray($context->data, $state); + } + + if($context->data instanceof KDatabaseQuerySelect) { + $context->data = $this->_queryDatabase($context->data, $state); + } + } + } + + protected function _beforeCount(KModelContextInterface $context) + { + if($this->getConfig()->filter) { + $result = $this->_beforeFetch($context); + } else { + $result = $context->data; + } + + return $result; + } + + protected function _queryArray(array $data, KModelStateInterface $state) + { + return $data; + } + + protected function _queryDatabase(KDatabaseQuerySelect $query, KModelStateInterface $state) + { + return $query; + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/model/behavior/recursable.php b/Sites/pages/components/com_pages/model/behavior/recursable.php new file mode 100644 index 00000000..8a3da168 --- /dev/null +++ b/Sites/pages/components/com_pages/model/behavior/recursable.php @@ -0,0 +1,93 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesModelBehaviorRecursable extends KModelBehaviorAbstract +{ + private $__children = array(); + + protected function _initialize(KObjectConfig $config) + { + $config->append([ + 'priority' => self::PRIORITY_HIGH, + 'key' => null, + ]); + + parent::_initialize($config); + } + + public function hasChildren() + { + $result = false; + $parent = $this->getMixer()->getHandle(); + + if(isset($this->__children[$parent])) { + $result = (boolean) count($this->__children[$parent]); + } + + return $result; + } + + public function getChildren() + { + $result = array(); + + if($this->hasChildren()) + { + $parent = $this->getMixer()->getHandle(); + $result = $this->__children[$parent]; + } + + return $result; + } + + public function getMixableMethods($exclude = array()) + { + $methods = array(); + if($this->getMixer() instanceof KModelEntityInterface) { + $methods = parent::getMixableMethods($exclude); + } + + return $methods; + } + + protected function _afterFetch(KModelContext $context) + { + $state = $context->state; + + if (!$state->isUnique() && $state->recurse && ($state->level == 0 || $state->level > 1)) + { + $entities = clone $context->entity; + $key = $this->getConfig()->key ?? $entities->getIdentityKey(); + + //Filter children + foreach ($entities as $entity) + { + //Mixin the behavior + $entity->mixin($this); + + //Get the handle for the parent + $parent = $entity->getHandle(); + + if($parent && $children = $entities->find([$key => $parent])) + { + foreach($children as $child) + { + //Store the nodes by parent + $this->__children[$parent][] = $child; + + $context->entity->remove($child); + } + } + } + + //Mixin the behavior + $context->entity->mixin($this); + } + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/model/behavior/searchable.php b/Sites/pages/components/com_pages/model/behavior/searchable.php new file mode 100644 index 00000000..83844e47 --- /dev/null +++ b/Sites/pages/components/com_pages/model/behavior/searchable.php @@ -0,0 +1,101 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesModelBehaviorSearchable extends ComPagesModelBehaviorQueryable +{ + protected $_columns; + + public function __construct(KObjectConfig $config) + { + parent::__construct($config); + + $this->_columns = (array) KObjectConfig::unbox($config->columns); + } + + protected function _initialize(KObjectConfig $config) + { + $config->append(array( + 'columns' => '', + )); + + parent::_initialize($config); + } + + public function onMixin(KObjectMixable $mixer) + { + parent::onMixin($mixer); + + $mixer->getState() + ->insert('search', 'string'); + } + + protected function _beforeFetch(KModelContextInterface $context) + { + $state = $context->state; + + if ($search = $state->search) + { + // Parse $state->search for possible column prefix + if (preg_match('#^([a-z0-9\-_]+)\s*:\s*(.+)\s*$#i', $search, $matches)) + { + if (in_array($matches[1], $this->_columns)) + { + $this->_columns = (array) $matches[1]; + $state->search = $matches[2]; + } + } + + return parent::_beforeFetch($context); + } + } + + protected function _queryArray(array $data, KModelStateInterface $state) + { + $columns = $this->_columns; + $value = $state->search; + + $data = array_filter($data, function($item) use ($columns, $value) + { + foreach($columns as $column) + { + if (isset($item[$column]) && stripos($item[$column], $value) !== FALSE) { + return true; + } + } + }); + + return $data; + } + + protected function _queryDatabase(KDatabaseQuerySelect $query, KModelStateInterface $state) + { + $conditions = array(); + + if($columns = array_intersect($this->_columns, array_keys($this->getTable()->getColumns()))) + { + foreach ($columns as $column) + { + if (in_array($column, $columns)) + { + $column = $this->getTable()->mapColumns($column); + $conditions[] = 'tbl.' . $column . ' LIKE :search'; + } + } + + if ($conditions) + { + $query->where('(' . implode(' OR ', $conditions) . ')') + ->bind(array('search' => '%' . $state->search . '%')); + } + } + else $query = false; + + return $query; + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/model/behavior/sortable.php b/Sites/pages/components/com_pages/model/behavior/sortable.php new file mode 100644 index 00000000..b1ad1d17 --- /dev/null +++ b/Sites/pages/components/com_pages/model/behavior/sortable.php @@ -0,0 +1,135 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesModelBehaviorSortable extends ComPagesModelBehaviorQueryable +{ + protected function _initialize(KObjectConfig $config) + { + $config->append([ + 'priority' => self::PRIORITY_HIGH, + ]); + + parent::_initialize($config); + } + + public function onMixin(KObjectMixable $mixer) + { + parent::onMixin($mixer); + + $mixer->getState() + ->insert('sort', 'cmd', 'order') + ->insert('order', 'word', 'asc'); + } + + /** + * Split the sort state if format is [property,ASC|DESC] + * + * @param KModelContextInterface $context A model context object + * @return void + */ + protected function _afterReset(KModelContextInterface $context) + { + if($context->modified->contains('sort')) + { + if(strpos($context->state->sort, ',') !== false) + { + $context->state->sort = explode(',', $context->state->sort); + foreach($context->state->sort as $key => $value) + { + if(strtoupper($value) == 'DESC' || strtoupper($value) == 'ASC') + { + unset($context->state->sort[$key]); + $context->state->order = strtolower($value); + } + } + } + + //Support for JSOAPI spec: https://jsonapi.org/format/#fetching-sorting + if($context->state->sort[0] == '-') + { + $context->state->sort = ltrim($context->state->sort, '-'); + $context->state->order = 'desc'; + } + } + } + + protected function _queryArray(array $data, KModelStateInterface $state) + { + if($state->sort && $state->sort != 'order') + { + usort($data, function($first, $second) use($state) + { + $sorting = 0; + $name = $state->sort; + + $first_value = $first[$name]; + $second_value = $second[$name]; + + if($name == 'date') + { + $first_value = is_int($first_value) ? $first_value : strtotime($first_value); + $second_value = is_int($second_value) ? $second_value : strtotime($second_value); + } + + if($first_value > $second_value) { + $sorting = 1; + } elseif ($first_value < $second_value) { + $sorting = -1; + } + + return $sorting; + }); + } + + if($state->order) + { + switch($state->order) + { + case 'desc': + case 'descending': + $data = array_reverse($data); + break; + + case 'random': + case 'shuffle': + shuffle($data); + break; + + } + } + + return $data; + } + + protected function _queryDatabase(KDatabaseQuerySelect $query, KModelStateInterface $state) + { + if(!$query->isCountQuery()) + { + if($state->sort && $state->sort != 'order') + { + $order = strtoupper($state->order); + + if(isset($query->columns[$state->sort])) { + $column = $query->columns[$state->sort]; + } else { + $column = 'tbl.'.$this->getTable()->mapColumns($state->sort); + } + + $query->order($column, $order); + } + + if($state->order && in_array($state->order, ['shuffle', 'random'])) { + $query->shuffle(); + } + + } + + return $query; + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/model/behavior/sparsable.php b/Sites/pages/components/com_pages/model/behavior/sparsable.php new file mode 100644 index 00000000..095d4b56 --- /dev/null +++ b/Sites/pages/components/com_pages/model/behavior/sparsable.php @@ -0,0 +1,142 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +/** + * Sparsable Model Behavior + * + * By making a model sparsable, you enables the ability for clients to choose the returned properties of a model + * entity with URL query parameters. This is useful for optimizing requests, making API calls more efficient + * and fast. + * + * A client can request to get only specific fields in the response by including a fields[TYPE] parameter. The + * value of the fields parameter MUST be a comma-separated (U+002C COMMA, “,”) list that refers to the name(s) + * of the fields to be returned. + * + * The behavior will ALAWYS include the identity key property of the specific type in the returned properties. + * + * Based on the Sparse Fieldsets specification in the JSON API + * @link http://jsonapi.org/format/#fetching-sparse-fieldsets + * + * @author Johan Janssens + */ +class ComPagesModelBehaviorSparsable extends ComPagesModelBehaviorQueryable +{ + protected function _initialize(KObjectConfig $config) + { + $config->append(array( + 'filter' => false + )); + + parent::_initialize($config); + } + + /** + * Insert the model states + * + * @param KObjectMixable $mixer + */ + public function onMixin(KObjectMixable $mixer) + { + parent::onMixin($mixer); + + $mixer->getState() + ->insert('fields', 'cmd', array()); + } + + /** + * Parse the fields state + * + * @param KModelContextInterface $context A model context object + * @return void + */ + protected function _afterReset(KModelContextInterface $context) + { + if($context->modified->contains('fields')) + { + $fields = $context->state->fields; + + foreach ($fields as $type => $value) + { + if(is_string($value)) { + $fields[$type] = array_unique(explode(',', $value)); + } + } + + $context->state->fields = $fields; + } + } + + /** + * Filter data fields + * + * @param KModelContextInterface $context A model context object + * @return void + */ + protected function _queryArray(array $data, KModelStateInterface $state) + { + $fields = $state->fields; + $type = $this->getType(); + + if(isset($fields[$type])) + { + //Always include the unique states (required for routing) + $fields = array_flip(array_merge($fields[$type], $state->getNames(true))); + + foreach($data as $key => $item) { + $data[$key] = array_intersect_key($item, $fields); + } + } + + return $data; + } + + /** + * Add query colums based on fields + * + * @param KModelContextInterface $context A model context object + * @return void + */ + protected function _queryDatabase(KDatabaseQuerySelect $query, KModelStateInterface $state) + { + $table = $this->getTable(); + $columns = $table->getColumns(true); + + $fields = $state->fields; + $type = $this->getType(); + + if(isset($fields[$type])) + { + $result = array(); + $columns = array_keys($table->getColumns()); + + foreach($fields[$type] as $field) + { + if(in_array($field, $columns)) + { + $column = $table->mapColumns($field); + $result[] = 'tbl.'.$column; + } + } + + if(!empty($result)) + { + $query->columns = array(); + + //Always include the identity column + if($table->getIdentityColumn()) { + $result[] = 'tbl.'.$table->getIdentityColumn(); + } + + $query->columns($result); + } + } + + return $query; + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/model/cache.php b/Sites/pages/components/com_pages/model/cache.php new file mode 100644 index 00000000..c39a9d03 --- /dev/null +++ b/Sites/pages/components/com_pages/model/cache.php @@ -0,0 +1,87 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesModelCache extends ComPagesModelCollection +{ + private $__data; + + public function __construct(KObjectConfig $config) + { + parent::__construct($config); + + $this->getState() + ->insert('id', 'url', '', true); + } + + protected function _initialize(KObjectConfig $config) + { + $config->append([ + 'type' => 'cache', + 'cache_path' => $this->getObject('com://site/pages.config')->getSitePath('cache'), + 'identity_key' => 'id', + ]); + + parent::_initialize($config); + } + + public function fetchData() + { + if(!isset($this->__data)) + { + $this->__data = array(); + + $dispatcher = $this->getObject('com://site/pages.dispatcher.http'); + if($dispatcher->isCacheable(false)) + { + $state = $this->getState(); + $files = array(); + + if ($state->isUnique()) + { + $file = $dispatcher->locateCache($state->id); + + if(file_exists($file)) { + $files[] = $file; + } + } + else $files = glob($this->getConfig()->cache_path.'/response_*'); + + foreach ($files as $file) + { + $data = require $file; + + $valid = $dispatcher->validateCache($data['validators'], true); + + $this->__data[] = array( + 'id' => $data['id'], + 'url' => $data['url'], + 'date' => $this->getObject('date', array('date' => $data['headers']['Last-Modified'])), + 'hash' => $data['headers']['Etag'], + 'token' => $data['token'], + 'format' => $data['format'], + 'language' => $data['language'], + 'collections' => $data['headers']['Content-Collections'] ?? array(), + 'robots' => isset($data['headers']['X-Robots-Tag']) ? array_map('trim', explode(',', $data['headers']['X-Robots-Tag'])) : array(), + 'status' => $data['status'], + 'valid' => $valid + ); + } + } + } + + return $this->__data; + } + + protected function _actionReset(KModelContext $context) + { + $this->__data = null; + + parent::_actionReset($context); + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/model/collection.php b/Sites/pages/components/com_pages/model/collection.php new file mode 100644 index 00000000..e3336677 --- /dev/null +++ b/Sites/pages/components/com_pages/model/collection.php @@ -0,0 +1,338 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +abstract class ComPagesModelCollection extends KModelAbstract implements ComPagesModelInterface, ComPagesModelFilterable +{ + private $__type; + private $__name; + private $__persistable; + + public function __construct(KObjectConfig $config) + { + parent::__construct($config); + + //Insert the identity_key + if($config->identity_key) { + $this->getState()->insertUnique($config->identity_key, 'url'); + } + + //Setup callbacks + $this->addCommandCallback('before.fetch' , '_initializeContext'); + $this->addCommandCallback('before.count' , '_initializeContext'); + $this->addCommandCallback('before.persist', '_initializeContext'); + $this->addCommandCallback('before.hash' , '_initializeContext'); + + $this->addCommandCallback('before.persist', '_beforePersist'); + + //Set the type + $this->__type = $config->type; + + //Set the name + $this->__name = $config->name; + + //Set if the collection is persistable + $this->__persistable = $config->persistable; + } + + protected function _initialize(KObjectConfig $config) + { + $config->append([ + 'entity' => $this->getIdentifier()->getName(), + 'type' => $this->getIdentifier()->getPackage() .'-'. KStringInflector::pluralize($this->getIdentifier()->getName()), + 'name' => '', //the collection name used to generate this model + 'search' => [], //properties to allow searching on + 'identity_key' => null, + 'persistable' => false, + 'state' => 'com://site/pages.model.state', + ])->append([ + 'behaviors' => [ + 'com://site/pages.model.behavior.paginatable', + 'com://site/pages.model.behavior.sortable', + 'com://site/pages.model.behavior.sparsable', + 'com://site/pages.model.behavior.filterable', + 'com://site/pages.model.behavior.searchable' => ['columns' => $config->search], + ], + ]); + + parent::_initialize($config); + } + + protected function _initializeContext(KModelContext $context) + { + //Validate the state + $this->_validateState(); + + //Fetch the data + $data = $this->fetchData(); + + //Filter the data + $context->data = $this->filterData($data); + } + + public function setState(array $values) + { + //Automatically create states that don't exist yet + foreach($values as $name => $value) + { + if(!$this->getState()->has($name)) { + $this->getState()->insert($name, 'string'); + } + } + + return parent::setState($values); + } + + final public function hash($refresh = false) + { + $context = $this->getContext(); + $context->refresh = $refresh; + + if ($this->invokeCommand('before.hash', $context) !== false) + { + $context->result = $this->_actionHash($context); + $this->invokeCommand('after.hash', $context); + } + + return $context->result; + } + + final public function persist() + { + if(isset($this->_entity)) + { + $context = $this->getContext(); + $context->entity = $this->_entity; + + if ($this->invokeCommand('before.persist', $context) !== false) + { + $context->result = $this->_actionPersist($context); + $this->invokeCommand('after.persist', $context); + } + } + + return $context->result; + } + + public function getType() + { + return $this->__type; + } + + public function getName() + { + return $this->__name; + } + + public function getIdentityKey() + { + return $this->_identity_key; + } + + public function getPrimaryKey() + { + if(!$this->getIdentityKey()) + { + $keys = array(); + foreach ($this->getState() as $name => $state) + { + //Unique values cannot be null or an empty string + if($state->unique) + { + foreach($state->required as $required) { + $keys[] = $required; + } + + $keys[] = $state->name; + } + } + } + else $keys = (array) $this->getIdentityKey(); + + return (array) $keys; + } + + public function getHashState() + { + $states = array(); + foreach($this->getState() as $state) + { + if(($state->required === true || $state->unique === true || $state->internal === true) && !is_null($state->value)) { + $states[$state->name] = KObjectConfig::unbox($state->value); + } + } + + return $states; + } + + public function isAtomic() + { + $atomic = true; + + if(!$this->getState()->isUnique()) + { + foreach($this->getPrimaryKey() as $key) + { + if(!$this->getState()->get($key)) + { + $atomic = false; + break; + } + } + } + + return $atomic; + } + + public function fetchData() + { + return array(); + } + + public function filterData($data) + { + $state = $this->getState(); + + $result = array(); + foreach($data as $key => $item) + { + $filtered = $this->filterItem($item, $state); + + //Do not include the item if filtering returns empty array, null, or false + if(!empty($filtered)) + { + if(is_array($filtered)) { + $result[$key] = $filtered; + } else { + $result[$key] = $item; + } + } + } + + return $result; + } + + public function filterItem(&$item, KModelStateInterface $state) + { + foreach($state->getValues(true) as $key => $value) + { + if(isset($item[$key]) && !in_array($item[$key], (array) $value)) { + return false; + } + } + + return true; + } + + protected function _validateState() + { + foreach($this->getState() as $name => $state) + { + if($state->required === true && is_null($state->value)) + { + $collection = $this->getName(); + + throw new RuntimeException( + sprintf('State "%s" is required for collection: %s', $state->name, $collection) + ); + + } + } + } + + protected function _actionFetch(KModelContext $context) + { + $entities = $this->create($context->data); + + //Mark the entities as fetched + foreach($entities as $key => $entity) + { + $entity->setStatus(ComPagesModelEntityItem::STATUS_FETCHED); + $entity->resetModified(); + } + + return $entities; + } + + protected function _actionCreate(KModelContext $context) + { + $options = array(); + + //Set the entity identifier + $identifier = $this->getConfig()->entity; + if(is_string($identifier) && strpos($identifier, '.') === false ) + { + $identifier = $this->getIdentifier()->toArray(); + $identifier['path'] = ['model', 'entity']; + $identifier['name'] = KStringInflector::pluralize($this->getConfig()->entity); + } + + $options['entity'] = $this->getIdentifier($identifier); + + //Set the identitiy key + if($identity_key = $context->getIdentityKey()) { + $options['identity_key'] = $identity_key; + } + + //Delegate entity instantiation + $entity = $this->getObject('com://site/pages.model.entity.items', $options); + + // Insert the data + $data = $context->entity; + if(!empty($data) && !is_numeric(key($data))) { + $data = array($data); + } + + foreach($data as $properties) { + $entity->create($properties, ComPagesModelEntityItem::STATUS_CREATED); + } + + return $entity; + } + + protected function _actionCount(KModelContext $context) + { + if(!$context->state->isUnique()) { + $result = count($context->data); + } else { + $result = 1; + } + + return $result; + } + + protected function _beforePersist(KModelContext $context) + { + return $this->isPersistable(); + } + + protected function _actionPersist(KModelContext $context) + { + return false; + } + + protected function _actionHash(KModelContext $context) + { + return null; + } + + public function getContext() + { + $context = new ComPagesModelContextCollection(); + $context->setSubject($this); + $context->setState($this->getState()); + $context->setIdentityKey($this->getIdentityKey()); + + return $context; + } + + public function isPersistable() + { + return $this->__persistable; + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/model/context/collection.php b/Sites/pages/components/com_pages/model/context/collection.php new file mode 100644 index 00000000..f078732e --- /dev/null +++ b/Sites/pages/components/com_pages/model/context/collection.php @@ -0,0 +1,40 @@ + + * @link https://github.com/joomlatools/joomlatools-framework for the canonical source repository + */ + +class ComPagesModelContextCollection extends KModelContext +{ + private $__data; + private $__entity; + + public function setData($data) + { + return $this->__data = $data; + } + + public function getData() + { + return $this->__data; + } + + public function setEntity($entity) + { + return $this->__entity = $entity; + } + + public function getEntity() + { + return $this->__entity; + } + + public function getAction() + { + $parts = explode('.', $this->getName()); + return $parts[1]; + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/model/database.php b/Sites/pages/components/com_pages/model/database.php new file mode 100644 index 00000000..33605879 --- /dev/null +++ b/Sites/pages/components/com_pages/model/database.php @@ -0,0 +1,251 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesModelDatabase extends ComPagesModelCollection +{ + private $__table; + private $__data; + + protected $_hash_key; + + public function __construct(KObjectConfig $config) + { + parent::__construct($config); + + $this->__table = $config->table; + + // Set the dynamic states based on the unique table keys + foreach ($this->getTable()->getUniqueColumns() as $key => $column) + { + if(!empty($column->related)) + { + $related = $this->getTable()->mapColumns($column->related, true); + $this->getState()->insertComposite($key, $column->filter, $related); + } + else $this->getState()->insertUnique($key, $column->filter); + } + + $this->_hash_key = $config->hash_key; + } + + protected function _initialize(KObjectConfig $config) + { + $config->append(array( + 'persistable' => true, + 'table' => '', + 'hash_key' => '', + )); + + parent::_initialize($config); + } + + protected function _initializeContext(KModelContext $context) + { + //Validate the state + $this->_validateState(); + + if($context->action == 'count' || $context->action == 'hash') { + $query = $this->getQuery(false); + } else { + $query = $this->getQuery(); + } + + if($context->action == 'count') { + $query->columns('COUNT(*)'); + } + + $context->data = $query; + } + + public function fetchData() + { + return $this->__data; + } + + public function getTable() + { + if(!($this->__table instanceof KDatabaseTableInterface)) + { + //Make sure we have a table identifier + if(!($this->__table instanceof KObjectIdentifier)) + { + if(is_string($this->__table) && strpos($this->__table, '.') === false ) + { + $identifier = 'com://site/pages.database.table.'.$this->__table; + $this->__table = $this->getObject($identifier, array('name' => $this->__table)); + } + else $this->__table = $this->getObject($this->__table); + } + + if(!$this->__table instanceof KDatabaseTableInterface) + { + throw new UnexpectedValueException( + 'Table: '.get_class($this->__table).' does not implement KDatabaseTableInterface' + ); + } + } + + return $this->__table; + } + + protected function getQuery($columns = true) + { + $query = $this->getObject('lib:database.query.select') + ->table(array('tbl' => $this->getTable()->getName())); + + if($columns) { + $query->columns('tbl.*'); + } + + if ($states = $this->getState()->getValues()) + { + $columns = $this->getTable()->filter($states); + + foreach ($columns as $column => $value) + { + if (isset($value)) + { + $query->where('tbl.' . $column . ' ' . (is_array($value) ? 'IN' : '=') . ' :' . $column) + ->bind(array($column => $value)); + } + } + } + + return $query; + } + + public function getIdentityKey() + { + if(!$key = $this->getConfig()->identity_key) + { + if(!$this->getTable()->getIdentityColumn()) { + $key = parent::getIdentityKey(); + } else { + $key = 'id'; + } + } + + return $key; + } + + public function _actionHash(KModelContext $context) + { + $hash = parent::_actionHash($context); + + if($this->_hash_key) + { + $query = $context->data; + + $id = $this->getIdentityKey(); + $key = $this->getTable()->mapColumns($this->_hash_key); + + $query->columns(['hash' => 'CRC32(GROUP_CONCAT(DISTINCT tbl.'.$id.', "-", tbl.'.$key.'))']); + + $hash = $this->getTable()->select($query, KDatabase::FETCH_FIELD); + } + else + { + if($modified = $this->getTable()->getSchema()->modified) { + $hash = hash('crc32b', $modified); + } + } + + return $hash; + } + + protected function _actionFetch(KModelContext $context) + { + $data = array(); + + if($context->data instanceof KDatabaseQueryInterface) + { + $data = $this->getTable()->select($context->data, KDatabase::FETCH_ARRAY_LIST); + $data = array_values($data); + + //Store the raw data + $this->__data = $data; + } + + $entities = $this->create($data); + + //Mark the entities as fetched + foreach($entities as $key => $entity) { + $entity->setStatus(ComPagesModelEntityItem::STATUS_FETCHED); + } + + return $entities; + } + + protected function _actionCount(KModelContext $context) + { + $result = 0; + + if($context->data instanceof KDatabaseQueryInterface) { + $result = $this->getTable()->count($context->data); + } + + return $result; + } + + protected function _actionPersist(KModelContext $context) + { + $result = true; + + foreach($context->entity as $entity) + { + //Cast the entity to KDatabaseRowInterface + if(!$entity instanceof KDatabaseRowInterface) + { + $row = $this->getTable()->createRow([ + 'data' => $entity->getProperties() + ]); + } + + try + { + if($entity->getStatus() == $entity::STATUS_CREATED) { + $result = $this->getTable()->insert($row); + } + + if($entity->getStatus() == $entity::STATUS_UPDATED) { + $result = $this->getTable()->update($row); + } + + if($entity->getStatus() == $entity::STATUS_DELETED) { + $result = $this->getTable()->delete($row); + } + } + catch(RuntimeException $exception) + { + if($exception->getCode() == 1062) { + throw new ComPagesModelExceptionConflict($exception->getMessage()); + } else { + throw new ComPagesModelExceptionError(); + } + } + + if($result !== false) + { + if($result > 0) + { + $result = self::PERSIST_SUCCESS; + $entity->resetModified(); + } + else $result = self::PERSIST_NOCHANGE; + } + else + { + $result = self::PERSIST_FAILURE; + break; + } + } + + return $result; + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/model/decorator.php b/Sites/pages/components/com_pages/model/decorator.php new file mode 100644 index 00000000..ae256f03 --- /dev/null +++ b/Sites/pages/components/com_pages/model/decorator.php @@ -0,0 +1,329 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesModelDecorator extends KModelAbstract implements ComPagesModelInterface +{ + private $__persistable; + private $__delegate; + private $__name; + + public function __construct(KObjectConfig $config) + { + parent::__construct($config); + + $this->__delegate = $config->delegate; + + //Set if the collection is persistable + $this->__persistable = $config->persistable; + + //Set the name + $this->__name = $config->name; + } + + protected function _initialize(KObjectConfig $config) + { + $config->append(array( + 'persistable' => true, + 'delegate' => '', + 'name' => '', //the collection name used to generate this model + )); + + parent::_initialize($config); + } + + public function getDelegate() + { + if(!$this->__delegate instanceof KControllerModellable && !$this->__delegate instanceof KModelInterface) + { + //Make sure we have a controller identifier + if(!($this->__delegate instanceof KObjectIdentifier)) + { + $identifier = $this->getIdentifier($this->__delegate); + + if($identifier->path[0] != 'controller' && $identifier->path[0] != 'model') + { + throw new UnexpectedValueException( + 'Identifier: '.$identifier.' is not a controller or model identifier' + ); + } + + $this->__delegate = $identifier; + } + + $this->__delegate = $this->getObject($this->__delegate); + + if(!$this->__delegate instanceof KControllerModellable && !$this->__delegate instanceof KModelInterface) + { + throw new UnexpectedValueException( + 'Decorator: '.get_class($this->__delegate).' does not implement KControllerModellable or KModelInterface' + ); + } + } + + return $this->__delegate; + } + + public function setState(array $values) + { + $delegate = $this->getDelegate(); + + if($delegate instanceof KControllerModellable) { + $delegate->getModel()->setState($values); + } else { + $delegate->setState($values); + } + + return $this; + } + + public function getState() + { + $delegate = $this->getDelegate(); + + if($delegate instanceof KControllerModellable) { + $state = $delegate->getModel()->getState(); + } else { + $state = $delegate->getState(); + } + + return $state; + } + + public function getType() + { + $name = $this->getDelegate()->getIdentifier()->getName(); + $package = $this->getDelegate()->getIdentifier()->getPackage(); + + return sprintf('%s-%s', $package, $name); + } + + public function getName() + { + return $this->__name; + } + + public function getIdentityKey() + { + $delegate = $this->getDelegate(); + + if($delegate instanceof KControllerModellable) { + $model = $delegate->getModel(); + } else { + $model = $delegate; + } + + if(!$model instanceof ComPagesModelInterface) { + $key = $model->fetch()->getIdentityKey(); + } else { + $key = $model->getIdentityKey(); + } + + return $key; + } + + public function getPrimaryKey() + { + $delegate = $this->getDelegate(); + + if($delegate instanceof KControllerModellable) { + $model = $delegate->getModel(); + } else { + $model = $delegate; + } + + if(!$model instanceof ComPagesModelInterface) { + $key = $model->fetch()->getIdentityKey(); + } else { + $key = $model->getPrimaryKey(); + } + + return (array) $key; + } + + public function getHashState() + { + $hash = null; + $delegate = $this->getDelegate(); + + if($delegate instanceof KControllerModellable) { + $model = $delegate->getModel(); + } else { + $model = $delegate; + } + + if($model instanceof KModelDatabase) + { + $states = array(); + foreach($model->getState() as $state) + { + if(($state->required === true || $state->unique === true || $state->internal === true) && !is_null($state->value)) { + $states[$state->name] = KObjectConfig::unbox($state->value); + } + } + } + + if($model instanceof ComPagesModelInterface) { + $states = $model->getHashState(); + } + + return $states; + } + + public function isAtomic() + { + $atomic = true; + + if(!$this->getState()->isUnique()) + { + foreach($this->getPrimaryKey() as $key) + { + if(!$this->getState()->get($key)) + { + $atomic = false; + break; + } + } + } + + return $atomic; + } + + final public function hash($refresh = false) + { + $context = $this->getContext(); + $context->refresh = $refresh; + + if ($this->invokeCommand('before.hash', $context) !== false) + { + $context->result = $this->_actionHash($context); + $this->invokeCommand('after.hash', $context); + } + + return $context->result; + } + + final public function persist() + { + if(isset($this->_entity)) + { + $context = $this->getContext(); + $context->entity = $this->_entity; + + if ($this->invokeCommand('before.persist', $context) !== false) + { + $context->result = $this->_actionPersist($context); + $this->invokeCommand('after.persist', $context); + } + } + + return $context->result; + } + + protected function _actionFetch(KModelContext $context) + { + $delegate = $this->getDelegate(); + + if($delegate instanceof KControllerModellable) + { + if ($this->getState()->isUnique()) { + $result = $this->getDelegate()->read(); + } else { + $result = $this->getDelegate()->browse(); + } + } + else $result = $this->getDelegate()->fetch(); + + return $result; + } + + protected function _actionCount(KModelContext $context) + { + return $this->getDelegate()->count(); + } + + protected function _actionReset(KModelContext $context) + { + $delegate = $this->getDelegate(); + + if($delegate instanceof KControllerModellable) { + $delegate->getModel()->reset(); + } else { + $delegate->reset(); + } + } + + protected function _actionHash(KModelContext $context) + { + $hash = null; + $delegate = $this->getDelegate(); + + if($delegate instanceof KControllerModellable) { + $model = $delegate->getModel(); + } else { + $model = $delegate; + } + + if($model instanceof KModelDatabase) + { + if($modified = $model->getTable()->getSchema()->modified) { + $hash = hash('crc32b', $modified); + } + } + + if($model instanceof ComPagesModelInterface) { + $hash = $model->hash($context->refresh); + } + + return $hash; + } + + + protected function _beforePersist(KModelContext $context) + { + return $this->isPersistable(); + } + + protected function _actionPersist(KModelContext $context) + { + $result = self::PERSIST_SUCCESS; + $delegate = $this->getDelegate(); + + if($delegate instanceof KControllerModellable) { + $model = $delegate->getModel(); + } else { + $model = $delegate; + } + + if($model instanceof ComPagesModelInterface) { + $result = $model->persist(); + } + + return $result; + } + + public function isPersistable() + { + if($result = $this->__persistable) + { + $delegate = $this->getDelegate(); + + if($delegate instanceof KControllerModellable) { + $model = $delegate->getModel(); + } else { + $model = $delegate; + } + + if(!$model instanceof ComPagesModelInterface) { + $result = false; + } + } + + return $result; + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/model/entity/interface.php b/Sites/pages/components/com_pages/model/entity/interface.php new file mode 100644 index 00000000..e2253db8 --- /dev/null +++ b/Sites/pages/components/com_pages/model/entity/interface.php @@ -0,0 +1,13 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +interface ComPagesModelEntityInterface extends KModelEntityInterface, KObjectInstantiable +{ + +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/model/entity/item.php b/Sites/pages/components/com_pages/model/entity/item.php new file mode 100644 index 00000000..e60f71f4 --- /dev/null +++ b/Sites/pages/components/com_pages/model/entity/item.php @@ -0,0 +1,137 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesModelEntityItem extends KModelEntityAbstract implements ComPagesModelEntityInterface +{ + use ComPagesObjectDebuggable; + + private $__internal_properties; + + public static function getInstance(KObjectConfigInterface $config, KObjectManagerInterface $manager) + { + if($config->entity) + { + $config->object_identifier = $config->entity; + + if(!$class = $manager->getClass($config->entity, false)) { + $instance = new static($config); + } else { + $instance = new $class($config); + } + } + else $instance = new static($config); + + return $instance; + } + + public function __construct(KObjectConfig $config) + { + parent::__construct($config); + + $this->__internal_properties = KObjectConfig::unbox($config->internal_properties); + } + + protected function _initialize(KObjectConfig $config) + { + $config->append([ + 'internal_properties' => [], + ]); + + parent::_initialize($config); + } + + public function getInteralProperties() + { + return $this->__internal_properties; + } + + public function get($property, $default = null) + { + $result = $this->getProperty($property); + + if($result instanceof Traversable) { + $result = iterator_count($result) ? $result : $default; + } elseif($result instanceof Countable) { + $result = count($result) ? $result : $default; + } else { + $result = !empty($result) ? $result : $default; + } + + return $result; + } + + public function has($name) + { + return parent::hasProperty($name); + } + + public function save() + { + if (!$this->isNew()) { + $this->setStatus(self::STATUS_UPDATED); + } else { + $this->setStatus(self::STATUS_CREATED); + } + + return true; + } + + public function delete() + { + $this->setStatus(self::STATUS_DELETED); + return true; + } + + public function resetModified() + { + $this->_modified = array(); + return $this; + } + + public function toArray() + { + $data = parent::toArray(); + + $computed = $this->getComputedProperties(); + $internal = $this->getInteralProperties(); + + //Remove internal properties + $data = array_diff_key($data, array_flip($internal)); + + //Add none-internal computed properties + foreach(array_diff($computed, $internal) as $property) { + $data[$property] = $this->{$property}; + } + + //Unpack config objects + array_walk_recursive($data, function(&$value, $key) + { + if($value instanceof KObjectConfigInterface) { + $value = KObjectConfig::unbox($value); + } + }); + + return $data; + } + + public function __call($method, $arguments) + { + $parts = KStringInflector::explode($method); + + //Check if a behavior is mixed + if ($parts[0] == 'is' && isset($parts[1])) + { + if(!isset($this->_mixed_methods[$method])) { + return false; + } + } + + return parent::__call($method, $arguments); + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/model/entity/items.php b/Sites/pages/components/com_pages/model/entity/items.php new file mode 100644 index 00000000..056fd325 --- /dev/null +++ b/Sites/pages/components/com_pages/model/entity/items.php @@ -0,0 +1,125 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesModelEntityItems extends KModelEntityComposite implements JsonSerializable, ComPagesModelEntityInterface +{ + use ComPagesObjectDebuggable; + + public static function getInstance(KObjectConfigInterface $config, KObjectManagerInterface $manager) + { + if($config->entity) + { + $config->object_identifier = $config->entity; + + if(!$class = $manager->getClass($config->entity, false)) { + $instance = new self($config); + } else { + $instance = new $class($config); + } + } + else $instance = new self($config); + + return $instance; + } + + public function get($property, $default = null) + { + $result = $default; + if($entity = $this->getIterator()->current()) { + $result = $entity->get($property, $default); + } + + return $result; + } + + public function has($property) + { + $result = false; + if($entity = $this->getIterator()->current()) { + $result = $entity->has($property); + } + + return $result; + } + + public function jsonSerialize() + { + $result = array(); + foreach ($this as $key => $entity) { + $result[$key] = $entity->jsonSerialize(); + } + + return $result; + } + + public function create(array $properties = array(), $status = null) + { + if($this->_prototypable) + { + if(!$this->_prototype instanceof KModelEntityInterface) + { + $identifier = $this->getIdentifier()->toArray(); + $identifier['name'] = KStringInflector::singularize($identifier['name']); + + //The entity default options + $options = array( + 'identity_key' => $this->getIdentityKey(), + 'entity' => $this->getIdentifier($identifier) + ); + + //Delegate entity instantiation + $this->_prototype = $this->getObject('com://site/pages.model.entity.item', $options); + } + + $entity = clone $this->_prototype; + + $entity->setStatus($status); + $entity->setProperties($properties, $entity->isNew()); + } + else + { + $identifier = $this->getIdentifier()->toArray(); + $identifier['name'] = KStringInflector::singularize($identifier['name']); + + //The entity default options + $options = array( + 'data' => $properties, + 'status' => $status, + 'identity_key' => $this->getIdentityKey(), + 'entity' => $this->getIdentifier($identifier) + ); + + //Delegate entity instantiation + $entity = $this->getObject('com://site/pages.model.entity.item', $options); + } + + //Insert the entity into the collection + $this->insert($entity); + + return $entity; + } + + public function __call($method, $arguments) + { + $result = null; + + $methods = $this->getMethods(); + if(!isset($methods[$method])) + { + //Forward the call to the entity + if($entity = parent::getIterator()->current()) { + $result = $entity->__call($method, $arguments); + } + + } + else $result = KObject::__call($method, $arguments); + + return $result; + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/model/entity/page.php b/Sites/pages/components/com_pages/model/entity/page.php new file mode 100644 index 00000000..3a5cda2f --- /dev/null +++ b/Sites/pages/components/com_pages/model/entity/page.php @@ -0,0 +1,248 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesModelEntityPage extends ComPagesModelEntityItem +{ + private $__parent; + + protected function _initialize(KObjectConfig $config) + { + $config->append([ + 'data' => [ + 'path' => '', + 'slug' => '', + 'name' => '', + 'title' => '', + 'summary' => '', + 'content' => '', + 'excerpt' => null, + 'text' => '', + 'image' => [ + //'url' => '', + //'alt' => null, + //'caption' => null, + ], + 'date' => 'now', + 'author' => null, + 'access' => [], + 'metadata' => [ + 'og:type' => 'website', + 'og:title' => null, + 'og:url' => null, + 'og:image' => null, + 'og:description' => null, + ], + 'direction' => 'auto', + 'language' => 'en-GB', + 'canonical' => null, + ], + 'internal_properties' => [ + 'format', + 'route', + 'slug', + 'path', + 'folder', + 'content', + 'hash', + 'text', + 'excerpt', + ], + ]); + + parent::_initialize($config); + } + + public function getPropertyFolder() + { + return dirname($this->path); + } + + public function getPropertyExcerpt() + { + $parts = preg_split('##i', $this->getContent(), 2); + + if(count($parts) > 1) { + $excerpt = $parts[0]; + } else { + $excerpt = null; + } + + return $excerpt; + } + + public function getPropertyText() + { + $parts = preg_split('##i', $this->getContent(), 2); + + if(count($parts) > 1) { + $text = $parts[1]; + } else { + $text = $parts[0]; + } + + return $text; + } + + public function setPropertyImage($value) + { + //Normalize images + $image = null; + + if(!empty($value) && !$value instanceof ComPagesObjectConfig) + { + if(is_array($value)) { + $url = $value['url'] ?? ''; + } else { + $url = $value; + } + + if($url) + { + if(is_string($url) && strpos($url, '://') === false) { + $url = '/'.ltrim($url, '/'); + } + + $url = $this->getObject('lib:http.url')->setUrl($url); + + $image = [ + 'url' => $url, + 'alt' => $value['alt'] ?? null, + 'caption' => $value['caption'] ?? null, + ]; + } + + $image = new ComPagesObjectConfig($image); + } + else $image = new ComPagesObjectConfig($value); + + return $image; + } + + public function setPropertyMetadata($metadata) + { + if(!$metadata instanceof ComPagesObjectConfig) + { + $metadata = new ComPagesObjectConfig($metadata); + + if(!isset($metadata->description) && $this->summary) { + $metadata->set('description', $this->summary); + } + + if($this->image && $this->image->url) { + $metadata->set('og:image', $this->image->url); + } + + //Type and image are required. If they are not set remove any opengraph properties + if(!empty($metadata->get('og:type')) && !empty($metadata->get('og:image'))) + { + if($this->title) { + $metadata->set('og:title', $this->title); + } + + if($this->summary) { + $metadata->set('og:description', $this->summary); + } + + if($this->language) { + $metadata->set('og:locale', $this->language); + } + } + else + { + foreach($metadata as $name => $value) + { + if(strpos($name, 'og:') === 0 || strpos($name, 'twitter:') === 0) { + $metadata->remove($name); + } + } + } + } + + return $metadata; + } + + public function setPropertyName($name) + { + if(empty($name)) { + $name = ucwords(str_replace(array('_', '-'), ' ', $this->slug)); + } + + return $name; + } + + public function setPropertyAccess($value) + { + return new ComPagesObjectConfig($value); + } + + public function setPropertyProcess($value) + { + return new ComPagesObjectConfig($value); + } + + public function setPropertyCollection($value) + { + return new ComPagesObjectConfig($value); + } + + public function setPropertyForm($value) + { + return new ComPagesObjectConfig($value); + } + + public function setPropertyDate($value) + { + //Set the date based on the modified time of the file + if(is_integer($value)) { + $date = $this->getObject('date')->setTimestamp($value); + } else { + $date = $this->getObject('date', array('date' => trim($value))); + } + + return $date; + } + + public function getParent() + { + if(!$this->__parent) + { + $page = $this->getObject('page.registry')->getPage($this->folder); + + $this->__parent = $this->getObject($this->getIdentifier(), + array('data' => $page->toArray()) + ); + } + + return $this->__parent; + } + + public function getContent() + { + if(!$this->content) { + $this->content = $this->getObject('page.registry')->getPageContent($this->path); + } + + return $this->content; + } + + public function getContentType() + { + return 'text/html'; + } + + public function getHandle() + { + return $this->path; + } + + public function __toString() + { + return $this->getObject('page.registry')->getPageContent($this->path, true); + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/model/entity/pages.php b/Sites/pages/components/com_pages/model/entity/pages.php new file mode 100644 index 00000000..f6fdee66 --- /dev/null +++ b/Sites/pages/components/com_pages/model/entity/pages.php @@ -0,0 +1,20 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesModelEntityPages extends ComPagesModelEntityItems +{ + protected function _initialize(KObjectConfig $config) + { + $config->append([ + 'prototypable' => false + ]); + + parent::_initialize($config); + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/model/exception/conflict.php b/Sites/pages/components/com_pages/model/exception/conflict.php new file mode 100644 index 00000000..ad126589 --- /dev/null +++ b/Sites/pages/components/com_pages/model/exception/conflict.php @@ -0,0 +1,16 @@ + + * @link https://github.com/joomlatools/joomlatools-framework for the canonical source repository + */ + +/** + * Conflict Model Exception + * + * @author Johan Janssens + * @package Koowa\Library\Controller\Exception + */ +class ComPagesModelExceptionConflict extends KHttpExceptionConflict implements ComPagesModelException {} diff --git a/Sites/pages/components/com_pages/model/exception/error.php b/Sites/pages/components/com_pages/model/exception/error.php new file mode 100644 index 00000000..8f3baefd --- /dev/null +++ b/Sites/pages/components/com_pages/model/exception/error.php @@ -0,0 +1,16 @@ + + * @link https://github.com/joomlatools/joomlatools-framework for the canonical source repository + */ + +/** + * Failed Model Exception + * + * @author Johan Janssens + * @package Koowa\Library\Controller\Exception + */ +class ComPagesModelExceptionError extends Exception implements ComPagesModelException {} diff --git a/Sites/pages/components/com_pages/model/exception/exception.php b/Sites/pages/components/com_pages/model/exception/exception.php new file mode 100644 index 00000000..7722b1e8 --- /dev/null +++ b/Sites/pages/components/com_pages/model/exception/exception.php @@ -0,0 +1,16 @@ + + * @link https://github.com/joomlatools/joomlatools-framework for the canonical source repository + */ + +/** + * Model Exception Interface + * + * @author Johan Janssens + * @package Koowa\Library\Controller\Exception + */ +interface ComPagesModelException extends KException {} diff --git a/Sites/pages/components/com_pages/model/factory.php b/Sites/pages/components/com_pages/model/factory.php new file mode 100644 index 00000000..c06a93d1 --- /dev/null +++ b/Sites/pages/components/com_pages/model/factory.php @@ -0,0 +1,113 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesModelFactory extends KObject implements KObjectSingleton +{ + private $__models; + + public function createModel($name, $state = array(), $replace = true) + { + $model = null; + + if($collection = $this->getObject('page.registry')->getCollection($name)) + { + //Create the model + $model = KHttpUrl::fromString($collection->model); + + $identifier = $model->toString(KHttpUrl::BASE); + $config = $model->query; + + if(is_string($identifier) && strpos($identifier, '.') === false ) + { + $temp = $this->getIdentifier()->toArray(); + $temp['name'] = $identifier; + + $identifier = $temp; + } + + //Set the name + $config['name'] = $name; + + //Set the type + if($collection->has('type')) { + $config['type'] = $collection->type; + } + + //Add additional config + if($collection->has('config')) { + $config = array_merge($config, KObjectConfig::unbox($collection->config)); + } + + $model = $this->getObject($identifier, $config); + + if(!$model instanceof KControllerModellable && !$model instanceof KModelInterface) + { + throw new UnexpectedValueException( + 'Collection: '.get_class($model).' does not implement KModelInterface or KControllerModellable' + ); + } + + if($model instanceof KControllerModellable || !$model instanceof ComPagesModelInterface) { + $model = $this->getObject('com://site/pages.model.decorator', ['delegate' => $model]); + } + + //Add model filters for unique fields + if($collection->has('schema')) + { + $schema = (array) KObjectConfig::unbox($collection->schema); + + foreach($schema as $field => $constraints) + { + if(in_array('unique', $constraints)) + { + $filters = array_diff($constraints, ['unique', 'required']); + + //Do not add a filter if it already exists + if(!$model->getState()->has($field)) { + $model->getState()->insert($field, $filters, null, true); + } + } + } + } + + //Set the model state + if(isset($collection->state)) + { + //Remove states with 'null' values + $default_state = KObjectConfig::unbox($collection->state); + foreach($default_state as $k => $v) + { + if(is_null($v)) { + unset($default_state[$k]); + } + } + + if($replace) { + $state = array_replace_recursive($default_state, $state); + } else { + $state = array_replace_recursive($state, $default_state); + } + } + + $model->setState($state); + + //Store the collection + $hash = hash('crc32b', $name.serialize($model->getHashState())); + $this->__models[$hash] = $model; + } + else throw new UnexpectedValueException('Collection: '.$name.' cannot be found'); + + return $model; + } + + public function getModels() + { + return (array) $this->__models; + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/model/filesystem.php b/Sites/pages/components/com_pages/model/filesystem.php new file mode 100644 index 00000000..f2ed1edc --- /dev/null +++ b/Sites/pages/components/com_pages/model/filesystem.php @@ -0,0 +1,205 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesModelFilesystem extends ComPagesModelCollection +{ + private $__data; + + protected $_path; + protected $_base_path; + protected $_identity_key_length; + + public function __construct(KObjectConfig $config) + { + parent::__construct($config); + + $this->_path = $config->path; + $this->_base_path = $config->base_path; + + $this->_identity_key_length = $config->identity_key_length; + } + + protected function _initialize(KObjectConfig $config) + { + $config->append([ + 'persistable' => true, + 'identity_key' => null, + 'identity_key_length' => 4, + 'path' => '', + 'base_path' => $this->getObject('com:pages.config')->getSitePath(), + ]); + + parent::_initialize($config); + } + + public function getPath(array $variables = array()) + { + $path = (string) KHttpUrl::fromTemplate($this->_path, $variables); + $path = $path[0] != '/' ? $this->_base_path.'/'.$path : $path; + + return $path; + } + + public function createIdentity() + { + return bin2hex(random_bytes($this->_identity_key_length)); + } + + public function fetchData() + { + if(!isset($this->__data)) + { + $this->__data = array(); + $path = $this->getPath($this->getState()->getValues()); + + //Only fetch data if the file exists + if(file_exists($path)) { + $this->__data = $this->getObject('object.config.factory')->fromFile($path, false); + } + } + + return $this->__data; + } + + protected function _actionReset(KModelContext $context) + { + $this->__data = null; + + parent::_actionReset($context); + } + + protected function _actionHash(KModelContext $context) + { + $hash = parent::_actionHash($context); + $path = $this->getPath($this->getState()->getValues()); + + if(file_exists($path)) { + $hash = hash('crc32b', filemtime($path)); + } + + return $hash; + } + + protected function _actionPersist(KModelContext $context) + { + $result = true; + $identity_key = $this->getIdentityKey(); + + $data = $context->data; + + if($identity_key) + { + $keys = array_column($data, $identity_key); + $data = array_combine($keys, $data); + } + + foreach($context->entity as $entity) + { + $key = $entity->getProperty($identity_key); + $values = $entity->toArray(); + + if($entity->getStatus() == $entity::STATUS_CREATED) + { + //Only add none existing entities + if(!isset($data[$key])) + { + //Prevent duplicate unique values + foreach($context->state as $state) + { + $name = $state->name; + + if($state->unique && array_search($entity->$name, array_column($data, $name)) !== false) + { + throw new ComPagesModelExceptionConflict( + sprintf("Duplicate entry '%s' for key '%s'", $entity->$name, $name) + ); + } + } + + if($identity_key) + { + if(!$key) + { + $key = $this->createIdentity(); + $entity->setProperty($identity_key, $key, false); + } + + $data[$key] = [$identity_key => $key] + $values; + } + else $data[] = $values; + + $result = self::PERSIST_SUCCESS; + } + else $result = self::PERSIST_FAILURE; + } + + if($entity->getStatus() == $entity::STATUS_UPDATED) + { + //Only update existing entities + if(isset($data[$key])) + { + //Do not update is no data has changed + if(array_diff_assoc($values, $data[$key])) + { + unset($data[$key]); + + //Prevent duplicate unique values + foreach($context->state as $state) + { + $name = $state->name; + + if($state->unique && array_search($entity->$name, array_column($data, $name)) !== false) + { + throw new ComPagesModelExceptionConflict( + sprintf("Duplicate entry '%s' for key '%s'", $entity->$name, $state->name) + ); + } + } + + $data[$key] = $values; + $result = self::PERSIST_SUCCESS; + } + else $result = self::PERSIST_NOCHANGE; + + } + else $result = self::PERSIST_FAILURE; + } + + if($entity->getStatus() == $entity::STATUS_DELETED) + { + //Only delete existing entities + if(isset($data[$key])) + { + unset($data[$key]); + $result = self::PERSIST_SUCCESS; + } + else $result = self::PERSIST_FAILURE; + } + + //Reset the entity modified state + if($result === self::PERSIST_SUCCESS) { + $entity->resetModified(); + } + + if($result === self::PERSIST_FAILURE) { + break; + } + } + + if($result === self::PERSIST_SUCCESS) + { + $data = array_values($data); + + $path = $this->getPath($this->getState()->getValues()); + $this->getObject('object.config.factory')->toFile($path, $data); + } + + return $result; + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/model/filterable.php b/Sites/pages/components/com_pages/model/filterable.php new file mode 100644 index 00000000..ccf6f73e --- /dev/null +++ b/Sites/pages/components/com_pages/model/filterable.php @@ -0,0 +1,15 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +interface ComPagesModelFilterable extends KModelInterface +{ + public function fetchData(); + public function filterData($data); + public function filterItem(&$item, KModelStateInterface $state); +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/model/interface.php b/Sites/pages/components/com_pages/model/interface.php new file mode 100644 index 00000000..4af56949 --- /dev/null +++ b/Sites/pages/components/com_pages/model/interface.php @@ -0,0 +1,28 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +interface ComPagesModelInterface extends KModelInterface +{ + const PERSIST_SUCCESS = 1; + const PERSIST_NOCHANGE = 2; + const PERSIST_FAILURE = 3; + + public function persist(); + public function hash($refresh = false); + + public function getName(); + public function getType(); + public function getIdentityKey(); + public function getPrimaryKey(); + + public function getHashState(); + + public function isAtomic(); + public function isPersistable(); +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/model/pages.php b/Sites/pages/components/com_pages/model/pages.php new file mode 100644 index 00000000..5734ba24 --- /dev/null +++ b/Sites/pages/components/com_pages/model/pages.php @@ -0,0 +1,154 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesModelPages extends ComPagesModelCollection +{ + private $__data; + + public function __construct(KObjectConfig $config) + { + parent::__construct($config); + + $this->getState() + ->insertComposite('slug', 'cmd', array('folder'), '') + ->insertInternal('folder', 'url') + ->insertInternal('recurse', 'cmd') + ->insertInternal('level', 'int', 0) + ->insertInternal('collection', 'boolean'); + } + + protected function _initialize(KObjectConfig $config) + { + $config->append([ + 'type' => 'pages', + 'behaviors' => ['com://site/pages.model.behavior.recursable' => ['key' => 'folder']] + ]); + + parent::_initialize($config); + } + + public function fetchData() + { + if(!isset($this->__data)) + { + $this->__data = array(); + + //If folder is not defined to set root path + $state = $this->getState(); + $folder = $state->folder ?? '.'; + + if($folder) + { + $registry = $this->getObject('page.registry'); + + if ($state->isUnique()) + { + if($page = $registry->getPage($folder.'/'.$this->getState()->slug)) { + $this->__data = array($page->toArray()); + } + } + else + { + if(!$state->recurse) { + $mode = ComPagesPageRegistry::PAGES_ONLY; + } else { + $mode = ComPagesPageRegistry::PAGES_TREE; + } + + $this->__data = array_values($registry->getPages($folder, $mode, $state->level - 1)); + } + } + } + + return $this->__data; + } + + public function filterItem(&$page, KModelStateInterface $state) + { + $result = true; + + //Un-routable + if($page['route'] === false) { + $result = false; + } + + //Collection + if($result && !is_null($state->collection)) + { + if($state->collection === true) { + $result = isset($page['collection']) && $page['collection'] !== false; + } + + if($state->collection === false) { + $result = !isset($page['collection']) || $page['collection'] === false; + } + } + + //Permissions + if($result) + { + //Goups + if(isset($page['access']['groups'])) + { + $groups = $this->getObject('com://site/pages.database.table.groups') + ->select($this->getObject('user')->getGroups(), KDatabase::FETCH_ARRAY_LIST); + + $groups = array_map('strtolower', array_column($groups, 'title')); + + if(!array_intersect($groups, $page['access']['groups'])) { + $result = false; + } + } + + //Roles + if($result && isset($page['access']['roles'])) + { + $roles = $this->getObject('com://site/pages.database.table.roles') + ->select($this->getObject('user')->getRoles(), KDatabase::FETCH_ARRAY_LIST); + + $roles = array_map('strtolower', array_column($roles, 'title')); + + if(!array_intersect($roles, $page['access']['roles'])) { + $result = false; + } + } + } + + return $result; + } + + protected function _actionHash(KModelContext $context) + { + $data = array_column($context->data, 'hash', 'path'); + return hash('crc32b', serialize($data)); + } + + + protected function _actionFetch(KModelContext $context) + { + foreach($context->data as $page) + { + //Unset page attributes + unset($page['process']); + unset($page['collection']); + unset($page['form']); + unset($page['layout']); + unset($page['redirect']); + } + + return parent::_actionFetch($context); + } + + protected function _actionReset(KModelContext $context) + { + $this->__data = null; + + parent::_actionReset($context); + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/model/state/state.php b/Sites/pages/components/com_pages/model/state/state.php new file mode 100644 index 00000000..9ab9b24e --- /dev/null +++ b/Sites/pages/components/com_pages/model/state/state.php @@ -0,0 +1,31 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesModelState extends KModelState +{ + public function insertUnique($name, $filter, $default = null) + { + return parent::insert($name, $filter, $default, true); + } + + public function insertComposite($name, $filter, $related, $default = null) + { + return parent::insert($name, $filter, $default, true, $related, false); + } + + public function insertRequired($name, $filter, $default = null) + { + return parent::insert($name, $filter, $default, false, true); + } + + public function insertInternal($name, $filter, $default = null) + { + return parent::insert($name, $filter, $default, false, array(), true); + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/model/webservice.php b/Sites/pages/components/com_pages/model/webservice.php new file mode 100644 index 00000000..ebf63065 --- /dev/null +++ b/Sites/pages/components/com_pages/model/webservice.php @@ -0,0 +1,280 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesModelWebservice extends ComPagesModelCollection +{ + static private $__resource_cache = array(); + + private $__http; + private $__data; + + protected $_url; + protected $_cache_time; + protected $_data_path; + protected $_hash_key; + + public function __construct(KObjectConfig $config) + { + parent::__construct($config); + + $this->__http = $config->http; + $this->_url = $config->url; + + $this->_cache_time = $config->cache; + $this->_data_path = $config->data_path; + $this->_hash_key = (array) KObjectConfig::unbox($config->hash_key); + } + + protected function _initialize(KObjectConfig $config) + { + $config->append([ + 'persistable' => true, + 'identity_key' => 'id', + 'http' => 'com://site/pages.http.cache', + 'entity' => 'resource', + 'url' => '', + 'data_path' => '', + 'hash_key' => array(), + 'cache' => true, + 'headers' => array() + ]); + + parent::_initialize($config); + } + + protected function _initializeContext(KModelContext $context) + { + //Set a minimum cache time of 1min if refreshing + if($context->action == 'hash' && $this->_cache_time !== false) { + $this->_cache_time = $context->refresh ? 60 : $this->_cache_time; + } + + parent::_initializeContext($context); + } + + public function getUrl(array $variables = array()) + { + return KHttpUrl::fromTemplate($this->_url, $variables); + } + + public function getHeaders($cache = true) + { + $headers = KObjectConfig::unbox($this->getConfig()->headers); + + if($cache !== true) + { + if($cache !== false) + { + //Convert max_age to seconds + if(!is_numeric($cache)) + { + if($max_age = strtotime($cache)) { + $max_age = $max_age - strtotime('now'); + } + } + else $max_age = $cache; + + $headers['Cache-Control'] = ['max-age' => (int) $max_age]; + } + else $headers['Cache-Control'] = ['no-store']; + } + + return $headers; + } + + public function fetchData() + { + if(!isset($this->__data)) + { + $data = array(); + + if($url = $this->getUrl($this->getState()->getValues())) { + $data = $this->_getHttpData($url, $this->_cache_time, $this->_data_path); + } + + $this->__data = $data; + } + + return $this->__data; + } + + protected function _actionReset(KModelContext $context) + { + $this->__data = null; + + parent::_actionReset($context); + } + + protected function _actionHash(KModelContext $context) + { + $hash = parent::_actionHash($context); + + $data = $context->data; + + $url = $this->getUrl($this->getState()->getValues()); + $identity = $this->getState()->get($this->getIdentityKey()); + + if($this->_hash_key) + { + $result = array(); + foreach($this->_hash_key as $key) + { + $column = array_column($data, $key, $this->getIdentityKey()); + + if($this->getState()->isUnique() && isset($column[$identity])) { + $column = $column[$identity]; + } + + $result[$key] = $column; + } + + $data = $result; + } + + $hash = hash('crc32b', serialize($data).$url); + return $hash; + } + + protected function _actionPersist(KModelContext $context) + { + $result = true; + $entity = $context->entity; + + $http = $this->_getHttpClient(); + $url = $this->getUrl($this->getState()->getValues()); + + $headers = $this->getHeaders(); + $headers['Origin'] = $url->toString(KHttpUrl::AUTHORITY); + + $data = array(); + if(!$context->state->isUnique()) + { + foreach($context->entity as $entity) { + $data = array_merge($entity->getProperties(true), $data); + } + } + else $data = $entity->getProperties(true); + + if($entity->getStatus() == $entity::STATUS_CREATED) + { + if($context->state->isUnique()) { + $result = $http->put($url, $data, $headers); + } else { + $result = $http->post($url, $data, $headers); + } + + if($result !== false) + { + foreach($result as $name => $value) { + $entity->setProperty($name, $value, false); + } + + $result = self::PERSIST_SUCCESS; + } + else $result = self::PERSIST_FAILURE; + } + + if($entity->getStatus() == $entity::STATUS_UPDATED) + { + $result = $http->patch($url, $data, $headers); + + if($result !== false) + { + if(!empty($result)) + { + foreach($result as $name => $value) { + $entity->setProperty($name, $value, false); + } + + $result = self::PERSIST_SUCCESS; + } + else $result = self::PERSIST_NOCHANGE; + } + else $result = self::PERSIST_FAILURE; + } + + if($entity->getStatus() == $entity::STATUS_DELETED) + { + $result = $http->delete($url, $data, $headers); + + if($result !== false) { + $result = self::PERSIST_SUCCESS; + } else { + $result = self::PERSIST_FAILURE; + } + } + + return $result; + } + + protected function _getHttpClient() + { + if(!($this->__http instanceof KHttpClientInterface)) + { + $this->__http = $this->getObject($this->__http); + + if(!$this->__http instanceof KHttpClientInterface) + { + throw new UnexpectedValueException( + 'Http client: '.get_class($this->__http).' does not implement KHttpClientInterface' + ); + } + } + + return $this->__http; + } + + protected function _getHttpData($url, $cache = true, $path = null) + { + $http = $this->_getHttpClient(); + + try + { + $key = md5((string) $url); + + if(!isset(self::$__resource_cache[$key])) + { + $headers = $this->getHeaders($cache); + $data = $http->get($url, $headers); + + self::$__resource_cache[$key] = $data; + } + else $data = self::$__resource_cache[$key]; + } + catch(KHttpException $e) + { + //Re-throw exception if in debug mode + if($http->isDebug()) { + throw $e; + } else { + $data = array(); + } + } + + if($path) + { + if(is_string($path)) { + $segments = explode('/', $path); + } else { + $segments = KObjectConfig::unbox($path); + } + + foreach($segments as $segment) + { + if(!isset($data[$segment])) { + $data = array(); break; + } else { + $data = $data[$segment]; + } + } + } + + return $data; + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/object/config/config.php b/Sites/pages/components/com_pages/object/config/config.php new file mode 100644 index 00000000..39b8a988 --- /dev/null +++ b/Sites/pages/components/com_pages/object/config/config.php @@ -0,0 +1,63 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesObjectConfig extends KObjectConfig implements JsonSerializable +{ + public function get($name, $default = null) + { + if(!is_array($name)) { + $segments = explode('/', $name); + } else { + $segments = $name; + } + + $result = parent::get(array_shift($segments), $default); + + if(!empty($segments) && $result instanceof KObjectConfigInterface) { + $result = $result->get($segments, $default); + } + + return $result; + } + + public function has($name) + { + return (bool) $this->get($name); + } + + public function toString() + { + $json = new ComPagesObjectConfigJson($this); + return $json->toString(); + } + + public function jsonSerialize() + { + return $this->toArray(); + } + + final public function __toString() + { + $result = ''; + + //Not allowed to throw exceptions in __toString() See : https://bugs.php.net/bug.php?id=53648 + try { + $result = $this->toString(); + } catch (Exception $e) { + trigger_error('ComPagesObjectConfig::__toString exception: '. (string) $e, E_USER_ERROR); + } + + return $result; + } + + public function __debugInfo() + { + return self::unbox($this); + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/object/config/csv.php b/Sites/pages/components/com_pages/object/config/csv.php new file mode 100644 index 00000000..904e540a --- /dev/null +++ b/Sites/pages/components/com_pages/object/config/csv.php @@ -0,0 +1,93 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesObjectConfigCsv extends KObjectConfigFormat +{ + /** + * The format + * + * @var string + */ + protected static $_format = 'text/csv'; + + /** + * Character used for enclosing fields + * + * @var string + */ + const ENCLOSURE = '"'; + + /** + * Character used for separating fields + * + * @var string + */ + const DELIMITER = ','; + + /** + * The escape character + * + * @var string + */ + const ESCAPE_CHAR = '\\'; + + /** + * Read from a CSV string and create a config object + * + * @param string $string + * @param bool $object If TRUE return a ConfigObject, if FALSE return an array. Default TRUE. + * @throws DomainException + * @throws RuntimeException + * @return KObjectConfigCsv|array + */ + public function fromString($string, $object = true) + { + $data = preg_split("/\r\n|\n|\r/", trim($string)); + + //Parse the csv + array_walk($data, function(&$row) { + $row = str_getcsv($row, static::DELIMITER, static::ENCLOSURE, static::ESCAPE_CHAR); + }); + + //Get the header + $header = array_shift($data); + + //Combine row and header + array_walk($data, function(&$row) use ($header) { + $row = array_combine($header, array_map('trim', $row)); + }); + + return $object ? $this->merge($data) : $data; + } + + /** + * Write a config object to a CSV string. + * + * @return string|false Returns a CSV encoded string on success. False on failure. + */ + public function toString() + { + $result = array(); + + if($data = $this->toArray()) + { + $fp = fopen('php://temp', 'r+b'); + + fputcsv($fp, array_keys($data[0]), static::DELIMITER, static::ENCLOSURE, static::ESCAPE_CHAR); + foreach($data as $row) { + fputcsv($fp, $row, static::DELIMITER, static::ENCLOSURE, static::ESCAPE_CHAR); + } + + $result = rtrim(stream_get_contents($fp), "\n"); + fclose($fp); + } + + return $result; + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/object/config/frontmatter.php b/Sites/pages/components/com_pages/object/config/frontmatter.php new file mode 100644 index 00000000..2e6181f5 --- /dev/null +++ b/Sites/pages/components/com_pages/object/config/frontmatter.php @@ -0,0 +1,110 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesObjectConfigFrontmatter extends KObjectConfigYaml +{ + private $__content = ''; + private $__filename = ''; + private $__hash = ''; + + public function fromFile($filename, $object = true) + { + //Store the filename + $this->__filename = $filename; + + return parent::fromFile($filename, $object); + } + + public function fromString($string, $object = true) + { + // Calculate the hash + $this->__hash = hash("crc32b", $string); + + // Normalize line endings to Unix style. + $string = preg_replace("/(\r\n|\r)/", "\n", $string); + + if (strpos($string, "---") !== false) + { + if(preg_match('#^\s*---(.*|[\s\S]*)\s*---#siU', $string, $matches)) + { + $data = parent::fromString($matches[1], false); + + //Handle dynamic data + array_walk_recursive ($data, function(&$value, $key) + { + if(is_string($value) && strpos($value, 'data://') === 0) + { + $matches = array(); + preg_match('#data\:\/\/([^\[]+)(?:\[(.*)\])*#si', $value, $matches); + + if(!empty($matches[0])) + { + $data = Koowa::getObject('data.registry') + ->fromPath($matches[1]); + + if($data && !empty($matches[2])) { + $data = $data->get($matches[2]); + } + + $value = $data; + } + } + }); + + $this->merge($data); + } + + $this->setContent(str_replace($matches[0], '', $string)); + } + else $this->setContent($string); + + return $object ? $this : $this->toArray(); + } + + public function toString() + { + $string = $this->getContent(); + + //Add frontmatter + if($this->count()) { + $string = "---\n" . trim(parent::toString()) . "\n---\n\n" . $string; + } + + // Normalize line endings to Unix style. + $string = preg_replace("/(\r\n|\r)/", "\n", $string); + + return $string; + } + + public function getContent() + { + return $this->__content; + } + + public function setContent($content) + { + $this->__content = trim($content); + return $this; + } + + public function getFilename() + { + return $this->__filename; + } + + public function getFiletype() + { + return pathinfo($this->getFilename(), PATHINFO_EXTENSION); + } + + public function getHash() + { + return $this->__hash; + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/object/config/html.php b/Sites/pages/components/com_pages/object/config/html.php new file mode 100644 index 00000000..94283e86 --- /dev/null +++ b/Sites/pages/components/com_pages/object/config/html.php @@ -0,0 +1,82 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesObjectConfigHtml extends ComPagesObjectConfigXml +{ + protected static $_format = 'text/html'; + + public function fromString($string, $object = true) + { + $data = array(); + + if(!empty($string)) + { + $dom = new DOMDocumentHtml('1.0', 'UTF-8'); + libxml_use_internal_errors(true); + + $dom->normalizeDocument(); + $dom->preserveWhiteSpace = false; + + if($dom->loadHtml($string, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD | LIBXML_NOBLANKS) === false) { + throw new DomainException('Cannot parse HTML string'); + } + + libxml_use_internal_errors(false); + + $data = $this->_domToArray($dom); + } + + return $object ? $this->merge($data) : $data; + } + + public function toString() + { + return $this->toDom()->saveHTML(); + } + + public function toDom() + { + $data = $this->toArray(); + + $dom = new DOMDocumentHtml('1.0', 'UTF-8'); + $dom->preserveWhiteSpace = false; + $dom->formatOutput = true; + + $this->_arrayToDom($dom, $dom, $data); + + return $dom; + } +} + +class DomDocumentHtml extends DOMDocument +{ + private $__xpath; + + public function __toString() { + return parent::safeHTML(); + } + + public function query($expression) + { + if(!isset($this->__xpath)) { + $this->__xpath = new DOMXPath($this); + } + + return $this->__xpath->query($expression); + } + + public function evaluate($expression) + { + if(!isset($this->__xpath)) { + $this->__xpath = new DOMXPath($this); + } + + return $this->__xpath->evaluate($expression); + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/object/config/json.php b/Sites/pages/components/com_pages/object/config/json.php new file mode 100644 index 00000000..6bd5df69 --- /dev/null +++ b/Sites/pages/components/com_pages/object/config/json.php @@ -0,0 +1,46 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesObjectConfigJson extends KObjectConfigJson +{ + protected static $_media_type = 'application/vnd.api+json'; + + public function fromString($string, $object = true) + { + $data = parent::fromString($string, false); + + //Transparently handle json api + $result = array(); + if(isset($data['data'])) + { + $data = $data['data']; + + //Collection + if(is_numeric(key($data))) + { + foreach($data as $key => $item) + { + if($item['id']) { + $result[$key] = ['id' => $item['id']] + $item['attributes']; + } + } + } + //Resource + else + { + if($data['id']) { + $result = ['id' => $data['id']] + $data['attributes']; + } + } + } + else $result = $data; + + return $object ? $this->merge($result) : $result; + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/object/config/markdown.php b/Sites/pages/components/com_pages/object/config/markdown.php new file mode 100644 index 00000000..046a9c3c --- /dev/null +++ b/Sites/pages/components/com_pages/object/config/markdown.php @@ -0,0 +1,24 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesObjectConfigMarkdown extends ComPagesObjectConfigFrontmatter +{ + protected static $_media_type = 'text/markdown'; + + public function setContent($content) + { + $this->content = \Michelf\MarkdownExtra::defaultTransform($content); + return $this; + } + + public function getContent() + { + return $this->content; + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/object/config/xml.php b/Sites/pages/components/com_pages/object/config/xml.php new file mode 100644 index 00000000..0f659d38 --- /dev/null +++ b/Sites/pages/components/com_pages/object/config/xml.php @@ -0,0 +1,213 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesObjectConfigXml extends KObjectConfigXml +{ + public function fromString($string, $object = true) + { + $data = array(); + + if(!empty($string)) + { + $dom = new DOMDocumentXml('1.0', 'UTF-8'); + $dom->preserveWhiteSpace = false; + + if($dom->loadXml($string) === false) { + throw new DomainException('Cannot parse XML string'); + } + + $data = $this->_domToArray($dom); + } + + return $object ? $this->merge($data) : $data; + } + + public function toString() + { + return $this->toDom()->saveXML(); + } + + public function toDom() + { + $data = $this->toArray(); + + $dom = new DOMDocumentXml('1.0', 'UTF-8'); + $dom->preserveWhiteSpace = false; + $dom->formatOutput = true; + + $this->_arrayToDom($dom, $dom, $data); + + return $dom; + } + + protected function _domToArray(DomNode $node) + { + $result = array(); + + if ($node->hasAttributes()) + { + $attributes = $node->attributes; + foreach ($attributes as $attribute) { + $result['@attributes'][$attribute->name] = $attribute->value; + } + } + + if ($node->hasChildNodes()) + { + $children = $node->childNodes; + if ($children->length == 1) + { + $child = $children->item(0); + if (in_array($child->nodeType, [XML_TEXT_NODE, XML_CDATA_SECTION_NODE])) + { + $result['@value'] = $child->nodeValue; + return count($result) == 1 ? $result['@value'] : $result; + } + } + + $groups = array(); + foreach ($children as $child) + { + if($child->nodeType == XML_TEXT_NODE) + { + if(!ctype_space($child->nodeValue)) { + $result['@text'] = $child->nodeValue; + } + + continue; + } + + if($child->nodeType == XML_COMMENT_NODE) + { + if(!ctype_space($child->nodeValue)) { + $result['@comment'] = $child->nodeValue; + } + + continue; + } + + if (isset($result[$child->nodeName]) && $result[$child->nodeName]) + { + if (!isset($groups[$child->nodeName])) + { + $result[$child->nodeName] = array($result[$child->nodeName]); + $groups[$child->nodeName] = 1; + } + + $result[$child->nodeName][] = $this->_domToArray($child); + } + else $result[$child->nodeName] = $this->_domToArray($child); + } + } + + return $result; + } + + protected function _arrayToDom(DOMDocument $xml, $node, $data) + { + //Create value and attributes + if (is_array($data)) + { + // get the attributes first.; + if (array_key_exists('@attributes', $data) && is_array($data['@attributes'])) + { + if(!$node instanceof DOMDocument) + { + foreach ($data['@attributes'] as $key => $value) { + $node->setAttribute($key, $this->_encodeValue($value)); + } + } + + unset($data['@attributes']); + } + + if (array_key_exists('@value', $data)) + { + if(!$node instanceof DOMDocument) + { + $node->appendChild($xml->createTextNode($this->_encodeValue($data['@value']))); + unset($data['@value']); + } + + return $node; + } + } + + //Create subnodes using recursion + if (is_array($data)) + { + // recurse to get the node for that key + foreach ($data as $key => $value) + { + if (is_array($value) && is_numeric(key($value))) + { + foreach ($value as $k => $v) { + $node->appendChild($this->_arrayToDom($xml, $xml->createElement($key), $v)); + } + } + else + { + if($key == '@text') { + $node->appendChild($xml->createTextNode($value)); + } elseif($key == '@comment') { + $node->appendChild($xml->createComment($value)); + } else { + $node->appendChild($this->_arrayToDom($xml, $xml->createElement($key), $value)); + } + } + + unset($data[$key]); //remove the key from the array once done. + } + } + + //Append any text values + if (!is_array($data)) { + $node->appendChild($xml->createTextNode($this->_encodeValue($data))); + } + + return $node; + } + + + protected function _encodeValue($value) + { + //Convert boolean to text value + $value = $value === true ? 'true' : $value; + $value = $value === false ? 'false' : $value; + + return $value; + } +} + +class DomDocumentXml extends DOMDocument +{ + private $__xpath; + + public function __toString() { + return parent::saveXML(); + } + + public function query($expression) + { + if(!isset($this->__xpath)) { + $this->__xpath = new DOMXPath($this); + } + + return $this->__xpath->query($expression); + } + + public function evaluate($expression) + { + if(!isset($this->__xpath)) { + $this->__xpath = new DOMXPath($this); + } + + return $this->__xpath->evaluate($expression); + } +} diff --git a/Sites/pages/components/com_pages/object/debuggable.php b/Sites/pages/components/com_pages/object/debuggable.php new file mode 100644 index 00000000..9e1dee22 --- /dev/null +++ b/Sites/pages/components/com_pages/object/debuggable.php @@ -0,0 +1,57 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +trait ComPagesObjectDebuggable +{ + public function __debugInfo() + { + if($this instanceof Traversable || method_exists($this, 'toArray')) + { + if(method_exists($this, 'toArray')) { + $properties = $this->toArray(); + } else { + $properties = iterator_to_array($this->getIterator()); + } + } + else $properties= get_object_vars($this); + + array_walk_recursive($properties, function(&$property, $key) + { + if(is_object($property)) + { + //Call __debugInfo and use result + if(method_exists($property, '__debugInfo')) + { + ob_start(); + var_dump($property); + $debug_info = ob_get_contents(); + ob_end_clean(); + + $property = $debug_info; + } + //Cast to string if possible + elseif(method_exists($property, '__toString')){ + $property = (string) $property; + } + //Object identifier + elseif($property instanceof KObjectInterface) + { + $identifier = (string)$property->getIdentifier(); + $property = $identifier . ' :: (' . get_class($property) . ')'; + + } + //Class name + else $property = get_class($property); + } + }); + + return $properties; + } +} + diff --git a/Sites/pages/components/com_pages/object/locator/extension.php b/Sites/pages/components/com_pages/object/locator/extension.php new file mode 100644 index 00000000..c55cf8ba --- /dev/null +++ b/Sites/pages/components/com_pages/object/locator/extension.php @@ -0,0 +1,24 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesObjectLocatorExtension extends KObjectLocatorAbstract +{ + protected static $_name = 'ext'; + + protected function _initialize(KObjectConfig $config) + { + $config->append(array( + 'sequence' => array( + 'Ext', + ) + )); + + parent::_initialize($config); + } +} diff --git a/Sites/pages/components/com_pages/page/entity.php b/Sites/pages/components/com_pages/page/entity.php new file mode 100644 index 00000000..e6d91e2e --- /dev/null +++ b/Sites/pages/components/com_pages/page/entity.php @@ -0,0 +1,139 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesPageEntity extends ComPagesModelEntityPage implements ComPagesPageInterface +{ + protected function _initialize(KObjectConfig $config) + { + $config->append([ + 'data' => [ + 'redirect' => '', + 'process' => [ + 'filters' => [], + ], + 'layout' => array(), + 'colllection' => null, + 'form' => null, + ], + ]); + + parent::_initialize($config); + } + + public function get($name, $default = null) + { + if(!is_array($name)) { + $segments = explode('/', $name); + } else { + $segments = $name; + } + + $result = parent::get(array_shift($segments), $default); + + if(!empty($segments) && $result instanceof KObjectConfigInterface) { + $result = $result->get($segments, $default); + } + + return $result; + } + + public function has($name) + { + return (bool) $this->get($name); + } + + public function setPropertyLayout($value) + { + if($value) { + $value = new ComPagesObjectConfig($value); + } + + return $value; + } + + public function setPropertyCollection($value) + { + if($value) { + $value = new ComPagesObjectConfig($value); + } + + return $value; + } + + public function setPropertyForm($value) + { + if($value) { + $value = new ComPagesObjectConfig($value); + } + + return $value; + } + + public function setPropertyProcess($value) + { + if($value) { + $value = new ComPagesObjectConfig($value); + } + + return $value; + } + + public function getType() + { + $type = 'page'; + + if($this->isCollection()) { + $type = 'collection'; + } + + if($this->isForm()) { + $type = 'form'; + } + + if($this->isDecorator()) { + $type = 'decorator'; + } + + if($this->isRedirect()) { + $type = 'redirect'; + } + + return $type; + } + + public function isRedirect() + { + return $this->redirect ? $this->redirect : false; + } + + public function isCollection() + { + return $this->collection ? $this->collection : false; + } + + public function isForm() + { + return $this->form ? $this->form : false; + } + + public function isDecorator() + { + return (bool) $this->process->get('decorate', false) !== false; + } + + public function isSubmittable() + { + return $this->isForm() && isset($this->form->schema); + } + + public function isEditable() + { + return $this->isCollection() && isset($this->collection->schema); + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/page/interface.php b/Sites/pages/components/com_pages/page/interface.php new file mode 100644 index 00000000..685b0779 --- /dev/null +++ b/Sites/pages/components/com_pages/page/interface.php @@ -0,0 +1,21 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +interface ComPagesPageInterface +{ + public function getType(); + + public function isRedirect(); + public function isForm(); + public function isCollection(); + public function isDecorator(); + + public function isSubmittable(); + public function isEditable(); +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/page/locator.php b/Sites/pages/components/com_pages/page/locator.php new file mode 100644 index 00000000..1e345cc2 --- /dev/null +++ b/Sites/pages/components/com_pages/page/locator.php @@ -0,0 +1,58 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesPageLocator extends KTemplateLocatorFile +{ + protected static $_name = 'page'; + + protected function _initialize(KObjectConfig $config) + { + $config->append([ + 'base_path' => $this->getObject('com://site/pages.config')->getSitePath(), + ]); + + parent::_initialize($config); + } + + public function find(array $info) + { + $path = ltrim(str_replace(parse_url($info['url'], PHP_URL_SCHEME).'://', '', $info['url']), '/'); + + $file = pathinfo($path, PATHINFO_FILENAME); + $format = pathinfo($path, PATHINFO_EXTENSION) ?: 'html'; + $path = ltrim(pathinfo($path, PATHINFO_DIRNAME), '.'); + + //Prepend the base path + if($path) { + $path = $this->getBasePath().'/'.$path; + } else { + $path = $this->getBasePath(); + } + + if($this->realPath($path.'/'.$file)) { + $pattern = $path.'/'.$file.'/index.'.$format.'*'; + } else { + $pattern = $path.'/'.$file.'.'.$format.'*'; + } + + //Try to find the file + $result = false; + if ($results = glob($pattern)) + { + foreach($results as $file) + { + if($result = $this->realPath($file)) { + break; + } + } + } + + return $result; + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/page/object.php b/Sites/pages/components/com_pages/page/object.php new file mode 100644 index 00000000..a89718ad --- /dev/null +++ b/Sites/pages/components/com_pages/page/object.php @@ -0,0 +1,91 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesPageObject extends ComPagesObjectConfigFrontmatter implements ComPagesPageInterface +{ + public function get($name, $default = null) + { + if(!is_array($name)) { + $segments = explode('/', $name); + } else { + $segments = $name; + } + + $result = parent::get(array_shift($segments), $default); + + if(!empty($segments) && $result instanceof KObjectConfigInterface) { + $result = $result->get($segments, $default); + } + + return $result; + } + + public function has($name) + { + return (bool) $this->get($name); + } + + public function getType() + { + $type = 'page'; + + if($this->isCollection()) { + $type = 'collection'; + } + + if($this->isForm()) { + $type = 'form'; + } + + if($this->isDecorator()) { + $type = 'decorator'; + } + + if($this->isRedirect()) { + $type = 'redirect'; + } + + return $type; + } + + public function isRedirect() + { + return isset($this->redirect) && $this->redirect !== false ? KObjectConfig::unbox($this->redirect) : false; + } + + public function isForm() + { + return isset($this->form) && $this->form !== false ? KObjectConfig::unbox($this->form) : false; + } + + public function isCollection() + { + return isset($this->collection) && $this->collection !== false ? KObjectConfig::unbox($this->collection) : false; + } + + public function isDecorator() + { + return (bool) $this->process->get('decorate', false) !== false; + } + + public function isSubmittable() + { + return $this->isForm() && isset($this->form->schema); + } + + public function isEditable() + { + return $this->isCollection() && isset($this->collection->schema); + } + + public function __debugInfo() + { + return self::unbox($this); + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/page/page.php b/Sites/pages/components/com_pages/page/page.php new file mode 100644 index 00000000..08776f6e --- /dev/null +++ b/Sites/pages/components/com_pages/page/page.php @@ -0,0 +1,19 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesPage extends ComPagesPageEntity implements KObjectSingleton +{ + public function __construct(KObjectConfig $config) + { + parent::__construct($config); + + //Add a global object alias + $this->getObject('manager')->registerAlias($this->getIdentifier(), 'page'); + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/page/registry.php b/Sites/pages/components/com_pages/page/registry.php new file mode 100644 index 00000000..855628a3 --- /dev/null +++ b/Sites/pages/components/com_pages/page/registry.php @@ -0,0 +1,598 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesPageRegistry extends KObject implements KObjectSingleton +{ + const PAGES_TREE = \RecursiveIteratorIterator::SELF_FIRST; + const PAGES_ONLY = \RecursiveIteratorIterator::CHILD_FIRST; + + private $__locator = null; + + private $__pages = array(); + private $__data = null; + private $__collections = array(); + private $__redirects = array(); + private $__hashes = array(); + private $__entities = array(); + + public function __construct(KObjectConfig $config) + { + parent::__construct($config); + + //Create the locator + $this->__locator = $this->getObject('com://site/pages.page.locator'); + + //Load the cache and do not refresh it + $basedir = $this->getLocator()->getBasePath().'/pages'; + $this->__data = $this->loadCache($basedir, false); + + //Set the collection + $this->__collections = array_merge(KObjectConfig::unbox($config->collections), $this->__data['collections']); + + //Set the redirects + $this->__redirects = array_merge(KObjectConfig::unbox($config->redirects), $this->__data['redirects']); + } + + protected function _initialize(KObjectConfig $config) + { + $config->append([ + 'cache' => JDEBUG ? false : true, + 'cache_path' => $this->getObject('com://site/pages.config')->getSitePath('cache'), + 'cache_validation' => true, + 'collections' => array('pages' => ['model' => 'com://site/pages.model.pages']), + 'redirects' => array(), + 'properties' => array(), + ]); + + parent::_initialize($config); + } + + public function getHash($path = null) + { + $result = null; + + if($path) + { + $size = function($path) use(&$size) + { + $result = array(); + + if (is_dir($path)) + { + $files = array_diff(scandir($path), array('.', '..', '.DS_Store')); + + foreach ($files as $file) + { + if (is_dir($path.'/'.$file)) { + $result[$file] = $size($path .'/'.$file); + } else { + $result[$file] = sprintf('%u', filemtime($path .'/'.$file)); + } + } + } + else $result[basename($path)] = sprintf('%u', filemtime($path)); + + return $result; + }; + + if(file_exists($path)) + { + if(!isset($this->__hashes[$path])) { + $this->__hashes[$path] = hash('crc32b', serialize($size($path))); + } + + $result = $this->__hashes[$path]; + } + } + else $result = $this->__data['hash']; + + return $result; + } + + public function getLocator() + { + return $this->__locator; + } + + public function getCollection($name) + { + $result = false; + + if(isset($this->__collections[$name])) + { + $result = new ComPagesObjectConfig($this->__collections[$name]); + + //If the collections extends another collection merge it + if(isset($result->extend)) + { + if(!$extend = $this->getCollection($result->extend)) + { + throw new RuntimeException( + sprintf('Cannot extend from collection. No collection defined in: %s', $result->extend) + ); + } + + //Merge state + if($extend->has('state')) { + $extend->state->merge($result->get('state', array())); + } else { + $extend->state = $result->get('state'); + } + + //Merge page + if($extend->has('page')) { + $extend->page->merge($result->get('page', array())); + } else { + $extend->page = $result->get('page'); + } + + //Merge type + if($result->has('type')) { + $extend->type = $result->get('type'); + } + + $result = $extend; + } + + if(!isset($result->model)) { + $result->model = 'com://site/pages.model.pages'; + } + } + else + { + //Assume we are being passed a fully qualified identifier + if(is_string($name) && strpos($name, ':') !== false) { + $result = new ComPagesObjectConfig(['model' => $name]); + } + } + + return $result; + } + + public function getRedirects() + { + return $this->__redirects; + } + + public function getPages($path = '', $mode = self::PAGES_ONLY, $depth = -1) + { + $result = array(); + $files = $this->__data['files']; + + if($path = trim($path, '.')) + { + $segments = array(); + foreach(explode('/', $path) as $segment) + { + $segments[] = $segment; + if(!isset($files[implode('/', $segments)])) + { + $files = false; + break; + } + else $files = $files[implode('/', $segments)]; + } + } + + if(is_array($files)) + { + $iterator = new RecursiveArrayIterator($files); + $iterator = new RecursiveIteratorIterator($iterator, $mode); + + //Set the max dept, -1 for full depth + $iterator->setMaxDepth($depth); + + foreach ($iterator as $page => $file) + { + if(!is_string($file)) + { + //Do not include a directory without an index file (no existing page) + if(!$file = $this->getLocator()->locate('page://pages/'. $page)) { + continue; + } + } + + //Get the relative file path + $basedir = $this->getLocator()->getBasePath().'/pages'; + $file = trim(str_replace($basedir, '', $file), '/'); + + $result[$page] = $this->__data['pages'][$file]; + } + } + + return $result; + } + + public function getPage($path) + { + $page = false; + + $path = ltrim($path, './'); + + if(!isset($this->__pages[$path])) + { + if($file = $this->getLocator()->locate('page://pages/'. $path)) + { + //Get the relative file path + $basedir = $this->getLocator()->getBasePath().'/pages'; + $file = trim(str_replace($basedir, '', $file), '/'); + + //Load the page + $page = new ComPagesPageObject($this->__data['pages'][$file]); + + //Get the parent + $parent_path = trim(dirname($page->path), '.'); + + //Set page default properties from parent collection + if(!$page->isCollection() && $parent_path && $parent_page = $this->getPage($parent_path)) + { + if($parent_page->isCollection() && $parent_page->has('collection/page')) + { + foreach($parent_page->get('collection/page') as $property => $value) { + $page->set($property, $value); + } + } + } + + //Set the layout (if not set yet) + if($page->has('layout')) + { + if (is_string($page->layout)) { + $page->layout = new ComPagesObjectConfig(['path' => $page->layout]); + } else { + $page->layout = new ComPagesObjectConfig($page->layout); + } + } + + //Get the collection + if($page->isCollection()) { + $page->collection = $this->getCollection($page->path); + } + + $this->__pages[$path] = $page; + } + else $this->__pages[$path] = false; + } + + if (isset($this->__pages[$path])) { + $page = $this->__pages[$path]; + } + + return $page; + } + + public function getPageContent($path, $render = false) + { + $content = false; + + if($path instanceof ComPagesPageObject) { + $path = $path->path; + } + + if($render) + { + $template = $this->getObject('com://site/pages.template.default'); + + //Load and render the page + if($template->loadFile('page://pages/'.$path)) + { + $content = $template->render(KObjectConfig::unbox($template->getData())); + + //Remove filter tags + $content = preg_replace('#]*)>#siU', '', $content); + } + } + else + { + $file = $this->getObject('template.locator.factory')->locate('page://pages/'.$path); + $page = (new ComPagesObjectConfigFrontmatter())->fromFile($file); + + $content = $page->getContent(); + } + + return $content; + } + + public function getPageEntity($path) + { + $entity = null; + + if($page = $this->getPage($path)) + { + if(!isset($this->__entities[$path])) { + $this->__entities[$path] = $this->getObject('com://site/pages.page.entity', ['data' => $page]); + } + + $entity = $this->__entities[$path]; + } + + return $entity; + } + + public function getRoutes($path = null) + { + if(!is_null($path)) { + $result = $this->__data['routes'][$path]; + } else { + $result = $this->__data['routes']; + } + + return $result; + } + + public function isPage($path) + { + if(!isset($this->__pages[$path])) { + $result = (bool) $this->getLocator()->locate('page://pages/'. $path); + } else { + $result = ($this->__pages[$path] === false) ? false : true; + } + + return $result; + } + + public function loadCache($basedir, $refresh = true) + { + if ($refresh || (!$cache = $this->isCached($basedir))) + { + $pages = array(); + $routes = array(); + $collections = array(); + $redirects = array(); + + //Create the data + $iterate = function ($dir) use (&$iterate, $basedir, &$pages, &$routes, &$collections, &$redirects) + { + $order = false; + $nodes = array(); + $files = array(); + + //Only include pages + if(is_dir($dir) && !file_exists($dir.'/.ignore')) + { + //List + foreach (new DirectoryIterator($dir) as $node) + { + if (strpos($node->getFilename(), '.order.') !== false && !is_array($order)) { + $order = $this->getObject('object.config.factory')->fromFile((string)$node->getFileInfo(), false); + } else { + $nodes[] = $node->getFilename(); + } + } + + if(is_array($order)) { + //Remove files that don't exist from ordering (to prevent loops) + $nodes = array_merge(array_intersect($order, $nodes), $nodes); + } else { + //Order the files alphabetically + natsort($nodes); + } + + //Prevent duplicates + if ($nodes = array_unique($nodes)) + { + foreach ($nodes as $node) + { + //Exclude files or folder that start with '.' or '_' + if (!in_array($node[0], array('.', '_'))) + { + $info = pathinfo($node); + + $file = $dir . '/' . $node; + $path = trim(str_replace($basedir, '', $dir . '/' . $info['filename']), '/'); + + if (isset($info['extension'])) + { + /** + * Variables + * + * Calculate the path specific variables + */ + $format = pathinfo($path, PATHINFO_EXTENSION) ?: $info['extension']; + $slug = pathinfo($path, PATHINFO_FILENAME); + + //Handle format + $path = str_replace('.'.$format, '', $path); + $path = $format != 'html' ? $path.'.'.$format : $path; + + //Handle index pages + if($slug == 'index') + { + $path = str_replace(array('/index', 'index'), '', $path); + $slug = pathinfo($path, PATHINFO_FILENAME); + } + + /** + * Page + * + * Load and initialise the page object + */ + $page = (new ComPagesPageObject())->fromFile($file); + + //Append the page properties + $page->append($this->getConfig()->properties); + + //Set the path + $page->path = $path; + + //Set the slug + $page->slug = $slug; + + //Set the format + $page->format = $format; + + //Set the hash + $page->hash = $page->getHash(); + + //Set the process + if (!$page->process) { + $page->process = array(); + } + + //Set the route + if (!$page->route && $page->route !== false) { + $page->route = $path; + } + + //Set the date (if not set yet) + if (!isset($page->date)) { + $page->date = filemtime($file); + } + + //Set the process + if (!$page->language) { + $page->language = 'en-GB'; + } + + //Set the metadata + if(!$page->metadata) { + $page->metadata = array(); + } + + //Set robots metadata + if(!isset($page->metadata['robots'])) + { + if (!$page->getContent() && !$page->layout) { + $page->metadata['robots'] = ['none']; + } else { + $page->metadata['robots'] = array(); + } + } + else $page->metadata['robots'] = (array) $page->metadata['robots']; + + /** + * Cache + * + * Inject data into the cache + */ + $file = trim(str_replace($basedir, '', $file), '/'); + + //Page + $pages[$file] = $page->toArray(); + + //Route + if($page->route !== false) + { + $routes[$path] = (array) KObjectConfig::unbox($page->route); + unset($page->route); + } + + //File (do not include index pages) + if(strpos($file, '/index') === false) { + $files[$path] = $file; + } + + //Collection + if($collection = $page->isCollection()) { + $collections[$path] = KObjectConfig::unbox($collection); + } + + //Redirects + if($page->redirect) { + $redirects[$path] = $page->redirect; + } + } + else + { + //Iterate over path + if($result = $iterate($file)) { + $files[$path] = $result; + } + } + } + } + } + + return $files; + } + else return false; + }; + + Closure::bind($iterate, $this, get_class()); + + $result['files'] = $iterate($basedir); + $result['pages'] = $pages; + $result['routes'] = $routes; + $result['collections'] = $collections; + $result['redirects'] = array_flip($redirects); + + //Calculate the hash + if($this->getConfig()->cache && $this->getConfig()->cache_validation) { + $result['hash'] = $this->getHash($basedir); + } + + $this->storeCache($basedir, $result); + } + else + { + if (!$result = require($cache)) { + throw new RuntimeException(sprintf('The page registry "%s" cannot be loaded from cache.', $cache)); + } + + //Check if the cache is still valid, if not refresh it + if($this->getConfig()->cache_validation && $result['hash'] != $this->getHash($basedir)) { + $this->loadCache($basedir, true); + } + } + + return $result; + } + + public function storeCache($file, $data) + { + if($this->getConfig()->cache) + { + $path = $this->getConfig()->cache_path; + + if(!is_dir($path) && (false === @mkdir($path, 0777, true) && !is_dir($path))) { + throw new RuntimeException(sprintf('The page registry cache path "%s" does not exist', $path)); + } + + if(!is_writable($path)) { + throw new RuntimeException(sprintf('The page registry cache path "%s" is not writable', $path)); + } + + if(!is_string($data)) + { + $result = 'getConfig()->cache_path.'/page_'.$hash.'.php'; + + if(@file_put_contents($file, $result) === false) { + throw new RuntimeException(sprintf('The page registry cannot be cached in "%s"', $file)); + } + + //Override default permissions for cache files + @chmod($file, 0666 & ~umask()); + + return $file; + } + + return false; + } + + public function isCached($file) + { + $result = false; + + if($this->getConfig()->cache) + { + $hash = crc32($file.PHP_VERSION); + $cache = $this->getConfig()->cache_path.'/page_'.$hash.'.php'; + $result = is_file($cache) ? $cache : false; + } + + return $result; + } + + +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/page/trait.php b/Sites/pages/components/com_pages/page/trait.php new file mode 100644 index 00000000..5f167dd3 --- /dev/null +++ b/Sites/pages/components/com_pages/page/trait.php @@ -0,0 +1,42 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +trait ComPagesPageTrait +{ + private $__page; + + public function setPage($page) + { + $this->__page = $page; + return $this; + } + + public function getPage($path = null) + { + if(is_null($path)) + { + if(!$this->__page instanceof ComPagesPageInterface) + { + $this->__page = $this->getObject($this->__page ?? 'page'); + + if(!$this->__page instanceof ComPagesPageInterface) + { + throw new UnexpectedValueException( + 'Page: '.get_class($this->__page).' does not implement ComPagesPageInterface' + ); + } + } + + $result = $this->__page; + } + else $result = $this->getObject('page.registry')->getPageEntity($path); + + return $result; + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/pages.php b/Sites/pages/components/com_pages/pages.php new file mode 100644 index 00000000..a64b4af2 --- /dev/null +++ b/Sites/pages/components/com_pages/pages.php @@ -0,0 +1,19 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +defined('_JEXEC') or die; +if (!class_exists('Koowa')) { + return; +} + +try { + Koowa::getObject('com://site/pages.dispatcher.http')->dispatch(); +} catch(Exception $exception) { + Koowa::getObject('exception.handler')->handleException($exception); +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/resources/config/bootstrapper.php b/Sites/pages/components/com_pages/resources/config/bootstrapper.php new file mode 100644 index 00000000..2d131853 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/config/bootstrapper.php @@ -0,0 +1,69 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +//Load config +if(file_exists(JPATH_CONFIGURATION.'/configuration-pages.php')) { + $config = (array) include JPATH_CONFIGURATION.'/configuration-pages.php'; +} else { + $config = array(); +} + +//Load config options +return [ + + 'priority' => KObjectBootstrapper::PRIORITY_HIGH, + 'aliases' => [ + 'router' => 'com://site/pages.dispatcher.router', + 'page' => 'com://site/pages.page', + 'page.registry' => 'com://site/pages.page.registry', + 'data.registry' => 'com://site/pages.data.registry', + 'model.factory' => 'com://site/pages.model.factory', + 'com://site/pages.version' => 'com://admin/pages.version', + ], + + 'identifiers' => [ + 'response' => [ + 'headers' => $config['headers'] ?? array(), + ], + 'object.config.factory' => [ + 'formats' => [ + 'md' => 'com://site/pages.object.config.markdown', + 'csv' => 'com://site/pages.object.config.csv', + 'json' => 'com://site/pages.object.config.json', + 'xml' => 'com://site/pages.object.config.xml', + 'html' => 'com://site/pages.object.config.html', + ], + ], + 'template.locator.factory' => [ + 'locators' => [ + 'com://site/pages.data.locator', + 'com://site/pages.page.locator', + 'com://site/pages.template.locator.theme' + ] + ], + 'template.engine.factory' => [ + 'engines' => [ + 'lib:template.engine.markdown', + ] + ], + 'event.subscriber.factory' => [ + 'subscribers' => [ + 'com://site/pages.event.subscriber.bootstrapper', + 'com://site/pages.event.subscriber.dispatcher', + 'com://site/pages.event.subscriber.pagedecorator', + 'com://site/pages.event.subscriber.exception', + 'com://site/pages.event.subscriber.staticcache', + 'com://site/pages.event.subscriber.prefetcher', + ] + ], + 'com://site/pages.dispatcher.router.site' => [ + 'routes' => isset($config['sites']) ? array_flip($config['sites']) : array(JPATH_ROOT.'/joomlatools-pages' => '[*]'), + ], + ] +]; \ No newline at end of file diff --git a/Sites/pages/components/com_pages/resources/config/site.php b/Sites/pages/components/com_pages/resources/config/site.php new file mode 100644 index 00000000..449b1852 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/config/site.php @@ -0,0 +1,71 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +return [ + + 'composer_path' => $config['composer_path'], + 'identifiers' => [ + 'com://site/pages.template.filter.asset' => [ + 'schemes' => $config['aliases'] ?? array() + ], + 'page.registry' => [ + 'cache' => $config['page_cache'], + 'cache_path' => $config['page_cache_path'], + 'cache_validation' => $config['page_cache_validation'], + 'collections' => $config['collections'], + 'redirects' => array_flip($config['redirects']), + 'properties' => $config['page'], + ], + 'data.registry' => [ + 'namespaces' => $config['data_namespaces'], + 'cache' => $config['data_cache'], + 'cache_path' => $config['data_cache_path'], + 'cache_validation' => $config['data_cache_validation'], + ], + 'template.engine.factory' => [ + 'cache' => $config['template_cache'], + 'cache_path' => $config['template_cache_path'], + 'cache_reload' => $config['template_cache_validation'], + ], + 'com://site/pages.dispatcher.behavior.cacheable' => [ + 'cache' => $config['http_cache'], + 'cache_path' => $config['http_cache_path'], + 'cache_time' => !is_null($config['http_cache_time_browser']) ? $config['http_cache_time_browser'] : $config['http_cache_time'], + 'cache_time_shared' => $config['http_cache_time'], + 'cache_control' => $config['http_cache_control'], + 'cache_control_private' => $config['http_cache_control_private'], + + ], + 'com://site/pages.http.cache' => [ + 'cache' => $config['http_resource_cache'], + 'cache_path' => $config['http_resource_cache_path'], + 'debug' => $config['http_resource_cache_debug'], + ], + 'com://site/pages.model.cache' => [ + 'cache_path' => $config['http_cache_path'], + ], + 'lib:template.engine.markdown' => [ + 'compiler' => function($text) { + //See: https://michelf.ca/projects/php-markdown/extra/ + return \Michelf\MarkdownExtra::defaultTransform($text); + } + ], + 'com://site/pages.template.filter.highlight' => [ + 'highlighter' => function($source, $language) { + //See: https://github.com/scrivo/highlight.php + return (new \Highlight\Highlighter())->highlight($language, $source, false)->value; + } + ], + 'com://site/pages.event.subscriber.staticcache' => [ + 'enable' => $config['http_static_cache'] && $config['http_cache'], + 'cache_path' => $config['http_static_cache_path'], + ], + ], + 'extensions' => $config['extensions'] ?? array(), +]; \ No newline at end of file diff --git a/Sites/pages/components/com_pages/resources/mason/revalidator.js b/Sites/pages/components/com_pages/resources/mason/revalidator.js new file mode 100644 index 00000000..76b0d6f4 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/mason/revalidator.js @@ -0,0 +1,320 @@ +const mason = require("@joomlatools/mason-tools-v1"); +const https = require("https"); +const http = require("http"); +const chalk = require("chalk"); + +class Revalidator { + options = { + origin: null, + endpoint: "/cache.json", + concurrency: 10, + force: false, + unauthorized: false, + headers: {}, + }; + + constructor(options = {}) { + this.options = { ...this.options, ...options }; + + //Turn off certificate validation for TLS connections (only needed for self-signed certs) + if (this.options.unauthorized) { + process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = 0; + } + } + + async revalidate(url, collections) { + const time = Date.now(); + + //Cache origin url + if (this.options.origin) { + const origin = new URL(this.options.origin); + + if (url) { + // Sanitize the url + if (url.indexOf("/") == 0) { + url = origin.origin + url; + } + + if (!/^https?:\/\//i.test(url)) { + url = origin.protocol + "//" + url; + } + } else url = this.options.origin; + } + + //Cache endpoint url + const cache = new URL(this.options.endpoint, url); + + //Filter:id + if (url) { + let page = new URL(url); + + if (url.substr(-1) == "/" || page.pathname.length > 1) { + cache.searchParams.set("id", page.pathname + page.search); + } + } + + //Filter:valid + if (!this.options.force) { + cache.searchParams.set("filter[valid]", "neq:true"); + } + + //Filter:collection + if (collections) { + if (collections instanceof Array) { + collections = collections.join(","); + } + + cache.searchParams.set("filter[collections]", "in:" + collections); + } + + //Request options + var options = { + headers: { + ...{ + "Cache-Control": "must-revalidate", + Accept: "text/html", + }, + ...this.options.headers, + }, + }; + + if (cache.username && cache.password) { + let authorization = new Buffer.from( + cache.username + ":" + cache.password + ).toString("base64"); + options.headers["Authorization"] = "Basic " + authorization; + } + + this.getRequest(cache, options) + .then((response) => { + var data = response.json(); + + //Check data + if (data["data"]) { + data = data["data"]; + } + + //Check status code + if (response.statusCode == 404) { + throw new Error("Url Not Cached"); + } + + //Check status code + if (response.statusCode !== 200) { + throw new Error(`Request Failed Status Code: ${response.statusCode}`); + } + + //Get request time + mason.log.debug( + "\n", + `${chalk.green("✔")} Cache fetched from: ${decodeURIComponent( + cache.toString() + )} - ${response.time()} s` + ); + + //Calculate the total elapsed time + let totalTime = () => { + let date = new Date(Date.now() - time); + let min = date.getUTCMinutes(); + let sec = date.getUTCSeconds(); + let ms = (date.getUTCMilliseconds() / 1000).toFixed(2) * 1000; + + return min + ":" + sec + "." + ms; + }; + + if (data.length != undefined) { + if (data.length > 0) { + mason.log.debug( + ` ${chalk.green("✔")} Revalidation started total: ${ + data.length + }, concurrency: ${this.options.concurrency}…` + ); + + // Async function to revalidate the cache with a concurrency limit + this.revalidateList(data, options).finally(() => { + mason.log.debug( + "\n", + chalk.bold(`Revalidation completed in ${totalTime()} min`) + ); + }); + } else mason.log.debug("\n", chalk.bold(`Cache is valid`)); + } else { + mason.log.debug( + ` ${chalk.green("✔")} Revalidation started, total: 1` + ); + + this.revalidateUrl(data["attributes"], options).finally(() => { + mason.log.debug( + "\n", + chalk.bold(`Revalidation completed in ${totalTime()} min`) + ); + }); + } + }) + .catch((error) => { + mason.log.error(error.message); + }); + } + + async revalidateList(list, options) { + for (let i = 0; i < list.length; i += this.options.concurrency) { + mason.log.debug(chalk.dim(" --- starting batch ---")); + const requests = list + .slice(i, i + this.options.concurrency) + .map((item) => { + return this.revalidateUrl(item["attributes"], options); + }); + + await Promise.allSettled(requests); + } + } + + async revalidateUrl(item, options) { + let url = item["url"]; + + let request = this.getRequest(url, options) + .then((response) => { + let time = response.time(); + let status = response.headers["cache-status"].toLowerCase(); + + if (!status.includes("hit") && !status.includes("identical")) { + if (status.includes("purged")) { + mason.log.debug( + chalk.red(" » Purged: " + url + " - " + time + " s") + ); + } else { + mason.log.debug(" » Regenerated: " + url + " - " + time + " s"); + } + } else + mason.log.debug( + chalk.gray(" » Not Modified: " + url + " - " + time + " s") + ); + }) + .catch((error) => { + mason.log.error("Failed: " + url + " with error: " + error.message); + }); + + return request; + } + + async getRequest(url, options) { + options = options || {}; + + let promise = new Promise((resolve, reject) => { + let callback = (response) => { + let data = ""; + + response.on("data", (chunk) => { + data += chunk; + }); + + response.on("end", () => { + response.data = data; + resolve(response); + }); + + response.on("error", (error) => { + reject(error); + }); + + response.json = () => { + return JSON.parse(data); + }; + + response.hash = () => { + let hash = null; + + if (response.headers.etag) { + hash = response.headers.etag.replace("-gzip", ""); + } + + return hash; + }; + + response.time = (metric = "tot") => { + let time = null; + let timing = response.timing(); + + if (timing[metric]) { + metric = timing[metric]; + time = (metric.dur / 1000).toFixed(2); + } + + return time; + }; + + response.timing = () => { + var timing = {}; + + if (response.headers["server-timing"]) { + let timings = response.headers["server-timing"].split(","); + + timings.forEach((metric) => { + metric = metric.split(";"); + + var values = {}; + var name = ""; + + metric.forEach((part) => { + if (part.includes("=")) { + var [key, value] = part.split("="); + values[key] = value.replace(/"/g, ""); + } else name = part; + }); + + if (name) { + timing[name] = values; + } + }); + } + + return timing; + }; + }; + + url = new URL(url); + + //Create the request based on the protocol + let protocol = url.protocol.replace(":", ""); + + if (protocol == "https") { + var request = https.get(url, options, callback); + } else { + var request = http.get(url, options, callback); + } + + request.on("error", (error) => { + reject(error); + }); + + request.end(); + }); + + return promise; + } +} + +async function revalidateCache(config = {}) { + const argv = require("yargs").argv; + + config = mason.config.merge( + { + force: argv.force, + unauthorized: argv.u, + concurrency: argv.concurrency != null ? argv.concurrency : 10, + headers: argv.headers != null ? argv.headers : {}, + }, + config + ); + + //Revaliate cache + const cache = new Revalidator(config); + + await cache.revalidate(argv._[1], argv.collections); +} + +module.exports = { + version: 1.0, + masonRevalidator: Revalidator, + revalidateCache, +}; diff --git a/Sites/pages/components/com_pages/resources/scripts/proxy.php b/Sites/pages/components/com_pages/resources/scripts/proxy.php new file mode 100644 index 00000000..bcfa37aa --- /dev/null +++ b/Sites/pages/components/com_pages/resources/scripts/proxy.php @@ -0,0 +1,183 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +/** + * Http Transparent Async Reverse Cache Proxy + * + * This anonymous function implements an async http cache proxy following the https://tools.ietf.org/html/rfc7234 + * specification. It supports an array based php file cache with 'headers', 'content' and 'status' properties. + * + * The proxy will return the resource from cache immediatly if it exists and validate it async in the background. + * This ensure that each request is equally fast. + * + * + * array (), + * 'content' => '', + * 'status' => '', + * ?> + * + * + * The proxy will forward any requests that are: + * - Not GET or HEAD + * - Contain Cache-Control directives + * + * The proxy offers Cache Validation using ETag + * + * @author Johan Janssens + * + * @param string $cache_path The path for the cache responses + * @param callable $callback The callback to execute the application + * @param integer $user The user identifier + */ +return function($cache_path = JPATH_ROOT.'/joomlatools-pages/cache/responses', callable $callback) +{ + ini_set('output_buffering', false); + ini_set('zlib.output_compression', false); + + //Do not process cache for none GET or HEAD requests + if(!in_array($_SERVER['REQUEST_METHOD'], ['GET', 'HEAD'])) + { + call_user_func($callback); + return false; + } + + //If request include cache control directives pass it on for validation + if(isset($_SERVER['HTTP_CACHE_CONTROL'])) + { + call_user_func($callback); + return false; + } + + //If the cache path doesn't exist + if(!file_exists($cache_path)) + { + call_user_func($callback); + return false; + } + + //Get the url + $host = filter_var($_SERVER['HTTP_HOST'], FILTER_SANITIZE_URL); + $request = filter_var($_SERVER['REQUEST_URI'], FILTER_SANITIZE_URL); + $parts = parse_url('https://'.$host.$request); + $url = trim($host.$request, '/'); + + //Get the format + $format = pathinfo($parts['path'], PATHINFO_EXTENSION) ?: ''; + + //Get the user + $hash = crc32($parts['path'].$parts['query']); + $file = $cache_path . '/response_' . $hash . '.php'; + + //Clear the cache for the specific file to avoid any errors. + clearstatcache (true, $parts); + + if (is_file($file)) + { + $data = require $file; + + $headers = $data['headers']; + $content = $data['content']; + $status = $data['status']; + + $max_age = false; + $age = max(time() - strtotime($headers['Date']), 0); + + //Check the cache is stale + if(isset($headers['Cache-Control'])) + { + $cache_control = explode(',', $headers['Cache-Control']); + + foreach ($cache_control as $key => $value) + { + if(is_string($value)) + { + $parts = explode('=', $value); + + if (count($parts) > 1) + { + unset( $cache_control[$key]); + $cache_control[trim($parts[0])] = trim($parts[1]); + } + } + } + + + if (isset($cache_control['max-age'])) { + $max_age = $cache_control['max-age']; + } + + if (isset($cache_control['s-maxage'])) { + $max_age = $cache_control['s-maxage']; + } + } + + //Divide the max_age in half and set it in the $_SERVER global + if(!strstr($headers['Cache-Status'], 'EXPIRED') && $max_age) { + $_SERVER['HTTP_CACHE_CONTROL'] = 'max-age='.(int) ($max_age / 2); + } + + //Cache validation + if(isset($_SERVER['HTTP_IF_NONE_MATCH']) && isset($headers['Etag'])) + { + $etags = preg_split('/\s*,\s*/', $_SERVER['HTTP_IF_NONE_MATCH'], null, PREG_SPLIT_NO_EMPTY); + + //RFC-7232 explicitly states that ETags should be content-coding aware + $etags = str_replace('-gzip', '', $etags); + + if(in_array($headers['Etag'], $etags) || in_array('*', $etags)) + { + http_response_code ('304'); + header('Cache-Status: HIT'); + + //Generating a 304 response MUST generate any of the following header fields that would have been sent + //in a 200 (OK) response to the same request: Cache-Control, Content-Location, Date, ETag and Vary + $required = ['Cache-Control', 'Content-Location', 'ETag', 'Vary']; + + foreach($required as $header) + { + if(isset($headers[$header])) { + header($header.': '.$headers[$header]); + } + } + + //Refresh the date + header('Date: '.date('D, d M Y H:i:s', strtotime('now')).' GMT'); + + //Revalidation the cache async + fastcgi_finish_request(); + call_user_func($callback); + + return true; + } + } + + //Send the headers + foreach ($headers as $name => $value) { + header($name . ': ' . $value); + } + + //Set response code + http_response_code ($status); + //header('Cache-Status: HIT'); + + //Send the content + if($_SERVER['REQUEST_METHOD'] == 'GET') { + echo $content; + } + + //Revalidation the cache async + fastcgi_finish_request(); + call_user_func($callback); + + return true; + } + else call_user_func($callback); +}; \ No newline at end of file diff --git a/Sites/pages/components/com_pages/resources/server/apache.txt b/Sites/pages/components/com_pages/resources/server/apache.txt new file mode 100644 index 00000000..1442e4c0 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/server/apache.txt @@ -0,0 +1,56 @@ +## +# Joomlatools Pages +# +# @copyright Copyright (C) 2018 Johan Janssens and Timble CVBA. (http://www.timble.net) +# @license GNU GPLv3 +# @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository +## + +## Begin - Joomlatools Pages - static cache +# + # Define the filesystem location of the static cache + SetEnvIf Request_URI "^.*" PAGES_STATIC_PATH=joomlatools-pages/cache/static + + # Define the filesystem locations (related to server root) + RewriteRule ^ - [E=PAGES_STATIC_ROOT:%{DOCUMENT_ROOT}/%{ENV:PAGES_STATIC_PATH}] + + # Prevent direct access to the static cache + RewriteRule ^joomlatools-pages/cache/static - [END,R=404] + + # Condition - Do not serve from cache on browser refresh or when caching is not allowed + RewriteCond %{HTTP:Cache-Control} (must-revalidate|max-age|no-cache|no-store) + RewriteRule .* - [S=4] + + # Condition - Only return cache for none logged in GET request + RewriteCond %{REQUEST_METHOD} !GET [OR] + RewriteCond %{HTTP_COOKIE} ^.*joomla_user_state=logged_in.*$ + RewriteRule .* - [S=3] + + # Rewrite - / + # Edit when running in a subfolder + RewriteCond "expr=%{REQUEST_URI} =~ m#/#" + RewriteCond %{ENV:PAGES_STATIC_ROOT}/%{REQUEST_URI}/index\.html -s + RewriteRule .* %{ENV:PAGES_STATIC_PATH}/%{REQUEST_URI}/index\.html [T=text/html,E=STATIC,L] + + # Rewrite - /path/to/page.html + RewriteCond %{ENV:PAGES_STATIC_ROOT}/%{REQUEST_URI}\.html -s + RewriteRule .* %{ENV:PAGES_STATIC_PATH}/%{REQUEST_URI}\.html [T=text/html,E=STATIC,L] + + # Rewrite - /path/to/page.[format] + RewriteCond %{ENV:PAGES_STATIC_ROOT}/%{REQUEST_URI} -s + RewriteRule .* %{ENV:PAGES_STATIC_PATH}/%{REQUEST_URI} [E=STATIC,L] + + # Allow browser content sniffing + Header always unset X-Content-Type-Options env=REDIRECT_STATIC + + # Mark response as STATIC + Header set Cache-Status "HIT, STATIC" env=REDIRECT_STATIC + + # Force explicit browser and proxy cache expiration + Header set Cache-Control "max-age=86400,s-maxage=604800" env=REDIRECT_STATIC + + # Force cache revaliation + #Header set Cache-Control "no-cache" env=REDIRECT_STATIC + +# +## End - Joomlatools Pages - static cache \ No newline at end of file diff --git a/Sites/pages/components/com_pages/resources/vendor/autoload.php b/Sites/pages/components/com_pages/resources/vendor/autoload.php new file mode 100644 index 00000000..f526ea35 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/autoload.php @@ -0,0 +1,25 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +spl_autoload_register(function ($class) +{ + if (strpos($class, 'Michelf\MarkdownExtra') === 0) + { + require_once __DIR__.'/markdown/MarkdownExtra.inc.php'; + return true; + } + + if (strpos($class, 'Highlight\\') === 0) + { + require_once __DIR__.'/highlight/Autoloader.php'; + return \Highlight\Autoloader::load($class); + } + + return false; +}); \ No newline at end of file diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/Autoloader.php b/Sites/pages/components/com_pages/resources/vendor/highlight/Autoloader.php new file mode 100644 index 00000000..2bcc9f33 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/Autoloader.php @@ -0,0 +1,72 @@ + + */ +class Autoloader +{ + /** + * The method to include the source file for a given class to use in + * the PHP spl_autoload_register function. + * + * @param string a name of a Scrivo class + * + * @return bool true if the source file was successfully included + */ + public static function load($class) + { + if (substr($class, 0, 10) !== "Highlight\\") { + return false; + } + + $c = str_replace("\\", "/", substr($class, 10)) . ".php"; + $res = include __DIR__ . "/$c"; + + return $res == 1 ? true : false; + } +} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/Highlighter.php b/Sites/pages/components/com_pages/resources/vendor/highlight/Highlighter.php new file mode 100644 index 00000000..15d82706 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/Highlighter.php @@ -0,0 +1,643 @@ +"; + + private $options; + + private $modeBuffer = ""; + private $result = ""; + private $top = null; + private $language = null; + private $keywordCount = 0; + private $relevance = 0; + private $ignoreIllegals = false; + + private static $classMap = array(); + private static $languages = null; + private static $aliases = null; + + private $autodetectSet = array( + "xml", "json", "javascript", "css", "php", "http", + ); + + public function __construct() + { + $this->options = array( + 'classPrefix' => 'hljs-', + 'tabReplace' => null, + 'useBR' => false, + 'languages' => null, + ); + + self::registerLanguages(); + } + + private static function registerLanguages() + { + // Languages that take precedence in the classMap array. + $languagePath = __DIR__ . DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR; + foreach (array("xml", "django", "javascript", "matlab", "cpp") as $languageId) { + $filePath = $languagePath . $languageId . ".json"; + if (is_readable($filePath)) { + self::registerLanguage($languageId, $filePath); + } + } + + $d = @dir($languagePath); + if ($d) { + while (($entry = $d->read()) !== false) { + if (substr($entry, -5) === ".json") { + $languageId = substr($entry, 0, -5); + $filePath = $languagePath . $entry; + if (is_readable($filePath)) { + self::registerLanguage($languageId, $filePath); + } + } + } + $d->close(); + } + + self::$languages = array_keys(self::$classMap); + } + + /** + * Register a language definition with the Highlighter's internal language + * storage. Languages are stored in a static variable, so they'll be available + * across all instances. You only need to register a language once. + * + * @param string $languageId The unique name of a language + * @param string $filePath The file path to the language definition + * @param bool $overwrite Overwrite language if it already exists + * + * @return Language The object containing the definition for a language's markup + */ + public static function registerLanguage($languageId, $filePath, $overwrite = false) + { + if (!isset(self::$classMap[$languageId]) || $overwrite) { + $lang = new Language($languageId, $filePath); + self::$classMap[$languageId] = $lang; + + if (isset($lang->mode->aliases)) { + foreach ($lang->mode->aliases as $alias) { + self::$aliases[$alias] = $languageId; + } + } + } + + return self::$classMap[$languageId]; + } + + private function testRe($re, $lexeme) + { + if (!$re) { + return false; + } + $test = preg_match($re, $lexeme, $match, PREG_OFFSET_CAPTURE); + if ($test === false) { + throw new \Exception("Invalid regexp: " . var_export($re, true)); + } + + return count($match) && ($match[0][1] == 0); + } + + private function escapeRe($value) + { + return sprintf('/%s/m', preg_quote($value)); + } + + private function subMode($lexeme, $mode) + { + for ($i = 0; $i < count($mode->contains); ++$i) { + if ($this->testRe($mode->contains[$i]->beginRe, $lexeme)) { + if ($mode->contains[$i]->endSameAsBegin) { + $matches = array(); + preg_match($mode->contains[$i]->beginRe, $lexeme, $matches); + + $mode->contains[$i]->endRe = $this->escapeRe($matches[0]); + } + + return $mode->contains[$i]; + } + } + } + + private function endOfMode($mode, $lexeme) + { + if ($this->testRe($mode->endRe, $lexeme)) { + while ($mode->endsParent && $mode->parent) { + $mode = $mode->parent; + } + + return $mode; + } + if ($mode->endsWithParent) { + return $this->endOfMode($mode->parent, $lexeme); + } + } + + private function isIllegal($lexeme, $mode) + { + return !$this->ignoreIllegals && $this->testRe($mode->illegalRe, $lexeme); + } + + private function keywordMatch($mode, $match) + { + $kwd = $this->language->caseInsensitive ? mb_strtolower($match[0], "UTF-8") : $match[0]; + + return isset($mode->keywords[$kwd]) ? $mode->keywords[$kwd] : null; + } + + private function buildSpan($classname, $insideSpan, $leaveOpen = false, $noPrefix = false) + { + $classPrefix = $noPrefix ? "" : $this->options['classPrefix']; + $openSpan = ""; + + if (!$classname) { + return $insideSpan; + } + + return $openSpan . $insideSpan . $closeSpan; + } + + private function escape($value) + { + return htmlspecialchars($value, ENT_NOQUOTES); + } + + private function processKeywords() + { + if (empty($this->top->keywords)) { + return $this->escape($this->modeBuffer); + } + + $result = ""; + $lastIndex = 0; + + /* TODO: when using the crystal language file on django and twigs code + * the values of $this->top->lexemesRe can become "" (empty). Check + * if this behaviour is consistent with highlight.js. + */ + if ($this->top->lexemesRe) { + while (preg_match($this->top->lexemesRe, $this->modeBuffer, $match, PREG_OFFSET_CAPTURE, $lastIndex)) { + $result .= $this->escape(substr($this->modeBuffer, $lastIndex, $match[0][1] - $lastIndex)); + $keyword_match = $this->keywordMatch($this->top, $match[0]); + + if ($keyword_match) { + $this->relevance += $keyword_match[1]; + $result .= $this->buildSpan($keyword_match[0], $this->escape($match[0][0])); + } else { + $result .= $this->escape($match[0][0]); + } + + $lastIndex = strlen($match[0][0]) + $match[0][1]; + } + } + + return $result . $this->escape(substr($this->modeBuffer, $lastIndex)); + } + + private function processSubLanguage() + { + try { + $hl = new Highlighter(); + $hl->setAutodetectLanguages($this->autodetectSet); + + $explicit = is_string($this->top->subLanguage); + if ($explicit && !in_array($this->top->subLanguage, self::$languages)) { + return $this->escape($this->modeBuffer); + } + + if ($explicit) { + $res = $hl->highlight( + $this->top->subLanguage, + $this->modeBuffer, + true, + isset($this->continuations[$this->top->subLanguage]) ? $this->continuations[$this->top->subLanguage] : null + ); + } else { + $res = $hl->highlightAuto( + $this->modeBuffer, + count($this->top->subLanguage) ? $this->top->subLanguage : null + ); + } + // Counting embedded language score towards the host language may + // be disabled with zeroing the containing mode relevance. Usecase + // in point is Markdown that allows XML everywhere and makes every + // XML snippet to have a much larger Markdown score. + if ($this->top->relevance > 0) { + $this->relevance += $res->relevance; + } + if ($explicit) { + $this->continuations[$this->top->subLanguage] = $res->top; + } + + return $this->buildSpan($res->language, $res->value, false, true); + } catch (\Exception $e) { + error_log("TODO, is this a relevant catch?"); + error_log($e); + + return $this->escape($this->modeBuffer); + } + } + + private function processBuffer() + { + if (is_object($this->top) && $this->top->subLanguage) { + $this->result .= $this->processSubLanguage(); + } else { + $this->result .= $this->processKeywords(); + } + + $this->modeBuffer = ''; + } + + private function startNewMode($mode) + { + $this->result .= $mode->className ? $this->buildSpan($mode->className, "", true) : ""; + + $t = clone $mode; + $t->parent = $this->top; + $this->top = $t; + } + + private function processLexeme($buffer, $lexeme = null) + { + $this->modeBuffer .= $buffer; + + if ($lexeme === null) { + $this->processBuffer(); + + return 0; + } + + $new_mode = $this->subMode($lexeme, $this->top); + if ($new_mode) { + if ($new_mode->skip) { + $this->modeBuffer .= $lexeme; + } else { + if ($new_mode->excludeBegin) { + $this->modeBuffer .= $lexeme; + } + $this->processBuffer(); + if (!$new_mode->returnBegin && !$new_mode->excludeBegin) { + $this->modeBuffer = $lexeme; + } + } + $this->startNewMode($new_mode, $lexeme); + + return $new_mode->returnBegin ? 0 : strlen($lexeme); + } + + $end_mode = $this->endOfMode($this->top, $lexeme); + if ($end_mode) { + $origin = $this->top; + if ($origin->skip) { + $this->modeBuffer .= $lexeme; + } else { + if (!($origin->returnEnd || $origin->excludeEnd)) { + $this->modeBuffer .= $lexeme; + } + $this->processBuffer(); + if ($origin->excludeEnd) { + $this->modeBuffer = $lexeme; + } + } + do { + if ($this->top->className) { + $this->result .= self::SPAN_END_TAG; + } + if (!$this->top->skip && !$this->top->subLanguage) { + $this->relevance += $this->top->relevance; + } + $this->top = $this->top->parent; + } while ($this->top != $end_mode->parent); + if ($end_mode->starts) { + if ($end_mode->endSameAsBegin) { + $end_mode->starts->endRe = $end_mode->endRe; + } + $this->startNewMode($end_mode->starts, ""); + } + + return $origin->returnEnd ? 0 : strlen($lexeme); + } + + if ($this->isIllegal($lexeme, $this->top)) { + $className = $this->top->className ? $this->top->className : "unnamed"; + $err = "Illegal lexeme \"{$lexeme}\" for mode \"{$className}\""; + + throw new \Exception($err); + } + + // Parser should not reach this point as all types of lexemes should + // be caught earlier, but if it does due to some bug make sure it + // advances at least one character forward to prevent infinite looping. + + $this->modeBuffer .= $lexeme; + $l = strlen($lexeme); + + return $l ? $l : 1; + } + + /** + * Replace tabs for something more usable. + */ + private function replaceTabs($code) + { + if ($this->options['tabReplace'] !== null) { + return str_replace("\t", $this->options['tabReplace'], $code); + } + + return $code; + } + + /** + * Set the set of languages used for autodetection. When using + * autodetection the code to highlight will be probed for every language + * in this set. Limiting this set to only the languages you want to use + * will greatly improve highlighting speed. + * + * @param array $set An array of language games to use for autodetection. This defaults + * to a typical set Web development languages. + */ + public function setAutodetectLanguages(array $set) + { + $this->autodetectSet = array_unique($set); + self::registerLanguages(); + } + + /** + * Get the tab replacement string. + * + * @return string The tab replacement string + */ + public function getTabReplace() + { + return $this->options['tabReplace']; + } + + /** + * Set the tab replacement string. This defaults to NULL: no tabs + * will be replaced. + * + * @param string $tabReplace The tab replacement string + */ + public function setTabReplace($tabReplace) + { + $this->options['tabReplace'] = $tabReplace; + } + + /** + * Get the class prefix string. + * + * @return string + * The class prefix string + */ + public function getClassPrefix() + { + return $this->options['classPrefix']; + } + + /** + * Set the class prefix string. + * + * @param string $classPrefix The class prefix string + */ + public function setClassPrefix($classPrefix) + { + $this->options['classPrefix'] = $classPrefix; + } + + /** + * @throws \DomainException if the requested language was not in this + * Highlighter's language set + */ + private function getLanguage($name) + { + if (isset(self::$classMap[$name])) { + return self::$classMap[$name]; + } elseif (isset(self::$aliases[$name]) && isset(self::$classMap[self::$aliases[$name]])) { + return self::$classMap[self::$aliases[$name]]; + } + + throw new \DomainException("Unknown language: $name"); + } + + /** + * Determine whether or not a language definition supports auto detection. + * + * @param string $name Language name + * + * @return bool + */ + private function autoDetection($name) + { + return !$this->getLanguage($name)->disableAutodetect; + } + + /** + * Core highlighting function. Accepts a language name, or an alias, and a + * string with the code to highlight. Returns an object with the following + * properties: + * - relevance (int) + * - value (an HTML string with highlighting markup). + * + * @throws \DomainException if the requested language was not in this + * Highlighter's language set + * @throws \Exception if an invalid regex was given in a language file + */ + public function highlight($language, $code, $ignoreIllegals = true, $continuation = null) + { + $this->language = $this->getLanguage($language); + $this->language->compile(); + $this->top = $continuation ? $continuation : $this->language->mode; + $this->continuations = array(); + $this->result = ""; + + for ($current = $this->top; $current != $this->language->mode; $current = $current->parent) { + if ($current->className) { + $this->result = $this->buildSpan($current->className, '', true) . $this->result; + } + } + + $this->modeBuffer = ""; + $this->relevance = 0; + $this->ignoreIllegals = $ignoreIllegals; + + $res = new \stdClass(); + $res->relevance = 0; + $res->value = ""; + $res->language = ""; + + try { + $match = null; + $count = 0; + $index = 0; + + while ($this->top && $this->top->terminators) { + $test = @preg_match($this->top->terminators, $code, $match, PREG_OFFSET_CAPTURE, $index); + if ($test === false) { + throw new \Exception("Invalid " . $this->language->name . " regExp " . var_export($this->top->terminators, true)); + } elseif ($test === 0) { + break; + } + $count = $this->processLexeme(substr($code, $index, $match[0][1] - $index), $match[0][0]); + $index = $match[0][1] + $count; + } + $this->processLexeme(substr($code, $index)); + + for ($current = $this->top; isset($current->parent); $current = $current->parent) { + if ($current->className) { + $this->result .= self::SPAN_END_TAG; + } + } + + $res->relevance = $this->relevance; + $res->value = $this->replaceTabs($this->result); + $res->language = $this->language->name; + $res->top = $this->top; + + return $res; + } catch (\Exception $e) { + if (strpos($e->getMessage(), "Illegal") !== false) { + $res->value = $this->escape($code); + + return $res; + } + throw $e; + } + } + + /** + * Highlight the given code by highlighting the given code with each + * registered language and then finding the match with highest accuracy. + * + * @param string $code + * @param string[]|null $languageSubset When set to null, this method will + * attempt to highlight $code with each language (170+). Set this to + * an array of languages of your choice to limit the amount of languages + * to try. + * + * @throws \DomainException if the attempted language to check does not exist + * @throws \Exception if an invalid regex was given in a language file + * + * @return \stdClass + */ + public function highlightAuto($code, $languageSubset = null) + { + $res = new \stdClass(); + $res->relevance = 0; + $res->value = $this->escape($code); + $res->language = ""; + $scnd = clone $res; + + $tmp = $languageSubset ? $languageSubset : $this->autodetectSet; + + foreach ($tmp as $l) { + // don't fail if we run into a non-existent language + try { + // skip any languages that don't support auto detection + if (!$this->autoDetection($l)) { + continue; + } + + $current = $this->highlight($l, $code, false); + } catch (\DomainException $e) { + continue; + } + + if ($current->relevance > $scnd->relevance) { + $scnd = $current; + } + if ($current->relevance > $res->relevance) { + $scnd = $res; + $res = $current; + } + } + + if ($scnd->language) { + $res->secondBest = $scnd; + } + + return $res; + } + + /** + * Return a list of all supported languages. Using this list in + * setAutodetectLanguages will turn on autodetection for all supported + * languages. + * + * @param bool $include_aliases specify whether language aliases + * should be included as well + * + * @return string[] An array of language names + */ + public function listLanguages($include_aliases = false) + { + if ($include_aliases === true) { + return array_merge(self::$languages, array_keys(self::$aliases)); + } + + return self::$languages; + } + + /** + * Returns list of all available aliases for given language name. + * + * @param string $language name or alias of language to look-up + * + * @throws \DomainException if the requested language was not in this + * Highlighter's language set + * + * @return string[] An array of all aliases associated with the requested + * language name language. Passed-in name is included as + * well. + */ + public function getAliasesForLanguage($language) + { + $language = self::getLanguage($language); + + if ($language->aliases === null) { + return array($language->name); + } + + return array_merge(array($language->name), $language->aliases); + } +} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/JsonRef.php b/Sites/pages/components/com_pages/resources/vendor/highlight/JsonRef.php new file mode 100644 index 00000000..71d3078b --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/JsonRef.php @@ -0,0 +1,137 @@ +decode(file_get_contents("data.json")); + * echo $data->spouse->spouse->name; // echos 'Kris Zyp' + * echo $data->oldestChild->name; // echos 'Jennika Zyp' + */ +class JsonRef +{ + /** + * Array to hold all data paths in the given JSON data. + * + * @var array + */ + private $paths = null; + + /** + * Recurse through the data tree and fill an array of paths that reference + * the nodes in the decoded JSON data structure. + * + * @param mixed $s Decoded JSON data (decoded with json_decode) + * @param string $r The current path key (for example: '#children.0'). + */ + private function getPaths(&$s, $r = "#") + { + $this->paths[$r] = &$s; + if (is_array($s) || is_object($s)) { + foreach ($s as $k => &$v) { + if ($k !== "\$ref") { + $this->getPaths($v, $r == "#" ? "#{$k}" : "{$r}.{$k}"); + } + } + } + } + + /** + * Recurse through the data tree and resolve all path references. + * + * @param mixed $s Decoded JSON data (decoded with json_decode) + */ + private function resolvePathReferences(&$s, $limit = 20, $depth = 1) + { + if ($depth >= $limit) { + return; + } + + ++$depth; + + if (is_array($s) || is_object($s)) { + foreach ($s as $k => &$v) { + if ($k === "\$ref") { + $s = $this->paths[$v]; + } else { + $this->resolvePathReferences($v, $limit, $depth); + } + } + } + } + + /** + * Decode JSON data that may contain path based references. + * + * @param string|object $json JSON data string or JSON data object + * + * @return mixed The decoded JSON data + */ + public function decode($json) + { + // Clear the path array. + $this->paths = array(); + // Decode the given JSON data if necessary. + $x = is_string($json) ? json_decode($json) : $json; + // Get all data paths. + $this->getPaths($x); + // Resolve all path references. + $this->resolvePathReferences($x); + // Return the data. + return $x; + } +} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/Language.php b/Sites/pages/components/com_pages/resources/vendor/highlight/Language.php new file mode 100644 index 00000000..c644647a --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/Language.php @@ -0,0 +1,346 @@ + true, + "end" => true, + "lexemes" => true, + "illegal" => true, + ); + + $def = array( + "begin" => "", + "beginRe" => "", + "beginKeywords" => "", + "excludeBegin" => "", + "returnBegin" => "", + "end" => "", + "endRe" => "", + "endSameAsBegin" => "", + "endsParent" => "", + "endsWithParent" => "", + "excludeEnd" => "", + "returnEnd" => "", + "starts" => "", + "terminators" => "", + "terminatorEnd" => "", + "lexemes" => "", + "lexemesRe" => "", + "illegal" => "", + "illegalRe" => "", + "className" => "", + "contains" => array(), + "keywords" => null, + "subLanguage" => null, + "subLanguageMode" => "", + "compiled" => false, + "relevance" => 1, + "skip" => false, + ); + + foreach ($patch as $k => $v) { + if (isset($e->$k)) { + $e->$k = str_replace("\\/", "/", $e->$k); + $e->$k = str_replace("/", "\\/", $e->$k); + } + } + + foreach ($def as $k => $v) { + if (!isset($e->$k) && is_object($e)) { + $e->$k = $v; + } + } + } + + public function __construct($lang, $filePath) + { + $json = file_get_contents($filePath); + $this->mode = json_decode($json); + + $this->name = $lang; + $this->aliases = isset($this->mode->aliases) ? $this->mode->aliases : null; + + $this->caseInsensitive = isset($this->mode->case_insensitive) ? $this->mode->case_insensitive : false; + $this->disableAutodetect = isset($this->mode->disableAutodetect) ? $this->mode->disableAutodetect : false; + } + + private function langRe($value, $global = false) + { + // PCRE allows us to change the definition of "new line." The + // `(*ANYCRLF)` matches `\r`, `\n`, and `\r\n` for `$` + // + // https://www.pcre.org/original/doc/html/pcrepattern.html + + return "/(*ANYCRLF){$value}/um" . ($this->caseInsensitive ? "i" : ""); + } + + private function processKeyWords($kw) + { + if (is_string($kw)) { + if ($this->caseInsensitive) { + $kw = mb_strtolower($kw, "UTF-8"); + } + $kw = array("keyword" => explode(" ", $kw)); + } else { + foreach ($kw as $cls => $vl) { + if (!is_array($vl)) { + if ($this->caseInsensitive) { + $vl = mb_strtolower($vl, "UTF-8"); + } + $kw->$cls = explode(" ", $vl); + } + } + } + + return $kw; + } + + private function inherit() + { + $result = new \stdClass(); + $objects = func_get_args(); + $parent = array_shift($objects); + + foreach ($parent as $key => $value) { + $result->{$key} = $value; + } + + foreach ($objects as $object) { + foreach ($object as $key => $value) { + $result->{$key} = $value; + } + } + + return $result; + } + + private function expandMode($mode) + { + if (isset($mode->variants) && !isset($mode->cachedVariants)) { + $mode->cachedVariants = array(); + + foreach ($mode->variants as $variant) { + $mode->cachedVariants[] = $this->inherit($mode, array('variants' => null), $variant); + } + } + + if (isset($mode->cachedVariants)) { + return $mode->cachedVariants; + } + + if (isset($mode->endsWithParent) && $mode->endsWithParent) { + return array($this->inherit($mode)); + } + + return array($mode); + } + + /** + * joinRe logically computes regexps.join(separator), but fixes the + * backreferences so they continue to match. + * + * @param array $regexps + * @param string $separator + * + * @return string + */ + private function joinRe($regexps, $separator) + { + // backreferenceRe matches an open parenthesis or backreference. To avoid + // an incorrect parse, it additionally matches the following: + // - [...] elements, where the meaning of parentheses and escapes change + // - other escape sequences, so we do not misparse escape sequences as + // interesting elements + // - non-matching or lookahead parentheses, which do not capture. These + // follow the '(' with a '?'. + $backreferenceRe = '#\[(?:[^\\\\\]]|\\\.)*\]|\(\??|\\\([1-9][0-9]*)|\\\.#'; + $numCaptures = 0; + $ret = ''; + + $strLen = count($regexps); + for ($i = 0; $i < $strLen; ++$i) { + $offset = $numCaptures; + $re = $regexps[$i]; + + if ($i > 0) { + $ret .= $separator; + } + + while (strlen($re) > 0) { + $matches = array(); + $matchFound = preg_match($backreferenceRe, $re, $matches, PREG_OFFSET_CAPTURE); + + if ($matchFound === 0) { + $ret .= $re; + break; + } + + // PHP aliases to match the JS naming conventions + $match = $matches[0]; + $index = $match[1]; + + $ret .= substr($re, 0, $index); + $re = substr($re, $index + strlen($match[0])); + + if (substr($match[0], 0, 1) === '\\' && isset($matches[1])) { + // Adjust the backreference. + $ret .= "\\" . strval(intval($matches[1][0]) + $offset); + } else { + $ret .= $match[0]; + if ($match[0] == "(") { + ++$numCaptures; + } + } + } + } + + return $ret; + } + + private function compileMode($mode, $parent = null) + { + if (isset($mode->compiled)) { + return; + } + $this->complete($mode); + $mode->compiled = true; + + $mode->keywords = $mode->keywords ? $mode->keywords : $mode->beginKeywords; + + /* Note: JsonRef method creates different references as those in the + * original source files. Two modes may refer to the same keywords + * set, so only testing if the mode has keywords is not enough: the + * mode's keywords might be compiled already, so it is necessary + * to do an 'is_array' check. + */ + if ($mode->keywords && !is_array($mode->keywords)) { + $compiledKeywords = array(); + + $mode->lexemesRe = $this->langRe($mode->lexemes ? $mode->lexemes : "\w+", true); + + foreach ($this->processKeyWords($mode->keywords) as $clsNm => $dat) { + if (!is_array($dat)) { + $dat = array($dat); + } + foreach ($dat as $kw) { + $pair = explode("|", $kw); + $compiledKeywords[$pair[0]] = array($clsNm, isset($pair[1]) ? intval($pair[1]) : 1); + } + } + $mode->keywords = $compiledKeywords; + } + + if ($parent) { + if ($mode->beginKeywords) { + $mode->begin = "\\b(" . implode("|", explode(" ", $mode->beginKeywords)) . ")\\b"; + } + if (!$mode->begin) { + $mode->begin = "\B|\b"; + } + $mode->beginRe = $this->langRe($mode->begin); + if ($mode->endSameAsBegin) { + $mode->end = $mode->begin; + } + if (!$mode->end && !$mode->endsWithParent) { + $mode->end = "\B|\b"; + } + if ($mode->end) { + $mode->endRe = $this->langRe($mode->end); + } + $mode->terminatorEnd = $mode->end; + if ($mode->endsWithParent && $parent->terminatorEnd) { + $mode->terminatorEnd .= ($mode->end ? "|" : "") . $parent->terminatorEnd; + } + } + + if ($mode->illegal) { + $mode->illegalRe = $this->langRe($mode->illegal); + } + + $expandedContains = array(); + foreach ($mode->contains as $c) { + $expandedContains = array_merge($expandedContains, $this->expandMode( + $c === 'self' ? $mode : $c + )); + } + + $mode->contains = $expandedContains; + + for ($i = 0; $i < count($mode->contains); ++$i) { + $this->compileMode($mode->contains[$i], $mode); + } + + if ($mode->starts) { + $this->compileMode($mode->starts, $parent); + } + + $terminators = array(); + + for ($i = 0; $i < count($mode->contains); ++$i) { + $terminators[] = $mode->contains[$i]->beginKeywords + ? "\.?(?:" . $mode->contains[$i]->begin . ")\.?" + : $mode->contains[$i]->begin; + } + if ($mode->terminatorEnd) { + $terminators[] = $mode->terminatorEnd; + } + if ($mode->illegal) { + $terminators[] = $mode->illegal; + } + $mode->terminators = count($terminators) ? $this->langRe($this->joinRe($terminators, "|"), true) : null; + } + + public function compile() + { + if (!isset($this->mode->compiled)) { + $jr = new JsonRef(); + $this->mode = $jr->decode($this->mode); + $this->compileMode($this->mode); + } + } +} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/1c.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/1c.json new file mode 100644 index 00000000..ebe2c2cb --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/1c.json @@ -0,0 +1 @@ +{"case_insensitive":true,"lexemes":"[A-Za-zА-Яа-яёЁ_][A-Za-zА-Яа-яёЁ_0-9]+","keywords":{"keyword":"далее возврат вызватьисключение выполнить для если и из или иначе иначеесли исключение каждого конецесли конецпопытки конеццикла не новый перейти перем по пока попытка прервать продолжить тогда цикл экспорт ","built_in":"разделительстраниц разделительстрок символтабуляции ansitooem oemtoansi ввестивидсубконто ввестиперечисление ввестипериод ввестиплансчетов выбранныйплансчетов датагод датамесяц датачисло заголовоксистемы значениевстроку значениеизстроки каталогиб каталогпользователя кодсимв конгода конецпериодаби конецрассчитанногопериодаби конецстандартногоинтервала конквартала конмесяца коннедели лог лог10 максимальноеколичествосубконто названиеинтерфейса названиенабораправ назначитьвид назначитьсчет найтиссылки началопериодаби началостандартногоинтервала начгода начквартала начмесяца начнедели номерднягода номерднянедели номернеделигода обработкаожидания основнойжурналрасчетов основнойплансчетов основнойязык очиститьокносообщений периодстр получитьвремята получитьдатута получитьдокументта получитьзначенияотбора получитьпозициюта получитьпустоезначение получитьта префиксавтонумерации пропись пустоезначение разм разобратьпозициюдокумента рассчитатьрегистрына рассчитатьрегистрыпо симв создатьобъект статусвозврата стрколичествострок сформироватьпозициюдокумента счетпокоду текущеевремя типзначения типзначениястр установитьтана установитьтапо фиксшаблон шаблон acos asin atan base64значение base64строка cos exp log log10 pow sin sqrt tan xmlзначение xmlстрока xmlтип xmlтипзнч активноеокно безопасныйрежим безопасныйрежимразделенияданных булево ввестидату ввестизначение ввестистроку ввестичисло возможностьчтенияxml вопрос восстановитьзначение врег выгрузитьжурналрегистрации выполнитьобработкуоповещения выполнитьпроверкуправдоступа вычислить год данныеформывзначение дата день деньгода деньнедели добавитьмесяц заблокироватьданныедляредактирования заблокироватьработупользователя завершитьработусистемы загрузитьвнешнююкомпоненту закрытьсправку записатьjson записатьxml записатьдатуjson записьжурналарегистрации заполнитьзначениясвойств запроситьразрешениепользователя запуститьприложение запуститьсистему зафиксироватьтранзакцию значениевданныеформы значениевстрокувнутр значениевфайл значениезаполнено значениеизстрокивнутр значениеизфайла изxmlтипа импортмоделиxdto имякомпьютера имяпользователя инициализироватьпредопределенныеданные информацияобошибке каталогбиблиотекимобильногоустройства каталогвременныхфайлов каталогдокументов каталогпрограммы кодироватьстроку кодлокализацииинформационнойбазы кодсимвола командасистемы конецгода конецдня конецквартала конецмесяца конецминуты конецнедели конецчаса конфигурациябазыданныхизмененадинамически конфигурацияизменена копироватьданныеформы копироватьфайл краткоепредставлениеошибки лев макс местноевремя месяц мин минута монопольныйрежим найти найтинедопустимыесимволыxml найтиокнопонавигационнойссылке найтипомеченныенаудаление найтипоссылкам найтифайлы началогода началодня началоквартала началомесяца началоминуты началонедели началочаса начатьзапросразрешенияпользователя начатьзапускприложения начатькопированиефайла начатьперемещениефайла начатьподключениевнешнейкомпоненты начатьподключениерасширенияработыскриптографией начатьподключениерасширенияработысфайлами начатьпоискфайлов начатьполучениекаталогавременныхфайлов начатьполучениекаталогадокументов начатьполучениерабочегокаталогаданныхпользователя начатьполучениефайлов начатьпомещениефайла начатьпомещениефайлов начатьсозданиедвоичныхданныхизфайла начатьсозданиекаталога начатьтранзакцию начатьудалениефайлов начатьустановкувнешнейкомпоненты начатьустановкурасширенияработыскриптографией начатьустановкурасширенияработысфайлами неделягода необходимостьзавершениясоединения номерсеансаинформационнойбазы номерсоединенияинформационнойбазы нрег нстр обновитьинтерфейс обновитьнумерациюобъектов обновитьповторноиспользуемыезначения обработкапрерыванияпользователя объединитьфайлы окр описаниеошибки оповестить оповеститьобизменении отключитьобработчикзапросанастроекклиенталицензирования отключитьобработчикожидания отключитьобработчикоповещения открытьзначение открытьиндекссправки открытьсодержаниесправки открытьсправку открытьформу открытьформумодально отменитьтранзакцию очиститьжурналрегистрации очиститьнастройкипользователя очиститьсообщения параметрыдоступа перейтипонавигационнойссылке переместитьфайл подключитьвнешнююкомпоненту подключитьобработчикзапросанастроекклиенталицензирования подключитьобработчикожидания подключитьобработчикоповещения подключитьрасширениеработыскриптографией подключитьрасширениеработысфайлами подробноепредставлениеошибки показатьвводдаты показатьвводзначения показатьвводстроки показатьвводчисла показатьвопрос показатьзначение показатьинформациюобошибке показатьнакарте показатьоповещениепользователя показатьпредупреждение полноеимяпользователя получитьcomобъект получитьxmlтип получитьадреспоместоположению получитьблокировкусеансов получитьвремязавершенияспящегосеанса получитьвремязасыпанияпассивногосеанса получитьвремяожиданияблокировкиданных получитьданныевыбора получитьдополнительныйпараметрклиенталицензирования получитьдопустимыекодылокализации получитьдопустимыечасовыепояса получитьзаголовокклиентскогоприложения получитьзаголовоксистемы получитьзначенияотборажурналарегистрации получитьидентификаторконфигурации получитьизвременногохранилища получитьимявременногофайла получитьимяклиенталицензирования получитьинформациюэкрановклиента получитьиспользованиежурналарегистрации получитьиспользованиесобытияжурналарегистрации получитькраткийзаголовокприложения получитьмакетоформления получитьмаскувсефайлы получитьмаскувсефайлыклиента получитьмаскувсефайлысервера получитьместоположениепоадресу получитьминимальнуюдлинупаролейпользователей получитьнавигационнуюссылку получитьнавигационнуюссылкуинформационнойбазы получитьобновлениеконфигурациибазыданных получитьобновлениепредопределенныхданныхинформационнойбазы получитьобщиймакет получитьобщуюформу получитьокна получитьоперативнуюотметкувремени получитьотключениебезопасногорежима получитьпараметрыфункциональныхопцийинтерфейса получитьполноеимяпредопределенногозначения получитьпредставлениянавигационныхссылок получитьпроверкусложностипаролейпользователей получитьразделительпути получитьразделительпутиклиента получитьразделительпутисервера получитьсеансыинформационнойбазы получитьскоростьклиентскогосоединения получитьсоединенияинформационнойбазы получитьсообщенияпользователю получитьсоответствиеобъектаиформы получитьсоставстандартногоинтерфейсаodata получитьструктурухранениябазыданных получитьтекущийсеансинформационнойбазы получитьфайл получитьфайлы получитьформу получитьфункциональнуюопцию получитьфункциональнуюопциюинтерфейса получитьчасовойпоясинформационнойбазы пользователиос поместитьвовременноехранилище поместитьфайл поместитьфайлы прав праводоступа предопределенноезначение представлениекодалокализации представлениепериода представлениеправа представлениеприложения представлениесобытияжурналарегистрации представлениечасовогопояса предупреждение прекратитьработусистемы привилегированныйрежим продолжитьвызов прочитатьjson прочитатьxml прочитатьдатуjson пустаястрока рабочийкаталогданныхпользователя разблокироватьданныедляредактирования разделитьфайл разорватьсоединениесвнешнимисточникомданных раскодироватьстроку рольдоступна секунда сигнал символ скопироватьжурналрегистрации смещениелетнеговремени смещениестандартноговремени соединитьбуферыдвоичныхданных создатькаталог создатьфабрикуxdto сокрл сокрлп сокрп сообщить состояние сохранитьзначение сохранитьнастройкипользователя сред стрдлина стрзаканчиваетсяна стрзаменить стрнайти стрначинаетсяс строка строкасоединенияинформационнойбазы стрполучитьстроку стрразделить стрсоединить стрсравнить стрчисловхождений стрчислострок стршаблон текущаядата текущаядатасеанса текущаяуниверсальнаядата текущаяуниверсальнаядатавмиллисекундах текущийвариантинтерфейсаклиентскогоприложения текущийвариантосновногошрифтаклиентскогоприложения текущийкодлокализации текущийрежимзапуска текущийязык текущийязыксистемы тип типзнч транзакцияактивна трег удалитьданныеинформационнойбазы удалитьизвременногохранилища удалитьобъекты удалитьфайлы универсальноевремя установитьбезопасныйрежим установитьбезопасныйрежимразделенияданных установитьблокировкусеансов установитьвнешнююкомпоненту установитьвремязавершенияспящегосеанса установитьвремязасыпанияпассивногосеанса установитьвремяожиданияблокировкиданных установитьзаголовокклиентскогоприложения установитьзаголовоксистемы установитьиспользованиежурналарегистрации установитьиспользованиесобытияжурналарегистрации установитькраткийзаголовокприложения установитьминимальнуюдлинупаролейпользователей установитьмонопольныйрежим установитьнастройкиклиенталицензирования установитьобновлениепредопределенныхданныхинформационнойбазы установитьотключениебезопасногорежима установитьпараметрыфункциональныхопцийинтерфейса установитьпривилегированныйрежим установитьпроверкусложностипаролейпользователей установитьрасширениеработыскриптографией установитьрасширениеработысфайлами установитьсоединениесвнешнимисточникомданных установитьсоответствиеобъектаиформы установитьсоставстандартногоинтерфейсаodata установитьчасовойпоясинформационнойбазы установитьчасовойпояссеанса формат цел час часовойпояс часовойпояссеанса число числопрописью этоадресвременногохранилища wsссылки библиотекакартинок библиотекамакетовоформлениякомпоновкиданных библиотекастилей бизнеспроцессы внешниеисточникиданных внешниеобработки внешниеотчеты встроенныепокупки главныйинтерфейс главныйстиль документы доставляемыеуведомления журналыдокументов задачи информацияобинтернетсоединении использованиерабочейдаты историяработыпользователя константы критерииотбора метаданные обработки отображениерекламы отправкадоставляемыхуведомлений отчеты панельзадачос параметрзапуска параметрысеанса перечисления планывидоврасчета планывидовхарактеристик планыобмена планысчетов полнотекстовыйпоиск пользователиинформационнойбазы последовательности проверкавстроенныхпокупок рабочаядата расширенияконфигурации регистрыбухгалтерии регистрынакопления регистрырасчета регистрысведений регламентныезадания сериализаторxdto справочники средствагеопозиционирования средствакриптографии средствамультимедиа средстваотображениярекламы средствапочты средствателефонии фабрикаxdto файловыепотоки фоновыезадания хранилищанастроек хранилищевариантовотчетов хранилищенастроекданныхформ хранилищеобщихнастроек хранилищепользовательскихнастроекдинамическихсписков хранилищепользовательскихнастроекотчетов хранилищесистемныхнастроек ","class":"webцвета windowsцвета windowsшрифты библиотекакартинок рамкистиля символы цветастиля шрифтыстиля автоматическоесохранениеданныхформывнастройках автонумерациявформе автораздвижениесерий анимациядиаграммы вариантвыравниванияэлементовизаголовков вариантуправлениявысотойтаблицы вертикальнаяпрокруткаформы вертикальноеположение вертикальноеположениеэлемента видгруппыформы виддекорацииформы виддополненияэлементаформы видизмененияданных видкнопкиформы видпереключателя видподписейкдиаграмме видполяформы видфлажка влияниеразмеранапузырекдиаграммы горизонтальноеположение горизонтальноеположениеэлемента группировкаколонок группировкаподчиненныхэлементовформы группыиэлементы действиеперетаскивания дополнительныйрежимотображения допустимыедействияперетаскивания интервалмеждуэлементамиформы использованиевывода использованиеполосыпрокрутки используемоезначениеточкибиржевойдиаграммы историявыборапривводе источникзначенийоситочекдиаграммы источникзначенияразмерапузырькадиаграммы категориягруппыкоманд максимумсерий начальноеотображениедерева начальноеотображениесписка обновлениетекстаредактирования ориентациядендрограммы ориентациядиаграммы ориентацияметокдиаграммы ориентацияметоксводнойдиаграммы ориентацияэлементаформы отображениевдиаграмме отображениевлегендедиаграммы отображениегруппыкнопок отображениезаголовкашкалыдиаграммы отображениезначенийсводнойдиаграммы отображениезначенияизмерительнойдиаграммы отображениеинтерваладиаграммыганта отображениекнопки отображениекнопкивыбора отображениеобсужденийформы отображениеобычнойгруппы отображениеотрицательныхзначенийпузырьковойдиаграммы отображениепанелипоиска отображениеподсказки отображениепредупрежденияприредактировании отображениеразметкиполосырегулирования отображениестраницформы отображениетаблицы отображениетекстазначениядиаграммыганта отображениеуправленияобычнойгруппы отображениефигурыкнопки палитрацветовдиаграммы поведениеобычнойгруппы поддержкамасштабадендрограммы поддержкамасштабадиаграммыганта поддержкамасштабасводнойдиаграммы поисквтаблицепривводе положениезаголовкаэлементаформы положениекартинкикнопкиформы положениекартинкиэлементаграфическойсхемы положениекоманднойпанелиформы положениекоманднойпанелиэлементаформы положениеопорнойточкиотрисовки положениеподписейкдиаграмме положениеподписейшкалызначенийизмерительнойдиаграммы положениесостоянияпросмотра положениестрокипоиска положениетекстасоединительнойлинии положениеуправленияпоиском положениешкалывремени порядокотображенияточекгоризонтальнойгистограммы порядоксерийвлегендедиаграммы размеркартинки расположениезаголовкашкалыдиаграммы растягиваниеповертикалидиаграммыганта режимавтоотображениясостояния режимвводастроктаблицы режимвыборанезаполненного режимвыделениядаты режимвыделениястрокитаблицы режимвыделениятаблицы режимизмененияразмера режимизменениясвязанногозначения режимиспользованиядиалогапечати режимиспользованияпараметракоманды режиммасштабированияпросмотра режимосновногоокнаклиентскогоприложения режимоткрытияокнаформы режимотображениявыделения режимотображениягеографическойсхемы режимотображениязначенийсерии режимотрисовкисеткиграфическойсхемы режимполупрозрачностидиаграммы режимпробеловдиаграммы режимразмещениянастранице режимредактированияколонки режимсглаживаниядиаграммы режимсглаживанияиндикатора режимсписказадач сквозноевыравнивание сохранениеданныхформывнастройках способзаполнениятекстазаголовкашкалыдиаграммы способопределенияограничивающегозначениядиаграммы стандартнаягруппакоманд стандартноеоформление статусоповещенияпользователя стильстрелки типаппроксимациилиниитрендадиаграммы типдиаграммы типединицышкалывремени типимпортасерийслоягеографическойсхемы типлиниигеографическойсхемы типлиниидиаграммы типмаркерагеографическойсхемы типмаркерадиаграммы типобластиоформления типорганизацииисточникаданныхгеографическойсхемы типотображениясериислоягеографическойсхемы типотображенияточечногообъектагеографическойсхемы типотображенияшкалыэлементалегендыгеографическойсхемы типпоискаобъектовгеографическойсхемы типпроекциигеографическойсхемы типразмещенияизмерений типразмещенияреквизитовизмерений типрамкиэлементауправления типсводнойдиаграммы типсвязидиаграммыганта типсоединениязначенийпосериямдиаграммы типсоединенияточекдиаграммы типсоединительнойлинии типстороныэлементаграфическойсхемы типформыотчета типшкалырадарнойдиаграммы факторлиниитрендадиаграммы фигуракнопки фигурыграфическойсхемы фиксациявтаблице форматдняшкалывремени форматкартинки ширинаподчиненныхэлементовформы виддвижениябухгалтерии виддвижениянакопления видпериодарегистрарасчета видсчета видточкимаршрутабизнеспроцесса использованиеагрегатарегистранакопления использованиегруппиэлементов использованиережимапроведения использованиесреза периодичностьагрегатарегистранакопления режимавтовремя режимзаписидокумента режимпроведениядокумента авторегистрацияизменений допустимыйномерсообщения отправкаэлементаданных получениеэлементаданных использованиерасшифровкитабличногодокумента ориентациястраницы положениеитоговколоноксводнойтаблицы положениеитоговстроксводнойтаблицы положениетекстаотносительнокартинки расположениезаголовкагруппировкитабличногодокумента способчтениязначенийтабличногодокумента типдвустороннейпечати типзаполненияобластитабличногодокумента типкурсоровтабличногодокумента типлиниирисункатабличногодокумента типлинииячейкитабличногодокумента типнаправленияпереходатабличногодокумента типотображениявыделениятабличногодокумента типотображениялинийсводнойтаблицы типразмещениятекстатабличногодокумента типрисункатабличногодокумента типсмещениятабличногодокумента типузоратабличногодокумента типфайлатабличногодокумента точностьпечати чередованиерасположениястраниц отображениевремениэлементовпланировщика типфайлаформатированногодокумента обходрезультатазапроса типзаписизапроса видзаполнениярасшифровкипостроителяотчета типдобавленияпредставлений типизмеренияпостроителяотчета типразмещенияитогов доступкфайлу режимдиалогавыборафайла режимоткрытияфайла типизмеренияпостроителязапроса видданныханализа методкластеризации типединицыинтервалавременианализаданных типзаполнениятаблицырезультатаанализаданных типиспользованиячисловыхзначенийанализаданных типисточникаданныхпоискаассоциаций типколонкианализаданныхдереворешений типколонкианализаданныхкластеризация типколонкианализаданныхобщаястатистика типколонкианализаданныхпоискассоциаций типколонкианализаданныхпоискпоследовательностей типколонкимоделипрогноза типмерырасстоянияанализаданных типотсеченияправилассоциации типполяанализаданных типстандартизациианализаданных типупорядочиванияправилассоциациианализаданных типупорядочиванияшаблоновпоследовательностейанализаданных типупрощениядереварешений wsнаправлениепараметра вариантxpathxs вариантзаписидатыjson вариантпростоготипаxs видгруппымоделиxs видфасетаxdto действиепостроителяdom завершенностьпростоготипаxs завершенностьсоставноготипаxs завершенностьсхемыxs запрещенныеподстановкиxs исключениягруппподстановкиxs категорияиспользованияатрибутаxs категорияограниченияидентичностиxs категорияограниченияпространствименxs методнаследованияxs модельсодержимогоxs назначениетипаxml недопустимыеподстановкиxs обработкапробельныхсимволовxs обработкасодержимогоxs ограничениезначенияxs параметрыотбораузловdom переносстрокjson позициявдокументеdom пробельныесимволыxml типатрибутаxml типзначенияjson типканоническогоxml типкомпонентыxs типпроверкиxml типрезультатаdomxpath типузлаdom типузлаxml формаxml формапредставленияxs форматдатыjson экранированиесимволовjson видсравнениякомпоновкиданных действиеобработкирасшифровкикомпоновкиданных направлениесортировкикомпоновкиданных расположениевложенныхэлементоврезультатакомпоновкиданных расположениеитоговкомпоновкиданных расположениегруппировкикомпоновкиданных расположениеполейгруппировкикомпоновкиданных расположениеполякомпоновкиданных расположениереквизитовкомпоновкиданных расположениересурсовкомпоновкиданных типбухгалтерскогоостаткакомпоновкиданных типвыводатекстакомпоновкиданных типгруппировкикомпоновкиданных типгруппыэлементовотборакомпоновкиданных типдополненияпериодакомпоновкиданных типзаголовкаполейкомпоновкиданных типмакетагруппировкикомпоновкиданных типмакетаобластикомпоновкиданных типостаткакомпоновкиданных типпериодакомпоновкиданных типразмещениятекстакомпоновкиданных типсвязинаборовданныхкомпоновкиданных типэлементарезультатакомпоновкиданных расположениелегендыдиаграммыкомпоновкиданных типпримененияотборакомпоновкиданных режимотображенияэлементанастройкикомпоновкиданных режимотображениянастроеккомпоновкиданных состояниеэлементанастройкикомпоновкиданных способвосстановлениянастроеккомпоновкиданных режимкомпоновкирезультата использованиепараметракомпоновкиданных автопозицияресурсовкомпоновкиданных вариантиспользованиягруппировкикомпоновкиданных расположениересурсоввдиаграммекомпоновкиданных фиксациякомпоновкиданных использованиеусловногооформлениякомпоновкиданных важностьинтернетпочтовогосообщения обработкатекстаинтернетпочтовогосообщения способкодированияинтернетпочтовоговложения способкодированиянеasciiсимволовинтернетпочтовогосообщения типтекстапочтовогосообщения протоколинтернетпочты статусразборапочтовогосообщения режимтранзакциизаписижурналарегистрации статустранзакциизаписижурналарегистрации уровеньжурналарегистрации расположениехранилищасертификатовкриптографии режимвключениясертификатовкриптографии режимпроверкисертификатакриптографии типхранилищасертификатовкриптографии кодировкаименфайловвzipфайле методсжатияzip методшифрованияzip режимвосстановленияпутейфайловzip режимобработкиподкаталоговzip режимсохраненияпутейzip уровеньсжатияzip звуковоеоповещение направлениепереходакстроке позициявпотоке порядокбайтов режимблокировкиданных режимуправленияблокировкойданных сервисвстроенныхпокупок состояниефоновогозадания типподписчикадоставляемыхуведомлений уровеньиспользованиязащищенногосоединенияftp направлениепорядкасхемызапроса типдополненияпериодамисхемызапроса типконтрольнойточкисхемызапроса типобъединениясхемызапроса типпараметрадоступнойтаблицысхемызапроса типсоединениясхемызапроса httpметод автоиспользованиеобщегореквизита автопрефиксномеразадачи вариантвстроенногоязыка видиерархии видрегистранакопления видтаблицывнешнегоисточникаданных записьдвиженийприпроведении заполнениепоследовательностей индексирование использованиебазыпланавидоврасчета использованиебыстроговыбора использованиеобщегореквизита использованиеподчинения использованиеполнотекстовогопоиска использованиеразделяемыхданныхобщегореквизита использованиереквизита назначениеиспользованияприложения назначениерасширенияконфигурации направлениепередачи обновлениепредопределенныхданных оперативноепроведение основноепредставлениевидарасчета основноепредставлениевидахарактеристики основноепредставлениезадачи основноепредставлениепланаобмена основноепредставлениесправочника основноепредставлениесчета перемещениеграницыприпроведении периодичностьномерабизнеспроцесса периодичностьномерадокумента периодичностьрегистрарасчета периодичностьрегистрасведений повторноеиспользованиевозвращаемыхзначений полнотекстовыйпоискпривводепостроке принадлежностьобъекта проведение разделениеаутентификацииобщегореквизита разделениеданныхобщегореквизита разделениерасширенийконфигурацииобщегореквизита режимавтонумерацииобъектов режимзаписирегистра режимиспользованиямодальности режимиспользованиясинхронныхвызововрасширенийплатформыивнешнихкомпонент режимповторногоиспользованиясеансов режимполученияданныхвыборапривводепостроке режимсовместимости режимсовместимостиинтерфейса режимуправленияблокировкойданныхпоумолчанию сериикодовпланавидовхарактеристик сериикодовпланасчетов сериикодовсправочника созданиепривводе способвыбора способпоискастрокипривводепостроке способредактирования типданныхтаблицывнешнегоисточникаданных типкодапланавидоврасчета типкодасправочника типмакета типномерабизнеспроцесса типномерадокумента типномеразадачи типформы удалениедвижений важностьпроблемыприменениярасширенияконфигурации вариантинтерфейсаклиентскогоприложения вариантмасштабаформклиентскогоприложения вариантосновногошрифтаклиентскогоприложения вариантстандартногопериода вариантстандартнойдатыначала видграницы видкартинки видотображенияполнотекстовогопоиска видрамки видсравнения видцвета видчисловогозначения видшрифта допустимаядлина допустимыйзнак использованиеbyteordermark использованиеметаданныхполнотекстовогопоиска источникрасширенийконфигурации клавиша кодвозвратадиалога кодировкаxbase кодировкатекста направлениепоиска направлениесортировки обновлениепредопределенныхданных обновлениеприизмененииданных отображениепанелиразделов проверказаполнения режимдиалогавопрос режимзапускаклиентскогоприложения режимокругления режимоткрытияформприложения режимполнотекстовогопоиска скоростьклиентскогосоединения состояниевнешнегоисточникаданных состояниеобновленияконфигурациибазыданных способвыборасертификатаwindows способкодированиястроки статуссообщения типвнешнейкомпоненты типплатформы типповеденияклавишиenter типэлементаинформацииовыполненииобновленияконфигурациибазыданных уровеньизоляциитранзакций хешфункция частидаты","type":"comобъект ftpсоединение httpзапрос httpсервисответ httpсоединение wsопределения wsпрокси xbase анализданных аннотацияxs блокировкаданных буфердвоичныхданных включениеxs выражениекомпоновкиданных генераторслучайныхчисел географическаясхема географическиекоординаты графическаясхема группамоделиxs данныерасшифровкикомпоновкиданных двоичныеданные дендрограмма диаграмма диаграммаганта диалогвыборафайла диалогвыборацвета диалогвыборашрифта диалограсписаниярегламентногозадания диалогредактированиястандартногопериода диапазон документdom документhtml документацияxs доставляемоеуведомление записьdom записьfastinfoset записьhtml записьjson записьxml записьzipфайла записьданных записьтекста записьузловdom запрос защищенноесоединениеopenssl значенияполейрасшифровкикомпоновкиданных извлечениетекста импортxs интернетпочта интернетпочтовоесообщение интернетпочтовыйпрофиль интернетпрокси интернетсоединение информациядляприложенияxs использованиеатрибутаxs использованиесобытияжурналарегистрации источникдоступныхнастроеккомпоновкиданных итераторузловdom картинка квалификаторыдаты квалификаторыдвоичныхданных квалификаторыстроки квалификаторычисла компоновщикмакетакомпоновкиданных компоновщикнастроеккомпоновкиданных конструктормакетаоформлениякомпоновкиданных конструкторнастроеккомпоновкиданных конструкторформатнойстроки линия макеткомпоновкиданных макетобластикомпоновкиданных макетоформлениякомпоновкиданных маскаxs менеджеркриптографии наборсхемxml настройкикомпоновкиданных настройкисериализацииjson обработкакартинок обработкарасшифровкикомпоновкиданных обходдереваdom объявлениеатрибутаxs объявлениенотацииxs объявлениеэлементаxs описаниеиспользованиясобытиядоступжурналарегистрации описаниеиспользованиясобытияотказвдоступежурналарегистрации описаниеобработкирасшифровкикомпоновкиданных описаниепередаваемогофайла описаниетипов определениегруппыатрибутовxs определениегруппымоделиxs определениеограниченияидентичностиxs определениепростоготипаxs определениесоставноготипаxs определениетипадокументаdom определенияxpathxs отборкомпоновкиданных пакетотображаемыхдокументов параметрвыбора параметркомпоновкиданных параметрызаписиjson параметрызаписиxml параметрычтенияxml переопределениеxs планировщик полеанализаданных полекомпоновкиданных построительdom построительзапроса построительотчета построительотчетаанализаданных построительсхемxml поток потоквпамяти почта почтовоесообщение преобразованиеxsl преобразованиекканоническомуxml процессорвыводарезультатакомпоновкиданныхвколлекциюзначений процессорвыводарезультатакомпоновкиданныхвтабличныйдокумент процессоркомпоновкиданных разыменовательпространствименdom рамка расписаниерегламентногозадания расширенноеимяxml результатчтенияданных своднаядиаграмма связьпараметравыбора связьпотипу связьпотипукомпоновкиданных сериализаторxdto сертификатклиентаwindows сертификатклиентафайл сертификаткриптографии сертификатыудостоверяющихцентровwindows сертификатыудостоверяющихцентровфайл сжатиеданных системнаяинформация сообщениепользователю сочетаниеклавиш сравнениезначений стандартнаядатаначала стандартныйпериод схемаxml схемакомпоновкиданных табличныйдокумент текстовыйдокумент тестируемоеприложение типданныхxml уникальныйидентификатор фабрикаxdto файл файловыйпоток фасетдлиныxs фасетколичестваразрядовдробнойчастиxs фасетмаксимальноговключающегозначенияxs фасетмаксимальногоисключающегозначенияxs фасетмаксимальнойдлиныxs фасетминимальноговключающегозначенияxs фасетминимальногоисключающегозначенияxs фасетминимальнойдлиныxs фасетобразцаxs фасетобщегоколичестваразрядовxs фасетперечисленияxs фасетпробельныхсимволовxs фильтрузловdom форматированнаястрока форматированныйдокумент фрагментxs хешированиеданных хранилищезначения цвет чтениеfastinfoset чтениеhtml чтениеjson чтениеxml чтениеzipфайла чтениеданных чтениетекста чтениеузловdom шрифт элементрезультатакомпоновкиданных comsafearray деревозначений массив соответствие списокзначений структура таблицазначений фиксированнаяструктура фиксированноесоответствие фиксированныймассив ","literal":"null истина ложь неопределено"},"contains":[{"className":"meta","lexemes":"[A-Za-zА-Яа-яёЁ_][A-Za-zА-Яа-яёЁ_0-9]+","begin":"#|&","end":"$","keywords":{"meta-keyword":"далее возврат вызватьисключение выполнить для если и из или иначе иначеесли исключение каждого конецесли конецпопытки конеццикла не новый перейти перем по пока попытка прервать продолжить тогда цикл экспорт загрузитьизфайла вебклиент вместо внешнеесоединение клиент конецобласти мобильноеприложениеклиент мобильноеприложениесервер наклиенте наклиентенасервере наклиентенасерверебезконтекста насервере насерверебезконтекста область перед после сервер толстыйклиентобычноеприложение толстыйклиентуправляемоеприложение тонкийклиент "},"contains":[{"className":"comment","begin":"//","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]}]},{"className":"function","lexemes":"[A-Za-zА-Яа-яёЁ_][A-Za-zА-Яа-яёЁ_0-9]+","variants":[{"begin":"процедура|функция","end":"\\)","keywords":"процедура функция"},{"begin":"конецпроцедуры|конецфункции","keywords":"конецпроцедуры конецфункции"}],"contains":[{"begin":"\\(","end":"\\)","endsParent":true,"contains":[{"className":"params","lexemes":"[A-Za-zА-Яа-яёЁ_][A-Za-zА-Яа-яёЁ_0-9]+","begin":"[A-Za-zА-Яа-яёЁ_][A-Za-zА-Яа-яёЁ_0-9]+","end":",","excludeEnd":true,"endsWithParent":true,"keywords":{"keyword":"знач","literal":"null истина ложь неопределено"},"contains":[{"className":"number","begin":"\\b\\d+(\\.\\d+)?","relevance":0},{"className":"string","begin":"\"|\\|","end":"\"|$","contains":[{"begin":"\"\""}]},{"begin":"'","end":"'","excludeBegin":true,"excludeEnd":true,"contains":[{"className":"number","begin":"\\d{4}([\\.\\Q\\/:\\E-]?\\d{2}){0,5}"}]}]},{"$ref":"#contains.0.contains.0"}]},{"className":"title","begin":"[A-Za-zА-Яа-яёЁ_][A-Za-zА-Яа-яёЁ_0-9]+","relevance":0}]},{"$ref":"#contains.0.contains.0"},{"className":"symbol","begin":"~","end":";|:","excludeEnd":true},{"$ref":"#contains.1.contains.0.contains.0.contains.0"},{"$ref":"#contains.1.contains.0.contains.0.contains.1"},{"$ref":"#contains.1.contains.0.contains.0.contains.2"}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/abnf.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/abnf.json new file mode 100644 index 00000000..7590ddfe --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/abnf.json @@ -0,0 +1 @@ +{"illegal":"[!@#$^&',?+~`|:]","keywords":"ALPHA BIT CHAR CR CRLF CTL DIGIT DQUOTE HEXDIG HTAB LF LWSP OCTET SP VCHAR WSP","contains":[{"begin":"^[a-zA-Z][a-zA-Z0-9-]*\\s*=","returnBegin":true,"end":"=","relevance":0,"contains":[{"className":"attribute","begin":"^[a-zA-Z][a-zA-Z0-9-]*"}]},{"className":"comment","begin":";","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"symbol","begin":"%b[0-1]+(-[0-1]+|(\\.[0-1]+)+){0,1}"},{"className":"symbol","begin":"%d[0-9]+(-[0-9]+|(\\.[0-9]+)+){0,1}"},{"className":"symbol","begin":"%x[0-9A-F]+(-[0-9A-F]+|(\\.[0-9A-F]+)+){0,1}"},{"className":"symbol","begin":"%[si]"},{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0}]},{"className":"number","begin":"\\b\\d+(\\.\\d+)?","relevance":0}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/accesslog.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/accesslog.json new file mode 100644 index 00000000..19405505 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/accesslog.json @@ -0,0 +1 @@ +{"contains":[{"className":"number","begin":"\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}(:\\d{1,5})?\\b"},{"className":"number","begin":"\\b\\d+\\b","relevance":0},{"className":"string","begin":"\"(GET|POST|HEAD|PUT|DELETE|CONNECT|OPTIONS|PATCH|TRACE)","end":"\"","keywords":"GET POST HEAD PUT DELETE CONNECT OPTIONS PATCH TRACE","illegal":"\\n","relevance":10},{"className":"string","begin":"\\[","end":"\\]","illegal":"\\n"},{"className":"string","begin":"\"","end":"\"","illegal":"\\n"}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/actionscript.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/actionscript.json new file mode 100644 index 00000000..8a78ea21 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/actionscript.json @@ -0,0 +1 @@ +{"aliases":["as"],"keywords":{"keyword":"as break case catch class const continue default delete do dynamic each else extends final finally for function get if implements import in include instanceof interface internal is namespace native new override package private protected public return set static super switch this throw try typeof use var void while with","literal":"true false null undefined"},"contains":[{"className":"string","begin":"'","end":"'","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0}]},{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"$ref":"#contains.0.contains.0"}]},{"className":"comment","begin":"//","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"/\\*","end":"\\*/","contains":[{"$ref":"#contains.2.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"number","begin":"(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)","relevance":0},{"className":"class","beginKeywords":"package","end":"{","contains":[{"className":"title","begin":"[a-zA-Z]\\w*","relevance":0}]},{"className":"class","beginKeywords":"class interface","end":"{","excludeEnd":true,"contains":[{"beginKeywords":"extends implements"},{"$ref":"#contains.5.contains.0"}]},{"className":"meta","beginKeywords":"import include","end":";","keywords":{"meta-keyword":"import include"}},{"className":"function","beginKeywords":"function","end":"[{;]","excludeEnd":true,"illegal":"\\S","contains":[{"$ref":"#contains.5.contains.0"},{"className":"params","begin":"\\(","end":"\\)","contains":[{"$ref":"#contains.0"},{"$ref":"#contains.1"},{"$ref":"#contains.2"},{"$ref":"#contains.3"},{"className":"rest_arg","begin":"[.]{3}","end":"[a-zA-Z_$][a-zA-Z0-9_$]*","relevance":10}]},{"begin":":\\s*([*]|[a-zA-Z_$][a-zA-Z0-9_$]*)"}]},{"begin":"\\.\\s*[a-zA-Z_]\\w*","relevance":0}],"illegal":"#"} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/ada.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/ada.json new file mode 100644 index 00000000..e39ff0e5 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/ada.json @@ -0,0 +1 @@ +{"case_insensitive":true,"keywords":{"keyword":"abort else new return abs elsif not reverse abstract end accept entry select access exception of separate aliased exit or some all others subtype and for out synchronized array function overriding at tagged generic package task begin goto pragma terminate body private then if procedure type case in protected constant interface is raise use declare range delay limited record when delta loop rem while digits renames with do mod requeue xor","literal":"True False"},"contains":[{"className":"comment","begin":"--","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"string","begin":"\"","end":"\"","contains":[{"begin":"\"\"","relevance":0}]},{"className":"string","begin":"'.'"},{"className":"number","begin":"\\b(\\d(_|\\d)*#\\w+(\\.\\w+)?#([eE][-+]?\\d(_|\\d)*)?|\\d(_|\\d)*(\\.\\d(_|\\d)*)?([eE][-+]?\\d(_|\\d)*)?)","relevance":0},{"className":"symbol","begin":"'[A-Za-z](_?[A-Za-z0-9.])*"},{"className":"title","begin":"(\\bwith\\s+)?(\\bprivate\\s+)?\\bpackage\\s+(\\bbody\\s+)?","end":"(is|$)","keywords":"package body","excludeBegin":true,"excludeEnd":true,"illegal":"\\Q[]{}%#'\"\\E"},{"begin":"(\\b(with|overriding)\\s+)?\\b(function|procedure)\\s+","end":"(\\bis|\\bwith|\\brenames|\\)\\s*;)","keywords":"overriding function procedure with is renames return","returnBegin":true,"contains":[{"$ref":"#contains.0"},{"className":"title","begin":"(\\bwith\\s+)?\\b(function|procedure)\\s+","end":"(\\(|\\s+|$)","excludeBegin":true,"excludeEnd":true,"illegal":"\\Q[]{}%#'\"\\E"},{"begin":"\\s+:\\s+","end":"\\s*(:=|;|\\)|=>|$)","illegal":"\\Q[]{}%#'\"\\E","contains":[{"beginKeywords":"loop for declare others","endsParent":true},{"className":"keyword","beginKeywords":"not null constant access function procedure in out aliased exception"},{"className":"type","begin":"[A-Za-z](_?[A-Za-z0-9.])*","endsParent":true,"relevance":0}]},{"className":"type","begin":"\\breturn\\s+","end":"(\\s+|;|$)","keywords":"return","excludeBegin":true,"excludeEnd":true,"endsParent":true,"illegal":"\\Q[]{}%#'\"\\E"}]},{"className":"type","begin":"\\b(sub)?type\\s+","end":"\\s+","keywords":"type","excludeBegin":true,"illegal":"\\Q[]{}%#'\"\\E"},{"$ref":"#contains.6.contains.2"}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/angelscript.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/angelscript.json new file mode 100644 index 00000000..08cb021c --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/angelscript.json @@ -0,0 +1 @@ +{"aliases":["asc"],"keywords":"for in|0 break continue while do|0 return if else case switch namespace is cast or and xor not get|0 in inout|10 out override set|0 private public const default|0 final shared external mixin|10 enum typedef funcdef this super import from interface abstract|0 try catch protected explicit","illegal":"(^using\\s+[A-Za-z0-9_\\.]+;$|\\bfunctions*[^\\(])","contains":[{"className":"string","begin":"'","end":"'","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0}],"relevance":0},{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"$ref":"#contains.0.contains.0"}],"relevance":0},{"className":"string","begin":"\"\"\"","end":"\"\"\""},{"className":"comment","begin":"//","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"/\\*","end":"\\*/","contains":[{"$ref":"#contains.3.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"beginKeywords":"interface namespace","end":"{","illegal":"[;.\\-]","contains":[{"className":"symbol","begin":"[a-zA-Z0-9_]+"}]},{"beginKeywords":"class","end":"{","illegal":"[;.\\-]","contains":[{"className":"symbol","begin":"[a-zA-Z0-9_]+","contains":[{"begin":"[:,]\\s*","contains":[{"className":"symbol","begin":"[a-zA-Z0-9_]+"}]}]}]},{"className":"built_in","begin":"\\b(void|bool|int|int8|int16|int32|int64|uint|uint8|uint16|uint32|uint64|string|ref|array|double|float|auto|dictionary)","contains":[{"className":"keyword","begin":"<","end":">","contains":[{"$ref":"#contains.7"},{"className":"symbol","begin":"[a-zA-Z0-9_]+@","contains":[{"$ref":"#contains.7.contains.0"}]}]}]},{"$ref":"#contains.7.contains.0.contains.1"},{"className":"literal","begin":"\\b(null|true|false)"},{"className":"number","begin":"(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?f?|\\.\\d+f?)([eE][-+]?\\d+f?)?)"}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/apache.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/apache.json new file mode 100644 index 00000000..b6ec17ef --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/apache.json @@ -0,0 +1 @@ +{"aliases":["apacheconf"],"case_insensitive":true,"contains":[{"className":"comment","begin":"#","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"section","begin":""},{"className":"attribute","begin":"\\w+","relevance":0,"keywords":{"nomarkup":"order deny allow setenv rewriterule rewriteengine rewritecond documentroot sethandler errordocument loadmodule options header listen serverroot servername"},"starts":{"end":"$","relevance":0,"keywords":{"literal":"on off all"},"contains":[{"className":"meta","begin":"\\s\\[","end":"\\]$"},{"className":"variable","begin":"[\\$%]\\{","end":"\\}","contains":["self",{"className":"number","begin":"[\\$%]\\d+"}]},{"$ref":"#contains.2.starts.contains.1.contains.1"},{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0}]}]}}],"illegal":"\\S"} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/applescript.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/applescript.json new file mode 100644 index 00000000..e00d74cb --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/applescript.json @@ -0,0 +1 @@ +{"aliases":["osascript"],"keywords":{"keyword":"about above after against and around as at back before beginning behind below beneath beside between but by considering contain contains continue copy div does eighth else end equal equals error every exit fifth first for fourth from front get given global if ignoring in into is it its last local me middle mod my ninth not of on onto or over prop property put ref reference repeat returning script second set seventh since sixth some tell tenth that the|0 then third through thru timeout times to transaction try until where while whose with without","literal":"AppleScript false linefeed return pi quote result space tab true","built_in":"alias application boolean class constant date file integer list number real record string text activate beep count delay launch log offset read round run say summarize write character characters contents day frontmost id item length month name paragraph paragraphs rest reverse running time version weekday word words year"},"contains":[{"className":"string","begin":"\"","end":"\"","illegal":"","contains":[{"begin":"\\\\[\\s\\S]","relevance":0}]},{"className":"number","begin":"(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)","relevance":0},{"className":"built_in","begin":"\\b(clipboard info|the clipboard|info for|list (disks|folder)|mount volume|path to|(close|open for) access|(get|set) eof|current date|do shell script|get volume settings|random number|set volume|system attribute|system info|time to GMT|(load|run|store) script|scripting components|ASCII (character|number)|localized string|choose (application|color|file|file name|folder|from list|remote application|URL)|display (alert|dialog))\\b|^\\s*return\\b"},{"className":"literal","begin":"\\b(text item delimiters|current application|missing value)\\b"},{"className":"keyword","begin":"\\b(apart from|aside from|instead of|out of|greater than|isn't|(doesn't|does not) (equal|come before|come after|contain)|(greater|less) than( or equal)?|(starts?|ends|begins?) with|contained by|comes (before|after)|a (ref|reference)|POSIX file|POSIX path|(date|time) string|quoted form)\\b"},{"beginKeywords":"on","illegal":"[${=;\\n]","contains":[{"className":"title","begin":"[a-zA-Z_]\\w*","relevance":0},{"className":"params","begin":"\\(","end":"\\)","contains":["self",{"$ref":"#contains.1"},{"$ref":"#contains.0"}]}]},{"className":"comment","begin":"--","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"\\(\\*","end":"\\*\\)","contains":["self",{"$ref":"#contains.6"},{"$ref":"#contains.6.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"#","end":"$","contains":[{"$ref":"#contains.6.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]}],"illegal":"//|->|=>|\\[\\["} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/arcade.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/arcade.json new file mode 100644 index 00000000..b261a41a --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/arcade.json @@ -0,0 +1 @@ +{"aliases":["arcade"],"keywords":{"keyword":"if for while var new function do return void else break","literal":"true false null undefined NaN Infinity PI BackSlash DoubleQuote ForwardSlash NewLine SingleQuote Tab","built_in":"Abs Acos Area AreaGeodetic Asin Atan Atan2 Average Boolean Buffer BufferGeodetic Ceil Centroid Clip Console Constrain Contains Cos Count Crosses Cut Date DateAdd DateDiff Day Decode DefaultValue Dictionary Difference Disjoint Distance Distinct DomainCode DomainName Equals Exp Extent Feature FeatureSet FeatureSetById FeatureSetByTitle FeatureSetByUrl Filter First Floor Geometry Guid HasKey Hour IIf IndexOf Intersection Intersects IsEmpty Length LengthGeodetic Log Max Mean Millisecond Min Minute Month MultiPartToSinglePart Multipoint NextSequenceValue Now Number OrderBy Overlaps Point Polygon Polyline Pow Random Relate Reverse Round Second SetGeometry Sin Sort Sqrt Stdev Sum SymmetricDifference Tan Text Timestamp Today ToLocal Top Touches ToUTC TypeOf Union Variance Weekday When Within Year "},"contains":[{"className":"string","begin":"'","end":"'","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0}]},{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"$ref":"#contains.0.contains.0"}]},{"className":"string","begin":"`","end":"`","contains":[{"$ref":"#contains.0.contains.0"},{"className":"subst","begin":"\\$\\{","end":"\\}","keywords":{"$ref":"#keywords"},"contains":[{"$ref":"#contains.0"},{"$ref":"#contains.1"},{"$ref":"#contains.2"},{"className":"number","variants":[{"begin":"\\b(0[bB][01]+)"},{"begin":"\\b(0[oO][0-7]+)"},{"begin":"(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)"}],"relevance":0},{"className":"regexp","begin":"\\/","end":"\\/[gimuy]*","illegal":"\\n","contains":[{"$ref":"#contains.0.contains.0"},{"begin":"\\[","end":"\\]","relevance":0,"contains":[{"$ref":"#contains.0.contains.0"}]}]}]}]},{"className":"comment","begin":"//","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"/\\*","end":"\\*/","contains":[{"$ref":"#contains.3.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"symbol","begin":"\\$[feature|layer|map|value|view]+"},{"$ref":"#contains.2.contains.1.contains.3"},{"begin":"[{,]\\s*","relevance":0,"contains":[{"begin":"[A-Za-z_][0-9A-Za-z_]*\\s*:","returnBegin":true,"relevance":0,"contains":[{"className":"attr","begin":"[A-Za-z_][0-9A-Za-z_]*","relevance":0}]}]},{"begin":"(!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~|\\b(return)\\b)\\s*","keywords":"return","contains":[{"$ref":"#contains.3"},{"$ref":"#contains.4"},{"$ref":"#contains.2.contains.1.contains.4"},{"className":"function","begin":"(\\(.*?\\)|[A-Za-z_][0-9A-Za-z_]*)\\s*=>","returnBegin":true,"end":"\\s*=>","contains":[{"className":"params","variants":[{"begin":"[A-Za-z_][0-9A-Za-z_]*"},{"begin":"\\(\\s*\\)"},{"begin":"\\(","end":"\\)","excludeBegin":true,"excludeEnd":true,"keywords":{"$ref":"#keywords"},"contains":[{"$ref":"#contains.0"},{"$ref":"#contains.1"},{"$ref":"#contains.2"},{"$ref":"#contains.2.contains.1.contains.3"},{"$ref":"#contains.2.contains.1.contains.4"},{"$ref":"#contains.4"},{"$ref":"#contains.3"}]}]}]}],"relevance":0},{"className":"function","beginKeywords":"function","end":"\\{","excludeEnd":true,"contains":[{"className":"title","begin":"[A-Za-z_][0-9A-Za-z_]*","relevance":0},{"className":"params","begin":"\\(","end":"\\)","excludeBegin":true,"excludeEnd":true,"contains":{"$ref":"#contains.8.contains.3.contains.0.variants.2.contains"}}],"illegal":"\\[|%"},{"begin":"\\$[(.]"}],"illegal":"#(?!!)"} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/arduino.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/arduino.json new file mode 100644 index 00000000..f3440543 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/arduino.json @@ -0,0 +1 @@ +{"keywords":{"keyword":"boolean byte word string String array int float while private char catch import module export virtual operator sizeof dynamic_cast|10 typedef const_cast|10 const for static_cast|10 union namespace unsigned long volatile static protected bool template mutable if public friend do goto auto void enum else break extern using asm case typeid short reinterpret_cast|10 default double register explicit signed typename try this switch continue inline delete alignof constexpr decltype noexcept static_assert thread_local restrict _Bool complex _Complex _Imaginary atomic_bool atomic_char atomic_schar atomic_uchar atomic_short atomic_ushort atomic_int atomic_uint atomic_long atomic_ulong atomic_llong atomic_ullong new throw return and or not","built_in":"setup loop while catch for if do goto try switch case else default break continue return KeyboardController MouseController SoftwareSerial EthernetServer EthernetClient LiquidCrystal RobotControl GSMVoiceCall EthernetUDP EsploraTFT HttpClient RobotMotor WiFiClient GSMScanner FileSystem Scheduler GSMServer YunClient YunServer IPAddress GSMClient GSMModem Keyboard Ethernet Console GSMBand Esplora Stepper Process WiFiUDP GSM_SMS Mailbox USBHost Firmata PImage Client Server GSMPIN FileIO Bridge Serial EEPROM Stream Mouse Audio Servo File Task GPRS WiFi Wire TFT GSM SPI SD runShellCommandAsynchronously analogWriteResolution retrieveCallingNumber printFirmwareVersion analogReadResolution sendDigitalPortPair noListenOnLocalhost readJoystickButton setFirmwareVersion readJoystickSwitch scrollDisplayRight getVoiceCallStatus scrollDisplayLeft writeMicroseconds delayMicroseconds beginTransmission getSignalStrength runAsynchronously getAsynchronously listenOnLocalhost getCurrentCarrier readAccelerometer messageAvailable sendDigitalPorts lineFollowConfig countryNameWrite runShellCommand readStringUntil rewindDirectory readTemperature setClockDivider readLightSensor endTransmission analogReference detachInterrupt countryNameRead attachInterrupt encryptionType readBytesUntil robotNameWrite readMicrophone robotNameRead cityNameWrite userNameWrite readJoystickY readJoystickX mouseReleased openNextFile scanNetworks noInterrupts digitalWrite beginSpeaker mousePressed isActionDone mouseDragged displayLogos noAutoscroll addParameter remoteNumber getModifiers keyboardRead userNameRead waitContinue processInput parseCommand printVersion readNetworks writeMessage blinkVersion cityNameRead readMessage setDataMode parsePacket isListening setBitOrder beginPacket isDirectory motorsWrite drawCompass digitalRead clearScreen serialEvent rightToLeft setTextSize leftToRight requestFrom keyReleased compassRead analogWrite interrupts WiFiServer disconnect playMelody parseFloat autoscroll getPINUsed setPINUsed setTimeout sendAnalog readSlider analogRead beginWrite createChar motorsStop keyPressed tempoWrite readButton subnetMask debugPrint macAddress writeGreen randomSeed attachGPRS readString sendString remotePort releaseAll mouseMoved background getXChange getYChange answerCall getResult voiceCall endPacket constrain getSocket writeJSON getButton available connected findUntil readBytes exitValue readGreen writeBlue startLoop IPAddress isPressed sendSysex pauseMode gatewayIP setCursor getOemKey tuneWrite noDisplay loadImage switchPIN onRequest onReceive changePIN playFile noBuffer parseInt overflow checkPIN knobRead beginTFT bitClear updateIR bitWrite position writeRGB highByte writeRed setSpeed readBlue noStroke remoteIP transfer shutdown hangCall beginSMS endWrite attached maintain noCursor checkReg checkPUK shiftOut isValid shiftIn pulseIn connect println localIP pinMode getIMEI display noBlink process getBand running beginSD drawBMP lowByte setBand release bitRead prepare pointTo readRed setMode noFill remove listen stroke detach attach noTone exists buffer height bitSet circle config cursor random IRread setDNS endSMS getKey micros millis begin print write ready flush width isPIN blink clear press mkdir rmdir close point yield image BSSID click delay read text move peek beep rect line open seek fill size turn stop home find step tone sqrt RSSI SSID end bit tan cos sin pow map abs max min get run put","literal":"DIGITAL_MESSAGE FIRMATA_STRING ANALOG_MESSAGE REPORT_DIGITAL REPORT_ANALOG INPUT_PULLUP SET_PIN_MODE INTERNAL2V56 SYSTEM_RESET LED_BUILTIN INTERNAL1V1 SYSEX_START INTERNAL EXTERNAL DEFAULT OUTPUT INPUT HIGH LOW"},"contains":[{"className":"meta","begin":"#\\s*[a-z]+\\b","end":"$","keywords":{"meta-keyword":"if else elif endif define undef warning error line pragma ifdef ifndef include"},"contains":[{"begin":"\\\\\\n","relevance":0},{"className":"meta-string","variants":[{"begin":"(u8?|U|L)?\"","end":"\"","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0}]},{"begin":"(?:u8?|U|L)?R\"([^()\\\\ ]{0,16})\\((?:.|\\n)*?\\)\\1\""},{"begin":"'\\\\?.","end":"'","illegal":"."}]},{"className":"meta-string","begin":"<[^\\n>]*>","end":"$","illegal":"\\n"},{"className":"comment","begin":"//","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"/\\*","end":"\\*/","contains":[{"$ref":"#contains.0.contains.3.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]}]},{"$ref":"#contains.0.contains.3"},{"$ref":"#contains.0.contains.4"},{"className":"string","begin":"'","end":"'","illegal":"\\n","contains":[{"$ref":"#contains.0.contains.1.variants.0.contains.0"}]},{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"$ref":"#contains.0.contains.1.variants.0.contains.0"},{"className":"subst","begin":"\\\\[abfnrtv]\\|\\\\x[0-9a-fA-F]*\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]","relevance":0},{"className":"subst","begin":"\\\\[abfnrtv]\\|\\\\x[0-9a-fA-F]*\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]","relevance":0}]},{"className":"number","begin":"(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)","relevance":0}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/armasm.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/armasm.json new file mode 100644 index 00000000..b1e43aa8 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/armasm.json @@ -0,0 +1 @@ +{"case_insensitive":true,"aliases":["arm"],"lexemes":"\\.?[a-zA-Z]\\w*","keywords":{"meta":".2byte .4byte .align .ascii .asciz .balign .byte .code .data .else .end .endif .endm .endr .equ .err .exitm .extern .global .hword .if .ifdef .ifndef .include .irp .long .macro .rept .req .section .set .skip .space .text .word .arm .thumb .code16 .code32 .force_thumb .thumb_func .ltorg ALIAS ALIGN ARM AREA ASSERT ATTR CN CODE CODE16 CODE32 COMMON CP DATA DCB DCD DCDU DCDO DCFD DCFDU DCI DCQ DCQU DCW DCWU DN ELIF ELSE END ENDFUNC ENDIF ENDP ENTRY EQU EXPORT EXPORTAS EXTERN FIELD FILL FUNCTION GBLA GBLL GBLS GET GLOBAL IF IMPORT INCBIN INCLUDE INFO KEEP LCLA LCLL LCLS LTORG MACRO MAP MEND MEXIT NOFP OPT PRESERVE8 PROC QN READONLY RELOC REQUIRE REQUIRE8 RLIST FN ROUT SETA SETL SETS SN SPACE SUBT THUMB THUMBX TTL WHILE WEND ","built_in":"r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 r13 r14 r15 pc lr sp ip sl sb fp a1 a2 a3 a4 v1 v2 v3 v4 v5 v6 v7 v8 f0 f1 f2 f3 f4 f5 f6 f7 p0 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14 p15 c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 q0 q1 q2 q3 q4 q5 q6 q7 q8 q9 q10 q11 q12 q13 q14 q15 cpsr_c cpsr_x cpsr_s cpsr_f cpsr_cx cpsr_cxs cpsr_xs cpsr_xsf cpsr_sf cpsr_cxsf spsr_c spsr_x spsr_s spsr_f spsr_cx spsr_cxs spsr_xs spsr_xsf spsr_sf spsr_cxsf s0 s1 s2 s3 s4 s5 s6 s7 s8 s9 s10 s11 s12 s13 s14 s15 s16 s17 s18 s19 s20 s21 s22 s23 s24 s25 s26 s27 s28 s29 s30 s31 d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 d10 d11 d12 d13 d14 d15 d16 d17 d18 d19 d20 d21 d22 d23 d24 d25 d26 d27 d28 d29 d30 d31 {PC} {VAR} {TRUE} {FALSE} {OPT} {CONFIG} {ENDIAN} {CODESIZE} {CPU} {FPU} {ARCHITECTURE} {PCSTOREOFFSET} {ARMASM_VERSION} {INTER} {ROPI} {RWPI} {SWST} {NOSWST} . @"},"contains":[{"className":"keyword","begin":"\\b(adc|(qd?|sh?|u[qh]?)?add(8|16)?|usada?8|(q|sh?|u[qh]?)?(as|sa)x|and|adrl?|sbc|rs[bc]|asr|b[lx]?|blx|bxj|cbn?z|tb[bh]|bic|bfc|bfi|[su]bfx|bkpt|cdp2?|clz|clrex|cmp|cmn|cpsi[ed]|cps|setend|dbg|dmb|dsb|eor|isb|it[te]{0,3}|lsl|lsr|ror|rrx|ldm(([id][ab])|f[ds])?|ldr((s|ex)?[bhd])?|movt?|mvn|mra|mar|mul|[us]mull|smul[bwt][bt]|smu[as]d|smmul|smmla|mla|umlaal|smlal?([wbt][bt]|d)|mls|smlsl?[ds]|smc|svc|sev|mia([bt]{2}|ph)?|mrr?c2?|mcrr2?|mrs|msr|orr|orn|pkh(tb|bt)|rbit|rev(16|sh)?|sel|[su]sat(16)?|nop|pop|push|rfe([id][ab])?|stm([id][ab])?|str(ex)?[bhd]?|(qd?)?sub|(sh?|q|u[qh]?)?sub(8|16)|[su]xt(a?h|a?b(16)?)|srs([id][ab])?|swpb?|swi|smi|tst|teq|wfe|wfi|yield)(eq|ne|cs|cc|mi|pl|vs|vc|hi|ls|ge|lt|gt|le|al|hs|lo)?[sptrx]?","end":"\\s"},{"className":"comment","begin":"[;@]","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}],"relevance":0},{"className":"comment","begin":"/\\*","end":"\\*/","contains":[{"$ref":"#contains.1.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0}]},{"className":"string","begin":"'","end":"[^\\\\]'","relevance":0},{"className":"title","begin":"\\|","end":"\\|","illegal":"\\n","relevance":0},{"className":"number","variants":[{"begin":"[#$=]?0x[0-9a-f]+"},{"begin":"[#$=]?0b[01]+"},{"begin":"[#$=]\\d+"},{"begin":"\\b\\d+"}],"relevance":0},{"className":"symbol","variants":[{"begin":"^[a-z_\\.\\$][a-z0-9_\\.\\$]+"},{"begin":"^\\s*[a-z_\\.\\$][a-z0-9_\\.\\$]+:"},{"begin":"[=#]\\w+"}],"relevance":0}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/asciidoc.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/asciidoc.json new file mode 100644 index 00000000..5fccf25e --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/asciidoc.json @@ -0,0 +1 @@ +{"aliases":["adoc"],"contains":[{"className":"comment","begin":"^/{4,}\\n","end":"\\n/{4,}$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}],"relevance":10},{"className":"comment","begin":"^//","end":"$","contains":[{"$ref":"#contains.0.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}],"relevance":0},{"className":"title","begin":"^\\.\\w.*$"},{"begin":"^[=\\*]{4,}\\n","end":"\\n^[=\\*]{4,}$","relevance":10},{"className":"section","relevance":10,"variants":[{"begin":"^(={1,5}) .+?( \\1)?$"},{"begin":"^[^\\[\\]\\n]+?\\n[=\\-~\\^\\+]{2,}$"}]},{"className":"meta","begin":"^:.+?:","end":"\\s","excludeEnd":true,"relevance":10},{"className":"meta","begin":"^\\[.+?\\]$","relevance":0},{"className":"quote","begin":"^_{4,}\\n","end":"\\n_{4,}$","relevance":10},{"className":"code","begin":"^[\\-\\.]{4,}\\n","end":"\\n[\\-\\.]{4,}$","relevance":10},{"begin":"^\\+{4,}\\n","end":"\\n\\+{4,}$","contains":[{"begin":"<","end":">","subLanguage":"xml","relevance":0}],"relevance":10},{"className":"bullet","begin":"^(\\*+|\\-+|\\.+|[^\\n]+?::)\\s+"},{"className":"symbol","begin":"^(NOTE|TIP|IMPORTANT|WARNING|CAUTION):\\s+","relevance":10},{"className":"strong","begin":"\\B\\*(?![\\*\\s])","end":"(\\n{2}|\\*)","contains":[{"begin":"\\\\*\\w","relevance":0}]},{"className":"emphasis","begin":"\\B'(?!['\\s])","end":"(\\n{2}|')","contains":[{"begin":"\\\\'\\w","relevance":0}],"relevance":0},{"className":"emphasis","begin":"_(?![_\\s])","end":"(\\n{2}|_)","relevance":0},{"className":"string","variants":[{"begin":"``.+?''"},{"begin":"`.+?'"}]},{"className":"code","begin":"(`.+?`|\\+.+?\\+)","relevance":0},{"className":"code","begin":"^[ \\t]","end":"$","relevance":0},{"begin":"^'{3,}[ \\t]*$","relevance":10},{"begin":"(link:)?(http|https|ftp|file|irc|image:?):\\S+\\[.*?\\]","returnBegin":true,"contains":[{"begin":"(link|image:?):","relevance":0},{"className":"link","begin":"\\w","end":"[^\\[]+","relevance":0},{"className":"string","begin":"\\[","end":"\\]","excludeBegin":true,"excludeEnd":true,"relevance":0}],"relevance":10}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/aspectj.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/aspectj.json new file mode 100644 index 00000000..c6d5a54b --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/aspectj.json @@ -0,0 +1 @@ +{"keywords":"false synchronized int abstract float private char boolean static null if const for true while long throw strictfp finally protected import native final return void enum else extends implements break transient new catch instanceof byte super volatile case assert short package default double public try this switch continue throws privileged aspectOf adviceexecution proceed cflowbelow cflow initialization preinitialization staticinitialization withincode target within execution getWithinTypeName handler thisJoinPoint thisJoinPointStaticPart thisEnclosingJoinPointStaticPart declare parents warning error soft precedence thisAspectInstance","illegal":"<\\/|#","contains":[{"className":"comment","begin":"/\\*\\*","end":"\\*/","contains":[{"begin":"\\w+@","relevance":0},{"className":"doctag","begin":"@[A-Za-z]+"},{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}],"relevance":0},{"className":"comment","begin":"//","end":"$","contains":[{"$ref":"#contains.0.contains.2"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"/\\*","end":"\\*/","contains":[{"$ref":"#contains.0.contains.2"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"string","begin":"'","end":"'","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0}]},{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"$ref":"#contains.3.contains.0"}]},{"className":"class","beginKeywords":"aspect","end":"[{;=]","excludeEnd":true,"illegal":"[:;\"\\[\\]]","contains":[{"beginKeywords":"extends implements pertypewithin perthis pertarget percflowbelow percflow issingleton"},{"className":"title","begin":"[a-zA-Z_]\\w*","relevance":0},{"begin":"\\([^\\)]*","end":"[)]+","keywords":"false synchronized int abstract float private char boolean static null if const for true while long throw strictfp finally protected import native final return void enum else extends implements break transient new catch instanceof byte super volatile case assert short package default double public try this switch continue throws privileged aspectOf adviceexecution proceed cflowbelow cflow initialization preinitialization staticinitialization withincode target within execution getWithinTypeName handler thisJoinPoint thisJoinPointStaticPart thisEnclosingJoinPointStaticPart declare parents warning error soft precedence thisAspectInstance get set args call","excludeEnd":false}]},{"className":"class","beginKeywords":"class interface","end":"[{;=]","excludeEnd":true,"relevance":0,"keywords":"class interface","illegal":"[:\"\\[\\]]","contains":[{"beginKeywords":"extends implements"},{"$ref":"#contains.5.contains.1"}]},{"beginKeywords":"pointcut after before around throwing returning","end":"[)]","excludeEnd":false,"illegal":"[\"\\[\\]]","contains":[{"begin":"[a-zA-Z_]\\w*\\s*\\(","returnBegin":true,"contains":[{"$ref":"#contains.5.contains.1"}]}]},{"begin":"[:]","returnBegin":true,"end":"[{;]","relevance":0,"excludeEnd":false,"keywords":"false synchronized int abstract float private char boolean static null if const for true while long throw strictfp finally protected import native final return void enum else extends implements break transient new catch instanceof byte super volatile case assert short package default double public try this switch continue throws privileged aspectOf adviceexecution proceed cflowbelow cflow initialization preinitialization staticinitialization withincode target within execution getWithinTypeName handler thisJoinPoint thisJoinPointStaticPart thisEnclosingJoinPointStaticPart declare parents warning error soft precedence thisAspectInstance","illegal":"[\"\\[\\]]","contains":[{"begin":"[a-zA-Z_]\\w*\\s*\\(","keywords":"false synchronized int abstract float private char boolean static null if const for true while long throw strictfp finally protected import native final return void enum else extends implements break transient new catch instanceof byte super volatile case assert short package default double public try this switch continue throws privileged aspectOf adviceexecution proceed cflowbelow cflow initialization preinitialization staticinitialization withincode target within execution getWithinTypeName handler thisJoinPoint thisJoinPointStaticPart thisEnclosingJoinPointStaticPart declare parents warning error soft precedence thisAspectInstance get set args call","relevance":0},{"$ref":"#contains.4"}]},{"beginKeywords":"new throw","relevance":0},{"className":"function","begin":"\\w+ +\\w+(\\.)?\\w+\\s*\\([^\\)]*\\)\\s*((throws)[\\w\\s,]+)?[\\{;]","returnBegin":true,"end":"[{;=]","keywords":"false synchronized int abstract float private char boolean static null if const for true while long throw strictfp finally protected import native final return void enum else extends implements break transient new catch instanceof byte super volatile case assert short package default double public try this switch continue throws privileged aspectOf adviceexecution proceed cflowbelow cflow initialization preinitialization staticinitialization withincode target within execution getWithinTypeName handler thisJoinPoint thisJoinPointStaticPart thisEnclosingJoinPointStaticPart declare parents warning error soft precedence thisAspectInstance","excludeEnd":true,"contains":[{"begin":"[a-zA-Z_]\\w*\\s*\\(","returnBegin":true,"relevance":0,"contains":[{"$ref":"#contains.5.contains.1"}]},{"className":"params","begin":"\\(","end":"\\)","relevance":0,"keywords":"false synchronized int abstract float private char boolean static null if const for true while long throw strictfp finally protected import native final return void enum else extends implements break transient new catch instanceof byte super volatile case assert short package default double public try this switch continue throws privileged aspectOf adviceexecution proceed cflowbelow cflow initialization preinitialization staticinitialization withincode target within execution getWithinTypeName handler thisJoinPoint thisJoinPointStaticPart thisEnclosingJoinPointStaticPart declare parents warning error soft precedence thisAspectInstance","contains":[{"$ref":"#contains.3"},{"$ref":"#contains.4"},{"className":"number","begin":"(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)","relevance":0},{"$ref":"#contains.2"}]},{"$ref":"#contains.1"},{"$ref":"#contains.2"}]},{"$ref":"#contains.10.contains.1.contains.2"},{"className":"meta","begin":"@[A-Za-z]+"}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/autohotkey.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/autohotkey.json new file mode 100644 index 00000000..04fe7981 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/autohotkey.json @@ -0,0 +1 @@ +{"case_insensitive":true,"aliases":["ahk"],"keywords":{"keyword":"Break Continue Critical Exit ExitApp Gosub Goto New OnExit Pause return SetBatchLines SetTimer Suspend Thread Throw Until ahk_id ahk_class ahk_pid ahk_exe ahk_group","literal":"true false NOT AND OR","built_in":"ComSpec Clipboard ClipboardAll ErrorLevel"},"contains":[{"begin":"`[\\s\\S]"},{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"$ref":"#contains.0"}]},{"className":"comment","begin":";","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}],"relevance":0},{"className":"comment","begin":"/\\*","end":"\\*/","contains":[{"$ref":"#contains.2.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"number","begin":"\\b\\d+(\\.\\d+)?","relevance":0},{"className":"variable","begin":"%[a-zA-Z0-9#_$@]+%"},{"className":"built_in","begin":"^\\s*\\w+\\s*(,|%)"},{"className":"title","variants":[{"begin":"^[^\\n\";]+::(?!=)"},{"begin":"^[^\\n\";]+:(?!=)","relevance":0}]},{"className":"meta","begin":"^\\s*#\\w+","end":"$","relevance":0},{"className":"built_in","begin":"A_[a-zA-Z0-9]+"},{"begin":",\\s*,"}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/autoit.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/autoit.json new file mode 100644 index 00000000..b8da42fc --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/autoit.json @@ -0,0 +1 @@ +{"case_insensitive":true,"illegal":"\\/\\*","keywords":{"keyword":"ByRef Case Const ContinueCase ContinueLoop Default Dim Do Else ElseIf EndFunc EndIf EndSelect EndSwitch EndWith Enum Exit ExitLoop For Func Global If In Local Next ReDim Return Select Static Step Switch Then To Until Volatile WEnd While With","built_in":"Abs ACos AdlibRegister AdlibUnRegister Asc AscW ASin Assign ATan AutoItSetOption AutoItWinGetTitle AutoItWinSetTitle Beep Binary BinaryLen BinaryMid BinaryToString BitAND BitNOT BitOR BitRotate BitShift BitXOR BlockInput Break Call CDTray Ceiling Chr ChrW ClipGet ClipPut ConsoleRead ConsoleWrite ConsoleWriteError ControlClick ControlCommand ControlDisable ControlEnable ControlFocus ControlGetFocus ControlGetHandle ControlGetPos ControlGetText ControlHide ControlListView ControlMove ControlSend ControlSetText ControlShow ControlTreeView Cos Dec DirCopy DirCreate DirGetSize DirMove DirRemove DllCall DllCallAddress DllCallbackFree DllCallbackGetPtr DllCallbackRegister DllClose DllOpen DllStructCreate DllStructGetData DllStructGetPtr DllStructGetSize DllStructSetData DriveGetDrive DriveGetFileSystem DriveGetLabel DriveGetSerial DriveGetType DriveMapAdd DriveMapDel DriveMapGet DriveSetLabel DriveSpaceFree DriveSpaceTotal DriveStatus EnvGet EnvSet EnvUpdate Eval Execute Exp FileChangeDir FileClose FileCopy FileCreateNTFSLink FileCreateShortcut FileDelete FileExists FileFindFirstFile FileFindNextFile FileFlush FileGetAttrib FileGetEncoding FileGetLongName FileGetPos FileGetShortcut FileGetShortName FileGetSize FileGetTime FileGetVersion FileInstall FileMove FileOpen FileOpenDialog FileRead FileReadLine FileReadToArray FileRecycle FileRecycleEmpty FileSaveDialog FileSelectFolder FileSetAttrib FileSetEnd FileSetPos FileSetTime FileWrite FileWriteLine Floor FtpSetProxy FuncName GUICreate GUICtrlCreateAvi GUICtrlCreateButton GUICtrlCreateCheckbox GUICtrlCreateCombo GUICtrlCreateContextMenu GUICtrlCreateDate GUICtrlCreateDummy GUICtrlCreateEdit GUICtrlCreateGraphic GUICtrlCreateGroup GUICtrlCreateIcon GUICtrlCreateInput GUICtrlCreateLabel GUICtrlCreateList GUICtrlCreateListView GUICtrlCreateListViewItem GUICtrlCreateMenu GUICtrlCreateMenuItem GUICtrlCreateMonthCal GUICtrlCreateObj GUICtrlCreatePic GUICtrlCreateProgress GUICtrlCreateRadio GUICtrlCreateSlider GUICtrlCreateTab GUICtrlCreateTabItem GUICtrlCreateTreeView GUICtrlCreateTreeViewItem GUICtrlCreateUpdown GUICtrlDelete GUICtrlGetHandle GUICtrlGetState GUICtrlRead GUICtrlRecvMsg GUICtrlRegisterListViewSort GUICtrlSendMsg GUICtrlSendToDummy GUICtrlSetBkColor GUICtrlSetColor GUICtrlSetCursor GUICtrlSetData GUICtrlSetDefBkColor GUICtrlSetDefColor GUICtrlSetFont GUICtrlSetGraphic GUICtrlSetImage GUICtrlSetLimit GUICtrlSetOnEvent GUICtrlSetPos GUICtrlSetResizing GUICtrlSetState GUICtrlSetStyle GUICtrlSetTip GUIDelete GUIGetCursorInfo GUIGetMsg GUIGetStyle GUIRegisterMsg GUISetAccelerators GUISetBkColor GUISetCoord GUISetCursor GUISetFont GUISetHelp GUISetIcon GUISetOnEvent GUISetState GUISetStyle GUIStartGroup GUISwitch Hex HotKeySet HttpSetProxy HttpSetUserAgent HWnd InetClose InetGet InetGetInfo InetGetSize InetRead IniDelete IniRead IniReadSection IniReadSectionNames IniRenameSection IniWrite IniWriteSection InputBox Int IsAdmin IsArray IsBinary IsBool IsDeclared IsDllStruct IsFloat IsFunc IsHWnd IsInt IsKeyword IsNumber IsObj IsPtr IsString Log MemGetStats Mod MouseClick MouseClickDrag MouseDown MouseGetCursor MouseGetPos MouseMove MouseUp MouseWheel MsgBox Number ObjCreate ObjCreateInterface ObjEvent ObjGet ObjName OnAutoItExitRegister OnAutoItExitUnRegister Ping PixelChecksum PixelGetColor PixelSearch ProcessClose ProcessExists ProcessGetStats ProcessList ProcessSetPriority ProcessWait ProcessWaitClose ProgressOff ProgressOn ProgressSet Ptr Random RegDelete RegEnumKey RegEnumVal RegRead RegWrite Round Run RunAs RunAsWait RunWait Send SendKeepActive SetError SetExtended ShellExecute ShellExecuteWait Shutdown Sin Sleep SoundPlay SoundSetWaveVolume SplashImageOn SplashOff SplashTextOn Sqrt SRandom StatusbarGetText StderrRead StdinWrite StdioClose StdoutRead String StringAddCR StringCompare StringFormat StringFromASCIIArray StringInStr StringIsAlNum StringIsAlpha StringIsASCII StringIsDigit StringIsFloat StringIsInt StringIsLower StringIsSpace StringIsUpper StringIsXDigit StringLeft StringLen StringLower StringMid StringRegExp StringRegExpReplace StringReplace StringReverse StringRight StringSplit StringStripCR StringStripWS StringToASCIIArray StringToBinary StringTrimLeft StringTrimRight StringUpper Tan TCPAccept TCPCloseSocket TCPConnect TCPListen TCPNameToIP TCPRecv TCPSend TCPShutdown, UDPShutdown TCPStartup, UDPStartup TimerDiff TimerInit ToolTip TrayCreateItem TrayCreateMenu TrayGetMsg TrayItemDelete TrayItemGetHandle TrayItemGetState TrayItemGetText TrayItemSetOnEvent TrayItemSetState TrayItemSetText TraySetClick TraySetIcon TraySetOnEvent TraySetPauseIcon TraySetState TraySetToolTip TrayTip UBound UDPBind UDPCloseSocket UDPOpen UDPRecv UDPSend VarGetType WinActivate WinActive WinClose WinExists WinFlash WinGetCaretPos WinGetClassList WinGetClientSize WinGetHandle WinGetPos WinGetProcess WinGetState WinGetText WinGetTitle WinKill WinList WinMenuSelectItem WinMinimizeAll WinMinimizeAllUndo WinMove WinSetOnTop WinSetState WinSetTitle WinSetTrans WinWait","literal":"True False And Null Not Or"},"contains":[{"variants":[{"className":"comment","begin":";","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}],"relevance":0},{"className":"comment","begin":"#cs","end":"#ce","contains":[{"$ref":"#contains.0.variants.0.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"#comments-start","end":"#comments-end","contains":[{"$ref":"#contains.0.variants.0.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]}]},{"begin":"\\$[A-z0-9_]+"},{"className":"string","variants":[{"begin":"\"","end":"\"","contains":[{"begin":"\"\"","relevance":0}]},{"begin":"'","end":"'","contains":[{"begin":"''","relevance":0}]}]},{"variants":[{"className":"number","begin":"\\b(0b[01]+)","relevance":0},{"className":"number","begin":"(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)","relevance":0}]},{"className":"meta","begin":"#","end":"$","keywords":{"meta-keyword":"comments include include-once NoTrayIcon OnAutoItStartRegister pragma compile RequireAdmin"},"contains":[{"begin":"\\\\\\n","relevance":0},{"beginKeywords":"include","keywords":{"meta-keyword":"include"},"end":"$","contains":[{"$ref":"#contains.2"},{"className":"meta-string","variants":[{"begin":"<","end":">"},{"begin":"\"","end":"\"","contains":[{"begin":"\"\"","relevance":0}]},{"begin":"'","end":"'","contains":[{"begin":"''","relevance":0}]}]}]},{"$ref":"#contains.2"},{"$ref":"#contains.0"}]},{"className":"symbol","begin":"@[A-z0-9_]+"},{"className":"function","beginKeywords":"Func","end":"$","illegal":"\\$|\\[|%","contains":[{"className":"title","begin":"[a-zA-Z_]\\w*","relevance":0},{"className":"params","begin":"\\(","end":"\\)","contains":[{"$ref":"#contains.1"},{"$ref":"#contains.2"},{"$ref":"#contains.3"}]}]}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/avrasm.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/avrasm.json new file mode 100644 index 00000000..e35344b4 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/avrasm.json @@ -0,0 +1 @@ +{"case_insensitive":true,"lexemes":"\\.?[a-zA-Z]\\w*","keywords":{"keyword":"adc add adiw and andi asr bclr bld brbc brbs brcc brcs break breq brge brhc brhs brid brie brlo brlt brmi brne brpl brsh brtc brts brvc brvs bset bst call cbi cbr clc clh cli cln clr cls clt clv clz com cp cpc cpi cpse dec eicall eijmp elpm eor fmul fmuls fmulsu icall ijmp in inc jmp ld ldd ldi lds lpm lsl lsr mov movw mul muls mulsu neg nop or ori out pop push rcall ret reti rjmp rol ror sbc sbr sbrc sbrs sec seh sbi sbci sbic sbis sbiw sei sen ser ses set sev sez sleep spm st std sts sub subi swap tst wdr","built_in":"r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 r13 r14 r15 r16 r17 r18 r19 r20 r21 r22 r23 r24 r25 r26 r27 r28 r29 r30 r31 x|0 xh xl y|0 yh yl z|0 zh zl ucsr1c udr1 ucsr1a ucsr1b ubrr1l ubrr1h ucsr0c ubrr0h tccr3c tccr3a tccr3b tcnt3h tcnt3l ocr3ah ocr3al ocr3bh ocr3bl ocr3ch ocr3cl icr3h icr3l etimsk etifr tccr1c ocr1ch ocr1cl twcr twdr twar twsr twbr osccal xmcra xmcrb eicra spmcsr spmcr portg ddrg ping portf ddrf sreg sph spl xdiv rampz eicrb eimsk gimsk gicr eifr gifr timsk tifr mcucr mcucsr tccr0 tcnt0 ocr0 assr tccr1a tccr1b tcnt1h tcnt1l ocr1ah ocr1al ocr1bh ocr1bl icr1h icr1l tccr2 tcnt2 ocr2 ocdr wdtcr sfior eearh eearl eedr eecr porta ddra pina portb ddrb pinb portc ddrc pinc portd ddrd pind spdr spsr spcr udr0 ucsr0a ucsr0b ubrr0l acsr admux adcsr adch adcl porte ddre pine pinf","meta":".byte .cseg .db .def .device .dseg .dw .endmacro .equ .eseg .exit .include .list .listmac .macro .nolist .org .set"},"contains":[{"className":"comment","begin":"/\\*","end":"\\*/","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":";","end":"$","contains":[{"$ref":"#contains.0.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}],"relevance":0},{"className":"number","begin":"(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)","relevance":0},{"className":"number","begin":"\\b(0b[01]+)","relevance":0},{"className":"number","begin":"\\b(\\$[a-zA-Z0-9]+|0o[0-7]+)"},{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0}]},{"className":"string","begin":"'","end":"[^\\\\]'","illegal":"[^\\\\][^']"},{"className":"symbol","begin":"^[A-Za-z0-9_.$]+:"},{"className":"meta","begin":"#","end":"$"},{"className":"subst","begin":"@[0-9]+"}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/awk.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/awk.json new file mode 100644 index 00000000..3e8e195d --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/awk.json @@ -0,0 +1 @@ +{"keywords":{"keyword":"BEGIN END if else while do for in break continue delete next nextfile function func exit|10"},"contains":[{"className":"variable","variants":[{"begin":"\\$[\\w\\d#@][\\w\\d_]*"},{"begin":"\\$\\{(.*?)}"}]},{"className":"string","contains":[{"begin":"\\\\[\\s\\S]","relevance":0}],"variants":[{"begin":"(u|b)?r?'''","end":"'''","relevance":10},{"begin":"(u|b)?r?\"\"\"","end":"\"\"\"","relevance":10},{"begin":"(u|r|ur)'","end":"'","relevance":10},{"begin":"(u|r|ur)\"","end":"\"","relevance":10},{"begin":"(b|br)'","end":"'"},{"begin":"(b|br)\"","end":"\""},{"className":"string","begin":"'","end":"'","illegal":"\\n","contains":[{"$ref":"#contains.1.contains.0"}]},{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"$ref":"#contains.1.contains.0"}]}]},{"className":"regexp","begin":"\\/","end":"\\/[gimuy]*","illegal":"\\n","contains":[{"$ref":"#contains.1.contains.0"},{"begin":"\\[","end":"\\]","relevance":0,"contains":[{"$ref":"#contains.1.contains.0"}]}]},{"className":"comment","begin":"#","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"number","begin":"\\b\\d+(\\.\\d+)?","relevance":0}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/axapta.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/axapta.json new file mode 100644 index 00000000..1622c8de --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/axapta.json @@ -0,0 +1 @@ +{"keywords":"false int abstract private char boolean static null if for true while long throw finally protected final return void enum else break new catch byte super case short default double public try this switch continue reverse firstfast firstonly forupdate nofetch sum avg minof maxof count order group by asc desc index hint like dispaly edit client server ttsbegin ttscommit str real date container anytype common div mod","contains":[{"className":"comment","begin":"//","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"/\\*","end":"\\*/","contains":[{"$ref":"#contains.0.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"string","begin":"'","end":"'","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0}]},{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"$ref":"#contains.2.contains.0"}]},{"className":"number","begin":"(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)","relevance":0},{"className":"meta","begin":"#","end":"$"},{"className":"class","beginKeywords":"class interface","end":"{","excludeEnd":true,"illegal":":","contains":[{"beginKeywords":"extends implements"},{"className":"title","begin":"[a-zA-Z_]\\w*","relevance":0}]}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/bash.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/bash.json new file mode 100644 index 00000000..c752a0d4 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/bash.json @@ -0,0 +1 @@ +{"aliases":["sh","zsh"],"lexemes":"\\b-?[a-z\\._]+\\b","keywords":{"keyword":"if then else elif fi for while in do done case esac function","literal":"true false","built_in":"break cd continue eval exec exit export getopts hash pwd readonly return shift test times trap umask unset alias bind builtin caller command declare echo enable help let local logout mapfile printf read readarray source type typeset ulimit unalias set shopt autoload bg bindkey bye cap chdir clone comparguments compcall compctl compdescribe compfiles compgroups compquote comptags comptry compvalues dirs disable disown echotc echoti emulate fc fg float functions getcap getln history integer jobs kill limit log noglob popd print pushd pushln rehash sched setcap setopt stat suspend ttyctl unfunction unhash unlimit unsetopt vared wait whence where which zcompile zformat zftp zle zmodload zparseopts zprof zpty zregexparse zsocket zstyle ztcp","_":"-ne -eq -lt -gt -f -d -e -s -l -a"},"contains":[{"className":"meta","begin":"^#![^\\n]+sh\\s*$","relevance":10},{"className":"function","begin":"\\w[\\w\\d_]*\\s*\\(\\s*\\)\\s*\\{","returnBegin":true,"contains":[{"className":"title","begin":"\\w[\\w\\d_]*","relevance":0}],"relevance":0},{"className":"comment","begin":"#","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"string","begin":"\"","end":"\"","contains":[{"begin":"\\\\[\\s\\S]","relevance":0},{"className":"variable","variants":[{"begin":"\\$[\\w\\d#@][\\w\\d_]*"},{"begin":"\\$\\{(.*?)}"}]},{"className":"variable","begin":"\\$\\(","end":"\\)","contains":[{"$ref":"#contains.3.contains.0"}]}]},{"className":"","begin":"\\\\\""},{"className":"string","begin":"'","end":"'"},{"$ref":"#contains.3.contains.1"}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/basic.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/basic.json new file mode 100644 index 00000000..47f065c0 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/basic.json @@ -0,0 +1 @@ +{"case_insensitive":true,"illegal":"^.","lexemes":"[a-zA-Z][a-zA-Z0-9_$%!#]*","keywords":{"keyword":"ABS ASC AND ATN AUTO|0 BEEP BLOAD|10 BSAVE|10 CALL CALLS CDBL CHAIN CHDIR CHR$|10 CINT CIRCLE CLEAR CLOSE CLS COLOR COM COMMON CONT COS CSNG CSRLIN CVD CVI CVS DATA DATE$ DEFDBL DEFINT DEFSNG DEFSTR DEF|0 SEG USR DELETE DIM DRAW EDIT END ENVIRON ENVIRON$ EOF EQV ERASE ERDEV ERDEV$ ERL ERR ERROR EXP FIELD FILES FIX FOR|0 FRE GET GOSUB|10 GOTO HEX$ IF|0 THEN ELSE|0 INKEY$ INP INPUT INPUT# INPUT$ INSTR IMP INT IOCTL IOCTL$ KEY ON OFF LIST KILL LEFT$ LEN LET LINE LLIST LOAD LOC LOCATE LOF LOG LPRINT USING LSET MERGE MID$ MKDIR MKD$ MKI$ MKS$ MOD NAME NEW NEXT NOISE NOT OCT$ ON OR PEN PLAY STRIG OPEN OPTION BASE OUT PAINT PALETTE PCOPY PEEK PMAP POINT POKE POS PRINT PRINT] PSET PRESET PUT RANDOMIZE READ REM RENUM RESET|0 RESTORE RESUME RETURN|0 RIGHT$ RMDIR RND RSET RUN SAVE SCREEN SGN SHELL SIN SOUND SPACE$ SPC SQR STEP STICK STOP STR$ STRING$ SWAP SYSTEM TAB TAN TIME$ TIMER TROFF TRON TO USR VAL VARPTR VARPTR$ VIEW WAIT WHILE WEND WIDTH WINDOW WRITE XOR"},"contains":[{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0}]},{"className":"comment","begin":"REM","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}],"relevance":10},{"className":"comment","begin":"'","end":"$","contains":[{"$ref":"#contains.1.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}],"relevance":0},{"className":"symbol","begin":"^[0-9]+ ","relevance":10},{"className":"number","begin":"\\b([0-9]+[0-9edED.]*[#!]?)","relevance":0},{"className":"number","begin":"(&[hH][0-9a-fA-F]{1,4})"},{"className":"number","begin":"(&[oO][0-7]{1,6})"}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/bnf.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/bnf.json new file mode 100644 index 00000000..ca054841 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/bnf.json @@ -0,0 +1 @@ +{"contains":[{"className":"attribute","begin":"<","end":">"},{"begin":"::=","starts":{"end":"$","contains":[{"begin":"<","end":">"},{"className":"comment","begin":"//","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"/\\*","end":"\\*/","contains":[{"$ref":"#contains.1.starts.contains.1.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"string","begin":"'","end":"'","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0}]},{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"$ref":"#contains.1.starts.contains.3.contains.0"}]}]}}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/brainfuck.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/brainfuck.json new file mode 100644 index 00000000..5b73fb15 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/brainfuck.json @@ -0,0 +1 @@ +{"aliases":["bf"],"contains":[{"className":"comment","begin":"[^\\[\\]\\.,\\+\\-<> \r\n]","end":"[\\[\\]\\.,\\+\\-<> \r\n]","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}],"returnEnd":true,"relevance":0},{"className":"title","begin":"[\\[\\]]","relevance":0},{"className":"string","begin":"[\\.,]","relevance":0},{"begin":"\\+\\+|\\-\\-","returnBegin":true,"contains":[{"className":"literal","begin":"[\\+\\-]","relevance":0}]},{"$ref":"#contains.3.contains.0"}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/cal.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/cal.json new file mode 100644 index 00000000..372049df --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/cal.json @@ -0,0 +1 @@ +{"case_insensitive":true,"keywords":{"keyword":"div mod in and or not xor asserterror begin case do downto else end exit for if of repeat then to until while with var","literal":"false true"},"illegal":"\\/\\*","contains":[{"className":"string","begin":"'","end":"'","contains":[{"begin":"''"}]},{"className":"string","begin":"(#\\d+)+"},{"className":"number","begin":"\\b\\d+(\\.\\d+)?(DT|D|T)","relevance":0},{"className":"string","begin":"\"","end":"\""},{"className":"number","begin":"\\b\\d+(\\.\\d+)?","relevance":0},{"className":"class","begin":"OBJECT (Table|Form|Report|Dataport|Codeunit|XMLport|MenuSuite|Page|Query) (\\d+) ([^\\r\\n]+)","returnBegin":true,"contains":[{"className":"title","begin":"[a-zA-Z]\\w*","relevance":0},{"className":"function","beginKeywords":"procedure","end":"[:;]","keywords":"procedure|10","contains":[{"$ref":"#contains.5.contains.0"},{"className":"params","begin":"\\(","end":"\\)","keywords":"div mod in and or not xor asserterror begin case do downto else end exit for if of repeat then to until while with var","contains":[{"$ref":"#contains.0"},{"$ref":"#contains.1"}]},{"className":"comment","begin":"//","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"\\{","end":"\\}","contains":[{"$ref":"#contains.5.contains.1.contains.2.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}],"relevance":0},{"className":"comment","begin":"\\(\\*","end":"\\*\\)","contains":[{"$ref":"#contains.5.contains.1.contains.2.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}],"relevance":10}]}]},{"$ref":"#contains.5.contains.1"}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/capnproto.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/capnproto.json new file mode 100644 index 00000000..de1f6a19 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/capnproto.json @@ -0,0 +1 @@ +{"aliases":["capnp"],"keywords":{"keyword":"struct enum interface union group import using const annotation extends in of on as with from fixed","built_in":"Void Bool Int8 Int16 Int32 Int64 UInt8 UInt16 UInt32 UInt64 Float32 Float64 Text Data AnyPointer AnyStruct Capability List","literal":"true false"},"contains":[{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0}]},{"className":"number","begin":"\\b\\d+(\\.\\d+)?","relevance":0},{"className":"comment","begin":"#","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"meta","begin":"@0x[\\w\\d]{16};","illegal":"\\n"},{"className":"symbol","begin":"@\\d+\\b"},{"className":"class","beginKeywords":"struct enum","end":"\\{","illegal":"\\n","contains":[{"className":"title","begin":"[a-zA-Z]\\w*","relevance":0,"starts":{"endsWithParent":true,"excludeEnd":true}}]},{"className":"class","beginKeywords":"interface","end":"\\{","illegal":"\\n","contains":[{"className":"title","begin":"[a-zA-Z]\\w*","relevance":0,"starts":{"endsWithParent":true,"excludeEnd":true}}]}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/ceylon.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/ceylon.json new file mode 100644 index 00000000..00e1270f --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/ceylon.json @@ -0,0 +1 @@ +{"keywords":{"keyword":"assembly module package import alias class interface object given value assign void function new of extends satisfies abstracts in out return break continue throw assert dynamic if else switch case for while try catch finally then let this outer super is exists nonempty shared abstract formal default actual variable late native deprecatedfinal sealed annotation suppressWarnings small","meta":"doc by license see throws tagged"},"illegal":"\\$[^01]|#[^0-9a-fA-F]","contains":[{"className":"comment","begin":"//","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"/\\*","end":"\\*/","contains":["self",{"$ref":"#contains.0.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"meta","begin":"@[a-z]\\w*(?:\\:\"[^\"]*\")?"},{"className":"string","begin":"\"\"\"","end":"\"\"\"","relevance":10},{"className":"string","begin":"\"","end":"\"","contains":[{"className":"subst","excludeBegin":true,"excludeEnd":true,"begin":"``","end":"``","keywords":"assembly module package import alias class interface object given value assign void function new of extends satisfies abstracts in out return break continue throw assert dynamic if else switch case for while try catch finally then let this outer super is exists nonempty","relevance":10,"contains":[{"$ref":"#contains.3"},{"$ref":"#contains.4"},{"className":"string","begin":"'","end":"'"},{"className":"number","begin":"#[0-9a-fA-F_]+|\\$[01_]+|[0-9_]+(?:\\.[0-9_](?:[eE][+-]?\\d+)?)?[kMGTPmunpf]?","relevance":0}]}]},{"$ref":"#contains.4.contains.0.contains.2"},{"$ref":"#contains.4.contains.0.contains.3"}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/clean.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/clean.json new file mode 100644 index 00000000..4bacbb61 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/clean.json @@ -0,0 +1 @@ +{"aliases":["clean","icl","dcl"],"keywords":{"keyword":"if let in with where case of class instance otherwise implementation definition system module from import qualified as special code inline foreign export ccall stdcall generic derive infix infixl infixr","built_in":"Int Real Char Bool","literal":"True False"},"contains":[{"className":"comment","begin":"//","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"/\\*","end":"\\*/","contains":[{"$ref":"#contains.0.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"string","begin":"'","end":"'","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0}]},{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"$ref":"#contains.2.contains.0"}]},{"className":"number","begin":"(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)","relevance":0},{"begin":"->|<-[|:]?|#!?|>>=|\\{\\||\\|\\}|:==|=:|<>"}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/clojure-repl.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/clojure-repl.json new file mode 100644 index 00000000..b8a4f7b1 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/clojure-repl.json @@ -0,0 +1 @@ +{"contains":[{"className":"meta","begin":"^([\\w.-]+|\\s*#_)?=>","starts":{"end":"$","subLanguage":"clojure"}}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/clojure.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/clojure.json new file mode 100644 index 00000000..a9faa0e2 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/clojure.json @@ -0,0 +1 @@ +{"aliases":["clj"],"illegal":"\\S","contains":[{"begin":"\\(","end":"\\)","contains":[{"className":"comment","begin":"comment","end":"","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"keywords":{"builtin-name":"def defonce cond apply if-not if-let if not not= = < > <= >= == + / * - rem quot neg? pos? delay? symbol? keyword? true? false? integer? empty? coll? list? set? ifn? fn? associative? sequential? sorted? counted? reversible? number? decimal? class? distinct? isa? float? rational? reduced? ratio? odd? even? char? seq? vector? string? map? nil? contains? zero? instance? not-every? not-any? libspec? -> ->> .. . inc compare do dotimes mapcat take remove take-while drop letfn drop-last take-last drop-while while intern condp case reduced cycle split-at split-with repeat replicate iterate range merge zipmap declare line-seq sort comparator sort-by dorun doall nthnext nthrest partition eval doseq await await-for let agent atom send send-off release-pending-sends add-watch mapv filterv remove-watch agent-error restart-agent set-error-handler error-handler set-error-mode! error-mode shutdown-agents quote var fn loop recur throw try monitor-enter monitor-exit defmacro defn defn- macroexpand macroexpand-1 for dosync and or when when-not when-let comp juxt partial sequence memoize constantly complement identity assert peek pop doto proxy defstruct first rest cons defprotocol cast coll deftype defrecord last butlast sigs reify second ffirst fnext nfirst nnext defmulti defmethod meta with-meta ns in-ns create-ns import refer keys select-keys vals key val rseq name namespace promise into transient persistent! conj! assoc! dissoc! pop! disj! use class type num float double short byte boolean bigint biginteger bigdec print-method print-dup throw-if printf format load compile get-in update-in pr pr-on newline flush read slurp read-line subvec with-open memfn time re-find re-groups rand-int rand mod locking assert-valid-fdecl alias resolve ref deref refset swap! reset! set-validator! compare-and-set! alter-meta! reset-meta! commute get-validator alter ref-set ref-history-count ref-min-history ref-max-history ensure sync io! new next conj set! to-array future future-call into-array aset gen-class reduce map filter find empty hash-map hash-set sorted-map sorted-map-by sorted-set sorted-set-by vec vector seq flatten reverse assoc dissoc list disj get union difference intersection extend extend-type extend-protocol int nth delay count concat chunk chunk-buffer chunk-append chunk-first chunk-rest max min dec unchecked-inc-int unchecked-inc unchecked-dec-inc unchecked-dec unchecked-negate unchecked-add-int unchecked-add unchecked-subtract-int unchecked-subtract chunk-next chunk-cons chunked-seq? prn vary-meta lazy-seq spread list* str find-keyword keyword symbol gensym force rationalize"},"lexemes":"[a-zA-Z_\\-!.?+*=<>&#'][a-zA-Z_\\-!.?+*=<>&#'0-9/;:]*","className":"name","begin":"[a-zA-Z_\\-!.?+*=<>&#'][a-zA-Z_\\-!.?+*=<>&#'0-9/;:]*","starts":{"endsWithParent":true,"relevance":0,"contains":[{"$ref":"#contains.0"},{"className":"string","begin":"\"","end":"\"","illegal":null,"contains":[{"begin":"\\\\[\\s\\S]","relevance":0}]},{"className":"comment","begin":"\\^[a-zA-Z_\\-!.?+*=<>&#'][a-zA-Z_\\-!.?+*=<>&#'0-9/;:]*"},{"className":"comment","begin":"\\^\\{","end":"\\}","contains":[{"begin":"[\\[\\{]","end":"[\\]\\}]","contains":{"$ref":"#contains.0.contains.1.starts.contains"}}]},{"className":"comment","begin":";","end":"$","contains":[{"$ref":"#contains.0.contains.0.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}],"relevance":0},{"className":"symbol","begin":"[:]{1,2}[a-zA-Z_\\-!.?+*=<>&#'][a-zA-Z_\\-!.?+*=<>&#'0-9/;:]*"},{"$ref":"#contains.0.contains.1.starts.contains.3.contains.0"},{"className":"number","begin":"[-+]?\\d+(\\.\\d+)?","relevance":0},{"className":"literal","begin":"\\b(true|false|nil)\\b"},{"begin":"[a-zA-Z_\\-!.?+*=<>&#'][a-zA-Z_\\-!.?+*=<>&#'0-9/;:]*","relevance":0}]}},{"$ref":"#contains.0.contains.1.starts"}]},{"$ref":"#contains.0.contains.1.starts.contains.1"},{"$ref":"#contains.0.contains.1.starts.contains.2"},{"$ref":"#contains.0.contains.1.starts.contains.3"},{"$ref":"#contains.0.contains.1.starts.contains.4"},{"$ref":"#contains.0.contains.1.starts.contains.5"},{"$ref":"#contains.0.contains.1.starts.contains.3.contains.0"},{"$ref":"#contains.0.contains.1.starts.contains.7"},{"$ref":"#contains.0.contains.1.starts.contains.8"}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/cmake.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/cmake.json new file mode 100644 index 00000000..df9caae7 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/cmake.json @@ -0,0 +1 @@ +{"aliases":["cmake.in"],"case_insensitive":true,"keywords":{"keyword":"break cmake_host_system_information cmake_minimum_required cmake_parse_arguments cmake_policy configure_file continue elseif else endforeach endfunction endif endmacro endwhile execute_process file find_file find_library find_package find_path find_program foreach function get_cmake_property get_directory_property get_filename_component get_property if include include_guard list macro mark_as_advanced math message option return separate_arguments set_directory_properties set_property set site_name string unset variable_watch while add_compile_definitions add_compile_options add_custom_command add_custom_target add_definitions add_dependencies add_executable add_library add_link_options add_subdirectory add_test aux_source_directory build_command create_test_sourcelist define_property enable_language enable_testing export fltk_wrap_ui get_source_file_property get_target_property get_test_property include_directories include_external_msproject include_regular_expression install link_directories link_libraries load_cache project qt_wrap_cpp qt_wrap_ui remove_definitions set_source_files_properties set_target_properties set_tests_properties source_group target_compile_definitions target_compile_features target_compile_options target_include_directories target_link_directories target_link_libraries target_link_options target_sources try_compile try_run ctest_build ctest_configure ctest_coverage ctest_empty_binary_directory ctest_memcheck ctest_read_custom_files ctest_run_script ctest_sleep ctest_start ctest_submit ctest_test ctest_update ctest_upload build_name exec_program export_library_dependencies install_files install_programs install_targets load_command make_directory output_required_files remove subdir_depends subdirs use_mangled_mesa utility_source variable_requires write_file qt5_use_modules qt5_use_package qt5_wrap_cpp on off true false and or not command policy target test exists is_newer_than is_directory is_symlink is_absolute matches less greater equal less_equal greater_equal strless strgreater strequal strless_equal strgreater_equal version_less version_greater version_equal version_less_equal version_greater_equal in_list defined"},"contains":[{"className":"variable","begin":"\\${","end":"}"},{"className":"comment","begin":"#","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0}]},{"className":"number","begin":"\\b\\d+(\\.\\d+)?","relevance":0}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/coffeescript.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/coffeescript.json new file mode 100644 index 00000000..ea6d9df0 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/coffeescript.json @@ -0,0 +1 @@ +{"aliases":["coffee","cson","iced"],"keywords":{"keyword":"in if for while finally new do return else break catch instanceof throw try this switch continue typeof delete debugger super yield import export from as default await then unless until loop of by when and or is isnt not","literal":"true false null undefined yes no on off","built_in":"npm require console print module global window document"},"illegal":"\\/\\*","contains":[{"className":"number","begin":"\\b(0b[01]+)","relevance":0},{"className":"number","begin":"(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)","relevance":0,"starts":{"end":"(\\s*/)?","relevance":0}},{"className":"string","variants":[{"begin":"'''","end":"'''","contains":[{"begin":"\\\\[\\s\\S]","relevance":0}]},{"begin":"'","end":"'","contains":[{"$ref":"#contains.2.variants.0.contains.0"}]},{"begin":"\"\"\"","end":"\"\"\"","contains":[{"$ref":"#contains.2.variants.0.contains.0"},{"className":"subst","begin":"#\\{","end":"}","keywords":{"$ref":"#keywords"},"contains":[{"$ref":"#contains.0"},{"$ref":"#contains.1"},{"$ref":"#contains.2"},{"className":"regexp","variants":[{"begin":"///","end":"///","contains":[{"$ref":"#contains.2.variants.2.contains.1"},{"className":"comment","begin":"#","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]}]},{"begin":"//[gim]*","relevance":0},{"begin":"\\/(?![ *])(\\\\\\/|.)*?\\/[gim]*(?=\\W|$)"}]},{"begin":"@[A-Za-z$_][0-9A-Za-z$_]*"},{"subLanguage":"javascript","excludeBegin":true,"excludeEnd":true,"variants":[{"begin":"```","end":"```"},{"begin":"`","end":"`"}]}]}]},{"begin":"\"","end":"\"","contains":[{"$ref":"#contains.2.variants.0.contains.0"},{"$ref":"#contains.2.variants.2.contains.1"}]}]},{"$ref":"#contains.2.variants.2.contains.1.contains.3"},{"$ref":"#contains.2.variants.2.contains.1.contains.4"},{"$ref":"#contains.2.variants.2.contains.1.contains.5"},{"className":"comment","begin":"###","end":"###","contains":[{"$ref":"#contains.2.variants.2.contains.1.contains.3.variants.0.contains.1.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"$ref":"#contains.2.variants.2.contains.1.contains.3.variants.0.contains.1"},{"className":"function","begin":"^\\s*[A-Za-z$_][0-9A-Za-z$_]*\\s*=\\s*(\\(.*\\))?\\s*\\B[-=]>","end":"[-=]>","returnBegin":true,"contains":[{"className":"title","begin":"[A-Za-z$_][0-9A-Za-z$_]*","relevance":0},{"className":"params","begin":"\\([^\\(]","returnBegin":true,"contains":[{"begin":"\\(","end":"\\)","keywords":{"$ref":"#keywords"},"contains":["self",{"$ref":"#contains.0"},{"$ref":"#contains.1"},{"$ref":"#contains.2"},{"$ref":"#contains.2.variants.2.contains.1.contains.3"},{"$ref":"#contains.2.variants.2.contains.1.contains.4"},{"$ref":"#contains.2.variants.2.contains.1.contains.5"}]}]}]},{"begin":"[:\\(,=]\\s*","relevance":0,"contains":[{"className":"function","begin":"(\\(.*\\))?\\s*\\B[-=]>","end":"[-=]>","returnBegin":true,"contains":[{"$ref":"#contains.8.contains.1"}]}]},{"className":"class","beginKeywords":"class","end":"$","illegal":"[:=\"\\[\\]]","contains":[{"beginKeywords":"extends","endsWithParent":true,"illegal":"[:=\"\\[\\]]","contains":[{"$ref":"#contains.8.contains.0"}]},{"$ref":"#contains.8.contains.0"}]},{"begin":"[A-Za-z$_][0-9A-Za-z$_]*:","end":":","returnBegin":true,"returnEnd":true,"relevance":0}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/coq.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/coq.json new file mode 100644 index 00000000..2c82bdda --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/coq.json @@ -0,0 +1 @@ +{"keywords":{"keyword":"_ as at cofix else end exists exists2 fix for forall fun if IF in let match mod Prop return Set then Type using where with Abort About Add Admit Admitted All Arguments Assumptions Axiom Back BackTo Backtrack Bind Blacklist Canonical Cd Check Class Classes Close Coercion Coercions CoFixpoint CoInductive Collection Combined Compute Conjecture Conjectures Constant constr Constraint Constructors Context Corollary CreateHintDb Cut Declare Defined Definition Delimit Dependencies DependentDerive Drop eauto End Equality Eval Example Existential Existentials Existing Export exporting Extern Extract Extraction Fact Field Fields File Fixpoint Focus for From Function Functional Generalizable Global Goal Grab Grammar Graph Guarded Heap Hint HintDb Hints Hypotheses Hypothesis ident Identity If Immediate Implicit Import Include Inductive Infix Info Initial Inline Inspect Instance Instances Intro Intros Inversion Inversion_clear Language Left Lemma Let Libraries Library Load LoadPath Local Locate Ltac ML Mode Module Modules Monomorphic Morphism Next NoInline Notation Obligation Obligations Opaque Open Optimize Options Parameter Parameters Parametric Path Paths pattern Polymorphic Preterm Print Printing Program Projections Proof Proposition Pwd Qed Quit Rec Record Recursive Redirect Relation Remark Remove Require Reserved Reset Resolve Restart Rewrite Right Ring Rings Save Scheme Scope Scopes Script Search SearchAbout SearchHead SearchPattern SearchRewrite Section Separate Set Setoid Show Solve Sorted Step Strategies Strategy Structure SubClass Table Tables Tactic Term Test Theorem Time Timeout Transparent Type Typeclasses Types Undelimit Undo Unfocus Unfocused Unfold Universe Universes Unset Unshelve using Variable Variables Variant Verbose Visibility where with","built_in":"abstract absurd admit after apply as assert assumption at auto autorewrite autounfold before bottom btauto by case case_eq cbn cbv change classical_left classical_right clear clearbody cofix compare compute congruence constr_eq constructor contradict contradiction cut cutrewrite cycle decide decompose dependent destruct destruction dintuition discriminate discrR do double dtauto eapply eassumption eauto ecase econstructor edestruct ediscriminate eelim eexact eexists einduction einjection eleft elim elimtype enough equality erewrite eright esimplify_eq esplit evar exact exactly_once exfalso exists f_equal fail field field_simplify field_simplify_eq first firstorder fix fold fourier functional generalize generalizing gfail give_up has_evar hnf idtac in induction injection instantiate intro intro_pattern intros intuition inversion inversion_clear is_evar is_var lapply lazy left lia lra move native_compute nia nsatz omega once pattern pose progress proof psatz quote record red refine reflexivity remember rename repeat replace revert revgoals rewrite rewrite_strat right ring ring_simplify rtauto set setoid_reflexivity setoid_replace setoid_rewrite setoid_symmetry setoid_transitivity shelve shelve_unifiable simpl simple simplify_eq solve specialize split split_Rabs split_Rmult stepl stepr subst sum swap symmetry tactic tauto time timeout top transitivity trivial try tryif unfold unify until using vm_compute with"},"contains":[{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0}]},{"className":"comment","begin":"\\(\\*","end":"\\*\\)","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"number","begin":"(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)","relevance":0},{"className":"type","excludeBegin":true,"begin":"\\|\\s*","end":"\\w+"},{"begin":"[-=]>"}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/cos.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/cos.json new file mode 100644 index 00000000..06ecfea2 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/cos.json @@ -0,0 +1 @@ +{"case_insensitive":true,"aliases":["cos","cls"],"keywords":"property parameter class classmethod clientmethod extends as break catch close continue do d|0 else elseif for goto halt hang h|0 if job j|0 kill k|0 lock l|0 merge new open quit q|0 read r|0 return set s|0 tcommit throw trollback try tstart use view while write w|0 xecute x|0 zkill znspace zn ztrap zwrite zw zzdump zzwrite print zbreak zinsert zload zprint zremove zsave zzprint mv mvcall mvcrt mvdim mvprint zquit zsync ascii","contains":[{"className":"number","begin":"\\b(\\d+(\\.\\d*)?|\\.\\d+)","relevance":0},{"className":"string","variants":[{"begin":"\"","end":"\"","contains":[{"begin":"\"\"","relevance":0}]}]},{"className":"comment","begin":"//","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"/\\*","end":"\\*/","contains":[{"$ref":"#contains.2.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":";","end":"$","relevance":0},{"className":"built_in","begin":"(?:\\$\\$?|\\.\\.)\\^?[a-zA-Z]+"},{"className":"built_in","begin":"\\$\\$\\$[a-zA-Z]+"},{"className":"built_in","begin":"%[a-z]+(?:\\.[a-z]+)*"},{"className":"symbol","begin":"\\^%?[a-zA-Z][\\w]*"},{"className":"keyword","begin":"##class|##super|#define|#dim"},{"begin":"&sql\\(","end":"\\)","excludeBegin":true,"excludeEnd":true,"subLanguage":"sql"},{"begin":"&(js|jscript|javascript)<","end":">","excludeBegin":true,"excludeEnd":true,"subLanguage":"javascript"},{"begin":"&html<\\s*<","end":">\\s*>","subLanguage":"xml"}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/cpp.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/cpp.json new file mode 100644 index 00000000..b2b5ca59 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/cpp.json @@ -0,0 +1 @@ +{"aliases":["c","cc","h","c++","h++","hpp","hh","hxx","cxx"],"keywords":{"keyword":"int float while private char catch import module export virtual operator sizeof dynamic_cast|10 typedef const_cast|10 const for static_cast|10 union namespace unsigned long volatile static protected bool template mutable if public friend do goto auto void enum else break extern using asm case typeid short reinterpret_cast|10 default double register explicit signed typename try this switch continue inline delete alignof constexpr decltype noexcept static_assert thread_local restrict _Bool complex _Complex _Imaginary atomic_bool atomic_char atomic_schar atomic_uchar atomic_short atomic_ushort atomic_int atomic_uint atomic_long atomic_ulong atomic_llong atomic_ullong new throw return and or not","built_in":"std string cin cout cerr clog stdin stdout stderr stringstream istringstream ostringstream auto_ptr deque list queue stack vector map set bitset multiset multimap unordered_set unordered_map unordered_multiset unordered_multimap array shared_ptr abort abs acos asin atan2 atan calloc ceil cosh cos exit exp fabs floor fmod fprintf fputs free frexp fscanf isalnum isalpha iscntrl isdigit isgraph islower isprint ispunct isspace isupper isxdigit tolower toupper labs ldexp log10 log malloc realloc memchr memcmp memcpy memset modf pow printf putchar puts scanf sinh sin snprintf sprintf sqrt sscanf strcat strchr strcmp strcpy strcspn strlen strncat strncmp strncpy strpbrk strrchr strspn strstr tanh tan vfprintf vprintf vsprintf endl initializer_list unique_ptr","literal":"true false nullptr NULL"},"illegal":"]*>","end":"$","illegal":"\\n"},{"$ref":"#contains.1"},{"$ref":"#contains.2"}]},{"begin":"\\b(deque|list|queue|stack|vector|map|set|bitset|multiset|multimap|unordered_map|unordered_set|unordered_multiset|unordered_multimap|array)\\s*<","end":">","keywords":{"$ref":"#keywords"},"contains":["self",{"$ref":"#contains.0"}]},{"begin":"[a-zA-Z]\\w*::","keywords":{"$ref":"#keywords"}},{"variants":[{"begin":"=","end":";"},{"begin":"\\(","end":"\\)"},{"beginKeywords":"new throw return else","end":";"}],"keywords":{"$ref":"#keywords"},"contains":[{"$ref":"#contains.0"},{"$ref":"#contains.1"},{"$ref":"#contains.2"},{"$ref":"#contains.3"},{"$ref":"#contains.4"},{"begin":"\\(","end":"\\)","keywords":{"$ref":"#keywords"},"contains":[{"$ref":"#contains.0"},{"$ref":"#contains.1"},{"$ref":"#contains.2"},{"$ref":"#contains.3"},{"$ref":"#contains.4"},"self"],"relevance":0}],"relevance":0},{"className":"function","begin":"([a-zA-Z]\\w*[\\*&\\s]+)+[a-zA-Z]\\w*\\s*\\(","returnBegin":true,"end":"[{;=]","excludeEnd":true,"keywords":{"$ref":"#keywords"},"illegal":"[^\\w\\s\\*&]","contains":[{"begin":"[a-zA-Z]\\w*\\s*\\(","returnBegin":true,"contains":[{"className":"title","begin":"[a-zA-Z]\\w*","relevance":0}],"relevance":0},{"className":"params","begin":"\\(","end":"\\)","keywords":{"$ref":"#keywords"},"relevance":0,"contains":[{"$ref":"#contains.1"},{"$ref":"#contains.2"},{"$ref":"#contains.4"},{"$ref":"#contains.3"},{"$ref":"#contains.0"},{"begin":"\\(","end":"\\)","keywords":{"$ref":"#keywords"},"relevance":0,"contains":["self",{"$ref":"#contains.1"},{"$ref":"#contains.2"},{"$ref":"#contains.4"},{"$ref":"#contains.3"},{"$ref":"#contains.0"}]}]},{"$ref":"#contains.1"},{"$ref":"#contains.2"},{"$ref":"#contains.5"}]},{"className":"class","beginKeywords":"class struct","end":"[{;:]","contains":[{"begin":"<","end":">","contains":["self"]},{"$ref":"#contains.9.contains.0.contains.0"}]}],"exports":{"preprocessor":{"$ref":"#contains.5"},"strings":{"$ref":"#contains.4"},"keywords":{"$ref":"#keywords"}}} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/crmsh.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/crmsh.json new file mode 100644 index 00000000..e1a35f95 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/crmsh.json @@ -0,0 +1 @@ +{"aliases":["crm","pcmk"],"case_insensitive":true,"keywords":{"keyword":"params meta operations op rule attributes utilization read write deny defined not_defined in_range date spec in ref reference attribute type xpath version and or lt gt tag lte gte eq ne \\ number string","literal":"Master Started Slave Stopped start promote demote stop monitor true false"},"contains":[{"className":"comment","begin":"#","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"beginKeywords":"node","starts":{"end":"\\s*([\\w_-]+:)?","starts":{"className":"title","end":"\\s*[\\$\\w_][\\w_-]*"}}},{"beginKeywords":"primitive rsc_template","starts":{"className":"title","end":"\\s*[\\$\\w_][\\w_-]*","starts":{"end":"\\s*@?[\\w_][\\w_\\.:-]*"}}},{"begin":"\\b(group|clone|ms|master|location|colocation|order|fencing_topology|rsc_ticket|acl_target|acl_group|user|role|tag|xml)\\s+","keywords":"group clone ms master location colocation order fencing_topology rsc_ticket acl_target acl_group user role tag xml","starts":{"className":"title","end":"[\\$\\w_][\\w_-]*"}},{"beginKeywords":"property rsc_defaults op_defaults","starts":{"className":"title","end":"\\s*([\\w_-]+:)?"}},{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0}]},{"className":"meta","begin":"(ocf|systemd|service|lsb):[\\w_:-]+","relevance":0},{"className":"number","begin":"\\b\\d+(\\.\\d+)?(ms|s|h|m)?","relevance":0},{"className":"literal","begin":"[-]?(infinity|inf)","relevance":0},{"className":"attr","begin":"([A-Za-z\\$_\\#][\\w_-]+)=","relevance":0},{"className":"tag","begin":"","relevance":0}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/crystal.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/crystal.json new file mode 100644 index 00000000..0fd9b0b8 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/crystal.json @@ -0,0 +1 @@ +{"aliases":["cr"],"lexemes":"[a-zA-Z_]\\w*[!?=]?","keywords":{"keyword":"abstract alias annotation as as? asm begin break case class def do else elsif end ensure enum extend for fun if include instance_sizeof is_a? lib macro module next nil? of out pointerof private protected rescue responds_to? return require select self sizeof struct super then type typeof union uninitialized unless until verbatim when while with yield __DIR__ __END_LINE__ __FILE__ __LINE__","literal":"false nil true"},"contains":[{"className":"template-variable","variants":[{"begin":"\\{\\{","end":"\\}\\}"},{"begin":"\\{%","end":"%\\}"}],"keywords":{"$ref":"#keywords"},"contains":[{"className":"string","contains":[{"begin":"\\\\[\\s\\S]","relevance":0},{"className":"subst","begin":"#{","end":"}","keywords":{"$ref":"#keywords"},"contains":{"$ref":"#contains"}}],"variants":[{"begin":"'","end":"'"},{"begin":"\"","end":"\""},{"begin":"`","end":"`"},{"begin":"%[Qwi]?\\(","end":"\\)","contains":[{"begin":"\\(","end":"\\)","contains":{"$ref":"#contains.0.contains.0.variants.3.contains"}}]},{"begin":"%[Qwi]?\\[","end":"\\]","contains":[{"begin":"\\[","end":"\\]","contains":{"$ref":"#contains.0.contains.0.variants.4.contains"}}]},{"begin":"%[Qwi]?{","end":"}","contains":[{"begin":"{","end":"}","contains":{"$ref":"#contains.0.contains.0.variants.5.contains"}}]},{"begin":"%[Qwi]?<","end":">","contains":[{"begin":"<","end":">","contains":{"$ref":"#contains.0.contains.0.variants.6.contains"}}]},{"begin":"%[Qwi]?\\|","end":"\\|"},{"begin":"<<-\\w+$","end":"^\\s*\\w+$"}],"relevance":0},{"className":"string","variants":[{"begin":"%q\\(","end":"\\)","contains":[{"begin":"\\(","end":"\\)","contains":{"$ref":"#contains.0.contains.1.variants.0.contains"}}]},{"begin":"%q\\[","end":"\\]","contains":[{"begin":"\\[","end":"\\]","contains":{"$ref":"#contains.0.contains.1.variants.1.contains"}}]},{"begin":"%q{","end":"}","contains":[{"begin":"{","end":"}","contains":{"$ref":"#contains.0.contains.1.variants.2.contains"}}]},{"begin":"%q<","end":">","contains":[{"begin":"<","end":">","contains":{"$ref":"#contains.0.contains.1.variants.3.contains"}}]},{"begin":"%q\\|","end":"\\|"},{"begin":"<<-'\\w+'$","end":"^\\s*\\w+$"}],"relevance":0},{"className":"regexp","contains":[{"$ref":"#contains.0.contains.0.contains.0"},{"$ref":"#contains.0.contains.0.contains.1"}],"variants":[{"begin":"%r\\(","end":"\\)","contains":[{"begin":"\\(","end":"\\)","contains":{"$ref":"#contains.0.contains.2.variants.0.contains"}}]},{"begin":"%r\\[","end":"\\]","contains":[{"begin":"\\[","end":"\\]","contains":{"$ref":"#contains.0.contains.2.variants.1.contains"}}]},{"begin":"%r{","end":"}","contains":[{"begin":"{","end":"}","contains":{"$ref":"#contains.0.contains.2.variants.2.contains"}}]},{"begin":"%r<","end":">","contains":[{"begin":"<","end":">","contains":{"$ref":"#contains.0.contains.2.variants.3.contains"}}]},{"begin":"%r\\|","end":"\\|"}],"relevance":0},{"begin":"(?!%})(!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~|\\n|\\b(case|if|select|unless|until|when|while)\\b)\\s*","keywords":"case if select unless until when while","contains":[{"className":"regexp","contains":[{"$ref":"#contains.0.contains.0.contains.0"},{"$ref":"#contains.0.contains.0.contains.1"}],"variants":[{"begin":"//[a-z]*","relevance":0},{"begin":"/(?!\\/)","end":"/[a-z]*"}]}],"relevance":0},{"className":"meta","begin":"@\\[","end":"\\]","contains":[{"className":"meta-string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"$ref":"#contains.0.contains.0.contains.0"}]}]},{"className":"comment","begin":"#","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"class","beginKeywords":"class module struct","end":"$|;","illegal":"=","contains":[{"$ref":"#contains.0.contains.5"},{"className":"title","begin":"[A-Za-z_]\\w*(::\\w+)*(\\?|\\!)?","relevance":0},{"begin":"<"}]},{"className":"class","beginKeywords":"lib enum union","end":"$|;","illegal":"=","contains":[{"$ref":"#contains.0.contains.5"},{"className":"title","begin":"[A-Za-z_]\\w*(::\\w+)*(\\?|\\!)?","relevance":0}],"relevance":10},{"beginKeywords":"annotation","end":"$|;","illegal":"=","contains":[{"$ref":"#contains.0.contains.5"},{"className":"title","begin":"[A-Za-z_]\\w*(::\\w+)*(\\?|\\!)?","relevance":0}],"relevance":10},{"className":"function","beginKeywords":"def","end":"\\B\\b","contains":[{"className":"title","begin":"[a-zA-Z_]\\w*[!?=]?|[-+~]\\@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~|]|//|//=|&[-+*]=?|&\\*\\*|\\[\\][=?]?","relevance":0,"endsParent":true}]},{"className":"function","beginKeywords":"fun macro","end":"\\B\\b","contains":[{"className":"title","begin":"[a-zA-Z_]\\w*[!?=]?|[-+~]\\@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~|]|//|//=|&[-+*]=?|&\\*\\*|\\[\\][=?]?","relevance":0,"endsParent":true}],"relevance":5},{"className":"symbol","begin":"[a-zA-Z_]\\w*(\\!|\\?)?:","relevance":0},{"className":"symbol","begin":":","contains":[{"$ref":"#contains.0.contains.0"},{"begin":"[a-zA-Z_]\\w*[!?=]?|[-+~]\\@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~|]|//|//=|&[-+*]=?|&\\*\\*|\\[\\][=?]?"}],"relevance":0},{"className":"number","variants":[{"begin":"\\b0b([01_]+)(_*[ui](8|16|32|64|128))?"},{"begin":"\\b0o([0-7_]+)(_*[ui](8|16|32|64|128))?"},{"begin":"\\b0x([A-Fa-f0-9_]+)(_*[ui](8|16|32|64|128))?"},{"begin":"\\b([1-9][0-9_]*[0-9]|[0-9])(\\.[0-9][0-9_]*)?([eE]_*[-+]?[0-9_]*)?(_*f(32|64))?(?!_)"},{"begin":"\\b([1-9][0-9_]*|0)(_*[ui](8|16|32|64|128))?"}],"relevance":0}]},{"$ref":"#contains.0.contains.0"},{"$ref":"#contains.0.contains.1"},{"$ref":"#contains.0.contains.2"},{"$ref":"#contains.0.contains.3"},{"$ref":"#contains.0.contains.4"},{"$ref":"#contains.0.contains.5"},{"$ref":"#contains.0.contains.6"},{"$ref":"#contains.0.contains.7"},{"$ref":"#contains.0.contains.8"},{"$ref":"#contains.0.contains.9"},{"$ref":"#contains.0.contains.10"},{"$ref":"#contains.0.contains.11"},{"$ref":"#contains.0.contains.12"},{"$ref":"#contains.0.contains.13"}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/cs.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/cs.json new file mode 100644 index 00000000..792e1dd3 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/cs.json @@ -0,0 +1 @@ +{"aliases":["csharp","c#"],"keywords":{"keyword":"abstract as base bool break byte case catch char checked const continue decimal default delegate do double enum event explicit extern finally fixed float for foreach goto if implicit in int interface internal is lock long nameof object operator out override params private protected public readonly ref sbyte sealed short sizeof stackalloc static string struct switch this try typeof uint ulong unchecked unsafe ushort using virtual void volatile while add alias ascending async await by descending dynamic equals from get global group into join let on orderby partial remove select set value var where yield","literal":"null false true"},"illegal":"::","contains":[{"className":"comment","begin":"///","end":"$","contains":[{"className":"doctag","variants":[{"begin":"///","relevance":0},{"begin":""},{"begin":""}]},{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}],"returnBegin":true},{"className":"comment","begin":"//","end":"$","contains":[{"$ref":"#contains.0.contains.1"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"/\\*","end":"\\*/","contains":[{"$ref":"#contains.0.contains.1"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"meta","begin":"#","end":"$","keywords":{"meta-keyword":"if else elif endif define undef warning error line region endregion pragma checksum"}},{"variants":[{"className":"string","begin":"\\$@\"","end":"\"","contains":[{"begin":"{{"},{"begin":"}}"},{"begin":"\"\""},{"className":"subst","begin":"{","end":"}","keywords":{"$ref":"#keywords"},"contains":[{"$ref":"#contains.4.variants.0"},{"className":"string","begin":"\\$\"","end":"\"","illegal":"\\n","contains":[{"begin":"{{"},{"begin":"}}"},{"begin":"\\\\[\\s\\S]","relevance":0},{"className":"subst","begin":"{","end":"}","keywords":{"$ref":"#keywords"},"illegal":"\\n","contains":[{"className":"string","begin":"\\$@\"","end":"\"","contains":[{"begin":"{{"},{"begin":"}}"},{"begin":"\"\""},{"$ref":"#contains.4.variants.0.contains.3.contains.1.contains.3"}],"illegal":"\\n"},{"$ref":"#contains.4.variants.0.contains.3.contains.1"},{"className":"string","begin":"@\"","end":"\"","contains":[{"begin":"\"\""}],"illegal":"\\n"},{"className":"string","begin":"'","end":"'","illegal":"\\n","contains":[{"$ref":"#contains.4.variants.0.contains.3.contains.1.contains.2"}]},{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"$ref":"#contains.4.variants.0.contains.3.contains.1.contains.2"}]},{"className":"number","variants":[{"begin":"\\b(0b[01']+)"},{"begin":"(-?)\\b([\\d']+(\\.[\\d']*)?|\\.[\\d']+)(u|U|l|L|ul|UL|f|F|b|B)"},{"begin":"(-?)(\\b0[xX][a-fA-F0-9']+|(\\b[\\d']+(\\.[\\d']*)?|\\.[\\d']+)([eE][-+]?[\\d']+)?)"}],"relevance":0},{"className":"comment","begin":"/\\*","end":"\\*/","contains":{"$ref":"#contains.2.contains"},"illegal":"\\n"}]}]},{"className":"string","begin":"@\"","end":"\"","contains":{"$ref":"#contains.4.variants.0.contains.3.contains.1.contains.3.contains.2.contains"}},{"$ref":"#contains.4.variants.0.contains.3.contains.1.contains.3.contains.3"},{"$ref":"#contains.4.variants.0.contains.3.contains.1.contains.3.contains.4"},{"$ref":"#contains.4.variants.0.contains.3.contains.1.contains.3.contains.5"},{"$ref":"#contains.2"}]}]},{"$ref":"#contains.4.variants.0.contains.3.contains.1"},{"$ref":"#contains.4.variants.0.contains.3.contains.2"},{"$ref":"#contains.4.variants.0.contains.3.contains.1.contains.3.contains.3"},{"$ref":"#contains.4.variants.0.contains.3.contains.1.contains.3.contains.4"}]},{"$ref":"#contains.4.variants.0.contains.3.contains.1.contains.3.contains.5"},{"beginKeywords":"class interface","end":"[{;=]","illegal":"[^\\s:,]","contains":[{"className":"title","begin":"[a-zA-Z]\\w*","relevance":0},{"$ref":"#contains.1"},{"$ref":"#contains.2"}]},{"beginKeywords":"namespace","end":"[{;=]","illegal":"[^\\s:]","contains":[{"className":"title","begin":"[a-zA-Z](\\.?\\w)*","relevance":0},{"$ref":"#contains.1"},{"$ref":"#contains.2"}]},{"className":"meta","begin":"^\\s*\\[","excludeBegin":true,"end":"\\]","excludeEnd":true,"contains":[{"className":"meta-string","begin":"\"","end":"\""}]},{"beginKeywords":"new return throw await else","relevance":0},{"className":"function","begin":"([a-zA-Z]\\w*(<[a-zA-Z]\\w*(\\s*,\\s*[a-zA-Z]\\w*)*>)?(\\[\\])?\\s+)+[a-zA-Z]\\w*\\s*\\(","returnBegin":true,"end":"\\s*[{;=]","excludeEnd":true,"keywords":{"$ref":"#keywords"},"contains":[{"begin":"[a-zA-Z]\\w*\\s*\\(","returnBegin":true,"contains":[{"$ref":"#contains.6.contains.0"}],"relevance":0},{"className":"params","begin":"\\(","end":"\\)","excludeBegin":true,"excludeEnd":true,"keywords":{"$ref":"#keywords"},"relevance":0,"contains":[{"$ref":"#contains.4"},{"$ref":"#contains.4.variants.0.contains.3.contains.1.contains.3.contains.5"},{"$ref":"#contains.2"}]},{"$ref":"#contains.1"},{"$ref":"#contains.2"}]}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/csp.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/csp.json new file mode 100644 index 00000000..ad443884 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/csp.json @@ -0,0 +1 @@ +{"case_insensitive":false,"lexemes":"[a-zA-Z][a-zA-Z0-9_-]*","keywords":{"keyword":"base-uri child-src connect-src default-src font-src form-action frame-ancestors frame-src img-src media-src object-src plugin-types report-uri sandbox script-src style-src"},"contains":[{"className":"string","begin":"'","end":"'"},{"className":"attribute","begin":"^Content","end":":","excludeEnd":true}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/css.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/css.json new file mode 100644 index 00000000..768e065d --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/css.json @@ -0,0 +1 @@ +{"case_insensitive":true,"illegal":"[=\\/|'\\$]","contains":[{"className":"comment","begin":"/\\*","end":"\\*/","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"selector-id","begin":"#[A-Za-z0-9_-]+"},{"className":"selector-class","begin":"\\.[A-Za-z0-9_-]+"},{"className":"selector-attr","begin":"\\[","end":"\\]","illegal":"$"},{"className":"selector-pseudo","begin":":(:)?[a-zA-Z0-9\\_\\-\\+\\(\\)\"'.]+"},{"begin":"@(font-face|page)","lexemes":"[a-z-]+","keywords":"font-face page"},{"begin":"@","end":"[{;]","illegal":":","contains":[{"className":"keyword","begin":"\\w+"},{"begin":"\\s","endsWithParent":true,"excludeEnd":true,"relevance":0,"contains":[{"className":"string","begin":"'","end":"'","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0}]},{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"$ref":"#contains.6.contains.1.contains.0.contains.0"}]},{"className":"number","begin":"\\b\\d+(\\.\\d+)?(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?","relevance":0}]}]},{"className":"selector-tag","begin":"[a-zA-Z-][a-zA-Z0-9_-]*","relevance":0},{"begin":"{","end":"}","illegal":"\\S","contains":[{"$ref":"#contains.0"},{"begin":"(?:[A-Z\\_\\.\\-]+|--[a-zA-Z0-9_-]+)\\s*:","returnBegin":true,"end":";","endsWithParent":true,"contains":[{"className":"attribute","begin":"\\S","end":":","excludeEnd":true,"starts":{"endsWithParent":true,"excludeEnd":true,"contains":[{"begin":"[\\w-]+\\(","returnBegin":true,"contains":[{"className":"built_in","begin":"[\\w-]+"},{"begin":"\\(","end":"\\)","contains":[{"$ref":"#contains.6.contains.1.contains.0"},{"$ref":"#contains.6.contains.1.contains.1"}]}]},{"$ref":"#contains.6.contains.1.contains.2"},{"$ref":"#contains.6.contains.1.contains.1"},{"$ref":"#contains.6.contains.1.contains.0"},{"$ref":"#contains.0"},{"className":"number","begin":"#[0-9A-Fa-f]+"},{"className":"meta","begin":"!important"}]}}]}]}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/d.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/d.json new file mode 100644 index 00000000..5ae4057b --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/d.json @@ -0,0 +1 @@ +{"lexemes":"[a-zA-Z_]\\w*","keywords":{"keyword":"abstract alias align asm assert auto body break byte case cast catch class const continue debug default delete deprecated do else enum export extern final finally for foreach foreach_reverse|10 goto if immutable import in inout int interface invariant is lazy macro mixin module new nothrow out override package pragma private protected public pure ref return scope shared static struct super switch synchronized template this throw try typedef typeid typeof union unittest version void volatile while with __FILE__ __LINE__ __gshared|10 __thread __traits __DATE__ __EOF__ __TIME__ __TIMESTAMP__ __VENDOR__ __VERSION__","built_in":"bool cdouble cent cfloat char creal dchar delegate double dstring float function idouble ifloat ireal long real short string ubyte ucent uint ulong ushort wchar wstring","literal":"false null true"},"contains":[{"className":"comment","begin":"//","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"/\\*","end":"\\*/","contains":[{"$ref":"#contains.0.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"\\/\\+","end":"\\+\\/","contains":["self",{"$ref":"#contains.0.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}],"relevance":10},{"className":"string","begin":"x\"[\\da-fA-F\\s\\n\\r]*\"[cwd]?","relevance":10},{"className":"string","begin":"\"","contains":[{"begin":"\\\\(['\"\\?\\\\abfnrtv]|u[\\dA-Fa-f]{4}|[0-7]{1,3}|x[\\dA-Fa-f]{2}|U[\\dA-Fa-f]{8})|&[a-zA-Z\\d]{2,};","relevance":0}],"end":"\"[cwd]?"},{"className":"string","begin":"[rq]\"","end":"\"[cwd]?","relevance":5},{"className":"string","begin":"`","end":"`[cwd]?"},{"className":"string","begin":"q\"\\{","end":"\\}\""},{"className":"number","begin":"\\b(((0[xX](([\\da-fA-F][\\da-fA-F_]*|_[\\da-fA-F][\\da-fA-F_]*)\\.([\\da-fA-F][\\da-fA-F_]*|_[\\da-fA-F][\\da-fA-F_]*)|\\.?([\\da-fA-F][\\da-fA-F_]*|_[\\da-fA-F][\\da-fA-F_]*))[pP][+-]?(0|[1-9][\\d_]*|\\d[\\d_]*|[\\d_]+?\\d))|((0|[1-9][\\d_]*|\\d[\\d_]*|[\\d_]+?\\d)(\\.\\d*|([eE][+-]?(0|[1-9][\\d_]*|\\d[\\d_]*|[\\d_]+?\\d)))|\\d+\\.(0|[1-9][\\d_]*|\\d[\\d_]*|[\\d_]+?\\d)(0|[1-9][\\d_]*|\\d[\\d_]*|[\\d_]+?\\d)|\\.(0|[1-9][\\d_]*)([eE][+-]?(0|[1-9][\\d_]*|\\d[\\d_]*|[\\d_]+?\\d))?))([fF]|L|i|[fF]i|Li)?|((0|[1-9][\\d_]*)|0[bB][01_]+|0[xX]([\\da-fA-F][\\da-fA-F_]*|_[\\da-fA-F][\\da-fA-F_]*))(i|[fF]i|Li))","relevance":0},{"className":"number","begin":"\\b((0|[1-9][\\d_]*)|0[bB][01_]+|0[xX]([\\da-fA-F][\\da-fA-F_]*|_[\\da-fA-F][\\da-fA-F_]*))(L|u|U|Lu|LU|uL|UL)?","relevance":0},{"className":"string","begin":"'(\\\\(['\"\\?\\\\abfnrtv]|u[\\dA-Fa-f]{4}|[0-7]{1,3}|x[\\dA-Fa-f]{2}|U[\\dA-Fa-f]{8})|&[a-zA-Z\\d]{2,};|.)","end":"'","illegal":"."},{"className":"meta","begin":"^#!","end":"$","relevance":5},{"className":"meta","begin":"#(line)","end":"$","relevance":5},{"className":"keyword","begin":"@[a-zA-Z_][a-zA-Z_\\d]*"}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/dart.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/dart.json new file mode 100644 index 00000000..9553be73 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/dart.json @@ -0,0 +1 @@ +{"keywords":{"keyword":"assert async await break case catch class const continue default do else enum extends false final finally for if in is new null rethrow return super switch sync this throw true try var void while with yield abstract as dynamic export external factory get implements import library operator part set static typedef","built_in":"print Comparable DateTime Duration Function Iterable Iterator List Map Match Null Object Pattern RegExp Set Stopwatch String StringBuffer StringSink Symbol Type Uri bool double int num document window querySelector querySelectorAll Element ElementList"},"contains":[{"className":"string","variants":[{"begin":"r'''","end":"'''"},{"begin":"r\"\"\"","end":"\"\"\""},{"begin":"r'","end":"'","illegal":"\\n"},{"begin":"r\"","end":"\"","illegal":"\\n"},{"begin":"'''","end":"'''","contains":[{"begin":"\\\\[\\s\\S]","relevance":0},{"className":"subst","variants":[{"begin":"\\$[A-Za-z0-9_]+"}]},{"className":"subst","variants":[{"begin":"\\${","end":"}"}],"keywords":"true false null this is new super","contains":[{"className":"number","begin":"(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)","relevance":0},{"$ref":"#contains.0"}]}]},{"begin":"\"\"\"","end":"\"\"\"","contains":[{"$ref":"#contains.0.variants.4.contains.0"},{"$ref":"#contains.0.variants.4.contains.1"},{"$ref":"#contains.0.variants.4.contains.2"}]},{"begin":"'","end":"'","illegal":"\\n","contains":[{"$ref":"#contains.0.variants.4.contains.0"},{"$ref":"#contains.0.variants.4.contains.1"},{"$ref":"#contains.0.variants.4.contains.2"}]},{"begin":"\"","end":"\"","illegal":"\\n","contains":[{"$ref":"#contains.0.variants.4.contains.0"},{"$ref":"#contains.0.variants.4.contains.1"},{"$ref":"#contains.0.variants.4.contains.2"}]}]},{"className":"comment","begin":"/\\*\\*","end":"\\*/","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}],"subLanguage":"markdown"},{"className":"comment","begin":"///","end":"$","contains":[{"$ref":"#contains.1.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}],"subLanguage":"markdown"},{"className":"comment","begin":"//","end":"$","contains":[{"$ref":"#contains.1.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"/\\*","end":"\\*/","contains":[{"$ref":"#contains.1.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"class","beginKeywords":"class interface","end":"{","excludeEnd":true,"contains":[{"beginKeywords":"extends implements"},{"className":"title","begin":"[a-zA-Z_]\\w*","relevance":0}]},{"$ref":"#contains.0.variants.4.contains.2.contains.0"},{"className":"meta","begin":"@[A-Za-z]+"},{"begin":"=>"}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/delphi.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/delphi.json new file mode 100644 index 00000000..b72dc356 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/delphi.json @@ -0,0 +1 @@ +{"aliases":["dpr","dfm","pas","pascal","freepascal","lazarus","lpr","lfm"],"case_insensitive":true,"keywords":"exports register file shl array record property for mod while set ally label uses raise not stored class safecall var interface or private static exit index inherited to else stdcall override shr asm far resourcestring finalization packed virtual out and protected library do xorwrite goto near function end div overload object unit begin string on inline repeat until destructor write message program with read initialization except default nil if case cdecl in downto threadvar of try pascal const external constructor type public then implementation finally published procedure absolute reintroduce operator as is abstract alias assembler bitpacked break continue cppdecl cvar enumerator experimental platform deprecated unimplemented dynamic export far16 forward generic helper implements interrupt iochecks local name nodefault noreturn nostackframe oldfpccall otherwise saveregisters softfloat specialize strict unaligned varargs ","illegal":"\"|\\$[G-Zg-z]|\\/\\*|<\\/|\\|","contains":[{"className":"string","begin":"'","end":"'","contains":[{"begin":"''"}]},{"className":"string","begin":"(#\\d+)+"},{"className":"number","begin":"\\b\\d+(\\.\\d+)?","relevance":0},{"begin":"[a-zA-Z]\\w*\\s*=\\s*class\\s*\\(","returnBegin":true,"contains":[{"className":"title","begin":"[a-zA-Z]\\w*","relevance":0}]},{"className":"function","beginKeywords":"function constructor destructor procedure","end":"[:;]","keywords":"function constructor|10 destructor|10 procedure|10","contains":[{"$ref":"#contains.3.contains.0"},{"className":"params","begin":"\\(","end":"\\)","keywords":"exports register file shl array record property for mod while set ally label uses raise not stored class safecall var interface or private static exit index inherited to else stdcall override shr asm far resourcestring finalization packed virtual out and protected library do xorwrite goto near function end div overload object unit begin string on inline repeat until destructor write message program with read initialization except default nil if case cdecl in downto threadvar of try pascal const external constructor type public then implementation finally published procedure absolute reintroduce operator as is abstract alias assembler bitpacked break continue cppdecl cvar enumerator experimental platform deprecated unimplemented dynamic export far16 forward generic helper implements interrupt iochecks local name nodefault noreturn nostackframe oldfpccall otherwise saveregisters softfloat specialize strict unaligned varargs ","contains":[{"$ref":"#contains.0"},{"$ref":"#contains.1"},{"className":"meta","variants":[{"begin":"\\{\\$","end":"\\}"},{"begin":"\\(\\*\\$","end":"\\*\\)"}]},{"className":"comment","begin":"//","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"\\{","end":"\\}","contains":[{"$ref":"#contains.4.contains.1.contains.3.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}],"relevance":0},{"className":"comment","begin":"\\(\\*","end":"\\*\\)","contains":[{"$ref":"#contains.4.contains.1.contains.3.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}],"relevance":10}]},{"$ref":"#contains.4.contains.1.contains.2"},{"$ref":"#contains.4.contains.1.contains.3"},{"$ref":"#contains.4.contains.1.contains.4"},{"$ref":"#contains.4.contains.1.contains.5"}]},{"$ref":"#contains.4.contains.1.contains.2"},{"$ref":"#contains.4.contains.1.contains.3"},{"$ref":"#contains.4.contains.1.contains.4"},{"$ref":"#contains.4.contains.1.contains.5"}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/diff.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/diff.json new file mode 100644 index 00000000..e54052e1 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/diff.json @@ -0,0 +1 @@ +{"aliases":["patch"],"contains":[{"className":"meta","relevance":10,"variants":[{"begin":"^@@ +\\-\\d+,\\d+ +\\+\\d+,\\d+ +@@$"},{"begin":"^\\*\\*\\* +\\d+,\\d+ +\\*\\*\\*\\*$"},{"begin":"^\\-\\-\\- +\\d+,\\d+ +\\-\\-\\-\\-$"}]},{"className":"comment","variants":[{"begin":"Index: ","end":"$"},{"begin":"={3,}","end":"$"},{"begin":"^\\-{3}","end":"$"},{"begin":"^\\*{3} ","end":"$"},{"begin":"^\\+{3}","end":"$"},{"begin":"\\*{5}","end":"\\*{5}$"}]},{"className":"addition","begin":"^\\+","end":"$"},{"className":"deletion","begin":"^\\-","end":"$"},{"className":"addition","begin":"^\\!","end":"$"}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/django.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/django.json new file mode 100644 index 00000000..1afbaa50 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/django.json @@ -0,0 +1 @@ +{"aliases":["jinja"],"case_insensitive":true,"subLanguage":"xml","contains":[{"className":"comment","begin":"\\{%\\s*comment\\s*%}","end":"\\{%\\s*endcomment\\s*%}","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"\\{#","end":"#}","contains":[{"$ref":"#contains.0.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"template-tag","begin":"\\{%","end":"%}","contains":[{"className":"name","begin":"\\w+","keywords":{"name":"comment endcomment load templatetag ifchanged endifchanged if endif firstof for endfor ifnotequal endifnotequal widthratio extends include spaceless endspaceless regroup ifequal endifequal ssi now with cycle url filter endfilter debug block endblock else autoescape endautoescape csrf_token empty elif endwith static trans blocktrans endblocktrans get_static_prefix get_media_prefix plural get_current_language language get_available_languages get_current_language_bidi get_language_info get_language_info_list localize endlocalize localtime endlocaltime timezone endtimezone get_current_timezone verbatim"},"starts":{"endsWithParent":true,"keywords":"in by as","contains":[{"begin":"\\|[A-Za-z]+:?","keywords":{"name":"truncatewords removetags linebreaksbr yesno get_digit timesince random striptags filesizeformat escape linebreaks length_is ljust rjust cut urlize fix_ampersands title floatformat capfirst pprint divisibleby add make_list unordered_list urlencode timeuntil urlizetrunc wordcount stringformat linenumbers slice date dictsort dictsortreversed default_if_none pluralize lower join center default truncatewords_html upper length phone2numeric wordwrap time addslashes slugify first escapejs force_escape iriencode last safe safeseq truncatechars localize unlocalize localtime utc timezone"},"contains":[{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0}]},{"className":"string","begin":"'","end":"'","illegal":"\\n","contains":[{"$ref":"#contains.2.contains.0.starts.contains.0.contains.0.contains.0"}]}]}],"relevance":0}}]},{"className":"template-variable","begin":"\\{\\{","end":"}}","contains":[{"$ref":"#contains.2.contains.0.starts.contains.0"}]}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/dns.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/dns.json new file mode 100644 index 00000000..773d905c --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/dns.json @@ -0,0 +1 @@ +{"aliases":["bind","zone"],"keywords":{"keyword":"IN A AAAA AFSDB APL CAA CDNSKEY CDS CERT CNAME DHCID DLV DNAME DNSKEY DS HIP IPSECKEY KEY KX LOC MX NAPTR NS NSEC NSEC3 NSEC3PARAM PTR RRSIG RP SIG SOA SRV SSHFP TA TKEY TLSA TSIG TXT"},"contains":[{"className":"comment","begin":";","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}],"relevance":0},{"className":"meta","begin":"^\\$(TTL|GENERATE|INCLUDE|ORIGIN)\\b"},{"className":"number","begin":"((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:)))\\b"},{"className":"number","begin":"((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]).){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\b"},{"className":"number","begin":"\\b\\d+[dhwm]?","relevance":0}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/dockerfile.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/dockerfile.json new file mode 100644 index 00000000..f059e77d --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/dockerfile.json @@ -0,0 +1 @@ +{"aliases":["docker"],"case_insensitive":true,"keywords":"from maintainer expose env arg user onbuild stopsignal","contains":[{"className":"comment","begin":"#","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"string","begin":"'","end":"'","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0}]},{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"$ref":"#contains.1.contains.0"}]},{"className":"number","begin":"\\b\\d+(\\.\\d+)?","relevance":0},{"beginKeywords":"run cmd entrypoint volume add copy workdir label healthcheck shell","starts":{"end":"[^\\\\]$","subLanguage":"bash"}}],"illegal":"","contains":[{"className":"number","variants":[{"begin":"\\b(\\d+(\\.\\d*)?|\\.\\d+)(u|U|l|L|ul|UL|f|F)"},{"begin":"(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)"}],"relevance":0},{"$ref":"#contains.0.contains.0"}]},{"className":"comment","begin":"//","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"/\\*","end":"\\*/","contains":[{"$ref":"#contains.0.contains.5.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"$ref":"#contains.0.contains.4.contains.0"},{"className":"string","variants":[{"className":"string","begin":"((u8?|U)|L)?\"","end":"\"","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0}]},{"begin":"(u8?|U)?R\"","end":"\"","contains":[{"$ref":"#contains.0.contains.8.variants.0.contains.0"}]},{"begin":"'\\\\?.","end":"'","illegal":"."}]}]},{"$ref":"#contains.0.contains.0"},{"$ref":"#contains.0.contains.1"},{"$ref":"#contains.0.contains.2"},{"$ref":"#contains.0.contains.3"},{"$ref":"#contains.0.contains.4"},{"$ref":"#contains.0.contains.5"},{"$ref":"#contains.0.contains.6"},{"$ref":"#contains.0.contains.4.contains.0"},{"$ref":"#contains.0.contains.8"},{"className":"meta","begin":"#","end":"$","keywords":{"meta-keyword":"if else elif endif define undef ifdef ifndef"},"contains":[{"begin":"\\\\\\n","relevance":0},{"beginKeywords":"include","end":"$","keywords":{"meta-keyword":"include"},"contains":[{"className":"meta-string","variants":{"$ref":"#contains.0.contains.8.variants"}},{"className":"meta-string","begin":"<","end":">","illegal":"\\n"}]},{"$ref":"#contains.0.contains.8"},{"$ref":"#contains.0.contains.5"},{"$ref":"#contains.0.contains.6"}]},{"begin":"[a-zA-Z]\\w*::","keywords":""}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/dust.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/dust.json new file mode 100644 index 00000000..e250b853 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/dust.json @@ -0,0 +1 @@ +{"aliases":["dst"],"case_insensitive":true,"subLanguage":"xml","contains":[{"className":"template-tag","begin":"\\{[#\\/]","end":"\\}","illegal":";","contains":[{"className":"name","begin":"[a-zA-Z\\.-]+","starts":{"endsWithParent":true,"relevance":0,"contains":[{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0}]}]}}]},{"className":"template-variable","begin":"\\{","end":"\\}","illegal":";","keywords":"if eq ne lt lte gt gte select default math sep"}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/ebnf.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/ebnf.json new file mode 100644 index 00000000..e64018d0 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/ebnf.json @@ -0,0 +1 @@ +{"illegal":"\\S","contains":[{"className":"comment","begin":"\\(\\*","end":"\\*\\)","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"attribute","begin":"^[ ]*[a-zA-Z][a-zA-Z-]*([\\s-]+[a-zA-Z][a-zA-Z]*)*"},{"begin":"=","end":";","contains":[{"$ref":"#contains.0"},{"className":"meta","begin":"\\?.*\\?"},{"className":"string","begin":"'","end":"'","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0}]},{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"$ref":"#contains.2.contains.2.contains.0"}]}]}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/elixir.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/elixir.json new file mode 100644 index 00000000..0455fd39 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/elixir.json @@ -0,0 +1 @@ +{"lexemes":"[a-zA-Z_][a-zA-Z0-9_.]*(\\!|\\?)?","keywords":"and false then defined module in return redo retry end for true self when next until do begin unless nil break not case cond alias while ensure or include use alias fn quote require import with|0","contains":[{"className":"string","contains":[{"begin":"\\\\[\\s\\S]","relevance":0},{"className":"subst","begin":"#\\{","end":"}","lexemes":"[a-zA-Z_][a-zA-Z0-9_.]*(\\!|\\?)?","keywords":"and false then defined module in return redo retry end for true self when next until do begin unless nil break not case cond alias while ensure or include use alias fn quote require import with|0","contains":{"$ref":"#contains"}}],"variants":[{"begin":"'","end":"'"},{"begin":"\"","end":"\""}]},{"className":"comment","begin":"#","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"class","beginKeywords":"defimpl defmodule defprotocol defrecord","end":"\\bdo\\b|$|;","contains":[{"className":"title","begin":"[a-zA-Z_][a-zA-Z0-9_.]*(\\!|\\?)?","relevance":0,"endsParent":true}]},{"className":"function","beginKeywords":"def defp defmacro","end":"\\B\\b","contains":{"$ref":"#contains.2.contains"}},{"begin":"::"},{"className":"symbol","begin":":(?![\\s:])","contains":[{"$ref":"#contains.0"},{"begin":"[a-zA-Z_]\\w*[!?=]?|[-+~]\\@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?"}],"relevance":0},{"className":"symbol","begin":"[a-zA-Z_][a-zA-Z0-9_.]*(\\!|\\?)?:(?!:)","relevance":0},{"className":"number","begin":"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b","relevance":0},{"className":"variable","begin":"(\\$\\W)|((\\$|\\@\\@?)(\\w+))"},{"begin":"->"},{"begin":"(!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~)\\s*","contains":[{"$ref":"#contains.1"},{"className":"regexp","illegal":"\\n","contains":[{"$ref":"#contains.0.contains.0"},{"$ref":"#contains.0.contains.1"}],"variants":[{"begin":"/","end":"/[a-z]*"},{"begin":"%r\\[","end":"\\][a-z]*"}]}],"relevance":0}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/elm.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/elm.json new file mode 100644 index 00000000..5875c3a9 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/elm.json @@ -0,0 +1 @@ +{"keywords":"let in if then else case of where module import exposing type alias as infix infixl infixr port effect command subscription","contains":[{"beginKeywords":"port effect module","end":"exposing","keywords":"port effect module where command subscription exposing","contains":[{"begin":"\\(","end":"\\)","illegal":"\"","contains":[{"className":"type","begin":"\\b[A-Z][\\w]*(\\((\\.\\.|,|\\w+)\\))?"},{"variants":[{"className":"comment","begin":"--","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"{-","end":"-}","contains":["self",{"$ref":"#contains.0.contains.0.contains.1.variants.0.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]}]}]},{"$ref":"#contains.0.contains.0.contains.1"}],"illegal":"\\W\\.|;"},{"begin":"import","end":"$","keywords":"import as exposing","contains":[{"$ref":"#contains.0.contains.0"},{"$ref":"#contains.0.contains.0.contains.1"}],"illegal":"\\W\\.|;"},{"begin":"type","end":"$","keywords":"type alias","contains":[{"className":"type","begin":"\\b[A-Z][\\w']*","relevance":0},{"$ref":"#contains.0.contains.0"},{"begin":"{","end":"}","contains":{"$ref":"#contains.0.contains.0.contains"}},{"$ref":"#contains.0.contains.0.contains.1"}]},{"beginKeywords":"infix infixl infixr","end":"$","contains":[{"className":"number","begin":"(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)","relevance":0},{"$ref":"#contains.0.contains.0.contains.1"}]},{"begin":"port","end":"$","keywords":"port","contains":[{"$ref":"#contains.0.contains.0.contains.1"}]},{"className":"string","begin":"'\\\\?.","end":"'","illegal":"."},{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0}]},{"$ref":"#contains.3.contains.0"},{"$ref":"#contains.2.contains.0"},{"className":"title","begin":"^[_a-z][\\w']*","relevance":0},{"$ref":"#contains.0.contains.0.contains.1"},{"begin":"->|<-"}],"illegal":";"} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/erb.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/erb.json new file mode 100644 index 00000000..7472adbd --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/erb.json @@ -0,0 +1 @@ +{"subLanguage":"xml","contains":[{"className":"comment","begin":"<%#","end":"%>","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"begin":"<%[%=-]?","end":"[%-]?%>","subLanguage":"ruby","excludeBegin":true,"excludeEnd":true}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/erlang-repl.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/erlang-repl.json new file mode 100644 index 00000000..d7b79f06 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/erlang-repl.json @@ -0,0 +1 @@ +{"keywords":{"built_in":"spawn spawn_link self","keyword":"after and andalso|10 band begin bnot bor bsl bsr bxor case catch cond div end fun if let not of or orelse|10 query receive rem try when xor"},"contains":[{"className":"meta","begin":"^[0-9]+> ","relevance":10},{"className":"comment","begin":"%","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"number","begin":"\\b(\\d+#[a-fA-F0-9]+|\\d+(\\.\\d+)?([eE][-+]?\\d+)?)","relevance":0},{"className":"string","begin":"'","end":"'","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0}]},{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"$ref":"#contains.3.contains.0"}]},{"begin":"\\?(::)?([A-Z]\\w*(::)?)+"},{"begin":"->"},{"begin":"ok"},{"begin":"!"},{"begin":"(\\b[a-z'][a-zA-Z0-9_']*:[a-z'][a-zA-Z0-9_']*)|(\\b[a-z'][a-zA-Z0-9_']*)","relevance":0},{"begin":"[A-Z][a-zA-Z0-9_']*","relevance":0}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/erlang.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/erlang.json new file mode 100644 index 00000000..3d528ae3 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/erlang.json @@ -0,0 +1 @@ +{"aliases":["erl"],"keywords":{"keyword":"after and andalso|10 band begin bnot bor bsl bzr bxor case catch cond div end fun if let not of orelse|10 query receive rem try when xor","literal":"false true"},"illegal":"(","returnBegin":true,"illegal":"\\(|#|//|/\\*|\\\\|:|;","contains":[{"className":"params","begin":"\\(","end":"\\)","contains":[{"className":"comment","begin":"%","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"begin":"fun\\s+[a-z'][a-zA-Z0-9_']*/\\d+"},{"beginKeywords":"fun receive if try case","end":"end","keywords":{"$ref":"#keywords"},"contains":[{"$ref":"#contains.0.contains.0.contains.0"},{"$ref":"#contains.0.contains.0.contains.1"},{"className":"","begin":"'","end":"'","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0}]},{"$ref":"#contains.0.contains.0.contains.2"},{"begin":"([a-z'][a-zA-Z0-9_']*:[a-z'][a-zA-Z0-9_']*|[a-z'][a-zA-Z0-9_']*)\\(","end":"\\)","returnBegin":true,"relevance":0,"contains":[{"begin":"([a-z'][a-zA-Z0-9_']*:[a-z'][a-zA-Z0-9_']*|[a-z'][a-zA-Z0-9_']*)","relevance":0},{"begin":"\\(","end":"\\)","endsWithParent":true,"returnEnd":true,"relevance":0,"contains":{"$ref":"#contains.0.contains.0.contains"}}]},{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"$ref":"#contains.0.contains.0.contains.2.contains.2.contains.0"}]},{"className":"number","begin":"\\b(\\d+#[a-fA-F0-9]+|\\d+(\\.\\d+)?([eE][-+]?\\d+)?)","relevance":0},{"begin":"{","end":"}","relevance":0,"contains":{"$ref":"#contains.0.contains.0.contains"}},{"begin":"\\b_([A-Z][A-Za-z0-9_]*)?","relevance":0},{"begin":"[A-Z][a-zA-Z0-9_]*","relevance":0},{"begin":"#[a-zA-Z_]\\w*","relevance":0,"returnBegin":true,"contains":[{"begin":"#[a-zA-Z_]\\w*","relevance":0},{"begin":"{","end":"}","relevance":0,"contains":{"$ref":"#contains.0.contains.0.contains"}}]}]},{"$ref":"#contains.0.contains.0.contains.2.contains.4"},{"$ref":"#contains.0.contains.0.contains.2.contains.5"},{"$ref":"#contains.0.contains.0.contains.2.contains.6"},{"$ref":"#contains.0.contains.0.contains.2.contains.7"},{"$ref":"#contains.0.contains.0.contains.2.contains.8"},{"$ref":"#contains.0.contains.0.contains.2.contains.9"},{"$ref":"#contains.0.contains.0.contains.2.contains.10"}]},{"className":"title","begin":"[a-z'][a-zA-Z0-9_']*","relevance":0}],"starts":{"end":";|\\.","keywords":{"$ref":"#keywords"},"contains":{"$ref":"#contains.0.contains.0.contains"}}},{"$ref":"#contains.0.contains.0.contains.0"},{"begin":"^-","end":"\\.","relevance":0,"excludeEnd":true,"returnBegin":true,"lexemes":"-[a-zA-Z]\\w*","keywords":"-module -record -undef -export -ifdef -ifndef -author -copyright -doc -vsn -import -include -include_lib -compile -define -else -endif -file -behaviour -behavior -spec","contains":[{"$ref":"#contains.0.contains.0"}]},{"$ref":"#contains.0.contains.0.contains.2.contains.6"},{"$ref":"#contains.0.contains.0.contains.2.contains.5"},{"$ref":"#contains.0.contains.0.contains.2.contains.10"},{"$ref":"#contains.0.contains.0.contains.2.contains.8"},{"$ref":"#contains.0.contains.0.contains.2.contains.9"},{"$ref":"#contains.0.contains.0.contains.2.contains.7"},{"begin":"\\.$"}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/excel.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/excel.json new file mode 100644 index 00000000..56cb11c4 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/excel.json @@ -0,0 +1 @@ +{"aliases":["xlsx","xls"],"case_insensitive":true,"lexemes":"[a-zA-Z][\\w\\.]*","keywords":{"built_in":"ABS ACCRINT ACCRINTM ACOS ACOSH ACOT ACOTH AGGREGATE ADDRESS AMORDEGRC AMORLINC AND ARABIC AREAS ASC ASIN ASINH ATAN ATAN2 ATANH AVEDEV AVERAGE AVERAGEA AVERAGEIF AVERAGEIFS BAHTTEXT BASE BESSELI BESSELJ BESSELK BESSELY BETADIST BETA.DIST BETAINV BETA.INV BIN2DEC BIN2HEX BIN2OCT BINOMDIST BINOM.DIST BINOM.DIST.RANGE BINOM.INV BITAND BITLSHIFT BITOR BITRSHIFT BITXOR CALL CEILING CEILING.MATH CEILING.PRECISE CELL CHAR CHIDIST CHIINV CHITEST CHISQ.DIST CHISQ.DIST.RT CHISQ.INV CHISQ.INV.RT CHISQ.TEST CHOOSE CLEAN CODE COLUMN COLUMNS COMBIN COMBINA COMPLEX CONCAT CONCATENATE CONFIDENCE CONFIDENCE.NORM CONFIDENCE.T CONVERT CORREL COS COSH COT COTH COUNT COUNTA COUNTBLANK COUNTIF COUNTIFS COUPDAYBS COUPDAYS COUPDAYSNC COUPNCD COUPNUM COUPPCD COVAR COVARIANCE.P COVARIANCE.S CRITBINOM CSC CSCH CUBEKPIMEMBER CUBEMEMBER CUBEMEMBERPROPERTY CUBERANKEDMEMBER CUBESET CUBESETCOUNT CUBEVALUE CUMIPMT CUMPRINC DATE DATEDIF DATEVALUE DAVERAGE DAY DAYS DAYS360 DB DBCS DCOUNT DCOUNTA DDB DEC2BIN DEC2HEX DEC2OCT DECIMAL DEGREES DELTA DEVSQ DGET DISC DMAX DMIN DOLLAR DOLLARDE DOLLARFR DPRODUCT DSTDEV DSTDEVP DSUM DURATION DVAR DVARP EDATE EFFECT ENCODEURL EOMONTH ERF ERF.PRECISE ERFC ERFC.PRECISE ERROR.TYPE EUROCONVERT EVEN EXACT EXP EXPON.DIST EXPONDIST FACT FACTDOUBLE FALSE|0 F.DIST FDIST F.DIST.RT FILTERXML FIND FINDB F.INV F.INV.RT FINV FISHER FISHERINV FIXED FLOOR FLOOR.MATH FLOOR.PRECISE FORECAST FORECAST.ETS FORECAST.ETS.CONFINT FORECAST.ETS.SEASONALITY FORECAST.ETS.STAT FORECAST.LINEAR FORMULATEXT FREQUENCY F.TEST FTEST FV FVSCHEDULE GAMMA GAMMA.DIST GAMMADIST GAMMA.INV GAMMAINV GAMMALN GAMMALN.PRECISE GAUSS GCD GEOMEAN GESTEP GETPIVOTDATA GROWTH HARMEAN HEX2BIN HEX2DEC HEX2OCT HLOOKUP HOUR HYPERLINK HYPGEOM.DIST HYPGEOMDIST IF|0 IFERROR IFNA IFS IMABS IMAGINARY IMARGUMENT IMCONJUGATE IMCOS IMCOSH IMCOT IMCSC IMCSCH IMDIV IMEXP IMLN IMLOG10 IMLOG2 IMPOWER IMPRODUCT IMREAL IMSEC IMSECH IMSIN IMSINH IMSQRT IMSUB IMSUM IMTAN INDEX INDIRECT INFO INT INTERCEPT INTRATE IPMT IRR ISBLANK ISERR ISERROR ISEVEN ISFORMULA ISLOGICAL ISNA ISNONTEXT ISNUMBER ISODD ISREF ISTEXT ISO.CEILING ISOWEEKNUM ISPMT JIS KURT LARGE LCM LEFT LEFTB LEN LENB LINEST LN LOG LOG10 LOGEST LOGINV LOGNORM.DIST LOGNORMDIST LOGNORM.INV LOOKUP LOWER MATCH MAX MAXA MAXIFS MDETERM MDURATION MEDIAN MID MIDBs MIN MINIFS MINA MINUTE MINVERSE MIRR MMULT MOD MODE MODE.MULT MODE.SNGL MONTH MROUND MULTINOMIAL MUNIT N NA NEGBINOM.DIST NEGBINOMDIST NETWORKDAYS NETWORKDAYS.INTL NOMINAL NORM.DIST NORMDIST NORMINV NORM.INV NORM.S.DIST NORMSDIST NORM.S.INV NORMSINV NOT NOW NPER NPV NUMBERVALUE OCT2BIN OCT2DEC OCT2HEX ODD ODDFPRICE ODDFYIELD ODDLPRICE ODDLYIELD OFFSET OR PDURATION PEARSON PERCENTILE.EXC PERCENTILE.INC PERCENTILE PERCENTRANK.EXC PERCENTRANK.INC PERCENTRANK PERMUT PERMUTATIONA PHI PHONETIC PI PMT POISSON.DIST POISSON POWER PPMT PRICE PRICEDISC PRICEMAT PROB PRODUCT PROPER PV QUARTILE QUARTILE.EXC QUARTILE.INC QUOTIENT RADIANS RAND RANDBETWEEN RANK.AVG RANK.EQ RANK RATE RECEIVED REGISTER.ID REPLACE REPLACEB REPT RIGHT RIGHTB ROMAN ROUND ROUNDDOWN ROUNDUP ROW ROWS RRI RSQ RTD SEARCH SEARCHB SEC SECH SECOND SERIESSUM SHEET SHEETS SIGN SIN SINH SKEW SKEW.P SLN SLOPE SMALL SQL.REQUEST SQRT SQRTPI STANDARDIZE STDEV STDEV.P STDEV.S STDEVA STDEVP STDEVPA STEYX SUBSTITUTE SUBTOTAL SUM SUMIF SUMIFS SUMPRODUCT SUMSQ SUMX2MY2 SUMX2PY2 SUMXMY2 SWITCH SYD T TAN TANH TBILLEQ TBILLPRICE TBILLYIELD T.DIST T.DIST.2T T.DIST.RT TDIST TEXT TEXTJOIN TIME TIMEVALUE T.INV T.INV.2T TINV TODAY TRANSPOSE TREND TRIM TRIMMEAN TRUE|0 TRUNC T.TEST TTEST TYPE UNICHAR UNICODE UPPER VALUE VAR VAR.P VAR.S VARA VARP VARPA VDB VLOOKUP WEBSERVICE WEEKDAY WEEKNUM WEIBULL WEIBULL.DIST WORKDAY WORKDAY.INTL XIRR XNPV XOR YEAR YEARFRAC YIELD YIELDDISC YIELDMAT Z.TEST ZTEST"},"contains":[{"begin":"^=","end":"[^=]","returnEnd":true,"illegal":"=","relevance":10},{"className":"symbol","begin":"\\b[A-Z]{1,2}\\d+\\b","end":"[^\\d]","excludeEnd":true,"relevance":0},{"className":"symbol","begin":"[A-Z]{0,2}\\d*:[A-Z]{0,2}\\d*","relevance":0},{"begin":"\\\\[\\s\\S]","relevance":0},{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"$ref":"#contains.3"}]},{"className":"number","begin":"\\b\\d+(\\.\\d+)?(%)?","relevance":0},{"className":"comment","begin":"\\bN\\(","end":"\\)","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}],"excludeBegin":true,"excludeEnd":true,"illegal":"\\n"}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/fix.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/fix.json new file mode 100644 index 00000000..e09593dd --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/fix.json @@ -0,0 +1 @@ +{"contains":[{"begin":"[^\\x{2401}\\x{0001}]+","end":"[\\x{2401}\\x{0001}]","excludeEnd":true,"returnBegin":true,"returnEnd":false,"contains":[{"begin":"([^\\x{2401}\\x{0001}=]+)","end":"=([^\\x{2401}\\x{0001}=]+)","returnEnd":true,"returnBegin":false,"className":"attr"},{"begin":"=","end":"([\\x{2401}\\x{0001}])","excludeEnd":true,"excludeBegin":true,"className":"string"}]}],"case_insensitive":true} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/flix.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/flix.json new file mode 100644 index 00000000..a4aedbfd --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/flix.json @@ -0,0 +1 @@ +{"keywords":{"literal":"true false","keyword":"case class def else enum if impl import in lat rel index let match namespace switch type yield with"},"contains":[{"className":"comment","begin":"//","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"/\\*","end":"\\*/","contains":[{"$ref":"#contains.0.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"string","begin":"'(.|\\\\[xXuU][a-zA-Z0-9]+)'"},{"className":"string","variants":[{"begin":"\"","end":"\""}]},{"className":"function","beginKeywords":"def","end":"[:={\\[(\\n;]","excludeEnd":true,"contains":[{"className":"title","begin":"[^0-9\\n\\t \"'(),.`{}\\[\\]:;][^\\n\\t \"'(),.`{}\\[\\]:;]+|[^0-9\\n\\t \"'(),.`{}\\[\\]:;=]"}]},{"className":"number","begin":"(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)","relevance":0}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/fortran.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/fortran.json new file mode 100644 index 00000000..45a591b0 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/fortran.json @@ -0,0 +1 @@ +{"case_insensitive":true,"aliases":["f90","f95"],"keywords":{"literal":".False. .True.","keyword":"kind do while private call intrinsic where elsewhere type endtype endmodule endselect endinterface end enddo endif if forall endforall only contains default return stop then public subroutine|10 function program .and. .or. .not. .le. .eq. .ge. .gt. .lt. goto save else use module select case access blank direct exist file fmt form formatted iostat name named nextrec number opened rec recl sequential status unformatted unit continue format pause cycle exit c_null_char c_alert c_backspace c_form_feed flush wait decimal round iomsg synchronous nopass non_overridable pass protected volatile abstract extends import non_intrinsic value deferred generic final enumerator class associate bind enum c_int c_short c_long c_long_long c_signed_char c_size_t c_int8_t c_int16_t c_int32_t c_int64_t c_int_least8_t c_int_least16_t c_int_least32_t c_int_least64_t c_int_fast8_t c_int_fast16_t c_int_fast32_t c_int_fast64_t c_intmax_t C_intptr_t c_float c_double c_long_double c_float_complex c_double_complex c_long_double_complex c_bool c_char c_null_ptr c_null_funptr c_new_line c_carriage_return c_horizontal_tab c_vertical_tab iso_c_binding c_loc c_funloc c_associated c_f_pointer c_ptr c_funptr iso_fortran_env character_storage_size error_unit file_storage_size input_unit iostat_end iostat_eor numeric_storage_size output_unit c_f_procpointer ieee_arithmetic ieee_support_underflow_control ieee_get_underflow_mode ieee_set_underflow_mode newunit contiguous recursive pad position action delim readwrite eor advance nml interface procedure namelist include sequence elemental pure integer real character complex logical dimension allocatable|10 parameter external implicit|10 none double precision assign intent optional pointer target in out common equivalence data","built_in":"alog alog10 amax0 amax1 amin0 amin1 amod cabs ccos cexp clog csin csqrt dabs dacos dasin datan datan2 dcos dcosh ddim dexp dint dlog dlog10 dmax1 dmin1 dmod dnint dsign dsin dsinh dsqrt dtan dtanh float iabs idim idint idnint ifix isign max0 max1 min0 min1 sngl algama cdabs cdcos cdexp cdlog cdsin cdsqrt cqabs cqcos cqexp cqlog cqsin cqsqrt dcmplx dconjg derf derfc dfloat dgamma dimag dlgama iqint qabs qacos qasin qatan qatan2 qcmplx qconjg qcos qcosh qdim qerf qerfc qexp qgamma qimag qlgama qlog qlog10 qmax1 qmin1 qmod qnint qsign qsin qsinh qsqrt qtan qtanh abs acos aimag aint anint asin atan atan2 char cmplx conjg cos cosh exp ichar index int log log10 max min nint sign sin sinh sqrt tan tanh print write dim lge lgt lle llt mod nullify allocate deallocate adjustl adjustr all allocated any associated bit_size btest ceiling count cshift date_and_time digits dot_product eoshift epsilon exponent floor fraction huge iand ibclr ibits ibset ieor ior ishft ishftc lbound len_trim matmul maxexponent maxloc maxval merge minexponent minloc minval modulo mvbits nearest pack present product radix random_number random_seed range repeat reshape rrspacing scale scan selected_int_kind selected_real_kind set_exponent shape size spacing spread sum system_clock tiny transpose trim ubound unpack verify achar iachar transfer dble entry dprod cpu_time command_argument_count get_command get_command_argument get_environment_variable is_iostat_end ieee_arithmetic ieee_support_underflow_control ieee_get_underflow_mode ieee_set_underflow_mode is_iostat_eor move_alloc new_line selected_char_kind same_type_as extends_type_ofacosh asinh atanh bessel_j0 bessel_j1 bessel_jn bessel_y0 bessel_y1 bessel_yn erf erfc erfc_scaled gamma log_gamma hypot norm2 atomic_define atomic_ref execute_command_line leadz trailz storage_size merge_bits bge bgt ble blt dshiftl dshiftr findloc iall iany iparity image_index lcobound ucobound maskl maskr num_images parity popcnt poppar shifta shiftl shiftr this_image"},"illegal":"\\/\\*","contains":[{"className":"string","begin":"'","end":"'","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0}],"relevance":0},{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"$ref":"#contains.0.contains.0"}],"relevance":0},{"className":"function","beginKeywords":"subroutine function program","illegal":"[${=\\n]","contains":[{"className":"title","begin":"[a-zA-Z_]\\w*","relevance":0},{"className":"params","begin":"\\(","end":"\\)"}]},{"className":"comment","begin":"!","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}],"relevance":0},{"className":"number","begin":"(?=\\b|\\+|\\-|\\.)(?=\\.\\d|\\d)(?:\\d+)?(?:\\.?\\d*)(?:[de][+-]?\\d+)?\\b\\.?","relevance":0}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/fsharp.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/fsharp.json new file mode 100644 index 00000000..317291a4 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/fsharp.json @@ -0,0 +1 @@ +{"aliases":["fs"],"keywords":"abstract and as assert base begin class default delegate do done downcast downto elif else end exception extern false finally for fun function global if in inherit inline interface internal lazy let match member module mutable namespace new null of open or override private public rec return sig static struct then to true try type upcast use val void when while with yield","illegal":"\\/\\*","contains":[{"className":"keyword","begin":"\\b(yield|return|let|do)!"},{"className":"string","begin":"@\"","end":"\"","contains":[{"begin":"\"\""}]},{"className":"string","begin":"\"\"\"","end":"\"\"\""},{"className":"comment","begin":"\\(\\*","end":"\\*\\)","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"class","beginKeywords":"type","end":"\\(|=|$","excludeEnd":true,"contains":[{"className":"title","begin":"[a-zA-Z_]\\w*","relevance":0},{"begin":"<","end":">","contains":[{"className":"title","begin":"'[a-zA-Z0-9_]+","relevance":0}]}]},{"className":"meta","begin":"\\[<","end":">\\]","relevance":10},{"className":"symbol","begin":"\\B('[A-Za-z])\\b","contains":[{"begin":"\\\\[\\s\\S]","relevance":0}]},{"className":"comment","begin":"//","end":"$","contains":[{"$ref":"#contains.3.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"string","begin":"\"","end":"\"","illegal":null,"contains":[{"$ref":"#contains.6.contains.0"}]},{"className":"number","begin":"(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)","relevance":0}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/gams.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/gams.json new file mode 100644 index 00000000..ce0c9c97 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/gams.json @@ -0,0 +1 @@ +{"aliases":["gms"],"case_insensitive":true,"keywords":{"keyword":"abort acronym acronyms alias all and assign binary card diag display else eq file files for free ge gt if integer le loop lt maximizing minimizing model models ne negative no not option options or ord positive prod put putpage puttl repeat sameas semicont semiint smax smin solve sos1 sos2 sum system table then until using while xor yes","literal":"eps inf na","built-in":"abs arccos arcsin arctan arctan2 Beta betaReg binomial ceil centropy cos cosh cvPower div div0 eDist entropy errorf execSeed exp fact floor frac gamma gammaReg log logBeta logGamma log10 log2 mapVal max min mod ncpCM ncpF ncpVUpow ncpVUsin normal pi poly power randBinomial randLinear randTriangle round rPower sigmoid sign signPower sin sinh slexp sllog10 slrec sqexp sqlog10 sqr sqrec sqrt tan tanh trunc uniform uniformInt vcPower bool_and bool_eqv bool_imp bool_not bool_or bool_xor ifThen rel_eq rel_ge rel_gt rel_le rel_lt rel_ne gday gdow ghour gleap gmillisec gminute gmonth gsecond gyear jdate jnow jstart jtime errorLevel execError gamsRelease gamsVersion handleCollect handleDelete handleStatus handleSubmit heapFree heapLimit heapSize jobHandle jobKill jobStatus jobTerminate licenseLevel licenseStatus maxExecError sleep timeClose timeComp timeElapsed timeExec timeStart"},"contains":[{"className":"comment","begin":"^\\$ontext","end":"^\\$offtext","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"meta","begin":"^\\$[a-z0-9]+","end":"$","returnBegin":true,"contains":[{"className":"meta-keyword","begin":"^\\$[a-z0-9]+"}]},{"className":"comment","begin":"^\\*","end":"$","contains":[{"$ref":"#contains.0.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"//","end":"$","contains":[{"$ref":"#contains.0.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"/\\*","end":"\\*/","contains":[{"$ref":"#contains.0.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0}]},{"className":"string","begin":"'","end":"'","illegal":"\\n","contains":[{"$ref":"#contains.5.contains.0"}]},{"beginKeywords":"set sets parameter parameters variable variables scalar scalars equation equations","end":";","contains":[{"className":"comment","begin":"^\\*","end":"$","contains":[{"$ref":"#contains.0.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"$ref":"#contains.3"},{"$ref":"#contains.4"},{"$ref":"#contains.5"},{"$ref":"#contains.6"},{"begin":"/","end":"/","keywords":{"$ref":"#keywords"},"contains":[{"className":"comment","variants":[{"begin":"'","end":"'"},{"begin":"\"","end":"\""}],"illegal":"\\n","contains":[{"$ref":"#contains.5.contains.0"}]},{"$ref":"#contains.3"},{"$ref":"#contains.4"},{"$ref":"#contains.5"},{"$ref":"#contains.6"},{"className":"number","begin":"(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)","relevance":0}]},{"begin":"[a-z][a-z0-9_]*(\\([a-z0-9_, ]*\\))?[ \\t]+","excludeBegin":true,"end":"$","endsWithParent":true,"contains":[{"$ref":"#contains.7.contains.5.contains.0"},{"$ref":"#contains.7.contains.5"},{"className":"comment","begin":"([ ]*[a-z0-9&#*=?@>\\\\<:\\-,()$\\[\\]_.{}!+%^]+)+","relevance":0}]}]},{"beginKeywords":"table","end":";","returnBegin":true,"contains":[{"beginKeywords":"table","end":"$","contains":[{"$ref":"#contains.7.contains.6"}]},{"className":"comment","begin":"^\\*","end":"$","contains":[{"$ref":"#contains.0.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"$ref":"#contains.3"},{"$ref":"#contains.4"},{"$ref":"#contains.5"},{"$ref":"#contains.6"},{"$ref":"#contains.7.contains.5.contains.5"}]},{"className":"function","begin":"^[a-z][a-z0-9_,\\-+' ()$]+\\.{2}","returnBegin":true,"contains":[{"className":"title","begin":"^[a-z0-9_]+"},{"className":"params","begin":"\\(","end":"\\)","excludeBegin":true,"excludeEnd":true},{"className":"symbol","variants":[{"begin":"\\=[lgenxc]="},{"begin":"\\$"}]}]},{"$ref":"#contains.7.contains.5.contains.5"},{"$ref":"#contains.9.contains.2"}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/gauss.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/gauss.json new file mode 100644 index 00000000..ee3151de --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/gauss.json @@ -0,0 +1 @@ +{"aliases":["gss"],"case_insensitive":true,"keywords":{"keyword":"bool break call callexe checkinterrupt clear clearg closeall cls comlog compile continue create debug declare delete disable dlibrary dllcall do dos ed edit else elseif enable end endfor endif endp endo errorlog errorlogat expr external fn for format goto gosub graph if keyword let lib library line load loadarray loadexe loadf loadk loadm loadp loads loadx local locate loopnextindex lprint lpwidth lshow matrix msym ndpclex new open output outwidth plot plotsym pop prcsn print printdos proc push retp return rndcon rndmod rndmult rndseed run save saveall screen scroll setarray show sparse stop string struct system trace trap threadfor threadendfor threadbegin threadjoin threadstat threadend until use while winprint ne ge le gt lt and xor or not eq eqv","built_in":"abs acf aconcat aeye amax amean AmericanBinomCall AmericanBinomCall_Greeks AmericanBinomCall_ImpVol AmericanBinomPut AmericanBinomPut_Greeks AmericanBinomPut_ImpVol AmericanBSCall AmericanBSCall_Greeks AmericanBSCall_ImpVol AmericanBSPut AmericanBSPut_Greeks AmericanBSPut_ImpVol amin amult annotationGetDefaults annotationSetBkd annotationSetFont annotationSetLineColor annotationSetLineStyle annotationSetLineThickness annualTradingDays arccos arcsin areshape arrayalloc arrayindex arrayinit arraytomat asciiload asclabel astd astds asum atan atan2 atranspose axmargin balance band bandchol bandcholsol bandltsol bandrv bandsolpd bar base10 begwind besselj bessely beta box boxcox cdfBeta cdfBetaInv cdfBinomial cdfBinomialInv cdfBvn cdfBvn2 cdfBvn2e cdfCauchy cdfCauchyInv cdfChic cdfChii cdfChinc cdfChincInv cdfExp cdfExpInv cdfFc cdfFnc cdfFncInv cdfGam cdfGenPareto cdfHyperGeo cdfLaplace cdfLaplaceInv cdfLogistic cdfLogisticInv cdfmControlCreate cdfMvn cdfMvn2e cdfMvnce cdfMvne cdfMvt2e cdfMvtce cdfMvte cdfN cdfN2 cdfNc cdfNegBinomial cdfNegBinomialInv cdfNi cdfPoisson cdfPoissonInv cdfRayleigh cdfRayleighInv cdfTc cdfTci cdfTnc cdfTvn cdfWeibull cdfWeibullInv cdir ceil ChangeDir chdir chiBarSquare chol choldn cholsol cholup chrs close code cols colsf combinate combinated complex con cond conj cons ConScore contour conv convertsatostr convertstrtosa corrm corrms corrvc corrx corrxs cos cosh counts countwts crossprd crout croutp csrcol csrlin csvReadM csvReadSA cumprodc cumsumc curve cvtos datacreate datacreatecomplex datalist dataload dataloop dataopen datasave date datestr datestring datestrymd dayinyr dayofweek dbAddDatabase dbClose dbCommit dbCreateQuery dbExecQuery dbGetConnectOptions dbGetDatabaseName dbGetDriverName dbGetDrivers dbGetHostName dbGetLastErrorNum dbGetLastErrorText dbGetNumericalPrecPolicy dbGetPassword dbGetPort dbGetTableHeaders dbGetTables dbGetUserName dbHasFeature dbIsDriverAvailable dbIsOpen dbIsOpenError dbOpen dbQueryBindValue dbQueryClear dbQueryCols dbQueryExecPrepared dbQueryFetchAllM dbQueryFetchAllSA dbQueryFetchOneM dbQueryFetchOneSA dbQueryFinish dbQueryGetBoundValue dbQueryGetBoundValues dbQueryGetField dbQueryGetLastErrorNum dbQueryGetLastErrorText dbQueryGetLastInsertID dbQueryGetLastQuery dbQueryGetPosition dbQueryIsActive dbQueryIsForwardOnly dbQueryIsNull dbQueryIsSelect dbQueryIsValid dbQueryPrepare dbQueryRows dbQuerySeek dbQuerySeekFirst dbQuerySeekLast dbQuerySeekNext dbQuerySeekPrevious dbQuerySetForwardOnly dbRemoveDatabase dbRollback dbSetConnectOptions dbSetDatabaseName dbSetHostName dbSetNumericalPrecPolicy dbSetPort dbSetUserName dbTransaction DeleteFile delif delrows denseToSp denseToSpRE denToZero design det detl dfft dffti diag diagrv digamma doswin DOSWinCloseall DOSWinOpen dotfeq dotfeqmt dotfge dotfgemt dotfgt dotfgtmt dotfle dotflemt dotflt dotfltmt dotfne dotfnemt draw drop dsCreate dstat dstatmt dstatmtControlCreate dtdate dtday dttime dttodtv dttostr dttoutc dtvnormal dtvtodt dtvtoutc dummy dummybr dummydn eig eigh eighv eigv elapsedTradingDays endwind envget eof eqSolve eqSolvemt eqSolvemtControlCreate eqSolvemtOutCreate eqSolveset erf erfc erfccplx erfcplx error etdays ethsec etstr EuropeanBinomCall EuropeanBinomCall_Greeks EuropeanBinomCall_ImpVol EuropeanBinomPut EuropeanBinomPut_Greeks EuropeanBinomPut_ImpVol EuropeanBSCall EuropeanBSCall_Greeks EuropeanBSCall_ImpVol EuropeanBSPut EuropeanBSPut_Greeks EuropeanBSPut_ImpVol exctsmpl exec execbg exp extern eye fcheckerr fclearerr feq feqmt fflush fft ffti fftm fftmi fftn fge fgemt fgets fgetsa fgetsat fgetst fgt fgtmt fileinfo filesa fle flemt floor flt fltmt fmod fne fnemt fonts fopen formatcv formatnv fputs fputst fseek fstrerror ftell ftocv ftos ftostrC gamma gammacplx gammaii gausset gdaAppend gdaCreate gdaDStat gdaDStatMat gdaGetIndex gdaGetName gdaGetNames gdaGetOrders gdaGetType gdaGetTypes gdaGetVarInfo gdaIsCplx gdaLoad gdaPack gdaRead gdaReadByIndex gdaReadSome gdaReadSparse gdaReadStruct gdaReportVarInfo gdaSave gdaUpdate gdaUpdateAndPack gdaVars gdaWrite gdaWrite32 gdaWriteSome getarray getdims getf getGAUSShome getmatrix getmatrix4D getname getnamef getNextTradingDay getNextWeekDay getnr getorders getpath getPreviousTradingDay getPreviousWeekDay getRow getscalar3D getscalar4D getTrRow getwind glm gradcplx gradMT gradMTm gradMTT gradMTTm gradp graphprt graphset hasimag header headermt hess hessMT hessMTg hessMTgw hessMTm hessMTmw hessMTT hessMTTg hessMTTgw hessMTTm hessMTw hessp hist histf histp hsec imag indcv indexcat indices indices2 indicesf indicesfn indnv indsav integrate1d integrateControlCreate intgrat2 intgrat3 inthp1 inthp2 inthp3 inthp4 inthpControlCreate intquad1 intquad2 intquad3 intrleav intrleavsa intrsect intsimp inv invpd invswp iscplx iscplxf isden isinfnanmiss ismiss key keyav keyw lag lag1 lagn lapEighb lapEighi lapEighvb lapEighvi lapgEig lapgEigh lapgEighv lapgEigv lapgSchur lapgSvdcst lapgSvds lapgSvdst lapSvdcusv lapSvds lapSvdusv ldlp ldlsol linSolve listwise ln lncdfbvn lncdfbvn2 lncdfmvn lncdfn lncdfn2 lncdfnc lnfact lngammacplx lnpdfmvn lnpdfmvt lnpdfn lnpdft loadd loadstruct loadwind loess loessmt loessmtControlCreate log loglog logx logy lower lowmat lowmat1 ltrisol lu lusol machEpsilon make makevars makewind margin matalloc matinit mattoarray maxbytes maxc maxindc maxv maxvec mbesselei mbesselei0 mbesselei1 mbesseli mbesseli0 mbesseli1 meanc median mergeby mergevar minc minindc minv miss missex missrv moment momentd movingave movingaveExpwgt movingaveWgt nextindex nextn nextnevn nextwind ntos null null1 numCombinations ols olsmt olsmtControlCreate olsqr olsqr2 olsqrmt ones optn optnevn orth outtyp pacf packedToSp packr parse pause pdfCauchy pdfChi pdfExp pdfGenPareto pdfHyperGeo pdfLaplace pdfLogistic pdfn pdfPoisson pdfRayleigh pdfWeibull pi pinv pinvmt plotAddArrow plotAddBar plotAddBox plotAddHist plotAddHistF plotAddHistP plotAddPolar plotAddScatter plotAddShape plotAddTextbox plotAddTS plotAddXY plotArea plotBar plotBox plotClearLayout plotContour plotCustomLayout plotGetDefaults plotHist plotHistF plotHistP plotLayout plotLogLog plotLogX plotLogY plotOpenWindow plotPolar plotSave plotScatter plotSetAxesPen plotSetBar plotSetBarFill plotSetBarStacked plotSetBkdColor plotSetFill plotSetGrid plotSetLegend plotSetLineColor plotSetLineStyle plotSetLineSymbol plotSetLineThickness plotSetNewWindow plotSetTitle plotSetWhichYAxis plotSetXAxisShow plotSetXLabel plotSetXRange plotSetXTicInterval plotSetXTicLabel plotSetYAxisShow plotSetYLabel plotSetYRange plotSetZAxisShow plotSetZLabel plotSurface plotTS plotXY polar polychar polyeval polygamma polyint polymake polymat polymroot polymult polyroot pqgwin previousindex princomp printfm printfmt prodc psi putarray putf putvals pvCreate pvGetIndex pvGetParNames pvGetParVector pvLength pvList pvPack pvPacki pvPackm pvPackmi pvPacks pvPacksi pvPacksm pvPacksmi pvPutParVector pvTest pvUnpack QNewton QNewtonmt QNewtonmtControlCreate QNewtonmtOutCreate QNewtonSet QProg QProgmt QProgmtInCreate qqr qqre qqrep qr qre qrep qrsol qrtsol qtyr qtyre qtyrep quantile quantiled qyr qyre qyrep qz rank rankindx readr real reclassify reclassifyCuts recode recserar recsercp recserrc rerun rescale reshape rets rev rfft rffti rfftip rfftn rfftnp rfftp rndBernoulli rndBeta rndBinomial rndCauchy rndChiSquare rndCon rndCreateState rndExp rndGamma rndGeo rndGumbel rndHyperGeo rndi rndKMbeta rndKMgam rndKMi rndKMn rndKMnb rndKMp rndKMu rndKMvm rndLaplace rndLCbeta rndLCgam rndLCi rndLCn rndLCnb rndLCp rndLCu rndLCvm rndLogNorm rndMTu rndMVn rndMVt rndn rndnb rndNegBinomial rndp rndPoisson rndRayleigh rndStateSkip rndu rndvm rndWeibull rndWishart rotater round rows rowsf rref sampleData satostrC saved saveStruct savewind scale scale3d scalerr scalinfnanmiss scalmiss schtoc schur searchsourcepath seekr select selif seqa seqm setdif setdifsa setvars setvwrmode setwind shell shiftr sin singleindex sinh sleep solpd sortc sortcc sortd sorthc sorthcc sortind sortindc sortmc sortr sortrc spBiconjGradSol spChol spConjGradSol spCreate spDenseSubmat spDiagRvMat spEigv spEye spLDL spline spLU spNumNZE spOnes spreadSheetReadM spreadSheetReadSA spreadSheetWrite spScale spSubmat spToDense spTrTDense spTScalar spZeros sqpSolve sqpSolveMT sqpSolveMTControlCreate sqpSolveMTlagrangeCreate sqpSolveMToutCreate sqpSolveSet sqrt statements stdc stdsc stocv stof strcombine strindx strlen strput strrindx strsect strsplit strsplitPad strtodt strtof strtofcplx strtriml strtrimr strtrunc strtruncl strtruncpad strtruncr submat subscat substute subvec sumc sumr surface svd svd1 svd2 svdcusv svds svdusv sysstate tab tan tanh tempname time timedt timestr timeutc title tkf2eps tkf2ps tocart todaydt toeplitz token topolar trapchk trigamma trimr trunc type typecv typef union unionsa uniqindx uniqindxsa unique uniquesa upmat upmat1 upper utctodt utctodtv utrisol vals varCovMS varCovXS varget vargetl varmall varmares varput varputl vartypef vcm vcms vcx vcxs vec vech vecr vector vget view viewxyz vlist vnamecv volume vput vread vtypecv wait waitc walkindex where window writer xlabel xlsGetSheetCount xlsGetSheetSize xlsGetSheetTypes xlsMakeRange xlsReadM xlsReadSA xlsWrite xlsWriteM xlsWriteSA xpnd xtics xy xyz ylabel ytics zeros zeta zlabel ztics cdfEmpirical dot h5create h5open h5read h5readAttribute h5write h5writeAttribute ldl plotAddErrorBar plotAddSurface plotCDFEmpirical plotSetColormap plotSetContourLabels plotSetLegendFont plotSetTextInterpreter plotSetXTicCount plotSetYTicCount plotSetZLevels powerm strjoin sylvester strtrim","literal":"DB_AFTER_LAST_ROW DB_ALL_TABLES DB_BATCH_OPERATIONS DB_BEFORE_FIRST_ROW DB_BLOB DB_EVENT_NOTIFICATIONS DB_FINISH_QUERY DB_HIGH_PRECISION DB_LAST_INSERT_ID DB_LOW_PRECISION_DOUBLE DB_LOW_PRECISION_INT32 DB_LOW_PRECISION_INT64 DB_LOW_PRECISION_NUMBERS DB_MULTIPLE_RESULT_SETS DB_NAMED_PLACEHOLDERS DB_POSITIONAL_PLACEHOLDERS DB_PREPARED_QUERIES DB_QUERY_SIZE DB_SIMPLE_LOCKING DB_SYSTEM_TABLES DB_TABLES DB_TRANSACTIONS DB_UNICODE DB_VIEWS __STDIN __STDOUT __STDERR __FILE_DIR"},"illegal":"(\\{[%#]|[%#]\\}| <- )","contains":[{"className":"number","begin":"(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)","relevance":0},{"className":"comment","begin":"//","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"/\\*","end":"\\*/","contains":[{"$ref":"#contains.1.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"@","end":"@","contains":[{"$ref":"#contains.1.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"string","begin":"\"","end":"\"","contains":[{"begin":"\\\\[\\s\\S]","relevance":0}],"relevance":0},{"className":"meta","begin":"#","end":"$","keywords":{"meta-keyword":"define definecs|10 undef ifdef ifndef iflight ifdllcall ifmac ifos2win ifunix else endif lineson linesoff srcfile srcline"},"contains":[{"begin":"\\\\\\n","relevance":0},{"beginKeywords":"include","end":"$","keywords":{"meta-keyword":"include"},"contains":[{"className":"meta-string","begin":"\"","end":"\"","illegal":"\\n"}]},{"$ref":"#contains.1"},{"$ref":"#contains.2"},{"$ref":"#contains.3"}]},{"className":"keyword","begin":"\\bexternal (matrix|string|array|sparse matrix|struct|proc|keyword|fn)"},{"className":"function","beginKeywords":"proc keyword","end":";","excludeEnd":true,"contains":[{"className":"params","begin":"\\(","end":"\\)","excludeBegin":true,"excludeEnd":true,"endsWithParent":true,"relevance":0,"contains":[{"className":"literal","begin":"\\.\\.\\."},{"$ref":"#contains.0"},{"$ref":"#contains.2"},{"$ref":"#contains.3"},{"begin":"\\bstruct\\s+","end":"\\s","keywords":"struct","contains":[{"className":"type","begin":"[a-zA-Z_]\\w*","relevance":0}]}]},{"className":"title","begin":"[a-zA-Z_]\\w*","relevance":0},{"$ref":"#contains.0"},{"$ref":"#contains.2"},{"$ref":"#contains.3"}]},{"className":"function","beginKeywords":"fn","end":"=","excludeEnd":true,"contains":[{"$ref":"#contains.7.contains.0"},{"$ref":"#contains.7.contains.1"},{"$ref":"#contains.0"},{"$ref":"#contains.2"},{"$ref":"#contains.3"}]},{"beginKeywords":"for threadfor","end":";","relevance":0,"contains":[{"$ref":"#contains.2"},{"$ref":"#contains.3"},{"begin":"\\(","end":"\\)","relevance":0,"keywords":{"built_in":"abs acf aconcat aeye amax amean AmericanBinomCall AmericanBinomCall_Greeks AmericanBinomCall_ImpVol AmericanBinomPut AmericanBinomPut_Greeks AmericanBinomPut_ImpVol AmericanBSCall AmericanBSCall_Greeks AmericanBSCall_ImpVol AmericanBSPut AmericanBSPut_Greeks AmericanBSPut_ImpVol amin amult annotationGetDefaults annotationSetBkd annotationSetFont annotationSetLineColor annotationSetLineStyle annotationSetLineThickness annualTradingDays arccos arcsin areshape arrayalloc arrayindex arrayinit arraytomat asciiload asclabel astd astds asum atan atan2 atranspose axmargin balance band bandchol bandcholsol bandltsol bandrv bandsolpd bar base10 begwind besselj bessely beta box boxcox cdfBeta cdfBetaInv cdfBinomial cdfBinomialInv cdfBvn cdfBvn2 cdfBvn2e cdfCauchy cdfCauchyInv cdfChic cdfChii cdfChinc cdfChincInv cdfExp cdfExpInv cdfFc cdfFnc cdfFncInv cdfGam cdfGenPareto cdfHyperGeo cdfLaplace cdfLaplaceInv cdfLogistic cdfLogisticInv cdfmControlCreate cdfMvn cdfMvn2e cdfMvnce cdfMvne cdfMvt2e cdfMvtce cdfMvte cdfN cdfN2 cdfNc cdfNegBinomial cdfNegBinomialInv cdfNi cdfPoisson cdfPoissonInv cdfRayleigh cdfRayleighInv cdfTc cdfTci cdfTnc cdfTvn cdfWeibull cdfWeibullInv cdir ceil ChangeDir chdir chiBarSquare chol choldn cholsol cholup chrs close code cols colsf combinate combinated complex con cond conj cons ConScore contour conv convertsatostr convertstrtosa corrm corrms corrvc corrx corrxs cos cosh counts countwts crossprd crout croutp csrcol csrlin csvReadM csvReadSA cumprodc cumsumc curve cvtos datacreate datacreatecomplex datalist dataload dataloop dataopen datasave date datestr datestring datestrymd dayinyr dayofweek dbAddDatabase dbClose dbCommit dbCreateQuery dbExecQuery dbGetConnectOptions dbGetDatabaseName dbGetDriverName dbGetDrivers dbGetHostName dbGetLastErrorNum dbGetLastErrorText dbGetNumericalPrecPolicy dbGetPassword dbGetPort dbGetTableHeaders dbGetTables dbGetUserName dbHasFeature dbIsDriverAvailable dbIsOpen dbIsOpenError dbOpen dbQueryBindValue dbQueryClear dbQueryCols dbQueryExecPrepared dbQueryFetchAllM dbQueryFetchAllSA dbQueryFetchOneM dbQueryFetchOneSA dbQueryFinish dbQueryGetBoundValue dbQueryGetBoundValues dbQueryGetField dbQueryGetLastErrorNum dbQueryGetLastErrorText dbQueryGetLastInsertID dbQueryGetLastQuery dbQueryGetPosition dbQueryIsActive dbQueryIsForwardOnly dbQueryIsNull dbQueryIsSelect dbQueryIsValid dbQueryPrepare dbQueryRows dbQuerySeek dbQuerySeekFirst dbQuerySeekLast dbQuerySeekNext dbQuerySeekPrevious dbQuerySetForwardOnly dbRemoveDatabase dbRollback dbSetConnectOptions dbSetDatabaseName dbSetHostName dbSetNumericalPrecPolicy dbSetPort dbSetUserName dbTransaction DeleteFile delif delrows denseToSp denseToSpRE denToZero design det detl dfft dffti diag diagrv digamma doswin DOSWinCloseall DOSWinOpen dotfeq dotfeqmt dotfge dotfgemt dotfgt dotfgtmt dotfle dotflemt dotflt dotfltmt dotfne dotfnemt draw drop dsCreate dstat dstatmt dstatmtControlCreate dtdate dtday dttime dttodtv dttostr dttoutc dtvnormal dtvtodt dtvtoutc dummy dummybr dummydn eig eigh eighv eigv elapsedTradingDays endwind envget eof eqSolve eqSolvemt eqSolvemtControlCreate eqSolvemtOutCreate eqSolveset erf erfc erfccplx erfcplx error etdays ethsec etstr EuropeanBinomCall EuropeanBinomCall_Greeks EuropeanBinomCall_ImpVol EuropeanBinomPut EuropeanBinomPut_Greeks EuropeanBinomPut_ImpVol EuropeanBSCall EuropeanBSCall_Greeks EuropeanBSCall_ImpVol EuropeanBSPut EuropeanBSPut_Greeks EuropeanBSPut_ImpVol exctsmpl exec execbg exp extern eye fcheckerr fclearerr feq feqmt fflush fft ffti fftm fftmi fftn fge fgemt fgets fgetsa fgetsat fgetst fgt fgtmt fileinfo filesa fle flemt floor flt fltmt fmod fne fnemt fonts fopen formatcv formatnv fputs fputst fseek fstrerror ftell ftocv ftos ftostrC gamma gammacplx gammaii gausset gdaAppend gdaCreate gdaDStat gdaDStatMat gdaGetIndex gdaGetName gdaGetNames gdaGetOrders gdaGetType gdaGetTypes gdaGetVarInfo gdaIsCplx gdaLoad gdaPack gdaRead gdaReadByIndex gdaReadSome gdaReadSparse gdaReadStruct gdaReportVarInfo gdaSave gdaUpdate gdaUpdateAndPack gdaVars gdaWrite gdaWrite32 gdaWriteSome getarray getdims getf getGAUSShome getmatrix getmatrix4D getname getnamef getNextTradingDay getNextWeekDay getnr getorders getpath getPreviousTradingDay getPreviousWeekDay getRow getscalar3D getscalar4D getTrRow getwind glm gradcplx gradMT gradMTm gradMTT gradMTTm gradp graphprt graphset hasimag header headermt hess hessMT hessMTg hessMTgw hessMTm hessMTmw hessMTT hessMTTg hessMTTgw hessMTTm hessMTw hessp hist histf histp hsec imag indcv indexcat indices indices2 indicesf indicesfn indnv indsav integrate1d integrateControlCreate intgrat2 intgrat3 inthp1 inthp2 inthp3 inthp4 inthpControlCreate intquad1 intquad2 intquad3 intrleav intrleavsa intrsect intsimp inv invpd invswp iscplx iscplxf isden isinfnanmiss ismiss key keyav keyw lag lag1 lagn lapEighb lapEighi lapEighvb lapEighvi lapgEig lapgEigh lapgEighv lapgEigv lapgSchur lapgSvdcst lapgSvds lapgSvdst lapSvdcusv lapSvds lapSvdusv ldlp ldlsol linSolve listwise ln lncdfbvn lncdfbvn2 lncdfmvn lncdfn lncdfn2 lncdfnc lnfact lngammacplx lnpdfmvn lnpdfmvt lnpdfn lnpdft loadd loadstruct loadwind loess loessmt loessmtControlCreate log loglog logx logy lower lowmat lowmat1 ltrisol lu lusol machEpsilon make makevars makewind margin matalloc matinit mattoarray maxbytes maxc maxindc maxv maxvec mbesselei mbesselei0 mbesselei1 mbesseli mbesseli0 mbesseli1 meanc median mergeby mergevar minc minindc minv miss missex missrv moment momentd movingave movingaveExpwgt movingaveWgt nextindex nextn nextnevn nextwind ntos null null1 numCombinations ols olsmt olsmtControlCreate olsqr olsqr2 olsqrmt ones optn optnevn orth outtyp pacf packedToSp packr parse pause pdfCauchy pdfChi pdfExp pdfGenPareto pdfHyperGeo pdfLaplace pdfLogistic pdfn pdfPoisson pdfRayleigh pdfWeibull pi pinv pinvmt plotAddArrow plotAddBar plotAddBox plotAddHist plotAddHistF plotAddHistP plotAddPolar plotAddScatter plotAddShape plotAddTextbox plotAddTS plotAddXY plotArea plotBar plotBox plotClearLayout plotContour plotCustomLayout plotGetDefaults plotHist plotHistF plotHistP plotLayout plotLogLog plotLogX plotLogY plotOpenWindow plotPolar plotSave plotScatter plotSetAxesPen plotSetBar plotSetBarFill plotSetBarStacked plotSetBkdColor plotSetFill plotSetGrid plotSetLegend plotSetLineColor plotSetLineStyle plotSetLineSymbol plotSetLineThickness plotSetNewWindow plotSetTitle plotSetWhichYAxis plotSetXAxisShow plotSetXLabel plotSetXRange plotSetXTicInterval plotSetXTicLabel plotSetYAxisShow plotSetYLabel plotSetYRange plotSetZAxisShow plotSetZLabel plotSurface plotTS plotXY polar polychar polyeval polygamma polyint polymake polymat polymroot polymult polyroot pqgwin previousindex princomp printfm printfmt prodc psi putarray putf putvals pvCreate pvGetIndex pvGetParNames pvGetParVector pvLength pvList pvPack pvPacki pvPackm pvPackmi pvPacks pvPacksi pvPacksm pvPacksmi pvPutParVector pvTest pvUnpack QNewton QNewtonmt QNewtonmtControlCreate QNewtonmtOutCreate QNewtonSet QProg QProgmt QProgmtInCreate qqr qqre qqrep qr qre qrep qrsol qrtsol qtyr qtyre qtyrep quantile quantiled qyr qyre qyrep qz rank rankindx readr real reclassify reclassifyCuts recode recserar recsercp recserrc rerun rescale reshape rets rev rfft rffti rfftip rfftn rfftnp rfftp rndBernoulli rndBeta rndBinomial rndCauchy rndChiSquare rndCon rndCreateState rndExp rndGamma rndGeo rndGumbel rndHyperGeo rndi rndKMbeta rndKMgam rndKMi rndKMn rndKMnb rndKMp rndKMu rndKMvm rndLaplace rndLCbeta rndLCgam rndLCi rndLCn rndLCnb rndLCp rndLCu rndLCvm rndLogNorm rndMTu rndMVn rndMVt rndn rndnb rndNegBinomial rndp rndPoisson rndRayleigh rndStateSkip rndu rndvm rndWeibull rndWishart rotater round rows rowsf rref sampleData satostrC saved saveStruct savewind scale scale3d scalerr scalinfnanmiss scalmiss schtoc schur searchsourcepath seekr select selif seqa seqm setdif setdifsa setvars setvwrmode setwind shell shiftr sin singleindex sinh sleep solpd sortc sortcc sortd sorthc sorthcc sortind sortindc sortmc sortr sortrc spBiconjGradSol spChol spConjGradSol spCreate spDenseSubmat spDiagRvMat spEigv spEye spLDL spline spLU spNumNZE spOnes spreadSheetReadM spreadSheetReadSA spreadSheetWrite spScale spSubmat spToDense spTrTDense spTScalar spZeros sqpSolve sqpSolveMT sqpSolveMTControlCreate sqpSolveMTlagrangeCreate sqpSolveMToutCreate sqpSolveSet sqrt statements stdc stdsc stocv stof strcombine strindx strlen strput strrindx strsect strsplit strsplitPad strtodt strtof strtofcplx strtriml strtrimr strtrunc strtruncl strtruncpad strtruncr submat subscat substute subvec sumc sumr surface svd svd1 svd2 svdcusv svds svdusv sysstate tab tan tanh tempname time timedt timestr timeutc title tkf2eps tkf2ps tocart todaydt toeplitz token topolar trapchk trigamma trimr trunc type typecv typef union unionsa uniqindx uniqindxsa unique uniquesa upmat upmat1 upper utctodt utctodtv utrisol vals varCovMS varCovXS varget vargetl varmall varmares varput varputl vartypef vcm vcms vcx vcxs vec vech vecr vector vget view viewxyz vlist vnamecv volume vput vread vtypecv wait waitc walkindex where window writer xlabel xlsGetSheetCount xlsGetSheetSize xlsGetSheetTypes xlsMakeRange xlsReadM xlsReadSA xlsWrite xlsWriteM xlsWriteSA xpnd xtics xy xyz ylabel ytics zeros zeta zlabel ztics cdfEmpirical dot h5create h5open h5read h5readAttribute h5write h5writeAttribute ldl plotAddErrorBar plotAddSurface plotCDFEmpirical plotSetColormap plotSetContourLabels plotSetLegendFont plotSetTextInterpreter plotSetXTicCount plotSetYTicCount plotSetZLevels powerm strjoin sylvester strtrim","literal":"DB_AFTER_LAST_ROW DB_ALL_TABLES DB_BATCH_OPERATIONS DB_BEFORE_FIRST_ROW DB_BLOB DB_EVENT_NOTIFICATIONS DB_FINISH_QUERY DB_HIGH_PRECISION DB_LAST_INSERT_ID DB_LOW_PRECISION_DOUBLE DB_LOW_PRECISION_INT32 DB_LOW_PRECISION_INT64 DB_LOW_PRECISION_NUMBERS DB_MULTIPLE_RESULT_SETS DB_NAMED_PLACEHOLDERS DB_POSITIONAL_PLACEHOLDERS DB_PREPARED_QUERIES DB_QUERY_SIZE DB_SIMPLE_LOCKING DB_SYSTEM_TABLES DB_TABLES DB_TRANSACTIONS DB_UNICODE DB_VIEWS __STDIN __STDOUT __STDERR __FILE_DIR"},"contains":[{"$ref":"#contains.0"},{"$ref":"#contains.2"},{"$ref":"#contains.3"},{"className":"built_in","begin":"\\b(abs|acf|aconcat|aeye|amax|amean|AmericanBinomCall|AmericanBinomCall_Greeks|AmericanBinomCall_ImpVol|AmericanBinomPut|AmericanBinomPut_Greeks|AmericanBinomPut_ImpVol|AmericanBSCall|AmericanBSCall_Greeks|AmericanBSCall_ImpVol|AmericanBSPut|AmericanBSPut_Greeks|AmericanBSPut_ImpVol|amin|amult|annotationGetDefaults|annotationSetBkd|annotationSetFont|annotationSetLineColor|annotationSetLineStyle|annotationSetLineThickness|annualTradingDays|arccos|arcsin|areshape|arrayalloc|arrayindex|arrayinit|arraytomat|asciiload|asclabel|astd|astds|asum|atan|atan2|atranspose|axmargin|balance|band|bandchol|bandcholsol|bandltsol|bandrv|bandsolpd|bar|base10|begwind|besselj|bessely|beta|box|boxcox|cdfBeta|cdfBetaInv|cdfBinomial|cdfBinomialInv|cdfBvn|cdfBvn2|cdfBvn2e|cdfCauchy|cdfCauchyInv|cdfChic|cdfChii|cdfChinc|cdfChincInv|cdfExp|cdfExpInv|cdfFc|cdfFnc|cdfFncInv|cdfGam|cdfGenPareto|cdfHyperGeo|cdfLaplace|cdfLaplaceInv|cdfLogistic|cdfLogisticInv|cdfmControlCreate|cdfMvn|cdfMvn2e|cdfMvnce|cdfMvne|cdfMvt2e|cdfMvtce|cdfMvte|cdfN|cdfN2|cdfNc|cdfNegBinomial|cdfNegBinomialInv|cdfNi|cdfPoisson|cdfPoissonInv|cdfRayleigh|cdfRayleighInv|cdfTc|cdfTci|cdfTnc|cdfTvn|cdfWeibull|cdfWeibullInv|cdir|ceil|ChangeDir|chdir|chiBarSquare|chol|choldn|cholsol|cholup|chrs|close|code|cols|colsf|combinate|combinated|complex|con|cond|conj|cons|ConScore|contour|conv|convertsatostr|convertstrtosa|corrm|corrms|corrvc|corrx|corrxs|cos|cosh|counts|countwts|crossprd|crout|croutp|csrcol|csrlin|csvReadM|csvReadSA|cumprodc|cumsumc|curve|cvtos|datacreate|datacreatecomplex|datalist|dataload|dataloop|dataopen|datasave|date|datestr|datestring|datestrymd|dayinyr|dayofweek|dbAddDatabase|dbClose|dbCommit|dbCreateQuery|dbExecQuery|dbGetConnectOptions|dbGetDatabaseName|dbGetDriverName|dbGetDrivers|dbGetHostName|dbGetLastErrorNum|dbGetLastErrorText|dbGetNumericalPrecPolicy|dbGetPassword|dbGetPort|dbGetTableHeaders|dbGetTables|dbGetUserName|dbHasFeature|dbIsDriverAvailable|dbIsOpen|dbIsOpenError|dbOpen|dbQueryBindValue|dbQueryClear|dbQueryCols|dbQueryExecPrepared|dbQueryFetchAllM|dbQueryFetchAllSA|dbQueryFetchOneM|dbQueryFetchOneSA|dbQueryFinish|dbQueryGetBoundValue|dbQueryGetBoundValues|dbQueryGetField|dbQueryGetLastErrorNum|dbQueryGetLastErrorText|dbQueryGetLastInsertID|dbQueryGetLastQuery|dbQueryGetPosition|dbQueryIsActive|dbQueryIsForwardOnly|dbQueryIsNull|dbQueryIsSelect|dbQueryIsValid|dbQueryPrepare|dbQueryRows|dbQuerySeek|dbQuerySeekFirst|dbQuerySeekLast|dbQuerySeekNext|dbQuerySeekPrevious|dbQuerySetForwardOnly|dbRemoveDatabase|dbRollback|dbSetConnectOptions|dbSetDatabaseName|dbSetHostName|dbSetNumericalPrecPolicy|dbSetPort|dbSetUserName|dbTransaction|DeleteFile|delif|delrows|denseToSp|denseToSpRE|denToZero|design|det|detl|dfft|dffti|diag|diagrv|digamma|doswin|DOSWinCloseall|DOSWinOpen|dotfeq|dotfeqmt|dotfge|dotfgemt|dotfgt|dotfgtmt|dotfle|dotflemt|dotflt|dotfltmt|dotfne|dotfnemt|draw|drop|dsCreate|dstat|dstatmt|dstatmtControlCreate|dtdate|dtday|dttime|dttodtv|dttostr|dttoutc|dtvnormal|dtvtodt|dtvtoutc|dummy|dummybr|dummydn|eig|eigh|eighv|eigv|elapsedTradingDays|endwind|envget|eof|eqSolve|eqSolvemt|eqSolvemtControlCreate|eqSolvemtOutCreate|eqSolveset|erf|erfc|erfccplx|erfcplx|error|etdays|ethsec|etstr|EuropeanBinomCall|EuropeanBinomCall_Greeks|EuropeanBinomCall_ImpVol|EuropeanBinomPut|EuropeanBinomPut_Greeks|EuropeanBinomPut_ImpVol|EuropeanBSCall|EuropeanBSCall_Greeks|EuropeanBSCall_ImpVol|EuropeanBSPut|EuropeanBSPut_Greeks|EuropeanBSPut_ImpVol|exctsmpl|exec|execbg|exp|extern|eye|fcheckerr|fclearerr|feq|feqmt|fflush|fft|ffti|fftm|fftmi|fftn|fge|fgemt|fgets|fgetsa|fgetsat|fgetst|fgt|fgtmt|fileinfo|filesa|fle|flemt|floor|flt|fltmt|fmod|fne|fnemt|fonts|fopen|formatcv|formatnv|fputs|fputst|fseek|fstrerror|ftell|ftocv|ftos|ftostrC|gamma|gammacplx|gammaii|gausset|gdaAppend|gdaCreate|gdaDStat|gdaDStatMat|gdaGetIndex|gdaGetName|gdaGetNames|gdaGetOrders|gdaGetType|gdaGetTypes|gdaGetVarInfo|gdaIsCplx|gdaLoad|gdaPack|gdaRead|gdaReadByIndex|gdaReadSome|gdaReadSparse|gdaReadStruct|gdaReportVarInfo|gdaSave|gdaUpdate|gdaUpdateAndPack|gdaVars|gdaWrite|gdaWrite32|gdaWriteSome|getarray|getdims|getf|getGAUSShome|getmatrix|getmatrix4D|getname|getnamef|getNextTradingDay|getNextWeekDay|getnr|getorders|getpath|getPreviousTradingDay|getPreviousWeekDay|getRow|getscalar3D|getscalar4D|getTrRow|getwind|glm|gradcplx|gradMT|gradMTm|gradMTT|gradMTTm|gradp|graphprt|graphset|hasimag|header|headermt|hess|hessMT|hessMTg|hessMTgw|hessMTm|hessMTmw|hessMTT|hessMTTg|hessMTTgw|hessMTTm|hessMTw|hessp|hist|histf|histp|hsec|imag|indcv|indexcat|indices|indices2|indicesf|indicesfn|indnv|indsav|integrate1d|integrateControlCreate|intgrat2|intgrat3|inthp1|inthp2|inthp3|inthp4|inthpControlCreate|intquad1|intquad2|intquad3|intrleav|intrleavsa|intrsect|intsimp|inv|invpd|invswp|iscplx|iscplxf|isden|isinfnanmiss|ismiss|key|keyav|keyw|lag|lag1|lagn|lapEighb|lapEighi|lapEighvb|lapEighvi|lapgEig|lapgEigh|lapgEighv|lapgEigv|lapgSchur|lapgSvdcst|lapgSvds|lapgSvdst|lapSvdcusv|lapSvds|lapSvdusv|ldlp|ldlsol|linSolve|listwise|ln|lncdfbvn|lncdfbvn2|lncdfmvn|lncdfn|lncdfn2|lncdfnc|lnfact|lngammacplx|lnpdfmvn|lnpdfmvt|lnpdfn|lnpdft|loadd|loadstruct|loadwind|loess|loessmt|loessmtControlCreate|log|loglog|logx|logy|lower|lowmat|lowmat1|ltrisol|lu|lusol|machEpsilon|make|makevars|makewind|margin|matalloc|matinit|mattoarray|maxbytes|maxc|maxindc|maxv|maxvec|mbesselei|mbesselei0|mbesselei1|mbesseli|mbesseli0|mbesseli1|meanc|median|mergeby|mergevar|minc|minindc|minv|miss|missex|missrv|moment|momentd|movingave|movingaveExpwgt|movingaveWgt|nextindex|nextn|nextnevn|nextwind|ntos|null|null1|numCombinations|ols|olsmt|olsmtControlCreate|olsqr|olsqr2|olsqrmt|ones|optn|optnevn|orth|outtyp|pacf|packedToSp|packr|parse|pause|pdfCauchy|pdfChi|pdfExp|pdfGenPareto|pdfHyperGeo|pdfLaplace|pdfLogistic|pdfn|pdfPoisson|pdfRayleigh|pdfWeibull|pi|pinv|pinvmt|plotAddArrow|plotAddBar|plotAddBox|plotAddHist|plotAddHistF|plotAddHistP|plotAddPolar|plotAddScatter|plotAddShape|plotAddTextbox|plotAddTS|plotAddXY|plotArea|plotBar|plotBox|plotClearLayout|plotContour|plotCustomLayout|plotGetDefaults|plotHist|plotHistF|plotHistP|plotLayout|plotLogLog|plotLogX|plotLogY|plotOpenWindow|plotPolar|plotSave|plotScatter|plotSetAxesPen|plotSetBar|plotSetBarFill|plotSetBarStacked|plotSetBkdColor|plotSetFill|plotSetGrid|plotSetLegend|plotSetLineColor|plotSetLineStyle|plotSetLineSymbol|plotSetLineThickness|plotSetNewWindow|plotSetTitle|plotSetWhichYAxis|plotSetXAxisShow|plotSetXLabel|plotSetXRange|plotSetXTicInterval|plotSetXTicLabel|plotSetYAxisShow|plotSetYLabel|plotSetYRange|plotSetZAxisShow|plotSetZLabel|plotSurface|plotTS|plotXY|polar|polychar|polyeval|polygamma|polyint|polymake|polymat|polymroot|polymult|polyroot|pqgwin|previousindex|princomp|printfm|printfmt|prodc|psi|putarray|putf|putvals|pvCreate|pvGetIndex|pvGetParNames|pvGetParVector|pvLength|pvList|pvPack|pvPacki|pvPackm|pvPackmi|pvPacks|pvPacksi|pvPacksm|pvPacksmi|pvPutParVector|pvTest|pvUnpack|QNewton|QNewtonmt|QNewtonmtControlCreate|QNewtonmtOutCreate|QNewtonSet|QProg|QProgmt|QProgmtInCreate|qqr|qqre|qqrep|qr|qre|qrep|qrsol|qrtsol|qtyr|qtyre|qtyrep|quantile|quantiled|qyr|qyre|qyrep|qz|rank|rankindx|readr|real|reclassify|reclassifyCuts|recode|recserar|recsercp|recserrc|rerun|rescale|reshape|rets|rev|rfft|rffti|rfftip|rfftn|rfftnp|rfftp|rndBernoulli|rndBeta|rndBinomial|rndCauchy|rndChiSquare|rndCon|rndCreateState|rndExp|rndGamma|rndGeo|rndGumbel|rndHyperGeo|rndi|rndKMbeta|rndKMgam|rndKMi|rndKMn|rndKMnb|rndKMp|rndKMu|rndKMvm|rndLaplace|rndLCbeta|rndLCgam|rndLCi|rndLCn|rndLCnb|rndLCp|rndLCu|rndLCvm|rndLogNorm|rndMTu|rndMVn|rndMVt|rndn|rndnb|rndNegBinomial|rndp|rndPoisson|rndRayleigh|rndStateSkip|rndu|rndvm|rndWeibull|rndWishart|rotater|round|rows|rowsf|rref|sampleData|satostrC|saved|saveStruct|savewind|scale|scale3d|scalerr|scalinfnanmiss|scalmiss|schtoc|schur|searchsourcepath|seekr|select|selif|seqa|seqm|setdif|setdifsa|setvars|setvwrmode|setwind|shell|shiftr|sin|singleindex|sinh|sleep|solpd|sortc|sortcc|sortd|sorthc|sorthcc|sortind|sortindc|sortmc|sortr|sortrc|spBiconjGradSol|spChol|spConjGradSol|spCreate|spDenseSubmat|spDiagRvMat|spEigv|spEye|spLDL|spline|spLU|spNumNZE|spOnes|spreadSheetReadM|spreadSheetReadSA|spreadSheetWrite|spScale|spSubmat|spToDense|spTrTDense|spTScalar|spZeros|sqpSolve|sqpSolveMT|sqpSolveMTControlCreate|sqpSolveMTlagrangeCreate|sqpSolveMToutCreate|sqpSolveSet|sqrt|statements|stdc|stdsc|stocv|stof|strcombine|strindx|strlen|strput|strrindx|strsect|strsplit|strsplitPad|strtodt|strtof|strtofcplx|strtriml|strtrimr|strtrunc|strtruncl|strtruncpad|strtruncr|submat|subscat|substute|subvec|sumc|sumr|surface|svd|svd1|svd2|svdcusv|svds|svdusv|sysstate|tab|tan|tanh|tempname|time|timedt|timestr|timeutc|title|tkf2eps|tkf2ps|tocart|todaydt|toeplitz|token|topolar|trapchk|trigamma|trimr|trunc|type|typecv|typef|union|unionsa|uniqindx|uniqindxsa|unique|uniquesa|upmat|upmat1|upper|utctodt|utctodtv|utrisol|vals|varCovMS|varCovXS|varget|vargetl|varmall|varmares|varput|varputl|vartypef|vcm|vcms|vcx|vcxs|vec|vech|vecr|vector|vget|view|viewxyz|vlist|vnamecv|volume|vput|vread|vtypecv|wait|waitc|walkindex|where|window|writer|xlabel|xlsGetSheetCount|xlsGetSheetSize|xlsGetSheetTypes|xlsMakeRange|xlsReadM|xlsReadSA|xlsWrite|xlsWriteM|xlsWriteSA|xpnd|xtics|xy|xyz|ylabel|ytics|zeros|zeta|zlabel|ztics|cdfEmpirical|dot|h5create|h5open|h5read|h5readAttribute|h5write|h5writeAttribute|ldl|plotAddErrorBar|plotAddSurface|plotCDFEmpirical|plotSetColormap|plotSetContourLabels|plotSetLegendFont|plotSetTextInterpreter|plotSetXTicCount|plotSetYTicCount|plotSetZLevels|powerm|strjoin|sylvester|strtrim)\\b"},{"begin":"[a-zA-Z_]\\w*\\s*\\(","returnBegin":true,"keywords":{"$ref":"#keywords"},"relevance":0,"contains":[{"beginKeywords":"bool break call callexe checkinterrupt clear clearg closeall cls comlog compile continue create debug declare delete disable dlibrary dllcall do dos ed edit else elseif enable end endfor endif endp endo errorlog errorlogat expr external fn for format goto gosub graph if keyword let lib library line load loadarray loadexe loadf loadk loadm loadp loads loadx local locate loopnextindex lprint lpwidth lshow matrix msym ndpclex new open output outwidth plot plotsym pop prcsn print printdos proc push retp return rndcon rndmod rndmult rndseed run save saveall screen scroll setarray show sparse stop string struct system trace trap threadfor threadendfor threadbegin threadjoin threadstat threadend until use while winprint ne ge le gt lt and xor or not eq eqv"},{"$ref":"#contains.9.contains.2.contains.3"},{"className":"built_in","begin":"[a-zA-Z_]\\w*","relevance":0},{"$ref":"#contains.9.contains.2"}]},{"$ref":"#contains.4"},"self"]}]},{"variants":[{"begin":"[a-zA-Z_]\\w*\\.[a-zA-Z_]\\w*"},{"begin":"[a-zA-Z_]\\w*\\s*="}],"relevance":0},{"$ref":"#contains.9.contains.2.contains.4"},{"$ref":"#contains.7.contains.0.contains.4"}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/gcode.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/gcode.json new file mode 100644 index 00000000..ff17f3c5 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/gcode.json @@ -0,0 +1 @@ +{"aliases":["nc"],"case_insensitive":true,"lexemes":"[A-Z_][A-Z0-9_.]*","keywords":"IF DO WHILE ENDWHILE CALL ENDIF SUB ENDSUB GOTO REPEAT ENDREPEAT EQ LT GT NE GE LE OR XOR","contains":[{"className":"meta","begin":"\\%"},{"className":"meta","begin":"([O])([0-9]+)"},{"className":"comment","begin":"//","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"/\\*","end":"\\*/","contains":[{"$ref":"#contains.2.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"\\(","end":"\\)","contains":[{"$ref":"#contains.2.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"number","begin":"([-+]?([0-9]*\\.?[0-9]+\\.?))|(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)","relevance":0},{"className":"string","begin":"'","end":"'","illegal":null,"contains":[{"begin":"\\\\[\\s\\S]","relevance":0}]},{"className":"string","begin":"\"","end":"\"","illegal":null,"contains":[{"$ref":"#contains.6.contains.0"}]},{"className":"name","begin":"([G])([0-9]+\\.?[0-9]?)"},{"className":"name","begin":"([M])([0-9]+\\.?[0-9]?)"},{"className":"attr","begin":"(VC|VS|#)","end":"(\\d+)"},{"className":"attr","begin":"(VZOFX|VZOFY|VZOFZ)"},{"className":"built_in","begin":"(ATAN|ABS|ACOS|ASIN|SIN|COS|EXP|FIX|FUP|ROUND|LN|TAN)(\\[)","end":"([-+]?([0-9]*\\.?[0-9]+\\.?))(\\])"},{"className":"symbol","variants":[{"begin":"N","end":"\\d+","illegal":"\\W"}]}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/gherkin.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/gherkin.json new file mode 100644 index 00000000..3b15148f --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/gherkin.json @@ -0,0 +1 @@ +{"aliases":["feature"],"keywords":"Feature Background Ability Business Need Scenario Scenarios Scenario Outline Scenario Template Examples Given And Then But When","contains":[{"className":"symbol","begin":"\\*","relevance":0},{"className":"meta","begin":"@[^@\\s]+"},{"begin":"\\|","end":"\\|\\w*$","contains":[{"className":"string","begin":"[^|]+"}]},{"className":"variable","begin":"<","end":">"},{"className":"comment","begin":"#","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"string","begin":"\"\"\"","end":"\"\"\""},{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0}]}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/glsl.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/glsl.json new file mode 100644 index 00000000..67e7c32d --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/glsl.json @@ -0,0 +1 @@ +{"keywords":{"keyword":"break continue discard do else for if return while switch case default attribute binding buffer ccw centroid centroid varying coherent column_major const cw depth_any depth_greater depth_less depth_unchanged early_fragment_tests equal_spacing flat fractional_even_spacing fractional_odd_spacing highp in index inout invariant invocations isolines layout line_strip lines lines_adjacency local_size_x local_size_y local_size_z location lowp max_vertices mediump noperspective offset origin_upper_left out packed patch pixel_center_integer point_mode points precise precision quads r11f_g11f_b10f r16 r16_snorm r16f r16i r16ui r32f r32i r32ui r8 r8_snorm r8i r8ui readonly restrict rg16 rg16_snorm rg16f rg16i rg16ui rg32f rg32i rg32ui rg8 rg8_snorm rg8i rg8ui rgb10_a2 rgb10_a2ui rgba16 rgba16_snorm rgba16f rgba16i rgba16ui rgba32f rgba32i rgba32ui rgba8 rgba8_snorm rgba8i rgba8ui row_major sample shared smooth std140 std430 stream triangle_strip triangles triangles_adjacency uniform varying vertices volatile writeonly","type":"atomic_uint bool bvec2 bvec3 bvec4 dmat2 dmat2x2 dmat2x3 dmat2x4 dmat3 dmat3x2 dmat3x3 dmat3x4 dmat4 dmat4x2 dmat4x3 dmat4x4 double dvec2 dvec3 dvec4 float iimage1D iimage1DArray iimage2D iimage2DArray iimage2DMS iimage2DMSArray iimage2DRect iimage3D iimageBufferiimageCube iimageCubeArray image1D image1DArray image2D image2DArray image2DMS image2DMSArray image2DRect image3D imageBuffer imageCube imageCubeArray int isampler1D isampler1DArray isampler2D isampler2DArray isampler2DMS isampler2DMSArray isampler2DRect isampler3D isamplerBuffer isamplerCube isamplerCubeArray ivec2 ivec3 ivec4 mat2 mat2x2 mat2x3 mat2x4 mat3 mat3x2 mat3x3 mat3x4 mat4 mat4x2 mat4x3 mat4x4 sampler1D sampler1DArray sampler1DArrayShadow sampler1DShadow sampler2D sampler2DArray sampler2DArrayShadow sampler2DMS sampler2DMSArray sampler2DRect sampler2DRectShadow sampler2DShadow sampler3D samplerBuffer samplerCube samplerCubeArray samplerCubeArrayShadow samplerCubeShadow image1D uimage1DArray uimage2D uimage2DArray uimage2DMS uimage2DMSArray uimage2DRect uimage3D uimageBuffer uimageCube uimageCubeArray uint usampler1D usampler1DArray usampler2D usampler2DArray usampler2DMS usampler2DMSArray usampler2DRect usampler3D samplerBuffer usamplerCube usamplerCubeArray uvec2 uvec3 uvec4 vec2 vec3 vec4 void","built_in":"gl_MaxAtomicCounterBindings gl_MaxAtomicCounterBufferSize gl_MaxClipDistances gl_MaxClipPlanes gl_MaxCombinedAtomicCounterBuffers gl_MaxCombinedAtomicCounters gl_MaxCombinedImageUniforms gl_MaxCombinedImageUnitsAndFragmentOutputs gl_MaxCombinedTextureImageUnits gl_MaxComputeAtomicCounterBuffers gl_MaxComputeAtomicCounters gl_MaxComputeImageUniforms gl_MaxComputeTextureImageUnits gl_MaxComputeUniformComponents gl_MaxComputeWorkGroupCount gl_MaxComputeWorkGroupSize gl_MaxDrawBuffers gl_MaxFragmentAtomicCounterBuffers gl_MaxFragmentAtomicCounters gl_MaxFragmentImageUniforms gl_MaxFragmentInputComponents gl_MaxFragmentInputVectors gl_MaxFragmentUniformComponents gl_MaxFragmentUniformVectors gl_MaxGeometryAtomicCounterBuffers gl_MaxGeometryAtomicCounters gl_MaxGeometryImageUniforms gl_MaxGeometryInputComponents gl_MaxGeometryOutputComponents gl_MaxGeometryOutputVertices gl_MaxGeometryTextureImageUnits gl_MaxGeometryTotalOutputComponents gl_MaxGeometryUniformComponents gl_MaxGeometryVaryingComponents gl_MaxImageSamples gl_MaxImageUnits gl_MaxLights gl_MaxPatchVertices gl_MaxProgramTexelOffset gl_MaxTessControlAtomicCounterBuffers gl_MaxTessControlAtomicCounters gl_MaxTessControlImageUniforms gl_MaxTessControlInputComponents gl_MaxTessControlOutputComponents gl_MaxTessControlTextureImageUnits gl_MaxTessControlTotalOutputComponents gl_MaxTessControlUniformComponents gl_MaxTessEvaluationAtomicCounterBuffers gl_MaxTessEvaluationAtomicCounters gl_MaxTessEvaluationImageUniforms gl_MaxTessEvaluationInputComponents gl_MaxTessEvaluationOutputComponents gl_MaxTessEvaluationTextureImageUnits gl_MaxTessEvaluationUniformComponents gl_MaxTessGenLevel gl_MaxTessPatchComponents gl_MaxTextureCoords gl_MaxTextureImageUnits gl_MaxTextureUnits gl_MaxVaryingComponents gl_MaxVaryingFloats gl_MaxVaryingVectors gl_MaxVertexAtomicCounterBuffers gl_MaxVertexAtomicCounters gl_MaxVertexAttribs gl_MaxVertexImageUniforms gl_MaxVertexOutputComponents gl_MaxVertexOutputVectors gl_MaxVertexTextureImageUnits gl_MaxVertexUniformComponents gl_MaxVertexUniformVectors gl_MaxViewports gl_MinProgramTexelOffset gl_BackColor gl_BackLightModelProduct gl_BackLightProduct gl_BackMaterial gl_BackSecondaryColor gl_ClipDistance gl_ClipPlane gl_ClipVertex gl_Color gl_DepthRange gl_EyePlaneQ gl_EyePlaneR gl_EyePlaneS gl_EyePlaneT gl_Fog gl_FogCoord gl_FogFragCoord gl_FragColor gl_FragCoord gl_FragData gl_FragDepth gl_FrontColor gl_FrontFacing gl_FrontLightModelProduct gl_FrontLightProduct gl_FrontMaterial gl_FrontSecondaryColor gl_GlobalInvocationID gl_InstanceID gl_InvocationID gl_Layer gl_LightModel gl_LightSource gl_LocalInvocationID gl_LocalInvocationIndex gl_ModelViewMatrix gl_ModelViewMatrixInverse gl_ModelViewMatrixInverseTranspose gl_ModelViewMatrixTranspose gl_ModelViewProjectionMatrix gl_ModelViewProjectionMatrixInverse gl_ModelViewProjectionMatrixInverseTranspose gl_ModelViewProjectionMatrixTranspose gl_MultiTexCoord0 gl_MultiTexCoord1 gl_MultiTexCoord2 gl_MultiTexCoord3 gl_MultiTexCoord4 gl_MultiTexCoord5 gl_MultiTexCoord6 gl_MultiTexCoord7 gl_Normal gl_NormalMatrix gl_NormalScale gl_NumSamples gl_NumWorkGroups gl_ObjectPlaneQ gl_ObjectPlaneR gl_ObjectPlaneS gl_ObjectPlaneT gl_PatchVerticesIn gl_Point gl_PointCoord gl_PointSize gl_Position gl_PrimitiveID gl_PrimitiveIDIn gl_ProjectionMatrix gl_ProjectionMatrixInverse gl_ProjectionMatrixInverseTranspose gl_ProjectionMatrixTranspose gl_SampleID gl_SampleMask gl_SampleMaskIn gl_SamplePosition gl_SecondaryColor gl_TessCoord gl_TessLevelInner gl_TessLevelOuter gl_TexCoord gl_TextureEnvColor gl_TextureMatrix gl_TextureMatrixInverse gl_TextureMatrixInverseTranspose gl_TextureMatrixTranspose gl_Vertex gl_VertexID gl_ViewportIndex gl_WorkGroupID gl_WorkGroupSize gl_in gl_out EmitStreamVertex EmitVertex EndPrimitive EndStreamPrimitive abs acos acosh all any asin asinh atan atanh atomicAdd atomicAnd atomicCompSwap atomicCounter atomicCounterDecrement atomicCounterIncrement atomicExchange atomicMax atomicMin atomicOr atomicXor barrier bitCount bitfieldExtract bitfieldInsert bitfieldReverse ceil clamp cos cosh cross dFdx dFdy degrees determinant distance dot equal exp exp2 faceforward findLSB findMSB floatBitsToInt floatBitsToUint floor fma fract frexp ftransform fwidth greaterThan greaterThanEqual groupMemoryBarrier imageAtomicAdd imageAtomicAnd imageAtomicCompSwap imageAtomicExchange imageAtomicMax imageAtomicMin imageAtomicOr imageAtomicXor imageLoad imageSize imageStore imulExtended intBitsToFloat interpolateAtCentroid interpolateAtOffset interpolateAtSample inverse inversesqrt isinf isnan ldexp length lessThan lessThanEqual log log2 matrixCompMult max memoryBarrier memoryBarrierAtomicCounter memoryBarrierBuffer memoryBarrierImage memoryBarrierShared min mix mod modf noise1 noise2 noise3 noise4 normalize not notEqual outerProduct packDouble2x32 packHalf2x16 packSnorm2x16 packSnorm4x8 packUnorm2x16 packUnorm4x8 pow radians reflect refract round roundEven shadow1D shadow1DLod shadow1DProj shadow1DProjLod shadow2D shadow2DLod shadow2DProj shadow2DProjLod sign sin sinh smoothstep sqrt step tan tanh texelFetch texelFetchOffset texture texture1D texture1DLod texture1DProj texture1DProjLod texture2D texture2DLod texture2DProj texture2DProjLod texture3D texture3DLod texture3DProj texture3DProjLod textureCube textureCubeLod textureGather textureGatherOffset textureGatherOffsets textureGrad textureGradOffset textureLod textureLodOffset textureOffset textureProj textureProjGrad textureProjGradOffset textureProjLod textureProjLodOffset textureProjOffset textureQueryLevels textureQueryLod textureSize transpose trunc uaddCarry uintBitsToFloat umulExtended unpackDouble2x32 unpackHalf2x16 unpackSnorm2x16 unpackSnorm4x8 unpackUnorm2x16 unpackUnorm4x8 usubBorrow","literal":"true false"},"illegal":"\"","contains":[{"className":"comment","begin":"//","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"/\\*","end":"\\*/","contains":[{"$ref":"#contains.0.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"number","begin":"(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)","relevance":0},{"className":"meta","begin":"#","end":"$"}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/gml.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/gml.json new file mode 100644 index 00000000..ef1cfe7c --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/gml.json @@ -0,0 +1 @@ +{"aliases":["gml","GML"],"case_insensitive":false,"keywords":{"keywords":"begin end if then else while do for break continue with until repeat exit and or xor not return mod div switch case default var globalvar enum #macro #region #endregion","built_in":"is_real is_string is_array is_undefined is_int32 is_int64 is_ptr is_vec3 is_vec4 is_matrix is_bool typeof variable_global_exists variable_global_get variable_global_set variable_instance_exists variable_instance_get variable_instance_set variable_instance_get_names array_length_1d array_length_2d array_height_2d array_equals array_create array_copy random random_range irandom irandom_range random_set_seed random_get_seed randomize randomise choose abs round floor ceil sign frac sqrt sqr exp ln log2 log10 sin cos tan arcsin arccos arctan arctan2 dsin dcos dtan darcsin darccos darctan darctan2 degtorad radtodeg power logn min max mean median clamp lerp dot_product dot_product_3d dot_product_normalised dot_product_3d_normalised dot_product_normalized dot_product_3d_normalized math_set_epsilon math_get_epsilon angle_difference point_distance_3d point_distance point_direction lengthdir_x lengthdir_y real string int64 ptr string_format chr ansi_char ord string_length string_byte_length string_pos string_copy string_char_at string_ord_at string_byte_at string_set_byte_at string_delete string_insert string_lower string_upper string_repeat string_letters string_digits string_lettersdigits string_replace string_replace_all string_count string_hash_to_newline clipboard_has_text clipboard_set_text clipboard_get_text date_current_datetime date_create_datetime date_valid_datetime date_inc_year date_inc_month date_inc_week date_inc_day date_inc_hour date_inc_minute date_inc_second date_get_year date_get_month date_get_week date_get_day date_get_hour date_get_minute date_get_second date_get_weekday date_get_day_of_year date_get_hour_of_year date_get_minute_of_year date_get_second_of_year date_year_span date_month_span date_week_span date_day_span date_hour_span date_minute_span date_second_span date_compare_datetime date_compare_date date_compare_time date_date_of date_time_of date_datetime_string date_date_string date_time_string date_days_in_month date_days_in_year date_leap_year date_is_today date_set_timezone date_get_timezone game_set_speed game_get_speed motion_set motion_add place_free place_empty place_meeting place_snapped move_random move_snap move_towards_point move_contact_solid move_contact_all move_outside_solid move_outside_all move_bounce_solid move_bounce_all move_wrap distance_to_point distance_to_object position_empty position_meeting path_start path_end mp_linear_step mp_potential_step mp_linear_step_object mp_potential_step_object mp_potential_settings mp_linear_path mp_potential_path mp_linear_path_object mp_potential_path_object mp_grid_create mp_grid_destroy mp_grid_clear_all mp_grid_clear_cell mp_grid_clear_rectangle mp_grid_add_cell mp_grid_get_cell mp_grid_add_rectangle mp_grid_add_instances mp_grid_path mp_grid_draw mp_grid_to_ds_grid collision_point collision_rectangle collision_circle collision_ellipse collision_line collision_point_list collision_rectangle_list collision_circle_list collision_ellipse_list collision_line_list instance_position_list instance_place_list point_in_rectangle point_in_triangle point_in_circle rectangle_in_rectangle rectangle_in_triangle rectangle_in_circle instance_find instance_exists instance_number instance_position instance_nearest instance_furthest instance_place instance_create_depth instance_create_layer instance_copy instance_change instance_destroy position_destroy position_change instance_id_get instance_deactivate_all instance_deactivate_object instance_deactivate_region instance_activate_all instance_activate_object instance_activate_region room_goto room_goto_previous room_goto_next room_previous room_next room_restart game_end game_restart game_load game_save game_save_buffer game_load_buffer event_perform event_user event_perform_object event_inherited show_debug_message show_debug_overlay debug_event debug_get_callstack alarm_get alarm_set font_texture_page_size keyboard_set_map keyboard_get_map keyboard_unset_map keyboard_check keyboard_check_pressed keyboard_check_released keyboard_check_direct keyboard_get_numlock keyboard_set_numlock keyboard_key_press keyboard_key_release keyboard_clear io_clear mouse_check_button mouse_check_button_pressed mouse_check_button_released mouse_wheel_up mouse_wheel_down mouse_clear draw_self draw_sprite draw_sprite_pos draw_sprite_ext draw_sprite_stretched draw_sprite_stretched_ext draw_sprite_tiled draw_sprite_tiled_ext draw_sprite_part draw_sprite_part_ext draw_sprite_general draw_clear draw_clear_alpha draw_point draw_line draw_line_width draw_rectangle draw_roundrect draw_roundrect_ext draw_triangle draw_circle draw_ellipse draw_set_circle_precision draw_arrow draw_button draw_path draw_healthbar draw_getpixel draw_getpixel_ext draw_set_colour draw_set_color draw_set_alpha draw_get_colour draw_get_color draw_get_alpha merge_colour make_colour_rgb make_colour_hsv colour_get_red colour_get_green colour_get_blue colour_get_hue colour_get_saturation colour_get_value merge_color make_color_rgb make_color_hsv color_get_red color_get_green color_get_blue color_get_hue color_get_saturation color_get_value merge_color screen_save screen_save_part draw_set_font draw_set_halign draw_set_valign draw_text draw_text_ext string_width string_height string_width_ext string_height_ext draw_text_transformed draw_text_ext_transformed draw_text_colour draw_text_ext_colour draw_text_transformed_colour draw_text_ext_transformed_colour draw_text_color draw_text_ext_color draw_text_transformed_color draw_text_ext_transformed_color draw_point_colour draw_line_colour draw_line_width_colour draw_rectangle_colour draw_roundrect_colour draw_roundrect_colour_ext draw_triangle_colour draw_circle_colour draw_ellipse_colour draw_point_color draw_line_color draw_line_width_color draw_rectangle_color draw_roundrect_color draw_roundrect_color_ext draw_triangle_color draw_circle_color draw_ellipse_color draw_primitive_begin draw_vertex draw_vertex_colour draw_vertex_color draw_primitive_end sprite_get_uvs font_get_uvs sprite_get_texture font_get_texture texture_get_width texture_get_height texture_get_uvs draw_primitive_begin_texture draw_vertex_texture draw_vertex_texture_colour draw_vertex_texture_color texture_global_scale surface_create surface_create_ext surface_resize surface_free surface_exists surface_get_width surface_get_height surface_get_texture surface_set_target surface_set_target_ext surface_reset_target surface_depth_disable surface_get_depth_disable draw_surface draw_surface_stretched draw_surface_tiled draw_surface_part draw_surface_ext draw_surface_stretched_ext draw_surface_tiled_ext draw_surface_part_ext draw_surface_general surface_getpixel surface_getpixel_ext surface_save surface_save_part surface_copy surface_copy_part application_surface_draw_enable application_get_position application_surface_enable application_surface_is_enabled display_get_width display_get_height display_get_orientation display_get_gui_width display_get_gui_height display_reset display_mouse_get_x display_mouse_get_y display_mouse_set display_set_ui_visibility window_set_fullscreen window_get_fullscreen window_set_caption window_set_min_width window_set_max_width window_set_min_height window_set_max_height window_get_visible_rects window_get_caption window_set_cursor window_get_cursor window_set_colour window_get_colour window_set_color window_get_color window_set_position window_set_size window_set_rectangle window_center window_get_x window_get_y window_get_width window_get_height window_mouse_get_x window_mouse_get_y window_mouse_set window_view_mouse_get_x window_view_mouse_get_y window_views_mouse_get_x window_views_mouse_get_y audio_listener_position audio_listener_velocity audio_listener_orientation audio_emitter_position audio_emitter_create audio_emitter_free audio_emitter_exists audio_emitter_pitch audio_emitter_velocity audio_emitter_falloff audio_emitter_gain audio_play_sound audio_play_sound_on audio_play_sound_at audio_stop_sound audio_resume_music audio_music_is_playing audio_resume_sound audio_pause_sound audio_pause_music audio_channel_num audio_sound_length audio_get_type audio_falloff_set_model audio_play_music audio_stop_music audio_master_gain audio_music_gain audio_sound_gain audio_sound_pitch audio_stop_all audio_resume_all audio_pause_all audio_is_playing audio_is_paused audio_exists audio_sound_set_track_position audio_sound_get_track_position audio_emitter_get_gain audio_emitter_get_pitch audio_emitter_get_x audio_emitter_get_y audio_emitter_get_z audio_emitter_get_vx audio_emitter_get_vy audio_emitter_get_vz audio_listener_set_position audio_listener_set_velocity audio_listener_set_orientation audio_listener_get_data audio_set_master_gain audio_get_master_gain audio_sound_get_gain audio_sound_get_pitch audio_get_name audio_sound_set_track_position audio_sound_get_track_position audio_create_stream audio_destroy_stream audio_create_sync_group audio_destroy_sync_group audio_play_in_sync_group audio_start_sync_group audio_stop_sync_group audio_pause_sync_group audio_resume_sync_group audio_sync_group_get_track_pos audio_sync_group_debug audio_sync_group_is_playing audio_debug audio_group_load audio_group_unload audio_group_is_loaded audio_group_load_progress audio_group_name audio_group_stop_all audio_group_set_gain audio_create_buffer_sound audio_free_buffer_sound audio_create_play_queue audio_free_play_queue audio_queue_sound audio_get_recorder_count audio_get_recorder_info audio_start_recording audio_stop_recording audio_sound_get_listener_mask audio_emitter_get_listener_mask audio_get_listener_mask audio_sound_set_listener_mask audio_emitter_set_listener_mask audio_set_listener_mask audio_get_listener_count audio_get_listener_info audio_system show_message show_message_async clickable_add clickable_add_ext clickable_change clickable_change_ext clickable_delete clickable_exists clickable_set_style show_question show_question_async get_integer get_string get_integer_async get_string_async get_login_async get_open_filename get_save_filename get_open_filename_ext get_save_filename_ext show_error highscore_clear highscore_add highscore_value highscore_name draw_highscore sprite_exists sprite_get_name sprite_get_number sprite_get_width sprite_get_height sprite_get_xoffset sprite_get_yoffset sprite_get_bbox_left sprite_get_bbox_right sprite_get_bbox_top sprite_get_bbox_bottom sprite_save sprite_save_strip sprite_set_cache_size sprite_set_cache_size_ext sprite_get_tpe sprite_prefetch sprite_prefetch_multi sprite_flush sprite_flush_multi sprite_set_speed sprite_get_speed_type sprite_get_speed font_exists font_get_name font_get_fontname font_get_bold font_get_italic font_get_first font_get_last font_get_size font_set_cache_size path_exists path_get_name path_get_length path_get_time path_get_kind path_get_closed path_get_precision path_get_number path_get_point_x path_get_point_y path_get_point_speed path_get_x path_get_y path_get_speed script_exists script_get_name timeline_add timeline_delete timeline_clear timeline_exists timeline_get_name timeline_moment_clear timeline_moment_add_script timeline_size timeline_max_moment object_exists object_get_name object_get_sprite object_get_solid object_get_visible object_get_persistent object_get_mask object_get_parent object_get_physics object_is_ancestor room_exists room_get_name sprite_set_offset sprite_duplicate sprite_assign sprite_merge sprite_add sprite_replace sprite_create_from_surface sprite_add_from_surface sprite_delete sprite_set_alpha_from_sprite sprite_collision_mask font_add_enable_aa font_add_get_enable_aa font_add font_add_sprite font_add_sprite_ext font_replace font_replace_sprite font_replace_sprite_ext font_delete path_set_kind path_set_closed path_set_precision path_add path_assign path_duplicate path_append path_delete path_add_point path_insert_point path_change_point path_delete_point path_clear_points path_reverse path_mirror path_flip path_rotate path_rescale path_shift script_execute object_set_sprite object_set_solid object_set_visible object_set_persistent object_set_mask room_set_width room_set_height room_set_persistent room_set_background_colour room_set_background_color room_set_view room_set_viewport room_get_viewport room_set_view_enabled room_add room_duplicate room_assign room_instance_add room_instance_clear room_get_camera room_set_camera asset_get_index asset_get_type file_text_open_from_string file_text_open_read file_text_open_write file_text_open_append file_text_close file_text_write_string file_text_write_real file_text_writeln file_text_read_string file_text_read_real file_text_readln file_text_eof file_text_eoln file_exists file_delete file_rename file_copy directory_exists directory_create directory_destroy file_find_first file_find_next file_find_close file_attributes filename_name filename_path filename_dir filename_drive filename_ext filename_change_ext file_bin_open file_bin_rewrite file_bin_close file_bin_position file_bin_size file_bin_seek file_bin_write_byte file_bin_read_byte parameter_count parameter_string environment_get_variable ini_open_from_string ini_open ini_close ini_read_string ini_read_real ini_write_string ini_write_real ini_key_exists ini_section_exists ini_key_delete ini_section_delete ds_set_precision ds_exists ds_stack_create ds_stack_destroy ds_stack_clear ds_stack_copy ds_stack_size ds_stack_empty ds_stack_push ds_stack_pop ds_stack_top ds_stack_write ds_stack_read ds_queue_create ds_queue_destroy ds_queue_clear ds_queue_copy ds_queue_size ds_queue_empty ds_queue_enqueue ds_queue_dequeue ds_queue_head ds_queue_tail ds_queue_write ds_queue_read ds_list_create ds_list_destroy ds_list_clear ds_list_copy ds_list_size ds_list_empty ds_list_add ds_list_insert ds_list_replace ds_list_delete ds_list_find_index ds_list_find_value ds_list_mark_as_list ds_list_mark_as_map ds_list_sort ds_list_shuffle ds_list_write ds_list_read ds_list_set ds_map_create ds_map_destroy ds_map_clear ds_map_copy ds_map_size ds_map_empty ds_map_add ds_map_add_list ds_map_add_map ds_map_replace ds_map_replace_map ds_map_replace_list ds_map_delete ds_map_exists ds_map_find_value ds_map_find_previous ds_map_find_next ds_map_find_first ds_map_find_last ds_map_write ds_map_read ds_map_secure_save ds_map_secure_load ds_map_secure_load_buffer ds_map_secure_save_buffer ds_map_set ds_priority_create ds_priority_destroy ds_priority_clear ds_priority_copy ds_priority_size ds_priority_empty ds_priority_add ds_priority_change_priority ds_priority_find_priority ds_priority_delete_value ds_priority_delete_min ds_priority_find_min ds_priority_delete_max ds_priority_find_max ds_priority_write ds_priority_read ds_grid_create ds_grid_destroy ds_grid_copy ds_grid_resize ds_grid_width ds_grid_height ds_grid_clear ds_grid_set ds_grid_add ds_grid_multiply ds_grid_set_region ds_grid_add_region ds_grid_multiply_region ds_grid_set_disk ds_grid_add_disk ds_grid_multiply_disk ds_grid_set_grid_region ds_grid_add_grid_region ds_grid_multiply_grid_region ds_grid_get ds_grid_get_sum ds_grid_get_max ds_grid_get_min ds_grid_get_mean ds_grid_get_disk_sum ds_grid_get_disk_min ds_grid_get_disk_max ds_grid_get_disk_mean ds_grid_value_exists ds_grid_value_x ds_grid_value_y ds_grid_value_disk_exists ds_grid_value_disk_x ds_grid_value_disk_y ds_grid_shuffle ds_grid_write ds_grid_read ds_grid_sort ds_grid_set ds_grid_get effect_create_below effect_create_above effect_clear part_type_create part_type_destroy part_type_exists part_type_clear part_type_shape part_type_sprite part_type_size part_type_scale part_type_orientation part_type_life part_type_step part_type_death part_type_speed part_type_direction part_type_gravity part_type_colour1 part_type_colour2 part_type_colour3 part_type_colour_mix part_type_colour_rgb part_type_colour_hsv part_type_color1 part_type_color2 part_type_color3 part_type_color_mix part_type_color_rgb part_type_color_hsv part_type_alpha1 part_type_alpha2 part_type_alpha3 part_type_blend part_system_create part_system_create_layer part_system_destroy part_system_exists part_system_clear part_system_draw_order part_system_depth part_system_position part_system_automatic_update part_system_automatic_draw part_system_update part_system_drawit part_system_get_layer part_system_layer part_particles_create part_particles_create_colour part_particles_create_color part_particles_clear part_particles_count part_emitter_create part_emitter_destroy part_emitter_destroy_all part_emitter_exists part_emitter_clear part_emitter_region part_emitter_burst part_emitter_stream external_call external_define external_free window_handle window_device matrix_get matrix_set matrix_build_identity matrix_build matrix_build_lookat matrix_build_projection_ortho matrix_build_projection_perspective matrix_build_projection_perspective_fov matrix_multiply matrix_transform_vertex matrix_stack_push matrix_stack_pop matrix_stack_multiply matrix_stack_set matrix_stack_clear matrix_stack_top matrix_stack_is_empty browser_input_capture os_get_config os_get_info os_get_language os_get_region os_lock_orientation display_get_dpi_x display_get_dpi_y display_set_gui_size display_set_gui_maximise display_set_gui_maximize device_mouse_dbclick_enable display_set_timing_method display_get_timing_method display_set_sleep_margin display_get_sleep_margin virtual_key_add virtual_key_hide virtual_key_delete virtual_key_show draw_enable_drawevent draw_enable_swf_aa draw_set_swf_aa_level draw_get_swf_aa_level draw_texture_flush draw_flush gpu_set_blendenable gpu_set_ztestenable gpu_set_zfunc gpu_set_zwriteenable gpu_set_lightingenable gpu_set_fog gpu_set_cullmode gpu_set_blendmode gpu_set_blendmode_ext gpu_set_blendmode_ext_sepalpha gpu_set_colorwriteenable gpu_set_colourwriteenable gpu_set_alphatestenable gpu_set_alphatestref gpu_set_alphatestfunc gpu_set_texfilter gpu_set_texfilter_ext gpu_set_texrepeat gpu_set_texrepeat_ext gpu_set_tex_filter gpu_set_tex_filter_ext gpu_set_tex_repeat gpu_set_tex_repeat_ext gpu_set_tex_mip_filter gpu_set_tex_mip_filter_ext gpu_set_tex_mip_bias gpu_set_tex_mip_bias_ext gpu_set_tex_min_mip gpu_set_tex_min_mip_ext gpu_set_tex_max_mip gpu_set_tex_max_mip_ext gpu_set_tex_max_aniso gpu_set_tex_max_aniso_ext gpu_set_tex_mip_enable gpu_set_tex_mip_enable_ext gpu_get_blendenable gpu_get_ztestenable gpu_get_zfunc gpu_get_zwriteenable gpu_get_lightingenable gpu_get_fog gpu_get_cullmode gpu_get_blendmode gpu_get_blendmode_ext gpu_get_blendmode_ext_sepalpha gpu_get_blendmode_src gpu_get_blendmode_dest gpu_get_blendmode_srcalpha gpu_get_blendmode_destalpha gpu_get_colorwriteenable gpu_get_colourwriteenable gpu_get_alphatestenable gpu_get_alphatestref gpu_get_alphatestfunc gpu_get_texfilter gpu_get_texfilter_ext gpu_get_texrepeat gpu_get_texrepeat_ext gpu_get_tex_filter gpu_get_tex_filter_ext gpu_get_tex_repeat gpu_get_tex_repeat_ext gpu_get_tex_mip_filter gpu_get_tex_mip_filter_ext gpu_get_tex_mip_bias gpu_get_tex_mip_bias_ext gpu_get_tex_min_mip gpu_get_tex_min_mip_ext gpu_get_tex_max_mip gpu_get_tex_max_mip_ext gpu_get_tex_max_aniso gpu_get_tex_max_aniso_ext gpu_get_tex_mip_enable gpu_get_tex_mip_enable_ext gpu_push_state gpu_pop_state gpu_get_state gpu_set_state draw_light_define_ambient draw_light_define_direction draw_light_define_point draw_light_enable draw_set_lighting draw_light_get_ambient draw_light_get draw_get_lighting shop_leave_rating url_get_domain url_open url_open_ext url_open_full get_timer achievement_login achievement_logout achievement_post achievement_increment achievement_post_score achievement_available achievement_show_achievements achievement_show_leaderboards achievement_load_friends achievement_load_leaderboard achievement_send_challenge achievement_load_progress achievement_reset achievement_login_status achievement_get_pic achievement_show_challenge_notifications achievement_get_challenges achievement_event achievement_show achievement_get_info cloud_file_save cloud_string_save cloud_synchronise ads_enable ads_disable ads_setup ads_engagement_launch ads_engagement_available ads_engagement_active ads_event ads_event_preload ads_set_reward_callback ads_get_display_height ads_get_display_width ads_move ads_interstitial_available ads_interstitial_display device_get_tilt_x device_get_tilt_y device_get_tilt_z device_is_keypad_open device_mouse_check_button device_mouse_check_button_pressed device_mouse_check_button_released device_mouse_x device_mouse_y device_mouse_raw_x device_mouse_raw_y device_mouse_x_to_gui device_mouse_y_to_gui iap_activate iap_status iap_enumerate_products iap_restore_all iap_acquire iap_consume iap_product_details iap_purchase_details facebook_init facebook_login facebook_status facebook_graph_request facebook_dialog facebook_logout facebook_launch_offerwall facebook_post_message facebook_send_invite facebook_user_id facebook_accesstoken facebook_check_permission facebook_request_read_permissions facebook_request_publish_permissions gamepad_is_supported gamepad_get_device_count gamepad_is_connected gamepad_get_description gamepad_get_button_threshold gamepad_set_button_threshold gamepad_get_axis_deadzone gamepad_set_axis_deadzone gamepad_button_count gamepad_button_check gamepad_button_check_pressed gamepad_button_check_released gamepad_button_value gamepad_axis_count gamepad_axis_value gamepad_set_vibration gamepad_set_colour gamepad_set_color os_is_paused window_has_focus code_is_compiled http_get http_get_file http_post_string http_request json_encode json_decode zip_unzip load_csv base64_encode base64_decode md5_string_unicode md5_string_utf8 md5_file os_is_network_connected sha1_string_unicode sha1_string_utf8 sha1_file os_powersave_enable analytics_event analytics_event_ext win8_livetile_tile_notification win8_livetile_tile_clear win8_livetile_badge_notification win8_livetile_badge_clear win8_livetile_queue_enable win8_secondarytile_pin win8_secondarytile_badge_notification win8_secondarytile_delete win8_livetile_notification_begin win8_livetile_notification_secondary_begin win8_livetile_notification_expiry win8_livetile_notification_tag win8_livetile_notification_text_add win8_livetile_notification_image_add win8_livetile_notification_end win8_appbar_enable win8_appbar_add_element win8_appbar_remove_element win8_settingscharm_add_entry win8_settingscharm_add_html_entry win8_settingscharm_add_xaml_entry win8_settingscharm_set_xaml_property win8_settingscharm_get_xaml_property win8_settingscharm_remove_entry win8_share_image win8_share_screenshot win8_share_file win8_share_url win8_share_text win8_search_enable win8_search_disable win8_search_add_suggestions win8_device_touchscreen_available win8_license_initialize_sandbox win8_license_trial_version winphone_license_trial_version winphone_tile_title winphone_tile_count winphone_tile_back_title winphone_tile_back_content winphone_tile_back_content_wide winphone_tile_front_image winphone_tile_front_image_small winphone_tile_front_image_wide winphone_tile_back_image winphone_tile_back_image_wide winphone_tile_background_colour winphone_tile_background_color winphone_tile_icon_image winphone_tile_small_icon_image winphone_tile_wide_content winphone_tile_cycle_images winphone_tile_small_background_image physics_world_create physics_world_gravity physics_world_update_speed physics_world_update_iterations physics_world_draw_debug physics_pause_enable physics_fixture_create physics_fixture_set_kinematic physics_fixture_set_density physics_fixture_set_awake physics_fixture_set_restitution physics_fixture_set_friction physics_fixture_set_collision_group physics_fixture_set_sensor physics_fixture_set_linear_damping physics_fixture_set_angular_damping physics_fixture_set_circle_shape physics_fixture_set_box_shape physics_fixture_set_edge_shape physics_fixture_set_polygon_shape physics_fixture_set_chain_shape physics_fixture_add_point physics_fixture_bind physics_fixture_bind_ext physics_fixture_delete physics_apply_force physics_apply_impulse physics_apply_angular_impulse physics_apply_local_force physics_apply_local_impulse physics_apply_torque physics_mass_properties physics_draw_debug physics_test_overlap physics_remove_fixture physics_set_friction physics_set_density physics_set_restitution physics_get_friction physics_get_density physics_get_restitution physics_joint_distance_create physics_joint_rope_create physics_joint_revolute_create physics_joint_prismatic_create physics_joint_pulley_create physics_joint_wheel_create physics_joint_weld_create physics_joint_friction_create physics_joint_gear_create physics_joint_enable_motor physics_joint_get_value physics_joint_set_value physics_joint_delete physics_particle_create physics_particle_delete physics_particle_delete_region_circle physics_particle_delete_region_box physics_particle_delete_region_poly physics_particle_set_flags physics_particle_set_category_flags physics_particle_draw physics_particle_draw_ext physics_particle_count physics_particle_get_data physics_particle_get_data_particle physics_particle_group_begin physics_particle_group_circle physics_particle_group_box physics_particle_group_polygon physics_particle_group_add_point physics_particle_group_end physics_particle_group_join physics_particle_group_delete physics_particle_group_count physics_particle_group_get_data physics_particle_group_get_mass physics_particle_group_get_inertia physics_particle_group_get_centre_x physics_particle_group_get_centre_y physics_particle_group_get_vel_x physics_particle_group_get_vel_y physics_particle_group_get_ang_vel physics_particle_group_get_x physics_particle_group_get_y physics_particle_group_get_angle physics_particle_set_group_flags physics_particle_get_group_flags physics_particle_get_max_count physics_particle_get_radius physics_particle_get_density physics_particle_get_damping physics_particle_get_gravity_scale physics_particle_set_max_count physics_particle_set_radius physics_particle_set_density physics_particle_set_damping physics_particle_set_gravity_scale network_create_socket network_create_socket_ext network_create_server network_create_server_raw network_connect network_connect_raw network_send_packet network_send_raw network_send_broadcast network_send_udp network_send_udp_raw network_set_timeout network_set_config network_resolve network_destroy buffer_create buffer_write buffer_read buffer_seek buffer_get_surface buffer_set_surface buffer_delete buffer_exists buffer_get_type buffer_get_alignment buffer_poke buffer_peek buffer_save buffer_save_ext buffer_load buffer_load_ext buffer_load_partial buffer_copy buffer_fill buffer_get_size buffer_tell buffer_resize buffer_md5 buffer_sha1 buffer_base64_encode buffer_base64_decode buffer_base64_decode_ext buffer_sizeof buffer_get_address buffer_create_from_vertex_buffer buffer_create_from_vertex_buffer_ext buffer_copy_from_vertex_buffer buffer_async_group_begin buffer_async_group_option buffer_async_group_end buffer_load_async buffer_save_async gml_release_mode gml_pragma steam_activate_overlay steam_is_overlay_enabled steam_is_overlay_activated steam_get_persona_name steam_initialised steam_is_cloud_enabled_for_app steam_is_cloud_enabled_for_account steam_file_persisted steam_get_quota_total steam_get_quota_free steam_file_write steam_file_write_file steam_file_read steam_file_delete steam_file_exists steam_file_size steam_file_share steam_is_screenshot_requested steam_send_screenshot steam_is_user_logged_on steam_get_user_steam_id steam_user_owns_dlc steam_user_installed_dlc steam_set_achievement steam_get_achievement steam_clear_achievement steam_set_stat_int steam_set_stat_float steam_set_stat_avg_rate steam_get_stat_int steam_get_stat_float steam_get_stat_avg_rate steam_reset_all_stats steam_reset_all_stats_achievements steam_stats_ready steam_create_leaderboard steam_upload_score steam_upload_score_ext steam_download_scores_around_user steam_download_scores steam_download_friends_scores steam_upload_score_buffer steam_upload_score_buffer_ext steam_current_game_language steam_available_languages steam_activate_overlay_browser steam_activate_overlay_user steam_activate_overlay_store steam_get_user_persona_name steam_get_app_id steam_get_user_account_id steam_ugc_download steam_ugc_create_item steam_ugc_start_item_update steam_ugc_set_item_title steam_ugc_set_item_description steam_ugc_set_item_visibility steam_ugc_set_item_tags steam_ugc_set_item_content steam_ugc_set_item_preview steam_ugc_submit_item_update steam_ugc_get_item_update_progress steam_ugc_subscribe_item steam_ugc_unsubscribe_item steam_ugc_num_subscribed_items steam_ugc_get_subscribed_items steam_ugc_get_item_install_info steam_ugc_get_item_update_info steam_ugc_request_item_details steam_ugc_create_query_user steam_ugc_create_query_user_ex steam_ugc_create_query_all steam_ugc_create_query_all_ex steam_ugc_query_set_cloud_filename_filter steam_ugc_query_set_match_any_tag steam_ugc_query_set_search_text steam_ugc_query_set_ranked_by_trend_days steam_ugc_query_add_required_tag steam_ugc_query_add_excluded_tag steam_ugc_query_set_return_long_description steam_ugc_query_set_return_total_only steam_ugc_query_set_allow_cached_response steam_ugc_send_query shader_set shader_get_name shader_reset shader_current shader_is_compiled shader_get_sampler_index shader_get_uniform shader_set_uniform_i shader_set_uniform_i_array shader_set_uniform_f shader_set_uniform_f_array shader_set_uniform_matrix shader_set_uniform_matrix_array shader_enable_corner_id texture_set_stage texture_get_texel_width texture_get_texel_height shaders_are_supported vertex_format_begin vertex_format_end vertex_format_delete vertex_format_add_position vertex_format_add_position_3d vertex_format_add_colour vertex_format_add_color vertex_format_add_normal vertex_format_add_texcoord vertex_format_add_textcoord vertex_format_add_custom vertex_create_buffer vertex_create_buffer_ext vertex_delete_buffer vertex_begin vertex_end vertex_position vertex_position_3d vertex_colour vertex_color vertex_argb vertex_texcoord vertex_normal vertex_float1 vertex_float2 vertex_float3 vertex_float4 vertex_ubyte4 vertex_submit vertex_freeze vertex_get_number vertex_get_buffer_size vertex_create_buffer_from_buffer vertex_create_buffer_from_buffer_ext push_local_notification push_get_first_local_notification push_get_next_local_notification push_cancel_local_notification skeleton_animation_set skeleton_animation_get skeleton_animation_mix skeleton_animation_set_ext skeleton_animation_get_ext skeleton_animation_get_duration skeleton_animation_get_frames skeleton_animation_clear skeleton_skin_set skeleton_skin_get skeleton_attachment_set skeleton_attachment_get skeleton_attachment_create skeleton_collision_draw_set skeleton_bone_data_get skeleton_bone_data_set skeleton_bone_state_get skeleton_bone_state_set skeleton_get_minmax skeleton_get_num_bounds skeleton_get_bounds skeleton_animation_get_frame skeleton_animation_set_frame draw_skeleton draw_skeleton_time draw_skeleton_instance draw_skeleton_collision skeleton_animation_list skeleton_skin_list skeleton_slot_data layer_get_id layer_get_id_at_depth layer_get_depth layer_create layer_destroy layer_destroy_instances layer_add_instance layer_has_instance layer_set_visible layer_get_visible layer_exists layer_x layer_y layer_get_x layer_get_y layer_hspeed layer_vspeed layer_get_hspeed layer_get_vspeed layer_script_begin layer_script_end layer_shader layer_get_script_begin layer_get_script_end layer_get_shader layer_set_target_room layer_get_target_room layer_reset_target_room layer_get_all layer_get_all_elements layer_get_name layer_depth layer_get_element_layer layer_get_element_type layer_element_move layer_force_draw_depth layer_is_draw_depth_forced layer_get_forced_depth layer_background_get_id layer_background_exists layer_background_create layer_background_destroy layer_background_visible layer_background_change layer_background_sprite layer_background_htiled layer_background_vtiled layer_background_stretch layer_background_yscale layer_background_xscale layer_background_blend layer_background_alpha layer_background_index layer_background_speed layer_background_get_visible layer_background_get_sprite layer_background_get_htiled layer_background_get_vtiled layer_background_get_stretch layer_background_get_yscale layer_background_get_xscale layer_background_get_blend layer_background_get_alpha layer_background_get_index layer_background_get_speed layer_sprite_get_id layer_sprite_exists layer_sprite_create layer_sprite_destroy layer_sprite_change layer_sprite_index layer_sprite_speed layer_sprite_xscale layer_sprite_yscale layer_sprite_angle layer_sprite_blend layer_sprite_alpha layer_sprite_x layer_sprite_y layer_sprite_get_sprite layer_sprite_get_index layer_sprite_get_speed layer_sprite_get_xscale layer_sprite_get_yscale layer_sprite_get_angle layer_sprite_get_blend layer_sprite_get_alpha layer_sprite_get_x layer_sprite_get_y layer_tilemap_get_id layer_tilemap_exists layer_tilemap_create layer_tilemap_destroy tilemap_tileset tilemap_x tilemap_y tilemap_set tilemap_set_at_pixel tilemap_get_tileset tilemap_get_tile_width tilemap_get_tile_height tilemap_get_width tilemap_get_height tilemap_get_x tilemap_get_y tilemap_get tilemap_get_at_pixel tilemap_get_cell_x_at_pixel tilemap_get_cell_y_at_pixel tilemap_clear draw_tilemap draw_tile tilemap_set_global_mask tilemap_get_global_mask tilemap_set_mask tilemap_get_mask tilemap_get_frame tile_set_empty tile_set_index tile_set_flip tile_set_mirror tile_set_rotate tile_get_empty tile_get_index tile_get_flip tile_get_mirror tile_get_rotate layer_tile_exists layer_tile_create layer_tile_destroy layer_tile_change layer_tile_xscale layer_tile_yscale layer_tile_blend layer_tile_alpha layer_tile_x layer_tile_y layer_tile_region layer_tile_visible layer_tile_get_sprite layer_tile_get_xscale layer_tile_get_yscale layer_tile_get_blend layer_tile_get_alpha layer_tile_get_x layer_tile_get_y layer_tile_get_region layer_tile_get_visible layer_instance_get_instance instance_activate_layer instance_deactivate_layer camera_create camera_create_view camera_destroy camera_apply camera_get_active camera_get_default camera_set_default camera_set_view_mat camera_set_proj_mat camera_set_update_script camera_set_begin_script camera_set_end_script camera_set_view_pos camera_set_view_size camera_set_view_speed camera_set_view_border camera_set_view_angle camera_set_view_target camera_get_view_mat camera_get_proj_mat camera_get_update_script camera_get_begin_script camera_get_end_script camera_get_view_x camera_get_view_y camera_get_view_width camera_get_view_height camera_get_view_speed_x camera_get_view_speed_y camera_get_view_border_x camera_get_view_border_y camera_get_view_angle camera_get_view_target view_get_camera view_get_visible view_get_xport view_get_yport view_get_wport view_get_hport view_get_surface_id view_set_camera view_set_visible view_set_xport view_set_yport view_set_wport view_set_hport view_set_surface_id gesture_drag_time gesture_drag_distance gesture_flick_speed gesture_double_tap_time gesture_double_tap_distance gesture_pinch_distance gesture_pinch_angle_towards gesture_pinch_angle_away gesture_rotate_time gesture_rotate_angle gesture_tap_count gesture_get_drag_time gesture_get_drag_distance gesture_get_flick_speed gesture_get_double_tap_time gesture_get_double_tap_distance gesture_get_pinch_distance gesture_get_pinch_angle_towards gesture_get_pinch_angle_away gesture_get_rotate_time gesture_get_rotate_angle gesture_get_tap_count keyboard_virtual_show keyboard_virtual_hide keyboard_virtual_status keyboard_virtual_height","literal":"self other all noone global local undefined pointer_invalid pointer_null path_action_stop path_action_restart path_action_continue path_action_reverse true false pi GM_build_date GM_version GM_runtime_version timezone_local timezone_utc gamespeed_fps gamespeed_microseconds ev_create ev_destroy ev_step ev_alarm ev_keyboard ev_mouse ev_collision ev_other ev_draw ev_draw_begin ev_draw_end ev_draw_pre ev_draw_post ev_keypress ev_keyrelease ev_trigger ev_left_button ev_right_button ev_middle_button ev_no_button ev_left_press ev_right_press ev_middle_press ev_left_release ev_right_release ev_middle_release ev_mouse_enter ev_mouse_leave ev_mouse_wheel_up ev_mouse_wheel_down ev_global_left_button ev_global_right_button ev_global_middle_button ev_global_left_press ev_global_right_press ev_global_middle_press ev_global_left_release ev_global_right_release ev_global_middle_release ev_joystick1_left ev_joystick1_right ev_joystick1_up ev_joystick1_down ev_joystick1_button1 ev_joystick1_button2 ev_joystick1_button3 ev_joystick1_button4 ev_joystick1_button5 ev_joystick1_button6 ev_joystick1_button7 ev_joystick1_button8 ev_joystick2_left ev_joystick2_right ev_joystick2_up ev_joystick2_down ev_joystick2_button1 ev_joystick2_button2 ev_joystick2_button3 ev_joystick2_button4 ev_joystick2_button5 ev_joystick2_button6 ev_joystick2_button7 ev_joystick2_button8 ev_outside ev_boundary ev_game_start ev_game_end ev_room_start ev_room_end ev_no_more_lives ev_animation_end ev_end_of_path ev_no_more_health ev_close_button ev_user0 ev_user1 ev_user2 ev_user3 ev_user4 ev_user5 ev_user6 ev_user7 ev_user8 ev_user9 ev_user10 ev_user11 ev_user12 ev_user13 ev_user14 ev_user15 ev_step_normal ev_step_begin ev_step_end ev_gui ev_gui_begin ev_gui_end ev_cleanup ev_gesture ev_gesture_tap ev_gesture_double_tap ev_gesture_drag_start ev_gesture_dragging ev_gesture_drag_end ev_gesture_flick ev_gesture_pinch_start ev_gesture_pinch_in ev_gesture_pinch_out ev_gesture_pinch_end ev_gesture_rotate_start ev_gesture_rotating ev_gesture_rotate_end ev_global_gesture_tap ev_global_gesture_double_tap ev_global_gesture_drag_start ev_global_gesture_dragging ev_global_gesture_drag_end ev_global_gesture_flick ev_global_gesture_pinch_start ev_global_gesture_pinch_in ev_global_gesture_pinch_out ev_global_gesture_pinch_end ev_global_gesture_rotate_start ev_global_gesture_rotating ev_global_gesture_rotate_end vk_nokey vk_anykey vk_enter vk_return vk_shift vk_control vk_alt vk_escape vk_space vk_backspace vk_tab vk_pause vk_printscreen vk_left vk_right vk_up vk_down vk_home vk_end vk_delete vk_insert vk_pageup vk_pagedown vk_f1 vk_f2 vk_f3 vk_f4 vk_f5 vk_f6 vk_f7 vk_f8 vk_f9 vk_f10 vk_f11 vk_f12 vk_numpad0 vk_numpad1 vk_numpad2 vk_numpad3 vk_numpad4 vk_numpad5 vk_numpad6 vk_numpad7 vk_numpad8 vk_numpad9 vk_divide vk_multiply vk_subtract vk_add vk_decimal vk_lshift vk_lcontrol vk_lalt vk_rshift vk_rcontrol vk_ralt mb_any mb_none mb_left mb_right mb_middle c_aqua c_black c_blue c_dkgray c_fuchsia c_gray c_green c_lime c_ltgray c_maroon c_navy c_olive c_purple c_red c_silver c_teal c_white c_yellow c_orange fa_left fa_center fa_right fa_top fa_middle fa_bottom pr_pointlist pr_linelist pr_linestrip pr_trianglelist pr_trianglestrip pr_trianglefan bm_complex bm_normal bm_add bm_max bm_subtract bm_zero bm_one bm_src_colour bm_inv_src_colour bm_src_color bm_inv_src_color bm_src_alpha bm_inv_src_alpha bm_dest_alpha bm_inv_dest_alpha bm_dest_colour bm_inv_dest_colour bm_dest_color bm_inv_dest_color bm_src_alpha_sat tf_point tf_linear tf_anisotropic mip_off mip_on mip_markedonly audio_falloff_none audio_falloff_inverse_distance audio_falloff_inverse_distance_clamped audio_falloff_linear_distance audio_falloff_linear_distance_clamped audio_falloff_exponent_distance audio_falloff_exponent_distance_clamped audio_old_system audio_new_system audio_mono audio_stereo audio_3d cr_default cr_none cr_arrow cr_cross cr_beam cr_size_nesw cr_size_ns cr_size_nwse cr_size_we cr_uparrow cr_hourglass cr_drag cr_appstart cr_handpoint cr_size_all spritespeed_framespersecond spritespeed_framespergameframe asset_object asset_unknown asset_sprite asset_sound asset_room asset_path asset_script asset_font asset_timeline asset_tiles asset_shader fa_readonly fa_hidden fa_sysfile fa_volumeid fa_directory fa_archive ds_type_map ds_type_list ds_type_stack ds_type_queue ds_type_grid ds_type_priority ef_explosion ef_ring ef_ellipse ef_firework ef_smoke ef_smokeup ef_star ef_spark ef_flare ef_cloud ef_rain ef_snow pt_shape_pixel pt_shape_disk pt_shape_square pt_shape_line pt_shape_star pt_shape_circle pt_shape_ring pt_shape_sphere pt_shape_flare pt_shape_spark pt_shape_explosion pt_shape_cloud pt_shape_smoke pt_shape_snow ps_distr_linear ps_distr_gaussian ps_distr_invgaussian ps_shape_rectangle ps_shape_ellipse ps_shape_diamond ps_shape_line ty_real ty_string dll_cdecl dll_stdcall matrix_view matrix_projection matrix_world os_win32 os_windows os_macosx os_ios os_android os_symbian os_linux os_unknown os_winphone os_tizen os_win8native os_wiiu os_3ds os_psvita os_bb10 os_ps4 os_xboxone os_ps3 os_xbox360 os_uwp os_tvos os_switch browser_not_a_browser browser_unknown browser_ie browser_firefox browser_chrome browser_safari browser_safari_mobile browser_opera browser_tizen browser_edge browser_windows_store browser_ie_mobile device_ios_unknown device_ios_iphone device_ios_iphone_retina device_ios_ipad device_ios_ipad_retina device_ios_iphone5 device_ios_iphone6 device_ios_iphone6plus device_emulator device_tablet display_landscape display_landscape_flipped display_portrait display_portrait_flipped tm_sleep tm_countvsyncs of_challenge_win of_challen ge_lose of_challenge_tie leaderboard_type_number leaderboard_type_time_mins_secs cmpfunc_never cmpfunc_less cmpfunc_equal cmpfunc_lessequal cmpfunc_greater cmpfunc_notequal cmpfunc_greaterequal cmpfunc_always cull_noculling cull_clockwise cull_counterclockwise lighttype_dir lighttype_point iap_ev_storeload iap_ev_product iap_ev_purchase iap_ev_consume iap_ev_restore iap_storeload_ok iap_storeload_failed iap_status_uninitialised iap_status_unavailable iap_status_loading iap_status_available iap_status_processing iap_status_restoring iap_failed iap_unavailable iap_available iap_purchased iap_canceled iap_refunded fb_login_default fb_login_fallback_to_webview fb_login_no_fallback_to_webview fb_login_forcing_webview fb_login_use_system_account fb_login_forcing_safari phy_joint_anchor_1_x phy_joint_anchor_1_y phy_joint_anchor_2_x phy_joint_anchor_2_y phy_joint_reaction_force_x phy_joint_reaction_force_y phy_joint_reaction_torque phy_joint_motor_speed phy_joint_angle phy_joint_motor_torque phy_joint_max_motor_torque phy_joint_translation phy_joint_speed phy_joint_motor_force phy_joint_max_motor_force phy_joint_length_1 phy_joint_length_2 phy_joint_damping_ratio phy_joint_frequency phy_joint_lower_angle_limit phy_joint_upper_angle_limit phy_joint_angle_limits phy_joint_max_length phy_joint_max_torque phy_joint_max_force phy_debug_render_aabb phy_debug_render_collision_pairs phy_debug_render_coms phy_debug_render_core_shapes phy_debug_render_joints phy_debug_render_obb phy_debug_render_shapes phy_particle_flag_water phy_particle_flag_zombie phy_particle_flag_wall phy_particle_flag_spring phy_particle_flag_elastic phy_particle_flag_viscous phy_particle_flag_powder phy_particle_flag_tensile phy_particle_flag_colourmixing phy_particle_flag_colormixing phy_particle_group_flag_solid phy_particle_group_flag_rigid phy_particle_data_flag_typeflags phy_particle_data_flag_position phy_particle_data_flag_velocity phy_particle_data_flag_colour phy_particle_data_flag_color phy_particle_data_flag_category achievement_our_info achievement_friends_info achievement_leaderboard_info achievement_achievement_info achievement_filter_all_players achievement_filter_friends_only achievement_filter_favorites_only achievement_type_achievement_challenge achievement_type_score_challenge achievement_pic_loaded achievement_show_ui achievement_show_profile achievement_show_leaderboard achievement_show_achievement achievement_show_bank achievement_show_friend_picker achievement_show_purchase_prompt network_socket_tcp network_socket_udp network_socket_bluetooth network_type_connect network_type_disconnect network_type_data network_type_non_blocking_connect network_config_connect_timeout network_config_use_non_blocking_socket network_config_enable_reliable_udp network_config_disable_reliable_udp buffer_fixed buffer_grow buffer_wrap buffer_fast buffer_vbuffer buffer_network buffer_u8 buffer_s8 buffer_u16 buffer_s16 buffer_u32 buffer_s32 buffer_u64 buffer_f16 buffer_f32 buffer_f64 buffer_bool buffer_text buffer_string buffer_surface_copy buffer_seek_start buffer_seek_relative buffer_seek_end buffer_generalerror buffer_outofspace buffer_outofbounds buffer_invalidtype text_type button_type input_type ANSI_CHARSET DEFAULT_CHARSET EASTEUROPE_CHARSET RUSSIAN_CHARSET SYMBOL_CHARSET SHIFTJIS_CHARSET HANGEUL_CHARSET GB2312_CHARSET CHINESEBIG5_CHARSET JOHAB_CHARSET HEBREW_CHARSET ARABIC_CHARSET GREEK_CHARSET TURKISH_CHARSET VIETNAMESE_CHARSET THAI_CHARSET MAC_CHARSET BALTIC_CHARSET OEM_CHARSET gp_face1 gp_face2 gp_face3 gp_face4 gp_shoulderl gp_shoulderr gp_shoulderlb gp_shoulderrb gp_select gp_start gp_stickl gp_stickr gp_padu gp_padd gp_padl gp_padr gp_axislh gp_axislv gp_axisrh gp_axisrv ov_friends ov_community ov_players ov_settings ov_gamegroup ov_achievements lb_sort_none lb_sort_ascending lb_sort_descending lb_disp_none lb_disp_numeric lb_disp_time_sec lb_disp_time_ms ugc_result_success ugc_filetype_community ugc_filetype_microtrans ugc_visibility_public ugc_visibility_friends_only ugc_visibility_private ugc_query_RankedByVote ugc_query_RankedByPublicationDate ugc_query_AcceptedForGameRankedByAcceptanceDate ugc_query_RankedByTrend ugc_query_FavoritedByFriendsRankedByPublicationDate ugc_query_CreatedByFriendsRankedByPublicationDate ugc_query_RankedByNumTimesReported ugc_query_CreatedByFollowedUsersRankedByPublicationDate ugc_query_NotYetRated ugc_query_RankedByTotalVotesAsc ugc_query_RankedByVotesUp ugc_query_RankedByTextSearch ugc_sortorder_CreationOrderDesc ugc_sortorder_CreationOrderAsc ugc_sortorder_TitleAsc ugc_sortorder_LastUpdatedDesc ugc_sortorder_SubscriptionDateDesc ugc_sortorder_VoteScoreDesc ugc_sortorder_ForModeration ugc_list_Published ugc_list_VotedOn ugc_list_VotedUp ugc_list_VotedDown ugc_list_WillVoteLater ugc_list_Favorited ugc_list_Subscribed ugc_list_UsedOrPlayed ugc_list_Followed ugc_match_Items ugc_match_Items_Mtx ugc_match_Items_ReadyToUse ugc_match_Collections ugc_match_Artwork ugc_match_Videos ugc_match_Screenshots ugc_match_AllGuides ugc_match_WebGuides ugc_match_IntegratedGuides ugc_match_UsableInGame ugc_match_ControllerBindings vertex_usage_position vertex_usage_colour vertex_usage_color vertex_usage_normal vertex_usage_texcoord vertex_usage_textcoord vertex_usage_blendweight vertex_usage_blendindices vertex_usage_psize vertex_usage_tangent vertex_usage_binormal vertex_usage_fog vertex_usage_depth vertex_usage_sample vertex_type_float1 vertex_type_float2 vertex_type_float3 vertex_type_float4 vertex_type_colour vertex_type_color vertex_type_ubyte4 layerelementtype_undefined layerelementtype_background layerelementtype_instance layerelementtype_oldtilemap layerelementtype_sprite layerelementtype_tilemap layerelementtype_particlesystem layerelementtype_tile tile_rotate tile_flip tile_mirror tile_index_mask kbv_type_default kbv_type_ascii kbv_type_url kbv_type_email kbv_type_numbers kbv_type_phone kbv_type_phone_name kbv_returnkey_default kbv_returnkey_go kbv_returnkey_google kbv_returnkey_join kbv_returnkey_next kbv_returnkey_route kbv_returnkey_search kbv_returnkey_send kbv_returnkey_yahoo kbv_returnkey_done kbv_returnkey_continue kbv_returnkey_emergency kbv_autocapitalize_none kbv_autocapitalize_words kbv_autocapitalize_sentences kbv_autocapitalize_characters","symbol":"argument_relative argument argument0 argument1 argument2 argument3 argument4 argument5 argument6 argument7 argument8 argument9 argument10 argument11 argument12 argument13 argument14 argument15 argument_count x y xprevious yprevious xstart ystart hspeed vspeed direction speed friction gravity gravity_direction path_index path_position path_positionprevious path_speed path_scale path_orientation path_endaction object_index id solid persistent mask_index instance_count instance_id room_speed fps fps_real current_time current_year current_month current_day current_weekday current_hour current_minute current_second alarm timeline_index timeline_position timeline_speed timeline_running timeline_loop room room_first room_last room_width room_height room_caption room_persistent score lives health show_score show_lives show_health caption_score caption_lives caption_health event_type event_number event_object event_action application_surface gamemaker_pro gamemaker_registered gamemaker_version error_occurred error_last debug_mode keyboard_key keyboard_lastkey keyboard_lastchar keyboard_string mouse_x mouse_y mouse_button mouse_lastbutton cursor_sprite visible sprite_index sprite_width sprite_height sprite_xoffset sprite_yoffset image_number image_index image_speed depth image_xscale image_yscale image_angle image_alpha image_blend bbox_left bbox_right bbox_top bbox_bottom layer background_colour background_showcolour background_color background_showcolor view_enabled view_current view_visible view_xview view_yview view_wview view_hview view_xport view_yport view_wport view_hport view_angle view_hborder view_vborder view_hspeed view_vspeed view_object view_surface_id view_camera game_id game_display_name game_project_name game_save_id working_directory temp_directory program_directory browser_width browser_height os_type os_device os_browser os_version display_aa async_load delta_time webgl_enabled event_data iap_data phy_rotation phy_position_x phy_position_y phy_angular_velocity phy_linear_velocity_x phy_linear_velocity_y phy_speed_x phy_speed_y phy_speed phy_angular_damping phy_linear_damping phy_bullet phy_fixed_rotation phy_active phy_mass phy_inertia phy_com_x phy_com_y phy_dynamic phy_kinematic phy_sleeping phy_collision_points phy_collision_x phy_collision_y phy_col_normal_x phy_col_normal_y phy_position_xprevious phy_position_yprevious"},"contains":[{"className":"comment","begin":"//","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"/\\*","end":"\\*/","contains":[{"$ref":"#contains.0.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"string","begin":"'","end":"'","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0}]},{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"$ref":"#contains.2.contains.0"}]},{"className":"number","begin":"(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)","relevance":0}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/go.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/go.json new file mode 100644 index 00000000..fe270e13 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/go.json @@ -0,0 +1 @@ +{"aliases":["golang"],"keywords":{"keyword":"break default func interface select case map struct chan else goto package switch const fallthrough if range type continue for import return var go defer bool byte complex64 complex128 float32 float64 int8 int16 int32 int64 string uint8 uint16 uint32 uint64 int uint uintptr rune","literal":"true false iota nil","built_in":"append cap close complex copy imag len make new panic print println real recover delete"},"illegal":"","end":",\\s+","returnBegin":true,"endsWithParent":true,"contains":[{"className":"attr","begin":":\\w+"},{"className":"string","begin":"'","end":"'","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0}]},{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"$ref":"#contains.3.contains.3.contains.0.contains.1.contains.0"}]},{"begin":"\\w+","relevance":0}]}]},{"begin":"\\(\\s*","end":"\\s*\\)","excludeEnd":true,"contains":[{"begin":"\\w+\\s*=","end":"\\s+","returnBegin":true,"endsWithParent":true,"contains":[{"className":"attr","begin":"\\w+","relevance":0},{"$ref":"#contains.3.contains.3.contains.0.contains.1"},{"$ref":"#contains.3.contains.3.contains.0.contains.2"},{"begin":"\\w+","relevance":0}]}]}]},{"begin":"^\\s*[=~]\\s*"},{"begin":"#{","starts":{"end":"}","subLanguage":"ruby"}}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/handlebars.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/handlebars.json new file mode 100644 index 00000000..32ac3867 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/handlebars.json @@ -0,0 +1 @@ +{"aliases":["hbs","html.hbs","html.handlebars"],"case_insensitive":true,"subLanguage":"xml","contains":[{"className":"comment","begin":"{{!(--)?","end":"(--)?}}","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"template-tag","begin":"\\{\\{[#\\/]","end":"\\}\\}","contains":[{"className":"name","begin":"[a-zA-Z\\.-]+","keywords":{"builtin-name":"each in with if else unless bindattr action collection debugger log outlet template unbound view yield"},"starts":{"endsWithParent":true,"relevance":0,"contains":[{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0}]}]}}]},{"className":"template-variable","begin":"\\{\\{","end":"\\}\\}","keywords":{"$ref":"#contains.1.contains.0.keywords"}}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/haskell.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/haskell.json new file mode 100644 index 00000000..005e728d --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/haskell.json @@ -0,0 +1 @@ +{"aliases":["hs"],"keywords":"let in if then else case of where do module import hiding qualified type data newtype deriving class instance as default infix infixl infixr foreign export ccall stdcall cplusplus jvm dotnet safe unsafe family forall mdo proc rec","contains":[{"beginKeywords":"module","end":"where","keywords":"module where","contains":[{"begin":"\\(","end":"\\)","illegal":"\"","contains":[{"className":"meta","begin":"{-#","end":"#-}"},{"className":"meta","begin":"^#","end":"$"},{"className":"type","begin":"\\b[A-Z][\\w]*(\\((\\.\\.|,|\\w+)\\))?"},{"className":"title","begin":"[_a-z][\\w']*","relevance":0},{"variants":[{"className":"comment","begin":"--","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"{-","end":"-}","contains":["self",{"$ref":"#contains.0.contains.0.contains.4.variants.0.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]}]}]},{"$ref":"#contains.0.contains.0.contains.4"}],"illegal":"\\W\\.|;"},{"begin":"\\bimport\\b","end":"$","keywords":"import qualified as hiding","contains":[{"$ref":"#contains.0.contains.0"},{"$ref":"#contains.0.contains.0.contains.4"}],"illegal":"\\W\\.|;"},{"className":"class","begin":"^(\\s*)?(class|instance)\\b","end":"where","keywords":"class family instance where","contains":[{"className":"type","begin":"\\b[A-Z][\\w']*","relevance":0},{"$ref":"#contains.0.contains.0"},{"$ref":"#contains.0.contains.0.contains.4"}]},{"className":"class","begin":"\\b(data|(new)?type)\\b","end":"$","keywords":"data family type newtype deriving","contains":[{"$ref":"#contains.0.contains.0.contains.0"},{"$ref":"#contains.2.contains.0"},{"$ref":"#contains.0.contains.0"},{"begin":"{","end":"}","contains":{"$ref":"#contains.0.contains.0.contains"}},{"$ref":"#contains.0.contains.0.contains.4"}]},{"beginKeywords":"default","end":"$","contains":[{"$ref":"#contains.2.contains.0"},{"$ref":"#contains.0.contains.0"},{"$ref":"#contains.0.contains.0.contains.4"}]},{"beginKeywords":"infix infixl infixr","end":"$","contains":[{"className":"number","begin":"(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)","relevance":0},{"$ref":"#contains.0.contains.0.contains.4"}]},{"begin":"\\bforeign\\b","end":"$","keywords":"foreign import export ccall stdcall cplusplus jvm dotnet safe unsafe","contains":[{"$ref":"#contains.2.contains.0"},{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0}]},{"$ref":"#contains.0.contains.0.contains.4"}]},{"className":"meta","begin":"#!\\/usr\\/bin\\/env runhaskell","end":"$"},{"$ref":"#contains.0.contains.0.contains.0"},{"$ref":"#contains.0.contains.0.contains.1"},{"$ref":"#contains.6.contains.1"},{"$ref":"#contains.5.contains.0"},{"$ref":"#contains.2.contains.0"},{"className":"title","begin":"^[_a-z][\\w']*","relevance":0},{"$ref":"#contains.0.contains.0.contains.4"},{"begin":"->|<-"}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/haxe.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/haxe.json new file mode 100644 index 00000000..7d5fd3d0 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/haxe.json @@ -0,0 +1 @@ +{"aliases":["hx"],"keywords":{"keyword":"break case cast catch continue default do dynamic else enum extern for function here if import in inline never new override package private get set public return static super switch this throw trace try typedef untyped using var while Int Float String Bool Dynamic Void Array ","built_in":"trace this","literal":"true false null _"},"contains":[{"className":"string","begin":"'","end":"'","contains":[{"begin":"\\\\[\\s\\S]","relevance":0},{"className":"subst","begin":"\\$\\{","end":"\\}"},{"className":"subst","begin":"\\$","end":"\\W}"}]},{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"$ref":"#contains.0.contains.0"}]},{"className":"comment","begin":"//","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"/\\*","end":"\\*/","contains":[{"$ref":"#contains.2.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"number","begin":"(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)","relevance":0},{"className":"meta","begin":"@:","end":"$"},{"className":"meta","begin":"#","end":"$","keywords":{"meta-keyword":"if else elseif end error"}},{"className":"type","begin":":[ \t]*","end":"[^A-Za-z0-9_ \t\\->]","excludeBegin":true,"excludeEnd":true,"relevance":0},{"className":"type","begin":":[ \t]*","end":"\\W","excludeBegin":true,"excludeEnd":true},{"className":"type","begin":"new *","end":"\\W","excludeBegin":true,"excludeEnd":true},{"className":"class","beginKeywords":"enum","end":"\\{","contains":[{"className":"title","begin":"[a-zA-Z]\\w*","relevance":0}]},{"className":"class","beginKeywords":"abstract","end":"[\\{$]","contains":[{"className":"type","begin":"\\(","end":"\\)","excludeBegin":true,"excludeEnd":true},{"className":"type","begin":"from +","end":"\\W","excludeBegin":true,"excludeEnd":true},{"className":"type","begin":"to +","end":"\\W","excludeBegin":true,"excludeEnd":true},{"$ref":"#contains.10.contains.0"}],"keywords":{"keyword":"abstract from to"}},{"className":"class","begin":"\\b(class|interface) +","end":"[\\{$]","excludeEnd":true,"keywords":"class interface","contains":[{"className":"keyword","begin":"\\b(extends|implements) +","keywords":"extends implements","contains":[{"className":"type","begin":"[a-zA-Z]\\w*","relevance":0}]},{"$ref":"#contains.10.contains.0"}]},{"className":"function","beginKeywords":"function","end":"\\(","excludeEnd":true,"illegal":"\\S","contains":[{"$ref":"#contains.10.contains.0"}]}],"illegal":"<\\/"} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/hsp.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/hsp.json new file mode 100644 index 00000000..3fb73951 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/hsp.json @@ -0,0 +1 @@ +{"case_insensitive":true,"lexemes":"[\\w\\._]+","keywords":"goto gosub return break repeat loop continue wait await dim sdim foreach dimtype dup dupptr end stop newmod delmod mref run exgoto on mcall assert logmes newlab resume yield onexit onerror onkey onclick oncmd exist delete mkdir chdir dirlist bload bsave bcopy memfile if else poke wpoke lpoke getstr chdpm memexpand memcpy memset notesel noteadd notedel noteload notesave randomize noteunsel noteget split strrep setease button chgdisp exec dialog mmload mmplay mmstop mci pset pget syscolor mes print title pos circle cls font sysfont objsize picload color palcolor palette redraw width gsel gcopy gzoom gmode bmpsave hsvcolor getkey listbox chkbox combox input mesbox buffer screen bgscr mouse objsel groll line clrobj boxf objprm objmode stick grect grotate gsquare gradf objimage objskip objenable celload celdiv celput newcom querycom delcom cnvstow comres axobj winobj sendmsg comevent comevarg sarrayconv callfunc cnvwtos comevdisp libptr system hspstat hspver stat cnt err strsize looplev sublev iparam wparam lparam refstr refdval int rnd strlen length length2 length3 length4 vartype gettime peek wpeek lpeek varptr varuse noteinfo instr abs limit getease str strmid strf getpath strtrim sin cos tan atan sqrt double absf expf logf limitf powf geteasef mousex mousey mousew hwnd hinstance hdc ginfo objinfo dirinfo sysinfo thismod __hspver__ __hsp30__ __date__ __time__ __line__ __file__ _debug __hspdef__ and or xor not screen_normal screen_palette screen_hide screen_fixedsize screen_tool screen_frame gmode_gdi gmode_mem gmode_rgb0 gmode_alpha gmode_rgb0alpha gmode_add gmode_sub gmode_pixela ginfo_mx ginfo_my ginfo_act ginfo_sel ginfo_wx1 ginfo_wy1 ginfo_wx2 ginfo_wy2 ginfo_vx ginfo_vy ginfo_sizex ginfo_sizey ginfo_winx ginfo_winy ginfo_mesx ginfo_mesy ginfo_r ginfo_g ginfo_b ginfo_paluse ginfo_dispx ginfo_dispy ginfo_cx ginfo_cy ginfo_intid ginfo_newid ginfo_sx ginfo_sy objinfo_mode objinfo_bmscr objinfo_hwnd notemax notesize dir_cur dir_exe dir_win dir_sys dir_cmdline dir_desktop dir_mydoc dir_tv font_normal font_bold font_italic font_underline font_strikeout font_antialias objmode_normal objmode_guifont objmode_usefont gsquare_grad msgothic msmincho do until while wend for next _break _continue switch case default swbreak swend ddim ldim alloc m_pi rad2deg deg2rad ease_linear ease_quad_in ease_quad_out ease_quad_inout ease_cubic_in ease_cubic_out ease_cubic_inout ease_quartic_in ease_quartic_out ease_quartic_inout ease_bounce_in ease_bounce_out ease_bounce_inout ease_shake_in ease_shake_out ease_shake_inout ease_loop","contains":[{"className":"comment","begin":"//","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"/\\*","end":"\\*/","contains":[{"$ref":"#contains.0.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0}]},{"className":"string","begin":"'","end":"'","illegal":"\\n","contains":[{"$ref":"#contains.2.contains.0"}]},{"className":"string","begin":"{\"","end":"\"}","contains":[{"$ref":"#contains.2.contains.0"}]},{"className":"comment","begin":";","end":"$","contains":[{"$ref":"#contains.0.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}],"relevance":0},{"className":"meta","begin":"#","end":"$","keywords":{"meta-keyword":"addion cfunc cmd cmpopt comfunc const defcfunc deffunc define else endif enum epack func global if ifdef ifndef include modcfunc modfunc modinit modterm module pack packopt regcmd runtime undef usecom uselib"},"contains":[{"className":"meta-string","begin":"\"","end":"\"","illegal":"\\n","contains":{"$ref":"#contains.2.contains"}},{"className":"number","begin":"\\b\\d+(\\.\\d+)?","relevance":0},{"className":"number","begin":"(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)","relevance":0},{"$ref":"#contains.0"},{"$ref":"#contains.1"}]},{"className":"symbol","begin":"^\\*(\\w+|@)"},{"$ref":"#contains.6.contains.1"},{"$ref":"#contains.6.contains.2"}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/htmlbars.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/htmlbars.json new file mode 100644 index 00000000..af7e81bb --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/htmlbars.json @@ -0,0 +1 @@ +{"case_insensitive":true,"subLanguage":"xml","contains":[{"className":"comment","begin":"{{!(--)?","end":"(--)?}}","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"template-tag","begin":"\\{\\{[#\\/]","end":"\\}\\}","contains":[{"className":"name","begin":"[a-zA-Z\\.\\-]+","keywords":{"builtin-name":"action collection component concat debugger each each-in else get hash if input link-to loc log mut outlet partial query-params render textarea unbound unless with yield view"},"starts":{"endsWithParent":true,"relevance":0,"keywords":{"keyword":"as","built_in":"action collection component concat debugger each each-in else get hash if input link-to loc log mut outlet partial query-params render textarea unbound unless with yield view"},"contains":[{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0}]},{"illegal":"\\}\\}","begin":"[a-zA-Z0-9_]+=","returnBegin":true,"relevance":0,"contains":[{"className":"attr","begin":"[a-zA-Z0-9_]+"}]},{"className":"number","begin":"\\b\\d+(\\.\\d+)?","relevance":0}]}}]},{"className":"template-variable","begin":"\\{\\{[a-zA-Z][a-zA-Z\\-]+","end":"\\}\\}","keywords":{"keyword":"as","built_in":"action collection component concat debugger each each-in else get hash if input link-to loc log mut outlet partial query-params render textarea unbound unless with yield view"},"contains":[{"$ref":"#contains.1.contains.0.starts.contains.0"}]}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/http.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/http.json new file mode 100644 index 00000000..f80cb066 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/http.json @@ -0,0 +1 @@ +{"aliases":["https"],"illegal":"\\S","contains":[{"begin":"^HTTP/[0-9\\.]+","end":"$","contains":[{"className":"number","begin":"\\b\\d{3}\\b"}]},{"begin":"^[A-Z]+ (.*?) HTTP/[0-9\\.]+$","returnBegin":true,"end":"$","contains":[{"className":"string","begin":" ","end":" ","excludeBegin":true,"excludeEnd":true},{"begin":"HTTP/[0-9\\.]+"},{"className":"keyword","begin":"[A-Z]+"}]},{"className":"attribute","begin":"^\\w","end":": ","excludeEnd":true,"illegal":"\\n|\\s|=","starts":{"end":"$","relevance":0}},{"begin":"\\n\\n","starts":{"subLanguage":[],"endsWithParent":true}}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/hy.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/hy.json new file mode 100644 index 00000000..db024fa7 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/hy.json @@ -0,0 +1 @@ +{"aliases":["hylang"],"illegal":"\\S","contains":[{"className":"meta","begin":"^#!","end":"$"},{"begin":"\\(","end":"\\)","contains":[{"className":"comment","begin":"comment","end":"","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"keywords":{"builtin-name":"!= % %= & &= * ** **= *= *map + += , --build-class-- --import-- -= . / // //= /= < << <<= <= = > >= >> >>= @ @= ^ ^= abs accumulate all and any ap-compose ap-dotimes ap-each ap-each-while ap-filter ap-first ap-if ap-last ap-map ap-map-when ap-pipe ap-reduce ap-reject apply as-> ascii assert assoc bin break butlast callable calling-module-name car case cdr chain chr coll? combinations compile compress cond cons cons? continue count curry cut cycle dec def default-method defclass defmacro defmacro-alias defmacro/g! defmain defmethod defmulti defn defn-alias defnc defnr defreader defseq del delattr delete-route dict-comp dir disassemble dispatch-reader-macro distinct divmod do doto drop drop-last drop-while empty? end-sequence eval eval-and-compile eval-when-compile even? every? except exec filter first flatten float? fn fnc fnr for for* format fraction genexpr gensym get getattr global globals group-by hasattr hash hex id identity if if* if-not if-python2 import in inc input instance? integer integer-char? integer? interleave interpose is is-coll is-cons is-empty is-even is-every is-float is-instance is-integer is-integer-char is-iterable is-iterator is-keyword is-neg is-none is-not is-numeric is-odd is-pos is-string is-symbol is-zero isinstance islice issubclass iter iterable? iterate iterator? keyword keyword? lambda last len let lif lif-not list* list-comp locals loop macro-error macroexpand macroexpand-1 macroexpand-all map max merge-with method-decorator min multi-decorator multicombinations name neg? next none? nonlocal not not-in not? nth numeric? oct odd? open or ord partition permutations pos? post-route postwalk pow prewalk print product profile/calls profile/cpu put-route quasiquote quote raise range read read-str recursive-replace reduce remove repeat repeatedly repr require rest round route route-with-methods rwm second seq set-comp setattr setv some sorted string string? sum switch symbol? take take-nth take-while tee try unless unquote unquote-splicing vars walk when while with with* with-decorator with-gensyms xi xor yield yield-from zero? zip zip-longest | |= ~"},"lexemes":"[a-zA-Z_\\-!.?+*=<>&#'][a-zA-Z_\\-!.?+*=<>&#'0-9/;:]*","className":"name","begin":"[a-zA-Z_\\-!.?+*=<>&#'][a-zA-Z_\\-!.?+*=<>&#'0-9/;:]*","starts":{"endsWithParent":true,"relevance":0,"contains":[{"$ref":"#contains.1"},{"className":"string","begin":"\"","end":"\"","illegal":null,"contains":[{"begin":"\\\\[\\s\\S]","relevance":0}]},{"className":"comment","begin":"\\^[a-zA-Z_\\-!.?+*=<>&#'][a-zA-Z_\\-!.?+*=<>&#'0-9/;:]*"},{"className":"comment","begin":"\\^\\{","end":"\\}","contains":[{"$ref":"#contains.1.contains.0.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":";","end":"$","contains":[{"$ref":"#contains.1.contains.0.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}],"relevance":0},{"className":"symbol","begin":"[:]{1,2}[a-zA-Z_\\-!.?+*=<>&#'][a-zA-Z_\\-!.?+*=<>&#'0-9/;:]*"},{"begin":"[\\[\\{]","end":"[\\]\\}]","contains":{"$ref":"#contains.1.contains.1.starts.contains"}},{"className":"number","begin":"[-+]?\\d+(\\.\\d+)?","relevance":0},{"className":"literal","begin":"\\b([Tt]rue|[Ff]alse|nil|None)\\b"},{"begin":"[a-zA-Z_\\-!.?+*=<>&#'][a-zA-Z_\\-!.?+*=<>&#'0-9/;:]*","relevance":0}]}},{"$ref":"#contains.1.contains.1.starts"}]},{"$ref":"#contains.1.contains.1.starts.contains.1"},{"$ref":"#contains.1.contains.1.starts.contains.2"},{"$ref":"#contains.1.contains.1.starts.contains.3"},{"$ref":"#contains.1.contains.1.starts.contains.4"},{"$ref":"#contains.1.contains.1.starts.contains.5"},{"$ref":"#contains.1.contains.1.starts.contains.6"},{"$ref":"#contains.1.contains.1.starts.contains.7"},{"$ref":"#contains.1.contains.1.starts.contains.8"}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/inform7.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/inform7.json new file mode 100644 index 00000000..8c43d6ba --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/inform7.json @@ -0,0 +1 @@ +{"aliases":["i7"],"case_insensitive":true,"keywords":{"keyword":"thing room person man woman animal container supporter backdrop door scenery open closed locked inside gender is are say understand kind of rule"},"contains":[{"className":"string","begin":"\"","end":"\"","relevance":0,"contains":[{"className":"subst","begin":"\\[","end":"\\]"}]},{"className":"section","begin":"^(Volume|Book|Part|Chapter|Section|Table)\\b","end":"$"},{"begin":"^(Check|Carry out|Report|Instead of|To|Rule|When|Before|After)\\b","end":":","contains":[{"begin":"\\(This","end":"\\)"}]},{"className":"comment","begin":"\\[","end":"\\]","contains":["self"]}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/ini.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/ini.json new file mode 100644 index 00000000..7992519f --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/ini.json @@ -0,0 +1 @@ +{"aliases":["toml"],"case_insensitive":true,"illegal":"\\S","contains":[{"className":"comment","begin":";","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"#","end":"$","contains":[{"$ref":"#contains.0.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"section","begin":"^\\s*\\[+","end":"\\]+"},{"begin":"^[a-z0-9\\[\\]_\\.-]+\\s*=\\s*","end":"$","returnBegin":true,"contains":[{"className":"attr","begin":"[a-z0-9\\[\\]_\\.-]+"},{"begin":"=","endsWithParent":true,"relevance":0,"contains":[{"className":"comment","begin":";","end":"$","contains":[{"$ref":"#contains.0.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"$ref":"#contains.1"},{"className":"literal","begin":"\\bon|off|true|false|yes|no\\b"},{"className":"variable","variants":[{"begin":"\\$[\\w\\d\"][\\w\\d_]*"},{"begin":"\\$\\{(.*?)}"}]},{"className":"string","contains":[{"begin":"\\\\[\\s\\S]","relevance":0}],"variants":[{"begin":"'''","end":"'''","relevance":10},{"begin":"\"\"\"","end":"\"\"\"","relevance":10},{"begin":"\"","end":"\""},{"begin":"'","end":"'"}]},{"className":"number","begin":"([\\+\\-]+)?[\\d]+_[\\d_]+"},{"className":"number","begin":"\\b\\d+(\\.\\d+)?","relevance":0}]}]}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/irpf90.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/irpf90.json new file mode 100644 index 00000000..9fd83ac2 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/irpf90.json @@ -0,0 +1 @@ +{"case_insensitive":true,"keywords":{"literal":".False. .True.","keyword":"kind do while private call intrinsic where elsewhere type endtype endmodule endselect endinterface end enddo endif if forall endforall only contains default return stop then public subroutine|10 function program .and. .or. .not. .le. .eq. .ge. .gt. .lt. goto save else use module select case access blank direct exist file fmt form formatted iostat name named nextrec number opened rec recl sequential status unformatted unit continue format pause cycle exit c_null_char c_alert c_backspace c_form_feed flush wait decimal round iomsg synchronous nopass non_overridable pass protected volatile abstract extends import non_intrinsic value deferred generic final enumerator class associate bind enum c_int c_short c_long c_long_long c_signed_char c_size_t c_int8_t c_int16_t c_int32_t c_int64_t c_int_least8_t c_int_least16_t c_int_least32_t c_int_least64_t c_int_fast8_t c_int_fast16_t c_int_fast32_t c_int_fast64_t c_intmax_t C_intptr_t c_float c_double c_long_double c_float_complex c_double_complex c_long_double_complex c_bool c_char c_null_ptr c_null_funptr c_new_line c_carriage_return c_horizontal_tab c_vertical_tab iso_c_binding c_loc c_funloc c_associated c_f_pointer c_ptr c_funptr iso_fortran_env character_storage_size error_unit file_storage_size input_unit iostat_end iostat_eor numeric_storage_size output_unit c_f_procpointer ieee_arithmetic ieee_support_underflow_control ieee_get_underflow_mode ieee_set_underflow_mode newunit contiguous recursive pad position action delim readwrite eor advance nml interface procedure namelist include sequence elemental pure integer real character complex logical dimension allocatable|10 parameter external implicit|10 none double precision assign intent optional pointer target in out common equivalence data begin_provider &begin_provider end_provider begin_shell end_shell begin_template end_template subst assert touch soft_touch provide no_dep free irp_if irp_else irp_endif irp_write irp_read","built_in":"alog alog10 amax0 amax1 amin0 amin1 amod cabs ccos cexp clog csin csqrt dabs dacos dasin datan datan2 dcos dcosh ddim dexp dint dlog dlog10 dmax1 dmin1 dmod dnint dsign dsin dsinh dsqrt dtan dtanh float iabs idim idint idnint ifix isign max0 max1 min0 min1 sngl algama cdabs cdcos cdexp cdlog cdsin cdsqrt cqabs cqcos cqexp cqlog cqsin cqsqrt dcmplx dconjg derf derfc dfloat dgamma dimag dlgama iqint qabs qacos qasin qatan qatan2 qcmplx qconjg qcos qcosh qdim qerf qerfc qexp qgamma qimag qlgama qlog qlog10 qmax1 qmin1 qmod qnint qsign qsin qsinh qsqrt qtan qtanh abs acos aimag aint anint asin atan atan2 char cmplx conjg cos cosh exp ichar index int log log10 max min nint sign sin sinh sqrt tan tanh print write dim lge lgt lle llt mod nullify allocate deallocate adjustl adjustr all allocated any associated bit_size btest ceiling count cshift date_and_time digits dot_product eoshift epsilon exponent floor fraction huge iand ibclr ibits ibset ieor ior ishft ishftc lbound len_trim matmul maxexponent maxloc maxval merge minexponent minloc minval modulo mvbits nearest pack present product radix random_number random_seed range repeat reshape rrspacing scale scan selected_int_kind selected_real_kind set_exponent shape size spacing spread sum system_clock tiny transpose trim ubound unpack verify achar iachar transfer dble entry dprod cpu_time command_argument_count get_command get_command_argument get_environment_variable is_iostat_end ieee_arithmetic ieee_support_underflow_control ieee_get_underflow_mode ieee_set_underflow_mode is_iostat_eor move_alloc new_line selected_char_kind same_type_as extends_type_ofacosh asinh atanh bessel_j0 bessel_j1 bessel_jn bessel_y0 bessel_y1 bessel_yn erf erfc erfc_scaled gamma log_gamma hypot norm2 atomic_define atomic_ref execute_command_line leadz trailz storage_size merge_bits bge bgt ble blt dshiftl dshiftr findloc iall iany iparity image_index lcobound ucobound maskl maskr num_images parity popcnt poppar shifta shiftl shiftr this_image IRP_ALIGN irp_here"},"illegal":"\\/\\*","contains":[{"className":"string","begin":"'","end":"'","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0}],"relevance":0},{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"$ref":"#contains.0.contains.0"}],"relevance":0},{"className":"function","beginKeywords":"subroutine function program","illegal":"[${=\\n]","contains":[{"className":"title","begin":"[a-zA-Z_]\\w*","relevance":0},{"className":"params","begin":"\\(","end":"\\)"}]},{"className":"comment","begin":"!","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}],"relevance":0},{"className":"comment","begin":"begin_doc","end":"end_doc","contains":[{"$ref":"#contains.3.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}],"relevance":10},{"className":"number","begin":"(?=\\b|\\+|\\-|\\.)(?=\\.\\d|\\d)(?:\\d+)?(?:\\.?\\d*)(?:[de][+-]?\\d+)?\\b\\.?","relevance":0}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/isbl.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/isbl.json new file mode 100644 index 00000000..b7c2d20e --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/isbl.json @@ -0,0 +1 @@ +{"aliases":["isbl"],"case_insensitive":true,"lexemes":"[A-Za-zА-Яа-яёЁ_!][A-Za-zА-Яа-яёЁ_0-9]*","keywords":{"keyword":"and и else иначе endexcept endfinally endforeach конецвсе endif конецесли endwhile конецпока except exitfor finally foreach все if если in в not не or или try while пока ","built_in":"SYSRES_CONST_ACCES_RIGHT_TYPE_EDIT SYSRES_CONST_ACCES_RIGHT_TYPE_FULL SYSRES_CONST_ACCES_RIGHT_TYPE_VIEW SYSRES_CONST_ACCESS_MODE_REQUISITE_CODE SYSRES_CONST_ACCESS_NO_ACCESS_VIEW SYSRES_CONST_ACCESS_NO_ACCESS_VIEW_CODE SYSRES_CONST_ACCESS_RIGHTS_ADD_REQUISITE_CODE SYSRES_CONST_ACCESS_RIGHTS_ADD_REQUISITE_YES_CODE SYSRES_CONST_ACCESS_RIGHTS_CHANGE_REQUISITE_CODE SYSRES_CONST_ACCESS_RIGHTS_CHANGE_REQUISITE_YES_CODE SYSRES_CONST_ACCESS_RIGHTS_DELETE_REQUISITE_CODE SYSRES_CONST_ACCESS_RIGHTS_DELETE_REQUISITE_YES_CODE SYSRES_CONST_ACCESS_RIGHTS_EXECUTE_REQUISITE_CODE SYSRES_CONST_ACCESS_RIGHTS_EXECUTE_REQUISITE_YES_CODE SYSRES_CONST_ACCESS_RIGHTS_NO_ACCESS_REQUISITE_CODE SYSRES_CONST_ACCESS_RIGHTS_NO_ACCESS_REQUISITE_YES_CODE SYSRES_CONST_ACCESS_RIGHTS_RATIFY_REQUISITE_CODE SYSRES_CONST_ACCESS_RIGHTS_RATIFY_REQUISITE_YES_CODE SYSRES_CONST_ACCESS_RIGHTS_REQUISITE_CODE SYSRES_CONST_ACCESS_RIGHTS_VIEW SYSRES_CONST_ACCESS_RIGHTS_VIEW_CODE SYSRES_CONST_ACCESS_RIGHTS_VIEW_REQUISITE_CODE SYSRES_CONST_ACCESS_RIGHTS_VIEW_REQUISITE_YES_CODE SYSRES_CONST_ACCESS_TYPE_CHANGE SYSRES_CONST_ACCESS_TYPE_CHANGE_CODE SYSRES_CONST_ACCESS_TYPE_EXISTS SYSRES_CONST_ACCESS_TYPE_EXISTS_CODE SYSRES_CONST_ACCESS_TYPE_FULL SYSRES_CONST_ACCESS_TYPE_FULL_CODE SYSRES_CONST_ACCESS_TYPE_VIEW SYSRES_CONST_ACCESS_TYPE_VIEW_CODE SYSRES_CONST_ACTION_TYPE_ABORT SYSRES_CONST_ACTION_TYPE_ACCEPT SYSRES_CONST_ACTION_TYPE_ACCESS_RIGHTS SYSRES_CONST_ACTION_TYPE_ADD_ATTACHMENT SYSRES_CONST_ACTION_TYPE_CHANGE_CARD SYSRES_CONST_ACTION_TYPE_CHANGE_KIND SYSRES_CONST_ACTION_TYPE_CHANGE_STORAGE SYSRES_CONST_ACTION_TYPE_CONTINUE SYSRES_CONST_ACTION_TYPE_COPY SYSRES_CONST_ACTION_TYPE_CREATE SYSRES_CONST_ACTION_TYPE_CREATE_VERSION SYSRES_CONST_ACTION_TYPE_DELETE SYSRES_CONST_ACTION_TYPE_DELETE_ATTACHMENT SYSRES_CONST_ACTION_TYPE_DELETE_VERSION SYSRES_CONST_ACTION_TYPE_DISABLE_DELEGATE_ACCESS_RIGHTS SYSRES_CONST_ACTION_TYPE_ENABLE_DELEGATE_ACCESS_RIGHTS SYSRES_CONST_ACTION_TYPE_ENCRYPTION_BY_CERTIFICATE SYSRES_CONST_ACTION_TYPE_ENCRYPTION_BY_CERTIFICATE_AND_PASSWORD SYSRES_CONST_ACTION_TYPE_ENCRYPTION_BY_PASSWORD SYSRES_CONST_ACTION_TYPE_EXPORT_WITH_LOCK SYSRES_CONST_ACTION_TYPE_EXPORT_WITHOUT_LOCK SYSRES_CONST_ACTION_TYPE_IMPORT_WITH_UNLOCK SYSRES_CONST_ACTION_TYPE_IMPORT_WITHOUT_UNLOCK SYSRES_CONST_ACTION_TYPE_LIFE_CYCLE_STAGE SYSRES_CONST_ACTION_TYPE_LOCK SYSRES_CONST_ACTION_TYPE_LOCK_FOR_SERVER SYSRES_CONST_ACTION_TYPE_LOCK_MODIFY SYSRES_CONST_ACTION_TYPE_MARK_AS_READED SYSRES_CONST_ACTION_TYPE_MARK_AS_UNREADED SYSRES_CONST_ACTION_TYPE_MODIFY SYSRES_CONST_ACTION_TYPE_MODIFY_CARD SYSRES_CONST_ACTION_TYPE_MOVE_TO_ARCHIVE SYSRES_CONST_ACTION_TYPE_OFF_ENCRYPTION SYSRES_CONST_ACTION_TYPE_PASSWORD_CHANGE SYSRES_CONST_ACTION_TYPE_PERFORM SYSRES_CONST_ACTION_TYPE_RECOVER_FROM_LOCAL_COPY SYSRES_CONST_ACTION_TYPE_RESTART SYSRES_CONST_ACTION_TYPE_RESTORE_FROM_ARCHIVE SYSRES_CONST_ACTION_TYPE_REVISION SYSRES_CONST_ACTION_TYPE_SEND_BY_MAIL SYSRES_CONST_ACTION_TYPE_SIGN SYSRES_CONST_ACTION_TYPE_START SYSRES_CONST_ACTION_TYPE_UNLOCK SYSRES_CONST_ACTION_TYPE_UNLOCK_FROM_SERVER SYSRES_CONST_ACTION_TYPE_VERSION_STATE SYSRES_CONST_ACTION_TYPE_VERSION_VISIBILITY SYSRES_CONST_ACTION_TYPE_VIEW SYSRES_CONST_ACTION_TYPE_VIEW_SHADOW_COPY SYSRES_CONST_ACTION_TYPE_WORKFLOW_DESCRIPTION_MODIFY SYSRES_CONST_ACTION_TYPE_WRITE_HISTORY SYSRES_CONST_ACTIVE_VERSION_STATE_PICK_VALUE SYSRES_CONST_ADD_REFERENCE_MODE_NAME SYSRES_CONST_ADDITION_REQUISITE_CODE SYSRES_CONST_ADDITIONAL_PARAMS_REQUISITE_CODE SYSRES_CONST_ADITIONAL_JOB_END_DATE_REQUISITE_NAME SYSRES_CONST_ADITIONAL_JOB_READ_REQUISITE_NAME SYSRES_CONST_ADITIONAL_JOB_START_DATE_REQUISITE_NAME SYSRES_CONST_ADITIONAL_JOB_STATE_REQUISITE_NAME SYSRES_CONST_ADMINISTRATION_HISTORY_ADDING_USER_TO_GROUP_ACTION SYSRES_CONST_ADMINISTRATION_HISTORY_ADDING_USER_TO_GROUP_ACTION_CODE SYSRES_CONST_ADMINISTRATION_HISTORY_CREATION_COMP_ACTION SYSRES_CONST_ADMINISTRATION_HISTORY_CREATION_COMP_ACTION_CODE SYSRES_CONST_ADMINISTRATION_HISTORY_CREATION_GROUP_ACTION SYSRES_CONST_ADMINISTRATION_HISTORY_CREATION_GROUP_ACTION_CODE SYSRES_CONST_ADMINISTRATION_HISTORY_CREATION_USER_ACTION SYSRES_CONST_ADMINISTRATION_HISTORY_CREATION_USER_ACTION_CODE SYSRES_CONST_ADMINISTRATION_HISTORY_DATABASE_USER_CREATION SYSRES_CONST_ADMINISTRATION_HISTORY_DATABASE_USER_CREATION_ACTION SYSRES_CONST_ADMINISTRATION_HISTORY_DATABASE_USER_DELETION SYSRES_CONST_ADMINISTRATION_HISTORY_DATABASE_USER_DELETION_ACTION SYSRES_CONST_ADMINISTRATION_HISTORY_DELETION_COMP_ACTION SYSRES_CONST_ADMINISTRATION_HISTORY_DELETION_COMP_ACTION_CODE SYSRES_CONST_ADMINISTRATION_HISTORY_DELETION_GROUP_ACTION SYSRES_CONST_ADMINISTRATION_HISTORY_DELETION_GROUP_ACTION_CODE SYSRES_CONST_ADMINISTRATION_HISTORY_DELETION_USER_ACTION SYSRES_CONST_ADMINISTRATION_HISTORY_DELETION_USER_ACTION_CODE SYSRES_CONST_ADMINISTRATION_HISTORY_DELETION_USER_FROM_GROUP_ACTION SYSRES_CONST_ADMINISTRATION_HISTORY_DELETION_USER_FROM_GROUP_ACTION_CODE SYSRES_CONST_ADMINISTRATION_HISTORY_GRANTING_FILTERER_ACTION SYSRES_CONST_ADMINISTRATION_HISTORY_GRANTING_FILTERER_ACTION_CODE SYSRES_CONST_ADMINISTRATION_HISTORY_GRANTING_FILTERER_RESTRICTION_ACTION SYSRES_CONST_ADMINISTRATION_HISTORY_GRANTING_FILTERER_RESTRICTION_ACTION_CODE SYSRES_CONST_ADMINISTRATION_HISTORY_GRANTING_PRIVILEGE_ACTION SYSRES_CONST_ADMINISTRATION_HISTORY_GRANTING_PRIVILEGE_ACTION_CODE SYSRES_CONST_ADMINISTRATION_HISTORY_GRANTING_RIGHTS_ACTION SYSRES_CONST_ADMINISTRATION_HISTORY_GRANTING_RIGHTS_ACTION_CODE SYSRES_CONST_ADMINISTRATION_HISTORY_IS_MAIN_SERVER_CHANGED_ACTION SYSRES_CONST_ADMINISTRATION_HISTORY_IS_MAIN_SERVER_CHANGED_ACTION_CODE SYSRES_CONST_ADMINISTRATION_HISTORY_IS_PUBLIC_CHANGED_ACTION SYSRES_CONST_ADMINISTRATION_HISTORY_IS_PUBLIC_CHANGED_ACTION_CODE SYSRES_CONST_ADMINISTRATION_HISTORY_REMOVING_FILTERER_ACTION SYSRES_CONST_ADMINISTRATION_HISTORY_REMOVING_FILTERER_ACTION_CODE SYSRES_CONST_ADMINISTRATION_HISTORY_REMOVING_FILTERER_RESTRICTION_ACTION SYSRES_CONST_ADMINISTRATION_HISTORY_REMOVING_FILTERER_RESTRICTION_ACTION_CODE SYSRES_CONST_ADMINISTRATION_HISTORY_REMOVING_PRIVILEGE_ACTION SYSRES_CONST_ADMINISTRATION_HISTORY_REMOVING_PRIVILEGE_ACTION_CODE SYSRES_CONST_ADMINISTRATION_HISTORY_REMOVING_RIGHTS_ACTION SYSRES_CONST_ADMINISTRATION_HISTORY_REMOVING_RIGHTS_ACTION_CODE SYSRES_CONST_ADMINISTRATION_HISTORY_SERVER_LOGIN_CREATION SYSRES_CONST_ADMINISTRATION_HISTORY_SERVER_LOGIN_CREATION_ACTION SYSRES_CONST_ADMINISTRATION_HISTORY_SERVER_LOGIN_DELETION SYSRES_CONST_ADMINISTRATION_HISTORY_SERVER_LOGIN_DELETION_ACTION SYSRES_CONST_ADMINISTRATION_HISTORY_UPDATING_CATEGORY_ACTION SYSRES_CONST_ADMINISTRATION_HISTORY_UPDATING_CATEGORY_ACTION_CODE SYSRES_CONST_ADMINISTRATION_HISTORY_UPDATING_COMP_TITLE_ACTION SYSRES_CONST_ADMINISTRATION_HISTORY_UPDATING_COMP_TITLE_ACTION_CODE SYSRES_CONST_ADMINISTRATION_HISTORY_UPDATING_FULL_NAME_ACTION SYSRES_CONST_ADMINISTRATION_HISTORY_UPDATING_FULL_NAME_ACTION_CODE SYSRES_CONST_ADMINISTRATION_HISTORY_UPDATING_GROUP_ACTION SYSRES_CONST_ADMINISTRATION_HISTORY_UPDATING_GROUP_ACTION_CODE SYSRES_CONST_ADMINISTRATION_HISTORY_UPDATING_PARENT_GROUP_ACTION SYSRES_CONST_ADMINISTRATION_HISTORY_UPDATING_PARENT_GROUP_ACTION_CODE SYSRES_CONST_ADMINISTRATION_HISTORY_UPDATING_USER_AUTH_TYPE_ACTION SYSRES_CONST_ADMINISTRATION_HISTORY_UPDATING_USER_AUTH_TYPE_ACTION_CODE SYSRES_CONST_ADMINISTRATION_HISTORY_UPDATING_USER_LOGIN_ACTION SYSRES_CONST_ADMINISTRATION_HISTORY_UPDATING_USER_LOGIN_ACTION_CODE SYSRES_CONST_ADMINISTRATION_HISTORY_UPDATING_USER_STATUS_ACTION SYSRES_CONST_ADMINISTRATION_HISTORY_UPDATING_USER_STATUS_ACTION_CODE SYSRES_CONST_ADMINISTRATION_HISTORY_USER_PASSWORD_CHANGE SYSRES_CONST_ADMINISTRATION_HISTORY_USER_PASSWORD_CHANGE_ACTION SYSRES_CONST_ALL_ACCEPT_CONDITION_RUS SYSRES_CONST_ALL_USERS_GROUP SYSRES_CONST_ALL_USERS_GROUP_NAME SYSRES_CONST_ALL_USERS_SERVER_GROUP_NAME SYSRES_CONST_ALLOWED_ACCESS_TYPE_CODE SYSRES_CONST_ALLOWED_ACCESS_TYPE_NAME SYSRES_CONST_APP_VIEWER_TYPE_REQUISITE_CODE SYSRES_CONST_APPROVING_SIGNATURE_NAME SYSRES_CONST_APPROVING_SIGNATURE_REQUISITE_CODE SYSRES_CONST_ASSISTANT_SUBSTITUE_TYPE SYSRES_CONST_ASSISTANT_SUBSTITUE_TYPE_CODE SYSRES_CONST_ATTACH_TYPE_COMPONENT_TOKEN SYSRES_CONST_ATTACH_TYPE_DOC SYSRES_CONST_ATTACH_TYPE_EDOC SYSRES_CONST_ATTACH_TYPE_FOLDER SYSRES_CONST_ATTACH_TYPE_JOB SYSRES_CONST_ATTACH_TYPE_REFERENCE SYSRES_CONST_ATTACH_TYPE_TASK SYSRES_CONST_AUTH_ENCODED_PASSWORD SYSRES_CONST_AUTH_ENCODED_PASSWORD_CODE SYSRES_CONST_AUTH_NOVELL SYSRES_CONST_AUTH_PASSWORD SYSRES_CONST_AUTH_PASSWORD_CODE SYSRES_CONST_AUTH_WINDOWS SYSRES_CONST_AUTHENTICATING_SIGNATURE_NAME SYSRES_CONST_AUTHENTICATING_SIGNATURE_REQUISITE_CODE SYSRES_CONST_AUTO_ENUM_METHOD_FLAG SYSRES_CONST_AUTO_NUMERATION_CODE SYSRES_CONST_AUTO_STRONG_ENUM_METHOD_FLAG SYSRES_CONST_AUTOTEXT_NAME_REQUISITE_CODE SYSRES_CONST_AUTOTEXT_TEXT_REQUISITE_CODE SYSRES_CONST_AUTOTEXT_USAGE_ALL SYSRES_CONST_AUTOTEXT_USAGE_ALL_CODE SYSRES_CONST_AUTOTEXT_USAGE_SIGN SYSRES_CONST_AUTOTEXT_USAGE_SIGN_CODE SYSRES_CONST_AUTOTEXT_USAGE_WORK SYSRES_CONST_AUTOTEXT_USAGE_WORK_CODE SYSRES_CONST_AUTOTEXT_USE_ANYWHERE_CODE SYSRES_CONST_AUTOTEXT_USE_ON_SIGNING_CODE SYSRES_CONST_AUTOTEXT_USE_ON_WORK_CODE SYSRES_CONST_BEGIN_DATE_REQUISITE_CODE SYSRES_CONST_BLACK_LIFE_CYCLE_STAGE_FONT_COLOR SYSRES_CONST_BLUE_LIFE_CYCLE_STAGE_FONT_COLOR SYSRES_CONST_BTN_PART SYSRES_CONST_CALCULATED_ROLE_TYPE_CODE SYSRES_CONST_CALL_TYPE_VARIABLE_BUTTON_VALUE SYSRES_CONST_CALL_TYPE_VARIABLE_PROGRAM_VALUE SYSRES_CONST_CANCEL_MESSAGE_FUNCTION_RESULT SYSRES_CONST_CARD_PART SYSRES_CONST_CARD_REFERENCE_MODE_NAME SYSRES_CONST_CERTIFICATE_TYPE_REQUISITE_ENCRYPT_VALUE SYSRES_CONST_CERTIFICATE_TYPE_REQUISITE_SIGN_AND_ENCRYPT_VALUE SYSRES_CONST_CERTIFICATE_TYPE_REQUISITE_SIGN_VALUE SYSRES_CONST_CHECK_PARAM_VALUE_DATE_PARAM_TYPE SYSRES_CONST_CHECK_PARAM_VALUE_FLOAT_PARAM_TYPE SYSRES_CONST_CHECK_PARAM_VALUE_INTEGER_PARAM_TYPE SYSRES_CONST_CHECK_PARAM_VALUE_PICK_PARAM_TYPE SYSRES_CONST_CHECK_PARAM_VALUE_REEFRENCE_PARAM_TYPE SYSRES_CONST_CLOSED_RECORD_FLAG_VALUE_FEMININE SYSRES_CONST_CLOSED_RECORD_FLAG_VALUE_MASCULINE SYSRES_CONST_CODE_COMPONENT_TYPE_ADMIN SYSRES_CONST_CODE_COMPONENT_TYPE_DEVELOPER SYSRES_CONST_CODE_COMPONENT_TYPE_DOCS SYSRES_CONST_CODE_COMPONENT_TYPE_EDOC_CARDS SYSRES_CONST_CODE_COMPONENT_TYPE_EXTERNAL_EXECUTABLE SYSRES_CONST_CODE_COMPONENT_TYPE_OTHER SYSRES_CONST_CODE_COMPONENT_TYPE_REFERENCE SYSRES_CONST_CODE_COMPONENT_TYPE_REPORT SYSRES_CONST_CODE_COMPONENT_TYPE_SCRIPT SYSRES_CONST_CODE_COMPONENT_TYPE_URL SYSRES_CONST_CODE_REQUISITE_ACCESS SYSRES_CONST_CODE_REQUISITE_CODE SYSRES_CONST_CODE_REQUISITE_COMPONENT SYSRES_CONST_CODE_REQUISITE_DESCRIPTION SYSRES_CONST_CODE_REQUISITE_EXCLUDE_COMPONENT SYSRES_CONST_CODE_REQUISITE_RECORD SYSRES_CONST_COMMENT_REQ_CODE SYSRES_CONST_COMMON_SETTINGS_REQUISITE_CODE SYSRES_CONST_COMP_CODE_GRD SYSRES_CONST_COMPONENT_GROUP_TYPE_REQUISITE_CODE SYSRES_CONST_COMPONENT_TYPE_ADMIN_COMPONENTS SYSRES_CONST_COMPONENT_TYPE_DEVELOPER_COMPONENTS SYSRES_CONST_COMPONENT_TYPE_DOCS SYSRES_CONST_COMPONENT_TYPE_EDOC_CARDS SYSRES_CONST_COMPONENT_TYPE_EDOCS SYSRES_CONST_COMPONENT_TYPE_EXTERNAL_EXECUTABLE SYSRES_CONST_COMPONENT_TYPE_OTHER SYSRES_CONST_COMPONENT_TYPE_REFERENCE_TYPES SYSRES_CONST_COMPONENT_TYPE_REFERENCES SYSRES_CONST_COMPONENT_TYPE_REPORTS SYSRES_CONST_COMPONENT_TYPE_SCRIPTS SYSRES_CONST_COMPONENT_TYPE_URL SYSRES_CONST_COMPONENTS_REMOTE_SERVERS_VIEW_CODE SYSRES_CONST_CONDITION_BLOCK_DESCRIPTION SYSRES_CONST_CONST_FIRM_STATUS_COMMON SYSRES_CONST_CONST_FIRM_STATUS_INDIVIDUAL SYSRES_CONST_CONST_NEGATIVE_VALUE SYSRES_CONST_CONST_POSITIVE_VALUE SYSRES_CONST_CONST_SERVER_STATUS_DONT_REPLICATE SYSRES_CONST_CONST_SERVER_STATUS_REPLICATE SYSRES_CONST_CONTENTS_REQUISITE_CODE SYSRES_CONST_DATA_TYPE_BOOLEAN SYSRES_CONST_DATA_TYPE_DATE SYSRES_CONST_DATA_TYPE_FLOAT SYSRES_CONST_DATA_TYPE_INTEGER SYSRES_CONST_DATA_TYPE_PICK SYSRES_CONST_DATA_TYPE_REFERENCE SYSRES_CONST_DATA_TYPE_STRING SYSRES_CONST_DATA_TYPE_TEXT SYSRES_CONST_DATA_TYPE_VARIANT SYSRES_CONST_DATE_CLOSE_REQ_CODE SYSRES_CONST_DATE_FORMAT_DATE_ONLY_CHAR SYSRES_CONST_DATE_OPEN_REQ_CODE SYSRES_CONST_DATE_REQUISITE SYSRES_CONST_DATE_REQUISITE_CODE SYSRES_CONST_DATE_REQUISITE_NAME SYSRES_CONST_DATE_REQUISITE_TYPE SYSRES_CONST_DATE_TYPE_CHAR SYSRES_CONST_DATETIME_FORMAT_VALUE SYSRES_CONST_DEA_ACCESS_RIGHTS_ACTION_CODE SYSRES_CONST_DESCRIPTION_LOCALIZE_ID_REQUISITE_CODE SYSRES_CONST_DESCRIPTION_REQUISITE_CODE SYSRES_CONST_DET1_PART SYSRES_CONST_DET2_PART SYSRES_CONST_DET3_PART SYSRES_CONST_DET4_PART SYSRES_CONST_DET5_PART SYSRES_CONST_DET6_PART SYSRES_CONST_DETAIL_DATASET_KEY_REQUISITE_CODE SYSRES_CONST_DETAIL_PICK_REQUISITE_CODE SYSRES_CONST_DETAIL_REQ_CODE SYSRES_CONST_DO_NOT_USE_ACCESS_TYPE_CODE SYSRES_CONST_DO_NOT_USE_ACCESS_TYPE_NAME SYSRES_CONST_DO_NOT_USE_ON_VIEW_ACCESS_TYPE_CODE SYSRES_CONST_DO_NOT_USE_ON_VIEW_ACCESS_TYPE_NAME SYSRES_CONST_DOCUMENT_STORAGES_CODE SYSRES_CONST_DOCUMENT_TEMPLATES_TYPE_NAME SYSRES_CONST_DOUBLE_REQUISITE_CODE SYSRES_CONST_EDITOR_CLOSE_FILE_OBSERV_TYPE_CODE SYSRES_CONST_EDITOR_CLOSE_PROCESS_OBSERV_TYPE_CODE SYSRES_CONST_EDITOR_TYPE_REQUISITE_CODE SYSRES_CONST_EDITORS_APPLICATION_NAME_REQUISITE_CODE SYSRES_CONST_EDITORS_CREATE_SEVERAL_PROCESSES_REQUISITE_CODE SYSRES_CONST_EDITORS_EXTENSION_REQUISITE_CODE SYSRES_CONST_EDITORS_OBSERVER_BY_PROCESS_TYPE SYSRES_CONST_EDITORS_REFERENCE_CODE SYSRES_CONST_EDITORS_REPLACE_SPEC_CHARS_REQUISITE_CODE SYSRES_CONST_EDITORS_USE_PLUGINS_REQUISITE_CODE SYSRES_CONST_EDITORS_VIEW_DOCUMENT_OPENED_TO_EDIT_CODE SYSRES_CONST_EDOC_CARD_TYPE_REQUISITE_CODE SYSRES_CONST_EDOC_CARD_TYPES_LINK_REQUISITE_CODE SYSRES_CONST_EDOC_CERTIFICATE_AND_PASSWORD_ENCODE_CODE SYSRES_CONST_EDOC_CERTIFICATE_ENCODE_CODE SYSRES_CONST_EDOC_DATE_REQUISITE_CODE SYSRES_CONST_EDOC_KIND_REFERENCE_CODE SYSRES_CONST_EDOC_KINDS_BY_TEMPLATE_ACTION_CODE SYSRES_CONST_EDOC_MANAGE_ACCESS_CODE SYSRES_CONST_EDOC_NONE_ENCODE_CODE SYSRES_CONST_EDOC_NUMBER_REQUISITE_CODE SYSRES_CONST_EDOC_PASSWORD_ENCODE_CODE SYSRES_CONST_EDOC_READONLY_ACCESS_CODE SYSRES_CONST_EDOC_SHELL_LIFE_TYPE_VIEW_VALUE SYSRES_CONST_EDOC_SIZE_RESTRICTION_PRIORITY_REQUISITE_CODE SYSRES_CONST_EDOC_STORAGE_CHECK_ACCESS_RIGHTS_REQUISITE_CODE SYSRES_CONST_EDOC_STORAGE_COMPUTER_NAME_REQUISITE_CODE SYSRES_CONST_EDOC_STORAGE_DATABASE_NAME_REQUISITE_CODE SYSRES_CONST_EDOC_STORAGE_EDIT_IN_STORAGE_REQUISITE_CODE SYSRES_CONST_EDOC_STORAGE_LOCAL_PATH_REQUISITE_CODE SYSRES_CONST_EDOC_STORAGE_SHARED_SOURCE_NAME_REQUISITE_CODE SYSRES_CONST_EDOC_TEMPLATE_REQUISITE_CODE SYSRES_CONST_EDOC_TYPES_REFERENCE_CODE SYSRES_CONST_EDOC_VERSION_ACTIVE_STAGE_CODE SYSRES_CONST_EDOC_VERSION_DESIGN_STAGE_CODE SYSRES_CONST_EDOC_VERSION_OBSOLETE_STAGE_CODE SYSRES_CONST_EDOC_WRITE_ACCES_CODE SYSRES_CONST_EDOCUMENT_CARD_REQUISITES_REFERENCE_CODE_SELECTED_REQUISITE SYSRES_CONST_ENCODE_CERTIFICATE_TYPE_CODE SYSRES_CONST_END_DATE_REQUISITE_CODE SYSRES_CONST_ENUMERATION_TYPE_REQUISITE_CODE SYSRES_CONST_EXECUTE_ACCESS_RIGHTS_TYPE_CODE SYSRES_CONST_EXECUTIVE_FILE_STORAGE_TYPE SYSRES_CONST_EXIST_CONST SYSRES_CONST_EXIST_VALUE SYSRES_CONST_EXPORT_LOCK_TYPE_ASK SYSRES_CONST_EXPORT_LOCK_TYPE_WITH_LOCK SYSRES_CONST_EXPORT_LOCK_TYPE_WITHOUT_LOCK SYSRES_CONST_EXPORT_VERSION_TYPE_ASK SYSRES_CONST_EXPORT_VERSION_TYPE_LAST SYSRES_CONST_EXPORT_VERSION_TYPE_LAST_ACTIVE SYSRES_CONST_EXTENSION_REQUISITE_CODE SYSRES_CONST_FILTER_NAME_REQUISITE_CODE SYSRES_CONST_FILTER_REQUISITE_CODE SYSRES_CONST_FILTER_TYPE_COMMON_CODE SYSRES_CONST_FILTER_TYPE_COMMON_NAME SYSRES_CONST_FILTER_TYPE_USER_CODE SYSRES_CONST_FILTER_TYPE_USER_NAME SYSRES_CONST_FILTER_VALUE_REQUISITE_NAME SYSRES_CONST_FLOAT_NUMBER_FORMAT_CHAR SYSRES_CONST_FLOAT_REQUISITE_TYPE SYSRES_CONST_FOLDER_AUTHOR_VALUE SYSRES_CONST_FOLDER_KIND_ANY_OBJECTS SYSRES_CONST_FOLDER_KIND_COMPONENTS SYSRES_CONST_FOLDER_KIND_EDOCS SYSRES_CONST_FOLDER_KIND_JOBS SYSRES_CONST_FOLDER_KIND_TASKS SYSRES_CONST_FOLDER_TYPE_COMMON SYSRES_CONST_FOLDER_TYPE_COMPONENT SYSRES_CONST_FOLDER_TYPE_FAVORITES SYSRES_CONST_FOLDER_TYPE_INBOX SYSRES_CONST_FOLDER_TYPE_OUTBOX SYSRES_CONST_FOLDER_TYPE_QUICK_LAUNCH SYSRES_CONST_FOLDER_TYPE_SEARCH SYSRES_CONST_FOLDER_TYPE_SHORTCUTS SYSRES_CONST_FOLDER_TYPE_USER SYSRES_CONST_FROM_DICTIONARY_ENUM_METHOD_FLAG SYSRES_CONST_FULL_SUBSTITUTE_TYPE SYSRES_CONST_FULL_SUBSTITUTE_TYPE_CODE SYSRES_CONST_FUNCTION_CANCEL_RESULT SYSRES_CONST_FUNCTION_CATEGORY_SYSTEM SYSRES_CONST_FUNCTION_CATEGORY_USER SYSRES_CONST_FUNCTION_FAILURE_RESULT SYSRES_CONST_FUNCTION_SAVE_RESULT SYSRES_CONST_GENERATED_REQUISITE SYSRES_CONST_GREEN_LIFE_CYCLE_STAGE_FONT_COLOR SYSRES_CONST_GROUP_ACCOUNT_TYPE_VALUE_CODE SYSRES_CONST_GROUP_CATEGORY_NORMAL_CODE SYSRES_CONST_GROUP_CATEGORY_NORMAL_NAME SYSRES_CONST_GROUP_CATEGORY_SERVICE_CODE SYSRES_CONST_GROUP_CATEGORY_SERVICE_NAME SYSRES_CONST_GROUP_COMMON_CATEGORY_FIELD_VALUE SYSRES_CONST_GROUP_FULL_NAME_REQUISITE_CODE SYSRES_CONST_GROUP_NAME_REQUISITE_CODE SYSRES_CONST_GROUP_RIGHTS_T_REQUISITE_CODE SYSRES_CONST_GROUP_SERVER_CODES_REQUISITE_CODE SYSRES_CONST_GROUP_SERVER_NAME_REQUISITE_CODE SYSRES_CONST_GROUP_SERVICE_CATEGORY_FIELD_VALUE SYSRES_CONST_GROUP_USER_REQUISITE_CODE SYSRES_CONST_GROUPS_REFERENCE_CODE SYSRES_CONST_GROUPS_REQUISITE_CODE SYSRES_CONST_HIDDEN_MODE_NAME SYSRES_CONST_HIGH_LVL_REQUISITE_CODE SYSRES_CONST_HISTORY_ACTION_CREATE_CODE SYSRES_CONST_HISTORY_ACTION_DELETE_CODE SYSRES_CONST_HISTORY_ACTION_EDIT_CODE SYSRES_CONST_HOUR_CHAR SYSRES_CONST_ID_REQUISITE_CODE SYSRES_CONST_IDSPS_REQUISITE_CODE SYSRES_CONST_IMAGE_MODE_COLOR SYSRES_CONST_IMAGE_MODE_GREYSCALE SYSRES_CONST_IMAGE_MODE_MONOCHROME SYSRES_CONST_IMPORTANCE_HIGH SYSRES_CONST_IMPORTANCE_LOW SYSRES_CONST_IMPORTANCE_NORMAL SYSRES_CONST_IN_DESIGN_VERSION_STATE_PICK_VALUE SYSRES_CONST_INCOMING_WORK_RULE_TYPE_CODE SYSRES_CONST_INT_REQUISITE SYSRES_CONST_INT_REQUISITE_TYPE SYSRES_CONST_INTEGER_NUMBER_FORMAT_CHAR SYSRES_CONST_INTEGER_TYPE_CHAR SYSRES_CONST_IS_GENERATED_REQUISITE_NEGATIVE_VALUE SYSRES_CONST_IS_PUBLIC_ROLE_REQUISITE_CODE SYSRES_CONST_IS_REMOTE_USER_NEGATIVE_VALUE SYSRES_CONST_IS_REMOTE_USER_POSITIVE_VALUE SYSRES_CONST_IS_STORED_REQUISITE_NEGATIVE_VALUE SYSRES_CONST_IS_STORED_REQUISITE_STORED_VALUE SYSRES_CONST_ITALIC_LIFE_CYCLE_STAGE_DRAW_STYLE SYSRES_CONST_JOB_BLOCK_DESCRIPTION SYSRES_CONST_JOB_KIND_CONTROL_JOB SYSRES_CONST_JOB_KIND_JOB SYSRES_CONST_JOB_KIND_NOTICE SYSRES_CONST_JOB_STATE_ABORTED SYSRES_CONST_JOB_STATE_COMPLETE SYSRES_CONST_JOB_STATE_WORKING SYSRES_CONST_KIND_REQUISITE_CODE SYSRES_CONST_KIND_REQUISITE_NAME SYSRES_CONST_KINDS_CREATE_SHADOW_COPIES_REQUISITE_CODE SYSRES_CONST_KINDS_DEFAULT_EDOC_LIFE_STAGE_REQUISITE_CODE SYSRES_CONST_KINDS_EDOC_ALL_TEPLATES_ALLOWED_REQUISITE_CODE SYSRES_CONST_KINDS_EDOC_ALLOW_LIFE_CYCLE_STAGE_CHANGING_REQUISITE_CODE SYSRES_CONST_KINDS_EDOC_ALLOW_MULTIPLE_ACTIVE_VERSIONS_REQUISITE_CODE SYSRES_CONST_KINDS_EDOC_SHARE_ACCES_RIGHTS_BY_DEFAULT_CODE SYSRES_CONST_KINDS_EDOC_TEMPLATE_REQUISITE_CODE SYSRES_CONST_KINDS_EDOC_TYPE_REQUISITE_CODE SYSRES_CONST_KINDS_SIGNERS_REQUISITES_CODE SYSRES_CONST_KOD_INPUT_TYPE SYSRES_CONST_LAST_UPDATE_DATE_REQUISITE_CODE SYSRES_CONST_LIFE_CYCLE_START_STAGE_REQUISITE_CODE SYSRES_CONST_LILAC_LIFE_CYCLE_STAGE_FONT_COLOR SYSRES_CONST_LINK_OBJECT_KIND_COMPONENT SYSRES_CONST_LINK_OBJECT_KIND_DOCUMENT SYSRES_CONST_LINK_OBJECT_KIND_EDOC SYSRES_CONST_LINK_OBJECT_KIND_FOLDER SYSRES_CONST_LINK_OBJECT_KIND_JOB SYSRES_CONST_LINK_OBJECT_KIND_REFERENCE SYSRES_CONST_LINK_OBJECT_KIND_TASK SYSRES_CONST_LINK_REF_TYPE_REQUISITE_CODE SYSRES_CONST_LIST_REFERENCE_MODE_NAME SYSRES_CONST_LOCALIZATION_DICTIONARY_MAIN_VIEW_CODE SYSRES_CONST_MAIN_VIEW_CODE SYSRES_CONST_MANUAL_ENUM_METHOD_FLAG SYSRES_CONST_MASTER_COMP_TYPE_REQUISITE_CODE SYSRES_CONST_MASTER_TABLE_REC_ID_REQUISITE_CODE SYSRES_CONST_MAXIMIZED_MODE_NAME SYSRES_CONST_ME_VALUE SYSRES_CONST_MESSAGE_ATTENTION_CAPTION SYSRES_CONST_MESSAGE_CONFIRMATION_CAPTION SYSRES_CONST_MESSAGE_ERROR_CAPTION SYSRES_CONST_MESSAGE_INFORMATION_CAPTION SYSRES_CONST_MINIMIZED_MODE_NAME SYSRES_CONST_MINUTE_CHAR SYSRES_CONST_MODULE_REQUISITE_CODE SYSRES_CONST_MONITORING_BLOCK_DESCRIPTION SYSRES_CONST_MONTH_FORMAT_VALUE SYSRES_CONST_NAME_LOCALIZE_ID_REQUISITE_CODE SYSRES_CONST_NAME_REQUISITE_CODE SYSRES_CONST_NAME_SINGULAR_REQUISITE_CODE SYSRES_CONST_NAMEAN_INPUT_TYPE SYSRES_CONST_NEGATIVE_PICK_VALUE SYSRES_CONST_NEGATIVE_VALUE SYSRES_CONST_NO SYSRES_CONST_NO_PICK_VALUE SYSRES_CONST_NO_SIGNATURE_REQUISITE_CODE SYSRES_CONST_NO_VALUE SYSRES_CONST_NONE_ACCESS_RIGHTS_TYPE_CODE SYSRES_CONST_NONOPERATING_RECORD_FLAG_VALUE SYSRES_CONST_NONOPERATING_RECORD_FLAG_VALUE_MASCULINE SYSRES_CONST_NORMAL_ACCESS_RIGHTS_TYPE_CODE SYSRES_CONST_NORMAL_LIFE_CYCLE_STAGE_DRAW_STYLE SYSRES_CONST_NORMAL_MODE_NAME SYSRES_CONST_NOT_ALLOWED_ACCESS_TYPE_CODE SYSRES_CONST_NOT_ALLOWED_ACCESS_TYPE_NAME SYSRES_CONST_NOTE_REQUISITE_CODE SYSRES_CONST_NOTICE_BLOCK_DESCRIPTION SYSRES_CONST_NUM_REQUISITE SYSRES_CONST_NUM_STR_REQUISITE_CODE SYSRES_CONST_NUMERATION_AUTO_NOT_STRONG SYSRES_CONST_NUMERATION_AUTO_STRONG SYSRES_CONST_NUMERATION_FROM_DICTONARY SYSRES_CONST_NUMERATION_MANUAL SYSRES_CONST_NUMERIC_TYPE_CHAR SYSRES_CONST_NUMREQ_REQUISITE_CODE SYSRES_CONST_OBSOLETE_VERSION_STATE_PICK_VALUE SYSRES_CONST_OPERATING_RECORD_FLAG_VALUE SYSRES_CONST_OPERATING_RECORD_FLAG_VALUE_CODE SYSRES_CONST_OPERATING_RECORD_FLAG_VALUE_FEMININE SYSRES_CONST_OPERATING_RECORD_FLAG_VALUE_MASCULINE SYSRES_CONST_OPTIONAL_FORM_COMP_REQCODE_PREFIX SYSRES_CONST_ORANGE_LIFE_CYCLE_STAGE_FONT_COLOR SYSRES_CONST_ORIGINALREF_REQUISITE_CODE SYSRES_CONST_OURFIRM_REF_CODE SYSRES_CONST_OURFIRM_REQUISITE_CODE SYSRES_CONST_OURFIRM_VAR SYSRES_CONST_OUTGOING_WORK_RULE_TYPE_CODE SYSRES_CONST_PICK_NEGATIVE_RESULT SYSRES_CONST_PICK_POSITIVE_RESULT SYSRES_CONST_PICK_REQUISITE SYSRES_CONST_PICK_REQUISITE_TYPE SYSRES_CONST_PICK_TYPE_CHAR SYSRES_CONST_PLAN_STATUS_REQUISITE_CODE SYSRES_CONST_PLATFORM_VERSION_COMMENT SYSRES_CONST_PLUGINS_SETTINGS_DESCRIPTION_REQUISITE_CODE SYSRES_CONST_POSITIVE_PICK_VALUE SYSRES_CONST_POWER_TO_CREATE_ACTION_CODE SYSRES_CONST_POWER_TO_SIGN_ACTION_CODE SYSRES_CONST_PRIORITY_REQUISITE_CODE SYSRES_CONST_QUALIFIED_TASK_TYPE SYSRES_CONST_QUALIFIED_TASK_TYPE_CODE SYSRES_CONST_RECSTAT_REQUISITE_CODE SYSRES_CONST_RED_LIFE_CYCLE_STAGE_FONT_COLOR SYSRES_CONST_REF_ID_T_REF_TYPE_REQUISITE_CODE SYSRES_CONST_REF_REQUISITE SYSRES_CONST_REF_REQUISITE_TYPE SYSRES_CONST_REF_REQUISITES_REFERENCE_CODE_SELECTED_REQUISITE SYSRES_CONST_REFERENCE_RECORD_HISTORY_CREATE_ACTION_CODE SYSRES_CONST_REFERENCE_RECORD_HISTORY_DELETE_ACTION_CODE SYSRES_CONST_REFERENCE_RECORD_HISTORY_MODIFY_ACTION_CODE SYSRES_CONST_REFERENCE_TYPE_CHAR SYSRES_CONST_REFERENCE_TYPE_REQUISITE_NAME SYSRES_CONST_REFERENCES_ADD_PARAMS_REQUISITE_CODE SYSRES_CONST_REFERENCES_DISPLAY_REQUISITE_REQUISITE_CODE SYSRES_CONST_REMOTE_SERVER_STATUS_WORKING SYSRES_CONST_REMOTE_SERVER_TYPE_MAIN SYSRES_CONST_REMOTE_SERVER_TYPE_SECONDARY SYSRES_CONST_REMOTE_USER_FLAG_VALUE_CODE SYSRES_CONST_REPORT_APP_EDITOR_INTERNAL SYSRES_CONST_REPORT_BASE_REPORT_ID_REQUISITE_CODE SYSRES_CONST_REPORT_BASE_REPORT_REQUISITE_CODE SYSRES_CONST_REPORT_SCRIPT_REQUISITE_CODE SYSRES_CONST_REPORT_TEMPLATE_REQUISITE_CODE SYSRES_CONST_REPORT_VIEWER_CODE_REQUISITE_CODE SYSRES_CONST_REQ_ALLOW_COMPONENT_DEFAULT_VALUE SYSRES_CONST_REQ_ALLOW_RECORD_DEFAULT_VALUE SYSRES_CONST_REQ_ALLOW_SERVER_COMPONENT_DEFAULT_VALUE SYSRES_CONST_REQ_MODE_AVAILABLE_CODE SYSRES_CONST_REQ_MODE_EDIT_CODE SYSRES_CONST_REQ_MODE_HIDDEN_CODE SYSRES_CONST_REQ_MODE_NOT_AVAILABLE_CODE SYSRES_CONST_REQ_MODE_VIEW_CODE SYSRES_CONST_REQ_NUMBER_REQUISITE_CODE SYSRES_CONST_REQ_SECTION_VALUE SYSRES_CONST_REQ_TYPE_VALUE SYSRES_CONST_REQUISITE_FORMAT_BY_UNIT SYSRES_CONST_REQUISITE_FORMAT_DATE_FULL SYSRES_CONST_REQUISITE_FORMAT_DATE_TIME SYSRES_CONST_REQUISITE_FORMAT_LEFT SYSRES_CONST_REQUISITE_FORMAT_RIGHT SYSRES_CONST_REQUISITE_FORMAT_WITHOUT_UNIT SYSRES_CONST_REQUISITE_NUMBER_REQUISITE_CODE SYSRES_CONST_REQUISITE_SECTION_ACTIONS SYSRES_CONST_REQUISITE_SECTION_BUTTON SYSRES_CONST_REQUISITE_SECTION_BUTTONS SYSRES_CONST_REQUISITE_SECTION_CARD SYSRES_CONST_REQUISITE_SECTION_TABLE SYSRES_CONST_REQUISITE_SECTION_TABLE10 SYSRES_CONST_REQUISITE_SECTION_TABLE11 SYSRES_CONST_REQUISITE_SECTION_TABLE12 SYSRES_CONST_REQUISITE_SECTION_TABLE13 SYSRES_CONST_REQUISITE_SECTION_TABLE14 SYSRES_CONST_REQUISITE_SECTION_TABLE15 SYSRES_CONST_REQUISITE_SECTION_TABLE16 SYSRES_CONST_REQUISITE_SECTION_TABLE17 SYSRES_CONST_REQUISITE_SECTION_TABLE18 SYSRES_CONST_REQUISITE_SECTION_TABLE19 SYSRES_CONST_REQUISITE_SECTION_TABLE2 SYSRES_CONST_REQUISITE_SECTION_TABLE20 SYSRES_CONST_REQUISITE_SECTION_TABLE21 SYSRES_CONST_REQUISITE_SECTION_TABLE22 SYSRES_CONST_REQUISITE_SECTION_TABLE23 SYSRES_CONST_REQUISITE_SECTION_TABLE24 SYSRES_CONST_REQUISITE_SECTION_TABLE3 SYSRES_CONST_REQUISITE_SECTION_TABLE4 SYSRES_CONST_REQUISITE_SECTION_TABLE5 SYSRES_CONST_REQUISITE_SECTION_TABLE6 SYSRES_CONST_REQUISITE_SECTION_TABLE7 SYSRES_CONST_REQUISITE_SECTION_TABLE8 SYSRES_CONST_REQUISITE_SECTION_TABLE9 SYSRES_CONST_REQUISITES_PSEUDOREFERENCE_REQUISITE_NUMBER_REQUISITE_CODE SYSRES_CONST_RIGHT_ALIGNMENT_CODE SYSRES_CONST_ROLES_REFERENCE_CODE SYSRES_CONST_ROUTE_STEP_AFTER_RUS SYSRES_CONST_ROUTE_STEP_AND_CONDITION_RUS SYSRES_CONST_ROUTE_STEP_OR_CONDITION_RUS SYSRES_CONST_ROUTE_TYPE_COMPLEX SYSRES_CONST_ROUTE_TYPE_PARALLEL SYSRES_CONST_ROUTE_TYPE_SERIAL SYSRES_CONST_SBDATASETDESC_NEGATIVE_VALUE SYSRES_CONST_SBDATASETDESC_POSITIVE_VALUE SYSRES_CONST_SBVIEWSDESC_POSITIVE_VALUE SYSRES_CONST_SCRIPT_BLOCK_DESCRIPTION SYSRES_CONST_SEARCH_BY_TEXT_REQUISITE_CODE SYSRES_CONST_SEARCHES_COMPONENT_CONTENT SYSRES_CONST_SEARCHES_CRITERIA_ACTION_NAME SYSRES_CONST_SEARCHES_EDOC_CONTENT SYSRES_CONST_SEARCHES_FOLDER_CONTENT SYSRES_CONST_SEARCHES_JOB_CONTENT SYSRES_CONST_SEARCHES_REFERENCE_CODE SYSRES_CONST_SEARCHES_TASK_CONTENT SYSRES_CONST_SECOND_CHAR SYSRES_CONST_SECTION_REQUISITE_ACTIONS_VALUE SYSRES_CONST_SECTION_REQUISITE_CARD_VALUE SYSRES_CONST_SECTION_REQUISITE_CODE SYSRES_CONST_SECTION_REQUISITE_DETAIL_1_VALUE SYSRES_CONST_SECTION_REQUISITE_DETAIL_2_VALUE SYSRES_CONST_SECTION_REQUISITE_DETAIL_3_VALUE SYSRES_CONST_SECTION_REQUISITE_DETAIL_4_VALUE SYSRES_CONST_SECTION_REQUISITE_DETAIL_5_VALUE SYSRES_CONST_SECTION_REQUISITE_DETAIL_6_VALUE SYSRES_CONST_SELECT_REFERENCE_MODE_NAME SYSRES_CONST_SELECT_TYPE_SELECTABLE SYSRES_CONST_SELECT_TYPE_SELECTABLE_ONLY_CHILD SYSRES_CONST_SELECT_TYPE_SELECTABLE_WITH_CHILD SYSRES_CONST_SELECT_TYPE_UNSLECTABLE SYSRES_CONST_SERVER_TYPE_MAIN SYSRES_CONST_SERVICE_USER_CATEGORY_FIELD_VALUE SYSRES_CONST_SETTINGS_USER_REQUISITE_CODE SYSRES_CONST_SIGNATURE_AND_ENCODE_CERTIFICATE_TYPE_CODE SYSRES_CONST_SIGNATURE_CERTIFICATE_TYPE_CODE SYSRES_CONST_SINGULAR_TITLE_REQUISITE_CODE SYSRES_CONST_SQL_SERVER_AUTHENTIFICATION_FLAG_VALUE_CODE SYSRES_CONST_SQL_SERVER_ENCODE_AUTHENTIFICATION_FLAG_VALUE_CODE SYSRES_CONST_STANDART_ROUTE_REFERENCE_CODE SYSRES_CONST_STANDART_ROUTE_REFERENCE_COMMENT_REQUISITE_CODE SYSRES_CONST_STANDART_ROUTES_GROUPS_REFERENCE_CODE SYSRES_CONST_STATE_REQ_NAME SYSRES_CONST_STATE_REQUISITE_ACTIVE_VALUE SYSRES_CONST_STATE_REQUISITE_CLOSED_VALUE SYSRES_CONST_STATE_REQUISITE_CODE SYSRES_CONST_STATIC_ROLE_TYPE_CODE SYSRES_CONST_STATUS_PLAN_DEFAULT_VALUE SYSRES_CONST_STATUS_VALUE_AUTOCLEANING SYSRES_CONST_STATUS_VALUE_BLUE_SQUARE SYSRES_CONST_STATUS_VALUE_COMPLETE SYSRES_CONST_STATUS_VALUE_GREEN_SQUARE SYSRES_CONST_STATUS_VALUE_ORANGE_SQUARE SYSRES_CONST_STATUS_VALUE_PURPLE_SQUARE SYSRES_CONST_STATUS_VALUE_RED_SQUARE SYSRES_CONST_STATUS_VALUE_SUSPEND SYSRES_CONST_STATUS_VALUE_YELLOW_SQUARE SYSRES_CONST_STDROUTE_SHOW_TO_USERS_REQUISITE_CODE SYSRES_CONST_STORAGE_TYPE_FILE SYSRES_CONST_STORAGE_TYPE_SQL_SERVER SYSRES_CONST_STR_REQUISITE SYSRES_CONST_STRIKEOUT_LIFE_CYCLE_STAGE_DRAW_STYLE SYSRES_CONST_STRING_FORMAT_LEFT_ALIGN_CHAR SYSRES_CONST_STRING_FORMAT_RIGHT_ALIGN_CHAR SYSRES_CONST_STRING_REQUISITE_CODE SYSRES_CONST_STRING_REQUISITE_TYPE SYSRES_CONST_STRING_TYPE_CHAR SYSRES_CONST_SUBSTITUTES_PSEUDOREFERENCE_CODE SYSRES_CONST_SUBTASK_BLOCK_DESCRIPTION SYSRES_CONST_SYSTEM_SETTING_CURRENT_USER_PARAM_VALUE SYSRES_CONST_SYSTEM_SETTING_EMPTY_VALUE_PARAM_VALUE SYSRES_CONST_SYSTEM_VERSION_COMMENT SYSRES_CONST_TASK_ACCESS_TYPE_ALL SYSRES_CONST_TASK_ACCESS_TYPE_ALL_MEMBERS SYSRES_CONST_TASK_ACCESS_TYPE_MANUAL SYSRES_CONST_TASK_ENCODE_TYPE_CERTIFICATION SYSRES_CONST_TASK_ENCODE_TYPE_CERTIFICATION_AND_PASSWORD SYSRES_CONST_TASK_ENCODE_TYPE_NONE SYSRES_CONST_TASK_ENCODE_TYPE_PASSWORD SYSRES_CONST_TASK_ROUTE_ALL_CONDITION SYSRES_CONST_TASK_ROUTE_AND_CONDITION SYSRES_CONST_TASK_ROUTE_OR_CONDITION SYSRES_CONST_TASK_STATE_ABORTED SYSRES_CONST_TASK_STATE_COMPLETE SYSRES_CONST_TASK_STATE_CONTINUED SYSRES_CONST_TASK_STATE_CONTROL SYSRES_CONST_TASK_STATE_INIT SYSRES_CONST_TASK_STATE_WORKING SYSRES_CONST_TASK_TITLE SYSRES_CONST_TASK_TYPES_GROUPS_REFERENCE_CODE SYSRES_CONST_TASK_TYPES_REFERENCE_CODE SYSRES_CONST_TEMPLATES_REFERENCE_CODE SYSRES_CONST_TEST_DATE_REQUISITE_NAME SYSRES_CONST_TEST_DEV_DATABASE_NAME SYSRES_CONST_TEST_DEV_SYSTEM_CODE SYSRES_CONST_TEST_EDMS_DATABASE_NAME SYSRES_CONST_TEST_EDMS_MAIN_CODE SYSRES_CONST_TEST_EDMS_MAIN_DB_NAME SYSRES_CONST_TEST_EDMS_SECOND_CODE SYSRES_CONST_TEST_EDMS_SECOND_DB_NAME SYSRES_CONST_TEST_EDMS_SYSTEM_CODE SYSRES_CONST_TEST_NUMERIC_REQUISITE_NAME SYSRES_CONST_TEXT_REQUISITE SYSRES_CONST_TEXT_REQUISITE_CODE SYSRES_CONST_TEXT_REQUISITE_TYPE SYSRES_CONST_TEXT_TYPE_CHAR SYSRES_CONST_TYPE_CODE_REQUISITE_CODE SYSRES_CONST_TYPE_REQUISITE_CODE SYSRES_CONST_UNDEFINED_LIFE_CYCLE_STAGE_FONT_COLOR SYSRES_CONST_UNITS_SECTION_ID_REQUISITE_CODE SYSRES_CONST_UNITS_SECTION_REQUISITE_CODE SYSRES_CONST_UNOPERATING_RECORD_FLAG_VALUE_CODE SYSRES_CONST_UNSTORED_DATA_REQUISITE_CODE SYSRES_CONST_UNSTORED_DATA_REQUISITE_NAME SYSRES_CONST_USE_ACCESS_TYPE_CODE SYSRES_CONST_USE_ACCESS_TYPE_NAME SYSRES_CONST_USER_ACCOUNT_TYPE_VALUE_CODE SYSRES_CONST_USER_ADDITIONAL_INFORMATION_REQUISITE_CODE SYSRES_CONST_USER_AND_GROUP_ID_FROM_PSEUDOREFERENCE_REQUISITE_CODE SYSRES_CONST_USER_CATEGORY_NORMAL SYSRES_CONST_USER_CERTIFICATE_REQUISITE_CODE SYSRES_CONST_USER_CERTIFICATE_STATE_REQUISITE_CODE SYSRES_CONST_USER_CERTIFICATE_SUBJECT_NAME_REQUISITE_CODE SYSRES_CONST_USER_CERTIFICATE_THUMBPRINT_REQUISITE_CODE SYSRES_CONST_USER_COMMON_CATEGORY SYSRES_CONST_USER_COMMON_CATEGORY_CODE SYSRES_CONST_USER_FULL_NAME_REQUISITE_CODE SYSRES_CONST_USER_GROUP_TYPE_REQUISITE_CODE SYSRES_CONST_USER_LOGIN_REQUISITE_CODE SYSRES_CONST_USER_REMOTE_CONTROLLER_REQUISITE_CODE SYSRES_CONST_USER_REMOTE_SYSTEM_REQUISITE_CODE SYSRES_CONST_USER_RIGHTS_T_REQUISITE_CODE SYSRES_CONST_USER_SERVER_NAME_REQUISITE_CODE SYSRES_CONST_USER_SERVICE_CATEGORY SYSRES_CONST_USER_SERVICE_CATEGORY_CODE SYSRES_CONST_USER_STATUS_ADMINISTRATOR_CODE SYSRES_CONST_USER_STATUS_ADMINISTRATOR_NAME SYSRES_CONST_USER_STATUS_DEVELOPER_CODE SYSRES_CONST_USER_STATUS_DEVELOPER_NAME SYSRES_CONST_USER_STATUS_DISABLED_CODE SYSRES_CONST_USER_STATUS_DISABLED_NAME SYSRES_CONST_USER_STATUS_SYSTEM_DEVELOPER_CODE SYSRES_CONST_USER_STATUS_USER_CODE SYSRES_CONST_USER_STATUS_USER_NAME SYSRES_CONST_USER_STATUS_USER_NAME_DEPRECATED SYSRES_CONST_USER_TYPE_FIELD_VALUE_USER SYSRES_CONST_USER_TYPE_REQUISITE_CODE SYSRES_CONST_USERS_CONTROLLER_REQUISITE_CODE SYSRES_CONST_USERS_IS_MAIN_SERVER_REQUISITE_CODE SYSRES_CONST_USERS_REFERENCE_CODE SYSRES_CONST_USERS_REGISTRATION_CERTIFICATES_ACTION_NAME SYSRES_CONST_USERS_REQUISITE_CODE SYSRES_CONST_USERS_SYSTEM_REQUISITE_CODE SYSRES_CONST_USERS_USER_ACCESS_RIGHTS_TYPR_REQUISITE_CODE SYSRES_CONST_USERS_USER_AUTHENTICATION_REQUISITE_CODE SYSRES_CONST_USERS_USER_COMPONENT_REQUISITE_CODE SYSRES_CONST_USERS_USER_GROUP_REQUISITE_CODE SYSRES_CONST_USERS_VIEW_CERTIFICATES_ACTION_NAME SYSRES_CONST_VIEW_DEFAULT_CODE SYSRES_CONST_VIEW_DEFAULT_NAME SYSRES_CONST_VIEWER_REQUISITE_CODE SYSRES_CONST_WAITING_BLOCK_DESCRIPTION SYSRES_CONST_WIZARD_FORM_LABEL_TEST_STRING SYSRES_CONST_WIZARD_QUERY_PARAM_HEIGHT_ETALON_STRING SYSRES_CONST_WIZARD_REFERENCE_COMMENT_REQUISITE_CODE SYSRES_CONST_WORK_RULES_DESCRIPTION_REQUISITE_CODE SYSRES_CONST_WORK_TIME_CALENDAR_REFERENCE_CODE SYSRES_CONST_WORK_WORKFLOW_HARD_ROUTE_TYPE_VALUE SYSRES_CONST_WORK_WORKFLOW_HARD_ROUTE_TYPE_VALUE_CODE SYSRES_CONST_WORK_WORKFLOW_HARD_ROUTE_TYPE_VALUE_CODE_RUS SYSRES_CONST_WORK_WORKFLOW_SOFT_ROUTE_TYPE_VALUE_CODE_RUS SYSRES_CONST_WORKFLOW_ROUTE_TYPR_HARD SYSRES_CONST_WORKFLOW_ROUTE_TYPR_SOFT SYSRES_CONST_XML_ENCODING SYSRES_CONST_XREC_STAT_REQUISITE_CODE SYSRES_CONST_XRECID_FIELD_NAME SYSRES_CONST_YES SYSRES_CONST_YES_NO_2_REQUISITE_CODE SYSRES_CONST_YES_NO_REQUISITE_CODE SYSRES_CONST_YES_NO_T_REF_TYPE_REQUISITE_CODE SYSRES_CONST_YES_PICK_VALUE SYSRES_CONST_YES_VALUE CR FALSE nil NO_VALUE NULL TAB TRUE YES_VALUE ADMINISTRATORS_GROUP_NAME CUSTOMIZERS_GROUP_NAME DEVELOPERS_GROUP_NAME SERVICE_USERS_GROUP_NAME DECISION_BLOCK_FIRST_OPERAND_PROPERTY DECISION_BLOCK_NAME_PROPERTY DECISION_BLOCK_OPERATION_PROPERTY DECISION_BLOCK_RESULT_TYPE_PROPERTY DECISION_BLOCK_SECOND_OPERAND_PROPERTY ANY_FILE_EXTENTION COMPRESSED_DOCUMENT_EXTENSION EXTENDED_DOCUMENT_EXTENSION SHORT_COMPRESSED_DOCUMENT_EXTENSION SHORT_EXTENDED_DOCUMENT_EXTENSION JOB_BLOCK_ABORT_DEADLINE_PROPERTY JOB_BLOCK_AFTER_FINISH_EVENT JOB_BLOCK_AFTER_QUERY_PARAMETERS_EVENT JOB_BLOCK_ATTACHMENT_PROPERTY JOB_BLOCK_ATTACHMENTS_RIGHTS_GROUP_PROPERTY JOB_BLOCK_ATTACHMENTS_RIGHTS_TYPE_PROPERTY JOB_BLOCK_BEFORE_QUERY_PARAMETERS_EVENT JOB_BLOCK_BEFORE_START_EVENT JOB_BLOCK_CREATED_JOBS_PROPERTY JOB_BLOCK_DEADLINE_PROPERTY JOB_BLOCK_EXECUTION_RESULTS_PROPERTY JOB_BLOCK_IS_PARALLEL_PROPERTY JOB_BLOCK_IS_RELATIVE_ABORT_DEADLINE_PROPERTY JOB_BLOCK_IS_RELATIVE_DEADLINE_PROPERTY JOB_BLOCK_JOB_TEXT_PROPERTY JOB_BLOCK_NAME_PROPERTY JOB_BLOCK_NEED_SIGN_ON_PERFORM_PROPERTY JOB_BLOCK_PERFORMER_PROPERTY JOB_BLOCK_RELATIVE_ABORT_DEADLINE_TYPE_PROPERTY JOB_BLOCK_RELATIVE_DEADLINE_TYPE_PROPERTY JOB_BLOCK_SUBJECT_PROPERTY ENGLISH_LANGUAGE_CODE RUSSIAN_LANGUAGE_CODE smHidden smMaximized smMinimized smNormal wmNo wmYes COMPONENT_TOKEN_LINK_KIND DOCUMENT_LINK_KIND EDOCUMENT_LINK_KIND FOLDER_LINK_KIND JOB_LINK_KIND REFERENCE_LINK_KIND TASK_LINK_KIND COMPONENT_TOKEN_LOCK_TYPE EDOCUMENT_VERSION_LOCK_TYPE MONITOR_BLOCK_AFTER_FINISH_EVENT MONITOR_BLOCK_BEFORE_START_EVENT MONITOR_BLOCK_DEADLINE_PROPERTY MONITOR_BLOCK_INTERVAL_PROPERTY MONITOR_BLOCK_INTERVAL_TYPE_PROPERTY MONITOR_BLOCK_IS_RELATIVE_DEADLINE_PROPERTY MONITOR_BLOCK_NAME_PROPERTY MONITOR_BLOCK_RELATIVE_DEADLINE_TYPE_PROPERTY MONITOR_BLOCK_SEARCH_SCRIPT_PROPERTY NOTICE_BLOCK_AFTER_FINISH_EVENT NOTICE_BLOCK_ATTACHMENT_PROPERTY NOTICE_BLOCK_ATTACHMENTS_RIGHTS_GROUP_PROPERTY NOTICE_BLOCK_ATTACHMENTS_RIGHTS_TYPE_PROPERTY NOTICE_BLOCK_BEFORE_START_EVENT NOTICE_BLOCK_CREATED_NOTICES_PROPERTY NOTICE_BLOCK_DEADLINE_PROPERTY NOTICE_BLOCK_IS_RELATIVE_DEADLINE_PROPERTY NOTICE_BLOCK_NAME_PROPERTY NOTICE_BLOCK_NOTICE_TEXT_PROPERTY NOTICE_BLOCK_PERFORMER_PROPERTY NOTICE_BLOCK_RELATIVE_DEADLINE_TYPE_PROPERTY NOTICE_BLOCK_SUBJECT_PROPERTY dseAfterCancel dseAfterClose dseAfterDelete dseAfterDeleteOutOfTransaction dseAfterInsert dseAfterOpen dseAfterScroll dseAfterUpdate dseAfterUpdateOutOfTransaction dseBeforeCancel dseBeforeClose dseBeforeDelete dseBeforeDetailUpdate dseBeforeInsert dseBeforeOpen dseBeforeUpdate dseOnAnyRequisiteChange dseOnCloseRecord dseOnDeleteError dseOnOpenRecord dseOnPrepareUpdate dseOnUpdateError dseOnUpdateRatifiedRecord dseOnValidDelete dseOnValidUpdate reOnChange reOnChangeValues SELECTION_BEGIN_ROUTE_EVENT SELECTION_END_ROUTE_EVENT CURRENT_PERIOD_IS_REQUIRED PREVIOUS_CARD_TYPE_NAME SHOW_RECORD_PROPERTIES_FORM ACCESS_RIGHTS_SETTING_DIALOG_CODE ADMINISTRATOR_USER_CODE ANALYTIC_REPORT_TYPE asrtHideLocal asrtHideRemote CALCULATED_ROLE_TYPE_CODE COMPONENTS_REFERENCE_DEVELOPER_VIEW_CODE DCTS_TEST_PROTOCOLS_FOLDER_PATH E_EDOC_VERSION_ALREADY_APPROVINGLY_SIGNED E_EDOC_VERSION_ALREADY_APPROVINGLY_SIGNED_BY_USER E_EDOC_VERSION_ALREDY_SIGNED E_EDOC_VERSION_ALREDY_SIGNED_BY_USER EDOC_TYPES_CODE_REQUISITE_FIELD_NAME EDOCUMENTS_ALIAS_NAME FILES_FOLDER_PATH FILTER_OPERANDS_DELIMITER FILTER_OPERATIONS_DELIMITER FORMCARD_NAME FORMLIST_NAME GET_EXTENDED_DOCUMENT_EXTENSION_CREATION_MODE GET_EXTENDED_DOCUMENT_EXTENSION_IMPORT_MODE INTEGRATED_REPORT_TYPE IS_BUILDER_APPLICATION_ROLE IS_BUILDER_APPLICATION_ROLE2 IS_BUILDER_USERS ISBSYSDEV LOG_FOLDER_PATH mbCancel mbNo mbNoToAll mbOK mbYes mbYesToAll MEMORY_DATASET_DESRIPTIONS_FILENAME mrNo mrNoToAll mrYes mrYesToAll MULTIPLE_SELECT_DIALOG_CODE NONOPERATING_RECORD_FLAG_FEMININE NONOPERATING_RECORD_FLAG_MASCULINE OPERATING_RECORD_FLAG_FEMININE OPERATING_RECORD_FLAG_MASCULINE PROFILING_SETTINGS_COMMON_SETTINGS_CODE_VALUE PROGRAM_INITIATED_LOOKUP_ACTION ratDelete ratEdit ratInsert REPORT_TYPE REQUIRED_PICK_VALUES_VARIABLE rmCard rmList SBRTE_PROGID_DEV SBRTE_PROGID_RELEASE STATIC_ROLE_TYPE_CODE SUPPRESS_EMPTY_TEMPLATE_CREATION SYSTEM_USER_CODE UPDATE_DIALOG_DATASET USED_IN_OBJECT_HINT_PARAM USER_INITIATED_LOOKUP_ACTION USER_NAME_FORMAT USER_SELECTION_RESTRICTIONS WORKFLOW_TEST_PROTOCOLS_FOLDER_PATH ELS_SUBTYPE_CONTROL_NAME ELS_FOLDER_KIND_CONTROL_NAME REPEAT_PROCESS_CURRENT_OBJECT_EXCEPTION_NAME PRIVILEGE_COMPONENT_FULL_ACCESS PRIVILEGE_DEVELOPMENT_EXPORT PRIVILEGE_DEVELOPMENT_IMPORT PRIVILEGE_DOCUMENT_DELETE PRIVILEGE_ESD PRIVILEGE_FOLDER_DELETE PRIVILEGE_MANAGE_ACCESS_RIGHTS PRIVILEGE_MANAGE_REPLICATION PRIVILEGE_MANAGE_SESSION_SERVER PRIVILEGE_OBJECT_FULL_ACCESS PRIVILEGE_OBJECT_VIEW PRIVILEGE_RESERVE_LICENSE PRIVILEGE_SYSTEM_CUSTOMIZE PRIVILEGE_SYSTEM_DEVELOP PRIVILEGE_SYSTEM_INSTALL PRIVILEGE_TASK_DELETE PRIVILEGE_USER_PLUGIN_SETTINGS_CUSTOMIZE PRIVILEGES_PSEUDOREFERENCE_CODE ACCESS_TYPES_PSEUDOREFERENCE_CODE ALL_AVAILABLE_COMPONENTS_PSEUDOREFERENCE_CODE ALL_AVAILABLE_PRIVILEGES_PSEUDOREFERENCE_CODE ALL_REPLICATE_COMPONENTS_PSEUDOREFERENCE_CODE AVAILABLE_DEVELOPERS_COMPONENTS_PSEUDOREFERENCE_CODE COMPONENTS_PSEUDOREFERENCE_CODE FILTRATER_SETTINGS_CONFLICTS_PSEUDOREFERENCE_CODE GROUPS_PSEUDOREFERENCE_CODE RECEIVE_PROTOCOL_PSEUDOREFERENCE_CODE REFERENCE_REQUISITE_PSEUDOREFERENCE_CODE REFERENCE_REQUISITES_PSEUDOREFERENCE_CODE REFTYPES_PSEUDOREFERENCE_CODE REPLICATION_SEANCES_DIARY_PSEUDOREFERENCE_CODE SEND_PROTOCOL_PSEUDOREFERENCE_CODE SUBSTITUTES_PSEUDOREFERENCE_CODE SYSTEM_SETTINGS_PSEUDOREFERENCE_CODE UNITS_PSEUDOREFERENCE_CODE USERS_PSEUDOREFERENCE_CODE VIEWERS_PSEUDOREFERENCE_CODE CERTIFICATE_TYPE_ENCRYPT CERTIFICATE_TYPE_SIGN CERTIFICATE_TYPE_SIGN_AND_ENCRYPT STORAGE_TYPE_FILE STORAGE_TYPE_NAS_CIFS STORAGE_TYPE_SAPERION STORAGE_TYPE_SQL_SERVER COMPTYPE2_REQUISITE_DOCUMENTS_VALUE COMPTYPE2_REQUISITE_TASKS_VALUE COMPTYPE2_REQUISITE_FOLDERS_VALUE COMPTYPE2_REQUISITE_REFERENCES_VALUE SYSREQ_CODE SYSREQ_COMPTYPE2 SYSREQ_CONST_AVAILABLE_FOR_WEB SYSREQ_CONST_COMMON_CODE SYSREQ_CONST_COMMON_VALUE SYSREQ_CONST_FIRM_CODE SYSREQ_CONST_FIRM_STATUS SYSREQ_CONST_FIRM_VALUE SYSREQ_CONST_SERVER_STATUS SYSREQ_CONTENTS SYSREQ_DATE_OPEN SYSREQ_DATE_CLOSE SYSREQ_DESCRIPTION SYSREQ_DESCRIPTION_LOCALIZE_ID SYSREQ_DOUBLE SYSREQ_EDOC_ACCESS_TYPE SYSREQ_EDOC_AUTHOR SYSREQ_EDOC_CREATED SYSREQ_EDOC_DELEGATE_RIGHTS_REQUISITE_CODE SYSREQ_EDOC_EDITOR SYSREQ_EDOC_ENCODE_TYPE SYSREQ_EDOC_ENCRYPTION_PLUGIN_NAME SYSREQ_EDOC_ENCRYPTION_PLUGIN_VERSION SYSREQ_EDOC_EXPORT_DATE SYSREQ_EDOC_EXPORTER SYSREQ_EDOC_KIND SYSREQ_EDOC_LIFE_STAGE_NAME SYSREQ_EDOC_LOCKED_FOR_SERVER_CODE SYSREQ_EDOC_MODIFIED SYSREQ_EDOC_NAME SYSREQ_EDOC_NOTE SYSREQ_EDOC_QUALIFIED_ID SYSREQ_EDOC_SESSION_KEY SYSREQ_EDOC_SESSION_KEY_ENCRYPTION_PLUGIN_NAME SYSREQ_EDOC_SESSION_KEY_ENCRYPTION_PLUGIN_VERSION SYSREQ_EDOC_SIGNATURE_TYPE SYSREQ_EDOC_SIGNED SYSREQ_EDOC_STORAGE SYSREQ_EDOC_STORAGES_ARCHIVE_STORAGE SYSREQ_EDOC_STORAGES_CHECK_RIGHTS SYSREQ_EDOC_STORAGES_COMPUTER_NAME SYSREQ_EDOC_STORAGES_EDIT_IN_STORAGE SYSREQ_EDOC_STORAGES_EXECUTIVE_STORAGE SYSREQ_EDOC_STORAGES_FUNCTION SYSREQ_EDOC_STORAGES_INITIALIZED SYSREQ_EDOC_STORAGES_LOCAL_PATH SYSREQ_EDOC_STORAGES_SAPERION_DATABASE_NAME SYSREQ_EDOC_STORAGES_SEARCH_BY_TEXT SYSREQ_EDOC_STORAGES_SERVER_NAME SYSREQ_EDOC_STORAGES_SHARED_SOURCE_NAME SYSREQ_EDOC_STORAGES_TYPE SYSREQ_EDOC_TEXT_MODIFIED SYSREQ_EDOC_TYPE_ACT_CODE SYSREQ_EDOC_TYPE_ACT_DESCRIPTION SYSREQ_EDOC_TYPE_ACT_DESCRIPTION_LOCALIZE_ID SYSREQ_EDOC_TYPE_ACT_ON_EXECUTE SYSREQ_EDOC_TYPE_ACT_ON_EXECUTE_EXISTS SYSREQ_EDOC_TYPE_ACT_SECTION SYSREQ_EDOC_TYPE_ADD_PARAMS SYSREQ_EDOC_TYPE_COMMENT SYSREQ_EDOC_TYPE_EVENT_TEXT SYSREQ_EDOC_TYPE_NAME_IN_SINGULAR SYSREQ_EDOC_TYPE_NAME_IN_SINGULAR_LOCALIZE_ID SYSREQ_EDOC_TYPE_NAME_LOCALIZE_ID SYSREQ_EDOC_TYPE_NUMERATION_METHOD SYSREQ_EDOC_TYPE_PSEUDO_REQUISITE_CODE SYSREQ_EDOC_TYPE_REQ_CODE SYSREQ_EDOC_TYPE_REQ_DESCRIPTION SYSREQ_EDOC_TYPE_REQ_DESCRIPTION_LOCALIZE_ID SYSREQ_EDOC_TYPE_REQ_IS_LEADING SYSREQ_EDOC_TYPE_REQ_IS_REQUIRED SYSREQ_EDOC_TYPE_REQ_NUMBER SYSREQ_EDOC_TYPE_REQ_ON_CHANGE SYSREQ_EDOC_TYPE_REQ_ON_CHANGE_EXISTS SYSREQ_EDOC_TYPE_REQ_ON_SELECT SYSREQ_EDOC_TYPE_REQ_ON_SELECT_KIND SYSREQ_EDOC_TYPE_REQ_SECTION SYSREQ_EDOC_TYPE_VIEW_CARD SYSREQ_EDOC_TYPE_VIEW_CODE SYSREQ_EDOC_TYPE_VIEW_COMMENT SYSREQ_EDOC_TYPE_VIEW_IS_MAIN SYSREQ_EDOC_TYPE_VIEW_NAME SYSREQ_EDOC_TYPE_VIEW_NAME_LOCALIZE_ID SYSREQ_EDOC_VERSION_AUTHOR SYSREQ_EDOC_VERSION_CRC SYSREQ_EDOC_VERSION_DATA SYSREQ_EDOC_VERSION_EDITOR SYSREQ_EDOC_VERSION_EXPORT_DATE SYSREQ_EDOC_VERSION_EXPORTER SYSREQ_EDOC_VERSION_HIDDEN SYSREQ_EDOC_VERSION_LIFE_STAGE SYSREQ_EDOC_VERSION_MODIFIED SYSREQ_EDOC_VERSION_NOTE SYSREQ_EDOC_VERSION_SIGNATURE_TYPE SYSREQ_EDOC_VERSION_SIGNED SYSREQ_EDOC_VERSION_SIZE SYSREQ_EDOC_VERSION_SOURCE SYSREQ_EDOC_VERSION_TEXT_MODIFIED SYSREQ_EDOCKIND_DEFAULT_VERSION_STATE_CODE SYSREQ_FOLDER_KIND SYSREQ_FUNC_CATEGORY SYSREQ_FUNC_COMMENT SYSREQ_FUNC_GROUP SYSREQ_FUNC_GROUP_COMMENT SYSREQ_FUNC_GROUP_NUMBER SYSREQ_FUNC_HELP SYSREQ_FUNC_PARAM_DEF_VALUE SYSREQ_FUNC_PARAM_IDENT SYSREQ_FUNC_PARAM_NUMBER SYSREQ_FUNC_PARAM_TYPE SYSREQ_FUNC_TEXT SYSREQ_GROUP_CATEGORY SYSREQ_ID SYSREQ_LAST_UPDATE SYSREQ_LEADER_REFERENCE SYSREQ_LINE_NUMBER SYSREQ_MAIN_RECORD_ID SYSREQ_NAME SYSREQ_NAME_LOCALIZE_ID SYSREQ_NOTE SYSREQ_ORIGINAL_RECORD SYSREQ_OUR_FIRM SYSREQ_PROFILING_SETTINGS_BATCH_LOGING SYSREQ_PROFILING_SETTINGS_BATCH_SIZE SYSREQ_PROFILING_SETTINGS_PROFILING_ENABLED SYSREQ_PROFILING_SETTINGS_SQL_PROFILING_ENABLED SYSREQ_PROFILING_SETTINGS_START_LOGGED SYSREQ_RECORD_STATUS SYSREQ_REF_REQ_FIELD_NAME SYSREQ_REF_REQ_FORMAT SYSREQ_REF_REQ_GENERATED SYSREQ_REF_REQ_LENGTH SYSREQ_REF_REQ_PRECISION SYSREQ_REF_REQ_REFERENCE SYSREQ_REF_REQ_SECTION SYSREQ_REF_REQ_STORED SYSREQ_REF_REQ_TOKENS SYSREQ_REF_REQ_TYPE SYSREQ_REF_REQ_VIEW SYSREQ_REF_TYPE_ACT_CODE SYSREQ_REF_TYPE_ACT_DESCRIPTION SYSREQ_REF_TYPE_ACT_DESCRIPTION_LOCALIZE_ID SYSREQ_REF_TYPE_ACT_ON_EXECUTE SYSREQ_REF_TYPE_ACT_ON_EXECUTE_EXISTS SYSREQ_REF_TYPE_ACT_SECTION SYSREQ_REF_TYPE_ADD_PARAMS SYSREQ_REF_TYPE_COMMENT SYSREQ_REF_TYPE_COMMON_SETTINGS SYSREQ_REF_TYPE_DISPLAY_REQUISITE_NAME SYSREQ_REF_TYPE_EVENT_TEXT SYSREQ_REF_TYPE_MAIN_LEADING_REF SYSREQ_REF_TYPE_NAME_IN_SINGULAR SYSREQ_REF_TYPE_NAME_IN_SINGULAR_LOCALIZE_ID SYSREQ_REF_TYPE_NAME_LOCALIZE_ID SYSREQ_REF_TYPE_NUMERATION_METHOD SYSREQ_REF_TYPE_REQ_CODE SYSREQ_REF_TYPE_REQ_DESCRIPTION SYSREQ_REF_TYPE_REQ_DESCRIPTION_LOCALIZE_ID SYSREQ_REF_TYPE_REQ_IS_CONTROL SYSREQ_REF_TYPE_REQ_IS_FILTER SYSREQ_REF_TYPE_REQ_IS_LEADING SYSREQ_REF_TYPE_REQ_IS_REQUIRED SYSREQ_REF_TYPE_REQ_NUMBER SYSREQ_REF_TYPE_REQ_ON_CHANGE SYSREQ_REF_TYPE_REQ_ON_CHANGE_EXISTS SYSREQ_REF_TYPE_REQ_ON_SELECT SYSREQ_REF_TYPE_REQ_ON_SELECT_KIND SYSREQ_REF_TYPE_REQ_SECTION SYSREQ_REF_TYPE_VIEW_CARD SYSREQ_REF_TYPE_VIEW_CODE SYSREQ_REF_TYPE_VIEW_COMMENT SYSREQ_REF_TYPE_VIEW_IS_MAIN SYSREQ_REF_TYPE_VIEW_NAME SYSREQ_REF_TYPE_VIEW_NAME_LOCALIZE_ID SYSREQ_REFERENCE_TYPE_ID SYSREQ_STATE SYSREQ_STATЕ SYSREQ_SYSTEM_SETTINGS_VALUE SYSREQ_TYPE SYSREQ_UNIT SYSREQ_UNIT_ID SYSREQ_USER_GROUPS_GROUP_FULL_NAME SYSREQ_USER_GROUPS_GROUP_NAME SYSREQ_USER_GROUPS_GROUP_SERVER_NAME SYSREQ_USERS_ACCESS_RIGHTS SYSREQ_USERS_AUTHENTICATION SYSREQ_USERS_CATEGORY SYSREQ_USERS_COMPONENT SYSREQ_USERS_COMPONENT_USER_IS_PUBLIC SYSREQ_USERS_DOMAIN SYSREQ_USERS_FULL_USER_NAME SYSREQ_USERS_GROUP SYSREQ_USERS_IS_MAIN_SERVER SYSREQ_USERS_LOGIN SYSREQ_USERS_REFERENCE_USER_IS_PUBLIC SYSREQ_USERS_STATUS SYSREQ_USERS_USER_CERTIFICATE SYSREQ_USERS_USER_CERTIFICATE_INFO SYSREQ_USERS_USER_CERTIFICATE_PLUGIN_NAME SYSREQ_USERS_USER_CERTIFICATE_PLUGIN_VERSION SYSREQ_USERS_USER_CERTIFICATE_STATE SYSREQ_USERS_USER_CERTIFICATE_SUBJECT_NAME SYSREQ_USERS_USER_CERTIFICATE_THUMBPRINT SYSREQ_USERS_USER_DEFAULT_CERTIFICATE SYSREQ_USERS_USER_DESCRIPTION SYSREQ_USERS_USER_GLOBAL_NAME SYSREQ_USERS_USER_LOGIN SYSREQ_USERS_USER_MAIN_SERVER SYSREQ_USERS_USER_TYPE SYSREQ_WORK_RULES_FOLDER_ID RESULT_VAR_NAME RESULT_VAR_NAME_ENG AUTO_NUMERATION_RULE_ID CANT_CHANGE_ID_REQUISITE_RULE_ID CANT_CHANGE_OURFIRM_REQUISITE_RULE_ID CHECK_CHANGING_REFERENCE_RECORD_USE_RULE_ID CHECK_CODE_REQUISITE_RULE_ID CHECK_DELETING_REFERENCE_RECORD_USE_RULE_ID CHECK_FILTRATER_CHANGES_RULE_ID CHECK_RECORD_INTERVAL_RULE_ID CHECK_REFERENCE_INTERVAL_RULE_ID CHECK_REQUIRED_DATA_FULLNESS_RULE_ID CHECK_REQUIRED_REQUISITES_FULLNESS_RULE_ID MAKE_RECORD_UNRATIFIED_RULE_ID RESTORE_AUTO_NUMERATION_RULE_ID SET_FIRM_CONTEXT_FROM_RECORD_RULE_ID SET_FIRST_RECORD_IN_LIST_FORM_RULE_ID SET_IDSPS_VALUE_RULE_ID SET_NEXT_CODE_VALUE_RULE_ID SET_OURFIRM_BOUNDS_RULE_ID SET_OURFIRM_REQUISITE_RULE_ID SCRIPT_BLOCK_AFTER_FINISH_EVENT SCRIPT_BLOCK_BEFORE_START_EVENT SCRIPT_BLOCK_EXECUTION_RESULTS_PROPERTY SCRIPT_BLOCK_NAME_PROPERTY SCRIPT_BLOCK_SCRIPT_PROPERTY SUBTASK_BLOCK_ABORT_DEADLINE_PROPERTY SUBTASK_BLOCK_AFTER_FINISH_EVENT SUBTASK_BLOCK_ASSIGN_PARAMS_EVENT SUBTASK_BLOCK_ATTACHMENTS_PROPERTY SUBTASK_BLOCK_ATTACHMENTS_RIGHTS_GROUP_PROPERTY SUBTASK_BLOCK_ATTACHMENTS_RIGHTS_TYPE_PROPERTY SUBTASK_BLOCK_BEFORE_START_EVENT SUBTASK_BLOCK_CREATED_TASK_PROPERTY SUBTASK_BLOCK_CREATION_EVENT SUBTASK_BLOCK_DEADLINE_PROPERTY SUBTASK_BLOCK_IMPORTANCE_PROPERTY SUBTASK_BLOCK_INITIATOR_PROPERTY SUBTASK_BLOCK_IS_RELATIVE_ABORT_DEADLINE_PROPERTY SUBTASK_BLOCK_IS_RELATIVE_DEADLINE_PROPERTY SUBTASK_BLOCK_JOBS_TYPE_PROPERTY SUBTASK_BLOCK_NAME_PROPERTY SUBTASK_BLOCK_PARALLEL_ROUTE_PROPERTY SUBTASK_BLOCK_PERFORMERS_PROPERTY SUBTASK_BLOCK_RELATIVE_ABORT_DEADLINE_TYPE_PROPERTY SUBTASK_BLOCK_RELATIVE_DEADLINE_TYPE_PROPERTY SUBTASK_BLOCK_REQUIRE_SIGN_PROPERTY SUBTASK_BLOCK_STANDARD_ROUTE_PROPERTY SUBTASK_BLOCK_START_EVENT SUBTASK_BLOCK_STEP_CONTROL_PROPERTY SUBTASK_BLOCK_SUBJECT_PROPERTY SUBTASK_BLOCK_TASK_CONTROL_PROPERTY SUBTASK_BLOCK_TEXT_PROPERTY SUBTASK_BLOCK_UNLOCK_ATTACHMENTS_ON_STOP_PROPERTY SUBTASK_BLOCK_USE_STANDARD_ROUTE_PROPERTY SUBTASK_BLOCK_WAIT_FOR_TASK_COMPLETE_PROPERTY SYSCOMP_CONTROL_JOBS SYSCOMP_FOLDERS SYSCOMP_JOBS SYSCOMP_NOTICES SYSCOMP_TASKS SYSDLG_CREATE_EDOCUMENT SYSDLG_CREATE_EDOCUMENT_VERSION SYSDLG_CURRENT_PERIOD SYSDLG_EDIT_FUNCTION_HELP SYSDLG_EDOCUMENT_KINDS_FOR_TEMPLATE SYSDLG_EXPORT_MULTIPLE_EDOCUMENTS SYSDLG_EXPORT_SINGLE_EDOCUMENT SYSDLG_IMPORT_EDOCUMENT SYSDLG_MULTIPLE_SELECT SYSDLG_SETUP_ACCESS_RIGHTS SYSDLG_SETUP_DEFAULT_RIGHTS SYSDLG_SETUP_FILTER_CONDITION SYSDLG_SETUP_SIGN_RIGHTS SYSDLG_SETUP_TASK_OBSERVERS SYSDLG_SETUP_TASK_ROUTE SYSDLG_SETUP_USERS_LIST SYSDLG_SIGN_EDOCUMENT SYSDLG_SIGN_MULTIPLE_EDOCUMENTS SYSREF_ACCESS_RIGHTS_TYPES SYSREF_ADMINISTRATION_HISTORY SYSREF_ALL_AVAILABLE_COMPONENTS SYSREF_ALL_AVAILABLE_PRIVILEGES SYSREF_ALL_REPLICATING_COMPONENTS SYSREF_AVAILABLE_DEVELOPERS_COMPONENTS SYSREF_CALENDAR_EVENTS SYSREF_COMPONENT_TOKEN_HISTORY SYSREF_COMPONENT_TOKENS SYSREF_COMPONENTS SYSREF_CONSTANTS SYSREF_DATA_RECEIVE_PROTOCOL SYSREF_DATA_SEND_PROTOCOL SYSREF_DIALOGS SYSREF_DIALOGS_REQUISITES SYSREF_EDITORS SYSREF_EDOC_CARDS SYSREF_EDOC_TYPES SYSREF_EDOCUMENT_CARD_REQUISITES SYSREF_EDOCUMENT_CARD_TYPES SYSREF_EDOCUMENT_CARD_TYPES_REFERENCE SYSREF_EDOCUMENT_CARDS SYSREF_EDOCUMENT_HISTORY SYSREF_EDOCUMENT_KINDS SYSREF_EDOCUMENT_REQUISITES SYSREF_EDOCUMENT_SIGNATURES SYSREF_EDOCUMENT_TEMPLATES SYSREF_EDOCUMENT_TEXT_STORAGES SYSREF_EDOCUMENT_VIEWS SYSREF_FILTERER_SETUP_CONFLICTS SYSREF_FILTRATER_SETTING_CONFLICTS SYSREF_FOLDER_HISTORY SYSREF_FOLDERS SYSREF_FUNCTION_GROUPS SYSREF_FUNCTION_PARAMS SYSREF_FUNCTIONS SYSREF_JOB_HISTORY SYSREF_LINKS SYSREF_LOCALIZATION_DICTIONARY SYSREF_LOCALIZATION_LANGUAGES SYSREF_MODULES SYSREF_PRIVILEGES SYSREF_RECORD_HISTORY SYSREF_REFERENCE_REQUISITES SYSREF_REFERENCE_TYPE_VIEWS SYSREF_REFERENCE_TYPES SYSREF_REFERENCES SYSREF_REFERENCES_REQUISITES SYSREF_REMOTE_SERVERS SYSREF_REPLICATION_SESSIONS_LOG SYSREF_REPLICATION_SESSIONS_PROTOCOL SYSREF_REPORTS SYSREF_ROLES SYSREF_ROUTE_BLOCK_GROUPS SYSREF_ROUTE_BLOCKS SYSREF_SCRIPTS SYSREF_SEARCHES SYSREF_SERVER_EVENTS SYSREF_SERVER_EVENTS_HISTORY SYSREF_STANDARD_ROUTE_GROUPS SYSREF_STANDARD_ROUTES SYSREF_STATUSES SYSREF_SYSTEM_SETTINGS SYSREF_TASK_HISTORY SYSREF_TASK_KIND_GROUPS SYSREF_TASK_KINDS SYSREF_TASK_RIGHTS SYSREF_TASK_SIGNATURES SYSREF_TASKS SYSREF_UNITS SYSREF_USER_GROUPS SYSREF_USER_GROUPS_REFERENCE SYSREF_USER_SUBSTITUTION SYSREF_USERS SYSREF_USERS_REFERENCE SYSREF_VIEWERS SYSREF_WORKING_TIME_CALENDARS ACCESS_RIGHTS_TABLE_NAME EDMS_ACCESS_TABLE_NAME EDOC_TYPES_TABLE_NAME TEST_DEV_DB_NAME TEST_DEV_SYSTEM_CODE TEST_EDMS_DB_NAME TEST_EDMS_MAIN_CODE TEST_EDMS_MAIN_DB_NAME TEST_EDMS_SECOND_CODE TEST_EDMS_SECOND_DB_NAME TEST_EDMS_SYSTEM_CODE TEST_ISB5_MAIN_CODE TEST_ISB5_SECOND_CODE TEST_SQL_SERVER_2005_NAME TEST_SQL_SERVER_NAME ATTENTION_CAPTION cbsCommandLinks cbsDefault CONFIRMATION_CAPTION ERROR_CAPTION INFORMATION_CAPTION mrCancel mrOk EDOC_VERSION_ACTIVE_STAGE_CODE EDOC_VERSION_DESIGN_STAGE_CODE EDOC_VERSION_OBSOLETE_STAGE_CODE cpDataEnciphermentEnabled cpDigitalSignatureEnabled cpID cpIssuer cpPluginVersion cpSerial cpSubjectName cpSubjSimpleName cpValidFromDate cpValidToDate ISBL_SYNTAX NO_SYNTAX XML_SYNTAX WAIT_BLOCK_AFTER_FINISH_EVENT WAIT_BLOCK_BEFORE_START_EVENT WAIT_BLOCK_DEADLINE_PROPERTY WAIT_BLOCK_IS_RELATIVE_DEADLINE_PROPERTY WAIT_BLOCK_NAME_PROPERTY WAIT_BLOCK_RELATIVE_DEADLINE_TYPE_PROPERTY SYSRES_COMMON SYSRES_CONST SYSRES_MBFUNC SYSRES_SBDATA SYSRES_SBGUI SYSRES_SBINTF SYSRES_SBREFDSC SYSRES_SQLERRORS SYSRES_SYSCOMP atUser atGroup atRole aemEnabledAlways aemDisabledAlways aemEnabledOnBrowse aemEnabledOnEdit aemDisabledOnBrowseEmpty apBegin apEnd alLeft alRight asmNever asmNoButCustomize asmAsLastTime asmYesButCustomize asmAlways cirCommon cirRevoked ctSignature ctEncode ctSignatureEncode clbUnchecked clbChecked clbGrayed ceISB ceAlways ceNever ctDocument ctReference ctScript ctUnknown ctReport ctDialog ctFunction ctFolder ctEDocument ctTask ctJob ctNotice ctControlJob cfInternal cfDisplay ciUnspecified ciWrite ciRead ckFolder ckEDocument ckTask ckJob ckComponentToken ckAny ckReference ckScript ckReport ckDialog ctISBLEditor ctBevel ctButton ctCheckListBox ctComboBox ctComboEdit ctGrid ctDBCheckBox ctDBComboBox ctDBEdit ctDBEllipsis ctDBMemo ctDBNavigator ctDBRadioGroup ctDBStatusLabel ctEdit ctGroupBox ctInplaceHint ctMemo ctPanel ctListBox ctRadioButton ctRichEdit ctTabSheet ctWebBrowser ctImage ctHyperLink ctLabel ctDBMultiEllipsis ctRibbon ctRichView ctInnerPanel ctPanelGroup ctBitButton cctDate cctInteger cctNumeric cctPick cctReference cctString cctText cltInternal cltPrimary cltGUI dseBeforeOpen dseAfterOpen dseBeforeClose dseAfterClose dseOnValidDelete dseBeforeDelete dseAfterDelete dseAfterDeleteOutOfTransaction dseOnDeleteError dseBeforeInsert dseAfterInsert dseOnValidUpdate dseBeforeUpdate dseOnUpdateRatifiedRecord dseAfterUpdate dseAfterUpdateOutOfTransaction dseOnUpdateError dseAfterScroll dseOnOpenRecord dseOnCloseRecord dseBeforeCancel dseAfterCancel dseOnUpdateDeadlockError dseBeforeDetailUpdate dseOnPrepareUpdate dseOnAnyRequisiteChange dssEdit dssInsert dssBrowse dssInActive dftDate dftShortDate dftDateTime dftTimeStamp dotDays dotHours dotMinutes dotSeconds dtkndLocal dtkndUTC arNone arView arEdit arFull ddaView ddaEdit emLock emEdit emSign emExportWithLock emImportWithUnlock emChangeVersionNote emOpenForModify emChangeLifeStage emDelete emCreateVersion emImport emUnlockExportedWithLock emStart emAbort emReInit emMarkAsReaded emMarkAsUnreaded emPerform emAccept emResume emChangeRights emEditRoute emEditObserver emRecoveryFromLocalCopy emChangeWorkAccessType emChangeEncodeTypeToCertificate emChangeEncodeTypeToPassword emChangeEncodeTypeToNone emChangeEncodeTypeToCertificatePassword emChangeStandardRoute emGetText emOpenForView emMoveToStorage emCreateObject emChangeVersionHidden emDeleteVersion emChangeLifeCycleStage emApprovingSign emExport emContinue emLockFromEdit emUnLockForEdit emLockForServer emUnlockFromServer emDelegateAccessRights emReEncode ecotFile ecotProcess eaGet eaCopy eaCreate eaCreateStandardRoute edltAll edltNothing edltQuery essmText essmCard esvtLast esvtLastActive esvtSpecified edsfExecutive edsfArchive edstSQLServer edstFile edvstNone edvstEDocumentVersionCopy edvstFile edvstTemplate edvstScannedFile vsDefault vsDesign vsActive vsObsolete etNone etCertificate etPassword etCertificatePassword ecException ecWarning ecInformation estAll estApprovingOnly evtLast evtLastActive evtQuery fdtString fdtNumeric fdtInteger fdtDate fdtText fdtUnknown fdtWideString fdtLargeInteger ftInbox ftOutbox ftFavorites ftCommonFolder ftUserFolder ftComponents ftQuickLaunch ftShortcuts ftSearch grhAuto grhX1 grhX2 grhX3 hltText hltRTF hltHTML iffBMP iffJPEG iffMultiPageTIFF iffSinglePageTIFF iffTIFF iffPNG im8bGrayscale im24bRGB im1bMonochrome itBMP itJPEG itWMF itPNG ikhInformation ikhWarning ikhError ikhNoIcon icUnknown icScript icFunction icIntegratedReport icAnalyticReport icDataSetEventHandler icActionHandler icFormEventHandler icLookUpEventHandler icRequisiteChangeEventHandler icBeforeSearchEventHandler icRoleCalculation icSelectRouteEventHandler icBlockPropertyCalculation icBlockQueryParamsEventHandler icChangeSearchResultEventHandler icBlockEventHandler icSubTaskInitEventHandler icEDocDataSetEventHandler icEDocLookUpEventHandler icEDocActionHandler icEDocFormEventHandler icEDocRequisiteChangeEventHandler icStructuredConversionRule icStructuredConversionEventBefore icStructuredConversionEventAfter icWizardEventHandler icWizardFinishEventHandler icWizardStepEventHandler icWizardStepFinishEventHandler icWizardActionEnableEventHandler icWizardActionExecuteEventHandler icCreateJobsHandler icCreateNoticesHandler icBeforeLookUpEventHandler icAfterLookUpEventHandler icTaskAbortEventHandler icWorkflowBlockActionHandler icDialogDataSetEventHandler icDialogActionHandler icDialogLookUpEventHandler icDialogRequisiteChangeEventHandler icDialogFormEventHandler icDialogValidCloseEventHandler icBlockFormEventHandler icTaskFormEventHandler icReferenceMethod icEDocMethod icDialogMethod icProcessMessageHandler isShow isHide isByUserSettings jkJob jkNotice jkControlJob jtInner jtLeft jtRight jtFull jtCross lbpAbove lbpBelow lbpLeft lbpRight eltPerConnection eltPerUser sfcUndefined sfcBlack sfcGreen sfcRed sfcBlue sfcOrange sfcLilac sfsItalic sfsStrikeout sfsNormal ldctStandardRoute ldctWizard ldctScript ldctFunction ldctRouteBlock ldctIntegratedReport ldctAnalyticReport ldctReferenceType ldctEDocumentType ldctDialog ldctServerEvents mrcrtNone mrcrtUser mrcrtMaximal mrcrtCustom vtEqual vtGreaterOrEqual vtLessOrEqual vtRange rdYesterday rdToday rdTomorrow rdThisWeek rdThisMonth rdThisYear rdNextMonth rdNextWeek rdLastWeek rdLastMonth rdWindow rdFile rdPrinter rdtString rdtNumeric rdtInteger rdtDate rdtReference rdtAccount rdtText rdtPick rdtUnknown rdtLargeInteger rdtDocument reOnChange reOnChangeValues ttGlobal ttLocal ttUser ttSystem ssmBrowse ssmSelect ssmMultiSelect ssmBrowseModal smSelect smLike smCard stNone stAuthenticating stApproving sctString sctStream sstAnsiSort sstNaturalSort svtEqual svtContain soatString soatNumeric soatInteger soatDatetime soatReferenceRecord soatText soatPick soatBoolean soatEDocument soatAccount soatIntegerCollection soatNumericCollection soatStringCollection soatPickCollection soatDatetimeCollection soatBooleanCollection soatReferenceRecordCollection soatEDocumentCollection soatAccountCollection soatContents soatUnknown tarAbortByUser tarAbortByWorkflowException tvtAllWords tvtExactPhrase tvtAnyWord usNone usCompleted usRedSquare usBlueSquare usYellowSquare usGreenSquare usOrangeSquare usPurpleSquare usFollowUp utUnknown utUser utDeveloper utAdministrator utSystemDeveloper utDisconnected btAnd btDetailAnd btOr btNotOr btOnly vmView vmSelect vmNavigation vsmSingle vsmMultiple vsmMultipleCheck vsmNoSelection wfatPrevious wfatNext wfatCancel wfatFinish wfepUndefined wfepText3 wfepText6 wfepText9 wfepSpinEdit wfepDropDown wfepRadioGroup wfepFlag wfepText12 wfepText15 wfepText18 wfepText21 wfepText24 wfepText27 wfepText30 wfepRadioGroupColumn1 wfepRadioGroupColumn2 wfepRadioGroupColumn3 wfetQueryParameter wfetText wfetDelimiter wfetLabel wptString wptInteger wptNumeric wptBoolean wptDateTime wptPick wptText wptUser wptUserList wptEDocumentInfo wptEDocumentInfoList wptReferenceRecordInfo wptReferenceRecordInfoList wptFolderInfo wptTaskInfo wptContents wptFileName wptDate wsrComplete wsrGoNext wsrGoPrevious wsrCustom wsrCancel wsrGoFinal wstForm wstEDocument wstTaskCard wstReferenceRecordCard wstFinal waAll waPerformers waManual wsbStart wsbFinish wsbNotice wsbStep wsbDecision wsbWait wsbMonitor wsbScript wsbConnector wsbSubTask wsbLifeCycleStage wsbPause wdtInteger wdtFloat wdtString wdtPick wdtDateTime wdtBoolean wdtTask wdtJob wdtFolder wdtEDocument wdtReferenceRecord wdtUser wdtGroup wdtRole wdtIntegerCollection wdtFloatCollection wdtStringCollection wdtPickCollection wdtDateTimeCollection wdtBooleanCollection wdtTaskCollection wdtJobCollection wdtFolderCollection wdtEDocumentCollection wdtReferenceRecordCollection wdtUserCollection wdtGroupCollection wdtRoleCollection wdtContents wdtUserList wdtSearchDescription wdtDeadLine wdtPickSet wdtAccountCollection wiLow wiNormal wiHigh wrtSoft wrtHard wsInit wsRunning wsDone wsControlled wsAborted wsContinued wtmFull wtmFromCurrent wtmOnlyCurrent ","class":"AltState Application CallType ComponentTokens CreatedJobs CreatedNotices ControlState DialogResult Dialogs EDocuments EDocumentVersionSource Folders GlobalIDs Job Jobs InputValue LookUpReference LookUpRequisiteNames LookUpSearch Object ParentComponent Processes References Requisite ReportName Reports Result Scripts Searches SelectedAttachments SelectedItems SelectMode Sender ServerEvents ServiceFactory ShiftState SubTask SystemDialogs Tasks Wizard Wizards Work ВызовСпособ ИмяОтчета РеквЗнач ","literal":"null true false nil "},"illegal":"\\$|\\?|%|,|;$|~|#|@|)?\\s+)+[a-zA-Z_]\\w*\\s*\\(","returnBegin":true,"end":"[{;=]","excludeEnd":true,"keywords":"false synchronized int abstract float private char boolean var static null if const for true while long strictfp finally protected import native final void enum else break transient catch instanceof byte super volatile case assert short package default double public try this switch continue throws protected public private module requires exports do","contains":[{"begin":"[a-zA-Z_]\\w*\\s*\\(","returnBegin":true,"relevance":0,"contains":[{"$ref":"#contains.5.contains.1"}]},{"className":"params","begin":"\\(","end":"\\)","keywords":"false synchronized int abstract float private char boolean var static null if const for true while long strictfp finally protected import native final void enum else break transient catch instanceof byte super volatile case assert short package default double public try this switch continue throws protected public private module requires exports do","relevance":0,"contains":[{"$ref":"#contains.3"},{"$ref":"#contains.4"},{"className":"number","begin":"(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)","relevance":0},{"$ref":"#contains.2"}]},{"$ref":"#contains.1"},{"$ref":"#contains.2"}]},{"className":"number","begin":"\\b(0[bB]([01]+[01_]+[01]+|[01]+)|0[xX]([a-fA-F0-9]+[a-fA-F0-9_]+[a-fA-F0-9]+|[a-fA-F0-9]+)|(([\\d]+[\\d_]+[\\d]+|[\\d]+)(\\.([\\d]+[\\d_]+[\\d]+|[\\d]+))?|\\.([\\d]+[\\d_]+[\\d]+|[\\d]+))([eE][-+]?\\d+)?)[lLfF]?","relevance":0},{"className":"meta","begin":"@[A-Za-z]+"}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/javascript.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/javascript.json new file mode 100644 index 00000000..2a377650 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/javascript.json @@ -0,0 +1 @@ +{"aliases":["js","jsx"],"keywords":{"keyword":"in of if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const export super debugger as async await static import from as","literal":"true false null undefined NaN Infinity","built_in":"eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError TypeError URIError Number Math Date String RegExp Array Float32Array Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require module console window document Symbol Set Map WeakSet WeakMap Proxy Reflect Promise"},"contains":[{"className":"meta","relevance":10,"begin":"^\\s*['\"]use (strict|asm)['\"]"},{"className":"meta","begin":"^#!","end":"$"},{"className":"string","begin":"'","end":"'","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0}]},{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"$ref":"#contains.2.contains.0"}]},{"begin":"html`","end":"","starts":{"end":"`","returnEnd":false,"contains":[{"$ref":"#contains.2.contains.0"},{"className":"subst","begin":"\\$\\{","end":"\\}","keywords":{"$ref":"#keywords"},"contains":[{"$ref":"#contains.2"},{"$ref":"#contains.3"},{"$ref":"#contains.4"},{"begin":"css`","end":"","starts":{"end":"`","returnEnd":false,"contains":[{"$ref":"#contains.2.contains.0"},{"$ref":"#contains.4.starts.contains.1"}],"subLanguage":"css"}},{"className":"string","begin":"`","end":"`","contains":[{"$ref":"#contains.2.contains.0"},{"$ref":"#contains.4.starts.contains.1"}]},{"className":"number","variants":[{"begin":"\\b(0[bB][01]+)"},{"begin":"\\b(0[oO][0-7]+)"},{"begin":"(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)"}],"relevance":0},{"className":"regexp","begin":"\\/","end":"\\/[gimuy]*","illegal":"\\n","contains":[{"$ref":"#contains.2.contains.0"},{"begin":"\\[","end":"\\]","relevance":0,"contains":[{"$ref":"#contains.2.contains.0"}]}]}]}],"subLanguage":"xml"}},{"$ref":"#contains.4.starts.contains.1.contains.3"},{"$ref":"#contains.4.starts.contains.1.contains.4"},{"className":"comment","begin":"//","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"/\\*","end":"\\*/","contains":[{"$ref":"#contains.7.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"$ref":"#contains.4.starts.contains.1.contains.5"},{"begin":"[{,]\\s*","relevance":0,"contains":[{"begin":"[A-Za-z$_][0-9A-Za-z$_]*\\s*:","returnBegin":true,"relevance":0,"contains":[{"className":"attr","begin":"[A-Za-z$_][0-9A-Za-z$_]*","relevance":0}]}]},{"begin":"(!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~|\\b(case|return|throw)\\b)\\s*","keywords":"return throw case","contains":[{"$ref":"#contains.7"},{"$ref":"#contains.8"},{"$ref":"#contains.4.starts.contains.1.contains.6"},{"className":"function","begin":"(\\(.*?\\)|[A-Za-z$_][0-9A-Za-z$_]*)\\s*=>","returnBegin":true,"end":"\\s*=>","contains":[{"className":"params","variants":[{"begin":"[A-Za-z$_][0-9A-Za-z$_]*"},{"begin":"\\(\\s*\\)"},{"begin":"\\(","end":"\\)","excludeBegin":true,"excludeEnd":true,"keywords":{"$ref":"#keywords"},"contains":[{"$ref":"#contains.2"},{"$ref":"#contains.3"},{"$ref":"#contains.4"},{"$ref":"#contains.4.starts.contains.1.contains.3"},{"$ref":"#contains.4.starts.contains.1.contains.4"},{"$ref":"#contains.4.starts.contains.1.contains.5"},{"$ref":"#contains.4.starts.contains.1.contains.6"},{"$ref":"#contains.8"},{"$ref":"#contains.7"}]}]}]},{"className":"","begin":"\\s","end":"\\s*","skip":true},{"begin":"<","end":"(\\/[A-Za-z0-9\\\\._:-]+|[A-Za-z0-9\\\\._:-]+\\/)>","subLanguage":"xml","contains":[{"begin":"<[A-Za-z0-9\\\\._:-]+\\s*\\/>","skip":true},{"begin":"<[A-Za-z0-9\\\\._:-]+","end":"(\\/[A-Za-z0-9\\\\._:-]+|[A-Za-z0-9\\\\._:-]+\\/)>","skip":true,"contains":[{"begin":"<[A-Za-z0-9\\\\._:-]+\\s*\\/>","skip":true},"self"]}]}],"relevance":0},{"className":"function","beginKeywords":"function","end":"\\{","excludeEnd":true,"contains":[{"className":"title","begin":"[A-Za-z$_][0-9A-Za-z$_]*","relevance":0},{"className":"params","begin":"\\(","end":"\\)","excludeBegin":true,"excludeEnd":true,"contains":{"$ref":"#contains.11.contains.3.contains.0.variants.2.contains"}}],"illegal":"\\[|%"},{"begin":"\\$[(.]"},{"begin":"\\.\\s*[a-zA-Z_]\\w*","relevance":0},{"className":"class","beginKeywords":"class","end":"[{;=]","excludeEnd":true,"illegal":"[:\"\\[\\]]","contains":[{"beginKeywords":"extends"},{"className":"title","begin":"[a-zA-Z_]\\w*","relevance":0}]},{"beginKeywords":"constructor get set","end":"\\{","excludeEnd":true}],"illegal":"#(?!!)"} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/jboss-cli.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/jboss-cli.json new file mode 100644 index 00000000..fddb2091 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/jboss-cli.json @@ -0,0 +1 @@ +{"aliases":["wildfly-cli"],"lexemes":"[a-z-]+","keywords":{"keyword":"alias batch cd clear command connect connection-factory connection-info data-source deploy deployment-info deployment-overlay echo echo-dmr help history if jdbc-driver-info jms-queue|20 jms-topic|20 ls patch pwd quit read-attribute read-operation reload rollout-plan run-batch set shutdown try unalias undeploy unset version xa-data-source","literal":"true false"},"contains":[{"className":"comment","begin":"#","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0}]},{"className":"params","begin":"--[\\w\\-=\\/]+"},{"className":"function","begin":":[\\w\\-.]+","relevance":0},{"className":"string","begin":"\\B(([\\/.])[\\w\\-.\\/=]+)+"},{"className":"params","begin":"\\(","end":"\\)","contains":[{"begin":"[\\w-]+ *=","returnBegin":true,"relevance":0,"contains":[{"className":"attr","begin":"[\\w-]+"}]}],"relevance":0}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/json.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/json.json new file mode 100644 index 00000000..625ea056 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/json.json @@ -0,0 +1 @@ +{"contains":[{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0}]},{"className":"number","begin":"(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)","relevance":0},{"begin":"{","end":"}","contains":[{"className":"attr","begin":"\"","end":"\"","contains":[{"$ref":"#contains.0.contains.0"}],"illegal":"\\n"},{"end":",","endsWithParent":true,"excludeEnd":true,"contains":{"$ref":"#contains"},"keywords":{"literal":"true false null"},"begin":":"}],"illegal":"\\S"},{"begin":"\\[","end":"\\]","contains":[{"end":",","endsWithParent":true,"excludeEnd":true,"contains":{"$ref":"#contains"},"keywords":{"$ref":"#contains.2.contains.1.keywords"}}],"illegal":"\\S"}],"keywords":{"$ref":"#contains.2.contains.1.keywords"},"illegal":"\\S"} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/julia-repl.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/julia-repl.json new file mode 100644 index 00000000..7a3ad550 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/julia-repl.json @@ -0,0 +1 @@ +{"contains":[{"className":"meta","begin":"^julia>","relevance":10,"starts":{"end":"^(?![ ]{6})","subLanguage":"julia"},"aliases":["jldoctest"]}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/julia.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/julia.json new file mode 100644 index 00000000..c04cfccd --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/julia.json @@ -0,0 +1 @@ +{"lexemes":"[A-Za-z_\\x{00A1}-\\x{FFFF}][A-Za-z_0-9\\x{00A1}-\\x{FFFF}]*","keywords":{"keyword":"in isa where baremodule begin break catch ccall const continue do else elseif end export false finally for function global if import importall let local macro module quote return true try using while type immutable abstract bitstype typealias ","literal":"true false ARGS C_NULL DevNull ENDIAN_BOM ENV I Inf Inf16 Inf32 Inf64 InsertionSort JULIA_HOME LOAD_PATH MergeSort NaN NaN16 NaN32 NaN64 PROGRAM_FILE QuickSort RoundDown RoundFromZero RoundNearest RoundNearestTiesAway RoundNearestTiesUp RoundToZero RoundUp STDERR STDIN STDOUT VERSION catalan e|0 eu|0 eulergamma golden im nothing pi γ π φ ","built_in":"ANY AbstractArray AbstractChannel AbstractFloat AbstractMatrix AbstractRNG AbstractSerializer AbstractSet AbstractSparseArray AbstractSparseMatrix AbstractSparseVector AbstractString AbstractUnitRange AbstractVecOrMat AbstractVector Any ArgumentError Array AssertionError Associative Base64DecodePipe Base64EncodePipe Bidiagonal BigFloat BigInt BitArray BitMatrix BitVector Bool BoundsError BufferStream CachingPool CapturedException CartesianIndex CartesianRange Cchar Cdouble Cfloat Channel Char Cint Cintmax_t Clong Clonglong ClusterManager Cmd CodeInfo Colon Complex Complex128 Complex32 Complex64 CompositeException Condition ConjArray ConjMatrix ConjVector Cptrdiff_t Cshort Csize_t Cssize_t Cstring Cuchar Cuint Cuintmax_t Culong Culonglong Cushort Cwchar_t Cwstring DataType Date DateFormat DateTime DenseArray DenseMatrix DenseVecOrMat DenseVector Diagonal Dict DimensionMismatch Dims DirectIndexString Display DivideError DomainError EOFError EachLine Enum Enumerate ErrorException Exception ExponentialBackOff Expr Factorization FileMonitor Float16 Float32 Float64 Function Future GlobalRef GotoNode HTML Hermitian IO IOBuffer IOContext IOStream IPAddr IPv4 IPv6 IndexCartesian IndexLinear IndexStyle InexactError InitError Int Int128 Int16 Int32 Int64 Int8 IntSet Integer InterruptException InvalidStateException Irrational KeyError LabelNode LinSpace LineNumberNode LoadError LowerTriangular MIME Matrix MersenneTwister Method MethodError MethodTable Module NTuple NewvarNode NullException Nullable Number ObjectIdDict OrdinalRange OutOfMemoryError OverflowError Pair ParseError PartialQuickSort PermutedDimsArray Pipe PollingFileWatcher ProcessExitedException Ptr QuoteNode RandomDevice Range RangeIndex Rational RawFD ReadOnlyMemoryError Real ReentrantLock Ref Regex RegexMatch RemoteChannel RemoteException RevString RoundingMode RowVector SSAValue SegmentationFault SerializationState Set SharedArray SharedMatrix SharedVector Signed SimpleVector Slot SlotNumber SparseMatrixCSC SparseVector StackFrame StackOverflowError StackTrace StepRange StepRangeLen StridedArray StridedMatrix StridedVecOrMat StridedVector String SubArray SubString SymTridiagonal Symbol Symmetric SystemError TCPSocket Task Text TextDisplay Timer Tridiagonal Tuple Type TypeError TypeMapEntry TypeMapLevel TypeName TypeVar TypedSlot UDPSocket UInt UInt128 UInt16 UInt32 UInt64 UInt8 UndefRefError UndefVarError UnicodeError UniformScaling Union UnionAll UnitRange Unsigned UpperTriangular Val Vararg VecElement VecOrMat Vector VersionNumber Void WeakKeyDict WeakRef WorkerConfig WorkerPool "},"illegal":"<\\/","contains":[{"className":"number","begin":"(\\b0x[\\d_]*(\\.[\\d_]*)?|0x\\.\\d[\\d_]*)p[-+]?\\d+|\\b0[box][a-fA-F0-9][a-fA-F0-9_]*|(\\b\\d[\\d_]*(\\.[\\d_]*)?|\\.\\d[\\d_]*)([eEfF][-+]?\\d+)?","relevance":0},{"className":"string","begin":"'(.|\\\\[xXuU][a-zA-Z0-9]+)'"},{"className":"string","contains":[{"begin":"\\\\[\\s\\S]","relevance":0},{"className":"subst","begin":"\\$\\(","end":"\\)","keywords":{"$ref":"#keywords"},"contains":{"$ref":"#contains"}},{"className":"variable","begin":"\\$[A-Za-z_\\x{00A1}-\\x{FFFF}][A-Za-z_0-9\\x{00A1}-\\x{FFFF}]*"}],"variants":[{"begin":"\\w*\"\"\"","end":"\"\"\"\\w*","relevance":10},{"begin":"\\w*\"","end":"\"\\w*"}]},{"className":"string","contains":[{"$ref":"#contains.2.contains.0"},{"$ref":"#contains.2.contains.1"},{"$ref":"#contains.2.contains.2"}],"begin":"`","end":"`"},{"className":"meta","begin":"@[A-Za-z_\\x{00A1}-\\x{FFFF}][A-Za-z_0-9\\x{00A1}-\\x{FFFF}]*"},{"className":"comment","variants":[{"begin":"#=","end":"=#","relevance":10},{"begin":"#","end":"$"}]},{"className":"comment","begin":"#","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"keyword","begin":"\\b(((abstract|primitive)\\s+)type|(mutable\\s+)?struct)\\b"},{"begin":"<:"}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/kotlin.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/kotlin.json new file mode 100644 index 00000000..3cdae2f1 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/kotlin.json @@ -0,0 +1 @@ +{"aliases":["kt"],"keywords":{"keyword":"abstract as val var vararg get set class object open private protected public noinline crossinline dynamic final enum if else do while for when throw try catch finally import package is in fun override companion reified inline lateinit init interface annotation data sealed internal infix operator out by constructor super tailrec where const inner suspend typealias external expect actual trait volatile transient native default","built_in":"Byte Short Char Int Long Boolean Float Double Void Unit Nothing","literal":"true false null"},"contains":[{"className":"comment","begin":"/\\*\\*","end":"\\*/","contains":[{"className":"doctag","begin":"@[A-Za-z]+"},{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}],"relevance":0},{"className":"comment","begin":"//","end":"$","contains":[{"$ref":"#contains.0.contains.1"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"/\\*","end":"\\*/","contains":[{"className":"comment","begin":"/\\*","end":"\\*/","contains":[{"$ref":"#contains.0.contains.1"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"$ref":"#contains.0.contains.1"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"keyword","begin":"\\b(break|continue|return|this)\\b","starts":{"contains":[{"className":"symbol","begin":"@\\w+"}]}},{"className":"symbol","begin":"[a-zA-Z_]\\w*@"},{"className":"meta","begin":"@(?:file|property|field|get|set|receiver|param|setparam|delegate)\\s*:(?:\\s*[a-zA-Z_]\\w*)?"},{"className":"meta","begin":"@[a-zA-Z_]\\w*","contains":[{"begin":"\\(","end":"\\)","contains":[{"className":"meta-string","variants":[{"begin":"\"\"\"","end":"\"\"\"","contains":[{"className":"variable","begin":"\\$[a-zA-Z_]\\w*"},{"className":"subst","begin":"\\${","end":"}","contains":[{"className":"string","begin":"'","end":"'","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0}]},{"className":"number","begin":"(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)","relevance":0}]}]},{"begin":"'","end":"'","illegal":"\\n","contains":[{"$ref":"#contains.6.contains.0.contains.0.variants.0.contains.1.contains.0.contains.0"}]},{"begin":"\"","end":"\"","illegal":"\\n","contains":[{"$ref":"#contains.6.contains.0.contains.0.variants.0.contains.1.contains.0.contains.0"},{"$ref":"#contains.6.contains.0.contains.0.variants.0.contains.0"},{"$ref":"#contains.6.contains.0.contains.0.variants.0.contains.1"}]}]}]}]},{"className":"function","beginKeywords":"fun","end":"[(]|$","returnBegin":true,"excludeEnd":true,"keywords":{"$ref":"#keywords"},"illegal":"fun\\s+(<.*>)?[^\\s\\(]+(\\s+[^\\s\\(]+)\\s*=","relevance":5,"contains":[{"begin":"[a-zA-Z_]\\w*\\s*\\(","returnBegin":true,"relevance":0,"contains":[{"className":"title","begin":"[a-zA-Z_]\\w*","relevance":0}]},{"className":"type","begin":"<","end":">","keywords":"reified","relevance":0},{"className":"params","begin":"\\(","end":"\\)","endsParent":true,"keywords":{"$ref":"#keywords"},"relevance":0,"contains":[{"begin":":","end":"[=,\\/]","endsWithParent":true,"contains":[{"variants":[{"className":"type","begin":"[a-zA-Z_]\\w*"},{"begin":"\\(","end":"\\)","contains":[{"$ref":"#contains.7.contains.2.contains.0.contains.0"}]}]},{"$ref":"#contains.1"},{"$ref":"#contains.2"}],"relevance":0},{"$ref":"#contains.1"},{"$ref":"#contains.2"},{"$ref":"#contains.5"},{"$ref":"#contains.6"},{"className":"string","variants":{"$ref":"#contains.6.contains.0.contains.0.variants"}},{"$ref":"#contains.6.contains.0.contains.0.variants.0.contains.1.contains.1"}]},{"$ref":"#contains.2"}]},{"className":"class","beginKeywords":"class interface trait","end":"[:\\{(]|$","excludeEnd":true,"illegal":"extends implements","contains":[{"beginKeywords":"public protected internal private constructor"},{"$ref":"#contains.7.contains.0.contains.0"},{"className":"type","begin":"<","end":">","excludeBegin":true,"excludeEnd":true,"relevance":0},{"className":"type","begin":"[,:]\\s*","end":"[<\\(,]|$","excludeBegin":true,"returnEnd":true},{"$ref":"#contains.5"},{"$ref":"#contains.6"}]},{"$ref":"#contains.7.contains.2.contains.5"},{"className":"meta","begin":"^#!/usr/bin/env","end":"$","illegal":"\n"},{"className":"number","begin":"\\b(0[bB]([01]+[01_]+[01]+|[01]+)|0[xX]([a-fA-F0-9]+[a-fA-F0-9_]+[a-fA-F0-9]+|[a-fA-F0-9]+)|(([\\d]+[\\d_]+[\\d]+|[\\d]+)(\\.([\\d]+[\\d_]+[\\d]+|[\\d]+))?|\\.([\\d]+[\\d_]+[\\d]+|[\\d]+))([eE][-+]?\\d+)?)[lLfF]?","relevance":0}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/lasso.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/lasso.json new file mode 100644 index 00000000..9e44018b --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/lasso.json @@ -0,0 +1 @@ +{"aliases":["ls","lassoscript"],"case_insensitive":true,"lexemes":"[a-zA-Z_][\\w.]*|&[lg]t;","keywords":{"literal":"true false none minimal full all void and or not bw nbw ew new cn ncn lt lte gt gte eq neq rx nrx ft","built_in":"array date decimal duration integer map pair string tag xml null boolean bytes keyword list locale queue set stack staticarray local var variable global data self inherited currentcapture givenblock","keyword":"cache database_names database_schemanames database_tablenames define_tag define_type email_batch encode_set html_comment handle handle_error header if inline iterate ljax_target link link_currentaction link_currentgroup link_currentrecord link_detail link_firstgroup link_firstrecord link_lastgroup link_lastrecord link_nextgroup link_nextrecord link_prevgroup link_prevrecord log loop namespace_using output_none portal private protect records referer referrer repeating resultset rows search_args search_arguments select sort_args sort_arguments thread_atomic value_list while abort case else fail_if fail_ifnot fail if_empty if_false if_null if_true loop_abort loop_continue loop_count params params_up return return_value run_children soap_definetag soap_lastrequest soap_lastresponse tag_name ascending average by define descending do equals frozen group handle_failure import in into join let match max min on order parent protected provide public require returnhome skip split_thread sum take thread to trait type where with yield yieldhome"},"contains":[{"className":"meta","begin":"\\]|\\?>","relevance":0,"starts":{"end":"\\[|<\\?(lasso(script)?|=)","returnEnd":true,"relevance":0,"contains":[{"className":"comment","begin":"","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}],"relevance":0}]}},{"className":"meta","begin":"\\[noprocess\\]","starts":{"end":"\\[/noprocess\\]","returnEnd":true,"contains":[{"$ref":"#contains.0.starts.contains.0"}]}},{"className":"meta","begin":"\\[/noprocess|<\\?(lasso(script)?|=)"},{"className":"meta","begin":"\\[no_square_brackets","starts":{"end":"\\[/no_square_brackets\\]","lexemes":"[a-zA-Z_][\\w.]*|&[lg]t;","keywords":{"$ref":"#keywords"},"contains":[{"className":"meta","begin":"\\]|\\?>","relevance":0,"starts":{"end":"\\[noprocess\\]|<\\?(lasso(script)?|=)","returnEnd":true,"contains":[{"$ref":"#contains.0.starts.contains.0"}]}},{"$ref":"#contains.1"},{"$ref":"#contains.2"},{"className":"comment","begin":"//","end":"$","contains":[{"$ref":"#contains.0.starts.contains.0.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"/\\*","end":"\\*/","contains":[{"$ref":"#contains.0.starts.contains.0.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"number","begin":"(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)|(-?infinity|NaN)\\b","relevance":0},{"className":"string","begin":"'","end":"'","illegal":null,"contains":[{"begin":"\\\\[\\s\\S]","relevance":0}]},{"className":"string","begin":"\"","end":"\"","illegal":null,"contains":[{"$ref":"#contains.3.starts.contains.6.contains.0"}]},{"className":"string","begin":"`","end":"`"},{"variants":[{"begin":"[#$][a-zA-Z_][\\w.]*"},{"begin":"#","end":"\\d+","illegal":"\\W"}]},{"className":"type","begin":"::\\s*","end":"[a-zA-Z_][\\w.]*","illegal":"\\W"},{"className":"params","variants":[{"begin":"-(?!infinity)[a-zA-Z_][\\w.]*","relevance":0},{"begin":"(\\.\\.\\.)"}]},{"begin":"(->|\\.)\\s*","relevance":0,"contains":[{"className":"symbol","begin":"'[a-zA-Z_][\\w.]*'"}]},{"className":"class","beginKeywords":"define","returnEnd":true,"end":"\\(|=>","contains":[{"className":"title","begin":"[a-zA-Z_][\\w.]*(=(?!>))?|[-+*/%](?!>)","relevance":0}]}]}},{"className":"meta","begin":"\\[","relevance":0},{"className":"meta","begin":"^#!","end":"lasso9$","relevance":10},{"$ref":"#contains.3.starts.contains.3"},{"$ref":"#contains.3.starts.contains.4"},{"$ref":"#contains.3.starts.contains.5"},{"$ref":"#contains.3.starts.contains.6"},{"$ref":"#contains.3.starts.contains.7"},{"$ref":"#contains.3.starts.contains.8"},{"$ref":"#contains.3.starts.contains.9"},{"$ref":"#contains.3.starts.contains.10"},{"$ref":"#contains.3.starts.contains.11"},{"$ref":"#contains.3.starts.contains.12"},{"$ref":"#contains.3.starts.contains.13"}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/ldif.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/ldif.json new file mode 100644 index 00000000..7fa5e92f --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/ldif.json @@ -0,0 +1 @@ +{"contains":[{"className":"attribute","begin":"^dn","end":": ","excludeEnd":true,"starts":{"end":"$","relevance":0},"relevance":10},{"className":"attribute","begin":"^\\w","end":": ","excludeEnd":true,"starts":{"end":"$","relevance":0}},{"className":"literal","begin":"^-","end":"$"},{"className":"comment","begin":"#","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/leaf.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/leaf.json new file mode 100644 index 00000000..8e972ff3 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/leaf.json @@ -0,0 +1 @@ +{"contains":[{"className":"function","begin":"#+[A-Za-z_0-9]*\\(","end":" {","returnBegin":true,"excludeEnd":true,"contains":[{"className":"keyword","begin":"#+"},{"className":"title","begin":"[A-Za-z_][A-Za-z_0-9]*"},{"className":"params","begin":"\\(","end":"\\)","endsParent":true,"contains":[{"className":"string","begin":"\"","end":"\""},{"className":"variable","begin":"[A-Za-z_][A-Za-z_0-9]*"}]}]}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/less.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/less.json new file mode 100644 index 00000000..ceff78f5 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/less.json @@ -0,0 +1 @@ +{"case_insensitive":true,"illegal":"[=>'/<($\"]","contains":[{"className":"comment","begin":"//","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"/\\*","end":"\\*/","contains":[{"$ref":"#contains.0.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"keyword","begin":"@(import|media|charset|font-face|(-[a-z]+-)?keyframes|supports|document|namespace|page|viewport|host)\\b","starts":{"end":"[;{}]","returnEnd":true,"contains":[{"$ref":"#contains.0"},{"$ref":"#contains.1"},{"className":"string","begin":"~?'.*?'"},{"className":"string","begin":"~?\".*?\""},{"className":"number","begin":"\\b\\d+(\\.\\d+)?(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?","relevance":0},{"begin":"(url|data-uri)\\(","starts":{"className":"string","end":"[\\)\\n]","excludeEnd":true}},{"className":"number","begin":"#[0-9A-Fa-f]+\\b"},{"begin":"\\(","end":"\\)","contains":{"$ref":"#contains.2.starts.contains"},"relevance":0},{"className":"variable","begin":"@@?[\\w-]+","relevance":10},{"className":"variable","begin":"@{[\\w-]+}"},{"className":"built_in","begin":"~?`[^`]*?`"},{"className":"attribute","begin":"[\\w-]+\\s*:","end":":","returnBegin":true,"excludeEnd":true},{"className":"meta","begin":"!important"}],"relevance":0}},{"className":"variable","variants":[{"begin":"@[\\w-]+\\s*:","relevance":15},{"begin":"@[\\w-]+"}],"starts":{"end":"[;}]","returnEnd":true,"contains":[{"$ref":"#contains.0"},{"$ref":"#contains.1"},{"$ref":"#contains.2.starts.contains.2"},{"$ref":"#contains.2.starts.contains.3"},{"$ref":"#contains.2.starts.contains.4"},{"$ref":"#contains.2.starts.contains.5"},{"$ref":"#contains.2.starts.contains.6"},{"$ref":"#contains.2.starts.contains.7"},{"$ref":"#contains.2.starts.contains.8"},{"$ref":"#contains.2.starts.contains.9"},{"$ref":"#contains.2.starts.contains.10"},{"$ref":"#contains.2.starts.contains.11"},{"$ref":"#contains.2.starts.contains.12"},{"begin":"{","end":"}","contains":{"$ref":"#contains"}}]}},{"begin":"([\\w-]+|@{[\\w-]+})\\s*:","returnBegin":true,"end":"[;}]","relevance":0,"contains":[{"className":"attribute","begin":"([\\w-]+|@{[\\w-]+})","end":":","excludeEnd":true,"starts":{"endsWithParent":true,"illegal":"[<=$]","relevance":0,"contains":{"$ref":"#contains.2.starts.contains"}}}]},{"variants":[{"begin":"[\\.#:&\\[>]","end":"[;{}]"},{"begin":"([\\w-]+|@{[\\w-]+})","end":"{"}],"returnBegin":true,"returnEnd":true,"illegal":"[<='$\"]","relevance":0,"contains":[{"$ref":"#contains.0"},{"$ref":"#contains.1"},{"beginKeywords":"when","endsWithParent":true,"contains":[{"beginKeywords":"and not"},{"$ref":"#contains.0"},{"$ref":"#contains.1"},{"$ref":"#contains.2.starts.contains.2"},{"$ref":"#contains.2.starts.contains.3"},{"$ref":"#contains.2.starts.contains.4"},{"$ref":"#contains.2.starts.contains.5"},{"$ref":"#contains.2.starts.contains.6"},{"$ref":"#contains.2.starts.contains.7"},{"$ref":"#contains.2.starts.contains.8"},{"$ref":"#contains.2.starts.contains.9"},{"$ref":"#contains.2.starts.contains.10"},{"$ref":"#contains.2.starts.contains.11"},{"$ref":"#contains.2.starts.contains.12"}]},{"className":"keyword","begin":"all\\b"},{"className":"variable","begin":"@{[\\w-]+}"},{"className":"selector-tag","begin":"([\\w-]+|@{[\\w-]+})%?","relevance":0},{"className":"selector-id","begin":"#([\\w-]+|@{[\\w-]+})"},{"className":"selector-class","begin":"\\.([\\w-]+|@{[\\w-]+})","relevance":0},{"className":"selector-tag","begin":"&","relevance":0},{"className":"selector-attr","begin":"\\[","end":"\\]"},{"className":"selector-pseudo","begin":":(:)?[a-zA-Z0-9\\_\\-\\+\\(\\)\"'.]+"},{"begin":"\\(","end":"\\)","contains":{"$ref":"#contains.3.starts.contains"}},{"begin":"!important"}]}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/lisp.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/lisp.json new file mode 100644 index 00000000..1827bed6 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/lisp.json @@ -0,0 +1 @@ +{"illegal":"\\S","contains":[{"className":"number","variants":[{"begin":"(\\-|\\+)?\\d+(\\.\\d+|\\/\\d+)?((d|e|f|l|s|D|E|F|L|S)(\\+|\\-)?\\d+)?","relevance":0},{"begin":"#(b|B)[0-1]+(/[0-1]+)?"},{"begin":"#(o|O)[0-7]+(/[0-7]+)?"},{"begin":"#(x|X)[0-9a-fA-F]+(/[0-9a-fA-F]+)?"},{"begin":"#(c|C)\\((\\-|\\+)?\\d+(\\.\\d+|\\/\\d+)?((d|e|f|l|s|D|E|F|L|S)(\\+|\\-)?\\d+)? +(\\-|\\+)?\\d+(\\.\\d+|\\/\\d+)?((d|e|f|l|s|D|E|F|L|S)(\\+|\\-)?\\d+)?","end":"\\)"}]},{"className":"meta","begin":"^#!","end":"$"},{"className":"literal","begin":"\\b(t{1}|nil)\\b"},{"className":"string","begin":"\"","end":"\"","illegal":null,"contains":[{"begin":"\\\\[\\s\\S]","relevance":0}]},{"className":"comment","begin":";","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}],"relevance":0},{"contains":[{"$ref":"#contains.0"},{"$ref":"#contains.3"},{"begin":"\\*","end":"\\*"},{"className":"symbol","begin":"[:&][a-zA-Z_\\-\\+\\*\\/\\<\\=\\>\\&\\#][a-zA-Z0-9_\\-\\+\\*\\/\\<\\=\\>\\&\\#!]*"},{"begin":"\\(","end":"\\)","contains":["self",{"$ref":"#contains.2"},{"$ref":"#contains.3"},{"$ref":"#contains.0"},{"begin":"[a-zA-Z_\\-\\+\\*\\/\\<\\=\\>\\&\\#][a-zA-Z0-9_\\-\\+\\*\\/\\<\\=\\>\\&\\#!]*","relevance":0}]},{"$ref":"#contains.5.contains.4.contains.4"}],"variants":[{"begin":"['`]\\(","end":"\\)"},{"begin":"\\(quote ","end":"\\)","keywords":{"name":"quote"}},{"begin":"'\\|[^|]*?\\|"}]},{"variants":[{"begin":"'[a-zA-Z_\\-\\+\\*\\/\\<\\=\\>\\&\\#][a-zA-Z0-9_\\-\\+\\*\\/\\<\\=\\>\\&\\#!]*"},{"begin":"#'[a-zA-Z_\\-\\+\\*\\/\\<\\=\\>\\&\\#][a-zA-Z0-9_\\-\\+\\*\\/\\<\\=\\>\\&\\#!]*(::[a-zA-Z_\\-\\+\\*\\/\\<\\=\\>\\&\\#][a-zA-Z0-9_\\-\\+\\*\\/\\<\\=\\>\\&\\#!]*)*"}]},{"begin":"\\(\\s*","end":"\\)","contains":[{"className":"name","variants":[{"begin":"[a-zA-Z_\\-\\+\\*\\/\\<\\=\\>\\&\\#][a-zA-Z0-9_\\-\\+\\*\\/\\<\\=\\>\\&\\#!]*"},{"begin":"\\|[^|]*?\\|"}]},{"endsWithParent":true,"relevance":0,"contains":[{"$ref":"#contains.5"},{"$ref":"#contains.6"},{"$ref":"#contains.7"},{"$ref":"#contains.2"},{"$ref":"#contains.0"},{"$ref":"#contains.3"},{"$ref":"#contains.4"},{"$ref":"#contains.5.contains.2"},{"$ref":"#contains.5.contains.3"},{"begin":"\\|[^|]*?\\|"},{"$ref":"#contains.5.contains.4.contains.4"}]}]},{"$ref":"#contains.5.contains.4.contains.4"}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/livecodeserver.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/livecodeserver.json new file mode 100644 index 00000000..1eb58347 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/livecodeserver.json @@ -0,0 +1 @@ +{"case_insensitive":false,"keywords":{"keyword":"$_COOKIE $_FILES $_GET $_GET_BINARY $_GET_RAW $_POST $_POST_BINARY $_POST_RAW $_SESSION $_SERVER codepoint codepoints segment segments codeunit codeunits sentence sentences trueWord trueWords paragraph after byte bytes english the until http forever descending using line real8 with seventh for stdout finally element word words fourth before black ninth sixth characters chars stderr uInt1 uInt1s uInt2 uInt2s stdin string lines relative rel any fifth items from middle mid at else of catch then third it file milliseconds seconds second secs sec int1 int1s int4 int4s internet int2 int2s normal text item last long detailed effective uInt4 uInt4s repeat end repeat URL in try into switch to words https token binfile each tenth as ticks tick system real4 by dateItems without char character ascending eighth whole dateTime numeric short first ftp integer abbreviated abbr abbrev private case while if div mod wrap and or bitAnd bitNot bitOr bitXor among not in a an within contains ends with begins the keys of keys","literal":"SIX TEN FORMFEED NINE ZERO NONE SPACE FOUR FALSE COLON CRLF PI COMMA ENDOFFILE EOF EIGHT FIVE QUOTE EMPTY ONE TRUE RETURN CR LINEFEED RIGHT BACKSLASH NULL SEVEN TAB THREE TWO six ten formfeed nine zero none space four false colon crlf pi comma endoffile eof eight five quote empty one true return cr linefeed right backslash null seven tab three two RIVERSION RISTATE FILE_READ_MODE FILE_WRITE_MODE FILE_WRITE_MODE DIR_WRITE_MODE FILE_READ_UMASK FILE_WRITE_UMASK DIR_READ_UMASK DIR_WRITE_UMASK","built_in":"put abs acos aliasReference annuity arrayDecode arrayEncode asin atan atan2 average avg avgDev base64Decode base64Encode baseConvert binaryDecode binaryEncode byteOffset byteToNum cachedURL cachedURLs charToNum cipherNames codepointOffset codepointProperty codepointToNum codeunitOffset commandNames compound compress constantNames cos date dateFormat decompress difference directories diskSpace DNSServers exp exp1 exp2 exp10 extents files flushEvents folders format functionNames geometricMean global globals hasMemory harmonicMean hostAddress hostAddressToName hostName hostNameToAddress isNumber ISOToMac itemOffset keys len length libURLErrorData libUrlFormData libURLftpCommand libURLLastHTTPHeaders libURLLastRHHeaders libUrlMultipartFormAddPart libUrlMultipartFormData libURLVersion lineOffset ln ln1 localNames log log2 log10 longFilePath lower macToISO matchChunk matchText matrixMultiply max md5Digest median merge messageAuthenticationCode messageDigest millisec millisecs millisecond milliseconds min monthNames nativeCharToNum normalizeText num number numToByte numToChar numToCodepoint numToNativeChar offset open openfiles openProcesses openProcessIDs openSockets paragraphOffset paramCount param params peerAddress pendingMessages platform popStdDev populationStandardDeviation populationVariance popVariance processID random randomBytes replaceText result revCreateXMLTree revCreateXMLTreeFromFile revCurrentRecord revCurrentRecordIsFirst revCurrentRecordIsLast revDatabaseColumnCount revDatabaseColumnIsNull revDatabaseColumnLengths revDatabaseColumnNames revDatabaseColumnNamed revDatabaseColumnNumbered revDatabaseColumnTypes revDatabaseConnectResult revDatabaseCursors revDatabaseID revDatabaseTableNames revDatabaseType revDataFromQuery revdb_closeCursor revdb_columnbynumber revdb_columncount revdb_columnisnull revdb_columnlengths revdb_columnnames revdb_columntypes revdb_commit revdb_connect revdb_connections revdb_connectionerr revdb_currentrecord revdb_cursorconnection revdb_cursorerr revdb_cursors revdb_dbtype revdb_disconnect revdb_execute revdb_iseof revdb_isbof revdb_movefirst revdb_movelast revdb_movenext revdb_moveprev revdb_query revdb_querylist revdb_recordcount revdb_rollback revdb_tablenames revGetDatabaseDriverPath revNumberOfRecords revOpenDatabase revOpenDatabases revQueryDatabase revQueryDatabaseBlob revQueryResult revQueryIsAtStart revQueryIsAtEnd revUnixFromMacPath revXMLAttribute revXMLAttributes revXMLAttributeValues revXMLChildContents revXMLChildNames revXMLCreateTreeFromFileWithNamespaces revXMLCreateTreeWithNamespaces revXMLDataFromXPathQuery revXMLEvaluateXPath revXMLFirstChild revXMLMatchingNode revXMLNextSibling revXMLNodeContents revXMLNumberOfChildren revXMLParent revXMLPreviousSibling revXMLRootNode revXMLRPC_CreateRequest revXMLRPC_Documents revXMLRPC_Error revXMLRPC_GetHost revXMLRPC_GetMethod revXMLRPC_GetParam revXMLText revXMLRPC_Execute revXMLRPC_GetParamCount revXMLRPC_GetParamNode revXMLRPC_GetParamType revXMLRPC_GetPath revXMLRPC_GetPort revXMLRPC_GetProtocol revXMLRPC_GetRequest revXMLRPC_GetResponse revXMLRPC_GetSocket revXMLTree revXMLTrees revXMLValidateDTD revZipDescribeItem revZipEnumerateItems revZipOpenArchives round sampVariance sec secs seconds sentenceOffset sha1Digest shell shortFilePath sin specialFolderPath sqrt standardDeviation statRound stdDev sum sysError systemVersion tan tempName textDecode textEncode tick ticks time to tokenOffset toLower toUpper transpose truewordOffset trunc uniDecode uniEncode upper URLDecode URLEncode URLStatus uuid value variableNames variance version waitDepth weekdayNames wordOffset xsltApplyStylesheet xsltApplyStylesheetFromFile xsltLoadStylesheet xsltLoadStylesheetFromFile add breakpoint cancel clear local variable file word line folder directory URL close socket process combine constant convert create new alias folder directory decrypt delete variable word line folder directory URL dispatch divide do encrypt filter get include intersect kill libURLDownloadToFile libURLFollowHttpRedirects libURLftpUpload libURLftpUploadFile libURLresetAll libUrlSetAuthCallback libURLSetDriver libURLSetCustomHTTPHeaders libUrlSetExpect100 libURLSetFTPListCommand libURLSetFTPMode libURLSetFTPStopTime libURLSetStatusCallback load extension loadedExtensions multiply socket prepare process post seek rel relative read from process rename replace require resetAll resolve revAddXMLNode revAppendXML revCloseCursor revCloseDatabase revCommitDatabase revCopyFile revCopyFolder revCopyXMLNode revDeleteFolder revDeleteXMLNode revDeleteAllXMLTrees revDeleteXMLTree revExecuteSQL revGoURL revInsertXMLNode revMoveFolder revMoveToFirstRecord revMoveToLastRecord revMoveToNextRecord revMoveToPreviousRecord revMoveToRecord revMoveXMLNode revPutIntoXMLNode revRollBackDatabase revSetDatabaseDriverPath revSetXMLAttribute revXMLRPC_AddParam revXMLRPC_DeleteAllDocuments revXMLAddDTD revXMLRPC_Free revXMLRPC_FreeAll revXMLRPC_DeleteDocument revXMLRPC_DeleteParam revXMLRPC_SetHost revXMLRPC_SetMethod revXMLRPC_SetPort revXMLRPC_SetProtocol revXMLRPC_SetSocket revZipAddItemWithData revZipAddItemWithFile revZipAddUncompressedItemWithData revZipAddUncompressedItemWithFile revZipCancel revZipCloseArchive revZipDeleteItem revZipExtractItemToFile revZipExtractItemToVariable revZipSetProgressCallback revZipRenameItem revZipReplaceItemWithData revZipReplaceItemWithFile revZipOpenArchive send set sort split start stop subtract symmetric union unload vectorDotProduct wait write"},"contains":[{"className":"variable","variants":[{"begin":"\\b([gtps][A-Z]{1}[a-zA-Z0-9]*)(\\[.+\\])?(?:\\s*?)"},{"begin":"\\$_[A-Z]+"}],"relevance":0},{"className":"keyword","begin":"\\bend\\sif\\b"},{"className":"function","beginKeywords":"function","end":"$","contains":[{"$ref":"#contains.0"},{"className":"title","begin":"\\b([A-Za-z0-9_\\-]+)\\b","relevance":0},{"className":"string","begin":"'","end":"'","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0}]},{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"$ref":"#contains.2.contains.2.contains.0"}]},{"className":"number","begin":"\\b(0b[01]+)","relevance":0},{"className":"number","begin":"(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)","relevance":0},{"className":"title","begin":"[a-zA-Z]\\w*","relevance":0,"variants":[{"begin":"\\b_*rig[A-Z]+[A-Za-z0-9_\\-]*"},{"begin":"\\b_[a-z0-9\\-]+"}]}]},{"className":"function","begin":"\\bend\\s+","end":"$","keywords":"end","contains":[{"$ref":"#contains.2.contains.1"},{"$ref":"#contains.2.contains.6"}],"relevance":0},{"beginKeywords":"command on","end":"$","contains":[{"$ref":"#contains.0"},{"$ref":"#contains.2.contains.1"},{"$ref":"#contains.2.contains.2"},{"$ref":"#contains.2.contains.3"},{"$ref":"#contains.2.contains.4"},{"$ref":"#contains.2.contains.5"},{"$ref":"#contains.2.contains.6"}]},{"className":"meta","variants":[{"begin":"<\\?(rev|lc|livecode)","relevance":10},{"begin":"<\\?"},{"begin":"\\?>"}]},{"$ref":"#contains.2.contains.2"},{"$ref":"#contains.2.contains.3"},{"$ref":"#contains.2.contains.4"},{"$ref":"#contains.2.contains.5"},{"$ref":"#contains.2.contains.6"},{"className":"comment","begin":"/\\*","end":"\\*/","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"#","end":"$","contains":[{"$ref":"#contains.11.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"--","end":"$","contains":[{"$ref":"#contains.11.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"[^:]//","end":"$","contains":[{"$ref":"#contains.11.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]}],"illegal":";$|^\\[|^=|&|{"} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/livescript.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/livescript.json new file mode 100644 index 00000000..a5a75495 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/livescript.json @@ -0,0 +1 @@ +{"aliases":["ls"],"keywords":{"keyword":"in if for while finally new do return else break catch instanceof throw try this switch continue typeof delete debugger case default function var with then unless until loop of by when and or is isnt not it that otherwise from to til fallthrough super case default function var void const let enum export import native __hasProp __extends __slice __bind __indexOf","literal":"true false null undefined yes no on off it that void","built_in":"npm require console print module global window document"},"illegal":"\\/\\*","contains":[{"className":"number","begin":"\\b(0b[01]+)","relevance":0},{"className":"number","begin":"(\\b0[xX][a-fA-F0-9_]+)|(\\b\\d(\\d|_\\d)*(\\.(\\d(\\d|_\\d)*)?)?(_*[eE]([-+]\\d(_\\d|\\d)*)?)?[_a-z]*)","relevance":0,"starts":{"end":"(\\s*/)?","relevance":0}},{"className":"string","variants":[{"begin":"'''","end":"'''","contains":[{"begin":"\\\\[\\s\\S]","relevance":0}]},{"begin":"'","end":"'","contains":[{"$ref":"#contains.2.variants.0.contains.0"}]},{"begin":"\"\"\"","end":"\"\"\"","contains":[{"$ref":"#contains.2.variants.0.contains.0"},{"className":"subst","begin":"#\\{","end":"}","keywords":{"$ref":"#keywords"},"contains":[{"$ref":"#contains.0"},{"$ref":"#contains.1"},{"$ref":"#contains.2"},{"className":"regexp","variants":[{"begin":"//","end":"//[gim]*","contains":[{"$ref":"#contains.2.variants.2.contains.1"},{"className":"comment","begin":"#","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]}]},{"begin":"\\/(?![ *])(\\\\\\/|.)*?\\/[gim]*(?=\\W|$)"}]},{"begin":"@[A-Za-z$_](?:-[0-9A-Za-z$_]|[0-9A-Za-z$_])*"},{"begin":"``","end":"``","excludeBegin":true,"excludeEnd":true,"subLanguage":"javascript"}]},{"className":"subst","begin":"#[A-Za-z$_]","end":"(?:\\-[0-9A-Za-z$_]|[0-9A-Za-z$_])*","keywords":{"$ref":"#keywords"}}]},{"begin":"\"","end":"\"","contains":[{"$ref":"#contains.2.variants.0.contains.0"},{"$ref":"#contains.2.variants.2.contains.1"},{"$ref":"#contains.2.variants.2.contains.2"}]},{"begin":"\\\\","end":"(\\s|$)","excludeEnd":true}]},{"$ref":"#contains.2.variants.2.contains.1.contains.3"},{"$ref":"#contains.2.variants.2.contains.1.contains.4"},{"$ref":"#contains.2.variants.2.contains.1.contains.5"},{"className":"comment","begin":"\\/\\*","end":"\\*\\/","contains":[{"$ref":"#contains.2.variants.2.contains.1.contains.3.variants.0.contains.1.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"$ref":"#contains.2.variants.2.contains.1.contains.3.variants.0.contains.1"},{"className":"function","contains":[{"className":"title","begin":"[A-Za-z$_](?:-[0-9A-Za-z$_]|[0-9A-Za-z$_])*","relevance":0},{"className":"params","begin":"\\(","returnBegin":true,"contains":[{"begin":"\\(","end":"\\)","keywords":{"$ref":"#keywords"},"contains":["self",{"$ref":"#contains.0"},{"$ref":"#contains.1"},{"$ref":"#contains.2"},{"$ref":"#contains.2.variants.2.contains.1.contains.3"},{"$ref":"#contains.2.variants.2.contains.1.contains.4"},{"$ref":"#contains.2.variants.2.contains.1.contains.5"}]}]}],"returnBegin":true,"variants":[{"begin":"([A-Za-z$_](?:-[0-9A-Za-z$_]|[0-9A-Za-z$_])*\\s*(?:=|:=)\\s*)?(\\(.*\\))?\\s*\\B\\->\\*?","end":"\\->\\*?"},{"begin":"([A-Za-z$_](?:-[0-9A-Za-z$_]|[0-9A-Za-z$_])*\\s*(?:=|:=)\\s*)?!?(\\(.*\\))?\\s*\\B[-~]{1,2}>\\*?","end":"[-~]{1,2}>\\*?"},{"begin":"([A-Za-z$_](?:-[0-9A-Za-z$_]|[0-9A-Za-z$_])*\\s*(?:=|:=)\\s*)?(\\(.*\\))?\\s*\\B!?[-~]{1,2}>\\*?","end":"!?[-~]{1,2}>\\*?"}]},{"className":"class","beginKeywords":"class","end":"$","illegal":"[:=\"\\[\\]]","contains":[{"beginKeywords":"extends","endsWithParent":true,"illegal":"[:=\"\\[\\]]","contains":[{"$ref":"#contains.8.contains.0"}]},{"$ref":"#contains.8.contains.0"}]},{"begin":"[A-Za-z$_](?:-[0-9A-Za-z$_]|[0-9A-Za-z$_])*:","end":":","returnBegin":true,"returnEnd":true,"relevance":0}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/llvm.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/llvm.json new file mode 100644 index 00000000..9cb2a26c --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/llvm.json @@ -0,0 +1 @@ +{"keywords":"begin end true false declare define global constant private linker_private internal available_externally linkonce linkonce_odr weak weak_odr appending dllimport dllexport common default hidden protected extern_weak external thread_local zeroinitializer undef null to tail target triple datalayout volatile nuw nsw nnan ninf nsz arcp fast exact inbounds align addrspace section alias module asm sideeffect gc dbg linker_private_weak attributes blockaddress initialexec localdynamic localexec prefix unnamed_addr ccc fastcc coldcc x86_stdcallcc x86_fastcallcc arm_apcscc arm_aapcscc arm_aapcs_vfpcc ptx_device ptx_kernel intel_ocl_bicc msp430_intrcc spir_func spir_kernel x86_64_sysvcc x86_64_win64cc x86_thiscallcc cc c signext zeroext inreg sret nounwind noreturn noalias nocapture byval nest readnone readonly inlinehint noinline alwaysinline optsize ssp sspreq noredzone noimplicitfloat naked builtin cold nobuiltin noduplicate nonlazybind optnone returns_twice sanitize_address sanitize_memory sanitize_thread sspstrong uwtable returned type opaque eq ne slt sgt sle sge ult ugt ule uge oeq one olt ogt ole oge ord uno ueq une x acq_rel acquire alignstack atomic catch cleanup filter inteldialect max min monotonic nand personality release seq_cst singlethread umax umin unordered xchg add fadd sub fsub mul fmul udiv sdiv fdiv urem srem frem shl lshr ashr and or xor icmp fcmp phi call trunc zext sext fptrunc fpext uitofp sitofp fptoui fptosi inttoptr ptrtoint bitcast addrspacecast select va_arg ret br switch invoke unwind unreachable indirectbr landingpad resume malloc alloca free load store getelementptr extractelement insertelement shufflevector getresult extractvalue insertvalue atomicrmw cmpxchg fence argmemonly double","contains":[{"className":"keyword","begin":"i\\d+"},{"className":"comment","begin":";","end":"\\n","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}],"relevance":0},{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0}]},{"className":"string","variants":[{"begin":"\"","end":"[^\\\\]\""}],"relevance":0},{"className":"title","variants":[{"begin":"@([-a-zA-Z$._][\\w\\-$.]*)"},{"begin":"@\\d+"},{"begin":"!([-a-zA-Z$._][\\w\\-$.]*)"},{"begin":"!\\d+([-a-zA-Z$._][\\w\\-$.]*)"}]},{"className":"symbol","variants":[{"begin":"%([-a-zA-Z$._][\\w\\-$.]*)"},{"begin":"%\\d+"},{"begin":"#\\d+"}]},{"className":"number","variants":[{"begin":"0[xX][a-fA-F0-9]+"},{"begin":"-?\\d+(?:[.]\\d+)?(?:[eE][-+]?\\d+(?:[.]\\d+)?)?"}],"relevance":0}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/lsl.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/lsl.json new file mode 100644 index 00000000..9b746f6a --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/lsl.json @@ -0,0 +1 @@ +{"illegal":":","contains":[{"className":"string","begin":"\"","end":"\"","contains":[{"className":"subst","begin":"\\\\[tn\"\\\\]"}]},{"className":"comment","variants":[{"className":"comment","begin":"//","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"/\\*","end":"\\*/","contains":[{"$ref":"#contains.1.variants.0.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]}]},{"className":"number","begin":"(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)"},{"className":"section","variants":[{"begin":"\\b(?:state|default)\\b"},{"begin":"\\b(?:state_(?:entry|exit)|touch(?:_(?:start|end))?|(?:land_)?collision(?:_(?:start|end))?|timer|listen|(?:no_)?sensor|control|(?:not_)?at_(?:rot_)?target|money|email|experience_permissions(?:_denied)?|run_time_permissions|changed|attach|dataserver|moving_(?:start|end)|link_message|(?:on|object)_rez|remote_data|http_re(?:sponse|quest)|path_update|transaction_result)\\b"}]},{"className":"built_in","begin":"\\b(?:ll(?:AgentInExperience|(?:Create|DataSize|Delete|KeyCount|Keys|Read|Update)KeyValue|GetExperience(?:Details|ErrorMessage)|ReturnObjectsBy(?:ID|Owner)|Json(?:2List|[GS]etValue|ValueType)|Sin|Cos|Tan|Atan2|Sqrt|Pow|Abs|Fabs|Frand|Floor|Ceil|Round|Vec(?:Mag|Norm|Dist)|Rot(?:Between|2(?:Euler|Fwd|Left|Up))|(?:Euler|Axes)2Rot|Whisper|(?:Region|Owner)?Say|Shout|Listen(?:Control|Remove)?|Sensor(?:Repeat|Remove)?|Detected(?:Name|Key|Owner|Type|Pos|Vel|Grab|Rot|Group|LinkNumber)|Die|Ground|Wind|(?:[GS]et)(?:AnimationOverride|MemoryLimit|PrimMediaParams|ParcelMusicURL|Object(?:Desc|Name)|PhysicsMaterial|Status|Scale|Color|Alpha|Texture|Pos|Rot|Force|Torque)|ResetAnimationOverride|(?:Scale|Offset|Rotate)Texture|(?:Rot)?Target(?:Remove)?|(?:Stop)?MoveToTarget|Apply(?:Rotational)?Impulse|Set(?:KeyframedMotion|ContentType|RegionPos|(?:Angular)?Velocity|Buoyancy|HoverHeight|ForceAndTorque|TimerEvent|ScriptState|Damage|TextureAnim|Sound(?:Queueing|Radius)|Vehicle(?:Type|(?:Float|Vector|Rotation)Param)|(?:Touch|Sit)?Text|Camera(?:Eye|At)Offset|PrimitiveParams|ClickAction|Link(?:Alpha|Color|PrimitiveParams(?:Fast)?|Texture(?:Anim)?|Camera|Media)|RemoteScriptAccessPin|PayPrice|LocalRot)|ScaleByFactor|Get(?:(?:Max|Min)ScaleFactor|ClosestNavPoint|StaticPath|SimStats|Env|PrimitiveParams|Link(?:PrimitiveParams|Number(?:OfSides)?|Key|Name|Media)|HTTPHeader|FreeURLs|Object(?:Details|PermMask|PrimCount)|Parcel(?:MaxPrims|Details|Prim(?:Count|Owners))|Attached(?:List)?|(?:SPMax|Free|Used)Memory|Region(?:Name|TimeDilation|FPS|Corner|AgentCount)|Root(?:Position|Rotation)|UnixTime|(?:Parcel|Region)Flags|(?:Wall|GMT)clock|SimulatorHostname|BoundingBox|GeometricCenter|Creator|NumberOf(?:Prims|NotecardLines|Sides)|Animation(?:List)?|(?:Camera|Local)(?:Pos|Rot)|Vel|Accel|Omega|Time(?:stamp|OfDay)|(?:Object|CenterOf)?Mass|MassMKS|Energy|Owner|(?:Owner)?Key|SunDirection|Texture(?:Offset|Scale|Rot)|Inventory(?:Number|Name|Key|Type|Creator|PermMask)|Permissions(?:Key)?|StartParameter|List(?:Length|EntryType)|Date|Agent(?:Size|Info|Language|List)|LandOwnerAt|NotecardLine|Script(?:Name|State))|(?:Get|Reset|GetAndReset)Time|PlaySound(?:Slave)?|LoopSound(?:Master|Slave)?|(?:Trigger|Stop|Preload)Sound|(?:(?:Get|Delete)Sub|Insert)String|To(?:Upper|Lower)|Give(?:InventoryList|Money)|RezObject|(?:Stop)?LookAt|Sleep|CollisionFilter|(?:Take|Release)Controls|DetachFromAvatar|AttachToAvatar(?:Temp)?|InstantMessage|(?:GetNext)?Email|StopHover|MinEventDelay|RotLookAt|String(?:Length|Trim)|(?:Start|Stop)Animation|TargetOmega|Request(?:Experience)?Permissions|(?:Create|Break)Link|BreakAllLinks|(?:Give|Remove)Inventory|Water|PassTouches|Request(?:Agent|Inventory)Data|TeleportAgent(?:Home|GlobalCoords)?|ModifyLand|CollisionSound|ResetScript|MessageLinked|PushObject|PassCollisions|AxisAngle2Rot|Rot2(?:Axis|Angle)|A(?:cos|sin)|AngleBetween|AllowInventoryDrop|SubStringIndex|List2(?:CSV|Integer|Json|Float|String|Key|Vector|Rot|List(?:Strided)?)|DeleteSubList|List(?:Statistics|Sort|Randomize|(?:Insert|Find|Replace)List)|EdgeOfWorld|AdjustSoundVolume|Key2Name|TriggerSoundLimited|EjectFromLand|(?:CSV|ParseString)2List|OverMyLand|SameGroup|UnSit|Ground(?:Slope|Normal|Contour)|GroundRepel|(?:Set|Remove)VehicleFlags|(?:AvatarOn)?(?:Link)?SitTarget|Script(?:Danger|Profiler)|Dialog|VolumeDetect|ResetOtherScript|RemoteLoadScriptPin|(?:Open|Close)RemoteDataChannel|SendRemoteData|RemoteDataReply|(?:Integer|String)ToBase64|XorBase64|Log(?:10)?|Base64To(?:String|Integer)|ParseStringKeepNulls|RezAtRoot|RequestSimulatorData|ForceMouselook|(?:Load|Release|(?:E|Une)scape)URL|ParcelMedia(?:CommandList|Query)|ModPow|MapDestination|(?:RemoveFrom|AddTo|Reset)Land(?:Pass|Ban)List|(?:Set|Clear)CameraParams|HTTP(?:Request|Response)|TextBox|DetectedTouch(?:UV|Face|Pos|(?:N|Bin)ormal|ST)|(?:MD5|SHA1|DumpList2)String|Request(?:Secure)?URL|Clear(?:Prim|Link)Media|(?:Link)?ParticleSystem|(?:Get|Request)(?:Username|DisplayName)|RegionSayTo|CastRay|GenerateKey|TransferLindenDollars|ManageEstateAccess|(?:Create|Delete)Character|ExecCharacterCmd|Evade|FleeFrom|NavigateTo|PatrolPoints|Pursue|UpdateCharacter|WanderWithin))\\b"},{"className":"literal","variants":[{"begin":"\\b(?:PI|TWO_PI|PI_BY_TWO|DEG_TO_RAD|RAD_TO_DEG|SQRT2)\\b"},{"begin":"\\b(?:XP_ERROR_(?:EXPERIENCES_DISABLED|EXPERIENCE_(?:DISABLED|SUSPENDED)|INVALID_(?:EXPERIENCE|PARAMETERS)|KEY_NOT_FOUND|MATURITY_EXCEEDED|NONE|NOT_(?:FOUND|PERMITTED(?:_LAND)?)|NO_EXPERIENCE|QUOTA_EXCEEDED|RETRY_UPDATE|STORAGE_EXCEPTION|STORE_DISABLED|THROTTLED|UNKNOWN_ERROR)|JSON_APPEND|STATUS_(?:PHYSICS|ROTATE_[XYZ]|PHANTOM|SANDBOX|BLOCK_GRAB(?:_OBJECT)?|(?:DIE|RETURN)_AT_EDGE|CAST_SHADOWS|OK|MALFORMED_PARAMS|TYPE_MISMATCH|BOUNDS_ERROR|NOT_(?:FOUND|SUPPORTED)|INTERNAL_ERROR|WHITELIST_FAILED)|AGENT(?:_(?:BY_(?:LEGACY_|USER)NAME|FLYING|ATTACHMENTS|SCRIPTED|MOUSELOOK|SITTING|ON_OBJECT|AWAY|WALKING|IN_AIR|TYPING|CROUCHING|BUSY|ALWAYS_RUN|AUTOPILOT|LIST_(?:PARCEL(?:_OWNER)?|REGION)))?|CAMERA_(?:PITCH|DISTANCE|BEHINDNESS_(?:ANGLE|LAG)|(?:FOCUS|POSITION)(?:_(?:THRESHOLD|LOCKED|LAG))?|FOCUS_OFFSET|ACTIVE)|ANIM_ON|LOOP|REVERSE|PING_PONG|SMOOTH|ROTATE|SCALE|ALL_SIDES|LINK_(?:ROOT|SET|ALL_(?:OTHERS|CHILDREN)|THIS)|ACTIVE|PASS(?:IVE|_(?:ALWAYS|IF_NOT_HANDLED|NEVER))|SCRIPTED|CONTROL_(?:FWD|BACK|(?:ROT_)?(?:LEFT|RIGHT)|UP|DOWN|(?:ML_)?LBUTTON)|PERMISSION_(?:RETURN_OBJECTS|DEBIT|OVERRIDE_ANIMATIONS|SILENT_ESTATE_MANAGEMENT|TAKE_CONTROLS|TRIGGER_ANIMATION|ATTACH|CHANGE_LINKS|(?:CONTROL|TRACK)_CAMERA|TELEPORT)|INVENTORY_(?:TEXTURE|SOUND|OBJECT|SCRIPT|LANDMARK|CLOTHING|NOTECARD|BODYPART|ANIMATION|GESTURE|ALL|NONE)|CHANGED_(?:INVENTORY|COLOR|SHAPE|SCALE|TEXTURE|LINK|ALLOWED_DROP|OWNER|REGION(?:_START)?|TELEPORT|MEDIA)|OBJECT_(?:CLICK_ACTION|HOVER_HEIGHT|LAST_OWNER_ID|(?:PHYSICS|SERVER|STREAMING)_COST|UNKNOWN_DETAIL|CHARACTER_TIME|PHANTOM|PHYSICS|TEMP_ON_REZ|NAME|DESC|POS|PRIM_(?:COUNT|EQUIVALENCE)|RETURN_(?:PARCEL(?:_OWNER)?|REGION)|REZZER_KEY|ROO?T|VELOCITY|OMEGA|OWNER|GROUP|CREATOR|ATTACHED_POINT|RENDER_WEIGHT|(?:BODY_SHAPE|PATHFINDING)_TYPE|(?:RUNNING|TOTAL)_SCRIPT_COUNT|TOTAL_INVENTORY_COUNT|SCRIPT_(?:MEMORY|TIME))|TYPE_(?:INTEGER|FLOAT|STRING|KEY|VECTOR|ROTATION|INVALID)|(?:DEBUG|PUBLIC)_CHANNEL|ATTACH_(?:AVATAR_CENTER|CHEST|HEAD|BACK|PELVIS|MOUTH|CHIN|NECK|NOSE|BELLY|[LR](?:SHOULDER|HAND|FOOT|EAR|EYE|[UL](?:ARM|LEG)|HIP)|(?:LEFT|RIGHT)_PEC|HUD_(?:CENTER_[12]|TOP_(?:RIGHT|CENTER|LEFT)|BOTTOM(?:_(?:RIGHT|LEFT))?)|[LR]HAND_RING1|TAIL_(?:BASE|TIP)|[LR]WING|FACE_(?:JAW|[LR]EAR|[LR]EYE|TOUNGE)|GROIN|HIND_[LR]FOOT)|LAND_(?:LEVEL|RAISE|LOWER|SMOOTH|NOISE|REVERT)|DATA_(?:ONLINE|NAME|BORN|SIM_(?:POS|STATUS|RATING)|PAYINFO)|PAYMENT_INFO_(?:ON_FILE|USED)|REMOTE_DATA_(?:CHANNEL|REQUEST|REPLY)|PSYS_(?:PART_(?:BF_(?:ZERO|ONE(?:_MINUS_(?:DEST_COLOR|SOURCE_(ALPHA|COLOR)))?|DEST_COLOR|SOURCE_(ALPHA|COLOR))|BLEND_FUNC_(DEST|SOURCE)|FLAGS|(?:START|END)_(?:COLOR|ALPHA|SCALE|GLOW)|MAX_AGE|(?:RIBBON|WIND|INTERP_(?:COLOR|SCALE)|BOUNCE|FOLLOW_(?:SRC|VELOCITY)|TARGET_(?:POS|LINEAR)|EMISSIVE)_MASK)|SRC_(?:MAX_AGE|PATTERN|ANGLE_(?:BEGIN|END)|BURST_(?:RATE|PART_COUNT|RADIUS|SPEED_(?:MIN|MAX))|ACCEL|TEXTURE|TARGET_KEY|OMEGA|PATTERN_(?:DROP|EXPLODE|ANGLE(?:_CONE(?:_EMPTY)?)?)))|VEHICLE_(?:REFERENCE_FRAME|TYPE_(?:NONE|SLED|CAR|BOAT|AIRPLANE|BALLOON)|(?:LINEAR|ANGULAR)_(?:FRICTION_TIMESCALE|MOTOR_DIRECTION)|LINEAR_MOTOR_OFFSET|HOVER_(?:HEIGHT|EFFICIENCY|TIMESCALE)|BUOYANCY|(?:LINEAR|ANGULAR)_(?:DEFLECTION_(?:EFFICIENCY|TIMESCALE)|MOTOR_(?:DECAY_)?TIMESCALE)|VERTICAL_ATTRACTION_(?:EFFICIENCY|TIMESCALE)|BANKING_(?:EFFICIENCY|MIX|TIMESCALE)|FLAG_(?:NO_DEFLECTION_UP|LIMIT_(?:ROLL_ONLY|MOTOR_UP)|HOVER_(?:(?:WATER|TERRAIN|UP)_ONLY|GLOBAL_HEIGHT)|MOUSELOOK_(?:STEER|BANK)|CAMERA_DECOUPLED))|PRIM_(?:ALPHA_MODE(?:_(?:BLEND|EMISSIVE|MASK|NONE))?|NORMAL|SPECULAR|TYPE(?:_(?:BOX|CYLINDER|PRISM|SPHERE|TORUS|TUBE|RING|SCULPT))?|HOLE_(?:DEFAULT|CIRCLE|SQUARE|TRIANGLE)|MATERIAL(?:_(?:STONE|METAL|GLASS|WOOD|FLESH|PLASTIC|RUBBER))?|SHINY_(?:NONE|LOW|MEDIUM|HIGH)|BUMP_(?:NONE|BRIGHT|DARK|WOOD|BARK|BRICKS|CHECKER|CONCRETE|TILE|STONE|DISKS|GRAVEL|BLOBS|SIDING|LARGETILE|STUCCO|SUCTION|WEAVE)|TEXGEN_(?:DEFAULT|PLANAR)|SCULPT_(?:TYPE_(?:SPHERE|TORUS|PLANE|CYLINDER|MASK)|FLAG_(?:MIRROR|INVERT))|PHYSICS(?:_(?:SHAPE_(?:CONVEX|NONE|PRIM|TYPE)))?|(?:POS|ROT)_LOCAL|SLICE|TEXT|FLEXIBLE|POINT_LIGHT|TEMP_ON_REZ|PHANTOM|POSITION|SIZE|ROTATION|TEXTURE|NAME|OMEGA|DESC|LINK_TARGET|COLOR|BUMP_SHINY|FULLBRIGHT|TEXGEN|GLOW|MEDIA_(?:ALT_IMAGE_ENABLE|CONTROLS|(?:CURRENT|HOME)_URL|AUTO_(?:LOOP|PLAY|SCALE|ZOOM)|FIRST_CLICK_INTERACT|(?:WIDTH|HEIGHT)_PIXELS|WHITELIST(?:_ENABLE)?|PERMS_(?:INTERACT|CONTROL)|PARAM_MAX|CONTROLS_(?:STANDARD|MINI)|PERM_(?:NONE|OWNER|GROUP|ANYONE)|MAX_(?:URL_LENGTH|WHITELIST_(?:SIZE|COUNT)|(?:WIDTH|HEIGHT)_PIXELS)))|MASK_(?:BASE|OWNER|GROUP|EVERYONE|NEXT)|PERM_(?:TRANSFER|MODIFY|COPY|MOVE|ALL)|PARCEL_(?:MEDIA_COMMAND_(?:STOP|PAUSE|PLAY|LOOP|TEXTURE|URL|TIME|AGENT|UNLOAD|AUTO_ALIGN|TYPE|SIZE|DESC|LOOP_SET)|FLAG_(?:ALLOW_(?:FLY|(?:GROUP_)?SCRIPTS|LANDMARK|TERRAFORM|DAMAGE|CREATE_(?:GROUP_)?OBJECTS)|USE_(?:ACCESS_(?:GROUP|LIST)|BAN_LIST|LAND_PASS_LIST)|LOCAL_SOUND_ONLY|RESTRICT_PUSHOBJECT|ALLOW_(?:GROUP|ALL)_OBJECT_ENTRY)|COUNT_(?:TOTAL|OWNER|GROUP|OTHER|SELECTED|TEMP)|DETAILS_(?:NAME|DESC|OWNER|GROUP|AREA|ID|SEE_AVATARS))|LIST_STAT_(?:MAX|MIN|MEAN|MEDIAN|STD_DEV|SUM(?:_SQUARES)?|NUM_COUNT|GEOMETRIC_MEAN|RANGE)|PAY_(?:HIDE|DEFAULT)|REGION_FLAG_(?:ALLOW_DAMAGE|FIXED_SUN|BLOCK_TERRAFORM|SANDBOX|DISABLE_(?:COLLISIONS|PHYSICS)|BLOCK_FLY|ALLOW_DIRECT_TELEPORT|RESTRICT_PUSHOBJECT)|HTTP_(?:METHOD|MIMETYPE|BODY_(?:MAXLENGTH|TRUNCATED)|CUSTOM_HEADER|PRAGMA_NO_CACHE|VERBOSE_THROTTLE|VERIFY_CERT)|STRING_(?:TRIM(?:_(?:HEAD|TAIL))?)|CLICK_ACTION_(?:NONE|TOUCH|SIT|BUY|PAY|OPEN(?:_MEDIA)?|PLAY|ZOOM)|TOUCH_INVALID_FACE|PROFILE_(?:NONE|SCRIPT_MEMORY)|RC_(?:DATA_FLAGS|DETECT_PHANTOM|GET_(?:LINK_NUM|NORMAL|ROOT_KEY)|MAX_HITS|REJECT_(?:TYPES|AGENTS|(?:NON)?PHYSICAL|LAND))|RCERR_(?:CAST_TIME_EXCEEDED|SIM_PERF_LOW|UNKNOWN)|ESTATE_ACCESS_(?:ALLOWED_(?:AGENT|GROUP)_(?:ADD|REMOVE)|BANNED_AGENT_(?:ADD|REMOVE))|DENSITY|FRICTION|RESTITUTION|GRAVITY_MULTIPLIER|KFM_(?:COMMAND|CMD_(?:PLAY|STOP|PAUSE)|MODE|FORWARD|LOOP|PING_PONG|REVERSE|DATA|ROTATION|TRANSLATION)|ERR_(?:GENERIC|PARCEL_PERMISSIONS|MALFORMED_PARAMS|RUNTIME_PERMISSIONS|THROTTLED)|CHARACTER_(?:CMD_(?:(?:SMOOTH_)?STOP|JUMP)|DESIRED_(?:TURN_)?SPEED|RADIUS|STAY_WITHIN_PARCEL|LENGTH|ORIENTATION|ACCOUNT_FOR_SKIPPED_FRAMES|AVOIDANCE_MODE|TYPE(?:_(?:[ABCD]|NONE))?|MAX_(?:DECEL|TURN_RADIUS|(?:ACCEL|SPEED)))|PURSUIT_(?:OFFSET|FUZZ_FACTOR|GOAL_TOLERANCE|INTERCEPT)|REQUIRE_LINE_OF_SIGHT|FORCE_DIRECT_PATH|VERTICAL|HORIZONTAL|AVOID_(?:CHARACTERS|DYNAMIC_OBSTACLES|NONE)|PU_(?:EVADE_(?:HIDDEN|SPOTTED)|FAILURE_(?:DYNAMIC_PATHFINDING_DISABLED|INVALID_(?:GOAL|START)|NO_(?:NAVMESH|VALID_DESTINATION)|OTHER|TARGET_GONE|(?:PARCEL_)?UNREACHABLE)|(?:GOAL|SLOWDOWN_DISTANCE)_REACHED)|TRAVERSAL_TYPE(?:_(?:FAST|NONE|SLOW))?|CONTENT_TYPE_(?:ATOM|FORM|HTML|JSON|LLSD|RSS|TEXT|XHTML|XML)|GCNP_(?:RADIUS|STATIC)|(?:PATROL|WANDER)_PAUSE_AT_WAYPOINTS|OPT_(?:AVATAR|CHARACTER|EXCLUSION_VOLUME|LEGACY_LINKSET|MATERIAL_VOLUME|OTHER|STATIC_OBSTACLE|WALKABLE)|SIM_STAT_PCT_CHARS_STEPPED)\\b"},{"begin":"\\b(?:FALSE|TRUE)\\b"},{"begin":"\\b(?:ZERO_ROTATION)\\b"},{"begin":"\\b(?:EOF|JSON_(?:ARRAY|DELETE|FALSE|INVALID|NULL|NUMBER|OBJECT|STRING|TRUE)|NULL_KEY|TEXTURE_(?:BLANK|DEFAULT|MEDIA|PLYWOOD|TRANSPARENT)|URL_REQUEST_(?:GRANTED|DENIED))\\b"},{"begin":"\\b(?:ZERO_VECTOR|TOUCH_INVALID_(?:TEXCOORD|VECTOR))\\b"}]},{"className":"type","begin":"\\b(?:integer|float|string|key|vector|quaternion|rotation|list)\\b"}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/lua.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/lua.json new file mode 100644 index 00000000..2319b369 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/lua.json @@ -0,0 +1 @@ +{"lexemes":"[a-zA-Z_]\\w*","keywords":{"literal":"true false nil","keyword":"and break do else elseif end for goto if in local not or repeat return then until while","built_in":"_G _ENV _VERSION __index __newindex __mode __call __metatable __tostring __len __gc __add __sub __mul __div __mod __pow __concat __unm __eq __lt __le assert collectgarbage dofile error getfenv getmetatable ipairs load loadfile loadstringmodule next pairs pcall print rawequal rawget rawset require select setfenvsetmetatable tonumber tostring type unpack xpcall arg selfcoroutine resume yield status wrap create running debug getupvalue debug sethook getmetatable gethook setmetatable setlocal traceback setfenv getinfo setupvalue getlocal getregistry getfenv io lines write close flush open output type read stderr stdin input stdout popen tmpfile math log max acos huge ldexp pi cos tanh pow deg tan cosh sinh random randomseed frexp ceil floor rad abs sqrt modf asin min mod fmod log10 atan2 exp sin atan os exit setlocale date getenv difftime remove time clock tmpname rename execute package preload loadlib loaded loaders cpath config path seeall string sub upper len gfind rep find match char dump gmatch reverse byte format gsub lower table setn insert getn foreachi maxn foreach concat sort remove"},"contains":[{"className":"comment","begin":"--(?!\\[=*\\[)","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"--\\[=*\\[","end":"\\]=*\\]","contains":[{"begin":"\\[=*\\[","end":"\\]=*\\]","contains":["self"]},{"$ref":"#contains.0.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}],"relevance":10},{"className":"function","beginKeywords":"function","end":"\\)","contains":[{"className":"title","begin":"([_a-zA-Z]\\w*\\.)*([_a-zA-Z]\\w*:)?[_a-zA-Z]\\w*","relevance":0},{"className":"params","begin":"\\(","endsWithParent":true,"contains":[{"$ref":"#contains.0"},{"$ref":"#contains.1"}]},{"$ref":"#contains.0"},{"$ref":"#contains.1"}]},{"className":"number","begin":"(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)","relevance":0},{"className":"string","begin":"'","end":"'","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0}]},{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"$ref":"#contains.4.contains.0"}]},{"className":"string","begin":"\\[=*\\[","end":"\\]=*\\]","contains":[{"$ref":"#contains.1.contains.0"}],"relevance":5}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/makefile.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/makefile.json new file mode 100644 index 00000000..c949f9b7 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/makefile.json @@ -0,0 +1 @@ +{"aliases":["mk","mak"],"keywords":"define endef undefine ifdef ifndef ifeq ifneq else endif include -include sinclude override export unexport private vpath","lexemes":"[\\w-]+","contains":[{"className":"comment","begin":"#","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"variable","variants":[{"begin":"\\$\\([a-zA-Z_]\\w*\\)","contains":[{"begin":"\\\\[\\s\\S]","relevance":0}]},{"begin":"\\$[@%","subLanguage":"xml","relevance":0},{"className":"bullet","begin":"^\\s*([*+-]|(\\d+\\.))\\s+"},{"className":"strong","begin":"[*_]{2}.+?[*_]{2}"},{"className":"emphasis","variants":[{"begin":"\\*.+?\\*"},{"begin":"_.+?_","relevance":0}]},{"className":"quote","begin":"^>\\s+","end":"$"},{"className":"code","variants":[{"begin":"^```w*s*$","end":"^```s*$"},{"begin":"`.+?`"},{"begin":"^( {4}|\t)","end":"$","relevance":0}]},{"begin":"^[-\\*]{3,}","end":"$"},{"begin":"\\[.+?\\][\\(\\[].*?[\\)\\]]","returnBegin":true,"contains":[{"className":"string","begin":"\\[","end":"\\]","excludeBegin":true,"returnEnd":true,"relevance":0},{"className":"link","begin":"\\]\\(","end":"\\)","excludeBegin":true,"excludeEnd":true},{"className":"symbol","begin":"\\]\\[","end":"\\]","excludeBegin":true,"excludeEnd":true}],"relevance":10},{"begin":"^\\[[^\\n]+\\]:","returnBegin":true,"contains":[{"className":"symbol","begin":"\\[","end":"\\]","excludeBegin":true,"excludeEnd":true},{"className":"link","begin":":\\s*","end":"$","excludeBegin":true}]}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/mathematica.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/mathematica.json new file mode 100644 index 00000000..1a193af2 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/mathematica.json @@ -0,0 +1 @@ +{"aliases":["mma","wl"],"lexemes":"(\\$|\\b)[a-zA-Z]\\w*\\b","keywords":"AASTriangle AbelianGroup Abort AbortKernels AbortProtect AbortScheduledTask Above Abs AbsArg AbsArgPlot Absolute AbsoluteCorrelation AbsoluteCorrelationFunction AbsoluteCurrentValue AbsoluteDashing AbsoluteFileName AbsoluteOptions AbsolutePointSize AbsoluteThickness AbsoluteTime AbsoluteTiming AcceptanceThreshold AccountingForm Accumulate Accuracy AccuracyGoal ActionDelay ActionMenu ActionMenuBox ActionMenuBoxOptions Activate Active ActiveClassification ActiveClassificationObject ActiveItem ActivePrediction ActivePredictionObject ActiveStyle AcyclicGraphQ AddOnHelpPath AddSides AddTo AddToSearchIndex AddUsers AdjacencyGraph AdjacencyList AdjacencyMatrix AdjustmentBox AdjustmentBoxOptions AdjustTimeSeriesForecast AdministrativeDivisionData AffineHalfSpace AffineSpace AffineStateSpaceModel AffineTransform After AggregatedEntityClass AggregationLayer AircraftData AirportData AirPressureData AirTemperatureData AiryAi AiryAiPrime AiryAiZero AiryBi AiryBiPrime AiryBiZero AlgebraicIntegerQ AlgebraicNumber AlgebraicNumberDenominator AlgebraicNumberNorm AlgebraicNumberPolynomial AlgebraicNumberTrace AlgebraicRules AlgebraicRulesData Algebraics AlgebraicUnitQ Alignment AlignmentMarker AlignmentPoint All AllowAdultContent AllowedCloudExtraParameters AllowedCloudParameterExtensions AllowedDimensions AllowedFrequencyRange AllowedHeads AllowGroupClose AllowIncomplete AllowInlineCells AllowKernelInitialization AllowLooseGrammar AllowReverseGroupClose AllowScriptLevelChange AllTrue Alphabet AlphabeticOrder AlphabeticSort AlphaChannel AlternateImage AlternatingFactorial AlternatingGroup AlternativeHypothesis Alternatives AltitudeMethod AmbientLight AmbiguityFunction AmbiguityList Analytic AnatomyData AnatomyForm AnatomyPlot3D AnatomySkinStyle AnatomyStyling AnchoredSearch And AndersonDarlingTest AngerJ AngleBisector AngleBracket AnglePath AnglePath3D AngleVector AngularGauge Animate AnimationCycleOffset AnimationCycleRepetitions AnimationDirection AnimationDisplayTime AnimationRate AnimationRepetitions AnimationRunning AnimationRunTime AnimationTimeIndex Animator AnimatorBox AnimatorBoxOptions AnimatorElements Annotate Annotation AnnotationDelete AnnotationNames AnnotationRules AnnotationValue Annuity AnnuityDue Annulus AnomalyDetection AnomalyDetectorFunction Anonymous Antialiasing AntihermitianMatrixQ Antisymmetric AntisymmetricMatrixQ Antonyms AnyOrder AnySubset AnyTrue Apart ApartSquareFree APIFunction Appearance AppearanceElements AppearanceRules AppellF1 Append AppendCheck AppendLayer AppendTo ApplicationIdentificationKey Apply ApplySides ArcCos ArcCosh ArcCot ArcCoth ArcCsc ArcCsch ArcCurvature ARCHProcess ArcLength ArcSec ArcSech ArcSin ArcSinDistribution ArcSinh ArcTan ArcTanh Area Arg ArgMax ArgMin ArgumentCountQ ARIMAProcess ArithmeticGeometricMean ARMAProcess Around AroundReplace ARProcess Array ArrayComponents ArrayDepth ArrayFilter ArrayFlatten ArrayMesh ArrayPad ArrayPlot ArrayQ ArrayResample ArrayReshape ArrayRules Arrays Arrow Arrow3DBox ArrowBox Arrowheads ASATriangle Ask AskAppend AskConfirm AskDisplay AskedQ AskedValue AskFunction AskState AskTemplateDisplay AspectRatio AspectRatioFixed Assert AssociateTo Association AssociationFormat AssociationMap AssociationQ AssociationThread AssumeDeterministic Assuming Assumptions AstronomicalData AsymptoticDSolveValue AsymptoticEqual AsymptoticEquivalent AsymptoticGreater AsymptoticGreaterEqual AsymptoticIntegrate AsymptoticLess AsymptoticLessEqual AsymptoticOutputTracker AsymptoticRSolveValue AsymptoticSolve AsymptoticSum Asynchronous AsynchronousTaskObject AsynchronousTasks Atom AtomCoordinates AtomCount AtomDiagramCoordinates AtomList AtomQ AttentionLayer Attributes Audio AudioAmplify AudioAnnotate AudioAnnotationLookup AudioBlockMap AudioCapture AudioChannelAssignment AudioChannelCombine AudioChannelMix AudioChannels AudioChannelSeparate AudioData AudioDelay AudioDelete AudioDevice AudioDistance AudioFade AudioFrequencyShift AudioGenerator AudioIdentify AudioInputDevice AudioInsert AudioIntervals AudioJoin AudioLabel AudioLength AudioLocalMeasurements AudioLooping AudioLoudness AudioMeasurements AudioNormalize AudioOutputDevice AudioOverlay AudioPad AudioPan AudioPartition AudioPause AudioPitchShift AudioPlay AudioPlot AudioQ AudioRecord AudioReplace AudioResample AudioReverb AudioSampleRate AudioSpectralMap AudioSpectralTransformation AudioSplit AudioStop AudioStream AudioStreams AudioTimeStretch AudioTrim AudioType AugmentedPolyhedron AugmentedSymmetricPolynomial Authenticate Authentication AuthenticationDialog AutoAction Autocomplete AutocompletionFunction AutoCopy AutocorrelationTest AutoDelete AutoEvaluateEvents AutoGeneratedPackage AutoIndent AutoIndentSpacings AutoItalicWords AutoloadPath AutoMatch Automatic AutomaticImageSize AutoMultiplicationSymbol AutoNumberFormatting AutoOpenNotebooks AutoOpenPalettes AutoQuoteCharacters AutoRefreshed AutoRemove AutorunSequencing AutoScaling AutoScroll AutoSpacing AutoStyleOptions AutoStyleWords AutoSubmitting Axes AxesEdge AxesLabel AxesOrigin AxesStyle AxiomaticTheory AxisBabyMonsterGroupB Back Background BackgroundAppearance BackgroundTasksSettings Backslash Backsubstitution Backward Ball Band BandpassFilter BandstopFilter BarabasiAlbertGraphDistribution BarChart BarChart3D BarcodeImage BarcodeRecognize BaringhausHenzeTest BarLegend BarlowProschanImportance BarnesG BarOrigin BarSpacing BartlettHannWindow BartlettWindow BaseDecode BaseEncode BaseForm Baseline BaselinePosition BaseStyle BasicRecurrentLayer BatchNormalizationLayer BatchSize BatesDistribution BattleLemarieWavelet BayesianMaximization BayesianMaximizationObject BayesianMinimization BayesianMinimizationObject Because BeckmannDistribution Beep Before Begin BeginDialogPacket BeginFrontEndInteractionPacket BeginPackage BellB BellY Below BenfordDistribution BeniniDistribution BenktanderGibratDistribution BenktanderWeibullDistribution BernoulliB BernoulliDistribution BernoulliGraphDistribution BernoulliProcess BernsteinBasis BesselFilterModel BesselI BesselJ BesselJZero BesselK BesselY BesselYZero Beta BetaBinomialDistribution BetaDistribution BetaNegativeBinomialDistribution BetaPrimeDistribution BetaRegularized Between BetweennessCentrality BeveledPolyhedron BezierCurve BezierCurve3DBox BezierCurve3DBoxOptions BezierCurveBox BezierCurveBoxOptions BezierFunction BilateralFilter Binarize BinaryDeserialize BinaryDistance BinaryFormat BinaryImageQ BinaryRead BinaryReadList BinarySerialize BinaryWrite BinCounts BinLists Binomial BinomialDistribution BinomialProcess BinormalDistribution BiorthogonalSplineWavelet BipartiteGraphQ BiquadraticFilterModel BirnbaumImportance BirnbaumSaundersDistribution BitAnd BitClear BitGet BitLength BitNot BitOr BitSet BitShiftLeft BitShiftRight BitXor BiweightLocation BiweightMidvariance Black BlackmanHarrisWindow BlackmanNuttallWindow BlackmanWindow Blank BlankForm BlankNullSequence BlankSequence Blend Block BlockchainAddressData BlockchainBase BlockchainBlockData BlockchainContractValue BlockchainData BlockchainGet BlockchainKeyEncode BlockchainPut BlockchainTokenData BlockchainTransaction BlockchainTransactionData BlockchainTransactionSign BlockchainTransactionSubmit BlockMap BlockRandom BlomqvistBeta BlomqvistBetaTest Blue Blur BodePlot BohmanWindow Bold Bond BondCount BondList BondQ Bookmarks Boole BooleanConsecutiveFunction BooleanConvert BooleanCountingFunction BooleanFunction BooleanGraph BooleanMaxterms BooleanMinimize BooleanMinterms BooleanQ BooleanRegion Booleans BooleanStrings BooleanTable BooleanVariables BorderDimensions BorelTannerDistribution Bottom BottomHatTransform BoundaryDiscretizeGraphics BoundaryDiscretizeRegion BoundaryMesh BoundaryMeshRegion BoundaryMeshRegionQ BoundaryStyle BoundedRegionQ BoundingRegion Bounds Box BoxBaselineShift BoxData BoxDimensions Boxed Boxes BoxForm BoxFormFormatTypes BoxFrame BoxID BoxMargins BoxMatrix BoxObject BoxRatios BoxRotation BoxRotationPoint BoxStyle BoxWhiskerChart Bra BracketingBar BraKet BrayCurtisDistance BreadthFirstScan Break BridgeData BrightnessEqualize BroadcastStationData Brown BrownForsytheTest BrownianBridgeProcess BrowserCategory BSplineBasis BSplineCurve BSplineCurve3DBox BSplineCurve3DBoxOptions BSplineCurveBox BSplineCurveBoxOptions BSplineFunction BSplineSurface BSplineSurface3DBox BSplineSurface3DBoxOptions BubbleChart BubbleChart3D BubbleScale BubbleSizes BuildingData BulletGauge BusinessDayQ ButterflyGraph ButterworthFilterModel Button ButtonBar ButtonBox ButtonBoxOptions ButtonCell ButtonContents ButtonData ButtonEvaluator ButtonExpandable ButtonFrame ButtonFunction ButtonMargins ButtonMinHeight ButtonNote ButtonNotebook ButtonSource ButtonStyle ButtonStyleMenuListing Byte ByteArray ByteArrayFormat ByteArrayQ ByteArrayToString ByteCount ByteOrderingC CachedValue CacheGraphics CachePersistence CalendarConvert CalendarData CalendarType Callout CalloutMarker CalloutStyle CallPacket CanberraDistance Cancel CancelButton CandlestickChart CanonicalGraph CanonicalizePolygon CanonicalizePolyhedron CanonicalName CanonicalWarpingCorrespondence CanonicalWarpingDistance CantorMesh CantorStaircase Cap CapForm CapitalDifferentialD Capitalize CapsuleShape CaptureRunning CardinalBSplineBasis CarlemanLinearize CarmichaelLambda CaseOrdering Cases CaseSensitive Cashflow Casoratian Catalan CatalanNumber Catch Catenate CatenateLayer CauchyDistribution CauchyWindow CayleyGraph CDF CDFDeploy CDFInformation CDFWavelet Ceiling CelestialSystem Cell CellAutoOverwrite CellBaseline CellBoundingBox CellBracketOptions CellChangeTimes CellContents CellContext CellDingbat CellDynamicExpression CellEditDuplicate CellElementsBoundingBox CellElementSpacings CellEpilog CellEvaluationDuplicate CellEvaluationFunction CellEvaluationLanguage CellEventActions CellFrame CellFrameColor CellFrameLabelMargins CellFrameLabels CellFrameMargins CellGroup CellGroupData CellGrouping CellGroupingRules CellHorizontalScrolling CellID CellLabel CellLabelAutoDelete CellLabelMargins CellLabelPositioning CellLabelStyle CellLabelTemplate CellMargins CellObject CellOpen CellPrint CellProlog Cells CellSize CellStyle CellTags CellularAutomaton CensoredDistribution Censoring Center CenterArray CenterDot CentralFeature CentralMoment CentralMomentGeneratingFunction Cepstrogram CepstrogramArray CepstrumArray CForm ChampernowneNumber ChangeOptions ChannelBase ChannelBrokerAction ChannelDatabin ChannelHistoryLength ChannelListen ChannelListener ChannelListeners ChannelListenerWait ChannelObject ChannelPreSendFunction ChannelReceiverFunction ChannelSend ChannelSubscribers ChanVeseBinarize Character CharacterCounts CharacterEncoding CharacterEncodingsPath CharacteristicFunction CharacteristicPolynomial CharacterName CharacterRange Characters ChartBaseStyle ChartElementData ChartElementDataFunction ChartElementFunction ChartElements ChartLabels ChartLayout ChartLegends ChartStyle Chebyshev1FilterModel Chebyshev2FilterModel ChebyshevDistance ChebyshevT ChebyshevU Check CheckAbort CheckAll Checkbox CheckboxBar CheckboxBox CheckboxBoxOptions ChemicalData ChessboardDistance ChiDistribution ChineseRemainder ChiSquareDistribution ChoiceButtons ChoiceDialog CholeskyDecomposition Chop ChromaticityPlot ChromaticityPlot3D ChromaticPolynomial Circle CircleBox CircleDot CircleMinus CirclePlus CirclePoints CircleThrough CircleTimes CirculantGraph CircularOrthogonalMatrixDistribution CircularQuaternionMatrixDistribution CircularRealMatrixDistribution CircularSymplecticMatrixDistribution CircularUnitaryMatrixDistribution Circumsphere CityData ClassifierFunction ClassifierInformation ClassifierMeasurements ClassifierMeasurementsObject Classify ClassPriors Clear ClearAll ClearAttributes ClearCookies ClearPermissions ClearSystemCache ClebschGordan ClickPane Clip ClipboardNotebook ClipFill ClippingStyle ClipPlanes ClipPlanesStyle ClipRange Clock ClockGauge ClockwiseContourIntegral Close Closed CloseKernels ClosenessCentrality Closing ClosingAutoSave ClosingEvent CloudAccountData CloudBase CloudConnect CloudDeploy CloudDirectory CloudDisconnect CloudEvaluate CloudExport CloudExpression CloudExpressions CloudFunction CloudGet CloudImport CloudLoggingData CloudObject CloudObjectInformation CloudObjectInformationData CloudObjectNameFormat CloudObjects CloudObjectURLType CloudPublish CloudPut CloudRenderingMethod CloudSave CloudShare CloudSubmit CloudSymbol CloudUnshare ClusterClassify ClusterDissimilarityFunction ClusteringComponents ClusteringTree CMYKColor Coarse CodeAssistOptions Coefficient CoefficientArrays CoefficientDomain CoefficientList CoefficientRules CoifletWavelet Collect Colon ColonForm ColorBalance ColorCombine ColorConvert ColorCoverage ColorData ColorDataFunction ColorDetect ColorDistance ColorFunction ColorFunctionScaling Colorize ColorNegate ColorOutput ColorProfileData ColorQ ColorQuantize ColorReplace ColorRules ColorSelectorSettings ColorSeparate ColorSetter ColorSetterBox ColorSetterBoxOptions ColorSlider ColorsNear ColorSpace ColorToneMapping Column ColumnAlignments ColumnBackgrounds ColumnForm ColumnLines ColumnsEqual ColumnSpacings ColumnWidths CombinedEntityClass CombinerFunction CometData CommonDefaultFormatTypes Commonest CommonestFilter CommonName CommonUnits CommunityBoundaryStyle CommunityGraphPlot CommunityLabels CommunityRegionStyle CompanyData CompatibleUnitQ CompilationOptions CompilationTarget Compile Compiled CompiledCodeFunction CompiledFunction CompilerOptions Complement CompleteGraph CompleteGraphQ CompleteKaryTree CompletionsListPacket Complex Complexes ComplexExpand ComplexInfinity ComplexityFunction ComplexListPlot ComplexPlot ComplexPlot3D ComponentMeasurements ComponentwiseContextMenu Compose ComposeList ComposeSeries CompositeQ Composition CompoundElement CompoundExpression CompoundPoissonDistribution CompoundPoissonProcess CompoundRenewalProcess Compress CompressedData ComputeUncertainty Condition ConditionalExpression Conditioned Cone ConeBox ConfidenceLevel ConfidenceRange ConfidenceTransform ConfigurationPath ConformAudio ConformImages Congruent ConicHullRegion ConicHullRegion3DBox ConicHullRegionBox ConicOptimization Conjugate ConjugateTranspose Conjunction Connect ConnectedComponents ConnectedGraphComponents ConnectedGraphQ ConnectedMeshComponents ConnectedMoleculeComponents ConnectedMoleculeQ ConnectionSettings ConnectLibraryCallbackFunction ConnectSystemModelComponents ConnesWindow ConoverTest ConsoleMessage ConsoleMessagePacket ConsolePrint Constant ConstantArray ConstantArrayLayer ConstantImage ConstantPlusLayer ConstantRegionQ Constants ConstantTimesLayer ConstellationData ConstrainedMax ConstrainedMin Construct Containing ContainsAll ContainsAny ContainsExactly ContainsNone ContainsOnly ContentFieldOptions ContentLocationFunction ContentObject ContentPadding ContentsBoundingBox ContentSelectable ContentSize Context ContextMenu Contexts ContextToFileName Continuation Continue ContinuedFraction ContinuedFractionK ContinuousAction ContinuousMarkovProcess ContinuousTask ContinuousTimeModelQ ContinuousWaveletData ContinuousWaveletTransform ContourDetect ContourGraphics ContourIntegral ContourLabels ContourLines ContourPlot ContourPlot3D Contours ContourShading ContourSmoothing ContourStyle ContraharmonicMean ContrastiveLossLayer Control ControlActive ControlAlignment ControlGroupContentsBox ControllabilityGramian ControllabilityMatrix ControllableDecomposition ControllableModelQ ControllerDuration ControllerInformation ControllerInformationData ControllerLinking ControllerManipulate ControllerMethod ControllerPath ControllerState ControlPlacement ControlsRendering ControlType Convergents ConversionOptions ConversionRules ConvertToBitmapPacket ConvertToPostScript ConvertToPostScriptPacket ConvexHullMesh ConvexPolygonQ ConvexPolyhedronQ ConvolutionLayer Convolve ConwayGroupCo1 ConwayGroupCo2 ConwayGroupCo3 CookieFunction Cookies CoordinateBoundingBox CoordinateBoundingBoxArray CoordinateBounds CoordinateBoundsArray CoordinateChartData CoordinatesToolOptions CoordinateTransform CoordinateTransformData CoprimeQ Coproduct CopulaDistribution Copyable CopyDatabin CopyDirectory CopyFile CopyTag CopyToClipboard CornerFilter CornerNeighbors Correlation CorrelationDistance CorrelationFunction CorrelationTest Cos Cosh CoshIntegral CosineDistance CosineWindow CosIntegral Cot Coth Count CountDistinct CountDistinctBy CounterAssignments CounterBox CounterBoxOptions CounterClockwiseContourIntegral CounterEvaluator CounterFunction CounterIncrements CounterStyle CounterStyleMenuListing CountRoots CountryData Counts CountsBy Covariance CovarianceEstimatorFunction CovarianceFunction CoxianDistribution CoxIngersollRossProcess CoxModel CoxModelFit CramerVonMisesTest CreateArchive CreateCellID CreateChannel CreateCloudExpression CreateDatabin CreateDataSystemModel CreateDialog CreateDirectory CreateDocument CreateFile CreateIntermediateDirectories CreateManagedLibraryExpression CreateNotebook CreatePalette CreatePalettePacket CreatePermissionsGroup CreateScheduledTask CreateSearchIndex CreateSystemModel CreateTemporary CreateUUID CreateWindow CriterionFunction CriticalityFailureImportance CriticalitySuccessImportance CriticalSection Cross CrossEntropyLossLayer CrossingCount CrossingDetect CrossingPolygon CrossMatrix Csc Csch CTCLossLayer Cube CubeRoot Cubics Cuboid CuboidBox Cumulant CumulantGeneratingFunction Cup CupCap Curl CurlyDoubleQuote CurlyQuote CurrencyConvert CurrentDate CurrentImage CurrentlySpeakingPacket CurrentNotebookImage CurrentScreenImage CurrentValue Curry CurvatureFlowFilter CurveClosed Cyan CycleGraph CycleIndexPolynomial Cycles CyclicGroup Cyclotomic Cylinder CylinderBox CylindricalDecompositionD DagumDistribution DamData DamerauLevenshteinDistance DampingFactor Darker Dashed Dashing DatabaseConnect DatabaseDisconnect DatabaseReference Databin DatabinAdd DatabinRemove Databins DatabinUpload DataCompression DataDistribution DataRange DataReversed Dataset Date DateBounds Dated DateDelimiters DateDifference DatedUnit DateFormat DateFunction DateHistogram DateList DateListLogPlot DateListPlot DateListStepPlot DateObject DateObjectQ DateOverlapsQ DatePattern DatePlus DateRange DateReduction DateString DateTicksFormat DateValue DateWithinQ DaubechiesWavelet DavisDistribution DawsonF DayCount DayCountConvention DayHemisphere DaylightQ DayMatchQ DayName DayNightTerminator DayPlus DayRange DayRound DeBruijnGraph DeBruijnSequence Debug DebugTag Decapitalize Decimal DecimalForm DeclareKnownSymbols DeclarePackage Decompose DeconvolutionLayer Decrement Decrypt DecryptFile DedekindEta DeepSpaceProbeData Default DefaultAxesStyle DefaultBaseStyle DefaultBoxStyle DefaultButton DefaultColor DefaultControlPlacement DefaultDuplicateCellStyle DefaultDuration DefaultElement DefaultFaceGridsStyle DefaultFieldHintStyle DefaultFont DefaultFontProperties DefaultFormatType DefaultFormatTypeForStyle DefaultFrameStyle DefaultFrameTicksStyle DefaultGridLinesStyle DefaultInlineFormatType DefaultInputFormatType DefaultLabelStyle DefaultMenuStyle DefaultNaturalLanguage DefaultNewCellStyle DefaultNewInlineCellStyle DefaultNotebook DefaultOptions DefaultOutputFormatType DefaultPrintPrecision DefaultStyle DefaultStyleDefinitions DefaultTextFormatType DefaultTextInlineFormatType DefaultTicksStyle DefaultTooltipStyle DefaultValue DefaultValues Defer DefineExternal DefineInputStreamMethod DefineOutputStreamMethod DefineResourceFunction Definition Degree DegreeCentrality DegreeGraphDistribution DegreeLexicographic DegreeReverseLexicographic DEigensystem DEigenvalues Deinitialization Del DelaunayMesh Delayed Deletable Delete DeleteAnomalies DeleteBorderComponents DeleteCases DeleteChannel DeleteCloudExpression DeleteContents DeleteDirectory DeleteDuplicates DeleteDuplicatesBy DeleteFile DeleteMissing DeleteObject DeletePermissionsKey DeleteSearchIndex DeleteSmallComponents DeleteStopwords DeleteWithContents DeletionWarning DelimitedArray DelimitedSequence Delimiter DelimiterFlashTime DelimiterMatching Delimiters DeliveryFunction Dendrogram Denominator DensityGraphics DensityHistogram DensityPlot DensityPlot3D DependentVariables Deploy Deployed Depth DepthFirstScan Derivative DerivativeFilter DerivedKey DescriptorStateSpace DesignMatrix DestroyAfterEvaluation Det DeviceClose DeviceConfigure DeviceExecute DeviceExecuteAsynchronous DeviceObject DeviceOpen DeviceOpenQ DeviceRead DeviceReadBuffer DeviceReadLatest DeviceReadList DeviceReadTimeSeries Devices DeviceStreams DeviceWrite DeviceWriteBuffer DGaussianWavelet DiacriticalPositioning Diagonal DiagonalizableMatrixQ DiagonalMatrix DiagonalMatrixQ Dialog DialogIndent DialogInput DialogLevel DialogNotebook DialogProlog DialogReturn DialogSymbols Diamond DiamondMatrix DiceDissimilarity DictionaryLookup DictionaryWordQ DifferenceDelta DifferenceOrder DifferenceQuotient DifferenceRoot DifferenceRootReduce Differences DifferentialD DifferentialRoot DifferentialRootReduce DifferentiatorFilter DigitalSignature DigitBlock DigitBlockMinimum DigitCharacter DigitCount DigitQ DihedralAngle DihedralGroup Dilation DimensionalCombinations DimensionalMeshComponents DimensionReduce DimensionReducerFunction DimensionReduction Dimensions DiracComb DiracDelta DirectedEdge DirectedEdges DirectedGraph DirectedGraphQ DirectedInfinity Direction Directive Directory DirectoryName DirectoryQ DirectoryStack DirichletBeta DirichletCharacter DirichletCondition DirichletConvolve DirichletDistribution DirichletEta DirichletL DirichletLambda DirichletTransform DirichletWindow DisableConsolePrintPacket DisableFormatting DiscreteChirpZTransform DiscreteConvolve DiscreteDelta DiscreteHadamardTransform DiscreteIndicator DiscreteLimit DiscreteLQEstimatorGains DiscreteLQRegulatorGains DiscreteLyapunovSolve DiscreteMarkovProcess DiscreteMaxLimit DiscreteMinLimit DiscretePlot DiscretePlot3D DiscreteRatio DiscreteRiccatiSolve DiscreteShift DiscreteTimeModelQ DiscreteUniformDistribution DiscreteVariables DiscreteWaveletData DiscreteWaveletPacketTransform DiscreteWaveletTransform DiscretizeGraphics DiscretizeRegion Discriminant DisjointQ Disjunction Disk DiskBox DiskMatrix DiskSegment Dispatch DispatchQ DispersionEstimatorFunction Display DisplayAllSteps DisplayEndPacket DisplayFlushImagePacket DisplayForm DisplayFunction DisplayPacket DisplayRules DisplaySetSizePacket DisplayString DisplayTemporary DisplayWith DisplayWithRef DisplayWithVariable DistanceFunction DistanceMatrix DistanceTransform Distribute Distributed DistributedContexts DistributeDefinitions DistributionChart DistributionDomain DistributionFitTest DistributionParameterAssumptions DistributionParameterQ Dithering Div Divergence Divide DivideBy Dividers DivideSides Divisible Divisors DivisorSigma DivisorSum DMSList DMSString Do DockedCells DocumentGenerator DocumentGeneratorInformation DocumentGeneratorInformationData DocumentGenerators DocumentNotebook DocumentWeightingRules Dodecahedron DomainRegistrationInformation DominantColors DOSTextFormat Dot DotDashed DotEqual DotLayer DotPlusLayer Dotted DoubleBracketingBar DoubleContourIntegral DoubleDownArrow DoubleLeftArrow DoubleLeftRightArrow DoubleLeftTee DoubleLongLeftArrow DoubleLongLeftRightArrow DoubleLongRightArrow DoubleRightArrow DoubleRightTee DoubleUpArrow DoubleUpDownArrow DoubleVerticalBar DoublyInfinite Down DownArrow DownArrowBar DownArrowUpArrow DownLeftRightVector DownLeftTeeVector DownLeftVector DownLeftVectorBar DownRightTeeVector DownRightVector DownRightVectorBar Downsample DownTee DownTeeArrow DownValues DragAndDrop DrawEdges DrawFrontFaces DrawHighlighted Drop DropoutLayer DSolve DSolveValue Dt DualLinearProgramming DualPolyhedron DualSystemsModel DumpGet DumpSave DuplicateFreeQ Duration Dynamic DynamicBox DynamicBoxOptions DynamicEvaluationTimeout DynamicGeoGraphics DynamicImage DynamicLocation DynamicModule DynamicModuleBox DynamicModuleBoxOptions DynamicModuleParent DynamicModuleValues DynamicName DynamicNamespace DynamicReference DynamicSetting DynamicUpdating DynamicWrapper DynamicWrapperBox DynamicWrapperBoxOptionsE EarthImpactData EarthquakeData EccentricityCentrality Echo EchoFunction EclipseType EdgeAdd EdgeBetweennessCentrality EdgeCapacity EdgeCapForm EdgeColor EdgeConnectivity EdgeContract EdgeCost EdgeCount EdgeCoverQ EdgeCycleMatrix EdgeDashing EdgeDelete EdgeDetect EdgeForm EdgeIndex EdgeJoinForm EdgeLabeling EdgeLabels EdgeLabelStyle EdgeList EdgeOpacity EdgeQ EdgeRenderingFunction EdgeRules EdgeShapeFunction EdgeStyle EdgeThickness EdgeWeight EdgeWeightedGraphQ Editable EditButtonSettings EditCellTagsSettings EditDistance EffectiveInterest Eigensystem Eigenvalues EigenvectorCentrality Eigenvectors Element ElementData ElementwiseLayer ElidedForms Eliminate EliminationOrder Ellipsoid EllipticE EllipticExp EllipticExpPrime EllipticF EllipticFilterModel EllipticK EllipticLog EllipticNomeQ EllipticPi EllipticReducedHalfPeriods EllipticTheta EllipticThetaPrime EmbedCode EmbeddedHTML EmbeddedService EmbeddingLayer EmbeddingObject EmitSound EmphasizeSyntaxErrors EmpiricalDistribution Empty EmptyGraphQ EmptyRegion EnableConsolePrintPacket Enabled Encode Encrypt EncryptedObject EncryptFile End EndAdd EndDialogPacket EndFrontEndInteractionPacket EndOfBuffer EndOfFile EndOfLine EndOfString EndPackage EngineEnvironment EngineeringForm Enter EnterExpressionPacket EnterTextPacket Entity EntityClass EntityClassList EntityCopies EntityFunction EntityGroup EntityInstance EntityList EntityPrefetch EntityProperties EntityProperty EntityPropertyClass EntityRegister EntityStore EntityStores EntityTypeName EntityUnregister EntityValue Entropy EntropyFilter Environment Epilog EpilogFunction Equal EqualColumns EqualRows EqualTilde EqualTo EquatedTo Equilibrium EquirippleFilterKernel Equivalent Erf Erfc Erfi ErlangB ErlangC ErlangDistribution Erosion ErrorBox ErrorBoxOptions ErrorNorm ErrorPacket ErrorsDialogSettings EscapeRadius EstimatedBackground EstimatedDistribution EstimatedProcess EstimatorGains EstimatorRegulator EuclideanDistance EulerAngles EulerCharacteristic EulerE EulerGamma EulerianGraphQ EulerMatrix EulerPhi Evaluatable Evaluate Evaluated EvaluatePacket EvaluateScheduledTask EvaluationBox EvaluationCell EvaluationCompletionAction EvaluationData EvaluationElements EvaluationEnvironment EvaluationMode EvaluationMonitor EvaluationNotebook EvaluationObject EvaluationOrder Evaluator EvaluatorNames EvenQ EventData EventEvaluator EventHandler EventHandlerTag EventLabels EventSeries ExactBlackmanWindow ExactNumberQ ExactRootIsolation ExampleData Except ExcludedForms ExcludedLines ExcludedPhysicalQuantities ExcludePods Exclusions ExclusionsStyle Exists Exit ExitDialog ExoplanetData Exp Expand ExpandAll ExpandDenominator ExpandFileName ExpandNumerator Expectation ExpectationE ExpectedValue ExpGammaDistribution ExpIntegralE ExpIntegralEi ExpirationDate Exponent ExponentFunction ExponentialDistribution ExponentialFamily ExponentialGeneratingFunction ExponentialMovingAverage ExponentialPowerDistribution ExponentPosition ExponentStep Export ExportAutoReplacements ExportByteArray ExportForm ExportPacket ExportString Expression ExpressionCell ExpressionPacket ExpressionUUID ExpToTrig ExtendedEntityClass ExtendedGCD Extension ExtentElementFunction ExtentMarkers ExtentSize ExternalBundle ExternalCall ExternalDataCharacterEncoding ExternalEvaluate ExternalFunction ExternalFunctionName ExternalObject ExternalOptions ExternalSessionObject ExternalSessions ExternalTypeSignature ExternalValue Extract ExtractArchive ExtractLayer ExtremeValueDistributionFaceForm FaceGrids FaceGridsStyle FacialFeatures Factor FactorComplete Factorial Factorial2 FactorialMoment FactorialMomentGeneratingFunction FactorialPower FactorInteger FactorList FactorSquareFree FactorSquareFreeList FactorTerms FactorTermsList Fail Failure FailureAction FailureDistribution FailureQ False FareySequence FARIMAProcess FeatureDistance FeatureExtract FeatureExtraction FeatureExtractor FeatureExtractorFunction FeatureNames FeatureNearest FeatureSpacePlot FeatureSpacePlot3D FeatureTypes FEDisableConsolePrintPacket FeedbackLinearize FeedbackSector FeedbackSectorStyle FeedbackType FEEnableConsolePrintPacket FetalGrowthData Fibonacci Fibonorial FieldCompletionFunction FieldHint FieldHintStyle FieldMasked FieldSize File FileBaseName FileByteCount FileConvert FileDate FileExistsQ FileExtension FileFormat FileHandler FileHash FileInformation FileName FileNameDepth FileNameDialogSettings FileNameDrop FileNameForms FileNameJoin FileNames FileNameSetter FileNameSplit FileNameTake FilePrint FileSize FileSystemMap FileSystemScan FileTemplate FileTemplateApply FileType FilledCurve FilledCurveBox FilledCurveBoxOptions Filling FillingStyle FillingTransform FilteredEntityClass FilterRules FinancialBond FinancialData FinancialDerivative FinancialIndicator Find FindAnomalies FindArgMax FindArgMin FindChannels FindClique FindClusters FindCookies FindCurvePath FindCycle FindDevices FindDistribution FindDistributionParameters FindDivisions FindEdgeCover FindEdgeCut FindEdgeIndependentPaths FindEquationalProof FindEulerianCycle FindExternalEvaluators FindFaces FindFile FindFit FindFormula FindFundamentalCycles FindGeneratingFunction FindGeoLocation FindGeometricConjectures FindGeometricTransform FindGraphCommunities FindGraphIsomorphism FindGraphPartition FindHamiltonianCycle FindHamiltonianPath FindHiddenMarkovStates FindIndependentEdgeSet FindIndependentVertexSet FindInstance FindIntegerNullVector FindKClan FindKClique FindKClub FindKPlex FindLibrary FindLinearRecurrence FindList FindMatchingColor FindMaximum FindMaximumFlow FindMaxValue FindMeshDefects FindMinimum FindMinimumCostFlow FindMinimumCut FindMinValue FindMoleculeSubstructure FindPath FindPeaks FindPermutation FindPostmanTour FindProcessParameters FindRepeat FindRoot FindSequenceFunction FindSettings FindShortestPath FindShortestTour FindSpanningTree FindSystemModelEquilibrium FindTextualAnswer FindThreshold FindTransientRepeat FindVertexCover FindVertexCut FindVertexIndependentPaths Fine FinishDynamic FiniteAbelianGroupCount FiniteGroupCount FiniteGroupData First FirstCase FirstPassageTimeDistribution FirstPosition FischerGroupFi22 FischerGroupFi23 FischerGroupFi24Prime FisherHypergeometricDistribution FisherRatioTest FisherZDistribution Fit FitAll FitRegularization FittedModel FixedOrder FixedPoint FixedPointList FlashSelection Flat Flatten FlattenAt FlattenLayer FlatTopWindow FlipView Floor FlowPolynomial FlushPrintOutputPacket Fold FoldList FoldPair FoldPairList FollowRedirects Font FontColor FontFamily FontForm FontName FontOpacity FontPostScriptName FontProperties FontReencoding FontSize FontSlant FontSubstitutions FontTracking FontVariations FontWeight For ForAll Format FormatRules FormatType FormatTypeAutoConvert FormatValues FormBox FormBoxOptions FormControl FormFunction FormLayoutFunction FormObject FormPage FormTheme FormulaData FormulaLookup FortranForm Forward ForwardBackward Fourier FourierCoefficient FourierCosCoefficient FourierCosSeries FourierCosTransform FourierDCT FourierDCTFilter FourierDCTMatrix FourierDST FourierDSTMatrix FourierMatrix FourierParameters FourierSequenceTransform FourierSeries FourierSinCoefficient FourierSinSeries FourierSinTransform FourierTransform FourierTrigSeries FractionalBrownianMotionProcess FractionalGaussianNoiseProcess FractionalPart FractionBox FractionBoxOptions FractionLine Frame FrameBox FrameBoxOptions Framed FrameInset FrameLabel Frameless FrameMargins FrameRate FrameStyle FrameTicks FrameTicksStyle FRatioDistribution FrechetDistribution FreeQ FrenetSerretSystem FrequencySamplingFilterKernel FresnelC FresnelF FresnelG FresnelS Friday FrobeniusNumber FrobeniusSolve FromAbsoluteTime FromCharacterCode FromCoefficientRules FromContinuedFraction FromDate FromDigits FromDMS FromEntity FromJulianDate FromLetterNumber FromPolarCoordinates FromRomanNumeral FromSphericalCoordinates FromUnixTime Front FrontEndDynamicExpression FrontEndEventActions FrontEndExecute FrontEndObject FrontEndResource FrontEndResourceString FrontEndStackSize FrontEndToken FrontEndTokenExecute FrontEndValueCache FrontEndVersion FrontFaceColor FrontFaceOpacity Full FullAxes FullDefinition FullForm FullGraphics FullInformationOutputRegulator FullOptions FullRegion FullSimplify Function FunctionCompile FunctionCompileExport FunctionCompileExportByteArray FunctionCompileExportLibrary FunctionCompileExportString FunctionDomain FunctionExpand FunctionInterpolation FunctionPeriod FunctionRange FunctionSpace FussellVeselyImportanceGaborFilter GaborMatrix GaborWavelet GainMargins GainPhaseMargins GalaxyData GalleryView Gamma GammaDistribution GammaRegularized GapPenalty GARCHProcess GatedRecurrentLayer Gather GatherBy GaugeFaceElementFunction GaugeFaceStyle GaugeFrameElementFunction GaugeFrameSize GaugeFrameStyle GaugeLabels GaugeMarkers GaugeStyle GaussianFilter GaussianIntegers GaussianMatrix GaussianOrthogonalMatrixDistribution GaussianSymplecticMatrixDistribution GaussianUnitaryMatrixDistribution GaussianWindow GCD GegenbauerC General GeneralizedLinearModelFit GenerateAsymmetricKeyPair GenerateConditions GeneratedCell GeneratedDocumentBinding GenerateDerivedKey GenerateDigitalSignature GenerateDocument GeneratedParameters GeneratedQuantityMagnitudes GenerateHTTPResponse GenerateSecuredAuthenticationKey GenerateSymmetricKey GeneratingFunction GeneratorDescription GeneratorHistoryLength GeneratorOutputType Generic GenericCylindricalDecomposition GenomeData GenomeLookup GeoAntipode GeoArea GeoArraySize GeoBackground GeoBoundingBox GeoBounds GeoBoundsRegion GeoBubbleChart GeoCenter GeoCircle GeodesicClosing GeodesicDilation GeodesicErosion GeodesicOpening GeoDestination GeodesyData GeoDirection GeoDisk GeoDisplacement GeoDistance GeoDistanceList GeoElevationData GeoEntities GeoGraphics GeogravityModelData GeoGridDirectionDifference GeoGridLines GeoGridLinesStyle GeoGridPosition GeoGridRange GeoGridRangePadding GeoGridUnitArea GeoGridUnitDistance GeoGridVector GeoGroup GeoHemisphere GeoHemisphereBoundary GeoHistogram GeoIdentify GeoImage GeoLabels GeoLength GeoListPlot GeoLocation GeologicalPeriodData GeomagneticModelData GeoMarker GeometricAssertion GeometricBrownianMotionProcess GeometricDistribution GeometricMean GeometricMeanFilter GeometricScene GeometricTransformation GeometricTransformation3DBox GeometricTransformation3DBoxOptions GeometricTransformationBox GeometricTransformationBoxOptions GeoModel GeoNearest GeoPath GeoPosition GeoPositionENU GeoPositionXYZ GeoProjection GeoProjectionData GeoRange GeoRangePadding GeoRegionValuePlot GeoResolution GeoScaleBar GeoServer GeoSmoothHistogram GeoStreamPlot GeoStyling GeoStylingImageFunction GeoVariant GeoVector GeoVectorENU GeoVectorPlot GeoVectorXYZ GeoVisibleRegion GeoVisibleRegionBoundary GeoWithinQ GeoZoomLevel GestureHandler GestureHandlerTag Get GetBoundingBoxSizePacket GetContext GetEnvironment GetFileName GetFrontEndOptionsDataPacket GetLinebreakInformationPacket GetMenusPacket GetPageBreakInformationPacket Glaisher GlobalClusteringCoefficient GlobalPreferences GlobalSession Glow GoldenAngle GoldenRatio GompertzMakehamDistribution GoodmanKruskalGamma GoodmanKruskalGammaTest Goto Grad Gradient GradientFilter GradientOrientationFilter GrammarApply GrammarRules GrammarToken Graph Graph3D GraphAssortativity GraphAutomorphismGroup GraphCenter GraphComplement GraphData GraphDensity GraphDiameter GraphDifference GraphDisjointUnion GraphDistance GraphDistanceMatrix GraphElementData GraphEmbedding GraphHighlight GraphHighlightStyle GraphHub Graphics Graphics3D Graphics3DBox Graphics3DBoxOptions GraphicsArray GraphicsBaseline GraphicsBox GraphicsBoxOptions GraphicsColor GraphicsColumn GraphicsComplex GraphicsComplex3DBox GraphicsComplex3DBoxOptions GraphicsComplexBox GraphicsComplexBoxOptions GraphicsContents GraphicsData GraphicsGrid GraphicsGridBox GraphicsGroup GraphicsGroup3DBox GraphicsGroup3DBoxOptions GraphicsGroupBox GraphicsGroupBoxOptions GraphicsGrouping GraphicsHighlightColor GraphicsRow GraphicsSpacing GraphicsStyle GraphIntersection GraphLayout GraphLinkEfficiency GraphPeriphery GraphPlot GraphPlot3D GraphPower GraphPropertyDistribution GraphQ GraphRadius GraphReciprocity GraphRoot GraphStyle GraphUnion Gray GrayLevel Greater GreaterEqual GreaterEqualLess GreaterEqualThan GreaterFullEqual GreaterGreater GreaterLess GreaterSlantEqual GreaterThan GreaterTilde Green GreenFunction Grid GridBaseline GridBox GridBoxAlignment GridBoxBackground GridBoxDividers GridBoxFrame GridBoxItemSize GridBoxItemStyle GridBoxOptions GridBoxSpacings GridCreationSettings GridDefaultElement GridElementStyleOptions GridFrame GridFrameMargins GridGraph GridLines GridLinesStyle GroebnerBasis GroupActionBase GroupBy GroupCentralizer GroupElementFromWord GroupElementPosition GroupElementQ GroupElements GroupElementToWord GroupGenerators Groupings GroupMultiplicationTable GroupOrbits GroupOrder GroupPageBreakWithin GroupSetwiseStabilizer GroupStabilizer GroupStabilizerChain GroupTogetherGrouping GroupTogetherNestedGrouping GrowCutComponents Gudermannian GuidedFilter GumbelDistributionHaarWavelet HadamardMatrix HalfLine HalfNormalDistribution HalfPlane HalfSpace HamiltonianGraphQ HammingDistance HammingWindow HandlerFunctions HandlerFunctionsKeys HankelH1 HankelH2 HankelMatrix HankelTransform HannPoissonWindow HannWindow HaradaNortonGroupHN HararyGraph HarmonicMean HarmonicMeanFilter HarmonicNumber Hash Haversine HazardFunction Head HeadCompose HeaderLines Heads HeavisideLambda HeavisidePi HeavisideTheta HeldGroupHe HeldPart HelpBrowserLookup HelpBrowserNotebook HelpBrowserSettings Here HermiteDecomposition HermiteH HermitianMatrixQ HessenbergDecomposition Hessian HexadecimalCharacter Hexahedron HexahedronBox HexahedronBoxOptions HiddenMarkovProcess HiddenSurface Highlighted HighlightGraph HighlightImage HighlightMesh HighpassFilter HigmanSimsGroupHS HilbertCurve HilbertFilter HilbertMatrix Histogram Histogram3D HistogramDistribution HistogramList HistogramTransform HistogramTransformInterpolation HistoricalPeriodData HitMissTransform HITSCentrality HjorthDistribution HodgeDual HoeffdingD HoeffdingDTest Hold HoldAll HoldAllComplete HoldComplete HoldFirst HoldForm HoldPattern HoldRest HolidayCalendar HomeDirectory HomePage Horizontal HorizontalForm HorizontalGauge HorizontalScrollPosition HornerForm HostLookup HotellingTSquareDistribution HoytDistribution HTMLSave HTTPErrorResponse HTTPRedirect HTTPRequest HTTPRequestData HTTPResponse Hue HumanGrowthData HumpDownHump HumpEqual HurwitzLerchPhi HurwitzZeta HyperbolicDistribution HypercubeGraph HyperexponentialDistribution Hyperfactorial Hypergeometric0F1 Hypergeometric0F1Regularized Hypergeometric1F1 Hypergeometric1F1Regularized Hypergeometric2F1 Hypergeometric2F1Regularized HypergeometricDistribution HypergeometricPFQ HypergeometricPFQRegularized HypergeometricU Hyperlink HyperlinkCreationSettings Hyperplane Hyphenation HyphenationOptions HypoexponentialDistribution HypothesisTestDataI IconData Iconize IconizedObject IconRules Icosahedron Identity IdentityMatrix If IgnoreCase IgnoreDiacritics IgnorePunctuation IgnoreSpellCheck IgnoringInactive Im Image Image3D Image3DProjection Image3DSlices ImageAccumulate ImageAdd ImageAdjust ImageAlign ImageApply ImageApplyIndexed ImageAspectRatio ImageAssemble ImageAugmentationLayer ImageBoundingBoxes ImageCache ImageCacheValid ImageCapture ImageCaptureFunction ImageCases ImageChannels ImageClip ImageCollage ImageColorSpace ImageCompose ImageContainsQ ImageContents ImageConvolve ImageCooccurrence ImageCorners ImageCorrelate ImageCorrespondingPoints ImageCrop ImageData ImageDeconvolve ImageDemosaic ImageDifference ImageDimensions ImageDisplacements ImageDistance ImageEffect ImageExposureCombine ImageFeatureTrack ImageFileApply ImageFileFilter ImageFileScan ImageFilter ImageFocusCombine ImageForestingComponents ImageFormattingWidth ImageForwardTransformation ImageGraphics ImageHistogram ImageIdentify ImageInstanceQ ImageKeypoints ImageLevels ImageLines ImageMargins ImageMarker ImageMarkers ImageMeasurements ImageMesh ImageMultiply ImageOffset ImagePad ImagePadding ImagePartition ImagePeriodogram ImagePerspectiveTransformation ImagePosition ImagePreviewFunction ImagePyramid ImagePyramidApply ImageQ ImageRangeCache ImageRecolor ImageReflect ImageRegion ImageResize ImageResolution ImageRestyle ImageRotate ImageRotated ImageSaliencyFilter ImageScaled ImageScan ImageSize ImageSizeAction ImageSizeCache ImageSizeMultipliers ImageSizeRaw ImageSubtract ImageTake ImageTransformation ImageTrim ImageType ImageValue ImageValuePositions ImagingDevice ImplicitRegion Implies Import ImportAutoReplacements ImportByteArray ImportOptions ImportString ImprovementImportance In Inactivate Inactive IncidenceGraph IncidenceList IncidenceMatrix IncludeAromaticBonds IncludeConstantBasis IncludeDefinitions IncludeDirectories IncludeFileExtension IncludeGeneratorTasks IncludeHydrogens IncludeInflections IncludeMetaInformation IncludePods IncludeQuantities IncludeRelatedTables IncludeSingularTerm IncludeWindowTimes Increment IndefiniteMatrixQ Indent IndentingNewlineSpacings IndentMaxFraction IndependenceTest IndependentEdgeSetQ IndependentPhysicalQuantity IndependentUnit IndependentUnitDimension IndependentVertexSetQ Indeterminate IndeterminateThreshold IndexCreationOptions Indexed IndexGraph IndexTag Inequality InexactNumberQ InexactNumbers InfiniteLine InfinitePlane Infinity Infix InflationAdjust InflationMethod Information InformationData InformationDataGrid Inherited InheritScope InhomogeneousPoissonProcess InitialEvaluationHistory Initialization InitializationCell InitializationCellEvaluation InitializationCellWarning InitializationObjects InitializationValue Initialize InitialSeeding InlineCounterAssignments InlineCounterIncrements InlineRules Inner InnerPolygon InnerPolyhedron Inpaint Input InputAliases InputAssumptions InputAutoReplacements InputField InputFieldBox InputFieldBoxOptions InputForm InputGrouping InputNamePacket InputNotebook InputPacket InputSettings InputStream InputString InputStringPacket InputToBoxFormPacket Insert InsertionFunction InsertionPointObject InsertLinebreaks InsertResults Inset Inset3DBox Inset3DBoxOptions InsetBox InsetBoxOptions Insphere Install InstallService InstanceNormalizationLayer InString Integer IntegerDigits IntegerExponent IntegerLength IntegerName IntegerPart IntegerPartitions IntegerQ IntegerReverse Integers IntegerString Integral Integrate Interactive InteractiveTradingChart Interlaced Interleaving InternallyBalancedDecomposition InterpolatingFunction InterpolatingPolynomial Interpolation InterpolationOrder InterpolationPoints InterpolationPrecision Interpretation InterpretationBox InterpretationBoxOptions InterpretationFunction Interpreter InterpretTemplate InterquartileRange Interrupt InterruptSettings IntersectingQ Intersection Interval IntervalIntersection IntervalMarkers IntervalMarkersStyle IntervalMemberQ IntervalSlider IntervalUnion Into Inverse InverseBetaRegularized InverseCDF InverseChiSquareDistribution InverseContinuousWaveletTransform InverseDistanceTransform InverseEllipticNomeQ InverseErf InverseErfc InverseFourier InverseFourierCosTransform InverseFourierSequenceTransform InverseFourierSinTransform InverseFourierTransform InverseFunction InverseFunctions InverseGammaDistribution InverseGammaRegularized InverseGaussianDistribution InverseGudermannian InverseHankelTransform InverseHaversine InverseImagePyramid InverseJacobiCD InverseJacobiCN InverseJacobiCS InverseJacobiDC InverseJacobiDN InverseJacobiDS InverseJacobiNC InverseJacobiND InverseJacobiNS InverseJacobiSC InverseJacobiSD InverseJacobiSN InverseLaplaceTransform InverseMellinTransform InversePermutation InverseRadon InverseRadonTransform InverseSeries InverseShortTimeFourier InverseSpectrogram InverseSurvivalFunction InverseTransformedRegion InverseWaveletTransform InverseWeierstrassP InverseWishartMatrixDistribution InverseZTransform Invisible InvisibleApplication InvisibleTimes IPAddress IrreduciblePolynomialQ IslandData IsolatingInterval IsomorphicGraphQ IsotopeData Italic Item ItemAspectRatio ItemBox ItemBoxOptions ItemSize ItemStyle ItoProcessJaccardDissimilarity JacobiAmplitude Jacobian JacobiCD JacobiCN JacobiCS JacobiDC JacobiDN JacobiDS JacobiNC JacobiND JacobiNS JacobiP JacobiSC JacobiSD JacobiSN JacobiSymbol JacobiZeta JankoGroupJ1 JankoGroupJ2 JankoGroupJ3 JankoGroupJ4 JarqueBeraALMTest JohnsonDistribution Join JoinAcross Joined JoinedCurve JoinedCurveBox JoinedCurveBoxOptions JoinForm JordanDecomposition JordanModelDecomposition JulianDate JuliaSetBoettcher JuliaSetIterationCount JuliaSetPlot JuliaSetPointsK KagiChart KaiserBesselWindow KaiserWindow KalmanEstimator KalmanFilter KarhunenLoeveDecomposition KaryTree KatzCentrality KCoreComponents KDistribution KEdgeConnectedComponents KEdgeConnectedGraphQ KelvinBei KelvinBer KelvinKei KelvinKer KendallTau KendallTauTest KernelExecute KernelFunction KernelMixtureDistribution Kernels Ket Key KeyCollisionFunction KeyComplement KeyDrop KeyDropFrom KeyExistsQ KeyFreeQ KeyIntersection KeyMap KeyMemberQ KeypointStrength Keys KeySelect KeySort KeySortBy KeyTake KeyUnion KeyValueMap KeyValuePattern Khinchin KillProcess KirchhoffGraph KirchhoffMatrix KleinInvariantJ KnapsackSolve KnightTourGraph KnotData KnownUnitQ KochCurve KolmogorovSmirnovTest KroneckerDelta KroneckerModelDecomposition KroneckerProduct KroneckerSymbol KuiperTest KumaraswamyDistribution Kurtosis KuwaharaFilter KVertexConnectedComponents KVertexConnectedGraphQLABColor Label Labeled LabeledSlider LabelingFunction LabelingSize LabelStyle LabelVisibility LaguerreL LakeData LambdaComponents LambertW LaminaData LanczosWindow LandauDistribution Language LanguageCategory LanguageData LanguageIdentify LanguageOptions LaplaceDistribution LaplaceTransform Laplacian LaplacianFilter LaplacianGaussianFilter Large Larger Last Latitude LatitudeLongitude LatticeData LatticeReduce Launch LaunchKernels LayeredGraphPlot LayerSizeFunction LayoutInformation LCHColor LCM LeaderSize LeafCount LeapYearQ LearnDistribution LearnedDistribution LearningRate LearningRateMultipliers LeastSquares LeastSquaresFilterKernel Left LeftArrow LeftArrowBar LeftArrowRightArrow LeftDownTeeVector LeftDownVector LeftDownVectorBar LeftRightArrow LeftRightVector LeftTee LeftTeeArrow LeftTeeVector LeftTriangle LeftTriangleBar LeftTriangleEqual LeftUpDownVector LeftUpTeeVector LeftUpVector LeftUpVectorBar LeftVector LeftVectorBar LegendAppearance Legended LegendFunction LegendLabel LegendLayout LegendMargins LegendMarkers LegendMarkerSize LegendreP LegendreQ LegendreType Length LengthWhile LerchPhi Less LessEqual LessEqualGreater LessEqualThan LessFullEqual LessGreater LessLess LessSlantEqual LessThan LessTilde LetterCharacter LetterCounts LetterNumber LetterQ Level LeveneTest LeviCivitaTensor LevyDistribution Lexicographic LibraryDataType LibraryFunction LibraryFunctionError LibraryFunctionInformation LibraryFunctionLoad LibraryFunctionUnload LibraryLoad LibraryUnload LicenseID LiftingFilterData LiftingWaveletTransform LightBlue LightBrown LightCyan Lighter LightGray LightGreen Lighting LightingAngle LightMagenta LightOrange LightPink LightPurple LightRed LightSources LightYellow Likelihood Limit LimitsPositioning LimitsPositioningTokens LindleyDistribution Line Line3DBox Line3DBoxOptions LinearFilter LinearFractionalOptimization LinearFractionalTransform LinearGradientImage LinearizingTransformationData LinearLayer LinearModelFit LinearOffsetFunction LinearOptimization LinearProgramming LinearRecurrence LinearSolve LinearSolveFunction LineBox LineBoxOptions LineBreak LinebreakAdjustments LineBreakChart LinebreakSemicolonWeighting LineBreakWithin LineColor LineGraph LineIndent LineIndentMaxFraction LineIntegralConvolutionPlot LineIntegralConvolutionScale LineLegend LineOpacity LineSpacing LineWrapParts LinkActivate LinkClose LinkConnect LinkConnectedQ LinkCreate LinkError LinkFlush LinkFunction LinkHost LinkInterrupt LinkLaunch LinkMode LinkObject LinkOpen LinkOptions LinkPatterns LinkProtocol LinkRankCentrality LinkRead LinkReadHeld LinkReadyQ Links LinkService LinkWrite LinkWriteHeld LiouvilleLambda List Listable ListAnimate ListContourPlot ListContourPlot3D ListConvolve ListCorrelate ListCurvePathPlot ListDeconvolve ListDensityPlot ListDensityPlot3D Listen ListFormat ListFourierSequenceTransform ListInterpolation ListLineIntegralConvolutionPlot ListLinePlot ListLogLinearPlot ListLogLogPlot ListLogPlot ListPicker ListPickerBox ListPickerBoxBackground ListPickerBoxOptions ListPlay ListPlot ListPlot3D ListPointPlot3D ListPolarPlot ListQ ListSliceContourPlot3D ListSliceDensityPlot3D ListSliceVectorPlot3D ListStepPlot ListStreamDensityPlot ListStreamPlot ListSurfacePlot3D ListVectorDensityPlot ListVectorPlot ListVectorPlot3D ListZTransform Literal LiteralSearch LocalAdaptiveBinarize LocalCache LocalClusteringCoefficient LocalizeDefinitions LocalizeVariables LocalObject LocalObjects LocalResponseNormalizationLayer LocalSubmit LocalSymbol LocalTime LocalTimeZone LocationEquivalenceTest LocationTest Locator LocatorAutoCreate LocatorBox LocatorBoxOptions LocatorCentering LocatorPane LocatorPaneBox LocatorPaneBoxOptions LocatorRegion Locked Log Log10 Log2 LogBarnesG LogGamma LogGammaDistribution LogicalExpand LogIntegral LogisticDistribution LogisticSigmoid LogitModelFit LogLikelihood LogLinearPlot LogLogisticDistribution LogLogPlot LogMultinormalDistribution LogNormalDistribution LogPlot LogRankTest LogSeriesDistribution LongEqual Longest LongestCommonSequence LongestCommonSequencePositions LongestCommonSubsequence LongestCommonSubsequencePositions LongestMatch LongestOrderedSequence LongForm Longitude LongLeftArrow LongLeftRightArrow LongRightArrow LongShortTermMemoryLayer Lookup Loopback LoopFreeGraphQ LossFunction LowerCaseQ LowerLeftArrow LowerRightArrow LowerTriangularize LowerTriangularMatrixQ LowpassFilter LQEstimatorGains LQGRegulator LQOutputRegulatorGains LQRegulatorGains LUBackSubstitution LucasL LuccioSamiComponents LUDecomposition LunarEclipse LUVColor LyapunovSolve LyonsGroupLyMachineID MachineName MachineNumberQ MachinePrecision MacintoshSystemPageSetup Magenta Magnification Magnify MailAddressValidation MailExecute MailFolder MailItem MailReceiverFunction MailResponseFunction MailSearch MailServerConnect MailServerConnection MailSettings MainSolve MaintainDynamicCaches Majority MakeBoxes MakeExpression MakeRules ManagedLibraryExpressionID ManagedLibraryExpressionQ MandelbrotSetBoettcher MandelbrotSetDistance MandelbrotSetIterationCount MandelbrotSetMemberQ MandelbrotSetPlot MangoldtLambda ManhattanDistance Manipulate Manipulator MannedSpaceMissionData MannWhitneyTest MantissaExponent Manual Map MapAll MapAt MapIndexed MAProcess MapThread MarchenkoPasturDistribution MarcumQ MardiaCombinedTest MardiaKurtosisTest MardiaSkewnessTest MarginalDistribution MarkovProcessProperties Masking MatchingDissimilarity MatchLocalNameQ MatchLocalNames MatchQ Material MathematicalFunctionData MathematicaNotation MathieuC MathieuCharacteristicA MathieuCharacteristicB MathieuCharacteristicExponent MathieuCPrime MathieuGroupM11 MathieuGroupM12 MathieuGroupM22 MathieuGroupM23 MathieuGroupM24 MathieuS MathieuSPrime MathMLForm MathMLText Matrices MatrixExp MatrixForm MatrixFunction MatrixLog MatrixNormalDistribution MatrixPlot MatrixPower MatrixPropertyDistribution MatrixQ MatrixRank MatrixTDistribution Max MaxBend MaxCellMeasure MaxColorDistance MaxDetect MaxDuration MaxExtraBandwidths MaxExtraConditions MaxFeatureDisplacement MaxFeatures MaxFilter MaximalBy Maximize MaxItems MaxIterations MaxLimit MaxMemoryUsed MaxMixtureKernels MaxOverlapFraction MaxPlotPoints MaxPoints MaxRecursion MaxStableDistribution MaxStepFraction MaxSteps MaxStepSize MaxTrainingRounds MaxValue MaxwellDistribution MaxWordGap McLaughlinGroupMcL Mean MeanAbsoluteLossLayer MeanAround MeanClusteringCoefficient MeanDegreeConnectivity MeanDeviation MeanFilter MeanGraphDistance MeanNeighborDegree MeanShift MeanShiftFilter MeanSquaredLossLayer Median MedianDeviation MedianFilter MedicalTestData Medium MeijerG MeijerGReduce MeixnerDistribution MellinConvolve MellinTransform MemberQ MemoryAvailable MemoryConstrained MemoryConstraint MemoryInUse MengerMesh Menu MenuAppearance MenuCommandKey MenuEvaluator MenuItem MenuList MenuPacket MenuSortingValue MenuStyle MenuView Merge MergeDifferences MergingFunction MersennePrimeExponent MersennePrimeExponentQ Mesh MeshCellCentroid MeshCellCount MeshCellHighlight MeshCellIndex MeshCellLabel MeshCellMarker MeshCellMeasure MeshCellQuality MeshCells MeshCellShapeFunction MeshCellStyle MeshCoordinates MeshFunctions MeshPrimitives MeshQualityGoal MeshRange MeshRefinementFunction MeshRegion MeshRegionQ MeshShading MeshStyle Message MessageDialog MessageList MessageName MessageObject MessageOptions MessagePacket Messages MessagesNotebook MetaCharacters MetaInformation MeteorShowerData Method MethodOptions MexicanHatWavelet MeyerWavelet Midpoint Min MinColorDistance MinDetect MineralData MinFilter MinimalBy MinimalPolynomial MinimalStateSpaceModel Minimize MinimumTimeIncrement MinIntervalSize MinkowskiQuestionMark MinLimit MinMax MinorPlanetData Minors MinRecursion MinSize MinStableDistribution Minus MinusPlus MinValue Missing MissingBehavior MissingDataMethod MissingDataRules MissingQ MissingString MissingStyle MissingValuePattern MittagLefflerE MixedFractionParts MixedGraphQ MixedMagnitude MixedRadix MixedRadixQuantity MixedUnit MixtureDistribution Mod Modal Mode Modular ModularInverse ModularLambda Module Modulus MoebiusMu Molecule MoleculeContainsQ MoleculeEquivalentQ MoleculeGraph MoleculeModify MoleculePattern MoleculePlot MoleculePlot3D MoleculeProperty MoleculeQ MoleculeValue Moment Momentary MomentConvert MomentEvaluate MomentGeneratingFunction MomentOfInertia Monday Monitor MonomialList MonomialOrder MonsterGroupM MoonPhase MoonPosition MorletWavelet MorphologicalBinarize MorphologicalBranchPoints MorphologicalComponents MorphologicalEulerNumber MorphologicalGraph MorphologicalPerimeter MorphologicalTransform MortalityData Most MountainData MouseAnnotation MouseAppearance MouseAppearanceTag MouseButtons Mouseover MousePointerNote MousePosition MovieData MovingAverage MovingMap MovingMedian MoyalDistribution Multicolumn MultiedgeStyle MultigraphQ MultilaunchWarning MultiLetterItalics MultiLetterStyle MultilineFunction Multinomial MultinomialDistribution MultinormalDistribution MultiplicativeOrder Multiplicity MultiplySides Multiselection MultivariateHypergeometricDistribution MultivariatePoissonDistribution MultivariateTDistributionN NakagamiDistribution NameQ Names NamespaceBox NamespaceBoxOptions Nand NArgMax NArgMin NBernoulliB NBodySimulation NBodySimulationData NCache NDEigensystem NDEigenvalues NDSolve NDSolveValue Nearest NearestFunction NearestNeighborGraph NearestTo NebulaData NeedCurrentFrontEndPackagePacket NeedCurrentFrontEndSymbolsPacket NeedlemanWunschSimilarity Needs Negative NegativeBinomialDistribution NegativeDefiniteMatrixQ NegativeIntegers NegativeMultinomialDistribution NegativeRationals NegativeReals NegativeSemidefiniteMatrixQ NeighborhoodData NeighborhoodGraph Nest NestedGreaterGreater NestedLessLess NestedScriptRules NestGraph NestList NestWhile NestWhileList NetAppend NetBidirectionalOperator NetChain NetDecoder NetDelete NetDrop NetEncoder NetEvaluationMode NetExtract NetFlatten NetFoldOperator NetGraph NetInformation NetInitialize NetInsert NetInsertSharedArrays NetJoin NetMapOperator NetMapThreadOperator NetMeasurements NetModel NetNestOperator NetPairEmbeddingOperator NetPort NetPortGradient NetPrepend NetRename NetReplace NetReplacePart NetSharedArray NetStateObject NetTake NetTrain NetTrainResultsObject NetworkPacketCapture NetworkPacketRecording NetworkPacketRecordingDuring NetworkPacketTrace NeumannValue NevilleThetaC NevilleThetaD NevilleThetaN NevilleThetaS NewPrimitiveStyle NExpectation Next NextCell NextDate NextPrime NextScheduledTaskTime NHoldAll NHoldFirst NHoldRest NicholsGridLines NicholsPlot NightHemisphere NIntegrate NMaximize NMaxValue NMinimize NMinValue NominalVariables NonAssociative NoncentralBetaDistribution NoncentralChiSquareDistribution NoncentralFRatioDistribution NoncentralStudentTDistribution NonCommutativeMultiply NonConstants NondimensionalizationTransform None NoneTrue NonlinearModelFit NonlinearStateSpaceModel NonlocalMeansFilter NonNegative NonNegativeIntegers NonNegativeRationals NonNegativeReals NonPositive NonPositiveIntegers NonPositiveRationals NonPositiveReals Nor NorlundB Norm Normal NormalDistribution NormalGrouping NormalizationLayer Normalize Normalized NormalizedSquaredEuclideanDistance NormalMatrixQ NormalsFunction NormFunction Not NotCongruent NotCupCap NotDoubleVerticalBar Notebook NotebookApply NotebookAutoSave NotebookClose NotebookConvertSettings NotebookCreate NotebookCreateReturnObject NotebookDefault NotebookDelete NotebookDirectory NotebookDynamicExpression NotebookEvaluate NotebookEventActions NotebookFileName NotebookFind NotebookFindReturnObject NotebookGet NotebookGetLayoutInformationPacket NotebookGetMisspellingsPacket NotebookImport NotebookInformation NotebookInterfaceObject NotebookLocate NotebookObject NotebookOpen NotebookOpenReturnObject NotebookPath NotebookPrint NotebookPut NotebookPutReturnObject NotebookRead NotebookResetGeneratedCells Notebooks NotebookSave NotebookSaveAs NotebookSelection NotebookSetupLayoutInformationPacket NotebooksMenu NotebookTemplate NotebookWrite NotElement NotEqualTilde NotExists NotGreater NotGreaterEqual NotGreaterFullEqual NotGreaterGreater NotGreaterLess NotGreaterSlantEqual NotGreaterTilde Nothing NotHumpDownHump NotHumpEqual NotificationFunction NotLeftTriangle NotLeftTriangleBar NotLeftTriangleEqual NotLess NotLessEqual NotLessFullEqual NotLessGreater NotLessLess NotLessSlantEqual NotLessTilde NotNestedGreaterGreater NotNestedLessLess NotPrecedes NotPrecedesEqual NotPrecedesSlantEqual NotPrecedesTilde NotReverseElement NotRightTriangle NotRightTriangleBar NotRightTriangleEqual NotSquareSubset NotSquareSubsetEqual NotSquareSuperset NotSquareSupersetEqual NotSubset NotSubsetEqual NotSucceeds NotSucceedsEqual NotSucceedsSlantEqual NotSucceedsTilde NotSuperset NotSupersetEqual NotTilde NotTildeEqual NotTildeFullEqual NotTildeTilde NotVerticalBar Now NoWhitespace NProbability NProduct NProductFactors NRoots NSolve NSum NSumTerms NuclearExplosionData NuclearReactorData Null NullRecords NullSpace NullWords Number NumberCompose NumberDecompose NumberExpand NumberFieldClassNumber NumberFieldDiscriminant NumberFieldFundamentalUnits NumberFieldIntegralBasis NumberFieldNormRepresentatives NumberFieldRegulator NumberFieldRootsOfUnity NumberFieldSignature NumberForm NumberFormat NumberLinePlot NumberMarks NumberMultiplier NumberPadding NumberPoint NumberQ NumberSeparator NumberSigns NumberString Numerator NumeratorDenominator NumericalOrder NumericalSort NumericArray NumericArrayQ NumericArrayType NumericFunction NumericQ NuttallWindow NValues NyquistGridLines NyquistPlotO ObservabilityGramian ObservabilityMatrix ObservableDecomposition ObservableModelQ OceanData Octahedron OddQ Off Offset OLEData On ONanGroupON Once OneIdentity Opacity OpacityFunction OpacityFunctionScaling Open OpenAppend Opener OpenerBox OpenerBoxOptions OpenerView OpenFunctionInspectorPacket Opening OpenRead OpenSpecialOptions OpenTemporary OpenWrite Operate OperatingSystem OptimumFlowData Optional OptionalElement OptionInspectorSettings OptionQ Options OptionsPacket OptionsPattern OptionValue OptionValueBox OptionValueBoxOptions Or Orange Order OrderDistribution OrderedQ Ordering OrderingBy OrderingLayer Orderless OrderlessPatternSequence OrnsteinUhlenbeckProcess Orthogonalize OrthogonalMatrixQ Out Outer OuterPolygon OuterPolyhedron OutputAutoOverwrite OutputControllabilityMatrix OutputControllableModelQ OutputForm OutputFormData OutputGrouping OutputMathEditExpression OutputNamePacket OutputResponse OutputSizeLimit OutputStream Over OverBar OverDot Overflow OverHat Overlaps Overlay OverlayBox OverlayBoxOptions Overscript OverscriptBox OverscriptBoxOptions OverTilde OverVector OverwriteTarget OwenT OwnValuesPackage PackingMethod PaddedForm Padding PaddingLayer PaddingSize PadeApproximant PadLeft PadRight PageBreakAbove PageBreakBelow PageBreakWithin PageFooterLines PageFooters PageHeaderLines PageHeaders PageHeight PageRankCentrality PageTheme PageWidth Pagination PairedBarChart PairedHistogram PairedSmoothHistogram PairedTTest PairedZTest PaletteNotebook PalettePath PalindromeQ Pane PaneBox PaneBoxOptions Panel PanelBox PanelBoxOptions Paneled PaneSelector PaneSelectorBox PaneSelectorBoxOptions PaperWidth ParabolicCylinderD ParagraphIndent ParagraphSpacing ParallelArray ParallelCombine ParallelDo Parallelepiped ParallelEvaluate Parallelization Parallelize ParallelMap ParallelNeeds Parallelogram ParallelProduct ParallelSubmit ParallelSum ParallelTable ParallelTry Parameter ParameterEstimator ParameterMixtureDistribution ParameterVariables ParametricFunction ParametricNDSolve ParametricNDSolveValue ParametricPlot ParametricPlot3D ParametricRegion ParentBox ParentCell ParentConnect ParentDirectory ParentForm Parenthesize ParentList ParentNotebook ParetoDistribution ParetoPickandsDistribution ParkData Part PartBehavior PartialCorrelationFunction PartialD ParticleAcceleratorData ParticleData Partition PartitionGranularity PartitionsP PartitionsQ PartLayer PartOfSpeech PartProtection ParzenWindow PascalDistribution PassEventsDown PassEventsUp Paste PasteAutoQuoteCharacters PasteBoxFormInlineCells PasteButton Path PathGraph PathGraphQ Pattern PatternSequence PatternTest PauliMatrix PaulWavelet Pause PausedTime PDF PeakDetect PeanoCurve PearsonChiSquareTest PearsonCorrelationTest PearsonDistribution PercentForm PerfectNumber PerfectNumberQ PerformanceGoal Perimeter PeriodicBoundaryCondition PeriodicInterpolation Periodogram PeriodogramArray Permanent Permissions PermissionsGroup PermissionsGroupMemberQ PermissionsGroups PermissionsKey PermissionsKeys PermutationCycles PermutationCyclesQ PermutationGroup PermutationLength PermutationList PermutationListQ PermutationMax PermutationMin PermutationOrder PermutationPower PermutationProduct PermutationReplace Permutations PermutationSupport Permute PeronaMalikFilter Perpendicular PerpendicularBisector PersistenceLocation PersistenceTime PersistentObject PersistentObjects PersistentValue PersonData PERTDistribution PetersenGraph PhaseMargins PhaseRange PhysicalSystemData Pi Pick PIDData PIDDerivativeFilter PIDFeedforward PIDTune Piecewise PiecewiseExpand PieChart PieChart3D PillaiTrace PillaiTraceTest PingTime Pink PitchRecognize Pivoting PixelConstrained PixelValue PixelValuePositions Placed Placeholder PlaceholderReplace Plain PlanarAngle PlanarGraph PlanarGraphQ PlanckRadiationLaw PlaneCurveData PlanetaryMoonData PlanetData PlantData Play PlayRange Plot Plot3D Plot3Matrix PlotDivision PlotJoined PlotLabel PlotLabels PlotLayout PlotLegends PlotMarkers PlotPoints PlotRange PlotRangeClipping PlotRangeClipPlanesStyle PlotRangePadding PlotRegion PlotStyle PlotTheme Pluralize Plus PlusMinus Pochhammer PodStates PodWidth Point Point3DBox Point3DBoxOptions PointBox PointBoxOptions PointFigureChart PointLegend PointSize PoissonConsulDistribution PoissonDistribution PoissonProcess PoissonWindow PolarAxes PolarAxesOrigin PolarGridLines PolarPlot PolarTicks PoleZeroMarkers PolyaAeppliDistribution PolyGamma Polygon Polygon3DBox Polygon3DBoxOptions PolygonalNumber PolygonAngle PolygonBox PolygonBoxOptions PolygonCoordinates PolygonDecomposition PolygonHoleScale PolygonIntersections PolygonScale Polyhedron PolyhedronAngle PolyhedronCoordinates PolyhedronData PolyhedronDecomposition PolyhedronGenus PolyLog PolynomialExtendedGCD PolynomialForm PolynomialGCD PolynomialLCM PolynomialMod PolynomialQ PolynomialQuotient PolynomialQuotientRemainder PolynomialReduce PolynomialRemainder Polynomials PoolingLayer PopupMenu PopupMenuBox PopupMenuBoxOptions PopupView PopupWindow Position PositionIndex Positive PositiveDefiniteMatrixQ PositiveIntegers PositiveRationals PositiveReals PositiveSemidefiniteMatrixQ PossibleZeroQ Postfix PostScript Power PowerDistribution PowerExpand PowerMod PowerModList PowerRange PowerSpectralDensity PowersRepresentations PowerSymmetricPolynomial Precedence PrecedenceForm Precedes PrecedesEqual PrecedesSlantEqual PrecedesTilde Precision PrecisionGoal PreDecrement Predict PredictionRoot PredictorFunction PredictorInformation PredictorMeasurements PredictorMeasurementsObject PreemptProtect PreferencesPath Prefix PreIncrement Prepend PrependLayer PrependTo PreprocessingRules PreserveColor PreserveImageOptions Previous PreviousCell PreviousDate PriceGraphDistribution PrimaryPlaceholder Prime PrimeNu PrimeOmega PrimePi PrimePowerQ PrimeQ Primes PrimeZetaP PrimitivePolynomialQ PrimitiveRoot PrimitiveRootList PrincipalComponents PrincipalValue Print PrintableASCIIQ PrintAction PrintForm PrintingCopies PrintingOptions PrintingPageRange PrintingStartingPageNumber PrintingStyleEnvironment Printout3D Printout3DPreviewer PrintPrecision PrintTemporary Prism PrismBox PrismBoxOptions PrivateCellOptions PrivateEvaluationOptions PrivateFontOptions PrivateFrontEndOptions PrivateKey PrivateNotebookOptions PrivatePaths Probability ProbabilityDistribution ProbabilityPlot ProbabilityPr ProbabilityScalePlot ProbitModelFit ProcessConnection ProcessDirectory ProcessEnvironment Processes ProcessEstimator ProcessInformation ProcessObject ProcessParameterAssumptions ProcessParameterQ ProcessStateDomain ProcessStatus ProcessTimeDomain Product ProductDistribution ProductLog ProgressIndicator ProgressIndicatorBox ProgressIndicatorBoxOptions Projection Prolog PromptForm ProofObject Properties Property PropertyList PropertyValue Proportion Proportional Protect Protected ProteinData Pruning PseudoInverse PsychrometricPropertyData PublicKey PublisherID PulsarData PunctuationCharacter Purple Put PutAppend Pyramid PyramidBox PyramidBoxOptionsQBinomial QFactorial QGamma QHypergeometricPFQ QnDispersion QPochhammer QPolyGamma QRDecomposition QuadraticIrrationalQ QuadraticOptimization Quantile QuantilePlot Quantity QuantityArray QuantityDistribution QuantityForm QuantityMagnitude QuantityQ QuantityUnit QuantityVariable QuantityVariableCanonicalUnit QuantityVariableDimensions QuantityVariableIdentifier QuantityVariablePhysicalQuantity Quartics QuartileDeviation Quartiles QuartileSkewness Query QueueingNetworkProcess QueueingProcess QueueProperties Quiet Quit Quotient QuotientRemainderRadialGradientImage RadialityCentrality RadicalBox RadicalBoxOptions RadioButton RadioButtonBar RadioButtonBox RadioButtonBoxOptions Radon RadonTransform RamanujanTau RamanujanTauL RamanujanTauTheta RamanujanTauZ Ramp Random RandomChoice RandomColor RandomComplex RandomEntity RandomFunction RandomGeoPosition RandomGraph RandomImage RandomInstance RandomInteger RandomPermutation RandomPoint RandomPolygon RandomPolyhedron RandomPrime RandomReal RandomSample RandomSeed RandomSeeding RandomVariate RandomWalkProcess RandomWord Range RangeFilter RangeSpecification RankedMax RankedMin RarerProbability Raster Raster3D Raster3DBox Raster3DBoxOptions RasterArray RasterBox RasterBoxOptions Rasterize RasterSize Rational RationalFunctions Rationalize Rationals Ratios RawArray RawBoxes RawData RawMedium RayleighDistribution Re Read ReadByteArray ReadLine ReadList ReadProtected ReadString Real RealAbs RealBlockDiagonalForm RealDigits RealExponent Reals RealSign Reap RecognitionPrior RecognitionThreshold Record RecordLists RecordSeparators Rectangle RectangleBox RectangleBoxOptions RectangleChart RectangleChart3D RectangularRepeatingElement RecurrenceFilter RecurrenceTable RecurringDigitsForm Red Reduce RefBox ReferenceLineStyle ReferenceMarkers ReferenceMarkerStyle Refine ReflectionMatrix ReflectionTransform Refresh RefreshRate Region RegionBinarize RegionBoundary RegionBounds RegionCentroid RegionDifference RegionDimension RegionDisjoint RegionDistance RegionDistanceFunction RegionEmbeddingDimension RegionEqual RegionFunction RegionImage RegionIntersection RegionMeasure RegionMember RegionMemberFunction RegionMoment RegionNearest RegionNearestFunction RegionPlot RegionPlot3D RegionProduct RegionQ RegionResize RegionSize RegionSymmetricDifference RegionUnion RegionWithin RegisterExternalEvaluator RegularExpression Regularization RegularlySampledQ RegularPolygon ReIm ReImLabels ReImPlot ReImStyle Reinstall RelationalDatabase RelationGraph Release ReleaseHold ReliabilityDistribution ReliefImage ReliefPlot RemoteAuthorizationCaching RemoteConnect RemoteConnectionObject RemoteFile RemoteRun RemoteRunProcess Remove RemoveAlphaChannel RemoveAsynchronousTask RemoveAudioStream RemoveBackground RemoveChannelListener RemoveChannelSubscribers Removed RemoveDiacritics RemoveInputStreamMethod RemoveOutputStreamMethod RemoveProperty RemoveScheduledTask RemoveUsers RenameDirectory RenameFile RenderAll RenderingOptions RenewalProcess RenkoChart RepairMesh Repeated RepeatedNull RepeatedString RepeatedTiming RepeatingElement Replace ReplaceAll ReplaceHeldPart ReplaceImageValue ReplaceList ReplacePart ReplacePixelValue ReplaceRepeated ReplicateLayer RequiredPhysicalQuantities Resampling ResamplingAlgorithmData ResamplingMethod Rescale RescalingTransform ResetDirectory ResetMenusPacket ResetScheduledTask ReshapeLayer Residue ResizeLayer Resolve ResourceAcquire ResourceData ResourceFunction ResourceObject ResourceRegister ResourceRemove ResourceSearch ResourceSubmissionObject ResourceSubmit ResourceSystemBase ResourceUpdate ResponseForm Rest RestartInterval Restricted Resultant ResumePacket Return ReturnEntersInput ReturnExpressionPacket ReturnInputFormPacket ReturnPacket ReturnReceiptFunction ReturnTextPacket Reverse ReverseBiorthogonalSplineWavelet ReverseElement ReverseEquilibrium ReverseGraph ReverseSort ReverseSortBy ReverseUpEquilibrium RevolutionAxis RevolutionPlot3D RGBColor RiccatiSolve RiceDistribution RidgeFilter RiemannR RiemannSiegelTheta RiemannSiegelZ RiemannXi Riffle Right RightArrow RightArrowBar RightArrowLeftArrow RightComposition RightCosetRepresentative RightDownTeeVector RightDownVector RightDownVectorBar RightTee RightTeeArrow RightTeeVector RightTriangle RightTriangleBar RightTriangleEqual RightUpDownVector RightUpTeeVector RightUpVector RightUpVectorBar RightVector RightVectorBar RiskAchievementImportance RiskReductionImportance RogersTanimotoDissimilarity RollPitchYawAngles RollPitchYawMatrix RomanNumeral Root RootApproximant RootIntervals RootLocusPlot RootMeanSquare RootOfUnityQ RootReduce Roots RootSum Rotate RotateLabel RotateLeft RotateRight RotationAction RotationBox RotationBoxOptions RotationMatrix RotationTransform Round RoundImplies RoundingRadius Row RowAlignments RowBackgrounds RowBox RowHeights RowLines RowMinHeight RowReduce RowsEqual RowSpacings RSolve RSolveValue RudinShapiro RudvalisGroupRu Rule RuleCondition RuleDelayed RuleForm RulePlot RulerUnits Run RunProcess RunScheduledTask RunThrough RuntimeAttributes RuntimeOptions RussellRaoDissimilaritySameQ SameTest SampledEntityClass SampleDepth SampledSoundFunction SampledSoundList SampleRate SamplingPeriod SARIMAProcess SARMAProcess SASTriangle SatelliteData SatisfiabilityCount SatisfiabilityInstances SatisfiableQ Saturday Save Saveable SaveAutoDelete SaveConnection SaveDefinitions SavitzkyGolayMatrix SawtoothWave Scale Scaled ScaleDivisions ScaledMousePosition ScaleOrigin ScalePadding ScaleRanges ScaleRangeStyle ScalingFunctions ScalingMatrix ScalingTransform Scan ScheduledTask ScheduledTaskActiveQ ScheduledTaskInformation ScheduledTaskInformationData ScheduledTaskObject ScheduledTasks SchurDecomposition ScientificForm ScientificNotationThreshold ScorerGi ScorerGiPrime ScorerHi ScorerHiPrime ScreenRectangle ScreenStyleEnvironment ScriptBaselineShifts ScriptForm ScriptLevel ScriptMinSize ScriptRules ScriptSizeMultipliers Scrollbars ScrollingOptions ScrollPosition SearchAdjustment SearchIndexObject SearchIndices SearchQueryString SearchResultObject Sec Sech SechDistribution SecondOrderConeOptimization SectionGrouping SectorChart SectorChart3D SectorOrigin SectorSpacing SecuredAuthenticationKey SecuredAuthenticationKeys SeedRandom Select Selectable SelectComponents SelectedCells SelectedNotebook SelectFirst Selection SelectionAnimate SelectionCell SelectionCellCreateCell SelectionCellDefaultStyle SelectionCellParentStyle SelectionCreateCell SelectionDebuggerTag SelectionDuplicateCell SelectionEvaluate SelectionEvaluateCreateCell SelectionMove SelectionPlaceholder SelectionSetStyle SelectWithContents SelfLoops SelfLoopStyle SemanticImport SemanticImportString SemanticInterpretation SemialgebraicComponentInstances SemidefiniteOptimization SendMail SendMessage Sequence SequenceAlignment SequenceAttentionLayer SequenceCases SequenceCount SequenceFold SequenceFoldList SequenceForm SequenceHold SequenceLastLayer SequenceMostLayer SequencePosition SequencePredict SequencePredictorFunction SequenceReplace SequenceRestLayer SequenceReverseLayer SequenceSplit Series SeriesCoefficient SeriesData ServiceConnect ServiceDisconnect ServiceExecute ServiceObject ServiceRequest ServiceResponse ServiceSubmit SessionSubmit SessionTime Set SetAccuracy SetAlphaChannel SetAttributes Setbacks SetBoxFormNamesPacket SetCloudDirectory SetCookies SetDelayed SetDirectory SetEnvironment SetEvaluationNotebook SetFileDate SetFileLoadingContext SetNotebookStatusLine SetOptions SetOptionsPacket SetPermissions SetPrecision SetProperty SetSecuredAuthenticationKey SetSelectedNotebook SetSharedFunction SetSharedVariable SetSpeechParametersPacket SetStreamPosition SetSystemModel SetSystemOptions Setter SetterBar SetterBox SetterBoxOptions Setting SetUsers SetValue Shading Shallow ShannonWavelet ShapiroWilkTest Share SharingList Sharpen ShearingMatrix ShearingTransform ShellRegion ShenCastanMatrix ShiftedGompertzDistribution ShiftRegisterSequence Short ShortDownArrow Shortest ShortestMatch ShortestPathFunction ShortLeftArrow ShortRightArrow ShortTimeFourier ShortTimeFourierData ShortUpArrow Show ShowAutoConvert ShowAutoSpellCheck ShowAutoStyles ShowCellBracket ShowCellLabel ShowCellTags ShowClosedCellArea ShowCodeAssist ShowContents ShowControls ShowCursorTracker ShowGroupOpenCloseIcon ShowGroupOpener ShowInvisibleCharacters ShowPageBreaks ShowPredictiveInterface ShowSelection ShowShortBoxForm ShowSpecialCharacters ShowStringCharacters ShowSyntaxStyles ShrinkingDelay ShrinkWrapBoundingBox SiderealTime SiegelTheta SiegelTukeyTest SierpinskiCurve SierpinskiMesh Sign Signature SignedRankTest SignedRegionDistance SignificanceLevel SignPadding SignTest SimilarityRules SimpleGraph SimpleGraphQ SimplePolygonQ SimplePolyhedronQ Simplex Simplify Sin Sinc SinghMaddalaDistribution SingleEvaluation SingleLetterItalics SingleLetterStyle SingularValueDecomposition SingularValueList SingularValuePlot SingularValues Sinh SinhIntegral SinIntegral SixJSymbol Skeleton SkeletonTransform SkellamDistribution Skewness SkewNormalDistribution SkinStyle Skip SliceContourPlot3D SliceDensityPlot3D SliceDistribution SliceVectorPlot3D Slider Slider2D Slider2DBox Slider2DBoxOptions SliderBox SliderBoxOptions SlideView Slot SlotSequence Small SmallCircle Smaller SmithDecomposition SmithDelayCompensator SmithWatermanSimilarity SmoothDensityHistogram SmoothHistogram SmoothHistogram3D SmoothKernelDistribution SnDispersion Snippet SnubPolyhedron SocialMediaData Socket SocketConnect SocketListen SocketListener SocketObject SocketOpen SocketReadMessage SocketReadyQ Sockets SocketWaitAll SocketWaitNext SoftmaxLayer SokalSneathDissimilarity SolarEclipse SolarSystemFeatureData SolidAngle SolidData SolidRegionQ Solve SolveAlways SolveDelayed Sort SortBy SortedBy SortedEntityClass Sound SoundAndGraphics SoundNote SoundVolume SourceLink Sow Space SpaceCurveData SpaceForm Spacer Spacings Span SpanAdjustments SpanCharacterRounding SpanFromAbove SpanFromBoth SpanFromLeft SpanLineThickness SpanMaxSize SpanMinSize SpanningCharacters SpanSymmetric SparseArray SpatialGraphDistribution SpatialMedian SpatialTransformationLayer Speak SpeakTextPacket SpearmanRankTest SpearmanRho SpeciesData SpecificityGoal SpectralLineData Spectrogram SpectrogramArray Specularity SpeechRecognize SpeechSynthesize SpellingCorrection SpellingCorrectionList SpellingDictionaries SpellingDictionariesPath SpellingOptions SpellingSuggestionsPacket Sphere SphereBox SpherePoints SphericalBesselJ SphericalBesselY SphericalHankelH1 SphericalHankelH2 SphericalHarmonicY SphericalPlot3D SphericalRegion SphericalShell SpheroidalEigenvalue SpheroidalJoiningFactor SpheroidalPS SpheroidalPSPrime SpheroidalQS SpheroidalQSPrime SpheroidalRadialFactor SpheroidalS1 SpheroidalS1Prime SpheroidalS2 SpheroidalS2Prime Splice SplicedDistribution SplineClosed SplineDegree SplineKnots SplineWeights Split SplitBy SpokenString Sqrt SqrtBox SqrtBoxOptions Square SquaredEuclideanDistance SquareFreeQ SquareIntersection SquareMatrixQ SquareRepeatingElement SquaresR SquareSubset SquareSubsetEqual SquareSuperset SquareSupersetEqual SquareUnion SquareWave SSSTriangle StabilityMargins StabilityMarginsStyle StableDistribution Stack StackBegin StackComplete StackedDateListPlot StackedListPlot StackInhibit StadiumShape StandardAtmosphereData StandardDeviation StandardDeviationFilter StandardForm Standardize Standardized StandardOceanData StandbyDistribution Star StarClusterData StarData StarGraph StartAsynchronousTask StartExternalSession StartingStepSize StartOfLine StartOfString StartProcess StartScheduledTask StartupSound StartWebSession StateDimensions StateFeedbackGains StateOutputEstimator StateResponse StateSpaceModel StateSpaceRealization StateSpaceTransform StateTransformationLinearize StationaryDistribution StationaryWaveletPacketTransform StationaryWaveletTransform StatusArea StatusCentrality StepMonitor StereochemistryElements StieltjesGamma StirlingS1 StirlingS2 StopAsynchronousTask StoppingPowerData StopScheduledTask StrataVariables StratonovichProcess StreamColorFunction StreamColorFunctionScaling StreamDensityPlot StreamMarkers StreamPlot StreamPoints StreamPosition Streams StreamScale StreamStyle String StringBreak StringByteCount StringCases StringContainsQ StringCount StringDelete StringDrop StringEndsQ StringExpression StringExtract StringForm StringFormat StringFreeQ StringInsert StringJoin StringLength StringMatchQ StringPadLeft StringPadRight StringPart StringPartition StringPosition StringQ StringRepeat StringReplace StringReplaceList StringReplacePart StringReverse StringRiffle StringRotateLeft StringRotateRight StringSkeleton StringSplit StringStartsQ StringTake StringTemplate StringToByteArray StringToStream StringTrim StripBoxes StripOnInput StripWrapperBoxes StrokeForm StructuralImportance StructuredArray StructuredSelection StruveH StruveL Stub StudentTDistribution Style StyleBox StyleBoxAutoDelete StyleData StyleDefinitions StyleForm StyleHints StyleKeyMapping StyleMenuListing StyleNameDialogSettings StyleNames StylePrint StyleSheetPath Subdivide Subfactorial Subgraph SubMinus SubPlus SubresultantPolynomialRemainders SubresultantPolynomials Subresultants Subscript SubscriptBox SubscriptBoxOptions Subscripted Subsequences Subset SubsetEqual SubsetMap SubsetQ Subsets SubStar SubstitutionSystem Subsuperscript SubsuperscriptBox SubsuperscriptBoxOptions Subtract SubtractFrom SubtractSides SubValues Succeeds SucceedsEqual SucceedsSlantEqual SucceedsTilde Success SuchThat Sum SumConvergence SummationLayer Sunday SunPosition Sunrise Sunset SuperDagger SuperMinus SupernovaData SuperPlus Superscript SuperscriptBox SuperscriptBoxOptions Superset SupersetEqual SuperStar Surd SurdForm SurfaceArea SurfaceColor SurfaceData SurfaceGraphics SurvivalDistribution SurvivalFunction SurvivalModel SurvivalModelFit SuspendPacket SuzukiDistribution SuzukiGroupSuz SwatchLegend Switch Symbol SymbolName SymletWavelet Symmetric SymmetricGroup SymmetricKey SymmetricMatrixQ SymmetricPolynomial SymmetricReduction Symmetrize SymmetrizedArray SymmetrizedArrayRules SymmetrizedDependentComponents SymmetrizedIndependentComponents SymmetrizedReplacePart SynchronousInitialization SynchronousUpdating Synonyms Syntax SyntaxForm SyntaxInformation SyntaxLength SyntaxPacket SyntaxQ SynthesizeMissingValues SystemDialogInput SystemException SystemGet SystemHelpPath SystemInformation SystemInformationData SystemInstall SystemModel SystemModeler SystemModelExamples SystemModelLinearize SystemModelParametricSimulate SystemModelPlot SystemModelProgressReporting SystemModelReliability SystemModels SystemModelSimulate SystemModelSimulateSensitivity SystemModelSimulationData SystemOpen SystemOptions SystemProcessData SystemProcesses SystemsConnectionsModel SystemsModelDelay SystemsModelDelayApproximate SystemsModelDelete SystemsModelDimensions SystemsModelExtract SystemsModelFeedbackConnect SystemsModelLabels SystemsModelLinearity SystemsModelMerge SystemsModelOrder SystemsModelParallelConnect SystemsModelSeriesConnect SystemsModelStateFeedbackConnect SystemsModelVectorRelativeOrders SystemStub SystemTestTab TabFilling Table TableAlignments TableDepth TableDirections TableForm TableHeadings TableSpacing TableView TableViewBox TableViewBoxBackground TableViewBoxOptions TabSpacings TabView TabViewBox TabViewBoxOptions TagBox TagBoxNote TagBoxOptions TaggingRules TagSet TagSetDelayed TagStyle TagUnset Take TakeDrop TakeLargest TakeLargestBy TakeList TakeSmallest TakeSmallestBy TakeWhile Tally Tan Tanh TargetDevice TargetFunctions TargetSystem TargetUnits TaskAbort TaskExecute TaskObject TaskRemove TaskResume Tasks TaskSuspend TaskWait TautologyQ TelegraphProcess TemplateApply TemplateArgBox TemplateBox TemplateBoxOptions TemplateEvaluate TemplateExpression TemplateIf TemplateObject TemplateSequence TemplateSlot TemplateSlotSequence TemplateUnevaluated TemplateVerbatim TemplateWith TemporalData TemporalRegularity Temporary TemporaryVariable TensorContract TensorDimensions TensorExpand TensorProduct TensorQ TensorRank TensorReduce TensorSymmetry TensorTranspose TensorWedge TestID TestReport TestReportObject TestResultObject Tetrahedron TetrahedronBox TetrahedronBoxOptions TeXForm TeXSave Text Text3DBox Text3DBoxOptions TextAlignment TextBand TextBoundingBox TextBox TextCases TextCell TextClipboardType TextContents TextData TextElement TextForm TextGrid TextJustification TextLine TextPacket TextParagraph TextPosition TextRecognize TextSearch TextSearchReport TextSentences TextString TextStructure TextStyle TextTranslation Texture TextureCoordinateFunction TextureCoordinateScaling TextWords Therefore ThermodynamicData ThermometerGauge Thick Thickness Thin Thinning ThisLink ThompsonGroupTh Thread ThreadingLayer ThreeJSymbol Threshold Through Throw ThueMorse Thumbnail Thursday Ticks TicksStyle TideData Tilde TildeEqual TildeFullEqual TildeTilde TimeConstrained TimeConstraint TimeDirection TimeFormat TimeGoal TimelinePlot TimeObject TimeObjectQ Times TimesBy TimeSeries TimeSeriesAggregate TimeSeriesForecast TimeSeriesInsert TimeSeriesInvertibility TimeSeriesMap TimeSeriesMapThread TimeSeriesModel TimeSeriesModelFit TimeSeriesResample TimeSeriesRescale TimeSeriesShift TimeSeriesThread TimeSeriesWindow TimeUsed TimeValue TimeWarpingCorrespondence TimeWarpingDistance TimeZone TimeZoneConvert TimeZoneOffset Timing Tiny TitleGrouping TitsGroupT ToBoxes ToCharacterCode ToColor ToContinuousTimeModel ToDate Today ToDiscreteTimeModel ToEntity ToeplitzMatrix ToExpression ToFileName Together Toggle ToggleFalse Toggler TogglerBar TogglerBox TogglerBoxOptions ToHeldExpression ToInvertibleTimeSeries TokenWords Tolerance ToLowerCase Tomorrow ToNumberField TooBig Tooltip TooltipBox TooltipBoxOptions TooltipDelay TooltipStyle Top TopHatTransform ToPolarCoordinates TopologicalSort ToRadicals ToRules ToSphericalCoordinates ToString Total TotalHeight TotalLayer TotalVariationFilter TotalWidth TouchPosition TouchscreenAutoZoom TouchscreenControlPlacement ToUpperCase Tr Trace TraceAbove TraceAction TraceBackward TraceDepth TraceDialog TraceForward TraceInternal TraceLevel TraceOff TraceOn TraceOriginal TracePrint TraceScan TrackedSymbols TrackingFunction TracyWidomDistribution TradingChart TraditionalForm TraditionalFunctionNotation TraditionalNotation TraditionalOrder TrainingProgressCheckpointing TrainingProgressFunction TrainingProgressMeasurements TrainingProgressReporting TrainingStoppingCriterion TransferFunctionCancel TransferFunctionExpand TransferFunctionFactor TransferFunctionModel TransferFunctionPoles TransferFunctionTransform TransferFunctionZeros TransformationClass TransformationFunction TransformationFunctions TransformationMatrix TransformedDistribution TransformedField TransformedProcess TransformedRegion TransitionDirection TransitionDuration TransitionEffect TransitiveClosureGraph TransitiveReductionGraph Translate TranslationOptions TranslationTransform Transliterate Transparent TransparentColor Transpose TransposeLayer TrapSelection TravelDirections TravelDirectionsData TravelDistance TravelDistanceList TravelMethod TravelTime TreeForm TreeGraph TreeGraphQ TreePlot TrendStyle Triangle TriangleCenter TriangleConstruct TriangleMeasurement TriangleWave TriangularDistribution TriangulateMesh Trig TrigExpand TrigFactor TrigFactorList Trigger TrigReduce TrigToExp TrimmedMean TrimmedVariance TropicalStormData True TrueQ TruncatedDistribution TruncatedPolyhedron TsallisQExponentialDistribution TsallisQGaussianDistribution TTest Tube TubeBezierCurveBox TubeBezierCurveBoxOptions TubeBox TubeBoxOptions TubeBSplineCurveBox TubeBSplineCurveBoxOptions Tuesday TukeyLambdaDistribution TukeyWindow TunnelData Tuples TuranGraph TuringMachine TuttePolynomial TwoWayRule Typed TypeSpecifierUnateQ Uncompress UnconstrainedParameters Undefined UnderBar Underflow Underlined Underoverscript UnderoverscriptBox UnderoverscriptBoxOptions Underscript UnderscriptBox UnderscriptBoxOptions UnderseaFeatureData UndirectedEdge UndirectedGraph UndirectedGraphQ UndoOptions UndoTrackedVariables Unequal UnequalTo Unevaluated UniformDistribution UniformGraphDistribution UniformPolyhedron UniformSumDistribution Uninstall Union UnionPlus Unique UnitaryMatrixQ UnitBox UnitConvert UnitDimensions Unitize UnitRootTest UnitSimplify UnitStep UnitSystem UnitTriangle UnitVector UnitVectorLayer UnityDimensions UniverseModelData UniversityData UnixTime Unprotect UnregisterExternalEvaluator UnsameQ UnsavedVariables Unset UnsetShared UntrackedVariables Up UpArrow UpArrowBar UpArrowDownArrow Update UpdateDynamicObjects UpdateDynamicObjectsSynchronous UpdateInterval UpdateSearchIndex UpDownArrow UpEquilibrium UpperCaseQ UpperLeftArrow UpperRightArrow UpperTriangularize UpperTriangularMatrixQ Upsample UpSet UpSetDelayed UpTee UpTeeArrow UpTo UpValues URL URLBuild URLDecode URLDispatcher URLDownload URLDownloadSubmit URLEncode URLExecute URLExpand URLFetch URLFetchAsynchronous URLParse URLQueryDecode URLQueryEncode URLRead URLResponseTime URLSave URLSaveAsynchronous URLShorten URLSubmit UseGraphicsRange UserDefinedWavelet Using UsingFrontEnd UtilityFunctionV2Get ValenceErrorHandling ValidationLength ValidationSet Value ValueBox ValueBoxOptions ValueDimensions ValueForm ValuePreprocessingFunction ValueQ Values ValuesData Variables Variance VarianceEquivalenceTest VarianceEstimatorFunction VarianceGammaDistribution VarianceTest VectorAngle VectorAround VectorColorFunction VectorColorFunctionScaling VectorDensityPlot VectorGlyphData VectorGreater VectorGreaterEqual VectorLess VectorLessEqual VectorMarkers VectorPlot VectorPlot3D VectorPoints VectorQ Vectors VectorScale VectorStyle Vee Verbatim Verbose VerboseConvertToPostScriptPacket VerificationTest VerifyConvergence VerifyDerivedKey VerifyDigitalSignature VerifyInterpretation VerifySecurityCertificates VerifySolutions VerifyTestAssumptions Version VersionNumber VertexAdd VertexCapacity VertexColors VertexComponent VertexConnectivity VertexContract VertexCoordinateRules VertexCoordinates VertexCorrelationSimilarity VertexCosineSimilarity VertexCount VertexCoverQ VertexDataCoordinates VertexDegree VertexDelete VertexDiceSimilarity VertexEccentricity VertexInComponent VertexInDegree VertexIndex VertexJaccardSimilarity VertexLabeling VertexLabels VertexLabelStyle VertexList VertexNormals VertexOutComponent VertexOutDegree VertexQ VertexRenderingFunction VertexReplace VertexShape VertexShapeFunction VertexSize VertexStyle VertexTextureCoordinates VertexWeight VertexWeightedGraphQ Vertical VerticalBar VerticalForm VerticalGauge VerticalSeparator VerticalSlider VerticalTilde ViewAngle ViewCenter ViewMatrix ViewPoint ViewPointSelectorSettings ViewPort ViewProjection ViewRange ViewVector ViewVertical VirtualGroupData Visible VisibleCell VoiceStyleData VoigtDistribution VolcanoData Volume VonMisesDistribution VoronoiMeshWaitAll WaitAsynchronousTask WaitNext WaitUntil WakebyDistribution WalleniusHypergeometricDistribution WaringYuleDistribution WarpingCorrespondence WarpingDistance WatershedComponents WatsonUSquareTest WattsStrogatzGraphDistribution WaveletBestBasis WaveletFilterCoefficients WaveletImagePlot WaveletListPlot WaveletMapIndexed WaveletMatrixPlot WaveletPhi WaveletPsi WaveletScale WaveletScalogram WaveletThreshold WeaklyConnectedComponents WeaklyConnectedGraphComponents WeaklyConnectedGraphQ WeakStationarity WeatherData WeatherForecastData WebAudioSearch WebElementObject WeberE WebExecute WebImage WebImageSearch WebSearch WebSessionObject WebSessions WebWindowObject Wedge Wednesday WeibullDistribution WeierstrassE1 WeierstrassE2 WeierstrassE3 WeierstrassEta1 WeierstrassEta2 WeierstrassEta3 WeierstrassHalfPeriods WeierstrassHalfPeriodW1 WeierstrassHalfPeriodW2 WeierstrassHalfPeriodW3 WeierstrassInvariantG2 WeierstrassInvariantG3 WeierstrassInvariants WeierstrassP WeierstrassPPrime WeierstrassSigma WeierstrassZeta WeightedAdjacencyGraph WeightedAdjacencyMatrix WeightedData WeightedGraphQ Weights WelchWindow WheelGraph WhenEvent Which While White WhiteNoiseProcess WhitePoint Whitespace WhitespaceCharacter WhittakerM WhittakerW WienerFilter WienerProcess WignerD WignerSemicircleDistribution WikipediaData WikipediaSearch WilksW WilksWTest WindDirectionData WindingCount WindingPolygon WindowClickSelect WindowElements WindowFloating WindowFrame WindowFrameElements WindowMargins WindowMovable WindowOpacity WindowPersistentStyles WindowSelected WindowSize WindowStatusArea WindowTitle WindowToolbars WindowWidth WindSpeedData WindVectorData WinsorizedMean WinsorizedVariance WishartMatrixDistribution With WolframAlpha WolframAlphaDate WolframAlphaQuantity WolframAlphaResult WolframLanguageData Word WordBoundary WordCharacter WordCloud WordCount WordCounts WordData WordDefinition WordFrequency WordFrequencyData WordList WordOrientation WordSearch WordSelectionFunction WordSeparators WordSpacings WordStem WordTranslation WorkingPrecision WrapAround Write WriteLine WriteString WronskianXMLElement XMLObject XMLTemplate Xnor Xor XYZColorYellow Yesterday YuleDissimilarityZernikeR ZeroSymmetric ZeroTest ZeroWidthTimes Zeta ZetaZero ZIPCodeData ZipfDistribution ZoomCenter ZoomFactor ZTest ZTransform$Aborted $ActivationGroupID $ActivationKey $ActivationUserRegistered $AddOnsDirectory $AllowExternalChannelFunctions $AssertFunction $Assumptions $AsynchronousTask $AudioInputDevices $AudioOutputDevices $BaseDirectory $BatchInput $BatchOutput $BlockchainBase $BoxForms $ByteOrdering $CacheBaseDirectory $Canceled $ChannelBase $CharacterEncoding $CharacterEncodings $CloudBase $CloudConnected $CloudCreditsAvailable $CloudEvaluation $CloudExpressionBase $CloudObjectNameFormat $CloudObjectURLType $CloudRootDirectory $CloudSymbolBase $CloudUserID $CloudUserUUID $CloudVersion $CloudVersionNumber $CloudWolframEngineVersionNumber $CommandLine $CompilationTarget $ConditionHold $ConfiguredKernels $Context $ContextPath $ControlActiveSetting $Cookies $CookieStore $CreationDate $CurrentLink $CurrentTask $CurrentWebSession $DateStringFormat $DefaultAudioInputDevice $DefaultAudioOutputDevice $DefaultFont $DefaultFrontEnd $DefaultImagingDevice $DefaultLocalBase $DefaultMailbox $DefaultNetworkInterface $DefaultPath $Display $DisplayFunction $DistributedContexts $DynamicEvaluation $Echo $EmbedCodeEnvironments $EmbeddableServices $EntityStores $Epilog $EvaluationCloudBase $EvaluationCloudObject $EvaluationEnvironment $ExportFormats $Failed $FinancialDataSource $FontFamilies $FormatType $FrontEnd $FrontEndSession $GeoEntityTypes $GeoLocation $GeoLocationCity $GeoLocationCountry $GeoLocationPrecision $GeoLocationSource $HistoryLength $HomeDirectory $HTMLExportRules $HTTPCookies $HTTPRequest $IgnoreEOF $ImageFormattingWidth $ImagingDevice $ImagingDevices $ImportFormats $IncomingMailSettings $InitialDirectory $Initialization $InitializationContexts $Input $InputFileName $InputStreamMethods $Inspector $InstallationDate $InstallationDirectory $InterfaceEnvironment $InterpreterTypes $IterationLimit $KernelCount $KernelID $Language $LaunchDirectory $LibraryPath $LicenseExpirationDate $LicenseID $LicenseProcesses $LicenseServer $LicenseSubprocesses $LicenseType $Line $Linked $LinkSupported $LoadedFiles $LocalBase $LocalSymbolBase $MachineAddresses $MachineDomain $MachineDomains $MachineEpsilon $MachineID $MachineName $MachinePrecision $MachineType $MaxExtraPrecision $MaxLicenseProcesses $MaxLicenseSubprocesses $MaxMachineNumber $MaxNumber $MaxPiecewiseCases $MaxPrecision $MaxRootDegree $MessageGroups $MessageList $MessagePrePrint $Messages $MinMachineNumber $MinNumber $MinorReleaseNumber $MinPrecision $MobilePhone $ModuleNumber $NetworkConnected $NetworkInterfaces $NetworkLicense $NewMessage $NewSymbol $Notebooks $NoValue $NumberMarks $Off $OperatingSystem $Output $OutputForms $OutputSizeLimit $OutputStreamMethods $Packages $ParentLink $ParentProcessID $PasswordFile $PatchLevelID $Path $PathnameSeparator $PerformanceGoal $Permissions $PermissionsGroupBase $PersistenceBase $PersistencePath $PipeSupported $PlotTheme $Post $Pre $PreferencesDirectory $PreInitialization $PrePrint $PreRead $PrintForms $PrintLiteral $Printout3DPreviewer $ProcessID $ProcessorCount $ProcessorType $ProductInformation $ProgramName $PublisherID $RandomState $RecursionLimit $RegisteredDeviceClasses $RegisteredUserName $ReleaseNumber $RequesterAddress $RequesterWolframID $RequesterWolframUUID $ResourceSystemBase $RootDirectory $ScheduledTask $ScriptCommandLine $ScriptInputString $SecuredAuthenticationKeyTokens $ServiceCreditsAvailable $Services $SessionID $SetParentLink $SharedFunctions $SharedVariables $SoundDisplay $SoundDisplayFunction $SourceLink $SSHAuthentication $SummaryBoxDataSizeLimit $SuppressInputFormHeads $SynchronousEvaluation $SyntaxHandler $System $SystemCharacterEncoding $SystemID $SystemMemory $SystemShell $SystemTimeZone $SystemWordLength $TemplatePath $TemporaryDirectory $TemporaryPrefix $TestFileName $TextStyle $TimedOut $TimeUnit $TimeZone $TimeZoneEntity $TopDirectory $TraceOff $TraceOn $TracePattern $TracePostAction $TracePreAction $UnitSystem $Urgent $UserAddOnsDirectory $UserAgentLanguages $UserAgentMachine $UserAgentName $UserAgentOperatingSystem $UserAgentString $UserAgentVersion $UserBaseDirectory $UserDocumentsDirectory $Username $UserName $UserURLBase $Version $VersionNumber $VoiceStyles $WolframID $WolframUUID","contains":[{"className":"comment","begin":"\\(\\*","end":"\\*\\)","contains":["self",{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0}]},{"className":"number","begin":"(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)","relevance":0}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/matlab.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/matlab.json new file mode 100644 index 00000000..51d9885f --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/matlab.json @@ -0,0 +1 @@ +{"keywords":{"keyword":"break case catch classdef continue else elseif end enumerated events for function global if methods otherwise parfor persistent properties return spmd switch try while","built_in":"sin sind sinh asin asind asinh cos cosd cosh acos acosd acosh tan tand tanh atan atand atan2 atanh sec secd sech asec asecd asech csc cscd csch acsc acscd acsch cot cotd coth acot acotd acoth hypot exp expm1 log log1p log10 log2 pow2 realpow reallog realsqrt sqrt nthroot nextpow2 abs angle complex conj imag real unwrap isreal cplxpair fix floor ceil round mod rem sign airy besselj bessely besselh besseli besselk beta betainc betaln ellipj ellipke erf erfc erfcx erfinv expint gamma gammainc gammaln psi legendre cross dot factor isprime primes gcd lcm rat rats perms nchoosek factorial cart2sph cart2pol pol2cart sph2cart hsv2rgb rgb2hsv zeros ones eye repmat rand randn linspace logspace freqspace meshgrid accumarray size length ndims numel disp isempty isequal isequalwithequalnans cat reshape diag blkdiag tril triu fliplr flipud flipdim rot90 find sub2ind ind2sub bsxfun ndgrid permute ipermute shiftdim circshift squeeze isscalar isvector ans eps realmax realmin pi i inf nan isnan isinf isfinite j why compan gallery hadamard hankel hilb invhilb magic pascal rosser toeplitz vander wilkinson max min nanmax nanmin mean nanmean type table readtable writetable sortrows sort figure plot plot3 scatter scatter3 cellfun legend intersect ismember procrustes hold num2cell "},"illegal":"(//|\"|#|/\\*|\\s+/\\w+)","contains":[{"className":"function","beginKeywords":"function","end":"$","contains":[{"className":"title","begin":"[a-zA-Z_]\\w*","relevance":0},{"className":"params","variants":[{"begin":"\\(","end":"\\)"},{"begin":"\\[","end":"\\]"}]}]},{"className":"built_in","begin":"true|false","relevance":0,"starts":{"relevance":0,"contains":[{"begin":"('|\\.')+"}]}},{"begin":"[a-zA-Z][a-zA-Z_0-9]*('|\\.')+","relevance":0},{"className":"number","begin":"(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)","relevance":0,"starts":{"$ref":"#contains.1.starts"}},{"className":"string","begin":"'","end":"'","contains":[{"begin":"\\\\[\\s\\S]","relevance":0},{"begin":"''"}]},{"begin":"\\]|}|\\)","relevance":0,"starts":{"$ref":"#contains.1.starts"}},{"className":"string","begin":"\"","end":"\"","contains":[{"$ref":"#contains.4.contains.0"},{"begin":"\"\""}],"starts":{"$ref":"#contains.1.starts"}},{"className":"comment","begin":"^\\s*\\%\\{\\s*$","end":"^\\s*\\%\\}\\s*$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"\\%","end":"$","contains":[{"$ref":"#contains.7.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/maxima.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/maxima.json new file mode 100644 index 00000000..ae4c90f9 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/maxima.json @@ -0,0 +1 @@ +{"lexemes":"[A-Za-z_%][0-9A-Za-z_%]*","keywords":{"keyword":"if then else elseif for thru do while unless step in and or not","literal":"true false unknown inf minf ind und %e %i %pi %phi %gamma","built_in":" abasep abs absint absolute_real_time acos acosh acot acoth acsc acsch activate addcol add_edge add_edges addmatrices addrow add_vertex add_vertices adjacency_matrix adjoin adjoint af agd airy airy_ai airy_bi airy_dai airy_dbi algsys alg_type alias allroots alphacharp alphanumericp amortization %and annuity_fv annuity_pv antid antidiff AntiDifference append appendfile apply apply1 apply2 applyb1 apropos args arit_amortization arithmetic arithsum array arrayapply arrayinfo arraymake arraysetapply ascii asec asech asin asinh askinteger asksign assoc assoc_legendre_p assoc_legendre_q assume assume_external_byte_order asympa at atan atan2 atanh atensimp atom atvalue augcoefmatrix augmented_lagrangian_method av average_degree backtrace bars barsplot barsplot_description base64 base64_decode bashindices batch batchload bc2 bdvac belln benefit_cost bern bernpoly bernstein_approx bernstein_expand bernstein_poly bessel bessel_i bessel_j bessel_k bessel_simplify bessel_y beta beta_incomplete beta_incomplete_generalized beta_incomplete_regularized bezout bfallroots bffac bf_find_root bf_fmin_cobyla bfhzeta bfloat bfloatp bfpsi bfpsi0 bfzeta biconnected_components bimetric binomial bipartition block blockmatrixp bode_gain bode_phase bothcoef box boxplot boxplot_description break bug_report build_info|10 buildq build_sample burn cabs canform canten cardinality carg cartan cartesian_product catch cauchy_matrix cbffac cdf_bernoulli cdf_beta cdf_binomial cdf_cauchy cdf_chi2 cdf_continuous_uniform cdf_discrete_uniform cdf_exp cdf_f cdf_gamma cdf_general_finite_discrete cdf_geometric cdf_gumbel cdf_hypergeometric cdf_laplace cdf_logistic cdf_lognormal cdf_negative_binomial cdf_noncentral_chi2 cdf_noncentral_student_t cdf_normal cdf_pareto cdf_poisson cdf_rank_sum cdf_rayleigh cdf_signed_rank cdf_student_t cdf_weibull cdisplay ceiling central_moment cequal cequalignore cf cfdisrep cfexpand cgeodesic cgreaterp cgreaterpignore changename changevar chaosgame charat charfun charfun2 charlist charp charpoly chdir chebyshev_t chebyshev_u checkdiv check_overlaps chinese cholesky christof chromatic_index chromatic_number cint circulant_graph clear_edge_weight clear_rules clear_vertex_label clebsch_gordan clebsch_graph clessp clesspignore close closefile cmetric coeff coefmatrix cograd col collapse collectterms columnop columnspace columnswap columnvector combination combine comp2pui compare compfile compile compile_file complement_graph complete_bipartite_graph complete_graph complex_number_p components compose_functions concan concat conjugate conmetderiv connected_components connect_vertices cons constant constantp constituent constvalue cont2part content continuous_freq contortion contour_plot contract contract_edge contragrad contrib_ode convert coord copy copy_file copy_graph copylist copymatrix cor cos cosh cot coth cov cov1 covdiff covect covers crc24sum create_graph create_list csc csch csetup cspline ctaylor ct_coordsys ctransform ctranspose cube_graph cuboctahedron_graph cunlisp cv cycle_digraph cycle_graph cylindrical days360 dblint deactivate declare declare_constvalue declare_dimensions declare_fundamental_dimensions declare_fundamental_units declare_qty declare_translated declare_unit_conversion declare_units declare_weights decsym defcon define define_alt_display define_variable defint defmatch defrule defstruct deftaylor degree_sequence del delete deleten delta demo demoivre denom depends derivdegree derivlist describe desolve determinant dfloat dgauss_a dgauss_b dgeev dgemm dgeqrf dgesv dgesvd diag diagmatrix diag_matrix diagmatrixp diameter diff digitcharp dimacs_export dimacs_import dimension dimensionless dimensions dimensions_as_list direct directory discrete_freq disjoin disjointp disolate disp dispcon dispform dispfun dispJordan display disprule dispterms distrib divide divisors divsum dkummer_m dkummer_u dlange dodecahedron_graph dotproduct dotsimp dpart draw draw2d draw3d drawdf draw_file draw_graph dscalar echelon edge_coloring edge_connectivity edges eigens_by_jacobi eigenvalues eigenvectors eighth einstein eivals eivects elapsed_real_time elapsed_run_time ele2comp ele2polynome ele2pui elem elementp elevation_grid elim elim_allbut eliminate eliminate_using ellipse elliptic_e elliptic_ec elliptic_eu elliptic_f elliptic_kc elliptic_pi ematrix empty_graph emptyp endcons entermatrix entertensor entier equal equalp equiv_classes erf erfc erf_generalized erfi errcatch error errormsg errors euler ev eval_string evenp every evolution evolution2d evundiff example exp expand expandwrt expandwrt_factored expint expintegral_chi expintegral_ci expintegral_e expintegral_e1 expintegral_ei expintegral_e_simplify expintegral_li expintegral_shi expintegral_si explicit explose exponentialize express expt exsec extdiff extract_linear_equations extremal_subset ezgcd %f f90 facsum factcomb factor factorfacsum factorial factorout factorsum facts fast_central_elements fast_linsolve fasttimes featurep fernfale fft fib fibtophi fifth filename_merge file_search file_type fillarray findde find_root find_root_abs find_root_error find_root_rel first fix flatten flength float floatnump floor flower_snark flush flush1deriv flushd flushnd flush_output fmin_cobyla forget fortran fourcos fourexpand fourier fourier_elim fourint fourintcos fourintsin foursimp foursin fourth fposition frame_bracket freeof freshline fresnel_c fresnel_s from_adjacency_matrix frucht_graph full_listify fullmap fullmapl fullratsimp fullratsubst fullsetify funcsolve fundamental_dimensions fundamental_units fundef funmake funp fv g0 g1 gamma gamma_greek gamma_incomplete gamma_incomplete_generalized gamma_incomplete_regularized gauss gauss_a gauss_b gaussprob gcd gcdex gcdivide gcfac gcfactor gd generalized_lambert_w genfact gen_laguerre genmatrix gensym geo_amortization geo_annuity_fv geo_annuity_pv geomap geometric geometric_mean geosum get getcurrentdirectory get_edge_weight getenv get_lu_factors get_output_stream_string get_pixel get_plot_option get_tex_environment get_tex_environment_default get_vertex_label gfactor gfactorsum ggf girth global_variances gn gnuplot_close gnuplot_replot gnuplot_reset gnuplot_restart gnuplot_start go Gosper GosperSum gr2d gr3d gradef gramschmidt graph6_decode graph6_encode graph6_export graph6_import graph_center graph_charpoly graph_eigenvalues graph_flow graph_order graph_periphery graph_product graph_size graph_union great_rhombicosidodecahedron_graph great_rhombicuboctahedron_graph grid_graph grind grobner_basis grotzch_graph hamilton_cycle hamilton_path hankel hankel_1 hankel_2 harmonic harmonic_mean hav heawood_graph hermite hessian hgfred hilbertmap hilbert_matrix hipow histogram histogram_description hodge horner hypergeometric i0 i1 %ibes ic1 ic2 ic_convert ichr1 ichr2 icosahedron_graph icosidodecahedron_graph icurvature ident identfor identity idiff idim idummy ieqn %if ifactors iframes ifs igcdex igeodesic_coords ilt image imagpart imetric implicit implicit_derivative implicit_plot indexed_tensor indices induced_subgraph inferencep inference_result infix info_display init_atensor init_ctensor in_neighbors innerproduct inpart inprod inrt integerp integer_partitions integrate intersect intersection intervalp intopois intosum invariant1 invariant2 inverse_fft inverse_jacobi_cd inverse_jacobi_cn inverse_jacobi_cs inverse_jacobi_dc inverse_jacobi_dn inverse_jacobi_ds inverse_jacobi_nc inverse_jacobi_nd inverse_jacobi_ns inverse_jacobi_sc inverse_jacobi_sd inverse_jacobi_sn invert invert_by_adjoint invert_by_lu inv_mod irr is is_biconnected is_bipartite is_connected is_digraph is_edge_in_graph is_graph is_graph_or_digraph ishow is_isomorphic isolate isomorphism is_planar isqrt isreal_p is_sconnected is_tree is_vertex_in_graph items_inference %j j0 j1 jacobi jacobian jacobi_cd jacobi_cn jacobi_cs jacobi_dc jacobi_dn jacobi_ds jacobi_nc jacobi_nd jacobi_ns jacobi_p jacobi_sc jacobi_sd jacobi_sn JF jn join jordan julia julia_set julia_sin %k kdels kdelta kill killcontext kostka kron_delta kronecker_product kummer_m kummer_u kurtosis kurtosis_bernoulli kurtosis_beta kurtosis_binomial kurtosis_chi2 kurtosis_continuous_uniform kurtosis_discrete_uniform kurtosis_exp kurtosis_f kurtosis_gamma kurtosis_general_finite_discrete kurtosis_geometric kurtosis_gumbel kurtosis_hypergeometric kurtosis_laplace kurtosis_logistic kurtosis_lognormal kurtosis_negative_binomial kurtosis_noncentral_chi2 kurtosis_noncentral_student_t kurtosis_normal kurtosis_pareto kurtosis_poisson kurtosis_rayleigh kurtosis_student_t kurtosis_weibull label labels lagrange laguerre lambda lambert_w laplace laplacian_matrix last lbfgs lc2kdt lcharp lc_l lcm lc_u ldefint ldisp ldisplay legendre_p legendre_q leinstein length let letrules letsimp levi_civita lfreeof lgtreillis lhs li liediff limit Lindstedt linear linearinterpol linear_program linear_regression line_graph linsolve listarray list_correlations listify list_matrix_entries list_nc_monomials listoftens listofvars listp lmax lmin load loadfile local locate_matrix_entry log logcontract log_gamma lopow lorentz_gauge lowercasep lpart lratsubst lreduce lriemann lsquares_estimates lsquares_estimates_approximate lsquares_estimates_exact lsquares_mse lsquares_residual_mse lsquares_residuals lsum ltreillis lu_backsub lucas lu_factor %m macroexpand macroexpand1 make_array makebox makefact makegamma make_graph make_level_picture makelist makeOrders make_poly_continent make_poly_country make_polygon make_random_state make_rgb_picture makeset make_string_input_stream make_string_output_stream make_transform mandelbrot mandelbrot_set map mapatom maplist matchdeclare matchfix mat_cond mat_fullunblocker mat_function mathml_display mat_norm matrix matrixmap matrixp matrix_size mattrace mat_trace mat_unblocker max max_clique max_degree max_flow maximize_lp max_independent_set max_matching maybe md5sum mean mean_bernoulli mean_beta mean_binomial mean_chi2 mean_continuous_uniform mean_deviation mean_discrete_uniform mean_exp mean_f mean_gamma mean_general_finite_discrete mean_geometric mean_gumbel mean_hypergeometric mean_laplace mean_logistic mean_lognormal mean_negative_binomial mean_noncentral_chi2 mean_noncentral_student_t mean_normal mean_pareto mean_poisson mean_rayleigh mean_student_t mean_weibull median median_deviation member mesh metricexpandall mgf1_sha1 min min_degree min_edge_cut minfactorial minimalPoly minimize_lp minimum_spanning_tree minor minpack_lsquares minpack_solve min_vertex_cover min_vertex_cut mkdir mnewton mod mode_declare mode_identity ModeMatrix moebius mon2schur mono monomial_dimensions multibernstein_poly multi_display_for_texinfo multi_elem multinomial multinomial_coeff multi_orbit multiplot_mode multi_pui multsym multthru mycielski_graph nary natural_unit nc_degree ncexpt ncharpoly negative_picture neighbors new newcontext newdet new_graph newline newton new_variable next_prime nicedummies niceindices ninth nofix nonarray noncentral_moment nonmetricity nonnegintegerp nonscalarp nonzeroandfreeof notequal nounify nptetrad npv nroots nterms ntermst nthroot nullity nullspace num numbered_boundaries numberp number_to_octets num_distinct_partitions numerval numfactor num_partitions nusum nzeta nzetai nzetar octets_to_number octets_to_oid odd_girth oddp ode2 ode_check odelin oid_to_octets op opena opena_binary openr openr_binary openw openw_binary operatorp opsubst optimize %or orbit orbits ordergreat ordergreatp orderless orderlessp orthogonal_complement orthopoly_recur orthopoly_weight outermap out_neighbors outofpois pade parabolic_cylinder_d parametric parametric_surface parg parGosper parse_string parse_timedate part part2cont partfrac partition partition_set partpol path_digraph path_graph pathname_directory pathname_name pathname_type pdf_bernoulli pdf_beta pdf_binomial pdf_cauchy pdf_chi2 pdf_continuous_uniform pdf_discrete_uniform pdf_exp pdf_f pdf_gamma pdf_general_finite_discrete pdf_geometric pdf_gumbel pdf_hypergeometric pdf_laplace pdf_logistic pdf_lognormal pdf_negative_binomial pdf_noncentral_chi2 pdf_noncentral_student_t pdf_normal pdf_pareto pdf_poisson pdf_rank_sum pdf_rayleigh pdf_signed_rank pdf_student_t pdf_weibull pearson_skewness permanent permut permutation permutations petersen_graph petrov pickapart picture_equalp picturep piechart piechart_description planar_embedding playback plog plot2d plot3d plotdf ploteq plsquares pochhammer points poisdiff poisexpt poisint poismap poisplus poissimp poissubst poistimes poistrim polar polarform polartorect polar_to_xy poly_add poly_buchberger poly_buchberger_criterion poly_colon_ideal poly_content polydecomp poly_depends_p poly_elimination_ideal poly_exact_divide poly_expand poly_expt poly_gcd polygon poly_grobner poly_grobner_equal poly_grobner_member poly_grobner_subsetp poly_ideal_intersection poly_ideal_polysaturation poly_ideal_polysaturation1 poly_ideal_saturation poly_ideal_saturation1 poly_lcm poly_minimization polymod poly_multiply polynome2ele polynomialp poly_normal_form poly_normalize poly_normalize_list poly_polysaturation_extension poly_primitive_part poly_pseudo_divide poly_reduced_grobner poly_reduction poly_saturation_extension poly_s_polynomial poly_subtract polytocompanion pop postfix potential power_mod powerseries powerset prefix prev_prime primep primes principal_components print printf printfile print_graph printpois printprops prodrac product properties propvars psi psubst ptriangularize pui pui2comp pui2ele pui2polynome pui_direct puireduc push put pv qput qrange qty quad_control quad_qag quad_qagi quad_qagp quad_qags quad_qawc quad_qawf quad_qawo quad_qaws quadrilateral quantile quantile_bernoulli quantile_beta quantile_binomial quantile_cauchy quantile_chi2 quantile_continuous_uniform quantile_discrete_uniform quantile_exp quantile_f quantile_gamma quantile_general_finite_discrete quantile_geometric quantile_gumbel quantile_hypergeometric quantile_laplace quantile_logistic quantile_lognormal quantile_negative_binomial quantile_noncentral_chi2 quantile_noncentral_student_t quantile_normal quantile_pareto quantile_poisson quantile_rayleigh quantile_student_t quantile_weibull quartile_skewness quit qunit quotient racah_v racah_w radcan radius random random_bernoulli random_beta random_binomial random_bipartite_graph random_cauchy random_chi2 random_continuous_uniform random_digraph random_discrete_uniform random_exp random_f random_gamma random_general_finite_discrete random_geometric random_graph random_graph1 random_gumbel random_hypergeometric random_laplace random_logistic random_lognormal random_negative_binomial random_network random_noncentral_chi2 random_noncentral_student_t random_normal random_pareto random_permutation random_poisson random_rayleigh random_regular_graph random_student_t random_tournament random_tree random_weibull range rank rat ratcoef ratdenom ratdiff ratdisrep ratexpand ratinterpol rational rationalize ratnumer ratnump ratp ratsimp ratsubst ratvars ratweight read read_array read_binary_array read_binary_list read_binary_matrix readbyte readchar read_hashed_array readline read_list read_matrix read_nested_list readonly read_xpm real_imagpart_to_conjugate realpart realroots rearray rectangle rectform rectform_log_if_constant recttopolar rediff reduce_consts reduce_order region region_boundaries region_boundaries_plus rem remainder remarray rembox remcomps remcon remcoord remfun remfunction remlet remove remove_constvalue remove_dimensions remove_edge remove_fundamental_dimensions remove_fundamental_units remove_plot_option remove_vertex rempart remrule remsym remvalue rename rename_file reset reset_displays residue resolvante resolvante_alternee1 resolvante_bipartite resolvante_diedrale resolvante_klein resolvante_klein3 resolvante_produit_sym resolvante_unitaire resolvante_vierer rest resultant return reveal reverse revert revert2 rgb2level rhs ricci riemann rinvariant risch rk rmdir rncombine romberg room rootscontract round row rowop rowswap rreduce run_testsuite %s save saving scalarp scaled_bessel_i scaled_bessel_i0 scaled_bessel_i1 scalefactors scanmap scatterplot scatterplot_description scene schur2comp sconcat scopy scsimp scurvature sdowncase sec sech second sequal sequalignore set_alt_display setdifference set_draw_defaults set_edge_weight setelmx setequalp setify setp set_partitions set_plot_option set_prompt set_random_state set_tex_environment set_tex_environment_default setunits setup_autoload set_up_dot_simplifications set_vertex_label seventh sexplode sf sha1sum sha256sum shortest_path shortest_weighted_path show showcomps showratvars sierpinskiale sierpinskimap sign signum similaritytransform simp_inequality simplify_sum simplode simpmetderiv simtran sin sinh sinsert sinvertcase sixth skewness skewness_bernoulli skewness_beta skewness_binomial skewness_chi2 skewness_continuous_uniform skewness_discrete_uniform skewness_exp skewness_f skewness_gamma skewness_general_finite_discrete skewness_geometric skewness_gumbel skewness_hypergeometric skewness_laplace skewness_logistic skewness_lognormal skewness_negative_binomial skewness_noncentral_chi2 skewness_noncentral_student_t skewness_normal skewness_pareto skewness_poisson skewness_rayleigh skewness_student_t skewness_weibull slength smake small_rhombicosidodecahedron_graph small_rhombicuboctahedron_graph smax smin smismatch snowmap snub_cube_graph snub_dodecahedron_graph solve solve_rec solve_rec_rat some somrac sort sparse6_decode sparse6_encode sparse6_export sparse6_import specint spherical spherical_bessel_j spherical_bessel_y spherical_hankel1 spherical_hankel2 spherical_harmonic spherical_to_xyz splice split sposition sprint sqfr sqrt sqrtdenest sremove sremovefirst sreverse ssearch ssort sstatus ssubst ssubstfirst staircase standardize standardize_inverse_trig starplot starplot_description status std std1 std_bernoulli std_beta std_binomial std_chi2 std_continuous_uniform std_discrete_uniform std_exp std_f std_gamma std_general_finite_discrete std_geometric std_gumbel std_hypergeometric std_laplace std_logistic std_lognormal std_negative_binomial std_noncentral_chi2 std_noncentral_student_t std_normal std_pareto std_poisson std_rayleigh std_student_t std_weibull stemplot stirling stirling1 stirling2 strim striml strimr string stringout stringp strong_components struve_h struve_l sublis sublist sublist_indices submatrix subsample subset subsetp subst substinpart subst_parallel substpart substring subvar subvarp sum sumcontract summand_to_rec supcase supcontext symbolp symmdifference symmetricp system take_channel take_inference tan tanh taylor taylorinfo taylorp taylor_simplifier taytorat tcl_output tcontract tellrat tellsimp tellsimpafter tentex tenth test_mean test_means_difference test_normality test_proportion test_proportions_difference test_rank_sum test_sign test_signed_rank test_variance test_variance_ratio tex tex1 tex_display texput %th third throw time timedate timer timer_info tldefint tlimit todd_coxeter toeplitz tokens to_lisp topological_sort to_poly to_poly_solve totaldisrep totalfourier totient tpartpol trace tracematrix trace_options transform_sample translate translate_file transpose treefale tree_reduce treillis treinat triangle triangularize trigexpand trigrat trigreduce trigsimp trunc truncate truncated_cube_graph truncated_dodecahedron_graph truncated_icosahedron_graph truncated_tetrahedron_graph tr_warnings_get tube tutte_graph ueivects uforget ultraspherical underlying_graph undiff union unique uniteigenvectors unitp units unit_step unitvector unorder unsum untellrat untimer untrace uppercasep uricci uriemann uvect vandermonde_matrix var var1 var_bernoulli var_beta var_binomial var_chi2 var_continuous_uniform var_discrete_uniform var_exp var_f var_gamma var_general_finite_discrete var_geometric var_gumbel var_hypergeometric var_laplace var_logistic var_lognormal var_negative_binomial var_noncentral_chi2 var_noncentral_student_t var_normal var_pareto var_poisson var_rayleigh var_student_t var_weibull vector vectorpotential vectorsimp verbify vers vertex_coloring vertex_connectivity vertex_degree vertex_distance vertex_eccentricity vertex_in_degree vertex_out_degree vertices vertices_to_cycle vertices_to_path %w weyl wheel_graph wiener_index wigner_3j wigner_6j wigner_9j with_stdout write_binary_data writebyte write_data writefile wronskian xreduce xthru %y Zeilberger zeroequiv zerofor zeromatrix zeromatrixp zeta zgeev zheev zlange zn_add_table zn_carmichael_lambda zn_characteristic_factors zn_determinant zn_factor_generators zn_invert_by_lu zn_log zn_mult_table absboxchar activecontexts adapt_depth additive adim aform algebraic algepsilon algexact aliases allbut all_dotsimp_denoms allocation allsym alphabetic animation antisymmetric arrays askexp assume_pos assume_pos_pred assumescalar asymbol atomgrad atrig1 axes axis_3d axis_bottom axis_left axis_right axis_top azimuth background background_color backsubst berlefact bernstein_explicit besselexpand beta_args_sum_to_integer beta_expand bftorat bftrunc bindtest border boundaries_array box boxchar breakup %c capping cauchysum cbrange cbtics center cflength cframe_flag cnonmet_flag color color_bar color_bar_tics colorbox columns commutative complex cone context contexts contour contour_levels cosnpiflag ctaypov ctaypt ctayswitch ctayvar ct_coords ctorsion_flag ctrgsimp cube current_let_rule_package cylinder data_file_name debugmode decreasing default_let_rule_package delay dependencies derivabbrev derivsubst detout diagmetric diff dim dimensions dispflag display2d|10 display_format_internal distribute_over doallmxops domain domxexpt domxmxops domxnctimes dontfactor doscmxops doscmxplus dot0nscsimp dot0simp dot1simp dotassoc dotconstrules dotdistrib dotexptsimp dotident dotscrules draw_graph_program draw_realpart edge_color edge_coloring edge_partition edge_type edge_width %edispflag elevation %emode endphi endtheta engineering_format_floats enhanced3d %enumer epsilon_lp erfflag erf_representation errormsg error_size error_syms error_type %e_to_numlog eval even evenfun evflag evfun ev_point expandwrt_denom expintexpand expintrep expon expop exptdispflag exptisolate exptsubst facexpand facsum_combine factlim factorflag factorial_expand factors_only fb feature features file_name file_output_append file_search_demo file_search_lisp file_search_maxima|10 file_search_tests file_search_usage file_type_lisp file_type_maxima|10 fill_color fill_density filled_func fixed_vertices flipflag float2bf font font_size fortindent fortspaces fpprec fpprintprec functions gamma_expand gammalim gdet genindex gensumnum GGFCFMAX GGFINFINITY globalsolve gnuplot_command gnuplot_curve_styles gnuplot_curve_titles gnuplot_default_term_command gnuplot_dumb_term_command gnuplot_file_args gnuplot_file_name gnuplot_out_file gnuplot_pdf_term_command gnuplot_pm3d gnuplot_png_term_command gnuplot_postamble gnuplot_preamble gnuplot_ps_term_command gnuplot_svg_term_command gnuplot_term gnuplot_view_args Gosper_in_Zeilberger gradefs grid grid2d grind halfangles head_angle head_both head_length head_type height hypergeometric_representation %iargs ibase icc1 icc2 icounter idummyx ieqnprint ifb ifc1 ifc2 ifg ifgi ifr iframe_bracket_form ifri igeowedge_flag ikt1 ikt2 imaginary inchar increasing infeval infinity inflag infolists inm inmc1 inmc2 intanalysis integer integervalued integrate_use_rootsof integration_constant integration_constant_counter interpolate_color intfaclim ip_grid ip_grid_in irrational isolate_wrt_times iterations itr julia_parameter %k1 %k2 keepfloat key key_pos kinvariant kt label label_alignment label_orientation labels lassociative lbfgs_ncorrections lbfgs_nfeval_max leftjust legend letrat let_rule_packages lfg lg lhospitallim limsubst linear linear_solver linechar linel|10 linenum line_type linewidth line_width linsolve_params linsolvewarn lispdisp listarith listconstvars listdummyvars lmxchar load_pathname loadprint logabs logarc logcb logconcoeffp logexpand lognegint logsimp logx logx_secondary logy logy_secondary logz lriem m1pbranch macroexpansion macros mainvar manual_demo maperror mapprint matrix_element_add matrix_element_mult matrix_element_transpose maxapplydepth maxapplyheight maxima_tempdir|10 maxima_userdir|10 maxnegex MAX_ORD maxposex maxpsifracdenom maxpsifracnum maxpsinegint maxpsiposint maxtayorder mesh_lines_color method mod_big_prime mode_check_errorp mode_checkp mode_check_warnp mod_test mod_threshold modular_linear_solver modulus multiplicative multiplicities myoptions nary negdistrib negsumdispflag newline newtonepsilon newtonmaxiter nextlayerfactor niceindicespref nm nmc noeval nolabels nonegative_lp noninteger nonscalar noun noundisp nouns np npi nticks ntrig numer numer_pbranch obase odd oddfun opacity opproperties opsubst optimprefix optionset orientation origin orthopoly_returns_intervals outative outchar packagefile palette partswitch pdf_file pfeformat phiresolution %piargs piece pivot_count_sx pivot_max_sx plot_format plot_options plot_realpart png_file pochhammer_max_index points pointsize point_size points_joined point_type poislim poisson poly_coefficient_ring poly_elimination_order polyfactor poly_grobner_algorithm poly_grobner_debug poly_monomial_order poly_primary_elimination_order poly_return_term_list poly_secondary_elimination_order poly_top_reduction_only posfun position powerdisp pred prederror primep_number_of_tests product_use_gamma program programmode promote_float_to_bigfloat prompt proportional_axes props psexpand ps_file radexpand radius radsubstflag rassociative ratalgdenom ratchristof ratdenomdivide rateinstein ratepsilon ratfac rational ratmx ratprint ratriemann ratsimpexpons ratvarswitch ratweights ratweyl ratwtlvl real realonly redraw refcheck resolution restart resultant ric riem rmxchar %rnum_list rombergabs rombergit rombergmin rombergtol rootsconmode rootsepsilon run_viewer same_xy same_xyz savedef savefactors scalar scalarmatrixp scale scale_lp setcheck setcheckbreak setval show_edge_color show_edges show_edge_type show_edge_width show_id show_label showtime show_vertex_color show_vertex_size show_vertex_type show_vertices show_weight simp simplified_output simplify_products simpproduct simpsum sinnpiflag solvedecomposes solveexplicit solvefactors solvenullwarn solveradcan solvetrigwarn space sparse sphere spring_embedding_depth sqrtdispflag stardisp startphi starttheta stats_numer stringdisp structures style sublis_apply_lambda subnumsimp sumexpand sumsplitfact surface surface_hide svg_file symmetric tab taylordepth taylor_logexpand taylor_order_coefficients taylor_truncate_polynomials tensorkill terminal testsuite_files thetaresolution timer_devalue title tlimswitch tr track transcompile transform transform_xy translate_fast_arrays transparent transrun tr_array_as_ref tr_bound_function_applyp tr_file_tty_messagesp tr_float_can_branch_complex tr_function_call_default trigexpandplus trigexpandtimes triginverses trigsign trivial_solutions tr_numer tr_optimize_max_loop tr_semicompile tr_state_vars tr_warn_bad_function_calls tr_warn_fexpr tr_warn_meval tr_warn_mode tr_warn_undeclared tr_warn_undefined_variable tstep ttyoff tube_extremes ufg ug %unitexpand unit_vectors uric uriem use_fast_arrays user_preamble usersetunits values vect_cross verbose vertex_color vertex_coloring vertex_partition vertex_size vertex_type view warnings weyl width windowname windowtitle wired_surface wireframe xaxis xaxis_color xaxis_secondary xaxis_type xaxis_width xlabel xlabel_secondary xlength xrange xrange_secondary xtics xtics_axis xtics_rotate xtics_rotate_secondary xtics_secondary xtics_secondary_axis xu_grid x_voxel xy_file xyplane xy_scale yaxis yaxis_color yaxis_secondary yaxis_type yaxis_width ylabel ylabel_secondary ylength yrange yrange_secondary ytics ytics_axis ytics_rotate ytics_rotate_secondary ytics_secondary ytics_secondary_axis yv_grid y_voxel yx_ratio zaxis zaxis_color zaxis_type zaxis_width zeroa zerob zerobern zeta%pi zlabel zlabel_rotate zlength zmin zn_primroot_limit zn_primroot_pretest","symbol":"_ __ %|0 %%|0"},"contains":[{"className":"comment","begin":"/\\*","end":"\\*/","contains":["self"]},{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0}]},{"className":"number","relevance":0,"variants":[{"begin":"\\b(\\d+|\\d+\\.|\\.\\d+|\\d+\\.\\d+)[Ee][-+]?\\d+\\b"},{"begin":"\\b(\\d+|\\d+\\.|\\.\\d+|\\d+\\.\\d+)[Bb][-+]?\\d+\\b","relevance":10},{"begin":"\\b(\\.\\d+|\\d+\\.\\d+)\\b"},{"begin":"\\b(\\d+|0[0-9A-Za-z]+)\\.?\\b"}]}],"illegal":"@"} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/mel.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/mel.json new file mode 100644 index 00000000..2b933c48 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/mel.json @@ -0,0 +1 @@ +{"keywords":"int float string vector matrix if else switch case default while do for in break continue global proc return about abs addAttr addAttributeEditorNodeHelp addDynamic addNewShelfTab addPP addPanelCategory addPrefixToName advanceToNextDrivenKey affectedNet affects aimConstraint air alias aliasAttr align alignCtx alignCurve alignSurface allViewFit ambientLight angle angleBetween animCone animCurveEditor animDisplay animView annotate appendStringArray applicationName applyAttrPreset applyTake arcLenDimContext arcLengthDimension arclen arrayMapper art3dPaintCtx artAttrCtx artAttrPaintVertexCtx artAttrSkinPaintCtx artAttrTool artBuildPaintMenu artFluidAttrCtx artPuttyCtx artSelectCtx artSetPaintCtx artUserPaintCtx assignCommand assignInputDevice assignViewportFactories attachCurve attachDeviceAttr attachSurface attrColorSliderGrp attrCompatibility attrControlGrp attrEnumOptionMenu attrEnumOptionMenuGrp attrFieldGrp attrFieldSliderGrp attrNavigationControlGrp attrPresetEditWin attributeExists attributeInfo attributeMenu attributeQuery autoKeyframe autoPlace bakeClip bakeFluidShading bakePartialHistory bakeResults bakeSimulation basename basenameEx batchRender bessel bevel bevelPlus binMembership bindSkin blend2 blendShape blendShapeEditor blendShapePanel blendTwoAttr blindDataType boneLattice boundary boxDollyCtx boxZoomCtx bufferCurve buildBookmarkMenu buildKeyframeMenu button buttonManip CBG cacheFile cacheFileCombine cacheFileMerge cacheFileTrack camera cameraView canCreateManip canvas capitalizeString catch catchQuiet ceil changeSubdivComponentDisplayLevel changeSubdivRegion channelBox character characterMap characterOutlineEditor characterize chdir checkBox checkBoxGrp checkDefaultRenderGlobals choice circle circularFillet clamp clear clearCache clip clipEditor clipEditorCurrentTimeCtx clipSchedule clipSchedulerOutliner clipTrimBefore closeCurve closeSurface cluster cmdFileOutput cmdScrollFieldExecuter cmdScrollFieldReporter cmdShell coarsenSubdivSelectionList collision color colorAtPoint colorEditor colorIndex colorIndexSliderGrp colorSliderButtonGrp colorSliderGrp columnLayout commandEcho commandLine commandPort compactHairSystem componentEditor compositingInterop computePolysetVolume condition cone confirmDialog connectAttr connectControl connectDynamic connectJoint connectionInfo constrain constrainValue constructionHistory container containsMultibyte contextInfo control convertFromOldLayers convertIffToPsd convertLightmap convertSolidTx convertTessellation convertUnit copyArray copyFlexor copyKey copySkinWeights cos cpButton cpCache cpClothSet cpCollision cpConstraint cpConvClothToMesh cpForces cpGetSolverAttr cpPanel cpProperty cpRigidCollisionFilter cpSeam cpSetEdit cpSetSolverAttr cpSolver cpSolverTypes cpTool cpUpdateClothUVs createDisplayLayer createDrawCtx createEditor createLayeredPsdFile createMotionField createNewShelf createNode createRenderLayer createSubdivRegion cross crossProduct ctxAbort ctxCompletion ctxEditMode ctxTraverse currentCtx currentTime currentTimeCtx currentUnit curve curveAddPtCtx curveCVCtx curveEPCtx curveEditorCtx curveIntersect curveMoveEPCtx curveOnSurface curveSketchCtx cutKey cycleCheck cylinder dagPose date defaultLightListCheckBox defaultNavigation defineDataServer defineVirtualDevice deformer deg_to_rad delete deleteAttr deleteShadingGroupsAndMaterials deleteShelfTab deleteUI deleteUnusedBrushes delrandstr detachCurve detachDeviceAttr detachSurface deviceEditor devicePanel dgInfo dgdirty dgeval dgtimer dimWhen directKeyCtx directionalLight dirmap dirname disable disconnectAttr disconnectJoint diskCache displacementToPoly displayAffected displayColor displayCull displayLevelOfDetail displayPref displayRGBColor displaySmoothness displayStats displayString displaySurface distanceDimContext distanceDimension doBlur dolly dollyCtx dopeSheetEditor dot dotProduct doubleProfileBirailSurface drag dragAttrContext draggerContext dropoffLocator duplicate duplicateCurve duplicateSurface dynCache dynControl dynExport dynExpression dynGlobals dynPaintEditor dynParticleCtx dynPref dynRelEdPanel dynRelEditor dynamicLoad editAttrLimits editDisplayLayerGlobals editDisplayLayerMembers editRenderLayerAdjustment editRenderLayerGlobals editRenderLayerMembers editor editorTemplate effector emit emitter enableDevice encodeString endString endsWith env equivalent equivalentTol erf error eval evalDeferred evalEcho event exactWorldBoundingBox exclusiveLightCheckBox exec executeForEachObject exists exp expression expressionEditorListen extendCurve extendSurface extrude fcheck fclose feof fflush fgetline fgetword file fileBrowserDialog fileDialog fileExtension fileInfo filetest filletCurve filter filterCurve filterExpand filterStudioImport findAllIntersections findAnimCurves findKeyframe findMenuItem findRelatedSkinCluster finder firstParentOf fitBspline flexor floatEq floatField floatFieldGrp floatScrollBar floatSlider floatSlider2 floatSliderButtonGrp floatSliderGrp floor flow fluidCacheInfo fluidEmitter fluidVoxelInfo flushUndo fmod fontDialog fopen formLayout format fprint frameLayout fread freeFormFillet frewind fromNativePath fwrite gamma gauss geometryConstraint getApplicationVersionAsFloat getAttr getClassification getDefaultBrush getFileList getFluidAttr getInputDeviceRange getMayaPanelTypes getModifiers getPanel getParticleAttr getPluginResource getenv getpid glRender glRenderEditor globalStitch gmatch goal gotoBindPose grabColor gradientControl gradientControlNoAttr graphDollyCtx graphSelectContext graphTrackCtx gravity grid gridLayout group groupObjectsByName HfAddAttractorToAS HfAssignAS HfBuildEqualMap HfBuildFurFiles HfBuildFurImages HfCancelAFR HfConnectASToHF HfCreateAttractor HfDeleteAS HfEditAS HfPerformCreateAS HfRemoveAttractorFromAS HfSelectAttached HfSelectAttractors HfUnAssignAS hardenPointCurve hardware hardwareRenderPanel headsUpDisplay headsUpMessage help helpLine hermite hide hilite hitTest hotBox hotkey hotkeyCheck hsv_to_rgb hudButton hudSlider hudSliderButton hwReflectionMap hwRender hwRenderLoad hyperGraph hyperPanel hyperShade hypot iconTextButton iconTextCheckBox iconTextRadioButton iconTextRadioCollection iconTextScrollList iconTextStaticLabel ikHandle ikHandleCtx ikHandleDisplayScale ikSolver ikSplineHandleCtx ikSystem ikSystemInfo ikfkDisplayMethod illustratorCurves image imfPlugins inheritTransform insertJoint insertJointCtx insertKeyCtx insertKnotCurve insertKnotSurface instance instanceable instancer intField intFieldGrp intScrollBar intSlider intSliderGrp interToUI internalVar intersect iprEngine isAnimCurve isConnected isDirty isParentOf isSameObject isTrue isValidObjectName isValidString isValidUiName isolateSelect itemFilter itemFilterAttr itemFilterRender itemFilterType joint jointCluster jointCtx jointDisplayScale jointLattice keyTangent keyframe keyframeOutliner keyframeRegionCurrentTimeCtx keyframeRegionDirectKeyCtx keyframeRegionDollyCtx keyframeRegionInsertKeyCtx keyframeRegionMoveKeyCtx keyframeRegionScaleKeyCtx keyframeRegionSelectKeyCtx keyframeRegionSetKeyCtx keyframeRegionTrackCtx keyframeStats lassoContext lattice latticeDeformKeyCtx launch launchImageEditor layerButton layeredShaderPort layeredTexturePort layout layoutDialog lightList lightListEditor lightListPanel lightlink lineIntersection linearPrecision linstep listAnimatable listAttr listCameras listConnections listDeviceAttachments listHistory listInputDeviceAxes listInputDeviceButtons listInputDevices listMenuAnnotation listNodeTypes listPanelCategories listRelatives listSets listTransforms listUnselected listerEditor loadFluid loadNewShelf loadPlugin loadPluginLanguageResources loadPrefObjects localizedPanelLabel lockNode loft log longNameOf lookThru ls lsThroughFilter lsType lsUI Mayatomr mag makeIdentity makeLive makePaintable makeRoll makeSingleSurface makeTubeOn makebot manipMoveContext manipMoveLimitsCtx manipOptions manipRotateContext manipRotateLimitsCtx manipScaleContext manipScaleLimitsCtx marker match max memory menu menuBarLayout menuEditor menuItem menuItemToShelf menuSet menuSetPref messageLine min minimizeApp mirrorJoint modelCurrentTimeCtx modelEditor modelPanel mouse movIn movOut move moveIKtoFK moveKeyCtx moveVertexAlongDirection multiProfileBirailSurface mute nParticle nameCommand nameField namespace namespaceInfo newPanelItems newton nodeCast nodeIconButton nodeOutliner nodePreset nodeType noise nonLinear normalConstraint normalize nurbsBoolean nurbsCopyUVSet nurbsCube nurbsEditUV nurbsPlane nurbsSelect nurbsSquare nurbsToPoly nurbsToPolygonsPref nurbsToSubdiv nurbsToSubdivPref nurbsUVSet nurbsViewDirectionVector objExists objectCenter objectLayer objectType objectTypeUI obsoleteProc oceanNurbsPreviewPlane offsetCurve offsetCurveOnSurface offsetSurface openGLExtension openMayaPref optionMenu optionMenuGrp optionVar orbit orbitCtx orientConstraint outlinerEditor outlinerPanel overrideModifier paintEffectsDisplay pairBlend palettePort paneLayout panel panelConfiguration panelHistory paramDimContext paramDimension paramLocator parent parentConstraint particle particleExists particleInstancer particleRenderInfo partition pasteKey pathAnimation pause pclose percent performanceOptions pfxstrokes pickWalk picture pixelMove planarSrf plane play playbackOptions playblast plugAttr plugNode pluginInfo pluginResourceUtil pointConstraint pointCurveConstraint pointLight pointMatrixMult pointOnCurve pointOnSurface pointPosition poleVectorConstraint polyAppend polyAppendFacetCtx polyAppendVertex polyAutoProjection polyAverageNormal polyAverageVertex polyBevel polyBlendColor polyBlindData polyBoolOp polyBridgeEdge polyCacheMonitor polyCheck polyChipOff polyClipboard polyCloseBorder polyCollapseEdge polyCollapseFacet polyColorBlindData polyColorDel polyColorPerVertex polyColorSet polyCompare polyCone polyCopyUV polyCrease polyCreaseCtx polyCreateFacet polyCreateFacetCtx polyCube polyCut polyCutCtx polyCylinder polyCylindricalProjection polyDelEdge polyDelFacet polyDelVertex polyDuplicateAndConnect polyDuplicateEdge polyEditUV polyEditUVShell polyEvaluate polyExtrudeEdge polyExtrudeFacet polyExtrudeVertex polyFlipEdge polyFlipUV polyForceUV polyGeoSampler polyHelix polyInfo polyInstallAction polyLayoutUV polyListComponentConversion polyMapCut polyMapDel polyMapSew polyMapSewMove polyMergeEdge polyMergeEdgeCtx polyMergeFacet polyMergeFacetCtx polyMergeUV polyMergeVertex polyMirrorFace polyMoveEdge polyMoveFacet polyMoveFacetUV polyMoveUV polyMoveVertex polyNormal polyNormalPerVertex polyNormalizeUV polyOptUvs polyOptions polyOutput polyPipe polyPlanarProjection polyPlane polyPlatonicSolid polyPoke polyPrimitive polyPrism polyProjection polyPyramid polyQuad polyQueryBlindData polyReduce polySelect polySelectConstraint polySelectConstraintMonitor polySelectCtx polySelectEditCtx polySeparate polySetToFaceNormal polySewEdge polyShortestPathCtx polySmooth polySoftEdge polySphere polySphericalProjection polySplit polySplitCtx polySplitEdge polySplitRing polySplitVertex polyStraightenUVBorder polySubdivideEdge polySubdivideFacet polyToSubdiv polyTorus polyTransfer polyTriangulate polyUVSet polyUnite polyWedgeFace popen popupMenu pose pow preloadRefEd print progressBar progressWindow projFileViewer projectCurve projectTangent projectionContext projectionManip promptDialog propModCtx propMove psdChannelOutliner psdEditTextureFile psdExport psdTextureFile putenv pwd python querySubdiv quit rad_to_deg radial radioButton radioButtonGrp radioCollection radioMenuItemCollection rampColorPort rand randomizeFollicles randstate rangeControl readTake rebuildCurve rebuildSurface recordAttr recordDevice redo reference referenceEdit referenceQuery refineSubdivSelectionList refresh refreshAE registerPluginResource rehash reloadImage removeJoint removeMultiInstance removePanelCategory rename renameAttr renameSelectionList renameUI render renderGlobalsNode renderInfo renderLayerButton renderLayerParent renderLayerPostProcess renderLayerUnparent renderManip renderPartition renderQualityNode renderSettings renderThumbnailUpdate renderWindowEditor renderWindowSelectContext renderer reorder reorderDeformers requires reroot resampleFluid resetAE resetPfxToPolyCamera resetTool resolutionNode retarget reverseCurve reverseSurface revolve rgb_to_hsv rigidBody rigidSolver roll rollCtx rootOf rot rotate rotationInterpolation roundConstantRadius rowColumnLayout rowLayout runTimeCommand runup sampleImage saveAllShelves saveAttrPreset saveFluid saveImage saveInitialState saveMenu savePrefObjects savePrefs saveShelf saveToolSettings scale scaleBrushBrightness scaleComponents scaleConstraint scaleKey scaleKeyCtx sceneEditor sceneUIReplacement scmh scriptCtx scriptEditorInfo scriptJob scriptNode scriptTable scriptToShelf scriptedPanel scriptedPanelType scrollField scrollLayout sculpt searchPathArray seed selLoadSettings select selectContext selectCurveCV selectKey selectKeyCtx selectKeyframeRegionCtx selectMode selectPref selectPriority selectType selectedNodes selectionConnection separator setAttr setAttrEnumResource setAttrMapping setAttrNiceNameResource setConstraintRestPosition setDefaultShadingGroup setDrivenKeyframe setDynamic setEditCtx setEditor setFluidAttr setFocus setInfinity setInputDeviceMapping setKeyCtx setKeyPath setKeyframe setKeyframeBlendshapeTargetWts setMenuMode setNodeNiceNameResource setNodeTypeFlag setParent setParticleAttr setPfxToPolyCamera setPluginResource setProject setStampDensity setStartupMessage setState setToolTo setUITemplate setXformManip sets shadingConnection shadingGeometryRelCtx shadingLightRelCtx shadingNetworkCompare shadingNode shapeCompare shelfButton shelfLayout shelfTabLayout shellField shortNameOf showHelp showHidden showManipCtx showSelectionInTitle showShadingGroupAttrEditor showWindow sign simplify sin singleProfileBirailSurface size sizeBytes skinCluster skinPercent smoothCurve smoothTangentSurface smoothstep snap2to2 snapKey snapMode snapTogetherCtx snapshot soft softMod softModCtx sort sound soundControl source spaceLocator sphere sphrand spotLight spotLightPreviewPort spreadSheetEditor spring sqrt squareSurface srtContext stackTrace startString startsWith stitchAndExplodeShell stitchSurface stitchSurfacePoints strcmp stringArrayCatenate stringArrayContains stringArrayCount stringArrayInsertAtIndex stringArrayIntersector stringArrayRemove stringArrayRemoveAtIndex stringArrayRemoveDuplicates stringArrayRemoveExact stringArrayToString stringToStringArray strip stripPrefixFromName stroke subdAutoProjection subdCleanTopology subdCollapse subdDuplicateAndConnect subdEditUV subdListComponentConversion subdMapCut subdMapSewMove subdMatchTopology subdMirror subdToBlind subdToPoly subdTransferUVsToCache subdiv subdivCrease subdivDisplaySmoothness substitute substituteAllString substituteGeometry substring surface surfaceSampler surfaceShaderList swatchDisplayPort switchTable symbolButton symbolCheckBox sysFile system tabLayout tan tangentConstraint texLatticeDeformContext texManipContext texMoveContext texMoveUVShellContext texRotateContext texScaleContext texSelectContext texSelectShortestPathCtx texSmudgeUVContext texWinToolCtx text textCurves textField textFieldButtonGrp textFieldGrp textManip textScrollList textToShelf textureDisplacePlane textureHairColor texturePlacementContext textureWindow threadCount threePointArcCtx timeControl timePort timerX toNativePath toggle toggleAxis toggleWindowVisibility tokenize tokenizeList tolerance tolower toolButton toolCollection toolDropped toolHasOptions toolPropertyWindow torus toupper trace track trackCtx transferAttributes transformCompare transformLimits translator trim trunc truncateFluidCache truncateHairCache tumble tumbleCtx turbulence twoPointArcCtx uiRes uiTemplate unassignInputDevice undo undoInfo ungroup uniform unit unloadPlugin untangleUV untitledFileName untrim upAxis updateAE userCtx uvLink uvSnapshot validateShelfName vectorize view2dToolCtx viewCamera viewClipPlane viewFit viewHeadOn viewLookAt viewManip viewPlace viewSet visor volumeAxis vortex waitCursor warning webBrowser webBrowserPrefs whatIs window windowPref wire wireContext workspace wrinkle wrinkleContext writeTake xbmLangPathList xform","illegal":""},{"begin":"<=","relevance":0},{"begin":"=>","relevance":0},{"begin":"/\\\\"},{"begin":"\\\\\\/"}]},{"className":"built_in","variants":[{"begin":":-\\|-->"},{"begin":"=","relevance":0}]},{"className":"comment","begin":"%","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"/\\*","end":"\\*/","contains":[{"$ref":"#contains.2.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"number","begin":"0'.\\|0[box][0-9a-fA-F]*"},{"className":"number","begin":"\\b\\d+(\\.\\d+)?","relevance":0},{"className":"string","begin":"'","end":"'","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0}],"relevance":0},{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"$ref":"#contains.6.contains.0"},{"className":"subst","begin":"\\\\[abfnrtv]\\|\\\\x[0-9a-fA-F]*\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]","relevance":0},{"className":"subst","begin":"\\\\[abfnrtv]\\|\\\\x[0-9a-fA-F]*\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]","relevance":0}],"relevance":0},{"begin":":-"}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/mipsasm.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/mipsasm.json new file mode 100644 index 00000000..3bcbebbe --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/mipsasm.json @@ -0,0 +1 @@ +{"case_insensitive":true,"aliases":["mips"],"lexemes":"\\.?[a-zA-Z]\\w*","keywords":{"meta":".2byte .4byte .align .ascii .asciz .balign .byte .code .data .else .end .endif .endm .endr .equ .err .exitm .extern .global .hword .if .ifdef .ifndef .include .irp .long .macro .rept .req .section .set .skip .space .text .word .ltorg ","built_in":"$0 $1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14 $15 $16 $17 $18 $19 $20 $21 $22 $23 $24 $25 $26 $27 $28 $29 $30 $31 zero at v0 v1 a0 a1 a2 a3 a4 a5 a6 a7 t0 t1 t2 t3 t4 t5 t6 t7 t8 t9 s0 s1 s2 s3 s4 s5 s6 s7 s8 k0 k1 gp sp fp ra $f0 $f1 $f2 $f2 $f4 $f5 $f6 $f7 $f8 $f9 $f10 $f11 $f12 $f13 $f14 $f15 $f16 $f17 $f18 $f19 $f20 $f21 $f22 $f23 $f24 $f25 $f26 $f27 $f28 $f29 $f30 $f31 Context Random EntryLo0 EntryLo1 Context PageMask Wired EntryHi HWREna BadVAddr Count Compare SR IntCtl SRSCtl SRSMap Cause EPC PRId EBase Config Config1 Config2 Config3 LLAddr Debug DEPC DESAVE CacheErr ECC ErrorEPC TagLo DataLo TagHi DataHi WatchLo WatchHi PerfCtl PerfCnt "},"contains":[{"className":"keyword","begin":"\\b(addi?u?|andi?|b(al)?|beql?|bgez(al)?l?|bgtzl?|blezl?|bltz(al)?l?|bnel?|cl[oz]|divu?|ext|ins|j(al)?|jalr(.hb)?|jr(.hb)?|lbu?|lhu?|ll|lui|lw[lr]?|maddu?|mfhi|mflo|movn|movz|move|msubu?|mthi|mtlo|mul|multu?|nop|nor|ori?|rotrv?|sb|sc|se[bh]|sh|sllv?|slti?u?|srav?|srlv?|subu?|sw[lr]?|xori?|wsbh|abs.[sd]|add.[sd]|alnv.ps|bc1[ft]l?|c.(s?f|un|u?eq|[ou]lt|[ou]le|ngle?|seq|l[et]|ng[et]).[sd]|(ceil|floor|round|trunc).[lw].[sd]|cfc1|cvt.d.[lsw]|cvt.l.[dsw]|cvt.ps.s|cvt.s.[dlw]|cvt.s.p[lu]|cvt.w.[dls]|div.[ds]|ldx?c1|luxc1|lwx?c1|madd.[sd]|mfc1|mov[fntz]?.[ds]|msub.[sd]|mth?c1|mul.[ds]|neg.[ds]|nmadd.[ds]|nmsub.[ds]|p[lu][lu].ps|recip.fmt|r?sqrt.[ds]|sdx?c1|sub.[ds]|suxc1|swx?c1|break|cache|d?eret|[de]i|ehb|mfc0|mtc0|pause|prefx?|rdhwr|rdpgpr|sdbbp|ssnop|synci?|syscall|teqi?|tgei?u?|tlb(p|r|w[ir])|tlti?u?|tnei?|wait|wrpgpr)","end":"\\s"},{"className":"comment","begin":"[;#]","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"/\\*","end":"\\*/","contains":[{"$ref":"#contains.1.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0},{"className":"subst","begin":"\\\\[abfnrtv]\\|\\\\x[0-9a-fA-F]*\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]","relevance":0},{"className":"subst","begin":"\\\\[abfnrtv]\\|\\\\x[0-9a-fA-F]*\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]","relevance":0}]},{"className":"string","begin":"'","end":"[^\\\\]'","relevance":0},{"className":"title","begin":"\\|","end":"\\|","illegal":"\\n","relevance":0},{"className":"number","variants":[{"begin":"0x[0-9a-f]+"},{"begin":"\\b-?\\d+"}],"relevance":0},{"className":"symbol","variants":[{"begin":"^\\s*[a-z_\\.\\$][a-z0-9_\\.\\$]+:"},{"begin":"^\\s*[0-9]+:"},{"begin":"[0-9]+[bf]"}],"relevance":0}],"illegal":"/"} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/mizar.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/mizar.json new file mode 100644 index 00000000..2693fe9f --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/mizar.json @@ -0,0 +1 @@ +{"keywords":"environ vocabularies notations constructors definitions registrations theorems schemes requirements begin end definition registration cluster existence pred func defpred deffunc theorem proof let take assume then thus hence ex for st holds consider reconsider such that and in provided of as from be being by means equals implies iff redefine define now not or attr is mode suppose per cases set thesis contradiction scheme reserve struct correctness compatibility coherence symmetry assymetry reflexivity irreflexivity connectedness uniqueness commutativity idempotence involutiveness projectivity","contains":[{"className":"comment","begin":"::","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/mojolicious.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/mojolicious.json new file mode 100644 index 00000000..0f5e2b9f --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/mojolicious.json @@ -0,0 +1 @@ +{"subLanguage":"xml","contains":[{"className":"meta","begin":"^__(END|DATA)__$"},{"begin":"^\\s*%{1,2}={0,2}","end":"$","subLanguage":"perl"},{"begin":"<%{1,2}={0,2}","end":"={0,1}%>","subLanguage":"perl","excludeBegin":true,"excludeEnd":true}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/monkey.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/monkey.json new file mode 100644 index 00000000..cd4f757b --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/monkey.json @@ -0,0 +1 @@ +{"case_insensitive":true,"keywords":{"keyword":"public private property continue exit extern new try catch eachin not abstract final select case default const local global field end if then else elseif endif while wend repeat until forever for to step next return module inline throw import","built_in":"DebugLog DebugStop Error Print ACos ACosr ASin ASinr ATan ATan2 ATan2r ATanr Abs Abs Ceil Clamp Clamp Cos Cosr Exp Floor Log Max Max Min Min Pow Sgn Sgn Sin Sinr Sqrt Tan Tanr Seed PI HALFPI TWOPI","literal":"true false null and or shl shr mod"},"illegal":"\\/\\*","contains":[{"className":"comment","begin":"#rem","end":"#end","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"'","end":"$","contains":[{"$ref":"#contains.0.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}],"relevance":0},{"className":"function","beginKeywords":"function method","end":"[(=:]|$","illegal":"\\n","contains":[{"className":"title","begin":"[a-zA-Z_]\\w*","relevance":0}]},{"className":"class","beginKeywords":"class interface","end":"$","contains":[{"beginKeywords":"extends implements"},{"$ref":"#contains.2.contains.0"}]},{"className":"built_in","begin":"\\b(self|super)\\b"},{"className":"meta","begin":"\\s*#","end":"$","keywords":{"meta-keyword":"if else elseif endif end then"}},{"className":"meta","begin":"^\\s*strict\\b"},{"beginKeywords":"alias","end":"=","contains":[{"$ref":"#contains.2.contains.0"}]},{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0},{"className":"subst","begin":"\\\\[abfnrtv]\\|\\\\x[0-9a-fA-F]*\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]","relevance":0},{"className":"subst","begin":"\\\\[abfnrtv]\\|\\\\x[0-9a-fA-F]*\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]","relevance":0}]},{"className":"number","relevance":0,"variants":[{"begin":"[$][a-fA-F0-9]+"},{"className":"number","begin":"\\b\\d+(\\.\\d+)?","relevance":0}]}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/moonscript.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/moonscript.json new file mode 100644 index 00000000..082bede9 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/moonscript.json @@ -0,0 +1 @@ +{"aliases":["moon"],"keywords":{"keyword":"if then not for in while do return else elseif break continue switch and or unless when class extends super local import export from using","literal":"true false nil","built_in":"_G _VERSION assert collectgarbage dofile error getfenv getmetatable ipairs load loadfile loadstring module next pairs pcall print rawequal rawget rawset require select setfenv setmetatable tonumber tostring type unpack xpcall coroutine debug io math os package string table"},"illegal":"\\/\\*","contains":[{"className":"number","begin":"(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)","relevance":0,"starts":{"end":"(\\s*/)?","relevance":0}},{"className":"string","variants":[{"begin":"'","end":"'","contains":[{"begin":"\\\\[\\s\\S]","relevance":0}]},{"begin":"\"","end":"\"","contains":[{"$ref":"#contains.1.variants.0.contains.0"},{"className":"subst","begin":"#\\{","end":"}","keywords":{"$ref":"#keywords"},"contains":[{"$ref":"#contains.0"},{"$ref":"#contains.1"},{"className":"built_in","begin":"@__[a-zA-Z]\\w*"},{"begin":"@[a-zA-Z]\\w*"},{"begin":"[a-zA-Z]\\w*\\\\[a-zA-Z]\\w*"}]}]}]},{"$ref":"#contains.1.variants.1.contains.1.contains.2"},{"$ref":"#contains.1.variants.1.contains.1.contains.3"},{"$ref":"#contains.1.variants.1.contains.1.contains.4"},{"className":"comment","begin":"--","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"function","begin":"^\\s*[A-Za-z$_][0-9A-Za-z$_]*\\s*=\\s*(\\(.*\\))?\\s*\\B[-=]>","end":"[-=]>","returnBegin":true,"contains":[{"className":"title","begin":"[A-Za-z$_][0-9A-Za-z$_]*","relevance":0},{"className":"params","begin":"\\([^\\(]","returnBegin":true,"contains":[{"begin":"\\(","end":"\\)","keywords":{"$ref":"#keywords"},"contains":["self",{"$ref":"#contains.0"},{"$ref":"#contains.1"},{"$ref":"#contains.1.variants.1.contains.1.contains.2"},{"$ref":"#contains.1.variants.1.contains.1.contains.3"},{"$ref":"#contains.1.variants.1.contains.1.contains.4"}]}]}]},{"begin":"[\\(,:=]\\s*","relevance":0,"contains":[{"className":"function","begin":"(\\(.*\\))?\\s*\\B[-=]>","end":"[-=]>","returnBegin":true,"contains":[{"$ref":"#contains.6.contains.1"}]}]},{"className":"class","beginKeywords":"class","end":"$","illegal":"[:=\"\\[\\]]","contains":[{"beginKeywords":"extends","endsWithParent":true,"illegal":"[:=\"\\[\\]]","contains":[{"$ref":"#contains.6.contains.0"}]},{"$ref":"#contains.6.contains.0"}]},{"className":"name","begin":"[A-Za-z$_][0-9A-Za-z$_]*:","end":":","returnBegin":true,"returnEnd":true,"relevance":0}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/n1ql.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/n1ql.json new file mode 100644 index 00000000..e14a16b9 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/n1ql.json @@ -0,0 +1 @@ +{"case_insensitive":true,"contains":[{"beginKeywords":"build create index delete drop explain infer|10 insert merge prepare select update upsert|10","end":";","endsWithParent":true,"keywords":{"keyword":"all alter analyze and any array as asc begin between binary boolean break bucket build by call case cast cluster collate collection commit connect continue correlate cover create database dataset datastore declare decrement delete derived desc describe distinct do drop each element else end every except exclude execute exists explain fetch first flatten for force from function grant group gsi having if ignore ilike in include increment index infer inline inner insert intersect into is join key keys keyspace known last left let letting like limit lsm map mapping matched materialized merge minus namespace nest not number object offset on option or order outer over parse partition password path pool prepare primary private privilege procedure public raw realm reduce rename return returning revoke right role rollback satisfies schema select self semi set show some start statistics string system then to transaction trigger truncate under union unique unknown unnest unset update upsert use user using validate value valued values via view when where while with within work xor","literal":"true false null missing|5","built_in":"array_agg array_append array_concat array_contains array_count array_distinct array_ifnull array_length array_max array_min array_position array_prepend array_put array_range array_remove array_repeat array_replace array_reverse array_sort array_sum avg count max min sum greatest least ifmissing ifmissingornull ifnull missingif nullif ifinf ifnan ifnanorinf naninf neginfif posinfif clock_millis clock_str date_add_millis date_add_str date_diff_millis date_diff_str date_part_millis date_part_str date_trunc_millis date_trunc_str duration_to_str millis str_to_millis millis_to_str millis_to_utc millis_to_zone_name now_millis now_str str_to_duration str_to_utc str_to_zone_name decode_json encode_json encoded_size poly_length base64 base64_encode base64_decode meta uuid abs acos asin atan atan2 ceil cos degrees e exp ln log floor pi power radians random round sign sin sqrt tan trunc object_length object_names object_pairs object_inner_pairs object_values object_inner_values object_add object_put object_remove object_unwrap regexp_contains regexp_like regexp_position regexp_replace contains initcap length lower ltrim position repeat replace rtrim split substr title trim upper isarray isatom isboolean isnumber isobject isstring type toarray toatom toboolean tonumber toobject tostring"},"contains":[{"className":"string","begin":"'","end":"'","contains":[{"begin":"\\\\[\\s\\S]","relevance":0}],"relevance":0},{"className":"string","begin":"\"","end":"\"","contains":[{"$ref":"#contains.0.contains.0.contains.0"}],"relevance":0},{"className":"symbol","begin":"`","end":"`","contains":[{"$ref":"#contains.0.contains.0.contains.0"}],"relevance":2},{"className":"number","begin":"(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)","relevance":0},{"className":"comment","begin":"/\\*","end":"\\*/","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]}]},{"$ref":"#contains.0.contains.4"}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/nginx.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/nginx.json new file mode 100644 index 00000000..b3bb8fde --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/nginx.json @@ -0,0 +1 @@ +{"aliases":["nginxconf"],"contains":[{"className":"comment","begin":"#","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"begin":"[a-zA-Z_]\\w*\\s+{","returnBegin":true,"end":"{","contains":[{"className":"section","begin":"[a-zA-Z_]\\w*"}],"relevance":0},{"begin":"[a-zA-Z_]\\w*\\s","end":";|{","returnBegin":true,"contains":[{"className":"attribute","begin":"[a-zA-Z_]\\w*","starts":{"endsWithParent":true,"lexemes":"[a-z/_]+","keywords":{"literal":"on off yes no true false none blocked debug info notice warn error crit select break last permanent redirect kqueue rtsig epoll poll /dev/poll"},"relevance":0,"illegal":"=>","contains":[{"$ref":"#contains.0"},{"className":"string","contains":[{"begin":"\\\\[\\s\\S]","relevance":0},{"className":"variable","variants":[{"begin":"\\$\\d+"},{"begin":"\\$\\{","end":"}"},{"begin":"[\\$\\@][a-zA-Z_]\\w*"}]}],"variants":[{"begin":"\"","end":"\""},{"begin":"'","end":"'"}]},{"begin":"([a-z]+):/","end":"\\s","endsWithParent":true,"excludeEnd":true,"contains":[{"$ref":"#contains.2.contains.0.starts.contains.1.contains.1"}]},{"className":"regexp","contains":[{"$ref":"#contains.2.contains.0.starts.contains.1.contains.0"},{"$ref":"#contains.2.contains.0.starts.contains.1.contains.1"}],"variants":[{"begin":"\\s\\^","end":"\\s|{|;","returnEnd":true},{"begin":"~\\*?\\s+","end":"\\s|{|;","returnEnd":true},{"begin":"\\*(\\.[a-z\\-]+)+"},{"begin":"([a-z\\-]+\\.)+\\*"}]},{"className":"number","begin":"\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}(:\\d{1,5})?\\b"},{"className":"number","begin":"\\b\\d+[kKmMgGdshdwy]*\\b","relevance":0},{"$ref":"#contains.2.contains.0.starts.contains.1.contains.1"}]}}],"relevance":0}],"illegal":"[^\\s\\}]"} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/nimrod.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/nimrod.json new file mode 100644 index 00000000..17db1496 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/nimrod.json @@ -0,0 +1 @@ +{"aliases":["nim"],"keywords":{"keyword":"addr and as asm bind block break case cast const continue converter discard distinct div do elif else end enum except export finally for from generic if import in include interface is isnot iterator let macro method mixin mod nil not notin object of or out proc ptr raise ref return shl shr static template try tuple type using var when while with without xor yield","literal":"shared guarded stdin stdout stderr result true false","built_in":"int int8 int16 int32 int64 uint uint8 uint16 uint32 uint64 float float32 float64 bool char string cstring pointer expr stmt void auto any range array openarray varargs seq set clong culong cchar cschar cshort cint csize clonglong cfloat cdouble clongdouble cuchar cushort cuint culonglong cstringarray semistatic"},"contains":[{"className":"meta","begin":"{\\.","end":"\\.}","relevance":10},{"className":"string","begin":"[a-zA-Z]\\w*\"","end":"\"","contains":[{"begin":"\"\""}]},{"className":"string","begin":"([a-zA-Z]\\w*)?\"\"\"","end":"\"\"\""},{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0},{"className":"subst","begin":"\\\\[abfnrtv]\\|\\\\x[0-9a-fA-F]*\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]","relevance":0},{"className":"subst","begin":"\\\\[abfnrtv]\\|\\\\x[0-9a-fA-F]*\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]","relevance":0}]},{"className":"type","begin":"\\b[A-Z]\\w+\\b","relevance":0},{"className":"number","relevance":0,"variants":[{"begin":"\\b(0[xX][0-9a-fA-F][_0-9a-fA-F]*)('?[iIuU](8|16|32|64))?"},{"begin":"\\b(0o[0-7][_0-7]*)('?[iIuUfF](8|16|32|64))?"},{"begin":"\\b(0(b|B)[01][_01]*)('?[iIuUfF](8|16|32|64))?"},{"begin":"\\b(\\d[_\\d]*)('?[iIuUfF](8|16|32|64))?"}]},{"className":"comment","begin":"#","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/nix.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/nix.json new file mode 100644 index 00000000..f53f1d70 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/nix.json @@ -0,0 +1 @@ +{"aliases":["nixos"],"keywords":{"keyword":"rec with let in inherit assert if else then","literal":"true false or and null","built_in":"import abort baseNameOf dirOf isNull builtins map removeAttrs throw toString derivation"},"contains":[{"className":"number","begin":"\\b\\d+(\\.\\d+)?","relevance":0},{"className":"comment","begin":"#","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"/\\*","end":"\\*/","contains":[{"$ref":"#contains.1.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"string","contains":[{"className":"subst","begin":"\\$\\{","end":"}","keywords":{"$ref":"#keywords"},"contains":{"$ref":"#contains"}}],"variants":[{"begin":"''","end":"''"},{"begin":"\"","end":"\""}]},{"begin":"[a-zA-Z0-9-_]+(\\s*=)","returnBegin":true,"relevance":0,"contains":[{"className":"attr","begin":"\\S+"}]}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/nsis.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/nsis.json new file mode 100644 index 00000000..807c2dc5 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/nsis.json @@ -0,0 +1 @@ +{"case_insensitive":false,"keywords":{"keyword":"Abort AddBrandingImage AddSize AllowRootDirInstall AllowSkipFiles AutoCloseWindow BGFont BGGradient BrandingText BringToFront Call CallInstDLL Caption ChangeUI CheckBitmap ClearErrors CompletedText ComponentText CopyFiles CRCCheck CreateDirectory CreateFont CreateShortCut Delete DeleteINISec DeleteINIStr DeleteRegKey DeleteRegValue DetailPrint DetailsButtonText DirText DirVar DirVerify EnableWindow EnumRegKey EnumRegValue Exch Exec ExecShell ExecShellWait ExecWait ExpandEnvStrings File FileBufSize FileClose FileErrorText FileOpen FileRead FileReadByte FileReadUTF16LE FileReadWord FileSeek FileWrite FileWriteByte FileWriteUTF16LE FileWriteWord FindClose FindFirst FindNext FindWindow FlushINI FunctionEnd GetCurInstType GetCurrentAddress GetDlgItem GetDLLVersion GetDLLVersionLocal GetErrorLevel GetFileTime GetFileTimeLocal GetFullPathName GetFunctionAddress GetInstDirError GetLabelAddress GetTempFileName Goto HideWindow Icon IfAbort IfErrors IfFileExists IfRebootFlag IfSilent InitPluginsDir InstallButtonText InstallColors InstallDir InstallDirRegKey InstProgressFlags InstType InstTypeGetText InstTypeSetText Int64Cmp Int64CmpU Int64Fmt IntCmp IntCmpU IntFmt IntOp IntPtrCmp IntPtrCmpU IntPtrOp IsWindow LangString LicenseBkColor LicenseData LicenseForceSelection LicenseLangString LicenseText LoadLanguageFile LockWindow LogSet LogText ManifestDPIAware ManifestSupportedOS MessageBox MiscButtonText Name Nop OutFile Page PageCallbacks PageExEnd Pop Push Quit ReadEnvStr ReadINIStr ReadRegDWORD ReadRegStr Reboot RegDLL Rename RequestExecutionLevel ReserveFile Return RMDir SearchPath SectionEnd SectionGetFlags SectionGetInstTypes SectionGetSize SectionGetText SectionGroupEnd SectionIn SectionSetFlags SectionSetInstTypes SectionSetSize SectionSetText SendMessage SetAutoClose SetBrandingImage SetCompress SetCompressor SetCompressorDictSize SetCtlColors SetCurInstType SetDatablockOptimize SetDateSave SetDetailsPrint SetDetailsView SetErrorLevel SetErrors SetFileAttributes SetFont SetOutPath SetOverwrite SetRebootFlag SetRegView SetShellVarContext SetSilent ShowInstDetails ShowUninstDetails ShowWindow SilentInstall SilentUnInstall Sleep SpaceTexts StrCmp StrCmpS StrCpy StrLen SubCaption Unicode UninstallButtonText UninstallCaption UninstallIcon UninstallSubCaption UninstallText UninstPage UnRegDLL Var VIAddVersionKey VIFileVersion VIProductVersion WindowIcon WriteINIStr WriteRegBin WriteRegDWORD WriteRegExpandStr WriteRegMultiStr WriteRegNone WriteRegStr WriteUninstaller XPStyle","literal":"admin all auto both bottom bzip2 colored components current custom directory false force hide highest ifdiff ifnewer instfiles lastused leave left license listonly lzma nevershow none normal notset off on open print right show silent silentlog smooth textonly top true try un.components un.custom un.directory un.instfiles un.license uninstConfirm user Win10 Win7 Win8 WinVista zlib"},"contains":[{"className":"comment","begin":"#","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"/\\*","end":"\\*/","contains":[{"$ref":"#contains.0.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":";","end":"$","contains":[{"$ref":"#contains.0.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}],"relevance":0},{"className":"function","beginKeywords":"Function PageEx Section SectionGroup","end":"$"},{"className":"string","variants":[{"begin":"\"","end":"\""},{"begin":"'","end":"'"},{"begin":"`","end":"`"}],"illegal":"\\n","contains":[{"className":"meta","begin":"\\$(\\\\[nrt]|\\$)"},{"className":"variable","begin":"\\$(ADMINTOOLS|APPDATA|CDBURN_AREA|CMDLINE|COMMONFILES32|COMMONFILES64|COMMONFILES|COOKIES|DESKTOP|DOCUMENTS|EXEDIR|EXEFILE|EXEPATH|FAVORITES|FONTS|HISTORY|HWNDPARENT|INSTDIR|INTERNET_CACHE|LANGUAGE|LOCALAPPDATA|MUSIC|NETHOOD|OUTDIR|PICTURES|PLUGINSDIR|PRINTHOOD|PROFILE|PROGRAMFILES32|PROGRAMFILES64|PROGRAMFILES|QUICKLAUNCH|RECENT|RESOURCES_LOCALIZED|RESOURCES|SENDTO|SMPROGRAMS|SMSTARTUP|STARTMENU|SYSDIR|TEMP|TEMPLATES|VIDEOS|WINDIR)"},{"className":"variable","begin":"\\$+{[\\w\\.:-]+}"},{"className":"variable","begin":"\\$+\\w+","illegal":"\\(\\){}"},{"className":"variable","begin":"\\$+\\([\\w\\^\\.:-]+\\)"}]},{"className":"keyword","begin":"\\!(addincludedir|addplugindir|appendfile|cd|define|delfile|echo|else|endif|error|execute|finalize|getdllversion|gettlbversion|if|ifdef|ifmacrodef|ifmacrondef|ifndef|include|insertmacro|macro|macroend|makensis|packhdr|searchparse|searchreplace|system|tempfile|undef|verbose|warning)"},{"$ref":"#contains.4.contains.2"},{"$ref":"#contains.4.contains.3"},{"$ref":"#contains.4.contains.4"},{"className":"params","begin":"(ARCHIVE|FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_NORMAL|FILE_ATTRIBUTE_OFFLINE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_TEMPORARY|HKCR|HKCU|HKDD|HKEY_CLASSES_ROOT|HKEY_CURRENT_CONFIG|HKEY_CURRENT_USER|HKEY_DYN_DATA|HKEY_LOCAL_MACHINE|HKEY_PERFORMANCE_DATA|HKEY_USERS|HKLM|HKPD|HKU|IDABORT|IDCANCEL|IDIGNORE|IDNO|IDOK|IDRETRY|IDYES|MB_ABORTRETRYIGNORE|MB_DEFBUTTON1|MB_DEFBUTTON2|MB_DEFBUTTON3|MB_DEFBUTTON4|MB_ICONEXCLAMATION|MB_ICONINFORMATION|MB_ICONQUESTION|MB_ICONSTOP|MB_OK|MB_OKCANCEL|MB_RETRYCANCEL|MB_RIGHT|MB_RTLREADING|MB_SETFOREGROUND|MB_TOPMOST|MB_USERICON|MB_YESNO|NORMAL|OFFLINE|READONLY|SHCTX|SHELL_CONTEXT|SYSTEM|TEMPORARY)"},{"className":"class","begin":"\\w+\\:\\:\\w+"},{"className":"number","begin":"\\b\\d+(\\.\\d+)?","relevance":0}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/objectivec.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/objectivec.json new file mode 100644 index 00000000..70dcded1 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/objectivec.json @@ -0,0 +1 @@ +{"aliases":["mm","objc","obj-c"],"keywords":{"keyword":"int float while char export sizeof typedef const struct for union unsigned long volatile static bool mutable if do return goto void enum else break extern asm case short default double register explicit signed typename this switch continue wchar_t inline readonly assign readwrite self @synchronized id typeof nonatomic super unichar IBOutlet IBAction strong weak copy in out inout bycopy byref oneway __strong __weak __block __autoreleasing @private @protected @public @try @property @end @throw @catch @finally @autoreleasepool @synthesize @dynamic @selector @optional @required @encode @package @import @defs @compatibility_alias __bridge __bridge_transfer __bridge_retained __bridge_retain __covariant __contravariant __kindof _Nonnull _Nullable _Null_unspecified __FUNCTION__ __PRETTY_FUNCTION__ __attribute__ getter setter retain unsafe_unretained nonnull nullable null_unspecified null_resettable class instancetype NS_DESIGNATED_INITIALIZER NS_UNAVAILABLE NS_REQUIRES_SUPER NS_RETURNS_INNER_POINTER NS_INLINE NS_AVAILABLE NS_DEPRECATED NS_ENUM NS_OPTIONS NS_SWIFT_UNAVAILABLE NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_END NS_REFINED_FOR_SWIFT NS_SWIFT_NAME NS_SWIFT_NOTHROW NS_DURING NS_HANDLER NS_ENDHANDLER NS_VALUERETURN NS_VOIDRETURN","literal":"false true FALSE TRUE nil YES NO NULL","built_in":"BOOL dispatch_once_t dispatch_queue_t dispatch_sync dispatch_async dispatch_once"},"lexemes":"[a-zA-Z@][a-zA-Z0-9_]*","illegal":""}]}]},{"className":"class","begin":"(@interface|@class|@protocol|@implementation)\\b","end":"({|$)","excludeEnd":true,"keywords":"@interface @class @protocol @implementation","lexemes":"[a-zA-Z@][a-zA-Z0-9_]*","contains":[{"className":"title","begin":"[a-zA-Z_]\\w*","relevance":0}]},{"begin":"\\.[a-zA-Z_]\\w*","relevance":0}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/ocaml.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/ocaml.json new file mode 100644 index 00000000..8b5985bd --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/ocaml.json @@ -0,0 +1 @@ +{"aliases":["ml"],"keywords":{"keyword":"and as assert asr begin class constraint do done downto else end exception external for fun function functor if in include inherit! inherit initializer land lazy let lor lsl lsr lxor match method!|10 method mod module mutable new object of open! open or private rec sig struct then to try type val! val virtual when while with parser value","built_in":"array bool bytes char exn|5 float int int32 int64 list lazy_t|5 nativeint|5 string unit in_channel out_channel ref","literal":"true false"},"illegal":"\\/\\/|>>","lexemes":"[a-z_]\\w*!?","contains":[{"className":"literal","begin":"\\[(\\|\\|)?\\]|\\(\\)","relevance":0},{"className":"comment","begin":"\\(\\*","end":"\\*\\)","contains":["self",{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"symbol","begin":"'[A-Za-z_](?!')[\\w']*"},{"className":"type","begin":"`[A-Z][\\w']*"},{"className":"type","begin":"\\b[A-Z][\\w']*","relevance":0},{"begin":"[a-z_]\\w*'[\\w']*","relevance":0},{"className":"string","begin":"'","end":"'","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0}],"relevance":0},{"className":"string","begin":"\"","end":"\"","illegal":null,"contains":[{"$ref":"#contains.6.contains.0"},{"className":"subst","begin":"\\\\[abfnrtv]\\|\\\\x[0-9a-fA-F]*\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]","relevance":0},{"className":"subst","begin":"\\\\[abfnrtv]\\|\\\\x[0-9a-fA-F]*\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]","relevance":0}]},{"className":"number","begin":"\\b(0[xX][a-fA-F0-9_]+[Lln]?|0[oO][0-7_]+[Lln]?|0[bB][01_]+[Lln]?|[0-9][0-9_]*([Lln]|(\\.[0-9_]*)?([eE][-+]?[0-9_]+)?)?)","relevance":0},{"begin":"[-=]>"}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/openscad.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/openscad.json new file mode 100644 index 00000000..bdbdf8cf --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/openscad.json @@ -0,0 +1 @@ +{"aliases":["scad"],"keywords":{"keyword":"function module include use for intersection_for if else \\%","literal":"false true PI undef","built_in":"circle square polygon text sphere cube cylinder polyhedron translate rotate scale resize mirror multmatrix color offset hull minkowski union difference intersection abs sign sin cos tan acos asin atan atan2 floor round ceil ln log pow sqrt exp rands min max concat lookup str chr search version version_num norm cross parent_module echo import import_dxf dxf_linear_extrude linear_extrude rotate_extrude surface projection render children dxf_cross dxf_dim let assign"},"contains":[{"className":"comment","begin":"//","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"/\\*","end":"\\*/","contains":[{"$ref":"#contains.0.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"number","begin":"\\b\\d+(\\.\\d+)?(e-?\\d+)?","relevance":0},{"className":"meta","keywords":{"meta-keyword":"include use"},"begin":"include|use <","end":">"},{"className":"string","begin":"\"","end":"\"","illegal":null,"contains":[{"begin":"\\\\[\\s\\S]","relevance":0},{"className":"subst","begin":"\\\\[abfnrtv]\\|\\\\x[0-9a-fA-F]*\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]","relevance":0},{"className":"subst","begin":"\\\\[abfnrtv]\\|\\\\x[0-9a-fA-F]*\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]","relevance":0}]},{"className":"keyword","begin":"\\$(f[asn]|t|vp[rtd]|children)"},{"begin":"[*!#%]","relevance":0},{"className":"function","beginKeywords":"module function","end":"\\=|\\{","contains":[{"className":"params","begin":"\\(","end":"\\)","contains":["self",{"$ref":"#contains.2"},{"$ref":"#contains.4"},{"$ref":"#contains.5"},{"className":"literal","begin":"false|true|PI|undef"}]},{"className":"title","begin":"[a-zA-Z_]\\w*","relevance":0}]}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/oxygene.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/oxygene.json new file mode 100644 index 00000000..f8f5b768 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/oxygene.json @@ -0,0 +1 @@ +{"case_insensitive":true,"lexemes":"\\.?\\w+","keywords":"abstract add and array as asc aspect assembly async begin break block by case class concat const copy constructor continue create default delegate desc distinct div do downto dynamic each else empty end ensure enum equals event except exit extension external false final finalize finalizer finally flags for forward from function future global group has if implementation implements implies in index inherited inline interface into invariants is iterator join locked locking loop matching method mod module namespace nested new nil not notify nullable of old on operator or order out override parallel params partial pinned private procedure property protected public queryable raise read readonly record reintroduce remove repeat require result reverse sealed select self sequence set shl shr skip static step soft take then to true try tuple type union unit unsafe until uses using var virtual raises volatile where while with write xor yield await mapped deprecated stdcall cdecl pascal register safecall overload library platform reference packed strict published autoreleasepool selector strong weak unretained","illegal":"(\"|\\$[G-Zg-z]|\\/\\*||->)","contains":[{"className":"comment","begin":"{","end":"}","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}],"relevance":0},{"className":"comment","begin":"\\(\\*","end":"\\*\\)","contains":[{"$ref":"#contains.0.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}],"relevance":10},{"className":"comment","begin":"//","end":"$","contains":[{"$ref":"#contains.0.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"string","begin":"'","end":"'","contains":[{"begin":"''"}]},{"className":"string","begin":"(#\\d+)+"},{"className":"number","begin":"\\b\\d+(\\.\\d+)?","relevance":0},{"className":"function","beginKeywords":"function constructor destructor procedure method","end":"[:;]","keywords":"function constructor|10 destructor|10 procedure|10 method|10","contains":[{"className":"title","begin":"[a-zA-Z]\\w*","relevance":0},{"className":"params","begin":"\\(","end":"\\)","keywords":"abstract add and array as asc aspect assembly async begin break block by case class concat const copy constructor continue create default delegate desc distinct div do downto dynamic each else empty end ensure enum equals event except exit extension external false final finalize finalizer finally flags for forward from function future global group has if implementation implements implies in index inherited inline interface into invariants is iterator join locked locking loop matching method mod module namespace nested new nil not notify nullable of old on operator or order out override parallel params partial pinned private procedure property protected public queryable raise read readonly record reintroduce remove repeat require result reverse sealed select self sequence set shl shr skip static step soft take then to true try tuple type union unit unsafe until uses using var virtual raises volatile where while with write xor yield await mapped deprecated stdcall cdecl pascal register safecall overload library platform reference packed strict published autoreleasepool selector strong weak unretained","contains":[{"$ref":"#contains.3"},{"$ref":"#contains.4"}]},{"$ref":"#contains.0"},{"$ref":"#contains.1"}]},{"className":"class","begin":"=\\bclass\\b","end":"end;","keywords":"abstract add and array as asc aspect assembly async begin break block by case class concat const copy constructor continue create default delegate desc distinct div do downto dynamic each else empty end ensure enum equals event except exit extension external false final finalize finalizer finally flags for forward from function future global group has if implementation implements implies in index inherited inline interface into invariants is iterator join locked locking loop matching method mod module namespace nested new nil not notify nullable of old on operator or order out override parallel params partial pinned private procedure property protected public queryable raise read readonly record reintroduce remove repeat require result reverse sealed select self sequence set shl shr skip static step soft take then to true try tuple type union unit unsafe until uses using var virtual raises volatile where while with write xor yield await mapped deprecated stdcall cdecl pascal register safecall overload library platform reference packed strict published autoreleasepool selector strong weak unretained","contains":[{"$ref":"#contains.3"},{"$ref":"#contains.4"},{"$ref":"#contains.0"},{"$ref":"#contains.1"},{"$ref":"#contains.2"},{"$ref":"#contains.6"}]}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/parser3.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/parser3.json new file mode 100644 index 00000000..0b9c2217 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/parser3.json @@ -0,0 +1 @@ +{"subLanguage":"xml","relevance":0,"contains":[{"className":"comment","begin":"^#","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"\\^rem{","end":"}","contains":[{"className":"comment","begin":"{","end":"}","contains":["self",{"$ref":"#contains.0.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"$ref":"#contains.0.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}],"relevance":10},{"className":"meta","begin":"^@(?:BASE|USE|CLASS|OPTIONS)$","relevance":10},{"className":"title","begin":"@[\\w\\-]+\\[[\\w^;\\-]*\\](?:\\[[\\w^;\\-]*\\])?(?:.*)$"},{"className":"variable","begin":"\\$\\{?[\\w\\-\\.\\:]+\\}?"},{"className":"keyword","begin":"\\^[\\w\\-\\.\\:]+"},{"className":"number","begin":"\\^#[0-9a-fA-F]+"},{"className":"number","begin":"(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)","relevance":0}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/perl.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/perl.json new file mode 100644 index 00000000..ee6beaa8 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/perl.json @@ -0,0 +1 @@ +{"aliases":["pl","pm"],"lexemes":"[\\w\\.]+","keywords":"getpwent getservent quotemeta msgrcv scalar kill dbmclose undef lc ma syswrite tr send umask sysopen shmwrite vec qx utime local oct semctl localtime readpipe do return format read sprintf dbmopen pop getpgrp not getpwnam rewinddir qqfileno qw endprotoent wait sethostent bless s|0 opendir continue each sleep endgrent shutdown dump chomp connect getsockname die socketpair close flock exists index shmgetsub for endpwent redo lstat msgctl setpgrp abs exit select print ref gethostbyaddr unshift fcntl syscall goto getnetbyaddr join gmtime symlink semget splice x|0 getpeername recv log setsockopt cos last reverse gethostbyname getgrnam study formline endhostent times chop length gethostent getnetent pack getprotoent getservbyname rand mkdir pos chmod y|0 substr endnetent printf next open msgsnd readdir use unlink getsockopt getpriority rindex wantarray hex system getservbyport endservent int chr untie rmdir prototype tell listen fork shmread ucfirst setprotoent else sysseek link getgrgid shmctl waitpid unpack getnetbyname reset chdir grep split require caller lcfirst until warn while values shift telldir getpwuid my getprotobynumber delete and sort uc defined srand accept package seekdir getprotobyname semop our rename seek if q|0 chroot sysread setpwent no crypt getc chown sqrt write setnetent setpriority foreach tie sin msgget map stat getlogin unless elsif truncate exec keys glob tied closedirioctl socket readlink eval xor readline binmode setservent eof ord bind alarm pipe atan2 getgrent exp time push setgrent gt lt or ne m|0 break given say state when","contains":[{"variants":[{"begin":"\\$\\d"},{"begin":"[\\$%@](\\^\\w\\b|#\\w+(::\\w+)*|{\\w+}|\\w+(::\\w*)*)"},{"begin":"[\\$%@][^\\s\\w{]","relevance":0}]},{"className":"comment","begin":"#","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"^\\=\\w","end":"\\=cut","contains":[{"$ref":"#contains.1.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}],"endsWithParent":true},{"begin":"->{","end":"}","contains":{"$ref":"#contains"}},{"className":"string","contains":[{"begin":"\\\\[\\s\\S]","relevance":0},{"className":"subst","begin":"[$@]\\{","end":"\\}","keywords":"getpwent getservent quotemeta msgrcv scalar kill dbmclose undef lc ma syswrite tr send umask sysopen shmwrite vec qx utime local oct semctl localtime readpipe do return format read sprintf dbmopen pop getpgrp not getpwnam rewinddir qqfileno qw endprotoent wait sethostent bless s|0 opendir continue each sleep endgrent shutdown dump chomp connect getsockname die socketpair close flock exists index shmgetsub for endpwent redo lstat msgctl setpgrp abs exit select print ref gethostbyaddr unshift fcntl syscall goto getnetbyaddr join gmtime symlink semget splice x|0 getpeername recv log setsockopt cos last reverse gethostbyname getgrnam study formline endhostent times chop length gethostent getnetent pack getprotoent getservbyname rand mkdir pos chmod y|0 substr endnetent printf next open msgsnd readdir use unlink getsockopt getpriority rindex wantarray hex system getservbyport endservent int chr untie rmdir prototype tell listen fork shmread ucfirst setprotoent else sysseek link getgrgid shmctl waitpid unpack getnetbyname reset chdir grep split require caller lcfirst until warn while values shift telldir getpwuid my getprotobynumber delete and sort uc defined srand accept package seekdir getprotobyname semop our rename seek if q|0 chroot sysread setpwent no crypt getc chown sqrt write setnetent setpriority foreach tie sin msgget map stat getlogin unless elsif truncate exec keys glob tied closedirioctl socket readlink eval xor readline binmode setservent eof ord bind alarm pipe atan2 getgrent exp time push setgrent gt lt or ne m|0 break given say state when","contains":{"$ref":"#contains"}},{"$ref":"#contains.0"}],"variants":[{"begin":"q[qwxr]?\\s*\\(","end":"\\)","relevance":5},{"begin":"q[qwxr]?\\s*\\[","end":"\\]","relevance":5},{"begin":"q[qwxr]?\\s*\\{","end":"\\}","relevance":5},{"begin":"q[qwxr]?\\s*\\|","end":"\\|","relevance":5},{"begin":"q[qwxr]?\\s*\\<","end":"\\>","relevance":5},{"begin":"qw\\s+q","end":"q","relevance":5},{"begin":"'","end":"'","contains":[{"$ref":"#contains.4.contains.0"}]},{"begin":"\"","end":"\""},{"begin":"`","end":"`","contains":[{"$ref":"#contains.4.contains.0"}]},{"begin":"{\\w+}","contains":[],"relevance":0},{"begin":"-?\\w+\\s*\\=\\>","contains":[],"relevance":0}]},{"className":"number","begin":"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b","relevance":0},{"begin":"(\\/\\/|!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~|\\b(split|return|print|reverse|grep)\\b)\\s*","keywords":"split return print reverse grep","relevance":0,"contains":[{"$ref":"#contains.1"},{"className":"regexp","begin":"(s|tr|y)/(\\\\.|[^/])*/(\\\\.|[^/])*/[a-z]*","relevance":10},{"className":"regexp","begin":"(m|qr)?/","end":"/[a-z]*","contains":[{"$ref":"#contains.4.contains.0"}],"relevance":0}]},{"className":"function","beginKeywords":"sub","end":"(\\s*\\(.*?\\))?[;{]","excludeEnd":true,"relevance":5,"contains":[{"className":"title","begin":"[a-zA-Z]\\w*","relevance":0}]},{"begin":"-\\w\\b","relevance":0},{"begin":"^__DATA__$","end":"^__END__$","subLanguage":"mojolicious","contains":[{"begin":"^@@.*","end":"$","className":"comment"}]}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/pf.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/pf.json new file mode 100644 index 00000000..476adfe6 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/pf.json @@ -0,0 +1 @@ +{"aliases":["pf.conf"],"lexemes":"[a-z0-9_<>-]+","keywords":{"built_in":"block match pass load anchor|5 antispoof|10 set table","keyword":"in out log quick on rdomain inet inet6 proto from port os to routeallow-opts divert-packet divert-reply divert-to flags group icmp-typeicmp6-type label once probability recieved-on rtable prio queuetos tag tagged user keep fragment for os dropaf-to|10 binat-to|10 nat-to|10 rdr-to|10 bitmask least-stats random round-robinsource-hash static-portdup-to reply-to route-toparent bandwidth default min max qlimitblock-policy debug fingerprints hostid limit loginterface optimizationreassemble ruleset-optimization basic none profile skip state-defaultsstate-policy timeoutconst counters persistno modulate synproxy state|5 floating if-bound no-sync pflow|10 sloppysource-track global rule max-src-nodes max-src-states max-src-connmax-src-conn-rate overload flushscrub|5 max-mss min-ttl no-df|10 random-id","literal":"all any no-route self urpf-failed egress|5 unknown"},"contains":[{"className":"comment","begin":"#","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"number","begin":"\\b\\d+(\\.\\d+)?","relevance":0},{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0},{"className":"subst","begin":"\\\\[abfnrtv]\\|\\\\x[0-9a-fA-F]*\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]","relevance":0},{"className":"subst","begin":"\\\\[abfnrtv]\\|\\\\x[0-9a-fA-F]*\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]","relevance":0}]},{"className":"variable","begin":"\\$[\\w\\d#@][\\w\\d_]*"},{"className":"variable","begin":"<(?!\\/)","end":">"}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/pgsql.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/pgsql.json new file mode 100644 index 00000000..d8c946c6 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/pgsql.json @@ -0,0 +1 @@ +{"aliases":["postgres","postgresql"],"case_insensitive":true,"keywords":{"keyword":"ABORT ALTER ANALYZE BEGIN CALL CHECKPOINT|10 CLOSE CLUSTER COMMENT COMMIT COPY CREATE DEALLOCATE DECLARE DELETE DISCARD DO DROP END EXECUTE EXPLAIN FETCH GRANT IMPORT INSERT LISTEN LOAD LOCK MOVE NOTIFY PREPARE REASSIGN|10 REFRESH REINDEX RELEASE RESET REVOKE ROLLBACK SAVEPOINT SECURITY SELECT SET SHOW START TRUNCATE UNLISTEN|10 UPDATE VACUUM|10 VALUES AGGREGATE COLLATION CONVERSION|10 DATABASE DEFAULT PRIVILEGES DOMAIN TRIGGER EXTENSION FOREIGN WRAPPER|10 TABLE FUNCTION GROUP LANGUAGE LARGE OBJECT MATERIALIZED VIEW OPERATOR CLASS FAMILY POLICY PUBLICATION|10 ROLE RULE SCHEMA SEQUENCE SERVER STATISTICS SUBSCRIPTION SYSTEM TABLESPACE CONFIGURATION DICTIONARY PARSER TEMPLATE TYPE USER MAPPING PREPARED ACCESS METHOD CAST AS TRANSFORM TRANSACTION OWNED TO INTO SESSION AUTHORIZATION INDEX PROCEDURE ASSERTION ALL ANALYSE AND ANY ARRAY ASC ASYMMETRIC|10 BOTH CASE CHECK COLLATE COLUMN CONCURRENTLY|10 CONSTRAINT CROSS DEFERRABLE RANGE DESC DISTINCT ELSE EXCEPT FOR FREEZE|10 FROM FULL HAVING ILIKE IN INITIALLY INNER INTERSECT IS ISNULL JOIN LATERAL LEADING LIKE LIMIT NATURAL NOT NOTNULL NULL OFFSET ON ONLY OR ORDER OUTER OVERLAPS PLACING PRIMARY REFERENCES RETURNING SIMILAR SOME SYMMETRIC TABLESAMPLE THEN TRAILING UNION UNIQUE USING VARIADIC|10 VERBOSE WHEN WHERE WINDOW WITH BY RETURNS INOUT OUT SETOF|10 IF STRICT CURRENT CONTINUE OWNER LOCATION OVER PARTITION WITHIN BETWEEN ESCAPE EXTERNAL INVOKER DEFINER WORK RENAME VERSION CONNECTION CONNECT TABLES TEMP TEMPORARY FUNCTIONS SEQUENCES TYPES SCHEMAS OPTION CASCADE RESTRICT ADD ADMIN EXISTS VALID VALIDATE ENABLE DISABLE REPLICA|10 ALWAYS PASSING COLUMNS PATH REF VALUE OVERRIDING IMMUTABLE STABLE VOLATILE BEFORE AFTER EACH ROW PROCEDURAL ROUTINE NO HANDLER VALIDATOR OPTIONS STORAGE OIDS|10 WITHOUT INHERIT DEPENDS CALLED INPUT LEAKPROOF|10 COST ROWS NOWAIT SEARCH UNTIL ENCRYPTED|10 PASSWORD CONFLICT|10 INSTEAD INHERITS CHARACTERISTICS WRITE CURSOR ALSO STATEMENT SHARE EXCLUSIVE INLINE ISOLATION REPEATABLE READ COMMITTED SERIALIZABLE UNCOMMITTED LOCAL GLOBAL SQL PROCEDURES RECURSIVE SNAPSHOT ROLLUP CUBE TRUSTED|10 INCLUDE FOLLOWING PRECEDING UNBOUNDED RANGE GROUPS UNENCRYPTED|10 SYSID FORMAT DELIMITER HEADER QUOTE ENCODING FILTER OFF FORCE_QUOTE FORCE_NOT_NULL FORCE_NULL COSTS BUFFERS TIMING SUMMARY DISABLE_PAGE_SKIPPING RESTART CYCLE GENERATED IDENTITY DEFERRED IMMEDIATE LEVEL LOGGED UNLOGGED OF NOTHING NONE EXCLUDE ATTRIBUTE USAGE ROUTINES TRUE FALSE NAN INFINITY ALIAS BEGIN CONSTANT DECLARE END EXCEPTION RETURN PERFORM|10 RAISE GET DIAGNOSTICS STACKED|10 FOREACH LOOP ELSIF EXIT WHILE REVERSE SLICE DEBUG LOG INFO NOTICE WARNING ASSERT OPEN SUPERUSER NOSUPERUSER CREATEDB NOCREATEDB CREATEROLE NOCREATEROLE INHERIT NOINHERIT LOGIN NOLOGIN REPLICATION NOREPLICATION BYPASSRLS NOBYPASSRLS ","built_in":"CURRENT_TIME CURRENT_TIMESTAMP CURRENT_USER CURRENT_CATALOG|10 CURRENT_DATE LOCALTIME LOCALTIMESTAMP CURRENT_ROLE|10 CURRENT_SCHEMA|10 SESSION_USER PUBLIC FOUND NEW OLD TG_NAME|10 TG_WHEN|10 TG_LEVEL|10 TG_OP|10 TG_RELID|10 TG_RELNAME|10 TG_TABLE_NAME|10 TG_TABLE_SCHEMA|10 TG_NARGS|10 TG_ARGV|10 TG_EVENT|10 TG_TAG|10 ROW_COUNT RESULT_OID|10 PG_CONTEXT|10 RETURNED_SQLSTATE COLUMN_NAME CONSTRAINT_NAME PG_DATATYPE_NAME|10 MESSAGE_TEXT TABLE_NAME SCHEMA_NAME PG_EXCEPTION_DETAIL|10 PG_EXCEPTION_HINT|10 PG_EXCEPTION_CONTEXT|10 SQLSTATE SQLERRM|10 SUCCESSFUL_COMPLETION WARNING DYNAMIC_RESULT_SETS_RETURNED IMPLICIT_ZERO_BIT_PADDING NULL_VALUE_ELIMINATED_IN_SET_FUNCTION PRIVILEGE_NOT_GRANTED PRIVILEGE_NOT_REVOKED STRING_DATA_RIGHT_TRUNCATION DEPRECATED_FEATURE NO_DATA NO_ADDITIONAL_DYNAMIC_RESULT_SETS_RETURNED SQL_STATEMENT_NOT_YET_COMPLETE CONNECTION_EXCEPTION CONNECTION_DOES_NOT_EXIST CONNECTION_FAILURE SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION SQLSERVER_REJECTED_ESTABLISHMENT_OF_SQLCONNECTION TRANSACTION_RESOLUTION_UNKNOWN PROTOCOL_VIOLATION TRIGGERED_ACTION_EXCEPTION FEATURE_NOT_SUPPORTED INVALID_TRANSACTION_INITIATION LOCATOR_EXCEPTION INVALID_LOCATOR_SPECIFICATION INVALID_GRANTOR INVALID_GRANT_OPERATION INVALID_ROLE_SPECIFICATION DIAGNOSTICS_EXCEPTION STACKED_DIAGNOSTICS_ACCESSED_WITHOUT_ACTIVE_HANDLER CASE_NOT_FOUND CARDINALITY_VIOLATION DATA_EXCEPTION ARRAY_SUBSCRIPT_ERROR CHARACTER_NOT_IN_REPERTOIRE DATETIME_FIELD_OVERFLOW DIVISION_BY_ZERO ERROR_IN_ASSIGNMENT ESCAPE_CHARACTER_CONFLICT INDICATOR_OVERFLOW INTERVAL_FIELD_OVERFLOW INVALID_ARGUMENT_FOR_LOGARITHM INVALID_ARGUMENT_FOR_NTILE_FUNCTION INVALID_ARGUMENT_FOR_NTH_VALUE_FUNCTION INVALID_ARGUMENT_FOR_POWER_FUNCTION INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION INVALID_CHARACTER_VALUE_FOR_CAST INVALID_DATETIME_FORMAT INVALID_ESCAPE_CHARACTER INVALID_ESCAPE_OCTET INVALID_ESCAPE_SEQUENCE NONSTANDARD_USE_OF_ESCAPE_CHARACTER INVALID_INDICATOR_PARAMETER_VALUE INVALID_PARAMETER_VALUE INVALID_REGULAR_EXPRESSION INVALID_ROW_COUNT_IN_LIMIT_CLAUSE INVALID_ROW_COUNT_IN_RESULT_OFFSET_CLAUSE INVALID_TABLESAMPLE_ARGUMENT INVALID_TABLESAMPLE_REPEAT INVALID_TIME_ZONE_DISPLACEMENT_VALUE INVALID_USE_OF_ESCAPE_CHARACTER MOST_SPECIFIC_TYPE_MISMATCH NULL_VALUE_NOT_ALLOWED NULL_VALUE_NO_INDICATOR_PARAMETER NUMERIC_VALUE_OUT_OF_RANGE SEQUENCE_GENERATOR_LIMIT_EXCEEDED STRING_DATA_LENGTH_MISMATCH STRING_DATA_RIGHT_TRUNCATION SUBSTRING_ERROR TRIM_ERROR UNTERMINATED_C_STRING ZERO_LENGTH_CHARACTER_STRING FLOATING_POINT_EXCEPTION INVALID_TEXT_REPRESENTATION INVALID_BINARY_REPRESENTATION BAD_COPY_FILE_FORMAT UNTRANSLATABLE_CHARACTER NOT_AN_XML_DOCUMENT INVALID_XML_DOCUMENT INVALID_XML_CONTENT INVALID_XML_COMMENT INVALID_XML_PROCESSING_INSTRUCTION INTEGRITY_CONSTRAINT_VIOLATION RESTRICT_VIOLATION NOT_NULL_VIOLATION FOREIGN_KEY_VIOLATION UNIQUE_VIOLATION CHECK_VIOLATION EXCLUSION_VIOLATION INVALID_CURSOR_STATE INVALID_TRANSACTION_STATE ACTIVE_SQL_TRANSACTION BRANCH_TRANSACTION_ALREADY_ACTIVE HELD_CURSOR_REQUIRES_SAME_ISOLATION_LEVEL INAPPROPRIATE_ACCESS_MODE_FOR_BRANCH_TRANSACTION INAPPROPRIATE_ISOLATION_LEVEL_FOR_BRANCH_TRANSACTION NO_ACTIVE_SQL_TRANSACTION_FOR_BRANCH_TRANSACTION READ_ONLY_SQL_TRANSACTION SCHEMA_AND_DATA_STATEMENT_MIXING_NOT_SUPPORTED NO_ACTIVE_SQL_TRANSACTION IN_FAILED_SQL_TRANSACTION IDLE_IN_TRANSACTION_SESSION_TIMEOUT INVALID_SQL_STATEMENT_NAME TRIGGERED_DATA_CHANGE_VIOLATION INVALID_AUTHORIZATION_SPECIFICATION INVALID_PASSWORD DEPENDENT_PRIVILEGE_DESCRIPTORS_STILL_EXIST DEPENDENT_OBJECTS_STILL_EXIST INVALID_TRANSACTION_TERMINATION SQL_ROUTINE_EXCEPTION FUNCTION_EXECUTED_NO_RETURN_STATEMENT MODIFYING_SQL_DATA_NOT_PERMITTED PROHIBITED_SQL_STATEMENT_ATTEMPTED READING_SQL_DATA_NOT_PERMITTED INVALID_CURSOR_NAME EXTERNAL_ROUTINE_EXCEPTION CONTAINING_SQL_NOT_PERMITTED MODIFYING_SQL_DATA_NOT_PERMITTED PROHIBITED_SQL_STATEMENT_ATTEMPTED READING_SQL_DATA_NOT_PERMITTED EXTERNAL_ROUTINE_INVOCATION_EXCEPTION INVALID_SQLSTATE_RETURNED NULL_VALUE_NOT_ALLOWED TRIGGER_PROTOCOL_VIOLATED SRF_PROTOCOL_VIOLATED EVENT_TRIGGER_PROTOCOL_VIOLATED SAVEPOINT_EXCEPTION INVALID_SAVEPOINT_SPECIFICATION INVALID_CATALOG_NAME INVALID_SCHEMA_NAME TRANSACTION_ROLLBACK TRANSACTION_INTEGRITY_CONSTRAINT_VIOLATION SERIALIZATION_FAILURE STATEMENT_COMPLETION_UNKNOWN DEADLOCK_DETECTED SYNTAX_ERROR_OR_ACCESS_RULE_VIOLATION SYNTAX_ERROR INSUFFICIENT_PRIVILEGE CANNOT_COERCE GROUPING_ERROR WINDOWING_ERROR INVALID_RECURSION INVALID_FOREIGN_KEY INVALID_NAME NAME_TOO_LONG RESERVED_NAME DATATYPE_MISMATCH INDETERMINATE_DATATYPE COLLATION_MISMATCH INDETERMINATE_COLLATION WRONG_OBJECT_TYPE GENERATED_ALWAYS UNDEFINED_COLUMN UNDEFINED_FUNCTION UNDEFINED_TABLE UNDEFINED_PARAMETER UNDEFINED_OBJECT DUPLICATE_COLUMN DUPLICATE_CURSOR DUPLICATE_DATABASE DUPLICATE_FUNCTION DUPLICATE_PREPARED_STATEMENT DUPLICATE_SCHEMA DUPLICATE_TABLE DUPLICATE_ALIAS DUPLICATE_OBJECT AMBIGUOUS_COLUMN AMBIGUOUS_FUNCTION AMBIGUOUS_PARAMETER AMBIGUOUS_ALIAS INVALID_COLUMN_REFERENCE INVALID_COLUMN_DEFINITION INVALID_CURSOR_DEFINITION INVALID_DATABASE_DEFINITION INVALID_FUNCTION_DEFINITION INVALID_PREPARED_STATEMENT_DEFINITION INVALID_SCHEMA_DEFINITION INVALID_TABLE_DEFINITION INVALID_OBJECT_DEFINITION WITH_CHECK_OPTION_VIOLATION INSUFFICIENT_RESOURCES DISK_FULL OUT_OF_MEMORY TOO_MANY_CONNECTIONS CONFIGURATION_LIMIT_EXCEEDED PROGRAM_LIMIT_EXCEEDED STATEMENT_TOO_COMPLEX TOO_MANY_COLUMNS TOO_MANY_ARGUMENTS OBJECT_NOT_IN_PREREQUISITE_STATE OBJECT_IN_USE CANT_CHANGE_RUNTIME_PARAM LOCK_NOT_AVAILABLE OPERATOR_INTERVENTION QUERY_CANCELED ADMIN_SHUTDOWN CRASH_SHUTDOWN CANNOT_CONNECT_NOW DATABASE_DROPPED SYSTEM_ERROR IO_ERROR UNDEFINED_FILE DUPLICATE_FILE SNAPSHOT_TOO_OLD CONFIG_FILE_ERROR LOCK_FILE_EXISTS FDW_ERROR FDW_COLUMN_NAME_NOT_FOUND FDW_DYNAMIC_PARAMETER_VALUE_NEEDED FDW_FUNCTION_SEQUENCE_ERROR FDW_INCONSISTENT_DESCRIPTOR_INFORMATION FDW_INVALID_ATTRIBUTE_VALUE FDW_INVALID_COLUMN_NAME FDW_INVALID_COLUMN_NUMBER FDW_INVALID_DATA_TYPE FDW_INVALID_DATA_TYPE_DESCRIPTORS FDW_INVALID_DESCRIPTOR_FIELD_IDENTIFIER FDW_INVALID_HANDLE FDW_INVALID_OPTION_INDEX FDW_INVALID_OPTION_NAME FDW_INVALID_STRING_LENGTH_OR_BUFFER_LENGTH FDW_INVALID_STRING_FORMAT FDW_INVALID_USE_OF_NULL_POINTER FDW_TOO_MANY_HANDLES FDW_OUT_OF_MEMORY FDW_NO_SCHEMAS FDW_OPTION_NAME_NOT_FOUND FDW_REPLY_HANDLE FDW_SCHEMA_NOT_FOUND FDW_TABLE_NOT_FOUND FDW_UNABLE_TO_CREATE_EXECUTION FDW_UNABLE_TO_CREATE_REPLY FDW_UNABLE_TO_ESTABLISH_CONNECTION PLPGSQL_ERROR RAISE_EXCEPTION NO_DATA_FOUND TOO_MANY_ROWS ASSERT_FAILURE INTERNAL_ERROR DATA_CORRUPTED INDEX_CORRUPTED "},"illegal":":==|\\W\\s*\\(\\*|(^|\\s)\\$[a-z]|{{|[a-z]:\\s*$|\\.\\.\\.|TO:|DO:","contains":[{"className":"keyword","variants":[{"begin":"\\bTEXT\\s*SEARCH\\b"},{"begin":"\\b(PRIMARY|FOREIGN|FOR(\\s+NO)?)\\s+KEY\\b"},{"begin":"\\bPARALLEL\\s+(UNSAFE|RESTRICTED|SAFE)\\b"},{"begin":"\\bSTORAGE\\s+(PLAIN|EXTERNAL|EXTENDED|MAIN)\\b"},{"begin":"\\bMATCH\\s+(FULL|PARTIAL|SIMPLE)\\b"},{"begin":"\\bNULLS\\s+(FIRST|LAST)\\b"},{"begin":"\\bEVENT\\s+TRIGGER\\b"},{"begin":"\\b(MAPPING|OR)\\s+REPLACE\\b"},{"begin":"\\b(FROM|TO)\\s+(PROGRAM|STDIN|STDOUT)\\b"},{"begin":"\\b(SHARE|EXCLUSIVE)\\s+MODE\\b"},{"begin":"\\b(LEFT|RIGHT)\\s+(OUTER\\s+)?JOIN\\b"},{"begin":"\\b(FETCH|MOVE)\\s+(NEXT|PRIOR|FIRST|LAST|ABSOLUTE|RELATIVE|FORWARD|BACKWARD)\\b"},{"begin":"\\bPRESERVE\\s+ROWS\\b"},{"begin":"\\bDISCARD\\s+PLANS\\b"},{"begin":"\\bREFERENCING\\s+(OLD|NEW)\\b"},{"begin":"\\bSKIP\\s+LOCKED\\b"},{"begin":"\\bGROUPING\\s+SETS\\b"},{"begin":"\\b(BINARY|INSENSITIVE|SCROLL|NO\\s+SCROLL)\\s+(CURSOR|FOR)\\b"},{"begin":"\\b(WITH|WITHOUT)\\s+HOLD\\b"},{"begin":"\\bWITH\\s+(CASCADED|LOCAL)\\s+CHECK\\s+OPTION\\b"},{"begin":"\\bEXCLUDE\\s+(TIES|NO\\s+OTHERS)\\b"},{"begin":"\\bFORMAT\\s+(TEXT|XML|JSON|YAML)\\b"},{"begin":"\\bSET\\s+((SESSION|LOCAL)\\s+)?NAMES\\b"},{"begin":"\\bIS\\s+(NOT\\s+)?UNKNOWN\\b"},{"begin":"\\bSECURITY\\s+LABEL\\b"},{"begin":"\\bSTANDALONE\\s+(YES|NO|NO\\s+VALUE)\\b"},{"begin":"\\bWITH\\s+(NO\\s+)?DATA\\b"},{"begin":"\\b(FOREIGN|SET)\\s+DATA\\b"},{"begin":"\\bSET\\s+(CATALOG|CONSTRAINTS)\\b"},{"begin":"\\b(WITH|FOR)\\s+ORDINALITY\\b"},{"begin":"\\bIS\\s+(NOT\\s+)?DOCUMENT\\b"},{"begin":"\\bXML\\s+OPTION\\s+(DOCUMENT|CONTENT)\\b"},{"begin":"\\b(STRIP|PRESERVE)\\s+WHITESPACE\\b"},{"begin":"\\bNO\\s+(ACTION|MAXVALUE|MINVALUE)\\b"},{"begin":"\\bPARTITION\\s+BY\\s+(RANGE|LIST|HASH)\\b"},{"begin":"\\bAT\\s+TIME\\s+ZONE\\b"},{"begin":"\\bGRANTED\\s+BY\\b"},{"begin":"\\bRETURN\\s+(QUERY|NEXT)\\b"},{"begin":"\\b(ATTACH|DETACH)\\s+PARTITION\\b"},{"begin":"\\bFORCE\\s+ROW\\s+LEVEL\\s+SECURITY\\b"},{"begin":"\\b(INCLUDING|EXCLUDING)\\s+(COMMENTS|CONSTRAINTS|DEFAULTS|IDENTITY|INDEXES|STATISTICS|STORAGE|ALL)\\b"},{"begin":"\\bAS\\s+(ASSIGNMENT|IMPLICIT|PERMISSIVE|RESTRICTIVE|ENUM|RANGE)\\b"}]},{"begin":"\\b(FORMAT|FAMILY|VERSION)\\s*\\("},{"begin":"\\bINCLUDE\\s*\\(","keywords":"INCLUDE"},{"begin":"\\bRANGE(?!\\s*(BETWEEN|UNBOUNDED|CURRENT|[-0-9]+))"},{"begin":"\\b(VERSION|OWNER|TEMPLATE|TABLESPACE|CONNECTION\\s+LIMIT|PROCEDURE|RESTRICT|JOIN|PARSER|COPY|START|END|COLLATION|INPUT|ANALYZE|STORAGE|LIKE|DEFAULT|DELIMITER|ENCODING|COLUMN|CONSTRAINT|TABLE|SCHEMA)\\s*="},{"begin":"\\b(PG_\\w+?|HAS_[A-Z_]+_PRIVILEGE)\\b","relevance":10},{"begin":"\\bEXTRACT\\s*\\(","end":"\\bFROM\\b","returnEnd":true,"keywords":{"type":"CENTURY DAY DECADE DOW DOY EPOCH HOUR ISODOW ISOYEAR MICROSECONDS MILLENNIUM MILLISECONDS MINUTE MONTH QUARTER SECOND TIMEZONE TIMEZONE_HOUR TIMEZONE_MINUTE WEEK YEAR"}},{"begin":"\\b(XMLELEMENT|XMLPI)\\s*\\(\\s*NAME","keywords":{"keyword":"NAME"}},{"begin":"\\b(XMLPARSE|XMLSERIALIZE)\\s*\\(\\s*(DOCUMENT|CONTENT)","keywords":{"keyword":"DOCUMENT CONTENT"}},{"beginKeywords":"CACHE INCREMENT MAXVALUE MINVALUE","end":"(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)","returnEnd":true,"keywords":"BY CACHE INCREMENT MAXVALUE MINVALUE"},{"className":"type","begin":"\\b(WITH|WITHOUT)\\s+TIME\\s+ZONE\\b"},{"className":"type","begin":"\\bINTERVAL\\s+(YEAR|MONTH|DAY|HOUR|MINUTE|SECOND)(\\s+TO\\s+(MONTH|HOUR|MINUTE|SECOND))?\\b"},{"begin":"\\bRETURNS\\s+(LANGUAGE_HANDLER|TRIGGER|EVENT_TRIGGER|FDW_HANDLER|INDEX_AM_HANDLER|TSM_HANDLER)\\b","keywords":{"keyword":"RETURNS","type":"LANGUAGE_HANDLER TRIGGER EVENT_TRIGGER FDW_HANDLER INDEX_AM_HANDLER TSM_HANDLER"}},{"begin":"\\b(ARRAY_AGG|AVG|BIT_AND|BIT_OR|BOOL_AND|BOOL_OR|COUNT|EVERY|JSON_AGG|JSONB_AGG|JSON_OBJECT_AGG|JSONB_OBJECT_AGG|MAX|MIN|MODE|STRING_AGG|SUM|XMLAGG|CORR|COVAR_POP|COVAR_SAMP|REGR_AVGX|REGR_AVGY|REGR_COUNT|REGR_INTERCEPT|REGR_R2|REGR_SLOPE|REGR_SXX|REGR_SXY|REGR_SYY|STDDEV|STDDEV_POP|STDDEV_SAMP|VARIANCE|VAR_POP|VAR_SAMP|PERCENTILE_CONT|PERCENTILE_DISC|ROW_NUMBER|RANK|DENSE_RANK|PERCENT_RANK|CUME_DIST|NTILE|LAG|LEAD|FIRST_VALUE|LAST_VALUE|NTH_VALUE|NUM_NONNULLS|NUM_NULLS|ABS|CBRT|CEIL|CEILING|DEGREES|DIV|EXP|FLOOR|LN|LOG|MOD|PI|POWER|RADIANS|ROUND|SCALE|SIGN|SQRT|TRUNC|WIDTH_BUCKET|RANDOM|SETSEED|ACOS|ACOSD|ASIN|ASIND|ATAN|ATAND|ATAN2|ATAN2D|COS|COSD|COT|COTD|SIN|SIND|TAN|TAND|BIT_LENGTH|CHAR_LENGTH|CHARACTER_LENGTH|LOWER|OCTET_LENGTH|OVERLAY|POSITION|SUBSTRING|TREAT|TRIM|UPPER|ASCII|BTRIM|CHR|CONCAT|CONCAT_WS|CONVERT|CONVERT_FROM|CONVERT_TO|DECODE|ENCODE|INITCAPLEFT|LENGTH|LPAD|LTRIM|MD5|PARSE_IDENT|PG_CLIENT_ENCODING|QUOTE_IDENT|QUOTE_LITERAL|QUOTE_NULLABLE|REGEXP_MATCH|REGEXP_MATCHES|REGEXP_REPLACE|REGEXP_SPLIT_TO_ARRAY|REGEXP_SPLIT_TO_TABLE|REPEAT|REPLACE|REVERSE|RIGHT|RPAD|RTRIM|SPLIT_PART|STRPOS|SUBSTR|TO_ASCII|TO_HEX|TRANSLATE|OCTET_LENGTH|GET_BIT|GET_BYTE|SET_BIT|SET_BYTE|TO_CHAR|TO_DATE|TO_NUMBER|TO_TIMESTAMP|AGE|CLOCK_TIMESTAMP|DATE_PART|DATE_TRUNC|ISFINITE|JUSTIFY_DAYS|JUSTIFY_HOURS|JUSTIFY_INTERVAL|MAKE_DATE|MAKE_INTERVAL|MAKE_TIME|MAKE_TIMESTAMP|MAKE_TIMESTAMPTZ|NOW|STATEMENT_TIMESTAMP|TIMEOFDAY|TRANSACTION_TIMESTAMP|ENUM_FIRST|ENUM_LAST|ENUM_RANGE|AREA|CENTER|DIAMETER|HEIGHT|ISCLOSED|ISOPEN|NPOINTS|PCLOSE|POPEN|RADIUS|WIDTH|BOX|BOUND_BOX|CIRCLE|LINE|LSEG|PATH|POLYGON|ABBREV|BROADCAST|HOST|HOSTMASK|MASKLEN|NETMASK|NETWORK|SET_MASKLEN|TEXT|INET_SAME_FAMILYINET_MERGE|MACADDR8_SET7BIT|ARRAY_TO_TSVECTOR|GET_CURRENT_TS_CONFIG|NUMNODE|PLAINTO_TSQUERY|PHRASETO_TSQUERY|WEBSEARCH_TO_TSQUERY|QUERYTREE|SETWEIGHT|STRIP|TO_TSQUERY|TO_TSVECTOR|JSON_TO_TSVECTOR|JSONB_TO_TSVECTOR|TS_DELETE|TS_FILTER|TS_HEADLINE|TS_RANK|TS_RANK_CD|TS_REWRITE|TSQUERY_PHRASE|TSVECTOR_TO_ARRAY|TSVECTOR_UPDATE_TRIGGER|TSVECTOR_UPDATE_TRIGGER_COLUMN|XMLCOMMENT|XMLCONCAT|XMLELEMENT|XMLFOREST|XMLPI|XMLROOT|XMLEXISTS|XML_IS_WELL_FORMED|XML_IS_WELL_FORMED_DOCUMENT|XML_IS_WELL_FORMED_CONTENT|XPATH|XPATH_EXISTS|XMLTABLE|XMLNAMESPACES|TABLE_TO_XML|TABLE_TO_XMLSCHEMA|TABLE_TO_XML_AND_XMLSCHEMA|QUERY_TO_XML|QUERY_TO_XMLSCHEMA|QUERY_TO_XML_AND_XMLSCHEMA|CURSOR_TO_XML|CURSOR_TO_XMLSCHEMA|SCHEMA_TO_XML|SCHEMA_TO_XMLSCHEMA|SCHEMA_TO_XML_AND_XMLSCHEMA|DATABASE_TO_XML|DATABASE_TO_XMLSCHEMA|DATABASE_TO_XML_AND_XMLSCHEMA|XMLATTRIBUTES|TO_JSON|TO_JSONB|ARRAY_TO_JSON|ROW_TO_JSON|JSON_BUILD_ARRAY|JSONB_BUILD_ARRAY|JSON_BUILD_OBJECT|JSONB_BUILD_OBJECT|JSON_OBJECT|JSONB_OBJECT|JSON_ARRAY_LENGTH|JSONB_ARRAY_LENGTH|JSON_EACH|JSONB_EACH|JSON_EACH_TEXT|JSONB_EACH_TEXT|JSON_EXTRACT_PATH|JSONB_EXTRACT_PATH|JSON_OBJECT_KEYS|JSONB_OBJECT_KEYS|JSON_POPULATE_RECORD|JSONB_POPULATE_RECORD|JSON_POPULATE_RECORDSET|JSONB_POPULATE_RECORDSET|JSON_ARRAY_ELEMENTS|JSONB_ARRAY_ELEMENTS|JSON_ARRAY_ELEMENTS_TEXT|JSONB_ARRAY_ELEMENTS_TEXT|JSON_TYPEOF|JSONB_TYPEOF|JSON_TO_RECORD|JSONB_TO_RECORD|JSON_TO_RECORDSET|JSONB_TO_RECORDSET|JSON_STRIP_NULLS|JSONB_STRIP_NULLS|JSONB_SET|JSONB_INSERT|JSONB_PRETTY|CURRVAL|LASTVAL|NEXTVAL|SETVAL|COALESCE|NULLIF|GREATEST|LEAST|ARRAY_APPEND|ARRAY_CAT|ARRAY_NDIMS|ARRAY_DIMS|ARRAY_FILL|ARRAY_LENGTH|ARRAY_LOWER|ARRAY_POSITION|ARRAY_POSITIONS|ARRAY_PREPEND|ARRAY_REMOVE|ARRAY_REPLACE|ARRAY_TO_STRING|ARRAY_UPPER|CARDINALITY|STRING_TO_ARRAY|UNNEST|ISEMPTY|LOWER_INC|UPPER_INC|LOWER_INF|UPPER_INF|RANGE_MERGE|GENERATE_SERIES|GENERATE_SUBSCRIPTS|CURRENT_DATABASE|CURRENT_QUERY|CURRENT_SCHEMA|CURRENT_SCHEMAS|INET_CLIENT_ADDR|INET_CLIENT_PORT|INET_SERVER_ADDR|INET_SERVER_PORT|ROW_SECURITY_ACTIVE|FORMAT_TYPE|TO_REGCLASS|TO_REGPROC|TO_REGPROCEDURE|TO_REGOPER|TO_REGOPERATOR|TO_REGTYPE|TO_REGNAMESPACE|TO_REGROLE|COL_DESCRIPTION|OBJ_DESCRIPTION|SHOBJ_DESCRIPTION|TXID_CURRENT|TXID_CURRENT_IF_ASSIGNED|TXID_CURRENT_SNAPSHOT|TXID_SNAPSHOT_XIP|TXID_SNAPSHOT_XMAX|TXID_SNAPSHOT_XMIN|TXID_VISIBLE_IN_SNAPSHOT|TXID_STATUS|CURRENT_SETTING|SET_CONFIG|BRIN_SUMMARIZE_NEW_VALUES|BRIN_SUMMARIZE_RANGE|BRIN_DESUMMARIZE_RANGE|GIN_CLEAN_PENDING_LIST|SUPPRESS_REDUNDANT_UPDATES_TRIGGER|LO_FROM_BYTEA|LO_PUT|LO_GET|LO_CREAT|LO_CREATE|LO_UNLINK|LO_IMPORT|LO_EXPORT|LOREAD|LOWRITE|GROUPING|CAST)\\s*\\("},{"begin":"\\.(BIGINT|INT8|BIGSERIAL|SERIAL8|BIT|VARYING|VARBIT|BOOLEAN|BOOL|BOX|BYTEA|CHARACTER|CHAR|VARCHAR|CIDR|CIRCLE|DATE|DOUBLE|PRECISION|FLOAT8|FLOAT|INET|INTEGER|INT|INT4|INTERVAL|JSON|JSONB|LINE|LSEG|MACADDR|MACADDR8|MONEY|NUMERIC|DEC|DECIMAL|PATH|POINT|POLYGON|REAL|FLOAT4|SMALLINT|INT2|SMALLSERIAL|SERIAL2|SERIAL|SERIAL4|TEXT|TIME|ZONE|TIMETZ|TIMESTAMP|TIMESTAMPTZ|TSQUERY|TSVECTOR|TXID_SNAPSHOT|UUID|XML|NATIONAL|NCHAR|INT4RANGE|INT8RANGE|NUMRANGE|TSRANGE|TSTZRANGE|DATERANGE|ANYELEMENT|ANYARRAY|ANYNONARRAY|ANYENUM|ANYRANGE|CSTRING|INTERNAL|RECORD|PG_DDL_COMMAND|VOID|UNKNOWN|OPAQUE|REFCURSOR|NAME|OID|REGPROC|REGPROCEDURE|REGOPER|REGOPERATOR|REGCLASS|REGTYPE|REGROLE|REGNAMESPACE|REGCONFIG|REGDICTIONARY)\\b"},{"begin":"\\b(BIGINT|INT8|BIGSERIAL|SERIAL8|BIT|VARYING|VARBIT|BOOLEAN|BOOL|BOX|BYTEA|CHARACTER|CHAR|VARCHAR|CIDR|CIRCLE|DATE|DOUBLE|PRECISION|FLOAT8|FLOAT|INET|INTEGER|INT|INT4|INTERVAL|JSON|JSONB|LINE|LSEG|MACADDR|MACADDR8|MONEY|NUMERIC|DEC|DECIMAL|PATH|POINT|POLYGON|REAL|FLOAT4|SMALLINT|INT2|SMALLSERIAL|SERIAL2|SERIAL|SERIAL4|TEXT|TIME|ZONE|TIMETZ|TIMESTAMP|TIMESTAMPTZ|TSQUERY|TSVECTOR|TXID_SNAPSHOT|UUID|XML|NATIONAL|NCHAR|INT4RANGE|INT8RANGE|NUMRANGE|TSRANGE|TSTZRANGE|DATERANGE|ANYELEMENT|ANYARRAY|ANYNONARRAY|ANYENUM|ANYRANGE|CSTRING|INTERNAL|RECORD|PG_DDL_COMMAND|VOID|UNKNOWN|OPAQUE|REFCURSOR|NAME|OID|REGPROC|REGPROCEDURE|REGOPER|REGOPERATOR|REGCLASS|REGTYPE|REGROLE|REGNAMESPACE|REGCONFIG|REGDICTIONARY)\\s+PATH\\b","keywords":{"keyword":"PATH","type":"BIGINT INT8 BIGSERIAL SERIAL8 BIT VARYING VARBIT BOOLEAN BOOL BOX BYTEA CHARACTER CHAR VARCHAR CIDR CIRCLE DATE DOUBLE PRECISION FLOAT8 FLOAT INET INTEGER INT INT4 INTERVAL JSON JSONB LINE LSEG|10 MACADDR MACADDR8 MONEY NUMERIC DEC DECIMAL POINT POLYGON REAL FLOAT4 SMALLINT INT2 SMALLSERIAL|10 SERIAL2|10 SERIAL|10 SERIAL4|10 TEXT TIME ZONE TIMETZ|10 TIMESTAMP TIMESTAMPTZ|10 TSQUERY|10 TSVECTOR|10 TXID_SNAPSHOT|10 UUID XML NATIONAL NCHAR INT4RANGE|10 INT8RANGE|10 NUMRANGE|10 TSRANGE|10 TSTZRANGE|10 DATERANGE|10 ANYELEMENT ANYARRAY ANYNONARRAY ANYENUM ANYRANGE CSTRING INTERNAL RECORD PG_DDL_COMMAND VOID UNKNOWN OPAQUE REFCURSOR NAME OID REGPROC|10 REGPROCEDURE|10 REGOPER|10 REGOPERATOR|10 REGCLASS|10 REGTYPE|10 REGROLE|10 REGNAMESPACE|10 REGCONFIG|10 REGDICTIONARY|10 "}},{"className":"type","begin":"\\b(BIGINT|INT8|BIGSERIAL|SERIAL8|BIT|VARYING|VARBIT|BOOLEAN|BOOL|BOX|BYTEA|CHARACTER|CHAR|VARCHAR|CIDR|CIRCLE|DATE|DOUBLE|PRECISION|FLOAT8|FLOAT|INET|INTEGER|INT|INT4|INTERVAL|JSON|JSONB|LINE|LSEG|MACADDR|MACADDR8|MONEY|NUMERIC|DEC|DECIMAL|PATH|POINT|POLYGON|REAL|FLOAT4|SMALLINT|INT2|SMALLSERIAL|SERIAL2|SERIAL|SERIAL4|TEXT|TIME|ZONE|TIMETZ|TIMESTAMP|TIMESTAMPTZ|TSQUERY|TSVECTOR|TXID_SNAPSHOT|UUID|XML|NATIONAL|NCHAR|INT4RANGE|INT8RANGE|NUMRANGE|TSRANGE|TSTZRANGE|DATERANGE|ANYELEMENT|ANYARRAY|ANYNONARRAY|ANYENUM|ANYRANGE|CSTRING|INTERNAL|RECORD|PG_DDL_COMMAND|VOID|UNKNOWN|OPAQUE|REFCURSOR|NAME|OID|REGPROC|REGPROCEDURE|REGOPER|REGOPERATOR|REGCLASS|REGTYPE|REGROLE|REGNAMESPACE|REGCONFIG|REGDICTIONARY)\\b"},{"className":"string","begin":"'","end":"'","contains":[{"begin":"''"}]},{"className":"string","begin":"(e|E|u&|U&)'","end":"'","contains":[{"begin":"\\\\."}],"relevance":10},{"begin":"\\$([a-zA-Z_]?|[a-zA-Z_][a-zA-Z_0-9]*)\\$","endSameAsBegin":true,"contains":[{"subLanguage":["pgsql","perl","python","tcl","r","lua","java","php","ruby","bash","scheme","xml","json"],"endsWithParent":true}]},{"begin":"\"","end":"\"","contains":[{"begin":"\"\""}]},{"className":"number","begin":"(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)","relevance":0},{"className":"comment","begin":"/\\*","end":"\\*/","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"--","end":"$","contains":[{"$ref":"#contains.22.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"meta","variants":[{"begin":"%(ROW)?TYPE","relevance":10},{"begin":"\\$\\d+"},{"begin":"^#\\w","end":"$"}]},{"className":"symbol","begin":"<<\\s*[a-zA-Z_][a-zA-Z_0-9$]*\\s*>>","relevance":10}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/php.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/php.json new file mode 100644 index 00000000..5ee0472b --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/php.json @@ -0,0 +1 @@ +{"aliases":["php","php3","php4","php5","php6","php7"],"case_insensitive":true,"keywords":"and include_once list abstract global private echo interface as static endswitch array null if endwhile or const for endforeach self var while isset public protected exit foreach throw elseif include __FILE__ empty require_once do xor return parent clone use __CLASS__ __LINE__ else break print eval new catch __METHOD__ case exception default die require __FUNCTION__ enddeclare final try switch continue endfor endif declare unset true false trait goto instanceof insteadof __DIR__ __NAMESPACE__ yield finally","contains":[{"className":"comment","begin":"#","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"//","end":"$","contains":[{"className":"meta","begin":"<\\?(php)?|\\?>"},{"$ref":"#contains.0.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"/\\*","end":"\\*/","contains":[{"className":"doctag","begin":"@[A-Za-z]+"},{"$ref":"#contains.0.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"__halt_compiler.+?;","end":false,"contains":[{"$ref":"#contains.0.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}],"endsWithParent":true,"keywords":"__halt_compiler","lexemes":"[a-zA-Z_]\\w*"},{"className":"string","begin":"<<<['\"]?\\w+['\"]?$","end":"^\\w+;?$","contains":[{"begin":"\\\\[\\s\\S]","relevance":0},{"className":"subst","variants":[{"begin":"\\$\\w+"},{"begin":"\\{\\$","end":"\\}"}]}]},{"$ref":"#contains.1.contains.0"},{"className":"keyword","begin":"\\$this\\b"},{"begin":"\\$+[a-zA-Z_-ÿ][a-zA-Z0-9_-ÿ]*"},{"begin":"(::|->)+[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*"},{"className":"function","beginKeywords":"function","end":"[;{]","excludeEnd":true,"illegal":"\\$|\\[|%","contains":[{"className":"title","begin":"[a-zA-Z_]\\w*","relevance":0},{"className":"params","begin":"\\(","end":"\\)","contains":["self",{"$ref":"#contains.7"},{"className":"comment","begin":"/\\*","end":"\\*/","contains":[{"$ref":"#contains.0.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"string","contains":[{"$ref":"#contains.4.contains.0"},{"$ref":"#contains.1.contains.0"}],"variants":[{"begin":"b\"","end":"\""},{"begin":"b'","end":"'"},{"className":"string","begin":"'","end":"'","illegal":null,"contains":[{"$ref":"#contains.4.contains.0"}]},{"className":"string","begin":"\"","end":"\"","illegal":null,"contains":[{"$ref":"#contains.4.contains.0"},{"className":"subst","begin":"\\\\[abfnrtv]\\|\\\\x[0-9a-fA-F]*\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]","relevance":0},{"className":"subst","begin":"\\\\[abfnrtv]\\|\\\\x[0-9a-fA-F]*\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]","relevance":0}]}]},{"variants":[{"className":"number","begin":"\\b(0b[01]+)","relevance":0},{"className":"number","begin":"(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)","relevance":0}]}]}]},{"className":"class","beginKeywords":"class interface","end":"{","excludeEnd":true,"illegal":"[:\\(\\$\"]","contains":[{"beginKeywords":"extends implements"},{"$ref":"#contains.9.contains.0"}]},{"beginKeywords":"namespace","end":";","illegal":"[\\.']","contains":[{"$ref":"#contains.9.contains.0"}]},{"beginKeywords":"use","end":";","contains":[{"$ref":"#contains.9.contains.0"}]},{"begin":"=>"},{"$ref":"#contains.9.contains.1.contains.3"},{"$ref":"#contains.9.contains.1.contains.4"}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/plaintext.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/plaintext.json new file mode 100644 index 00000000..9ef18a96 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/plaintext.json @@ -0,0 +1 @@ +{"disableAutodetect":true} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/pony.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/pony.json new file mode 100644 index 00000000..78fd222f --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/pony.json @@ -0,0 +1 @@ +{"keywords":{"keyword":"actor addressof and as be break class compile_error compile_intrinsic consume continue delegate digestof do else elseif embed end error for fun if ifdef in interface is isnt lambda let match new not object or primitive recover repeat return struct then trait try type until use var where while with xor","meta":"iso val tag trn box ref","literal":"this false true"},"contains":[{"className":"type","begin":"\\b_?[A-Z][\\w]*","relevance":0},{"className":"string","begin":"\"\"\"","end":"\"\"\"","relevance":10},{"className":"string","begin":"\"","end":"\"","contains":[{"begin":"\\\\[\\s\\S]","relevance":0}]},{"className":"string","begin":"'","end":"'","contains":[{"$ref":"#contains.2.contains.0"}],"relevance":0},{"begin":"[a-zA-Z]\\w*'","relevance":0},{"className":"number","begin":"(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)","relevance":0},{"className":"comment","begin":"//","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"/\\*","end":"\\*/","contains":[{"$ref":"#contains.6.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/powershell.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/powershell.json new file mode 100644 index 00000000..bb25ace4 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/powershell.json @@ -0,0 +1 @@ +{"aliases":["ps"],"lexemes":"-?[A-z\\.\\-]+","case_insensitive":true,"keywords":{"keyword":"if else foreach return function do while until elseif begin for trap data dynamicparam end break throw param continue finally in switch exit filter try process catchValidateNoCircleInNodeResources ValidateNodeExclusiveResources ValidateNodeManager ValidateNodeResources ValidateNodeResourceSource ValidateNoNameNodeResources ThrowError IsHiddenResourceIsPatternMatched ","built_in":"Add-Computer Add-Content Add-History Add-JobTrigger Add-Member Add-PSSnapin Add-Type Checkpoint-Computer Clear-Content Clear-EventLog Clear-History Clear-Host Clear-Item Clear-ItemProperty Clear-Variable Compare-Object Complete-Transaction Connect-PSSession Connect-WSMan Convert-Path ConvertFrom-Csv ConvertFrom-Json ConvertFrom-SecureString ConvertFrom-StringData ConvertTo-Csv ConvertTo-Html ConvertTo-Json ConvertTo-SecureString ConvertTo-Xml Copy-Item Copy-ItemProperty Debug-Process Disable-ComputerRestore Disable-JobTrigger Disable-PSBreakpoint Disable-PSRemoting Disable-PSSessionConfiguration Disable-WSManCredSSP Disconnect-PSSession Disconnect-WSMan Disable-ScheduledJob Enable-ComputerRestore Enable-JobTrigger Enable-PSBreakpoint Enable-PSRemoting Enable-PSSessionConfiguration Enable-ScheduledJob Enable-WSManCredSSP Enter-PSSession Exit-PSSession Export-Alias Export-Clixml Export-Console Export-Counter Export-Csv Export-FormatData Export-ModuleMember Export-PSSession ForEach-Object Format-Custom Format-List Format-Table Format-Wide Get-Acl Get-Alias Get-AuthenticodeSignature Get-ChildItem Get-Command Get-ComputerRestorePoint Get-Content Get-ControlPanelItem Get-Counter Get-Credential Get-Culture Get-Date Get-Event Get-EventLog Get-EventSubscriber Get-ExecutionPolicy Get-FormatData Get-Host Get-HotFix Get-Help Get-History Get-IseSnippet Get-Item Get-ItemProperty Get-Job Get-JobTrigger Get-Location Get-Member Get-Module Get-PfxCertificate Get-Process Get-PSBreakpoint Get-PSCallStack Get-PSDrive Get-PSProvider Get-PSSession Get-PSSessionConfiguration Get-PSSnapin Get-Random Get-ScheduledJob Get-ScheduledJobOption Get-Service Get-TraceSource Get-Transaction Get-TypeData Get-UICulture Get-Unique Get-Variable Get-Verb Get-WinEvent Get-WmiObject Get-WSManCredSSP Get-WSManInstance Group-Object Import-Alias Import-Clixml Import-Counter Import-Csv Import-IseSnippet Import-LocalizedData Import-PSSession Import-Module Invoke-AsWorkflow Invoke-Command Invoke-Expression Invoke-History Invoke-Item Invoke-RestMethod Invoke-WebRequest Invoke-WmiMethod Invoke-WSManAction Join-Path Limit-EventLog Measure-Command Measure-Object Move-Item Move-ItemProperty New-Alias New-Event New-EventLog New-IseSnippet New-Item New-ItemProperty New-JobTrigger New-Object New-Module New-ModuleManifest New-PSDrive New-PSSession New-PSSessionConfigurationFile New-PSSessionOption New-PSTransportOption New-PSWorkflowExecutionOption New-PSWorkflowSession New-ScheduledJobOption New-Service New-TimeSpan New-Variable New-WebServiceProxy New-WinEvent New-WSManInstance New-WSManSessionOption Out-Default Out-File Out-GridView Out-Host Out-Null Out-Printer Out-String Pop-Location Push-Location Read-Host Receive-Job Register-EngineEvent Register-ObjectEvent Register-PSSessionConfiguration Register-ScheduledJob Register-WmiEvent Remove-Computer Remove-Event Remove-EventLog Remove-Item Remove-ItemProperty Remove-Job Remove-JobTrigger Remove-Module Remove-PSBreakpoint Remove-PSDrive Remove-PSSession Remove-PSSnapin Remove-TypeData Remove-Variable Remove-WmiObject Remove-WSManInstance Rename-Computer Rename-Item Rename-ItemProperty Reset-ComputerMachinePassword Resolve-Path Restart-Computer Restart-Service Restore-Computer Resume-Job Resume-Service Save-Help Select-Object Select-String Select-Xml Send-MailMessage Set-Acl Set-Alias Set-AuthenticodeSignature Set-Content Set-Date Set-ExecutionPolicy Set-Item Set-ItemProperty Set-JobTrigger Set-Location Set-PSBreakpoint Set-PSDebug Set-PSSessionConfiguration Set-ScheduledJob Set-ScheduledJobOption Set-Service Set-StrictMode Set-TraceSource Set-Variable Set-WmiInstance Set-WSManInstance Set-WSManQuickConfig Show-Command Show-ControlPanelItem Show-EventLog Sort-Object Split-Path Start-Job Start-Process Start-Service Start-Sleep Start-Transaction Start-Transcript Stop-Computer Stop-Job Stop-Process Stop-Service Stop-Transcript Suspend-Job Suspend-Service Tee-Object Test-ComputerSecureChannel Test-Connection Test-ModuleManifest Test-Path Test-PSSessionConfigurationFile Trace-Command Unblock-File Undo-Transaction Unregister-Event Unregister-PSSessionConfiguration Unregister-ScheduledJob Update-FormatData Update-Help Update-List Update-TypeData Use-Transaction Wait-Event Wait-Job Wait-Process Where-Object Write-Debug Write-Error Write-EventLog Write-Host Write-Output Write-Progress Write-Verbose Write-Warning Add-MDTPersistentDrive Disable-MDTMonitorService Enable-MDTMonitorService Get-MDTDeploymentShareStatistics Get-MDTMonitorData Get-MDTOperatingSystemCatalog Get-MDTPersistentDrive Import-MDTApplication Import-MDTDriver Import-MDTOperatingSystem Import-MDTPackage Import-MDTTaskSequence New-MDTDatabase Remove-MDTMonitorData Remove-MDTPersistentDrive Restore-MDTPersistentDrive Set-MDTMonitorData Test-MDTDeploymentShare Test-MDTMonitorData Update-MDTDatabaseSchema Update-MDTDeploymentShare Update-MDTLinkedDS Update-MDTMedia Add-VamtProductKey Export-VamtData Find-VamtManagedMachine Get-VamtConfirmationId Get-VamtProduct Get-VamtProductKey Import-VamtData Initialize-VamtData Install-VamtConfirmationId Install-VamtProductActivation Install-VamtProductKey Update-VamtProduct Add-CIDatastore Add-KeyManagementServer Add-NodeKeys Add-NsxDynamicCriteria Add-NsxDynamicMemberSet Add-NsxEdgeInterfaceAddress Add-NsxFirewallExclusionListMember Add-NsxFirewallRuleMember Add-NsxIpSetMember Add-NsxLicense Add-NsxLoadBalancerPoolMember Add-NsxLoadBalancerVip Add-NsxSecondaryManager Add-NsxSecurityGroupMember Add-NsxSecurityPolicyRule Add-NsxSecurityPolicyRuleGroup Add-NsxSecurityPolicyRuleService Add-NsxServiceGroupMember Add-NsxTransportZoneMember Add-PassthroughDevice Add-VDSwitchPhysicalNetworkAdapter Add-VDSwitchVMHost Add-VMHost Add-VMHostNtpServer Add-VirtualSwitchPhysicalNetworkAdapter Add-XmlElement Add-vRACustomForm Add-vRAPrincipalToTenantRole Add-vRAReservationNetwork Add-vRAReservationStorage Clear-NsxEdgeInterface Clear-NsxManagerTimeSettings Compress-Archive Connect-CIServer Connect-CisServer Connect-HCXServer Connect-NIServer Connect-NsxLogicalSwitch Connect-NsxServer Connect-NsxtServer Connect-SrmServer Connect-VIServer Connect-Vmc Connect-vRAServer Connect-vRNIServer ConvertFrom-Markdown ConvertTo-MOFInstance Copy-DatastoreItem Copy-HardDisk Copy-NsxEdge Copy-VDisk Copy-VMGuestFile Debug-Runspace Disable-NsxEdgeSsh Disable-RunspaceDebug Disable-vRNIDataSource Disconnect-CIServer Disconnect-CisServer Disconnect-HCXServer Disconnect-NsxLogicalSwitch Disconnect-NsxServer Disconnect-NsxtServer Disconnect-SrmServer Disconnect-VIServer Disconnect-Vmc Disconnect-vRAServer Disconnect-vRNIServer Dismount-Tools Enable-NsxEdgeSsh Enable-RunspaceDebug Enable-vRNIDataSource Expand-Archive Export-NsxObject Export-SpbmStoragePolicy Export-VApp Export-VDPortGroup Export-VDSwitch Export-VMHostProfile Export-vRAIcon Export-vRAPackage Find-Command Find-DscResource Find-Module Find-NsxWhereVMUsed Find-Package Find-PackageProvider Find-RoleCapability Find-Script Format-Hex Format-VMHostDiskPartition Format-XML Generate-VersionInfo Get-AdvancedSetting Get-AlarmAction Get-AlarmActionTrigger Get-AlarmDefinition Get-Annotation Get-CDDrive Get-CIAccessControlRule Get-CIDatastore Get-CINetworkAdapter Get-CIRole Get-CIUser Get-CIVApp Get-CIVAppNetwork Get-CIVAppStartRule Get-CIVAppTemplate Get-CIVM Get-CIVMTemplate Get-CIView Get-Catalog Get-CisCommand Get-CisService Get-CloudCommand Get-Cluster Get-CompatibleVersionAddtionaPropertiesStr Get-ComplexResourceQualifier Get-ConfigurationErrorCount Get-ContentLibraryItem Get-CustomAttribute Get-DSCResourceModules Get-Datacenter Get-Datastore Get-DatastoreCluster Get-DrsClusterGroup Get-DrsRecommendation Get-DrsRule Get-DrsVMHostRule Get-DscResource Get-EdgeGateway Get-EncryptedPassword Get-ErrorReport Get-EsxCli Get-EsxTop Get-ExternalNetwork Get-FileHash Get-FloppyDrive Get-Folder Get-HAPrimaryVMHost Get-HCXAppliance Get-HCXApplianceCompute Get-HCXApplianceDVS Get-HCXApplianceDatastore Get-HCXApplianceNetwork Get-HCXContainer Get-HCXDatastore Get-HCXGateway Get-HCXInterconnectStatus Get-HCXJob Get-HCXMigration Get-HCXNetwork Get-HCXNetworkExtension Get-HCXReplication Get-HCXReplicationSnapshot Get-HCXService Get-HCXSite Get-HCXSitePairing Get-HCXVM Get-HardDisk Get-IScsiHbaTarget Get-InnerMostErrorRecord Get-InstallPath Get-InstalledModule Get-InstalledScript Get-Inventory Get-ItemPropertyValue Get-KeyManagementServer Get-KmipClientCertificate Get-KmsCluster Get-Log Get-LogType Get-MarkdownOption Get-Media Get-MofInstanceName Get-MofInstanceText Get-NetworkAdapter Get-NetworkPool Get-NfsUser Get-NicTeamingPolicy Get-NsxApplicableMember Get-NsxApplicableSecurityAction Get-NsxBackingDVSwitch Get-NsxBackingPortGroup Get-NsxCliDfwAddrSet Get-NsxCliDfwFilter Get-NsxCliDfwRule Get-NsxClusterStatus Get-NsxController Get-NsxDynamicCriteria Get-NsxDynamicMemberSet Get-NsxEdge Get-NsxEdgeBgp Get-NsxEdgeBgpNeighbour Get-NsxEdgeCertificate Get-NsxEdgeCsr Get-NsxEdgeFirewall Get-NsxEdgeFirewallRule Get-NsxEdgeInterface Get-NsxEdgeInterfaceAddress Get-NsxEdgeNat Get-NsxEdgeNatRule Get-NsxEdgeOspf Get-NsxEdgeOspfArea Get-NsxEdgeOspfInterface Get-NsxEdgePrefix Get-NsxEdgeRedistributionRule Get-NsxEdgeRouting Get-NsxEdgeStaticRoute Get-NsxEdgeSubInterface Get-NsxFirewallExclusionListMember Get-NsxFirewallGlobalConfiguration Get-NsxFirewallPublishStatus Get-NsxFirewallRule Get-NsxFirewallRuleMember Get-NsxFirewallSavedConfiguration Get-NsxFirewallSection Get-NsxFirewallThreshold Get-NsxIpPool Get-NsxIpSet Get-NsxLicense Get-NsxLoadBalancer Get-NsxLoadBalancerApplicationProfile Get-NsxLoadBalancerApplicationRule Get-NsxLoadBalancerMonitor Get-NsxLoadBalancerPool Get-NsxLoadBalancerPoolMember Get-NsxLoadBalancerStats Get-NsxLoadBalancerVip Get-NsxLogicalRouter Get-NsxLogicalRouterBgp Get-NsxLogicalRouterBgpNeighbour Get-NsxLogicalRouterBridge Get-NsxLogicalRouterBridging Get-NsxLogicalRouterInterface Get-NsxLogicalRouterOspf Get-NsxLogicalRouterOspfArea Get-NsxLogicalRouterOspfInterface Get-NsxLogicalRouterPrefix Get-NsxLogicalRouterRedistributionRule Get-NsxLogicalRouterRouting Get-NsxLogicalRouterStaticRoute Get-NsxLogicalSwitch Get-NsxMacSet Get-NsxManagerBackup Get-NsxManagerCertificate Get-NsxManagerComponentSummary Get-NsxManagerNetwork Get-NsxManagerRole Get-NsxManagerSsoConfig Get-NsxManagerSyncStatus Get-NsxManagerSyslogServer Get-NsxManagerSystemSummary Get-NsxManagerTimeSettings Get-NsxManagerVcenterConfig Get-NsxSecondaryManager Get-NsxSecurityGroup Get-NsxSecurityGroupEffectiveIpAddress Get-NsxSecurityGroupEffectiveMacAddress Get-NsxSecurityGroupEffectiveMember Get-NsxSecurityGroupEffectiveVirtualMachine Get-NsxSecurityGroupEffectiveVnic Get-NsxSecurityGroupMemberTypes Get-NsxSecurityPolicy Get-NsxSecurityPolicyHighestUsedPrecedence Get-NsxSecurityPolicyRule Get-NsxSecurityTag Get-NsxSecurityTagAssignment Get-NsxSegmentIdRange Get-NsxService Get-NsxServiceDefinition Get-NsxServiceGroup Get-NsxServiceGroupMember Get-NsxServiceProfile Get-NsxSpoofguardNic Get-NsxSpoofguardPolicy Get-NsxSslVpn Get-NsxSslVpnAuthServer Get-NsxSslVpnClientInstallationPackage Get-NsxSslVpnIpPool Get-NsxSslVpnPrivateNetwork Get-NsxSslVpnUser Get-NsxTransportZone Get-NsxUserRole Get-NsxVdsContext Get-NsxtPolicyService Get-NsxtService Get-OSCustomizationNicMapping Get-OSCustomizationSpec Get-Org Get-OrgNetwork Get-OrgVdc Get-OrgVdcNetwork Get-OvfConfiguration Get-PSCurrentConfigurationNode Get-PSDefaultConfigurationDocument Get-PSMetaConfigDocumentInstVersionInfo Get-PSMetaConfigurationProcessed Get-PSReadLineKeyHandler Get-PSReadLineOption Get-PSRepository Get-PSTopConfigurationName Get-PSVersion Get-Package Get-PackageProvider Get-PackageSource Get-PassthroughDevice Get-PositionInfo Get-PowerCLICommunity Get-PowerCLIConfiguration Get-PowerCLIHelp Get-PowerCLIVersion Get-PowerNsxVersion Get-ProviderVdc Get-PublicKeyFromFile Get-PublicKeyFromStore Get-ResourcePool Get-Runspace Get-RunspaceDebug Get-ScsiController Get-ScsiLun Get-ScsiLunPath Get-SecurityInfo Get-SecurityPolicy Get-Snapshot Get-SpbmCapability Get-SpbmCompatibleStorage Get-SpbmEntityConfiguration Get-SpbmFaultDomain Get-SpbmPointInTimeReplica Get-SpbmReplicationGroup Get-SpbmReplicationPair Get-SpbmStoragePolicy Get-Stat Get-StatInterval Get-StatType Get-Tag Get-TagAssignment Get-TagCategory Get-Task Get-Template Get-TimeZone Get-Uptime Get-UsbDevice Get-VAIOFilter Get-VApp Get-VDBlockedPolicy Get-VDPort Get-VDPortgroup Get-VDPortgroupOverridePolicy Get-VDSecurityPolicy Get-VDSwitch Get-VDSwitchPrivateVlan Get-VDTrafficShapingPolicy Get-VDUplinkLacpPolicy Get-VDUplinkTeamingPolicy Get-VDisk Get-VIAccount Get-VICommand Get-VICredentialStoreItem Get-VIEvent Get-VIObjectByVIView Get-VIPermission Get-VIPrivilege Get-VIProperty Get-VIRole Get-VM Get-VMGuest Get-VMHost Get-VMHostAccount Get-VMHostAdvancedConfiguration Get-VMHostAuthentication Get-VMHostAvailableTimeZone Get-VMHostDiagnosticPartition Get-VMHostDisk Get-VMHostDiskPartition Get-VMHostFirewallDefaultPolicy Get-VMHostFirewallException Get-VMHostFirmware Get-VMHostHardware Get-VMHostHba Get-VMHostModule Get-VMHostNetwork Get-VMHostNetworkAdapter Get-VMHostNtpServer Get-VMHostPatch Get-VMHostPciDevice Get-VMHostProfile Get-VMHostProfileImageCacheConfiguration Get-VMHostProfileRequiredInput Get-VMHostProfileStorageDeviceConfiguration Get-VMHostProfileUserConfiguration Get-VMHostProfileVmPortGroupConfiguration Get-VMHostRoute Get-VMHostService Get-VMHostSnmp Get-VMHostStartPolicy Get-VMHostStorage Get-VMHostSysLogServer Get-VMQuestion Get-VMResourceConfiguration Get-VMStartPolicy Get-VTpm Get-VTpmCSR Get-VTpmCertificate Get-VasaProvider Get-VasaStorageArray Get-View Get-VirtualPortGroup Get-VirtualSwitch Get-VmcSddcNetworkService Get-VmcService Get-VsanClusterConfiguration Get-VsanComponent Get-VsanDisk Get-VsanDiskGroup Get-VsanEvacuationPlan Get-VsanFaultDomain Get-VsanIscsiInitiatorGroup Get-VsanIscsiInitiatorGroupTargetAssociation Get-VsanIscsiLun Get-VsanIscsiTarget Get-VsanObject Get-VsanResyncingComponent Get-VsanRuntimeInfo Get-VsanSpaceUsage Get-VsanStat Get-VsanView Get-vRAApplianceServiceStatus Get-vRAAuthorizationRole Get-vRABlueprint Get-vRABusinessGroup Get-vRACatalogItem Get-vRACatalogItemRequestTemplate Get-vRACatalogPrincipal Get-vRAComponentRegistryService Get-vRAComponentRegistryServiceEndpoint Get-vRAComponentRegistryServiceStatus Get-vRAContent Get-vRAContentData Get-vRAContentType Get-vRACustomForm Get-vRAEntitledCatalogItem Get-vRAEntitledService Get-vRAEntitlement Get-vRAExternalNetworkProfile Get-vRAGroupPrincipal Get-vRAIcon Get-vRANATNetworkProfile Get-vRANetworkProfileIPAddressList Get-vRANetworkProfileIPRangeSummary Get-vRAPackage Get-vRAPackageContent Get-vRAPropertyDefinition Get-vRAPropertyGroup Get-vRARequest Get-vRARequestDetail Get-vRAReservation Get-vRAReservationComputeResource Get-vRAReservationComputeResourceMemory Get-vRAReservationComputeResourceNetwork Get-vRAReservationComputeResourceResourcePool Get-vRAReservationComputeResourceStorage Get-vRAReservationPolicy Get-vRAReservationTemplate Get-vRAReservationType Get-vRAResource Get-vRAResourceAction Get-vRAResourceActionRequestTemplate Get-vRAResourceMetric Get-vRAResourceOperation Get-vRAResourceType Get-vRARoutedNetworkProfile Get-vRAService Get-vRAServiceBlueprint Get-vRASourceMachine Get-vRAStorageReservationPolicy Get-vRATenant Get-vRATenantDirectory Get-vRATenantDirectoryStatus Get-vRATenantRole Get-vRAUserPrincipal Get-vRAUserPrincipalGroupMembership Get-vRAVersion Get-vRNIAPIVersion Get-vRNIApplication Get-vRNIApplicationTier Get-vRNIDataSource Get-vRNIDataSourceSNMPConfig Get-vRNIDatastore Get-vRNIDistributedSwitch Get-vRNIDistributedSwitchPortGroup Get-vRNIEntity Get-vRNIEntityName Get-vRNIFirewallRule Get-vRNIFlow Get-vRNIHost Get-vRNIHostVMKNic Get-vRNIIPSet Get-vRNIL2Network Get-vRNINSXManager Get-vRNINodes Get-vRNIProblem Get-vRNIRecommendedRules Get-vRNIRecommendedRulesNsxBundle Get-vRNISecurityGroup Get-vRNISecurityTag Get-vRNIService Get-vRNIServiceGroup Get-vRNIVM Get-vRNIVMvNIC Get-vRNIvCenter Get-vRNIvCenterCluster Get-vRNIvCenterDatacenter Get-vRNIvCenterFolder Grant-NsxSpoofguardNicApproval Import-CIVApp Import-CIVAppTemplate Import-NsxObject Import-PackageProvider Import-PowerShellDataFile Import-SpbmStoragePolicy Import-VApp Import-VMHostProfile Import-vRAContentData Import-vRAIcon Import-vRAPackage Initialize-ConfigurationRuntimeState Install-Module Install-NsxCluster Install-Package Install-PackageProvider Install-Script Install-VMHostPatch Invoke-DrsRecommendation Invoke-NsxCli Invoke-NsxClusterResolveAll Invoke-NsxManagerSync Invoke-NsxRestMethod Invoke-NsxWebRequest Invoke-VMHostProfile Invoke-VMScript Invoke-XpathQuery Invoke-vRADataCollection Invoke-vRARestMethod Invoke-vRATenantDirectorySync Invoke-vRNIRestMethod Join-String Mount-Tools Move-Cluster Move-Datacenter Move-Datastore Move-Folder Move-HardDisk Move-Inventory Move-NsxSecurityPolicyRule Move-ResourcePool Move-Template Move-VApp Move-VDisk Move-VM Move-VMHost New-AdvancedSetting New-AlarmAction New-AlarmActionTrigger New-CDDrive New-CIAccessControlRule New-CIVApp New-CIVAppNetwork New-CIVAppTemplate New-CIVM New-Cluster New-CustomAttribute New-Datacenter New-Datastore New-DatastoreCluster New-DatastoreDrive New-DrsClusterGroup New-DrsRule New-DrsVMHostRule New-DscChecksum New-FloppyDrive New-Folder New-Guid New-HCXAppliance New-HCXMigration New-HCXNetworkExtension New-HCXNetworkMapping New-HCXReplication New-HCXSitePairing New-HCXStaticRoute New-HardDisk New-IScsiHbaTarget New-KmipClientCertificate New-NetworkAdapter New-NfsUser New-NsxAddressSpec New-NsxClusterVxlanConfig New-NsxController New-NsxDynamicCriteriaSpec New-NsxEdge New-NsxEdgeBgpNeighbour New-NsxEdgeCsr New-NsxEdgeFirewallRule New-NsxEdgeInterfaceSpec New-NsxEdgeNatRule New-NsxEdgeOspfArea New-NsxEdgeOspfInterface New-NsxEdgePrefix New-NsxEdgeRedistributionRule New-NsxEdgeSelfSignedCertificate New-NsxEdgeStaticRoute New-NsxEdgeSubInterface New-NsxEdgeSubInterfaceSpec New-NsxFirewallRule New-NsxFirewallSavedConfiguration New-NsxFirewallSection New-NsxIpPool New-NsxIpSet New-NsxLoadBalancerApplicationProfile New-NsxLoadBalancerApplicationRule New-NsxLoadBalancerMemberSpec New-NsxLoadBalancerMonitor New-NsxLoadBalancerPool New-NsxLogicalRouter New-NsxLogicalRouterBgpNeighbour New-NsxLogicalRouterBridge New-NsxLogicalRouterInterface New-NsxLogicalRouterInterfaceSpec New-NsxLogicalRouterOspfArea New-NsxLogicalRouterOspfInterface New-NsxLogicalRouterPrefix New-NsxLogicalRouterRedistributionRule New-NsxLogicalRouterStaticRoute New-NsxLogicalSwitch New-NsxMacSet New-NsxManager New-NsxSecurityGroup New-NsxSecurityPolicy New-NsxSecurityPolicyAssignment New-NsxSecurityPolicyFirewallRuleSpec New-NsxSecurityPolicyGuestIntrospectionSpec New-NsxSecurityPolicyNetworkIntrospectionSpec New-NsxSecurityTag New-NsxSecurityTagAssignment New-NsxSegmentIdRange New-NsxService New-NsxServiceGroup New-NsxSpoofguardPolicy New-NsxSslVpnAuthServer New-NsxSslVpnClientInstallationPackage New-NsxSslVpnIpPool New-NsxSslVpnPrivateNetwork New-NsxSslVpnUser New-NsxTransportZone New-NsxVdsContext New-OSCustomizationNicMapping New-OSCustomizationSpec New-Org New-OrgNetwork New-OrgVdc New-OrgVdcNetwork New-ResourcePool New-ScriptFileInfo New-ScsiController New-Snapshot New-SpbmRule New-SpbmRuleSet New-SpbmStoragePolicy New-StatInterval New-Tag New-TagAssignment New-TagCategory New-Template New-TemporaryFile New-VAIOFilter New-VApp New-VDPortgroup New-VDSwitch New-VDSwitchPrivateVlan New-VDisk New-VICredentialStoreItem New-VIInventoryDrive New-VIPermission New-VIProperty New-VIRole New-VISamlSecurityContext New-VM New-VMHostAccount New-VMHostNetworkAdapter New-VMHostProfile New-VMHostProfileVmPortGroupConfiguration New-VMHostRoute New-VTpm New-VasaProvider New-VcsOAuthSecurityContext New-VirtualPortGroup New-VirtualSwitch New-VsanDisk New-VsanDiskGroup New-VsanFaultDomain New-VsanIscsiInitiatorGroup New-VsanIscsiInitiatorGroupTargetAssociation New-VsanIscsiLun New-VsanIscsiTarget New-vRABusinessGroup New-vRAEntitlement New-vRAExternalNetworkProfile New-vRAGroupPrincipal New-vRANATNetworkProfile New-vRANetworkProfileIPRangeDefinition New-vRAPackage New-vRAPropertyDefinition New-vRAPropertyGroup New-vRAReservation New-vRAReservationNetworkDefinition New-vRAReservationPolicy New-vRAReservationStorageDefinition New-vRARoutedNetworkProfile New-vRAService New-vRAStorageReservationPolicy New-vRATenant New-vRATenantDirectory New-vRAUserPrincipal New-vRNIApplication New-vRNIApplicationTier New-vRNIDataSource Open-VMConsoleWindow Publish-Module Publish-NsxSpoofguardPolicy Publish-Script Register-PSRepository Register-PackageSource Remove-AdvancedSetting Remove-AlarmAction Remove-AlarmActionTrigger Remove-Alias Remove-CDDrive Remove-CIAccessControlRule Remove-CIVApp Remove-CIVAppNetwork Remove-CIVAppTemplate Remove-Cluster Remove-CustomAttribute Remove-Datacenter Remove-Datastore Remove-DatastoreCluster Remove-DrsClusterGroup Remove-DrsRule Remove-DrsVMHostRule Remove-FloppyDrive Remove-Folder Remove-HCXAppliance Remove-HCXNetworkExtension Remove-HCXReplication Remove-HCXSitePairing Remove-HardDisk Remove-IScsiHbaTarget Remove-Inventory Remove-KeyManagementServer Remove-NetworkAdapter Remove-NfsUser Remove-NsxCluster Remove-NsxClusterVxlanConfig Remove-NsxController Remove-NsxDynamicCriteria Remove-NsxDynamicMemberSet Remove-NsxEdge Remove-NsxEdgeBgpNeighbour Remove-NsxEdgeCertificate Remove-NsxEdgeCsr Remove-NsxEdgeFirewallRule Remove-NsxEdgeInterfaceAddress Remove-NsxEdgeNatRule Remove-NsxEdgeOspfArea Remove-NsxEdgeOspfInterface Remove-NsxEdgePrefix Remove-NsxEdgeRedistributionRule Remove-NsxEdgeStaticRoute Remove-NsxEdgeSubInterface Remove-NsxFirewallExclusionListMember Remove-NsxFirewallRule Remove-NsxFirewallRuleMember Remove-NsxFirewallSavedConfiguration Remove-NsxFirewallSection Remove-NsxIpPool Remove-NsxIpSet Remove-NsxIpSetMember Remove-NsxLoadBalancerApplicationProfile Remove-NsxLoadBalancerMonitor Remove-NsxLoadBalancerPool Remove-NsxLoadBalancerPoolMember Remove-NsxLoadBalancerVip Remove-NsxLogicalRouter Remove-NsxLogicalRouterBgpNeighbour Remove-NsxLogicalRouterBridge Remove-NsxLogicalRouterInterface Remove-NsxLogicalRouterOspfArea Remove-NsxLogicalRouterOspfInterface Remove-NsxLogicalRouterPrefix Remove-NsxLogicalRouterRedistributionRule Remove-NsxLogicalRouterStaticRoute Remove-NsxLogicalSwitch Remove-NsxMacSet Remove-NsxSecondaryManager Remove-NsxSecurityGroup Remove-NsxSecurityGroupMember Remove-NsxSecurityPolicy Remove-NsxSecurityPolicyAssignment Remove-NsxSecurityPolicyRule Remove-NsxSecurityPolicyRuleGroup Remove-NsxSecurityPolicyRuleService Remove-NsxSecurityTag Remove-NsxSecurityTagAssignment Remove-NsxSegmentIdRange Remove-NsxService Remove-NsxServiceGroup Remove-NsxSpoofguardPolicy Remove-NsxSslVpnClientInstallationPackage Remove-NsxSslVpnIpPool Remove-NsxSslVpnPrivateNetwork Remove-NsxSslVpnUser Remove-NsxTransportZone Remove-NsxTransportZoneMember Remove-NsxVdsContext Remove-OSCustomizationNicMapping Remove-OSCustomizationSpec Remove-Org Remove-OrgNetwork Remove-OrgVdc Remove-OrgVdcNetwork Remove-PSReadLineKeyHandler Remove-PassthroughDevice Remove-ResourcePool Remove-Snapshot Remove-SpbmStoragePolicy Remove-StatInterval Remove-Tag Remove-TagAssignment Remove-TagCategory Remove-Template Remove-UsbDevice Remove-VAIOFilter Remove-VApp Remove-VDPortGroup Remove-VDSwitch Remove-VDSwitchPhysicalNetworkAdapter Remove-VDSwitchPrivateVlan Remove-VDSwitchVMHost Remove-VDisk Remove-VICredentialStoreItem Remove-VIPermission Remove-VIProperty Remove-VIRole Remove-VM Remove-VMHost Remove-VMHostAccount Remove-VMHostNetworkAdapter Remove-VMHostNtpServer Remove-VMHostProfile Remove-VMHostProfileVmPortGroupConfiguration Remove-VMHostRoute Remove-VTpm Remove-VasaProvider Remove-VirtualPortGroup Remove-VirtualSwitch Remove-VirtualSwitchPhysicalNetworkAdapter Remove-VsanDisk Remove-VsanDiskGroup Remove-VsanFaultDomain Remove-VsanIscsiInitiatorGroup Remove-VsanIscsiInitiatorGroupTargetAssociation Remove-VsanIscsiLun Remove-VsanIscsiTarget Remove-vRABusinessGroup Remove-vRACustomForm Remove-vRAExternalNetworkProfile Remove-vRAGroupPrincipal Remove-vRAIcon Remove-vRANATNetworkProfile Remove-vRAPackage Remove-vRAPrincipalFromTenantRole Remove-vRAPropertyDefinition Remove-vRAPropertyGroup Remove-vRAReservation Remove-vRAReservationNetwork Remove-vRAReservationPolicy Remove-vRAReservationStorage Remove-vRARoutedNetworkProfile Remove-vRAService Remove-vRAStorageReservationPolicy Remove-vRATenant Remove-vRATenantDirectory Remove-vRAUserPrincipal Remove-vRNIApplication Remove-vRNIApplicationTier Remove-vRNIDataSource Repair-NsxEdge Repair-VsanObject Request-vRACatalogItem Request-vRAResourceAction Restart-CIVApp Restart-CIVAppGuest Restart-CIVM Restart-CIVMGuest Restart-VM Restart-VMGuest Restart-VMHost Restart-VMHostService Resume-HCXReplication Revoke-NsxSpoofguardNicApproval Save-Module Save-Package Save-Script Search-Cloud Set-AdvancedSetting Set-AlarmDefinition Set-Annotation Set-CDDrive Set-CIAccessControlRule Set-CINetworkAdapter Set-CIVApp Set-CIVAppNetwork Set-CIVAppStartRule Set-CIVAppTemplate Set-Cluster Set-CustomAttribute Set-Datacenter Set-Datastore Set-DatastoreCluster Set-DrsClusterGroup Set-DrsRule Set-DrsVMHostRule Set-FloppyDrive Set-Folder Set-HCXAppliance Set-HCXMigration Set-HCXReplication Set-HardDisk Set-IScsiHbaTarget Set-KeyManagementServer Set-KmsCluster Set-MarkdownOption Set-NetworkAdapter Set-NfsUser Set-NicTeamingPolicy Set-NodeExclusiveResources Set-NodeManager Set-NodeResourceSource Set-NodeResources Set-NsxEdge Set-NsxEdgeBgp Set-NsxEdgeFirewall Set-NsxEdgeInterface Set-NsxEdgeNat Set-NsxEdgeOspf Set-NsxEdgeRouting Set-NsxFirewallGlobalConfiguration Set-NsxFirewallRule Set-NsxFirewallSavedConfiguration Set-NsxFirewallThreshold Set-NsxLoadBalancer Set-NsxLoadBalancerPoolMember Set-NsxLogicalRouter Set-NsxLogicalRouterBgp Set-NsxLogicalRouterBridging Set-NsxLogicalRouterInterface Set-NsxLogicalRouterOspf Set-NsxLogicalRouterRouting Set-NsxManager Set-NsxManagerRole Set-NsxManagerTimeSettings Set-NsxSecurityPolicy Set-NsxSecurityPolicyFirewallRule Set-NsxSslVpn Set-OSCustomizationNicMapping Set-OSCustomizationSpec Set-Org Set-OrgNetwork Set-OrgVdc Set-OrgVdcNetwork Set-PSCurrentConfigurationNode Set-PSDefaultConfigurationDocument Set-PSMetaConfigDocInsProcessedBeforeMeta Set-PSMetaConfigVersionInfoV2 Set-PSReadLineKeyHandler Set-PSReadLineOption Set-PSRepository Set-PSTopConfigurationName Set-PackageSource Set-PowerCLIConfiguration Set-ResourcePool Set-ScsiController Set-ScsiLun Set-ScsiLunPath Set-SecurityPolicy Set-Snapshot Set-SpbmEntityConfiguration Set-SpbmStoragePolicy Set-StatInterval Set-Tag Set-TagCategory Set-Template Set-VAIOFilter Set-VApp Set-VDBlockedPolicy Set-VDPort Set-VDPortgroup Set-VDPortgroupOverridePolicy Set-VDSecurityPolicy Set-VDSwitch Set-VDTrafficShapingPolicy Set-VDUplinkLacpPolicy Set-VDUplinkTeamingPolicy Set-VDVlanConfiguration Set-VDisk Set-VIPermission Set-VIRole Set-VM Set-VMHost Set-VMHostAccount Set-VMHostAdvancedConfiguration Set-VMHostAuthentication Set-VMHostDiagnosticPartition Set-VMHostFirewallDefaultPolicy Set-VMHostFirewallException Set-VMHostFirmware Set-VMHostHba Set-VMHostModule Set-VMHostNetwork Set-VMHostNetworkAdapter Set-VMHostProfile Set-VMHostProfileImageCacheConfiguration Set-VMHostProfileStorageDeviceConfiguration Set-VMHostProfileUserConfiguration Set-VMHostProfileVmPortGroupConfiguration Set-VMHostRoute Set-VMHostService Set-VMHostSnmp Set-VMHostStartPolicy Set-VMHostStorage Set-VMHostSysLogServer Set-VMQuestion Set-VMResourceConfiguration Set-VMStartPolicy Set-VTpm Set-VirtualPortGroup Set-VirtualSwitch Set-VsanClusterConfiguration Set-VsanFaultDomain Set-VsanIscsiInitiatorGroup Set-VsanIscsiLun Set-VsanIscsiTarget Set-vRABusinessGroup Set-vRACatalogItem Set-vRACustomForm Set-vRAEntitlement Set-vRAExternalNetworkProfile Set-vRANATNetworkProfile Set-vRAReservation Set-vRAReservationNetwork Set-vRAReservationPolicy Set-vRAReservationStorage Set-vRARoutedNetworkProfile Set-vRAService Set-vRAStorageReservationPolicy Set-vRATenant Set-vRATenantDirectory Set-vRAUserPrincipal Set-vRNIDataSourceSNMPConfig Show-Markdown Start-CIVApp Start-CIVM Start-HCXMigration Start-HCXReplication Start-SpbmReplicationFailover Start-SpbmReplicationPrepareFailover Start-SpbmReplicationPromote Start-SpbmReplicationReverse Start-SpbmReplicationTestFailover Start-ThreadJob Start-VApp Start-VM Start-VMHost Start-VMHostService Start-VsanClusterDiskUpdate Start-VsanClusterRebalance Start-VsanEncryptionConfiguration Stop-CIVApp Stop-CIVAppGuest Stop-CIVM Stop-CIVMGuest Stop-SpbmReplicationTestFailover Stop-Task Stop-VApp Stop-VM Stop-VMGuest Stop-VMHost Stop-VMHostService Stop-VsanClusterRebalance Suspend-CIVApp Suspend-CIVM Suspend-HCXReplication Suspend-VM Suspend-VMGuest Suspend-VMHost Sync-SpbmReplicationGroup Test-ConflictingResources Test-HCXMigration Test-HCXReplication Test-Json Test-ModuleReloadRequired Test-MofInstanceText Test-NodeManager Test-NodeResourceSource Test-NodeResources Test-ScriptFileInfo Test-VMHostProfileCompliance Test-VMHostSnmp Test-VsanClusterHealth Test-VsanNetworkPerformance Test-VsanStoragePerformance Test-VsanVMCreation Test-vRAPackage Uninstall-Module Uninstall-Package Uninstall-Script Unlock-VM Unregister-PSRepository Unregister-PackageSource Update-ConfigurationDocumentRef Update-ConfigurationErrorCount Update-DependsOn Update-LocalConfigManager Update-Module Update-ModuleManifest Update-ModuleVersion Update-PowerNsx Update-Script Update-ScriptFileInfo Update-Tools Update-VsanHclDatabase ValidateUpdate-ConfigurationData Wait-Debugger Wait-NsxControllerJob Wait-NsxGenericJob Wait-NsxJob Wait-Task Wait-Tools Write-Information Write-Log Write-MetaConfigFile Write-NodeMOFFile","nomarkup":"-ne -eq -lt -gt -ge -le -not -like -notlike -match -notmatch -contains -notcontains -in -notin -replace"},"contains":[{"begin":"`[\\s\\S]","relevance":0},{"className":"number","begin":"\\b\\d+(\\.\\d+)?","relevance":0},{"className":"string","variants":[{"begin":"\"","end":"\""},{"begin":"@\"","end":"^\"@"}],"contains":[{"$ref":"#contains.0"},{"className":"variable","variants":[{"begin":"\\$[\\w\\d][\\w\\d_:]*"}]},{"className":"variable","begin":"\\$[A-z]","end":"[^A-z]"}]},{"className":"string","variants":[{"begin":"'","end":"'"},{"begin":"@'","end":"^'@"}]},{"className":"literal","begin":"\\$(null|true|false)\\b"},{"$ref":"#contains.2.contains.1"},{"className":"comment","begin":null,"end":null,"contains":[{"className":"doctag","variants":[{"begin":"\\.(synopsis|description|example|inputs|outputs|notes|link|component|role|functionality)"},{"begin":"\\.(parameter|forwardhelptargetname|forwardhelpcategory|remotehelprunspace|externalhelp)\\s+\\S+"}]}],"variants":[{"begin":"#","end":"$"},{"begin":"<#","end":"#>"}]}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/processing.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/processing.json new file mode 100644 index 00000000..27a79ea6 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/processing.json @@ -0,0 +1 @@ +{"keywords":{"keyword":"BufferedReader PVector PFont PImage PGraphics HashMap boolean byte char color double float int long String Array FloatDict FloatList IntDict IntList JSONArray JSONObject Object StringDict StringList Table TableRow XML false synchronized int abstract float private char boolean static null if const for true while long throw strictfp finally protected import native final return void enum else break transient new catch instanceof byte super volatile case assert short package default double public try this switch continue throws protected public private","literal":"P2D P3D HALF_PI PI QUARTER_PI TAU TWO_PI","title":"setup draw","built_in":"displayHeight displayWidth mouseY mouseX mousePressed pmouseX pmouseY key keyCode pixels focused frameCount frameRate height width size createGraphics beginDraw createShape loadShape PShape arc ellipse line point quad rect triangle bezier bezierDetail bezierPoint bezierTangent curve curveDetail curvePoint curveTangent curveTightness shape shapeMode beginContour beginShape bezierVertex curveVertex endContour endShape quadraticVertex vertex ellipseMode noSmooth rectMode smooth strokeCap strokeJoin strokeWeight mouseClicked mouseDragged mouseMoved mousePressed mouseReleased mouseWheel keyPressed keyPressedkeyReleased keyTyped print println save saveFrame day hour millis minute month second year background clear colorMode fill noFill noStroke stroke alpha blue brightness color green hue lerpColor red saturation modelX modelY modelZ screenX screenY screenZ ambient emissive shininess specular add createImage beginCamera camera endCamera frustum ortho perspective printCamera printProjection cursor frameRate noCursor exit loop noLoop popStyle pushStyle redraw binary boolean byte char float hex int str unbinary unhex join match matchAll nf nfc nfp nfs split splitTokens trim append arrayCopy concat expand reverse shorten sort splice subset box sphere sphereDetail createInput createReader loadBytes loadJSONArray loadJSONObject loadStrings loadTable loadXML open parseXML saveTable selectFolder selectInput beginRaw beginRecord createOutput createWriter endRaw endRecord PrintWritersaveBytes saveJSONArray saveJSONObject saveStream saveStrings saveXML selectOutput popMatrix printMatrix pushMatrix resetMatrix rotate rotateX rotateY rotateZ scale shearX shearY translate ambientLight directionalLight lightFalloff lights lightSpecular noLights normal pointLight spotLight image imageMode loadImage noTint requestImage tint texture textureMode textureWrap blend copy filter get loadPixels set updatePixels blendMode loadShader PShaderresetShader shader createFont loadFont text textFont textAlign textLeading textMode textSize textWidth textAscent textDescent abs ceil constrain dist exp floor lerp log mag map max min norm pow round sq sqrt acos asin atan atan2 cos degrees radians sin tan noise noiseDetail noiseSeed random randomGaussian randomSeed"},"contains":[{"className":"comment","begin":"//","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"/\\*","end":"\\*/","contains":[{"$ref":"#contains.0.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"string","begin":"'","end":"'","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0}]},{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"$ref":"#contains.2.contains.0"},{"className":"subst","begin":"\\\\[abfnrtv]\\|\\\\x[0-9a-fA-F]*\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]","relevance":0},{"className":"subst","begin":"\\\\[abfnrtv]\\|\\\\x[0-9a-fA-F]*\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]","relevance":0}]},{"className":"number","begin":"(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)","relevance":0}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/profile.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/profile.json new file mode 100644 index 00000000..6a981d32 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/profile.json @@ -0,0 +1 @@ +{"contains":[{"className":"number","begin":"(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)","relevance":0},{"begin":"[a-zA-Z_][\\da-zA-Z_]+\\.[\\da-zA-Z_]{1,3}","end":":","excludeEnd":true},{"begin":"(ncalls|tottime|cumtime)","end":"$","keywords":"ncalls tottime|10 cumtime|10 filename","relevance":10},{"begin":"function calls","end":"$","contains":[{"$ref":"#contains.0"}],"relevance":10},{"className":"string","begin":"'","end":"'","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0}]},{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"$ref":"#contains.4.contains.0"},{"className":"subst","begin":"\\\\[abfnrtv]\\|\\\\x[0-9a-fA-F]*\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]","relevance":0},{"className":"subst","begin":"\\\\[abfnrtv]\\|\\\\x[0-9a-fA-F]*\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]","relevance":0}]},{"className":"string","begin":"\\(","end":"\\)$","excludeBegin":true,"excludeEnd":true,"relevance":0}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/prolog.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/prolog.json new file mode 100644 index 00000000..a07d9090 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/prolog.json @@ -0,0 +1 @@ +{"contains":[{"begin":"[a-z][A-Za-z0-9_]*","relevance":0},{"className":"symbol","variants":[{"begin":"[A-Z][a-zA-Z0-9_]*"},{"begin":"_[A-Za-z0-9_]*"}],"relevance":0},{"begin":"\\(","end":"\\)","relevance":0,"contains":[{"$ref":"#contains.0"},{"$ref":"#contains.1"},{"$ref":"#contains.2"},{"begin":":-"},{"begin":"\\[","end":"\\]","contains":{"$ref":"#contains.2.contains"}},{"className":"comment","begin":"%","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"}]},{"className":"comment","begin":"/\\*","end":"\\*/","contains":[{"$ref":"#contains.2.contains.5.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0},{"className":"subst","begin":"\\\\[abfnrtv]\\|\\\\x[0-9a-fA-F]*\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]","relevance":0},{"className":"subst","begin":"\\\\[abfnrtv]\\|\\\\x[0-9a-fA-F]*\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]","relevance":0}]},{"className":"string","begin":"'","end":"'","illegal":"\\n","contains":[{"$ref":"#contains.2.contains.7.contains.0"}]},{"className":"string","begin":"`","end":"`","contains":[{"$ref":"#contains.2.contains.7.contains.0"}]},{"className":"string","begin":"0\\'(\\\\\\'|.)"},{"className":"string","begin":"0\\'\\\\s"},{"className":"number","begin":"(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)","relevance":0}]},{"$ref":"#contains.2.contains.3"},{"$ref":"#contains.2.contains.4"},{"$ref":"#contains.2.contains.5"},{"$ref":"#contains.2.contains.6"},{"$ref":"#contains.2.contains.7"},{"$ref":"#contains.2.contains.8"},{"$ref":"#contains.2.contains.9"},{"$ref":"#contains.2.contains.10"},{"$ref":"#contains.2.contains.11"},{"$ref":"#contains.2.contains.12"},{"begin":"\\.$"}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/properties.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/properties.json new file mode 100644 index 00000000..255f8ebd --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/properties.json @@ -0,0 +1 @@ +{"case_insensitive":true,"illegal":"\\S","contains":[{"className":"comment","begin":"^\\s*[!#]","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"begin":"([^\\\\\\W:= \\t\\f\\n]|\\\\.)+([ \\t\\f]*[:=][ \\t\\f]*|[ \\t\\f]+)","returnBegin":true,"contains":[{"className":"attr","begin":"([^\\\\\\W:= \\t\\f\\n]|\\\\.)+","endsParent":true,"relevance":0}],"starts":{"end":"([ \\t\\f]*[:=][ \\t\\f]*|[ \\t\\f]+)","relevance":0,"starts":{"className":"string","end":"$","relevance":0,"contains":[{"begin":"\\\\\\n"}]}}},{"begin":"([^\\\\:= \\t\\f\\n]|\\\\.)+([ \\t\\f]*[:=][ \\t\\f]*|[ \\t\\f]+)","returnBegin":true,"relevance":0,"contains":[{"className":"meta","begin":"([^\\\\:= \\t\\f\\n]|\\\\.)+","endsParent":true,"relevance":0}],"starts":{"$ref":"#contains.1.starts"}},{"className":"attr","relevance":0,"begin":"([^\\\\:= \\t\\f\\n]|\\\\.)+[ \\t\\f]*$"}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/protobuf.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/protobuf.json new file mode 100644 index 00000000..1ffbe7e9 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/protobuf.json @@ -0,0 +1 @@ +{"keywords":{"keyword":"package import option optional required repeated group oneof","built_in":"double float int32 int64 uint32 uint64 sint32 sint64 fixed32 fixed64 sfixed32 sfixed64 bool string bytes","literal":"true false"},"contains":[{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0},{"className":"subst","begin":"\\\\[abfnrtv]\\|\\\\x[0-9a-fA-F]*\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]","relevance":0},{"className":"subst","begin":"\\\\[abfnrtv]\\|\\\\x[0-9a-fA-F]*\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]","relevance":0}]},{"className":"number","begin":"\\b\\d+(\\.\\d+)?","relevance":0},{"className":"comment","begin":"//","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"class","beginKeywords":"message enum service","end":"\\{","illegal":"\\n","contains":[{"className":"title","begin":"[a-zA-Z]\\w*","relevance":0,"starts":{"endsWithParent":true,"excludeEnd":true}}]},{"className":"function","beginKeywords":"rpc","end":";","excludeEnd":true,"keywords":"rpc returns"},{"begin":"^\\s*[A-Z_]+","end":"\\s*=","excludeEnd":true}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/puppet.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/puppet.json new file mode 100644 index 00000000..5bb49535 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/puppet.json @@ -0,0 +1 @@ +{"aliases":["pp"],"contains":[{"className":"comment","begin":"#","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"variable","begin":"\\$([A-Za-z_]|::)(\\w|::)*"},{"className":"string","contains":[{"begin":"\\\\[\\s\\S]","relevance":0},{"$ref":"#contains.1"}],"variants":[{"begin":"'","end":"'"},{"begin":"\"","end":"\""}]},{"beginKeywords":"class","end":"\\{|;","illegal":"=","contains":[{"className":"title","begin":"([A-Za-z_]|::)(\\w|::)*","relevance":0},{"$ref":"#contains.0"}]},{"beginKeywords":"define","end":"\\{","contains":[{"className":"section","begin":"[a-zA-Z]\\w*","endsParent":true}]},{"begin":"[a-zA-Z]\\w*\\s+\\{","returnBegin":true,"end":"\\S","contains":[{"className":"keyword","begin":"[a-zA-Z]\\w*"},{"begin":"\\{","end":"\\}","keywords":{"keyword":"and case default else elsif false if in import enherits node or true undef unless main settings $string ","literal":"alias audit before loglevel noop require subscribe tag owner ensure group mode name|0 changes context force incl lens load_path onlyif provider returns root show_diff type_check en_address ip_address realname command environment hour monute month monthday special target weekday creates cwd ogoutput refresh refreshonly tries try_sleep umask backup checksum content ctime force ignore links mtime purge recurse recurselimit replace selinux_ignore_defaults selrange selrole seltype seluser source souirce_permissions sourceselect validate_cmd validate_replacement allowdupe attribute_membership auth_membership forcelocal gid ia_load_module members system host_aliases ip allowed_trunk_vlans description device_url duplex encapsulation etherchannel native_vlan speed principals allow_root auth_class auth_type authenticate_user k_of_n mechanisms rule session_owner shared options device fstype enable hasrestart directory present absent link atboot blockdevice device dump pass remounts poller_tag use message withpath adminfile allow_virtual allowcdrom category configfiles flavor install_options instance package_settings platform responsefile status uninstall_options vendor unless_system_user unless_uid binary control flags hasstatus manifest pattern restart running start stop allowdupe auths expiry gid groups home iterations key_membership keys managehome membership password password_max_age password_min_age profile_membership profiles project purge_ssh_keys role_membership roles salt shell uid baseurl cost descr enabled enablegroups exclude failovermethod gpgcheck gpgkey http_caching include includepkgs keepalive metadata_expire metalink mirrorlist priority protect proxy proxy_password proxy_username repo_gpgcheck s3_enabled skip_if_unavailable sslcacert sslclientcert sslclientkey sslverify mounted","built_in":"architecture augeasversion blockdevices boardmanufacturer boardproductname boardserialnumber cfkey dhcp_servers domain ec2_ ec2_userdata facterversion filesystems ldom fqdn gid hardwareisa hardwaremodel hostname id|0 interfaces ipaddress ipaddress_ ipaddress6 ipaddress6_ iphostnumber is_virtual kernel kernelmajversion kernelrelease kernelversion kernelrelease kernelversion lsbdistcodename lsbdistdescription lsbdistid lsbdistrelease lsbmajdistrelease lsbminordistrelease lsbrelease macaddress macaddress_ macosx_buildversion macosx_productname macosx_productversion macosx_productverson_major macosx_productversion_minor manufacturer memoryfree memorysize netmask metmask_ network_ operatingsystem operatingsystemmajrelease operatingsystemrelease osfamily partitions path physicalprocessorcount processor processorcount productname ps puppetversion rubysitedir rubyversion selinux selinux_config_mode selinux_config_policy selinux_current_mode selinux_current_mode selinux_enforced selinux_policyversion serialnumber sp_ sshdsakey sshecdsakey sshrsakey swapencrypted swapfree swapsize timezone type uniqueid uptime uptime_days uptime_hours uptime_seconds uuid virtual vlans xendomains zfs_version zonenae zones zpool_version"},"relevance":0,"contains":[{"$ref":"#contains.2"},{"$ref":"#contains.0"},{"begin":"[a-zA-Z_]+\\s*=>","returnBegin":true,"end":"=>","contains":[{"className":"attr","begin":"[a-zA-Z]\\w*"}]},{"className":"number","begin":"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b","relevance":0},{"$ref":"#contains.1"}]}],"relevance":0}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/purebasic.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/purebasic.json new file mode 100644 index 00000000..d9ad82d9 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/purebasic.json @@ -0,0 +1 @@ +{"aliases":["pb","pbi"],"keywords":"Align And Array As Break CallDebugger Case CompilerCase CompilerDefault CompilerElse CompilerElseIf CompilerEndIf CompilerEndSelect CompilerError CompilerIf CompilerSelect CompilerWarning Continue Data DataSection Debug DebugLevel Declare DeclareC DeclareCDLL DeclareDLL DeclareModule Default Define Dim DisableASM DisableDebugger DisableExplicit Else ElseIf EnableASM EnableDebugger EnableExplicit End EndDataSection EndDeclareModule EndEnumeration EndIf EndImport EndInterface EndMacro EndModule EndProcedure EndSelect EndStructure EndStructureUnion EndWith Enumeration EnumerationBinary Extends FakeReturn For ForEach ForEver Global Gosub Goto If Import ImportC IncludeBinary IncludeFile IncludePath Interface List Macro MacroExpandedCount Map Module NewList NewMap Next Not Or Procedure ProcedureC ProcedureCDLL ProcedureDLL ProcedureReturn Protected Prototype PrototypeC ReDim Read Repeat Restore Return Runtime Select Shared Static Step Structure StructureUnion Swap Threaded To UndefineMacro Until Until UnuseModule UseModule Wend While With XIncludeFile XOr","contains":[{"className":"comment","begin":";","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}],"relevance":0},{"className":"function","begin":"\\b(Procedure|Declare)(C|CDLL|DLL)?\\b","end":"\\(","excludeEnd":true,"returnBegin":true,"contains":[{"className":"keyword","begin":"(Procedure|Declare)(C|CDLL|DLL)?","excludeEnd":true},{"className":"type","begin":"\\.\\w*"},{"className":"title","begin":"[a-zA-Z_]\\w*","relevance":0}]},{"className":"string","begin":"(~)?\"","end":"\"","illegal":"\\n"},{"className":"symbol","begin":"#[a-zA-Z_]\\w*\\$?"}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/python.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/python.json new file mode 100644 index 00000000..1968b9fe --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/python.json @@ -0,0 +1 @@ +{"aliases":["py","gyp","ipython"],"keywords":{"keyword":"and elif is global as in if from raise for except finally print import pass return exec else break not with class assert yield try while continue del or def lambda async await nonlocal|10","built_in":"Ellipsis NotImplemented","literal":"False None True"},"illegal":"(<\\/|->|\\?)|=>","contains":[{"className":"meta","begin":"^(>>>|\\.\\.\\.) "},{"className":"number","relevance":0,"variants":[{"begin":"\\b(0b[01]+)[lLjJ]?"},{"begin":"\\b(0o[0-7]+)[lLjJ]?"},{"begin":"(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)[lLjJ]?"}]},{"className":"string","contains":[{"begin":"\\\\[\\s\\S]","relevance":0}],"variants":[{"begin":"(u|b)?r?'''","end":"'''","contains":[{"$ref":"#contains.2.contains.0"},{"$ref":"#contains.0"}],"relevance":10},{"begin":"(u|b)?r?\"\"\"","end":"\"\"\"","contains":[{"$ref":"#contains.2.contains.0"},{"$ref":"#contains.0"}],"relevance":10},{"begin":"(fr|rf|f)'''","end":"'''","contains":[{"$ref":"#contains.2.contains.0"},{"$ref":"#contains.0"},{"className":"subst","begin":"\\{","end":"\\}","keywords":{"$ref":"#keywords"},"illegal":"#","contains":[{"$ref":"#contains.2"},{"$ref":"#contains.1"},{"$ref":"#contains.0"}]}]},{"begin":"(fr|rf|f)\"\"\"","end":"\"\"\"","contains":[{"$ref":"#contains.2.contains.0"},{"$ref":"#contains.0"},{"$ref":"#contains.2.variants.2.contains.2"}]},{"begin":"(u|r|ur)'","end":"'","relevance":10},{"begin":"(u|r|ur)\"","end":"\"","relevance":10},{"begin":"(b|br)'","end":"'"},{"begin":"(b|br)\"","end":"\""},{"begin":"(fr|rf|f)'","end":"'","contains":[{"$ref":"#contains.2.contains.0"},{"$ref":"#contains.2.variants.2.contains.2"}]},{"begin":"(fr|rf|f)\"","end":"\"","contains":[{"$ref":"#contains.2.contains.0"},{"$ref":"#contains.2.variants.2.contains.2"}]},{"className":"string","begin":"'","end":"'","illegal":"\\n","contains":[{"$ref":"#contains.2.contains.0"}]},{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"$ref":"#contains.2.contains.0"},{"className":"subst","begin":"\\\\[abfnrtv]\\|\\\\x[0-9a-fA-F]*\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]","relevance":0},{"className":"subst","begin":"\\\\[abfnrtv]\\|\\\\x[0-9a-fA-F]*\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]","relevance":0}]}]},{"className":"comment","begin":"#","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"variants":[{"className":"function","beginKeywords":"def"},{"className":"class","beginKeywords":"class"}],"end":":","illegal":"[${=;\\n,]","contains":[{"className":"title","begin":"[a-zA-Z_]\\w*","relevance":0},{"className":"params","begin":"\\(","end":"\\)","contains":["self",{"$ref":"#contains.0"},{"$ref":"#contains.1"},{"$ref":"#contains.2"}]},{"begin":"->","endsWithParent":true,"keywords":"None"}]},{"className":"meta","begin":"^[\\t ]*@","end":"$"},{"begin":"\\b(print|exec)\\("}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/q.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/q.json new file mode 100644 index 00000000..c1a3973b --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/q.json @@ -0,0 +1 @@ +{"aliases":["k","kdb"],"keywords":{"keyword":"do while select delete by update from","literal":"0b 1b","built_in":"neg not null string reciprocal floor ceiling signum mod xbar xlog and or each scan over prior mmu lsq inv md5 ltime gtime count first var dev med cov cor all any rand sums prds mins maxs fills deltas ratios avgs differ prev next rank reverse iasc idesc asc desc msum mcount mavg mdev xrank mmin mmax xprev rotate distinct group where flip type key til get value attr cut set upsert raze union inter except cross sv vs sublist enlist read0 read1 hopen hclose hdel hsym hcount peach system ltrim rtrim trim lower upper ssr view tables views cols xcols keys xkey xcol xasc xdesc fkeys meta lj aj aj0 ij pj asof uj ww wj wj1 fby xgroup ungroup ej save load rsave rload show csv parse eval min max avg wavg wsum sin cos tan sum","type":"`float `double int `timestamp `timespan `datetime `time `boolean `symbol `char `byte `short `long `real `month `date `minute `second `guid"},"lexemes":"(`?)[A-Za-z0-9_]+\\b","contains":[{"className":"comment","begin":"//","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0},{"className":"subst","begin":"\\\\[abfnrtv]\\|\\\\x[0-9a-fA-F]*\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]","relevance":0},{"className":"subst","begin":"\\\\[abfnrtv]\\|\\\\x[0-9a-fA-F]*\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]","relevance":0}]},{"className":"number","begin":"(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)","relevance":0}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/qml.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/qml.json new file mode 100644 index 00000000..0638b658 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/qml.json @@ -0,0 +1 @@ +{"aliases":["qt"],"case_insensitive":false,"keywords":{"keyword":"in of on if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const export super debugger as async await import","literal":"true false null undefined NaN Infinity","built_in":"eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError TypeError URIError Number Math Date String RegExp Array Float32Array Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require module console window document Symbol Set Map WeakSet WeakMap Proxy Reflect Behavior bool color coordinate date double enumeration font geocircle georectangle geoshape int list matrix4x4 parent point quaternion real rect size string url variant vector2d vector3d vector4dPromise"},"contains":[{"className":"meta","begin":"^\\s*['\"]use (strict|asm)['\"]"},{"className":"string","begin":"'","end":"'","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0}]},{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"$ref":"#contains.1.contains.0"},{"className":"subst","begin":"\\\\[abfnrtv]\\|\\\\x[0-9a-fA-F]*\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]","relevance":0},{"className":"subst","begin":"\\\\[abfnrtv]\\|\\\\x[0-9a-fA-F]*\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]","relevance":0}]},{"className":"string","begin":"`","end":"`","contains":[{"$ref":"#contains.1.contains.0"},{"className":"subst","begin":"\\$\\{","end":"\\}"}]},{"className":"comment","begin":"//","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"/\\*","end":"\\*/","contains":[{"$ref":"#contains.4.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"number","variants":[{"begin":"\\b(0[bB][01]+)"},{"begin":"\\b(0[oO][0-7]+)"},{"begin":"(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)"}],"relevance":0},{"begin":"(!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~|\\b(case|return|throw)\\b)\\s*","keywords":"return throw case","contains":[{"$ref":"#contains.4"},{"$ref":"#contains.5"},{"className":"regexp","begin":"\\/","end":"\\/[gimuy]*","illegal":"\\n","contains":[{"$ref":"#contains.1.contains.0"},{"begin":"\\[","end":"\\]","relevance":0,"contains":[{"$ref":"#contains.1.contains.0"}]}]},{"begin":"<","end":">\\s*[);\\]]","relevance":0,"subLanguage":"xml"}],"relevance":0},{"className":"keyword","begin":"\\bsignal\\b","starts":{"className":"string","end":"(\\(|:|=|;|,|//|/\\*|$)","returnEnd":true}},{"className":"keyword","begin":"\\bproperty\\b","starts":{"className":"string","end":"(:|=|;|,|//|/\\*|$)","returnEnd":true}},{"className":"function","beginKeywords":"function","end":"\\{","excludeEnd":true,"contains":[{"className":"title","begin":"[A-Za-z$_][0-9A-Za-z$_]*","relevance":0},{"className":"params","begin":"\\(","end":"\\)","excludeBegin":true,"excludeEnd":true,"contains":[{"$ref":"#contains.4"},{"$ref":"#contains.5"}]}],"illegal":"\\[|%"},{"begin":"\\.[a-zA-Z]\\w*","relevance":0},{"className":"attribute","begin":"\\bid\\s*:","starts":{"className":"string","end":"[a-zA-Z_][a-zA-Z0-9\\._]*","returnEnd":false}},{"begin":"[a-zA-Z_][a-zA-Z0-9\\._]*\\s*:","returnBegin":true,"contains":[{"className":"attribute","begin":"[a-zA-Z_][a-zA-Z0-9\\._]*","end":"\\s*:","excludeEnd":true,"relevance":0}],"relevance":0},{"begin":"[a-zA-Z_][a-zA-Z0-9\\._]*\\s*{","end":"{","returnBegin":true,"relevance":0,"contains":[{"className":"title","begin":"[a-zA-Z_][a-zA-Z0-9\\._]*","relevance":0}]}],"illegal":"#"} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/r.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/r.json new file mode 100644 index 00000000..706c97b6 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/r.json @@ -0,0 +1 @@ +{"contains":[{"className":"comment","begin":"#","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"begin":"([a-zA-Z]|\\.[a-zA-Z.])[a-zA-Z0-9._]*","lexemes":"([a-zA-Z]|\\.[a-zA-Z.])[a-zA-Z0-9._]*","keywords":{"keyword":"function if in break next repeat else for return switch while try tryCatch stop warning require library attach detach source setMethod setGeneric setGroupGeneric setClass ...","literal":"NULL NA TRUE FALSE T F Inf NaN NA_integer_|10 NA_real_|10 NA_character_|10 NA_complex_|10"},"relevance":0},{"className":"number","begin":"0[xX][0-9a-fA-F]+[Li]?\\b","relevance":0},{"className":"number","begin":"\\d+(?:[eE][+\\-]?\\d*)?L\\b","relevance":0},{"className":"number","begin":"\\d+\\.(?!\\d)(?:i\\b)?","relevance":0},{"className":"number","begin":"\\d+(?:\\.\\d*)?(?:[eE][+\\-]?\\d*)?i?\\b","relevance":0},{"className":"number","begin":"\\.\\d+(?:[eE][+\\-]?\\d*)?i?\\b","relevance":0},{"begin":"`","end":"`","relevance":0},{"className":"string","contains":[{"begin":"\\\\[\\s\\S]","relevance":0}],"variants":[{"begin":"\"","end":"\""},{"begin":"'","end":"'"}]}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/reasonml.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/reasonml.json new file mode 100644 index 00000000..f13d675e --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/reasonml.json @@ -0,0 +1 @@ +{"aliases":["re"],"keywords":{"keyword":"and as asr assert begin class constraint do done downto else end exception externalfor fun function functor if in include inherit initializerland lazy let lor lsl lsr lxor match method mod module mutable new nonrecobject of open or private rec sig struct then to try type val virtual when while with","built_in":"array bool bytes char exn|5 float int int32 int64 list lazy_t|5 nativeint|5 ref string unit ","literal":"true false"},"illegal":"(:\\-|:=|\\${|\\+=)","contains":[{"className":"comment","begin":"/\\*","end":"\\*/","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}],"illegal":"^(\\#,\\/\\/)"},{"className":"character","begin":"'(\\\\[^']+|[^'])'","illegal":"\\n","relevance":0},{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0},{"className":"subst","begin":"\\\\[abfnrtv]\\|\\\\x[0-9a-fA-F]*\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]","relevance":0},{"className":"subst","begin":"\\\\[abfnrtv]\\|\\\\x[0-9a-fA-F]*\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]","relevance":0}]},{"className":"literal","begin":"\\(\\)","relevance":0},{"className":"literal","begin":"\\[\\|","end":"\\|\\]","relevance":0,"contains":[{"className":"identifier","relevance":0,"begin":"~?[a-z$_][0-9a-zA-Z$_]*"},{"className":"operator","relevance":0,"begin":"(\\|\\||\\&\\&|\\+\\+|\\*\\*|\\+\\.|\\*|\\/|\\*\\.|\\/\\.|\\.\\.\\.|\\|\\>|==|===)"},{"className":"number","relevance":0,"variants":[{"begin":"\\b(0[xX][a-fA-F0-9_]+[Lln]?|0[oO][0-7_]+[Lln]?|0[bB][01_]+[Lln]?|[0-9][0-9_]*([Lln]|(\\.[0-9_]*)?([eE][-+]?[0-9_]+)?)?)"},{"begin":"\\(\\-\\b(0[xX][a-fA-F0-9_]+[Lln]?|0[oO][0-7_]+[Lln]?|0[bB][01_]+[Lln]?|[0-9][0-9_]*([Lln]|(\\.[0-9_]*)?([eE][-+]?[0-9_]+)?)?)\\)"}]}]},{"className":"literal","begin":"\\[","end":"\\]","relevance":0,"contains":{"$ref":"#contains.4.contains"}},{"className":"constructor","begin":"`?[A-Z$_][0-9a-zA-Z$_]*\\(","end":"\\)","illegal":"\\n","keywords":{"$ref":"#keywords"},"contains":[{"$ref":"#contains.2"},{"$ref":"#contains.4.contains.1"},{"className":"params","begin":"\\b~?[a-z$_][0-9a-zA-Z$_]*"}]},{"className":"operator","begin":"\\s+(\\|\\||\\&\\&|\\+\\+|\\*\\*|\\+\\.|\\*|\\/|\\*\\.|\\/\\.|\\.\\.\\.|\\|\\>|==|===)\\s+","illegal":"\\-\\->","relevance":0},{"$ref":"#contains.4.contains.2"},{"className":"comment","begin":"//","end":"$","contains":[{"$ref":"#contains.0.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"pattern-match","begin":"\\|","returnBegin":true,"keywords":{"$ref":"#keywords"},"end":"=>","relevance":0,"contains":[{"$ref":"#contains.6"},{"$ref":"#contains.4.contains.1"},{"relevance":0,"className":"constructor","begin":"`?[A-Z$_][0-9a-zA-Z$_]*"}]},{"className":"function","relevance":0,"keywords":{"$ref":"#keywords"},"variants":[{"begin":"\\s(\\(\\.?.*?\\)|~?[a-z$_][0-9a-zA-Z$_]*)\\s*=>","end":"\\s*=>","returnBegin":true,"relevance":0,"contains":[{"className":"params","variants":[{"begin":"~?[a-z$_][0-9a-zA-Z$_]*"},{"begin":"~?[a-z$_][0-9a-zA-Z$_]*(s*:s*[a-z$_][0-9a-z$_]*((s*('?[a-z$_][0-9a-z$_]*s*(,'?[a-z$_][0-9a-z$_]*)*)?s*))?)?(s*:s*[a-z$_][0-9a-z$_]*((s*('?[a-z$_][0-9a-z$_]*s*(,'?[a-z$_][0-9a-z$_]*)*)?s*))?)?"},{"begin":"\\(\\s*\\)"}]}]},{"begin":"\\s\\(\\.?[^;\\|]*\\)\\s*=>","end":"\\s=>","returnBegin":true,"relevance":0,"contains":[{"className":"params","relevance":0,"variants":[{"begin":"~?[a-z$_][0-9a-zA-Z$_]*","end":"(,|\\n|\\))","relevance":0,"contains":[{"$ref":"#contains.4.contains.1"},{"className":"typing","begin":":","end":"(,|\\n)","returnBegin":true,"relevance":0,"contains":[{"className":"module","begin":"\\b`?[A-Z$_][0-9a-zA-Z$_]*","returnBegin":true,"end":".","relevance":0,"contains":[{"className":"identifier","begin":"`?[A-Z$_][0-9a-zA-Z$_]*","relevance":0}]},{"className":"module-access","keywords":{"$ref":"#keywords"},"returnBegin":true,"variants":[{"begin":"\\b(`?[A-Z$_][0-9a-zA-Z$_]*\\.)+~?[a-z$_][0-9a-zA-Z$_]*"},{"begin":"\\b(`?[A-Z$_][0-9a-zA-Z$_]*\\.)+\\(","end":"\\)","returnBegin":true,"contains":[{"$ref":"#contains.11"},{"begin":"\\(","end":"\\)","skip":true},{"$ref":"#contains.2"},{"$ref":"#contains.4.contains.1"},{"className":"module","begin":"\\b`?[A-Z$_][0-9a-zA-Z$_]*","returnBegin":true,"end":".","contains":[{"className":"identifier","begin":"`?[A-Z$_][0-9a-zA-Z$_]*","relevance":0}]},{"$ref":"#contains.11"}]},{"begin":"\\b(`?[A-Z$_][0-9a-zA-Z$_]*\\.)+{","end":"}"}],"contains":[{"$ref":"#contains.2"},{"$ref":"#contains.4.contains.1"},{"$ref":"#contains.11.variants.1.contains.0.variants.0.contains.1.contains.1.variants.1.contains.4"},{"$ref":"#contains.11"}]}]}]}]}]},{"begin":"\\(\\.\\s~?[a-z$_][0-9a-zA-Z$_]*\\)\\s*=>"}]},{"className":"module-def","begin":"\\bmodule\\s+~?[a-z$_][0-9a-zA-Z$_]*\\s+`?[A-Z$_][0-9a-zA-Z$_]*\\s+=\\s+{","end":"}","returnBegin":true,"keywords":{"$ref":"#keywords"},"relevance":0,"contains":[{"className":"module","relevance":0,"begin":"`?[A-Z$_][0-9a-zA-Z$_]*"},{"begin":"{","end":"}","skip":true},{"$ref":"#contains.2"},{"$ref":"#contains.4.contains.1"},{"$ref":"#contains.11.variants.1.contains.0.variants.0.contains.1.contains.1.variants.1.contains.4"},{"$ref":"#contains.11"}]},{"$ref":"#contains.11.variants.1.contains.0.variants.0.contains.1.contains.1"}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/rib.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/rib.json new file mode 100644 index 00000000..76cdb25c --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/rib.json @@ -0,0 +1 @@ +{"keywords":"ArchiveRecord AreaLightSource Atmosphere Attribute AttributeBegin AttributeEnd Basis Begin Blobby Bound Clipping ClippingPlane Color ColorSamples ConcatTransform Cone CoordinateSystem CoordSysTransform CropWindow Curves Cylinder DepthOfField Detail DetailRange Disk Displacement Display End ErrorHandler Exposure Exterior Format FrameAspectRatio FrameBegin FrameEnd GeneralPolygon GeometricApproximation Geometry Hider Hyperboloid Identity Illuminate Imager Interior LightSource MakeCubeFaceEnvironment MakeLatLongEnvironment MakeShadow MakeTexture Matte MotionBegin MotionEnd NuPatch ObjectBegin ObjectEnd ObjectInstance Opacity Option Orientation Paraboloid Patch PatchMesh Perspective PixelFilter PixelSamples PixelVariance Points PointsGeneralPolygons PointsPolygons Polygon Procedural Projection Quantize ReadArchive RelativeDetail ReverseOrientation Rotate Scale ScreenWindow ShadingInterpolation ShadingRate Shutter Sides Skew SolidBegin SolidEnd Sphere SubdivisionMesh Surface TextureCoordinates Torus Transform TransformBegin TransformEnd TransformPoints Translate TrimCurve WorldBegin WorldEnd","illegal":"\\]$"},{"begin":"<\\/","end":">"},{"begin":"^facet ","end":"\\}"},{"begin":"^1\\.\\.(\\d+)$","end":"$"}],"illegal":"."},{"className":"comment","begin":"^#","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"string","begin":"\"","end":"\"","contains":[{"begin":"\\\\[\\s\\S]","relevance":0},{"className":"variable","variants":[{"begin":"\\$[\\w\\d#@][\\w\\d_]*"},{"begin":"\\$\\{(.*?)}"}]},{"className":"variable","begin":"\\$\\(","end":"\\)","contains":[{"$ref":"#contains.2.contains.0"}]}]},{"className":"string","begin":"'","end":"'"},{"$ref":"#contains.2.contains.1"},{"begin":"[\\w-]+\\=([^\\s\\{\\}\\[\\]\\(\\)]+)","relevance":0,"returnBegin":true,"contains":[{"className":"attribute","begin":"[^=]+"},{"begin":"=","endsWithParent":true,"relevance":0,"contains":[{"$ref":"#contains.2"},{"$ref":"#contains.3"},{"$ref":"#contains.2.contains.1"},{"className":"literal","begin":"\\b(true|false|yes|no|nothing|nil|null)\\b"},{"begin":"(\"[^\"]*\"|[^\\s\\{\\}\\[\\]]+)"}]}]},{"className":"number","begin":"\\*[0-9a-fA-F]+"},{"begin":"\\b(add|remove|enable|disable|set|get|print|export|edit|find|run|debug|error|info|warning)([\\s[(]|])","returnBegin":true,"contains":[{"className":"builtin-name","begin":"\\w+"}]},{"className":"built_in","variants":[{"begin":"(\\.\\./|/|\\s)((traffic-flow|traffic-generator|firewall|scheduler|aaa|accounting|address-list|address|align|area|bandwidth-server|bfd|bgp|bridge|client|clock|community|config|connection|console|customer|default|dhcp-client|dhcp-server|discovery|dns|e-mail|ethernet|filter|firewall|firmware|gps|graphing|group|hardware|health|hotspot|identity|igmp-proxy|incoming|instance|interface|ip|ipsec|ipv6|irq|l2tp-server|lcd|ldp|logging|mac-server|mac-winbox|mangle|manual|mirror|mme|mpls|nat|nd|neighbor|network|note|ntp|ospf|ospf-v3|ovpn-server|page|peer|pim|ping|policy|pool|port|ppp|pppoe-client|pptp-server|prefix|profile|proposal|proxy|queue|radius|resource|rip|ripng|route|routing|screen|script|security-profiles|server|service|service-port|settings|shares|smb|sms|sniffer|snmp|snooper|socks|sstp-server|system|tool|tracking|type|upgrade|upnp|user-manager|users|user|vlan|secret|vrrp|watchdog|web-access|wireless|pptp|pppoe|lan|wan|layer7-protocol|lease|simple|raw);?\\s)+","relevance":10},{"begin":"\\.\\."}]}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/rsl.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/rsl.json new file mode 100644 index 00000000..2738a1d5 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/rsl.json @@ -0,0 +1 @@ +{"keywords":{"keyword":"float color point normal vector matrix while for if do return else break extern continue","built_in":"abs acos ambient area asin atan atmosphere attribute calculatenormal ceil cellnoise clamp comp concat cos degrees depth Deriv diffuse distance Du Dv environment exp faceforward filterstep floor format fresnel incident length lightsource log match max min mod noise normalize ntransform opposite option phong pnoise pow printf ptlined radians random reflect refract renderinfo round setcomp setxcomp setycomp setzcomp shadow sign sin smoothstep specular specularbrdf spline sqrt step tan texture textureinfo trace transform vtransform xcomp ycomp zcomp"},"illegal":"","starts":{"end":"$","contains":[{"className":"string","contains":[{"begin":"\\\\[\\s\\S]","relevance":0},{"className":"subst","begin":"#\\{","end":"}","keywords":{"$ref":"#keywords"},"contains":{"$ref":"#contains.3.starts.contains"}}],"variants":[{"begin":"'","end":"'"},{"begin":"\"","end":"\""},{"begin":"`","end":"`"},{"begin":"%[qQwWx]?\\(","end":"\\)"},{"begin":"%[qQwWx]?\\[","end":"\\]"},{"begin":"%[qQwWx]?{","end":"}"},{"begin":"%[qQwWx]?<","end":">"},{"begin":"%[qQwWx]?/","end":"/"},{"begin":"%[qQwWx]?%","end":"%"},{"begin":"%[qQwWx]?-","end":"-"},{"begin":"%[qQwWx]?\\|","end":"\\|"},{"begin":"\\B\\?(\\\\\\d{1,3}|\\\\x[A-Fa-f0-9]{1,2}|\\\\u[A-Fa-f0-9]{4}|\\\\?\\S)\\b"},{"begin":"<<[-~]?'?(\\w+)(?:.|\\n)*?\\n\\s*\\1\\b","returnBegin":true,"contains":[{"begin":"<<[-~]?'?"},{"begin":"\\w+","endSameAsBegin":true,"contains":[{"$ref":"#contains.3.starts.contains.0.contains.0"},{"$ref":"#contains.3.starts.contains.0.contains.1"}]}]}]},{"begin":"#<","end":">"},{"className":"class","beginKeywords":"class module","end":"$|;","illegal":"=","contains":[{"className":"title","begin":"[A-Za-z_]\\w*(::\\w+)*(\\?|\\!)?","relevance":0},{"begin":"<\\s*","contains":[{"begin":"([a-zA-Z]\\w*::)?[a-zA-Z]\\w*"}]},{"$ref":"#contains.0"},{"$ref":"#contains.1"},{"$ref":"#contains.2"}]},{"className":"function","beginKeywords":"def","end":"$|;","contains":[{"className":"title","begin":"[a-zA-Z_]\\w*[!?=]?|[-+~]\\@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?","relevance":0},{"className":"params","begin":"\\(","end":"\\)","endsParent":true,"keywords":{"$ref":"#keywords"},"contains":{"$ref":"#contains.3.starts.contains"}},{"$ref":"#contains.0"},{"$ref":"#contains.1"},{"$ref":"#contains.2"}]},{"begin":"[a-zA-Z]\\w*::"},{"className":"symbol","begin":"[a-zA-Z_]\\w*(\\!|\\?)?:","relevance":0},{"className":"symbol","begin":":(?!\\s)","contains":[{"$ref":"#contains.3.starts.contains.0"},{"begin":"[a-zA-Z_]\\w*[!?=]?|[-+~]\\@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?"}],"relevance":0},{"className":"number","begin":"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b","relevance":0},{"begin":"(\\$\\W)|((\\$|\\@\\@?)(\\w+))"},{"className":"params","begin":"\\|","end":"\\|","keywords":{"$ref":"#keywords"}},{"begin":"(!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~|unless)\\s*","keywords":"unless","contains":[{"$ref":"#contains.3.starts.contains.1"},{"className":"regexp","contains":[{"$ref":"#contains.3.starts.contains.0.contains.0"},{"$ref":"#contains.3.starts.contains.0.contains.1"}],"illegal":"\\n","variants":[{"begin":"/","end":"/[a-z]*"},{"begin":"%r{","end":"}[a-z]*"},{"begin":"%r\\(","end":"\\)[a-z]*"},{"begin":"%r!","end":"![a-z]*"},{"begin":"%r\\[","end":"\\][a-z]*"}]},{"$ref":"#contains.0"},{"$ref":"#contains.1"},{"$ref":"#contains.2"}],"relevance":0},{"$ref":"#contains.0"},{"$ref":"#contains.1"},{"$ref":"#contains.2"}]}},{"className":"meta","begin":"^([>?]>|[\\w#]+\\(\\w+\\):\\d+:\\d+>|(\\w+-)?\\d+\\.\\d+\\.\\d(p\\d+)?[^>]+>)","starts":{"end":"$","contains":{"$ref":"#contains.3.starts.contains"}}},{"$ref":"#contains.3.starts.contains.0"},{"$ref":"#contains.3.starts.contains.1"},{"$ref":"#contains.3.starts.contains.2"},{"$ref":"#contains.3.starts.contains.3"},{"$ref":"#contains.3.starts.contains.4"},{"$ref":"#contains.3.starts.contains.5"},{"$ref":"#contains.3.starts.contains.6"},{"$ref":"#contains.3.starts.contains.7"},{"$ref":"#contains.3.starts.contains.8"},{"$ref":"#contains.3.starts.contains.9"},{"$ref":"#contains.3.starts.contains.10"},{"$ref":"#contains.0"},{"$ref":"#contains.1"},{"$ref":"#contains.2"}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/ruleslanguage.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/ruleslanguage.json new file mode 100644 index 00000000..42fb8dd0 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/ruleslanguage.json @@ -0,0 +1 @@ +{"keywords":{"keyword":"BILL_PERIOD BILL_START BILL_STOP RS_EFFECTIVE_START RS_EFFECTIVE_STOP RS_JURIS_CODE RS_OPCO_CODE INTDADDATTRIBUTE|5 INTDADDVMSG|5 INTDBLOCKOP|5 INTDBLOCKOPNA|5 INTDCLOSE|5 INTDCOUNT|5 INTDCOUNTSTATUSCODE|5 INTDCREATEMASK|5 INTDCREATEDAYMASK|5 INTDCREATEFACTORMASK|5 INTDCREATEHANDLE|5 INTDCREATEOVERRIDEDAYMASK|5 INTDCREATEOVERRIDEMASK|5 INTDCREATESTATUSCODEMASK|5 INTDCREATETOUPERIOD|5 INTDDELETE|5 INTDDIPTEST|5 INTDEXPORT|5 INTDGETERRORCODE|5 INTDGETERRORMESSAGE|5 INTDISEQUAL|5 INTDJOIN|5 INTDLOAD|5 INTDLOADACTUALCUT|5 INTDLOADDATES|5 INTDLOADHIST|5 INTDLOADLIST|5 INTDLOADLISTDATES|5 INTDLOADLISTENERGY|5 INTDLOADLISTHIST|5 INTDLOADRELATEDCHANNEL|5 INTDLOADSP|5 INTDLOADSTAGING|5 INTDLOADUOM|5 INTDLOADUOMDATES|5 INTDLOADUOMHIST|5 INTDLOADVERSION|5 INTDOPEN|5 INTDREADFIRST|5 INTDREADNEXT|5 INTDRECCOUNT|5 INTDRELEASE|5 INTDREPLACE|5 INTDROLLAVG|5 INTDROLLPEAK|5 INTDSCALAROP|5 INTDSCALE|5 INTDSETATTRIBUTE|5 INTDSETDSTPARTICIPANT|5 INTDSETSTRING|5 INTDSETVALUE|5 INTDSETVALUESTATUS|5 INTDSHIFTSTARTTIME|5 INTDSMOOTH|5 INTDSORT|5 INTDSPIKETEST|5 INTDSUBSET|5 INTDTOU|5 INTDTOURELEASE|5 INTDTOUVALUE|5 INTDUPDATESTATS|5 INTDVALUE|5 STDEV INTDDELETEEX|5 INTDLOADEXACTUAL|5 INTDLOADEXCUT|5 INTDLOADEXDATES|5 INTDLOADEX|5 INTDLOADEXRELATEDCHANNEL|5 INTDSAVEEX|5 MVLOAD|5 MVLOADACCT|5 MVLOADACCTDATES|5 MVLOADACCTHIST|5 MVLOADDATES|5 MVLOADHIST|5 MVLOADLIST|5 MVLOADLISTDATES|5 MVLOADLISTHIST|5 IF FOR NEXT DONE SELECT END CALL ABORT CLEAR CHANNEL FACTOR LIST NUMBER OVERRIDE SET WEEK DISTRIBUTIONNODE ELSE WHEN THEN OTHERWISE IENUM CSV INCLUDE LEAVE RIDER SAVE DELETE NOVALUE SECTION WARN SAVE_UPDATE DETERMINANT LABEL REPORT REVENUE EACH IN FROM TOTAL CHARGE BLOCK AND OR CSV_FILE RATE_CODE AUXILIARY_DEMAND UIDACCOUNT RS BILL_PERIOD_SELECT HOURS_PER_MONTH INTD_ERROR_STOP SEASON_SCHEDULE_NAME ACCOUNTFACTOR ARRAYUPPERBOUND CALLSTOREDPROC GETADOCONNECTION GETCONNECT GETDATASOURCE GETQUALIFIER GETUSERID HASVALUE LISTCOUNT LISTOP LISTUPDATE LISTVALUE PRORATEFACTOR RSPRORATE SETBINPATH SETDBMONITOR WQ_OPEN BILLINGHOURS DATE DATEFROMFLOAT DATETIMEFROMSTRING DATETIMETOSTRING DATETOFLOAT DAY DAYDIFF DAYNAME DBDATETIME HOUR MINUTE MONTH MONTHDIFF MONTHHOURS MONTHNAME ROUNDDATE SAMEWEEKDAYLASTYEAR SECOND WEEKDAY WEEKDIFF YEAR YEARDAY YEARSTR COMPSUM HISTCOUNT HISTMAX HISTMIN HISTMINNZ HISTVALUE MAXNRANGE MAXRANGE MINRANGE COMPIKVA COMPKVA COMPKVARFROMKQKW COMPLF IDATTR FLAG LF2KW LF2KWH MAXKW POWERFACTOR READING2USAGE AVGSEASON MAXSEASON MONTHLYMERGE SEASONVALUE SUMSEASON ACCTREADDATES ACCTTABLELOAD CONFIGADD CONFIGGET CREATEOBJECT CREATEREPORT EMAILCLIENT EXPBLKMDMUSAGE EXPMDMUSAGE EXPORT_USAGE FACTORINEFFECT GETUSERSPECIFIEDSTOP INEFFECT ISHOLIDAY RUNRATE SAVE_PROFILE SETREPORTTITLE USEREXIT WATFORRUNRATE TO TABLE ACOS ASIN ATAN ATAN2 BITAND CEIL COS COSECANT COSH COTANGENT DIVQUOT DIVREM EXP FABS FLOOR FMOD FREPM FREXPN LOG LOG10 MAX MAXN MIN MINNZ MODF POW ROUND ROUND2VALUE ROUNDINT SECANT SIN SINH SQROOT TAN TANH FLOAT2STRING FLOAT2STRINGNC INSTR LEFT LEN LTRIM MID RIGHT RTRIM STRING STRINGNC TOLOWER TOUPPER TRIM NUMDAYS READ_DATE STAGING","built_in":"IDENTIFIER OPTIONS XML_ELEMENT XML_OP XML_ELEMENT_OF DOMDOCCREATE DOMDOCLOADFILE DOMDOCLOADXML DOMDOCSAVEFILE DOMDOCGETROOT DOMDOCADDPI DOMNODEGETNAME DOMNODEGETTYPE DOMNODEGETVALUE DOMNODEGETCHILDCT DOMNODEGETFIRSTCHILD DOMNODEGETSIBLING DOMNODECREATECHILDELEMENT DOMNODESETATTRIBUTE DOMNODEGETCHILDELEMENTCT DOMNODEGETFIRSTCHILDELEMENT DOMNODEGETSIBLINGELEMENT DOMNODEGETATTRIBUTECT DOMNODEGETATTRIBUTEI DOMNODEGETATTRIBUTEBYNAME DOMNODEGETBYNAME"},"contains":[{"className":"comment","begin":"//","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"/\\*","end":"\\*/","contains":[{"$ref":"#contains.0.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"string","begin":"'","end":"'","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0}]},{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"$ref":"#contains.2.contains.0"},{"className":"subst","begin":"\\\\[abfnrtv]\\|\\\\x[0-9a-fA-F]*\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]","relevance":0},{"className":"subst","begin":"\\\\[abfnrtv]\\|\\\\x[0-9a-fA-F]*\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]","relevance":0}]},{"className":"number","begin":"(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)","relevance":0},{"className":"literal","variants":[{"begin":"#\\s+[a-zA-Z\\ \\.]*","relevance":0},{"begin":"#[a-zA-Z\\ \\.]+"}]}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/rust.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/rust.json new file mode 100644 index 00000000..b05c020d --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/rust.json @@ -0,0 +1 @@ +{"aliases":["rs"],"keywords":{"keyword":"abstract as async await become box break const continue crate do dyn else enum extern false final fn for if impl in let loop macro match mod move mut override priv pub ref return self Self static struct super trait true try type typeof unsafe unsized use virtual where while yield","literal":"true false Some None Ok Err","built_in":"drop i8 i16 i32 i64 i128 isize u8 u16 u32 u64 u128 usize f32 f64 str char bool Box Option Result String Vec Copy Send Sized Sync Drop Fn FnMut FnOnce ToOwned Clone Debug PartialEq PartialOrd Eq Ord AsRef AsMut Into From Default Iterator Extend IntoIterator DoubleEndedIterator ExactSizeIterator SliceConcatExt ToString assert! assert_eq! bitflags! bytes! cfg! col! concat! concat_idents! debug_assert! debug_assert_eq! env! panic! file! format! format_args! include_bin! include_str! line! local_data_key! module_path! option_env! print! println! select! stringify! try! unimplemented! unreachable! vec! write! writeln! macro_rules! assert_ne! debug_assert_ne!"},"lexemes":"[a-zA-Z]\\w*!?","illegal":""}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/sas.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/sas.json new file mode 100644 index 00000000..612a6e9b --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/sas.json @@ -0,0 +1 @@ +{"aliases":["sas","SAS"],"case_insensitive":true,"keywords":{"literal":"null missing _all_ _automatic_ _character_ _infile_ _n_ _name_ _null_ _numeric_ _user_ _webout_","meta":"do if then else end until while abort array attrib by call cards cards4 catname continue datalines datalines4 delete delim delimiter display dm drop endsas error file filename footnote format goto in infile informat input keep label leave length libname link list lostcard merge missing modify options output out page put redirect remove rename replace retain return select set skip startsas stop title update waitsas where window x systask add and alter as cascade check create delete describe distinct drop foreign from group having index insert into in key like message modify msgtype not null on or order primary references reset restrict select set table unique update validate view where"},"contains":[{"className":"keyword","begin":"^\\s*(proc [\\w\\d_]+|data|run|quit)[\\s\\;]"},{"className":"variable","begin":"\\&[a-zA-Z_\\&][a-zA-Z0-9_]*\\.?"},{"className":"emphasis","begin":"^\\s*datalines|cards.*;","end":"^\\s*;\\s*$"},{"className":"built_in","begin":"%(bquote|nrbquote|cmpres|qcmpres|compstor|datatyp|display|do|else|end|eval|global|goto|if|index|input|keydef|label|left|length|let|local|lowcase|macro|mend|nrbquote|nrquote|nrstr|put|qcmpres|qleft|qlowcase|qscan|qsubstr|qsysfunc|qtrim|quote|qupcase|scan|str|substr|superq|syscall|sysevalf|sysexec|sysfunc|sysget|syslput|sysprod|sysrc|sysrput|then|to|trim|unquote|until|upcase|verify|while|window)"},{"className":"name","begin":"%[a-zA-Z_][a-zA-Z_0-9]*"},{"className":"meta","begin":"[^%](abs|addr|airy|arcos|arsin|atan|attrc|attrn|band|betainv|blshift|bnot|bor|brshift|bxor|byte|cdf|ceil|cexist|cinv|close|cnonct|collate|compbl|compound|compress|cos|cosh|css|curobs|cv|daccdb|daccdbsl|daccsl|daccsyd|dacctab|dairy|date|datejul|datepart|datetime|day|dclose|depdb|depdbsl|depdbsl|depsl|depsl|depsyd|depsyd|deptab|deptab|dequote|dhms|dif|digamma|dim|dinfo|dnum|dopen|doptname|doptnum|dread|dropnote|dsname|erf|erfc|exist|exp|fappend|fclose|fcol|fdelete|fetch|fetchobs|fexist|fget|fileexist|filename|fileref|finfo|finv|fipname|fipnamel|fipstate|floor|fnonct|fnote|fopen|foptname|foptnum|fpoint|fpos|fput|fread|frewind|frlen|fsep|fuzz|fwrite|gaminv|gamma|getoption|getvarc|getvarn|hbound|hms|hosthelp|hour|ibessel|index|indexc|indexw|input|inputc|inputn|int|intck|intnx|intrr|irr|jbessel|juldate|kurtosis|lag|lbound|left|length|lgamma|libname|libref|log|log10|log2|logpdf|logpmf|logsdf|lowcase|max|mdy|mean|min|minute|mod|month|mopen|mort|n|netpv|nmiss|normal|note|npv|open|ordinal|pathname|pdf|peek|peekc|pmf|point|poisson|poke|probbeta|probbnml|probchi|probf|probgam|probhypr|probit|probnegb|probnorm|probt|put|putc|putn|qtr|quote|ranbin|rancau|ranexp|rangam|range|rank|rannor|ranpoi|rantbl|rantri|ranuni|repeat|resolve|reverse|rewind|right|round|saving|scan|sdf|second|sign|sin|sinh|skewness|soundex|spedis|sqrt|std|stderr|stfips|stname|stnamel|substr|sum|symget|sysget|sysmsg|sysprod|sysrc|system|tan|tanh|time|timepart|tinv|tnonct|today|translate|tranwrd|trigamma|trim|trimn|trunc|uniform|upcase|uss|var|varfmt|varinfmt|varlabel|varlen|varname|varnum|varray|varrayx|vartype|verify|vformat|vformatd|vformatdx|vformatn|vformatnx|vformatw|vformatwx|vformatx|vinarray|vinarrayx|vinformat|vinformatd|vinformatdx|vinformatn|vinformatnx|vinformatw|vinformatwx|vinformatx|vlabel|vlabelx|vlength|vlengthx|vname|vnamex|vtype|vtypex|weekday|year|yyq|zipfips|zipname|zipnamel|zipstate)[(]"},{"className":"string","variants":[{"className":"string","begin":"'","end":"'","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0}]},{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"$ref":"#contains.6.variants.0.contains.0"},{"className":"subst","begin":"\\\\[abfnrtv]\\|\\\\x[0-9a-fA-F]*\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]","relevance":0},{"className":"subst","begin":"\\\\[abfnrtv]\\|\\\\x[0-9a-fA-F]*\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]","relevance":0}]}]},{"className":"comment","begin":"\\*","end":";","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"/\\*","end":"\\*/","contains":[{"$ref":"#contains.7.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/scala.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/scala.json new file mode 100644 index 00000000..575f0549 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/scala.json @@ -0,0 +1 @@ +{"keywords":{"literal":"true false null","keyword":"type yield lazy override def with val var sealed abstract private trait object if forSome for while throw finally protected extends import final return else break new catch super class case package default try this match continue throws implicit"},"contains":[{"className":"comment","begin":"//","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"/\\*","end":"\\*/","contains":[{"$ref":"#contains.0.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"string","variants":[{"begin":"\"","end":"\"","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0}]},{"begin":"\"\"\"","end":"\"\"\"","relevance":10},{"begin":"[a-z]+\"","end":"\"","illegal":"\\n","contains":[{"$ref":"#contains.2.variants.0.contains.0"},{"className":"subst","variants":[{"begin":"\\$[A-Za-z0-9_]+"},{"begin":"\\${","end":"}"}]}]},{"className":"string","begin":"[a-z]+\"\"\"","end":"\"\"\"","contains":[{"$ref":"#contains.2.variants.2.contains.1"}],"relevance":10}]},{"className":"symbol","begin":"'\\w[\\w\\d_]*(?!')"},{"className":"type","begin":"\\b[A-Z][A-Za-z0-9_]*","relevance":0},{"className":"function","beginKeywords":"def","end":"[:={\\[(\\n;]","excludeEnd":true,"contains":[{"className":"title","begin":"[^0-9\\n\\t \"'(),.`{}\\[\\]:;][^\\n\\t \"'(),.`{}\\[\\]:;]+|[^0-9\\n\\t \"'(),.`{}\\[\\]:;=]","relevance":0}]},{"className":"class","beginKeywords":"class object trait type","end":"[:={\\[\\n;]","excludeEnd":true,"contains":[{"beginKeywords":"extends with","relevance":10},{"begin":"\\[","end":"\\]","excludeBegin":true,"excludeEnd":true,"relevance":0,"contains":[{"$ref":"#contains.4"}]},{"className":"params","begin":"\\(","end":"\\)","excludeBegin":true,"excludeEnd":true,"relevance":0,"contains":[{"$ref":"#contains.4"}]},{"$ref":"#contains.5.contains.0"}]},{"className":"number","begin":"(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)","relevance":0},{"className":"meta","begin":"@[A-Za-z]+"}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/scheme.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/scheme.json new file mode 100644 index 00000000..97d55cbe --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/scheme.json @@ -0,0 +1 @@ +{"illegal":"\\S","contains":[{"className":"meta","begin":"^#!","end":"$"},{"className":"number","variants":[{"begin":"(\\-|\\+)?\\d+([./]\\d+)?","relevance":0},{"begin":"(\\-|\\+)?\\d+([./]\\d+)?[+\\-](\\-|\\+)?\\d+([./]\\d+)?i","relevance":0},{"begin":"#b[0-1]+(/[0-1]+)?"},{"begin":"#o[0-7]+(/[0-7]+)?"},{"begin":"#x[0-9a-f]+(/[0-9a-f]+)?"}]},{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0},{"className":"subst","begin":"\\\\[abfnrtv]\\|\\\\x[0-9a-fA-F]*\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]","relevance":0},{"className":"subst","begin":"\\\\[abfnrtv]\\|\\\\x[0-9a-fA-F]*\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]","relevance":0}]},{"className":"symbol","begin":"'[^\\(\\)\\[\\]\\{\\}\",'`;#|\\\\\\s]+"},{"variants":[{"begin":"'"},{"begin":"`"}],"contains":[{"begin":"\\(","end":"\\)","contains":["self",{"className":"literal","begin":"(#t|#f|#\\\\[^\\(\\)\\[\\]\\{\\}\",'`;#|\\\\\\s]+|#\\\\.)"},{"$ref":"#contains.2"},{"$ref":"#contains.1"},{"begin":"[^\\(\\)\\[\\]\\{\\}\",'`;#|\\\\\\s]+","relevance":0},{"$ref":"#contains.3"}]}]},{"variants":[{"begin":"\\(","end":"\\)"},{"begin":"\\[","end":"\\]"}],"contains":[{"begin":"lambda","endsWithParent":true,"returnBegin":true,"contains":[{"className":"name","begin":"[^\\(\\)\\[\\]\\{\\}\",'`;#|\\\\\\s]+","lexemes":"[^\\(\\)\\[\\]\\{\\}\",'`;#|\\\\\\s]+","keywords":{"builtin-name":"case-lambda call/cc class define-class exit-handler field import inherit init-field interface let*-values let-values let/ec mixin opt-lambda override protect provide public rename require require-for-syntax syntax syntax-case syntax-error unit/sig unless when with-syntax and begin call-with-current-continuation call-with-input-file call-with-output-file case cond define define-syntax delay do dynamic-wind else for-each if lambda let let* let-syntax letrec letrec-syntax map or syntax-rules ' * + , ,@ - ... / ; < <= = => > >= ` abs acos angle append apply asin assoc assq assv atan boolean? caar cadr call-with-input-file call-with-output-file call-with-values car cdddar cddddr cdr ceiling char->integer char-alphabetic? char-ci<=? char-ci=? char-ci>? char-downcase char-lower-case? char-numeric? char-ready? char-upcase char-upper-case? char-whitespace? char<=? char=? char>? char? close-input-port close-output-port complex? cons cos current-input-port current-output-port denominator display eof-object? eq? equal? eqv? eval even? exact->inexact exact? exp expt floor force gcd imag-part inexact->exact inexact? input-port? integer->char integer? interaction-environment lcm length list list->string list->vector list-ref list-tail list? load log magnitude make-polar make-rectangular make-string make-vector max member memq memv min modulo negative? newline not null-environment null? number->string number? numerator odd? open-input-file open-output-file output-port? pair? peek-char port? positive? procedure? quasiquote quote quotient rational? rationalize read read-char real-part real? remainder reverse round scheme-report-environment set! set-car! set-cdr! sin sqrt string string->list string->number string->symbol string-append string-ci<=? string-ci=? string-ci>? string-copy string-fill! string-length string-ref string-set! string<=? string=? string>? string? substring symbol->string symbol? tan transcript-off transcript-on truncate values vector vector->list vector-fill! vector-length vector-ref vector-set! with-input-from-file with-output-to-file write write-char zero?"}},{"begin":"\\(","end":"\\)","endsParent":true,"contains":[{"$ref":"#contains.4.contains.0.contains.4"}]}]},{"$ref":"#contains.5.contains.0.contains.0"},{"endsWithParent":true,"relevance":0,"contains":[{"$ref":"#contains.4.contains.0.contains.1"},{"$ref":"#contains.1"},{"$ref":"#contains.2"},{"$ref":"#contains.4.contains.0.contains.4"},{"$ref":"#contains.3"},{"$ref":"#contains.4"},{"$ref":"#contains.5"},{"className":"comment","begin":";","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}],"relevance":0},{"className":"comment","begin":"#\\|","end":"\\|#","contains":[{"$ref":"#contains.5.contains.2.contains.7.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]}]}]},{"$ref":"#contains.5.contains.2.contains.7"},{"$ref":"#contains.5.contains.2.contains.8"}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/scilab.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/scilab.json new file mode 100644 index 00000000..2ee399cc --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/scilab.json @@ -0,0 +1 @@ +{"aliases":["sci"],"lexemes":"%?\\w+","keywords":{"keyword":"abort break case clear catch continue do elseif else endfunction end for function global if pause return resume select try then while","literal":"%f %F %t %T %pi %eps %inf %nan %e %i %z %s","built_in":"abs and acos asin atan ceil cd chdir clearglobal cosh cos cumprod deff disp error exec execstr exists exp eye gettext floor fprintf fread fsolve imag isdef isempty isinfisnan isvector lasterror length load linspace list listfiles log10 log2 log max min msprintf mclose mopen ones or pathconvert poly printf prod pwd rand real round sinh sin size gsort sprintf sqrt strcat strcmps tring sum system tanh tan type typename warning zeros matrix"},"illegal":"(\"|#|/\\*|\\s+/\\w+)","contains":[{"className":"function","beginKeywords":"function","end":"$","contains":[{"className":"title","begin":"[a-zA-Z_]\\w*","relevance":0},{"className":"params","begin":"\\(","end":"\\)"}]},{"begin":"[a-zA-Z_][a-zA-Z_0-9]*('+[\\.']*|[\\.']+)","end":"","relevance":0},{"begin":"\\[","end":"\\]'*[\\.']*","relevance":0,"contains":[{"className":"number","begin":"(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)","relevance":0},{"className":"string","begin":"'|\"","end":"'|\"","contains":[{"begin":"\\\\[\\s\\S]","relevance":0},{"begin":"''"}]}]},{"className":"comment","begin":"//","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"$ref":"#contains.2.contains.0"},{"$ref":"#contains.2.contains.1"}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/scss.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/scss.json new file mode 100644 index 00000000..d1429e47 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/scss.json @@ -0,0 +1 @@ +{"case_insensitive":true,"illegal":"[=/|']","contains":[{"className":"comment","begin":"//","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"/\\*","end":"\\*/","contains":[{"$ref":"#contains.0.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"selector-id","begin":"\\#[A-Za-z0-9_-]+","relevance":0},{"className":"selector-class","begin":"\\.[A-Za-z0-9_-]+","relevance":0},{"className":"selector-attr","begin":"\\[","end":"\\]","illegal":"$"},{"className":"selector-tag","begin":"\\b(a|abbr|acronym|address|area|article|aside|audio|b|base|big|blockquote|body|br|button|canvas|caption|cite|code|col|colgroup|command|datalist|dd|del|details|dfn|div|dl|dt|em|embed|fieldset|figcaption|figure|footer|form|frame|frameset|(h[1-6])|head|header|hgroup|hr|html|i|iframe|img|input|ins|kbd|keygen|label|legend|li|link|map|mark|meta|meter|nav|noframes|noscript|object|ol|optgroup|option|output|p|param|pre|progress|q|rp|rt|ruby|samp|script|section|select|small|span|strike|strong|style|sub|sup|table|tbody|td|textarea|tfoot|th|thead|time|title|tr|tt|ul|var|video)\\b","relevance":0},{"begin":":(visited|valid|root|right|required|read-write|read-only|out-range|optional|only-of-type|only-child|nth-of-type|nth-last-of-type|nth-last-child|nth-child|not|link|left|last-of-type|last-child|lang|invalid|indeterminate|in-range|hover|focus|first-of-type|first-line|first-letter|first-child|first|enabled|empty|disabled|default|checked|before|after|active)"},{"begin":"::(after|before|choices|first-letter|first-line|repeat-index|repeat-item|selection|value)"},{"className":"variable","begin":"(\\$[a-zA-Z-][a-zA-Z0-9_-]*)\\b"},{"className":"attribute","begin":"\\b(z-index|word-wrap|word-spacing|word-break|width|widows|white-space|visibility|vertical-align|unicode-bidi|transition-timing-function|transition-property|transition-duration|transition-delay|transition|transform-style|transform-origin|transform|top|text-underline-position|text-transform|text-shadow|text-rendering|text-overflow|text-indent|text-decoration-style|text-decoration-line|text-decoration-color|text-decoration|text-align-last|text-align|tab-size|table-layout|right|resize|quotes|position|pointer-events|perspective-origin|perspective|page-break-inside|page-break-before|page-break-after|padding-top|padding-right|padding-left|padding-bottom|padding|overflow-y|overflow-x|overflow-wrap|overflow|outline-width|outline-style|outline-offset|outline-color|outline|orphans|order|opacity|object-position|object-fit|normal|none|nav-up|nav-right|nav-left|nav-index|nav-down|min-width|min-height|max-width|max-height|mask|marks|margin-top|margin-right|margin-left|margin-bottom|margin|list-style-type|list-style-position|list-style-image|list-style|line-height|letter-spacing|left|justify-content|initial|inherit|ime-mode|image-orientation|image-resolution|image-rendering|icon|hyphens|height|font-weight|font-variant-ligatures|font-variant|font-style|font-stretch|font-size-adjust|font-size|font-language-override|font-kerning|font-feature-settings|font-family|font|float|flex-wrap|flex-shrink|flex-grow|flex-flow|flex-direction|flex-basis|flex|filter|empty-cells|display|direction|cursor|counter-reset|counter-increment|content|column-width|column-span|column-rule-width|column-rule-style|column-rule-color|column-rule|column-gap|column-fill|column-count|columns|color|clip-path|clip|clear|caption-side|break-inside|break-before|break-after|box-sizing|box-shadow|box-decoration-break|bottom|border-width|border-top-width|border-top-style|border-top-right-radius|border-top-left-radius|border-top-color|border-top|border-style|border-spacing|border-right-width|border-right-style|border-right-color|border-right|border-radius|border-left-width|border-left-style|border-left-color|border-left|border-image-width|border-image-source|border-image-slice|border-image-repeat|border-image-outset|border-image|border-color|border-collapse|border-bottom-width|border-bottom-style|border-bottom-right-radius|border-bottom-left-radius|border-bottom-color|border-bottom|border|background-size|background-repeat|background-position|background-origin|background-image|background-color|background-clip|background-attachment|background-blend-mode|background|backface-visibility|auto|animation-timing-function|animation-play-state|animation-name|animation-iteration-count|animation-fill-mode|animation-duration|animation-direction|animation-delay|animation|align-self|align-items|align-content)\\b","illegal":"[^\\s]"},{"begin":"\\b(whitespace|wait|w-resize|visible|vertical-text|vertical-ideographic|uppercase|upper-roman|upper-alpha|underline|transparent|top|thin|thick|text|text-top|text-bottom|tb-rl|table-header-group|table-footer-group|sw-resize|super|strict|static|square|solid|small-caps|separate|se-resize|scroll|s-resize|rtl|row-resize|ridge|right|repeat|repeat-y|repeat-x|relative|progress|pointer|overline|outside|outset|oblique|nowrap|not-allowed|normal|none|nw-resize|no-repeat|no-drop|newspaper|ne-resize|n-resize|move|middle|medium|ltr|lr-tb|lowercase|lower-roman|lower-alpha|loose|list-item|line|line-through|line-edge|lighter|left|keep-all|justify|italic|inter-word|inter-ideograph|inside|inset|inline|inline-block|inherit|inactive|ideograph-space|ideograph-parenthesis|ideograph-numeric|ideograph-alpha|horizontal|hidden|help|hand|groove|fixed|ellipsis|e-resize|double|dotted|distribute|distribute-space|distribute-letter|distribute-all-lines|disc|disabled|default|decimal|dashed|crosshair|collapse|col-resize|circle|char|center|capitalize|break-word|break-all|bottom|both|bolder|bold|block|bidi-override|below|baseline|auto|always|all-scroll|absolute|table|table-cell)\\b"},{"begin":":","end":";","contains":[{"$ref":"#contains.8"},{"className":"number","begin":"#[0-9A-Fa-f]+"},{"className":"number","begin":"\\b\\d+(\\.\\d+)?(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?","relevance":0},{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0},{"className":"subst","begin":"\\\\[abfnrtv]\\|\\\\x[0-9a-fA-F]*\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]","relevance":0},{"className":"subst","begin":"\\\\[abfnrtv]\\|\\\\x[0-9a-fA-F]*\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]","relevance":0}]},{"className":"string","begin":"'","end":"'","illegal":"\\n","contains":[{"$ref":"#contains.11.contains.3.contains.0"}]},{"className":"meta","begin":"!important"}]},{"begin":"@","end":"[{;]","keywords":"mixin include extend for if else each while charset import debug media page content font-face namespace warn","contains":[{"$ref":"#contains.8"},{"$ref":"#contains.11.contains.3"},{"$ref":"#contains.11.contains.4"},{"$ref":"#contains.11.contains.1"},{"$ref":"#contains.11.contains.2"},{"begin":"\\s[A-Za-z0-9_.-]+","relevance":0}]}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/shell.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/shell.json new file mode 100644 index 00000000..03de3fc9 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/shell.json @@ -0,0 +1 @@ +{"aliases":["console"],"contains":[{"className":"meta","begin":"^\\s{0,3}[\\w\\d\\[\\]()@-]*[>%$#]","starts":{"end":"$","subLanguage":"bash"}}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/smali.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/smali.json new file mode 100644 index 00000000..a59b863b --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/smali.json @@ -0,0 +1 @@ +{"aliases":["smali"],"contains":[{"className":"string","begin":"\"","end":"\"","relevance":0},{"className":"comment","begin":"#","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}],"relevance":0},{"className":"keyword","variants":[{"begin":"\\s*\\.end\\s[a-zA-Z0-9]*"},{"begin":"^[ ]*\\.[a-zA-Z]*","relevance":0},{"begin":"\\s:[a-zA-Z_0-9]*","relevance":0},{"begin":"\\s(transient|constructor|abstract|final|synthetic|public|private|protected|static|bridge|system)"}]},{"className":"built_in","variants":[{"begin":"\\s(add|and|cmp|cmpg|cmpl|const|div|double|float|goto|if|int|long|move|mul|neg|new|nop|not|or|rem|return|shl|shr|sput|sub|throw|ushr|xor)\\s"},{"begin":"\\s(add|and|cmp|cmpg|cmpl|const|div|double|float|goto|if|int|long|move|mul|neg|new|nop|not|or|rem|return|shl|shr|sput|sub|throw|ushr|xor)((\\-|/)[a-zA-Z0-9]+)+\\s","relevance":10},{"begin":"\\s(aget|aput|array|check|execute|fill|filled|goto/16|goto/32|iget|instance|invoke|iput|monitor|packed|sget|sparse)((\\-|/)[a-zA-Z0-9]+)*\\s","relevance":10}]},{"className":"class","begin":"L[^(;:\n]*;","relevance":0},{"begin":"[vp][0-9]+"}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/smalltalk.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/smalltalk.json new file mode 100644 index 00000000..be81fd07 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/smalltalk.json @@ -0,0 +1 @@ +{"aliases":["st"],"keywords":"self super nil true false thisContext","contains":[{"className":"comment","begin":"\"","end":"\"","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"string","begin":"'","end":"'","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0}]},{"className":"type","begin":"\\b[A-Z][A-Za-z0-9_]*","relevance":0},{"begin":"[a-z][a-zA-Z0-9_]*:","relevance":0},{"className":"number","begin":"(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)","relevance":0},{"className":"symbol","begin":"#[a-zA-Z_]\\w*"},{"className":"string","begin":"\\$.{1}"},{"begin":"\\|[ ]*[a-z][a-zA-Z0-9_]*([ ]+[a-z][a-zA-Z0-9_]*)*[ ]*\\|","returnBegin":true,"end":"\\|","illegal":"\\S","contains":[{"begin":"(\\|[ ]*)?[a-z][a-zA-Z0-9_]*"}]},{"begin":"\\#\\(","end":"\\)","contains":[{"$ref":"#contains.1"},{"$ref":"#contains.6"},{"$ref":"#contains.4"},{"$ref":"#contains.5"}]}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/sml.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/sml.json new file mode 100644 index 00000000..da0fc482 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/sml.json @@ -0,0 +1 @@ +{"aliases":["ml"],"keywords":{"keyword":"abstype and andalso as case datatype do else end eqtype exception fn fun functor handle if in include infix infixr let local nonfix of op open orelse raise rec sharing sig signature struct structure then type val with withtype where while","built_in":"array bool char exn int list option order real ref string substring vector unit word","literal":"true false NONE SOME LESS EQUAL GREATER nil"},"illegal":"\\/\\/|>>","lexemes":"[a-z_]\\w*!?","contains":[{"className":"literal","begin":"\\[(\\|\\|)?\\]|\\(\\)","relevance":0},{"className":"comment","begin":"\\(\\*","end":"\\*\\)","contains":["self",{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"symbol","begin":"'[A-Za-z_](?!')[\\w']*"},{"className":"type","begin":"`[A-Z][\\w']*"},{"className":"type","begin":"\\b[A-Z][\\w']*","relevance":0},{"begin":"[a-z_]\\w*'[\\w']*"},{"className":"string","begin":"'","end":"'","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0}],"relevance":0},{"className":"string","begin":"\"","end":"\"","illegal":null,"contains":[{"$ref":"#contains.6.contains.0"},{"className":"subst","begin":"\\\\[abfnrtv]\\|\\\\x[0-9a-fA-F]*\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]","relevance":0},{"className":"subst","begin":"\\\\[abfnrtv]\\|\\\\x[0-9a-fA-F]*\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]","relevance":0}]},{"className":"number","begin":"\\b(0[xX][a-fA-F0-9_]+[Lln]?|0[oO][0-7_]+[Lln]?|0[bB][01_]+[Lln]?|[0-9][0-9_]*([Lln]|(\\.[0-9_]*)?([eE][-+]?[0-9_]+)?)?)","relevance":0},{"begin":"[-=]>"}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/sqf.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/sqf.json new file mode 100644 index 00000000..0141048a --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/sqf.json @@ -0,0 +1 @@ +{"aliases":["sqf"],"case_insensitive":true,"keywords":{"keyword":"case catch default do else exit exitWith for forEach from if private switch then throw to try waitUntil while with","built_in":"abs accTime acos action actionIDs actionKeys actionKeysImages actionKeysNames actionKeysNamesArray actionName actionParams activateAddons activatedAddons activateKey add3DENConnection add3DENEventHandler add3DENLayer addAction addBackpack addBackpackCargo addBackpackCargoGlobal addBackpackGlobal addCamShake addCuratorAddons addCuratorCameraArea addCuratorEditableObjects addCuratorEditingArea addCuratorPoints addEditorObject addEventHandler addForce addGoggles addGroupIcon addHandgunItem addHeadgear addItem addItemCargo addItemCargoGlobal addItemPool addItemToBackpack addItemToUniform addItemToVest addLiveStats addMagazine addMagazineAmmoCargo addMagazineCargo addMagazineCargoGlobal addMagazineGlobal addMagazinePool addMagazines addMagazineTurret addMenu addMenuItem addMissionEventHandler addMPEventHandler addMusicEventHandler addOwnedMine addPlayerScores addPrimaryWeaponItem addPublicVariableEventHandler addRating addResources addScore addScoreSide addSecondaryWeaponItem addSwitchableUnit addTeamMember addToRemainsCollector addTorque addUniform addVehicle addVest addWaypoint addWeapon addWeaponCargo addWeaponCargoGlobal addWeaponGlobal addWeaponItem addWeaponPool addWeaponTurret admin agent agents AGLToASL aimedAtTarget aimPos airDensityRTD airplaneThrottle airportSide AISFinishHeal alive all3DENEntities allAirports allControls allCurators allCutLayers allDead allDeadMen allDisplays allGroups allMapMarkers allMines allMissionObjects allow3DMode allowCrewInImmobile allowCuratorLogicIgnoreAreas allowDamage allowDammage allowFileOperations allowFleeing allowGetIn allowSprint allPlayers allSimpleObjects allSites allTurrets allUnits allUnitsUAV allVariables ammo ammoOnPylon and animate animateBay animateDoor animatePylon animateSource animationNames animationPhase animationSourcePhase animationState append apply armoryPoints arrayIntersect asin ASLToAGL ASLToATL assert assignAsCargo assignAsCargoIndex assignAsCommander assignAsDriver assignAsGunner assignAsTurret assignCurator assignedCargo assignedCommander assignedDriver assignedGunner assignedItems assignedTarget assignedTeam assignedVehicle assignedVehicleRole assignItem assignTeam assignToAirport atan atan2 atg ATLToASL attachedObject attachedObjects attachedTo attachObject attachTo attackEnabled backpack backpackCargo backpackContainer backpackItems backpackMagazines backpackSpaceFor behaviour benchmark binocular boundingBox boundingBoxReal boundingCenter breakOut breakTo briefingName buildingExit buildingPos buttonAction buttonSetAction cadetMode call callExtension camCommand camCommit camCommitPrepared camCommitted camConstuctionSetParams camCreate camDestroy cameraEffect cameraEffectEnableHUD cameraInterest cameraOn cameraView campaignConfigFile camPreload camPreloaded camPrepareBank camPrepareDir camPrepareDive camPrepareFocus camPrepareFov camPrepareFovRange camPreparePos camPrepareRelPos camPrepareTarget camSetBank camSetDir camSetDive camSetFocus camSetFov camSetFovRange camSetPos camSetRelPos camSetTarget camTarget camUseNVG canAdd canAddItemToBackpack canAddItemToUniform canAddItemToVest cancelSimpleTaskDestination canFire canMove canSlingLoad canStand canSuspend canTriggerDynamicSimulation canUnloadInCombat canVehicleCargo captive captiveNum cbChecked cbSetChecked ceil channelEnabled cheatsEnabled checkAIFeature checkVisibility className clearAllItemsFromBackpack clearBackpackCargo clearBackpackCargoGlobal clearGroupIcons clearItemCargo clearItemCargoGlobal clearItemPool clearMagazineCargo clearMagazineCargoGlobal clearMagazinePool clearOverlay clearRadio clearWeaponCargo clearWeaponCargoGlobal clearWeaponPool clientOwner closeDialog closeDisplay closeOverlay collapseObjectTree collect3DENHistory collectiveRTD combatMode commandArtilleryFire commandChat commander commandFire commandFollow commandFSM commandGetOut commandingMenu commandMove commandRadio commandStop commandSuppressiveFire commandTarget commandWatch comment commitOverlay compile compileFinal completedFSM composeText configClasses configFile configHierarchy configName configProperties configSourceAddonList configSourceMod configSourceModList confirmSensorTarget connectTerminalToUAV controlsGroupCtrl copyFromClipboard copyToClipboard copyWaypoints cos count countEnemy countFriendly countSide countType countUnknown create3DENComposition create3DENEntity createAgent createCenter createDialog createDiaryLink createDiaryRecord createDiarySubject createDisplay createGearDialog createGroup createGuardedPoint createLocation createMarker createMarkerLocal createMenu createMine createMissionDisplay createMPCampaignDisplay createSimpleObject createSimpleTask createSite createSoundSource createTask createTeam createTrigger createUnit createVehicle createVehicleCrew createVehicleLocal crew ctAddHeader ctAddRow ctClear ctCurSel ctData ctFindHeaderRows ctFindRowHeader ctHeaderControls ctHeaderCount ctRemoveHeaders ctRemoveRows ctrlActivate ctrlAddEventHandler ctrlAngle ctrlAutoScrollDelay ctrlAutoScrollRewind ctrlAutoScrollSpeed ctrlChecked ctrlClassName ctrlCommit ctrlCommitted ctrlCreate ctrlDelete ctrlEnable ctrlEnabled ctrlFade ctrlHTMLLoaded ctrlIDC ctrlIDD ctrlMapAnimAdd ctrlMapAnimClear ctrlMapAnimCommit ctrlMapAnimDone ctrlMapCursor ctrlMapMouseOver ctrlMapScale ctrlMapScreenToWorld ctrlMapWorldToScreen ctrlModel ctrlModelDirAndUp ctrlModelScale ctrlParent ctrlParentControlsGroup ctrlPosition ctrlRemoveAllEventHandlers ctrlRemoveEventHandler ctrlScale ctrlSetActiveColor ctrlSetAngle ctrlSetAutoScrollDelay ctrlSetAutoScrollRewind ctrlSetAutoScrollSpeed ctrlSetBackgroundColor ctrlSetChecked ctrlSetEventHandler ctrlSetFade ctrlSetFocus ctrlSetFont ctrlSetFontH1 ctrlSetFontH1B ctrlSetFontH2 ctrlSetFontH2B ctrlSetFontH3 ctrlSetFontH3B ctrlSetFontH4 ctrlSetFontH4B ctrlSetFontH5 ctrlSetFontH5B ctrlSetFontH6 ctrlSetFontH6B ctrlSetFontHeight ctrlSetFontHeightH1 ctrlSetFontHeightH2 ctrlSetFontHeightH3 ctrlSetFontHeightH4 ctrlSetFontHeightH5 ctrlSetFontHeightH6 ctrlSetFontHeightSecondary ctrlSetFontP ctrlSetFontPB ctrlSetFontSecondary ctrlSetForegroundColor ctrlSetModel ctrlSetModelDirAndUp ctrlSetModelScale ctrlSetPixelPrecision ctrlSetPosition ctrlSetScale ctrlSetStructuredText ctrlSetText ctrlSetTextColor ctrlSetTooltip ctrlSetTooltipColorBox ctrlSetTooltipColorShade ctrlSetTooltipColorText ctrlShow ctrlShown ctrlText ctrlTextHeight ctrlTextWidth ctrlType ctrlVisible ctRowControls ctRowCount ctSetCurSel ctSetData ctSetHeaderTemplate ctSetRowTemplate ctSetValue ctValue curatorAddons curatorCamera curatorCameraArea curatorCameraAreaCeiling curatorCoef curatorEditableObjects curatorEditingArea curatorEditingAreaType curatorMouseOver curatorPoints curatorRegisteredObjects curatorSelected curatorWaypointCost current3DENOperation currentChannel currentCommand currentMagazine currentMagazineDetail currentMagazineDetailTurret currentMagazineTurret currentMuzzle currentNamespace currentTask currentTasks currentThrowable currentVisionMode currentWaypoint currentWeapon currentWeaponMode currentWeaponTurret currentZeroing cursorObject cursorTarget customChat customRadio cutFadeOut cutObj cutRsc cutText damage date dateToNumber daytime deActivateKey debriefingText debugFSM debugLog deg delete3DENEntities deleteAt deleteCenter deleteCollection deleteEditorObject deleteGroup deleteGroupWhenEmpty deleteIdentity deleteLocation deleteMarker deleteMarkerLocal deleteRange deleteResources deleteSite deleteStatus deleteTeam deleteVehicle deleteVehicleCrew deleteWaypoint detach detectedMines diag_activeMissionFSMs diag_activeScripts diag_activeSQFScripts diag_activeSQSScripts diag_captureFrame diag_captureFrameToFile diag_captureSlowFrame diag_codePerformance diag_drawMode diag_enable diag_enabled diag_fps diag_fpsMin diag_frameNo diag_lightNewLoad diag_list diag_log diag_logSlowFrame diag_mergeConfigFile diag_recordTurretLimits diag_setLightNew diag_tickTime diag_toggle dialog diarySubjectExists didJIP didJIPOwner difficulty difficultyEnabled difficultyEnabledRTD difficultyOption direction directSay disableAI disableCollisionWith disableConversation disableDebriefingStats disableMapIndicators disableNVGEquipment disableRemoteSensors disableSerialization disableTIEquipment disableUAVConnectability disableUserInput displayAddEventHandler displayCtrl displayParent displayRemoveAllEventHandlers displayRemoveEventHandler displaySetEventHandler dissolveTeam distance distance2D distanceSqr distributionRegion do3DENAction doArtilleryFire doFire doFollow doFSM doGetOut doMove doorPhase doStop doSuppressiveFire doTarget doWatch drawArrow drawEllipse drawIcon drawIcon3D drawLine drawLine3D drawLink drawLocation drawPolygon drawRectangle drawTriangle driver drop dynamicSimulationDistance dynamicSimulationDistanceCoef dynamicSimulationEnabled dynamicSimulationSystemEnabled echo edit3DENMissionAttributes editObject editorSetEventHandler effectiveCommander emptyPositions enableAI enableAIFeature enableAimPrecision enableAttack enableAudioFeature enableAutoStartUpRTD enableAutoTrimRTD enableCamShake enableCaustics enableChannel enableCollisionWith enableCopilot enableDebriefingStats enableDiagLegend enableDynamicSimulation enableDynamicSimulationSystem enableEndDialog enableEngineArtillery enableEnvironment enableFatigue enableGunLights enableInfoPanelComponent enableIRLasers enableMimics enablePersonTurret enableRadio enableReload enableRopeAttach enableSatNormalOnDetail enableSaving enableSentences enableSimulation enableSimulationGlobal enableStamina enableTeamSwitch enableTraffic enableUAVConnectability enableUAVWaypoints enableVehicleCargo enableVehicleSensor enableWeaponDisassembly endLoadingScreen endMission engineOn enginesIsOnRTD enginesRpmRTD enginesTorqueRTD entities environmentEnabled estimatedEndServerTime estimatedTimeLeft evalObjectArgument everyBackpack everyContainer exec execEditorScript execFSM execVM exp expectedDestination exportJIPMessages eyeDirection eyePos face faction fadeMusic fadeRadio fadeSound fadeSpeech failMission fillWeaponsFromPool find findCover findDisplay findEditorObject findEmptyPosition findEmptyPositionReady findIf findNearestEnemy finishMissionInit finite fire fireAtTarget firstBackpack flag flagAnimationPhase flagOwner flagSide flagTexture fleeing floor flyInHeight flyInHeightASL fog fogForecast fogParams forceAddUniform forcedMap forceEnd forceFlagTexture forceFollowRoad forceMap forceRespawn forceSpeed forceWalk forceWeaponFire forceWeatherChange forEachMember forEachMemberAgent forEachMemberTeam forgetTarget format formation formationDirection formationLeader formationMembers formationPosition formationTask formatText formLeader freeLook fromEditor fuel fullCrew gearIDCAmmoCount gearSlotAmmoCount gearSlotData get3DENActionState get3DENAttribute get3DENCamera get3DENConnections get3DENEntity get3DENEntityID get3DENGrid get3DENIconsVisible get3DENLayerEntities get3DENLinesVisible get3DENMissionAttribute get3DENMouseOver get3DENSelected getAimingCoef getAllEnvSoundControllers getAllHitPointsDamage getAllOwnedMines getAllSoundControllers getAmmoCargo getAnimAimPrecision getAnimSpeedCoef getArray getArtilleryAmmo getArtilleryComputerSettings getArtilleryETA getAssignedCuratorLogic getAssignedCuratorUnit getBackpackCargo getBleedingRemaining getBurningValue getCameraViewDirection getCargoIndex getCenterOfMass getClientState getClientStateNumber getCompatiblePylonMagazines getConnectedUAV getContainerMaxLoad getCursorObjectParams getCustomAimCoef getDammage getDescription getDir getDirVisual getDLCAssetsUsage getDLCAssetsUsageByName getDLCs getEditorCamera getEditorMode getEditorObjectScope getElevationOffset getEnvSoundController getFatigue getForcedFlagTexture getFriend getFSMVariable getFuelCargo getGroupIcon getGroupIconParams getGroupIcons getHideFrom getHit getHitIndex getHitPointDamage getItemCargo getMagazineCargo getMarkerColor getMarkerPos getMarkerSize getMarkerType getMass getMissionConfig getMissionConfigValue getMissionDLCs getMissionLayerEntities getModelInfo getMousePosition getMusicPlayedTime getNumber getObjectArgument getObjectChildren getObjectDLC getObjectMaterials getObjectProxy getObjectTextures getObjectType getObjectViewDistance getOxygenRemaining getPersonUsedDLCs getPilotCameraDirection getPilotCameraPosition getPilotCameraRotation getPilotCameraTarget getPlateNumber getPlayerChannel getPlayerScores getPlayerUID getPos getPosASL getPosASLVisual getPosASLW getPosATL getPosATLVisual getPosVisual getPosWorld getPylonMagazines getRelDir getRelPos getRemoteSensorsDisabled getRepairCargo getResolution getShadowDistance getShotParents getSlingLoad getSoundController getSoundControllerResult getSpeed getStamina getStatValue getSuppression getTerrainGrid getTerrainHeightASL getText getTotalDLCUsageTime getUnitLoadout getUnitTrait getUserMFDText getUserMFDvalue getVariable getVehicleCargo getWeaponCargo getWeaponSway getWingsOrientationRTD getWingsPositionRTD getWPPos glanceAt globalChat globalRadio goggles goto group groupChat groupFromNetId groupIconSelectable groupIconsVisible groupId groupOwner groupRadio groupSelectedUnits groupSelectUnit gunner gusts halt handgunItems handgunMagazine handgunWeapon handsHit hasInterface hasPilotCamera hasWeapon hcAllGroups hcGroupParams hcLeader hcRemoveAllGroups hcRemoveGroup hcSelected hcSelectGroup hcSetGroup hcShowBar hcShownBar headgear hideBody hideObject hideObjectGlobal hideSelection hint hintC hintCadet hintSilent hmd hostMission htmlLoad HUDMovementLevels humidity image importAllGroups importance in inArea inAreaArray incapacitatedState inflame inflamed infoPanel infoPanelComponentEnabled infoPanelComponents infoPanels inGameUISetEventHandler inheritsFrom initAmbientLife inPolygon inputAction inRangeOfArtillery insertEditorObject intersect is3DEN is3DENMultiplayer isAbleToBreathe isAgent isArray isAutoHoverOn isAutonomous isAutotest isBleeding isBurning isClass isCollisionLightOn isCopilotEnabled isDamageAllowed isDedicated isDLCAvailable isEngineOn isEqualTo isEqualType isEqualTypeAll isEqualTypeAny isEqualTypeArray isEqualTypeParams isFilePatchingEnabled isFlashlightOn isFlatEmpty isForcedWalk isFormationLeader isGroupDeletedWhenEmpty isHidden isInRemainsCollector isInstructorFigureEnabled isIRLaserOn isKeyActive isKindOf isLaserOn isLightOn isLocalized isManualFire isMarkedForCollection isMultiplayer isMultiplayerSolo isNil isNull isNumber isObjectHidden isObjectRTD isOnRoad isPipEnabled isPlayer isRealTime isRemoteExecuted isRemoteExecutedJIP isServer isShowing3DIcons isSimpleObject isSprintAllowed isStaminaEnabled isSteamMission isStreamFriendlyUIEnabled isText isTouchingGround isTurnedOut isTutHintsEnabled isUAVConnectable isUAVConnected isUIContext isUniformAllowed isVehicleCargo isVehicleRadarOn isVehicleSensorEnabled isWalking isWeaponDeployed isWeaponRested itemCargo items itemsWithMagazines join joinAs joinAsSilent joinSilent joinString kbAddDatabase kbAddDatabaseTargets kbAddTopic kbHasTopic kbReact kbRemoveTopic kbTell kbWasSaid keyImage keyName knowsAbout land landAt landResult language laserTarget lbAdd lbClear lbColor lbColorRight lbCurSel lbData lbDelete lbIsSelected lbPicture lbPictureRight lbSelection lbSetColor lbSetColorRight lbSetCurSel lbSetData lbSetPicture lbSetPictureColor lbSetPictureColorDisabled lbSetPictureColorSelected lbSetPictureRight lbSetPictureRightColor lbSetPictureRightColorDisabled lbSetPictureRightColorSelected lbSetSelectColor lbSetSelectColorRight lbSetSelected lbSetText lbSetTextRight lbSetTooltip lbSetValue lbSize lbSort lbSortByValue lbText lbTextRight lbValue leader leaderboardDeInit leaderboardGetRows leaderboardInit leaderboardRequestRowsFriends leaderboardsRequestUploadScore leaderboardsRequestUploadScoreKeepBest leaderboardState leaveVehicle libraryCredits libraryDisclaimers lifeState lightAttachObject lightDetachObject lightIsOn lightnings limitSpeed linearConversion lineIntersects lineIntersectsObjs lineIntersectsSurfaces lineIntersectsWith linkItem list listObjects listRemoteTargets listVehicleSensors ln lnbAddArray lnbAddColumn lnbAddRow lnbClear lnbColor lnbCurSelRow lnbData lnbDeleteColumn lnbDeleteRow lnbGetColumnsPosition lnbPicture lnbSetColor lnbSetColumnsPos lnbSetCurSelRow lnbSetData lnbSetPicture lnbSetText lnbSetValue lnbSize lnbSort lnbSortByValue lnbText lnbValue load loadAbs loadBackpack loadFile loadGame loadIdentity loadMagazine loadOverlay loadStatus loadUniform loadVest local localize locationPosition lock lockCameraTo lockCargo lockDriver locked lockedCargo lockedDriver lockedTurret lockIdentity lockTurret lockWP log logEntities logNetwork logNetworkTerminate lookAt lookAtPos magazineCargo magazines magazinesAllTurrets magazinesAmmo magazinesAmmoCargo magazinesAmmoFull magazinesDetail magazinesDetailBackpack magazinesDetailUniform magazinesDetailVest magazinesTurret magazineTurretAmmo mapAnimAdd mapAnimClear mapAnimCommit mapAnimDone mapCenterOnCamera mapGridPosition markAsFinishedOnSteam markerAlpha markerBrush markerColor markerDir markerPos markerShape markerSize markerText markerType max members menuAction menuAdd menuChecked menuClear menuCollapse menuData menuDelete menuEnable menuEnabled menuExpand menuHover menuPicture menuSetAction menuSetCheck menuSetData menuSetPicture menuSetValue menuShortcut menuShortcutText menuSize menuSort menuText menuURL menuValue min mineActive mineDetectedBy missionConfigFile missionDifficulty missionName missionNamespace missionStart missionVersion mod modelToWorld modelToWorldVisual modelToWorldVisualWorld modelToWorldWorld modParams moonIntensity moonPhase morale move move3DENCamera moveInAny moveInCargo moveInCommander moveInDriver moveInGunner moveInTurret moveObjectToEnd moveOut moveTime moveTo moveToCompleted moveToFailed musicVolume name nameSound nearEntities nearestBuilding nearestLocation nearestLocations nearestLocationWithDubbing nearestObject nearestObjects nearestTerrainObjects nearObjects nearObjectsReady nearRoads nearSupplies nearTargets needReload netId netObjNull newOverlay nextMenuItemIndex nextWeatherChange nMenuItems not numberOfEnginesRTD numberToDate objectCurators objectFromNetId objectParent objStatus onBriefingGroup onBriefingNotes onBriefingPlan onBriefingTeamSwitch onCommandModeChanged onDoubleClick onEachFrame onGroupIconClick onGroupIconOverEnter onGroupIconOverLeave onHCGroupSelectionChanged onMapSingleClick onPlayerConnected onPlayerDisconnected onPreloadFinished onPreloadStarted onShowNewObject onTeamSwitch openCuratorInterface openDLCPage openMap openSteamApp openYoutubeVideo or orderGetIn overcast overcastForecast owner param params parseNumber parseSimpleArray parseText parsingNamespace particlesQuality pickWeaponPool pitch pixelGrid pixelGridBase pixelGridNoUIScale pixelH pixelW playableSlotsNumber playableUnits playAction playActionNow player playerRespawnTime playerSide playersNumber playGesture playMission playMove playMoveNow playMusic playScriptedMission playSound playSound3D position positionCameraToWorld posScreenToWorld posWorldToScreen ppEffectAdjust ppEffectCommit ppEffectCommitted ppEffectCreate ppEffectDestroy ppEffectEnable ppEffectEnabled ppEffectForceInNVG precision preloadCamera preloadObject preloadSound preloadTitleObj preloadTitleRsc preprocessFile preprocessFileLineNumbers primaryWeapon primaryWeaponItems primaryWeaponMagazine priority processDiaryLink productVersion profileName profileNamespace profileNameSteam progressLoadingScreen progressPosition progressSetPosition publicVariable publicVariableClient publicVariableServer pushBack pushBackUnique putWeaponPool queryItemsPool queryMagazinePool queryWeaponPool rad radioChannelAdd radioChannelCreate radioChannelRemove radioChannelSetCallSign radioChannelSetLabel radioVolume rain rainbow random rank rankId rating rectangular registeredTasks registerTask reload reloadEnabled remoteControl remoteExec remoteExecCall remoteExecutedOwner remove3DENConnection remove3DENEventHandler remove3DENLayer removeAction removeAll3DENEventHandlers removeAllActions removeAllAssignedItems removeAllContainers removeAllCuratorAddons removeAllCuratorCameraAreas removeAllCuratorEditingAreas removeAllEventHandlers removeAllHandgunItems removeAllItems removeAllItemsWithMagazines removeAllMissionEventHandlers removeAllMPEventHandlers removeAllMusicEventHandlers removeAllOwnedMines removeAllPrimaryWeaponItems removeAllWeapons removeBackpack removeBackpackGlobal removeCuratorAddons removeCuratorCameraArea removeCuratorEditableObjects removeCuratorEditingArea removeDrawIcon removeDrawLinks removeEventHandler removeFromRemainsCollector removeGoggles removeGroupIcon removeHandgunItem removeHeadgear removeItem removeItemFromBackpack removeItemFromUniform removeItemFromVest removeItems removeMagazine removeMagazineGlobal removeMagazines removeMagazinesTurret removeMagazineTurret removeMenuItem removeMissionEventHandler removeMPEventHandler removeMusicEventHandler removeOwnedMine removePrimaryWeaponItem removeSecondaryWeaponItem removeSimpleTask removeSwitchableUnit removeTeamMember removeUniform removeVest removeWeapon removeWeaponAttachmentCargo removeWeaponCargo removeWeaponGlobal removeWeaponTurret reportRemoteTarget requiredVersion resetCamShake resetSubgroupDirection resize resources respawnVehicle restartEditorCamera reveal revealMine reverse reversedMouseY roadAt roadsConnectedTo roleDescription ropeAttachedObjects ropeAttachedTo ropeAttachEnabled ropeAttachTo ropeCreate ropeCut ropeDestroy ropeDetach ropeEndPosition ropeLength ropes ropeUnwind ropeUnwound rotorsForcesRTD rotorsRpmRTD round runInitScript safeZoneH safeZoneW safeZoneWAbs safeZoneX safeZoneXAbs safeZoneY save3DENInventory saveGame saveIdentity saveJoysticks saveOverlay saveProfileNamespace saveStatus saveVar savingEnabled say say2D say3D scopeName score scoreSide screenshot screenToWorld scriptDone scriptName scudState secondaryWeapon secondaryWeaponItems secondaryWeaponMagazine select selectBestPlaces selectDiarySubject selectedEditorObjects selectEditorObject selectionNames selectionPosition selectLeader selectMax selectMin selectNoPlayer selectPlayer selectRandom selectRandomWeighted selectWeapon selectWeaponTurret sendAUMessage sendSimpleCommand sendTask sendTaskResult sendUDPMessage serverCommand serverCommandAvailable serverCommandExecutable serverName serverTime set set3DENAttribute set3DENAttributes set3DENGrid set3DENIconsVisible set3DENLayer set3DENLinesVisible set3DENLogicType set3DENMissionAttribute set3DENMissionAttributes set3DENModelsVisible set3DENObjectType set3DENSelected setAccTime setActualCollectiveRTD setAirplaneThrottle setAirportSide setAmmo setAmmoCargo setAmmoOnPylon setAnimSpeedCoef setAperture setApertureNew setArmoryPoints setAttributes setAutonomous setBehaviour setBleedingRemaining setBrakesRTD setCameraInterest setCamShakeDefParams setCamShakeParams setCamUseTI setCaptive setCenterOfMass setCollisionLight setCombatMode setCompassOscillation setConvoySeparation setCuratorCameraAreaCeiling setCuratorCoef setCuratorEditingAreaType setCuratorWaypointCost setCurrentChannel setCurrentTask setCurrentWaypoint setCustomAimCoef setCustomWeightRTD setDamage setDammage setDate setDebriefingText setDefaultCamera setDestination setDetailMapBlendPars setDir setDirection setDrawIcon setDriveOnPath setDropInterval setDynamicSimulationDistance setDynamicSimulationDistanceCoef setEditorMode setEditorObjectScope setEffectCondition setEngineRPMRTD setFace setFaceAnimation setFatigue setFeatureType setFlagAnimationPhase setFlagOwner setFlagSide setFlagTexture setFog setFormation setFormationTask setFormDir setFriend setFromEditor setFSMVariable setFuel setFuelCargo setGroupIcon setGroupIconParams setGroupIconsSelectable setGroupIconsVisible setGroupId setGroupIdGlobal setGroupOwner setGusts setHideBehind setHit setHitIndex setHitPointDamage setHorizonParallaxCoef setHUDMovementLevels setIdentity setImportance setInfoPanel setLeader setLightAmbient setLightAttenuation setLightBrightness setLightColor setLightDayLight setLightFlareMaxDistance setLightFlareSize setLightIntensity setLightnings setLightUseFlare setLocalWindParams setMagazineTurretAmmo setMarkerAlpha setMarkerAlphaLocal setMarkerBrush setMarkerBrushLocal setMarkerColor setMarkerColorLocal setMarkerDir setMarkerDirLocal setMarkerPos setMarkerPosLocal setMarkerShape setMarkerShapeLocal setMarkerSize setMarkerSizeLocal setMarkerText setMarkerTextLocal setMarkerType setMarkerTypeLocal setMass setMimic setMousePosition setMusicEffect setMusicEventHandler setName setNameSound setObjectArguments setObjectMaterial setObjectMaterialGlobal setObjectProxy setObjectTexture setObjectTextureGlobal setObjectViewDistance setOvercast setOwner setOxygenRemaining setParticleCircle setParticleClass setParticleFire setParticleParams setParticleRandom setPilotCameraDirection setPilotCameraRotation setPilotCameraTarget setPilotLight setPiPEffect setPitch setPlateNumber setPlayable setPlayerRespawnTime setPos setPosASL setPosASL2 setPosASLW setPosATL setPosition setPosWorld setPylonLoadOut setPylonsPriority setRadioMsg setRain setRainbow setRandomLip setRank setRectangular setRepairCargo setRotorBrakeRTD setShadowDistance setShotParents setSide setSimpleTaskAlwaysVisible setSimpleTaskCustomData setSimpleTaskDescription setSimpleTaskDestination setSimpleTaskTarget setSimpleTaskType setSimulWeatherLayers setSize setSkill setSlingLoad setSoundEffect setSpeaker setSpeech setSpeedMode setStamina setStaminaScheme setStatValue setSuppression setSystemOfUnits setTargetAge setTaskMarkerOffset setTaskResult setTaskState setTerrainGrid setText setTimeMultiplier setTitleEffect setTrafficDensity setTrafficDistance setTrafficGap setTrafficSpeed setTriggerActivation setTriggerArea setTriggerStatements setTriggerText setTriggerTimeout setTriggerType setType setUnconscious setUnitAbility setUnitLoadout setUnitPos setUnitPosWeak setUnitRank setUnitRecoilCoefficient setUnitTrait setUnloadInCombat setUserActionText setUserMFDText setUserMFDvalue setVariable setVectorDir setVectorDirAndUp setVectorUp setVehicleAmmo setVehicleAmmoDef setVehicleArmor setVehicleCargo setVehicleId setVehicleLock setVehiclePosition setVehicleRadar setVehicleReceiveRemoteTargets setVehicleReportOwnPosition setVehicleReportRemoteTargets setVehicleTIPars setVehicleVarName setVelocity setVelocityModelSpace setVelocityTransformation setViewDistance setVisibleIfTreeCollapsed setWantedRPMRTD setWaves setWaypointBehaviour setWaypointCombatMode setWaypointCompletionRadius setWaypointDescription setWaypointForceBehaviour setWaypointFormation setWaypointHousePosition setWaypointLoiterRadius setWaypointLoiterType setWaypointName setWaypointPosition setWaypointScript setWaypointSpeed setWaypointStatements setWaypointTimeout setWaypointType setWaypointVisible setWeaponReloadingTime setWind setWindDir setWindForce setWindStr setWingForceScaleRTD setWPPos show3DIcons showChat showCinemaBorder showCommandingMenu showCompass showCuratorCompass showGPS showHUD showLegend showMap shownArtilleryComputer shownChat shownCompass shownCuratorCompass showNewEditorObject shownGPS shownHUD shownMap shownPad shownRadio shownScoretable shownUAVFeed shownWarrant shownWatch showPad showRadio showScoretable showSubtitles showUAVFeed showWarrant showWatch showWaypoint showWaypoints side sideChat sideEnemy sideFriendly sideRadio simpleTasks simulationEnabled simulCloudDensity simulCloudOcclusion simulInClouds simulWeatherSync sin size sizeOf skill skillFinal skipTime sleep sliderPosition sliderRange sliderSetPosition sliderSetRange sliderSetSpeed sliderSpeed slingLoadAssistantShown soldierMagazines someAmmo sort soundVolume spawn speaker speed speedMode splitString sqrt squadParams stance startLoadingScreen step stop stopEngineRTD stopped str sunOrMoon supportInfo suppressFor surfaceIsWater surfaceNormal surfaceType swimInDepth switchableUnits switchAction switchCamera switchGesture switchLight switchMove synchronizedObjects synchronizedTriggers synchronizedWaypoints synchronizeObjectsAdd synchronizeObjectsRemove synchronizeTrigger synchronizeWaypoint systemChat systemOfUnits tan targetKnowledge targets targetsAggregate targetsQuery taskAlwaysVisible taskChildren taskCompleted taskCustomData taskDescription taskDestination taskHint taskMarkerOffset taskParent taskResult taskState taskType teamMember teamName teams teamSwitch teamSwitchEnabled teamType terminate terrainIntersect terrainIntersectASL terrainIntersectAtASL text textLog textLogFormat tg time timeMultiplier titleCut titleFadeOut titleObj titleRsc titleText toArray toFixed toLower toString toUpper triggerActivated triggerActivation triggerArea triggerAttachedVehicle triggerAttachObject triggerAttachVehicle triggerDynamicSimulation triggerStatements triggerText triggerTimeout triggerTimeoutCurrent triggerType turretLocal turretOwner turretUnit tvAdd tvClear tvCollapse tvCollapseAll tvCount tvCurSel tvData tvDelete tvExpand tvExpandAll tvPicture tvSetColor tvSetCurSel tvSetData tvSetPicture tvSetPictureColor tvSetPictureColorDisabled tvSetPictureColorSelected tvSetPictureRight tvSetPictureRightColor tvSetPictureRightColorDisabled tvSetPictureRightColorSelected tvSetText tvSetTooltip tvSetValue tvSort tvSortByValue tvText tvTooltip tvValue type typeName typeOf UAVControl uiNamespace uiSleep unassignCurator unassignItem unassignTeam unassignVehicle underwater uniform uniformContainer uniformItems uniformMagazines unitAddons unitAimPosition unitAimPositionVisual unitBackpack unitIsUAV unitPos unitReady unitRecoilCoefficient units unitsBelowHeight unlinkItem unlockAchievement unregisterTask updateDrawIcon updateMenuItem updateObjectTree useAISteeringComponent useAudioTimeForMoves userInputDisabled vectorAdd vectorCos vectorCrossProduct vectorDiff vectorDir vectorDirVisual vectorDistance vectorDistanceSqr vectorDotProduct vectorFromTo vectorMagnitude vectorMagnitudeSqr vectorModelToWorld vectorModelToWorldVisual vectorMultiply vectorNormalized vectorUp vectorUpVisual vectorWorldToModel vectorWorldToModelVisual vehicle vehicleCargoEnabled vehicleChat vehicleRadio vehicleReceiveRemoteTargets vehicleReportOwnPosition vehicleReportRemoteTargets vehicles vehicleVarName velocity velocityModelSpace verifySignature vest vestContainer vestItems vestMagazines viewDistance visibleCompass visibleGPS visibleMap visiblePosition visiblePositionASL visibleScoretable visibleWatch waves waypointAttachedObject waypointAttachedVehicle waypointAttachObject waypointAttachVehicle waypointBehaviour waypointCombatMode waypointCompletionRadius waypointDescription waypointForceBehaviour waypointFormation waypointHousePosition waypointLoiterRadius waypointLoiterType waypointName waypointPosition waypoints waypointScript waypointsEnabledUAV waypointShow waypointSpeed waypointStatements waypointTimeout waypointTimeoutCurrent waypointType waypointVisible weaponAccessories weaponAccessoriesCargo weaponCargo weaponDirection weaponInertia weaponLowered weapons weaponsItems weaponsItemsCargo weaponState weaponsTurret weightRTD WFSideText wind ","literal":"blufor civilian configNull controlNull displayNull east endl false grpNull independent lineBreak locationNull nil objNull opfor pi resistance scriptNull sideAmbientLife sideEmpty sideLogic sideUnknown taskNull teamMemberNull true west"},"contains":[{"className":"comment","begin":"//","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"/\\*","end":"\\*/","contains":[{"$ref":"#contains.0.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"number","begin":"\\b\\d+(\\.\\d+)?","relevance":0},{"className":"variable","begin":"\\b_+[a-zA-Z_]\\w*"},{"className":"title","begin":"[a-zA-Z][a-zA-Z0-9]+_fnc_\\w*"},{"className":"string","variants":[{"begin":"\"","end":"\"","contains":[{"begin":"\"\"","relevance":0}]},{"begin":"'","end":"'","contains":[{"begin":"''","relevance":0}]}]},{"className":"meta","begin":"#\\s*[a-z]+\\b","end":"$","keywords":{"meta-keyword":"if else elif endif define undef warning error line pragma ifdef ifndef include"},"contains":[{"begin":"\\\\\\n","relevance":0},{"className":"meta-string","variants":[{"begin":"(u8?|U|L)?\"","end":"\"","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0}]},{"begin":"(?:u8?|U|L)?R\"([^()\\\\ ]{0,16})\\((?:.|\\n)*?\\)\\1\""},{"begin":"'\\\\?.","end":"'","illegal":"."}]},{"className":"meta-string","begin":"<[^\\n>]*>","end":"$","illegal":"\\n"},{"$ref":"#contains.0"},{"$ref":"#contains.1"}]}],"illegal":"#|^\\$ "} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/sql.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/sql.json new file mode 100644 index 00000000..1d274a8d --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/sql.json @@ -0,0 +1 @@ +{"case_insensitive":true,"illegal":"[<>{}*]","contains":[{"beginKeywords":"begin end start commit rollback savepoint lock alter create drop rename call delete do handler insert load replace select truncate update set show pragma grant merge describe use explain help declare prepare execute deallocate release unlock purge reset change stop analyze cache flush optimize repair kill install uninstall checksum restore check backup revoke comment values with","end":";","endsWithParent":true,"lexemes":"[\\w\\.]+","keywords":{"keyword":"as abort abs absolute acc acce accep accept access accessed accessible account acos action activate add addtime admin administer advanced advise aes_decrypt aes_encrypt after agent aggregate ali alia alias all allocate allow alter always analyze ancillary and anti any anydata anydataset anyschema anytype apply archive archived archivelog are as asc ascii asin assembly assertion associate asynchronous at atan atn2 attr attri attrib attribu attribut attribute attributes audit authenticated authentication authid authors auto autoallocate autodblink autoextend automatic availability avg backup badfile basicfile before begin beginning benchmark between bfile bfile_base big bigfile bin binary_double binary_float binlog bit_and bit_count bit_length bit_or bit_xor bitmap blob_base block blocksize body both bound bucket buffer_cache buffer_pool build bulk by byte byteordermark bytes cache caching call calling cancel capacity cascade cascaded case cast catalog category ceil ceiling chain change changed char_base char_length character_length characters characterset charindex charset charsetform charsetid check checksum checksum_agg child choose chr chunk class cleanup clear client clob clob_base clone close cluster_id cluster_probability cluster_set clustering coalesce coercibility col collate collation collect colu colum column column_value columns columns_updated comment commit compact compatibility compiled complete composite_limit compound compress compute concat concat_ws concurrent confirm conn connec connect connect_by_iscycle connect_by_isleaf connect_by_root connect_time connection consider consistent constant constraint constraints constructor container content contents context contributors controlfile conv convert convert_tz corr corr_k corr_s corresponding corruption cos cost count count_big counted covar_pop covar_samp cpu_per_call cpu_per_session crc32 create creation critical cross cube cume_dist curdate current current_date current_time current_timestamp current_user cursor curtime customdatum cycle data database databases datafile datafiles datalength date_add date_cache date_format date_sub dateadd datediff datefromparts datename datepart datetime2fromparts day day_to_second dayname dayofmonth dayofweek dayofyear days db_role_change dbtimezone ddl deallocate declare decode decompose decrement decrypt deduplicate def defa defau defaul default defaults deferred defi defin define degrees delayed delegate delete delete_all delimited demand dense_rank depth dequeue des_decrypt des_encrypt des_key_file desc descr descri describ describe descriptor deterministic diagnostics difference dimension direct_load directory disable disable_all disallow disassociate discardfile disconnect diskgroup distinct distinctrow distribute distributed div do document domain dotnet double downgrade drop dumpfile duplicate duration each edition editionable editions element ellipsis else elsif elt empty enable enable_all enclosed encode encoding encrypt end end-exec endian enforced engine engines enqueue enterprise entityescaping eomonth error errors escaped evalname evaluate event eventdata events except exception exceptions exchange exclude excluding execu execut execute exempt exists exit exp expire explain explode export export_set extended extent external external_1 external_2 externally extract failed failed_login_attempts failover failure far fast feature_set feature_value fetch field fields file file_name_convert filesystem_like_logging final finish first first_value fixed flash_cache flashback floor flush following follows for forall force foreign form forma format found found_rows freelist freelists freepools fresh from from_base64 from_days ftp full function general generated get get_format get_lock getdate getutcdate global global_name globally go goto grant grants greatest group group_concat group_id grouping grouping_id groups gtid_subtract guarantee guard handler hash hashkeys having hea head headi headin heading heap help hex hierarchy high high_priority hosts hour hours http id ident_current ident_incr ident_seed identified identity idle_time if ifnull ignore iif ilike ilm immediate import in include including increment index indexes indexing indextype indicator indices inet6_aton inet6_ntoa inet_aton inet_ntoa infile initial initialized initially initrans inmemory inner innodb input insert install instance instantiable instr interface interleaved intersect into invalidate invisible is is_free_lock is_ipv4 is_ipv4_compat is_not is_not_null is_used_lock isdate isnull isolation iterate java join json json_exists keep keep_duplicates key keys kill language large last last_day last_insert_id last_value lateral lax lcase lead leading least leaves left len lenght length less level levels library like like2 like4 likec limit lines link list listagg little ln load load_file lob lobs local localtime localtimestamp locate locator lock locked log log10 log2 logfile logfiles logging logical logical_reads_per_call logoff logon logs long loop low low_priority lower lpad lrtrim ltrim main make_set makedate maketime managed management manual map mapping mask master master_pos_wait match matched materialized max maxextents maximize maxinstances maxlen maxlogfiles maxloghistory maxlogmembers maxsize maxtrans md5 measures median medium member memcompress memory merge microsecond mid migration min minextents minimum mining minus minute minutes minvalue missing mod mode model modification modify module monitoring month months mount move movement multiset mutex name name_const names nan national native natural nav nchar nclob nested never new newline next nextval no no_write_to_binlog noarchivelog noaudit nobadfile nocheck nocompress nocopy nocycle nodelay nodiscardfile noentityescaping noguarantee nokeep nologfile nomapping nomaxvalue nominimize nominvalue nomonitoring none noneditionable nonschema noorder nopr nopro noprom nopromp noprompt norely noresetlogs noreverse normal norowdependencies noschemacheck noswitch not nothing notice notnull notrim novalidate now nowait nth_value nullif nulls num numb numbe nvarchar nvarchar2 object ocicoll ocidate ocidatetime ociduration ociinterval ociloblocator ocinumber ociref ocirefcursor ocirowid ocistring ocitype oct octet_length of off offline offset oid oidindex old on online only opaque open operations operator optimal optimize option optionally or oracle oracle_date oradata ord ordaudio orddicom orddoc order ordimage ordinality ordvideo organization orlany orlvary out outer outfile outline output over overflow overriding package pad parallel parallel_enable parameters parent parse partial partition partitions pascal passing password password_grace_time password_lock_time password_reuse_max password_reuse_time password_verify_function patch path patindex pctincrease pctthreshold pctused pctversion percent percent_rank percentile_cont percentile_disc performance period period_add period_diff permanent physical pi pipe pipelined pivot pluggable plugin policy position post_transaction pow power pragma prebuilt precedes preceding precision prediction prediction_cost prediction_details prediction_probability prediction_set prepare present preserve prior priority private private_sga privileges procedural procedure procedure_analyze processlist profiles project prompt protection public publishingservername purge quarter query quick quiesce quota quotename radians raise rand range rank raw read reads readsize rebuild record records recover recovery recursive recycle redo reduced ref reference referenced references referencing refresh regexp_like register regr_avgx regr_avgy regr_count regr_intercept regr_r2 regr_slope regr_sxx regr_sxy reject rekey relational relative relaylog release release_lock relies_on relocate rely rem remainder rename repair repeat replace replicate replication required reset resetlogs resize resource respect restore restricted result result_cache resumable resume retention return returning returns reuse reverse revoke right rlike role roles rollback rolling rollup round row row_count rowdependencies rowid rownum rows rtrim rules safe salt sample save savepoint sb1 sb2 sb4 scan schema schemacheck scn scope scroll sdo_georaster sdo_topo_geometry search sec_to_time second seconds section securefile security seed segment select self semi sequence sequential serializable server servererror session session_user sessions_per_user set sets settings sha sha1 sha2 share shared shared_pool short show shrink shutdown si_averagecolor si_colorhistogram si_featurelist si_positionalcolor si_stillimage si_texture siblings sid sign sin size size_t sizes skip slave sleep smalldatetimefromparts smallfile snapshot some soname sort soundex source space sparse spfile split sql sql_big_result sql_buffer_result sql_cache sql_calc_found_rows sql_small_result sql_variant_property sqlcode sqldata sqlerror sqlname sqlstate sqrt square standalone standby start starting startup statement static statistics stats_binomial_test stats_crosstab stats_ks_test stats_mode stats_mw_test stats_one_way_anova stats_t_test_ stats_t_test_indep stats_t_test_one stats_t_test_paired stats_wsr_test status std stddev stddev_pop stddev_samp stdev stop storage store stored str str_to_date straight_join strcmp strict string struct stuff style subdate subpartition subpartitions substitutable substr substring subtime subtring_index subtype success sum suspend switch switchoffset switchover sync synchronous synonym sys sys_xmlagg sysasm sysaux sysdate sysdatetimeoffset sysdba sysoper system system_user sysutcdatetime table tables tablespace tablesample tan tdo template temporary terminated tertiary_weights test than then thread through tier ties time time_format time_zone timediff timefromparts timeout timestamp timestampadd timestampdiff timezone_abbr timezone_minute timezone_region to to_base64 to_date to_days to_seconds todatetimeoffset trace tracking transaction transactional translate translation treat trigger trigger_nestlevel triggers trim truncate try_cast try_convert try_parse type ub1 ub2 ub4 ucase unarchived unbounded uncompress under undo unhex unicode uniform uninstall union unique unix_timestamp unknown unlimited unlock unnest unpivot unrecoverable unsafe unsigned until untrusted unusable unused update updated upgrade upped upper upsert url urowid usable usage use use_stored_outlines user user_data user_resources users using utc_date utc_timestamp uuid uuid_short validate validate_password_strength validation valist value values var var_samp varcharc vari varia variab variabl variable variables variance varp varraw varrawc varray verify version versions view virtual visible void wait wallet warning warnings week weekday weekofyear wellformed when whene whenev wheneve whenever where while whitespace window with within without work wrapped xdb xml xmlagg xmlattributes xmlcast xmlcolattval xmlelement xmlexists xmlforest xmlindex xmlnamespaces xmlpi xmlquery xmlroot xmlschema xmlserialize xmltable xmltype xor year year_to_month years yearweek","literal":"true false null unknown","built_in":"array bigint binary bit blob bool boolean char character date dec decimal float int int8 integer interval number numeric real record serial serial8 smallint text time timestamp tinyint varchar varying void"},"contains":[{"className":"string","begin":"'","end":"'","contains":[{"begin":"\\\\[\\s\\S]","relevance":0},{"begin":"''"}]},{"className":"string","begin":"\"","end":"\"","contains":[{"$ref":"#contains.0.contains.0.contains.0"},{"begin":"\"\""}]},{"className":"string","begin":"`","end":"`","contains":[{"$ref":"#contains.0.contains.0.contains.0"}]},{"className":"number","begin":"(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)","relevance":0},{"className":"comment","begin":"/\\*","end":"\\*/","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"--","end":"$","contains":[{"$ref":"#contains.0.contains.4.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"#","end":"$","contains":[{"$ref":"#contains.0.contains.4.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]}]},{"$ref":"#contains.0.contains.4"},{"$ref":"#contains.0.contains.5"},{"$ref":"#contains.0.contains.6"}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/stan.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/stan.json new file mode 100644 index 00000000..e32a2119 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/stan.json @@ -0,0 +1 @@ +{"contains":[{"className":"comment","begin":"#","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"//","end":"$","contains":[{"$ref":"#contains.0.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"/\\*","end":"\\*/","contains":[{"$ref":"#contains.0.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"begin":"[a-zA-Z_]\\w*","lexemes":"[a-zA-Z_]\\w*","keywords":{"name":"for in while repeat until if then else","symbol":"bernoulli bernoulli_logit binomial binomial_logit beta_binomial hypergeometric categorical categorical_logit ordered_logistic neg_binomial neg_binomial_2 neg_binomial_2_log poisson poisson_log multinomial normal exp_mod_normal skew_normal student_t cauchy double_exponential logistic gumbel lognormal chi_square inv_chi_square scaled_inv_chi_square exponential inv_gamma weibull frechet rayleigh wiener pareto pareto_type_2 von_mises uniform multi_normal multi_normal_prec multi_normal_cholesky multi_gp multi_gp_cholesky multi_student_t gaussian_dlm_obs dirichlet lkj_corr lkj_corr_cholesky wishart inv_wishart","selector-tag":"int real vector simplex unit_vector ordered positive_ordered row_vector matrix cholesky_factor_corr cholesky_factor_cov corr_matrix cov_matrix","title":"functions model data parameters quantities transformed generated","literal":"true false"},"relevance":0},{"className":"number","begin":"0[xX][0-9a-fA-F]+[Li]?\\b","relevance":0},{"className":"number","begin":"0[xX][0-9a-fA-F]+[Li]?\\b","relevance":0},{"className":"number","begin":"\\d+(?:[eE][+\\-]?\\d*)?L\\b","relevance":0},{"className":"number","begin":"\\d+\\.(?!\\d)(?:i\\b)?","relevance":0},{"className":"number","begin":"\\d+(?:\\.\\d*)?(?:[eE][+\\-]?\\d*)?i?\\b","relevance":0},{"className":"number","begin":"\\.\\d+(?:[eE][+\\-]?\\d*)?i?\\b","relevance":0}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/stata.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/stata.json new file mode 100644 index 00000000..b275948e --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/stata.json @@ -0,0 +1 @@ +{"aliases":["do","ado"],"case_insensitive":true,"keywords":"if else in foreach for forv forva forval forvalu forvalue forvalues by bys bysort xi quietly qui capture about ac ac_7 acprplot acprplot_7 adjust ado adopath adoupdate alpha ameans an ano anov anova anova_estat anova_terms anovadef aorder ap app appe appen append arch arch_dr arch_estat arch_p archlm areg areg_p args arima arima_dr arima_estat arima_p as asmprobit asmprobit_estat asmprobit_lf asmprobit_mfx__dlg asmprobit_p ass asse asser assert avplot avplot_7 avplots avplots_7 bcskew0 bgodfrey bias binreg bip0_lf biplot bipp_lf bipr_lf bipr_p biprobit bitest bitesti bitowt blogit bmemsize boot bootsamp bootstrap bootstrap_8 boxco_l boxco_p boxcox boxcox_6 boxcox_p bprobit br break brier bro brow brows browse brr brrstat bs bs_7 bsampl_w bsample bsample_7 bsqreg bstat bstat_7 bstat_8 bstrap bstrap_7 bubble bubbleplot ca ca_estat ca_p cabiplot camat canon canon_8 canon_8_p canon_estat canon_p cap caprojection capt captu captur capture cat cc cchart cchart_7 cci cd censobs_table centile cf char chdir checkdlgfiles checkestimationsample checkhlpfiles checksum chelp ci cii cl class classutil clear cli clis clist clo clog clog_lf clog_p clogi clogi_sw clogit clogit_lf clogit_p clogitp clogl_sw cloglog clonevar clslistarray cluster cluster_measures cluster_stop cluster_tree cluster_tree_8 clustermat cmdlog cnr cnre cnreg cnreg_p cnreg_sw cnsreg codebook collaps4 collapse colormult_nb colormult_nw compare compress conf confi confir confirm conren cons const constr constra constrai constrain constraint continue contract copy copyright copysource cor corc corr corr2data corr_anti corr_kmo corr_smc corre correl correla correlat correlate corrgram cou coun count cox cox_p cox_sw coxbase coxhaz coxvar cprplot cprplot_7 crc cret cretu cretur creturn cross cs cscript cscript_log csi ct ct_is ctset ctst_5 ctst_st cttost cumsp cumsp_7 cumul cusum cusum_7 cutil d|0 datasig datasign datasigna datasignat datasignatu datasignatur datasignature datetof db dbeta de dec deco decod decode deff des desc descr descri describ describe destring dfbeta dfgls dfuller di di_g dir dirstats dis discard disp disp_res disp_s displ displa display distinct do doe doed doedi doedit dotplot dotplot_7 dprobit drawnorm drop ds ds_util dstdize duplicates durbina dwstat dydx e|0 ed edi edit egen eivreg emdef en enc enco encod encode eq erase ereg ereg_lf ereg_p ereg_sw ereghet ereghet_glf ereghet_glf_sh ereghet_gp ereghet_ilf ereghet_ilf_sh ereghet_ip eret eretu eretur ereturn err erro error esize est est_cfexist est_cfname est_clickable est_expand est_hold est_table est_unhold est_unholdok estat estat_default estat_summ estat_vce_only esti estimates etodow etof etomdy ex exi exit expand expandcl fac fact facto factor factor_estat factor_p factor_pca_rotated factor_rotate factormat fcast fcast_compute fcast_graph fdades fdadesc fdadescr fdadescri fdadescrib fdadescribe fdasav fdasave fdause fh_st file open file read file close file filefilter fillin find_hlp_file findfile findit findit_7 fit fl fli flis flist for5_0 forest forestplot form forma format fpredict frac_154 frac_adj frac_chk frac_cox frac_ddp frac_dis frac_dv frac_in frac_mun frac_pp frac_pq frac_pv frac_wgt frac_xo fracgen fracplot fracplot_7 fracpoly fracpred fron_ex fron_hn fron_p fron_tn fron_tn2 frontier ftodate ftoe ftomdy ftowdate funnel funnelplot g|0 gamhet_glf gamhet_gp gamhet_ilf gamhet_ip gamma gamma_d2 gamma_p gamma_sw gammahet gdi_hexagon gdi_spokes ge gen gene gener genera generat generate genrank genstd genvmean gettoken gl gladder gladder_7 glim_l01 glim_l02 glim_l03 glim_l04 glim_l05 glim_l06 glim_l07 glim_l08 glim_l09 glim_l10 glim_l11 glim_l12 glim_lf glim_mu glim_nw1 glim_nw2 glim_nw3 glim_p glim_v1 glim_v2 glim_v3 glim_v4 glim_v5 glim_v6 glim_v7 glm glm_6 glm_p glm_sw glmpred glo glob globa global glogit glogit_8 glogit_p gmeans gnbre_lf gnbreg gnbreg_5 gnbreg_p gomp_lf gompe_sw gomper_p gompertz gompertzhet gomphet_glf gomphet_glf_sh gomphet_gp gomphet_ilf gomphet_ilf_sh gomphet_ip gphdot gphpen gphprint gprefs gprobi_p gprobit gprobit_8 gr gr7 gr_copy gr_current gr_db gr_describe gr_dir gr_draw gr_draw_replay gr_drop gr_edit gr_editviewopts gr_example gr_example2 gr_export gr_print gr_qscheme gr_query gr_read gr_rename gr_replay gr_save gr_set gr_setscheme gr_table gr_undo gr_use graph graph7 grebar greigen greigen_7 greigen_8 grmeanby grmeanby_7 gs_fileinfo gs_filetype gs_graphinfo gs_stat gsort gwood h|0 hadimvo hareg hausman haver he heck_d2 heckma_p heckman heckp_lf heckpr_p heckprob hel help hereg hetpr_lf hetpr_p hetprob hettest hexdump hilite hist hist_7 histogram hlogit hlu hmeans hotel hotelling hprobit hreg hsearch icd9 icd9_ff icd9p iis impute imtest inbase include inf infi infil infile infix inp inpu input ins insheet insp inspe inspec inspect integ inten intreg intreg_7 intreg_p intrg2_ll intrg_ll intrg_ll2 ipolate iqreg ir irf irf_create irfm iri is_svy is_svysum isid istdize ivprob_1_lf ivprob_lf ivprobit ivprobit_p ivreg ivreg_footnote ivtob_1_lf ivtob_lf ivtobit ivtobit_p jackknife jacknife jknife jknife_6 jknife_8 jkstat joinby kalarma1 kap kap_3 kapmeier kappa kapwgt kdensity kdensity_7 keep ksm ksmirnov ktau kwallis l|0 la lab labbe labbeplot labe label labelbook ladder levels levelsof leverage lfit lfit_p li lincom line linktest lis list lloghet_glf lloghet_glf_sh lloghet_gp lloghet_ilf lloghet_ilf_sh lloghet_ip llogi_sw llogis_p llogist llogistic llogistichet lnorm_lf lnorm_sw lnorma_p lnormal lnormalhet lnormhet_glf lnormhet_glf_sh lnormhet_gp lnormhet_ilf lnormhet_ilf_sh lnormhet_ip lnskew0 loadingplot loc loca local log logi logis_lf logistic logistic_p logit logit_estat logit_p loglogs logrank loneway lookfor lookup lowess lowess_7 lpredict lrecomp lroc lroc_7 lrtest ls lsens lsens_7 lsens_x lstat ltable ltable_7 ltriang lv lvr2plot lvr2plot_7 m|0 ma mac macr macro makecns man manova manova_estat manova_p manovatest mantel mark markin markout marksample mat mat_capp mat_order mat_put_rr mat_rapp mata mata_clear mata_describe mata_drop mata_matdescribe mata_matsave mata_matuse mata_memory mata_mlib mata_mosave mata_rename mata_which matalabel matcproc matlist matname matr matri matrix matrix_input__dlg matstrik mcc mcci md0_ md1_ md1debug_ md2_ md2debug_ mds mds_estat mds_p mdsconfig mdslong mdsmat mdsshepard mdytoe mdytof me_derd mean means median memory memsize menl meqparse mer merg merge meta mfp mfx mhelp mhodds minbound mixed_ll mixed_ll_reparm mkassert mkdir mkmat mkspline ml ml_5 ml_adjs ml_bhhhs ml_c_d ml_check ml_clear ml_cnt ml_debug ml_defd ml_e0 ml_e0_bfgs ml_e0_cycle ml_e0_dfp ml_e0i ml_e1 ml_e1_bfgs ml_e1_bhhh ml_e1_cycle ml_e1_dfp ml_e2 ml_e2_cycle ml_ebfg0 ml_ebfr0 ml_ebfr1 ml_ebh0q ml_ebhh0 ml_ebhr0 ml_ebr0i ml_ecr0i ml_edfp0 ml_edfr0 ml_edfr1 ml_edr0i ml_eds ml_eer0i ml_egr0i ml_elf ml_elf_bfgs ml_elf_bhhh ml_elf_cycle ml_elf_dfp ml_elfi ml_elfs ml_enr0i ml_enrr0 ml_erdu0 ml_erdu0_bfgs ml_erdu0_bhhh ml_erdu0_bhhhq ml_erdu0_cycle ml_erdu0_dfp ml_erdu0_nrbfgs ml_exde ml_footnote ml_geqnr ml_grad0 ml_graph ml_hbhhh ml_hd0 ml_hold ml_init ml_inv ml_log ml_max ml_mlout ml_mlout_8 ml_model ml_nb0 ml_opt ml_p ml_plot ml_query ml_rdgrd ml_repor ml_s_e ml_score ml_searc ml_technique ml_unhold mleval mlf_ mlmatbysum mlmatsum mlog mlogi mlogit mlogit_footnote mlogit_p mlopts mlsum mlvecsum mnl0_ mor more mov move mprobit mprobit_lf mprobit_p mrdu0_ mrdu1_ mvdecode mvencode mvreg mvreg_estat n|0 nbreg nbreg_al nbreg_lf nbreg_p nbreg_sw nestreg net newey newey_7 newey_p news nl nl_7 nl_9 nl_9_p nl_p nl_p_7 nlcom nlcom_p nlexp2 nlexp2_7 nlexp2a nlexp2a_7 nlexp3 nlexp3_7 nlgom3 nlgom3_7 nlgom4 nlgom4_7 nlinit nllog3 nllog3_7 nllog4 nllog4_7 nlog_rd nlogit nlogit_p nlogitgen nlogittree nlpred no nobreak noi nois noisi noisil noisily note notes notes_dlg nptrend numlabel numlist odbc old_ver olo olog ologi ologi_sw ologit ologit_p ologitp on one onew onewa oneway op_colnm op_comp op_diff op_inv op_str opr opro oprob oprob_sw oprobi oprobi_p oprobit oprobitp opts_exclusive order orthog orthpoly ou out outf outfi outfil outfile outs outsh outshe outshee outsheet ovtest pac pac_7 palette parse parse_dissim pause pca pca_8 pca_display pca_estat pca_p pca_rotate pcamat pchart pchart_7 pchi pchi_7 pcorr pctile pentium pergram pergram_7 permute permute_8 personal peto_st pkcollapse pkcross pkequiv pkexamine pkexamine_7 pkshape pksumm pksumm_7 pl plo plot plugin pnorm pnorm_7 poisgof poiss_lf poiss_sw poisso_p poisson poisson_estat post postclose postfile postutil pperron pr prais prais_e prais_e2 prais_p predict predictnl preserve print pro prob probi probit probit_estat probit_p proc_time procoverlay procrustes procrustes_estat procrustes_p profiler prog progr progra program prop proportion prtest prtesti pwcorr pwd q\\s qby qbys qchi qchi_7 qladder qladder_7 qnorm qnorm_7 qqplot qqplot_7 qreg qreg_c qreg_p qreg_sw qu quadchk quantile quantile_7 que quer query range ranksum ratio rchart rchart_7 rcof recast reclink recode reg reg3 reg3_p regdw regr regre regre_p2 regres regres_p regress regress_estat regriv_p remap ren rena renam rename renpfix repeat replace report reshape restore ret retu retur return rm rmdir robvar roccomp roccomp_7 roccomp_8 rocf_lf rocfit rocfit_8 rocgold rocplot rocplot_7 roctab roctab_7 rolling rologit rologit_p rot rota rotat rotate rotatemat rreg rreg_p ru run runtest rvfplot rvfplot_7 rvpplot rvpplot_7 sa safesum sample sampsi sav save savedresults saveold sc sca scal scala scalar scatter scm_mine sco scob_lf scob_p scobi_sw scobit scor score scoreplot scoreplot_help scree screeplot screeplot_help sdtest sdtesti se search separate seperate serrbar serrbar_7 serset set set_defaults sfrancia sh she shel shell shewhart shewhart_7 signestimationsample signrank signtest simul simul_7 simulate simulate_8 sktest sleep slogit slogit_d2 slogit_p smooth snapspan so sor sort spearman spikeplot spikeplot_7 spikeplt spline_x split sqreg sqreg_p sret sretu sretur sreturn ssc st st_ct st_hc st_hcd st_hcd_sh st_is st_issys st_note st_promo st_set st_show st_smpl st_subid stack statsby statsby_8 stbase stci stci_7 stcox stcox_estat stcox_fr stcox_fr_ll stcox_p stcox_sw stcoxkm stcoxkm_7 stcstat stcurv stcurve stcurve_7 stdes stem stepwise stereg stfill stgen stir stjoin stmc stmh stphplot stphplot_7 stphtest stphtest_7 stptime strate strate_7 streg streg_sw streset sts sts_7 stset stsplit stsum sttocc sttoct stvary stweib su suest suest_8 sum summ summa summar summari summariz summarize sunflower sureg survcurv survsum svar svar_p svmat svy svy_disp svy_dreg svy_est svy_est_7 svy_estat svy_get svy_gnbreg_p svy_head svy_header svy_heckman_p svy_heckprob_p svy_intreg_p svy_ivreg_p svy_logistic_p svy_logit_p svy_mlogit_p svy_nbreg_p svy_ologit_p svy_oprobit_p svy_poisson_p svy_probit_p svy_regress_p svy_sub svy_sub_7 svy_x svy_x_7 svy_x_p svydes svydes_8 svygen svygnbreg svyheckman svyheckprob svyintreg svyintreg_7 svyintrg svyivreg svylc svylog_p svylogit svymarkout svymarkout_8 svymean svymlog svymlogit svynbreg svyolog svyologit svyoprob svyoprobit svyopts svypois svypois_7 svypoisson svyprobit svyprobt svyprop svyprop_7 svyratio svyreg svyreg_p svyregress svyset svyset_7 svyset_8 svytab svytab_7 svytest svytotal sw sw_8 swcnreg swcox swereg swilk swlogis swlogit swologit swoprbt swpois swprobit swqreg swtobit swweib symmetry symmi symplot symplot_7 syntax sysdescribe sysdir sysuse szroeter ta tab tab1 tab2 tab_or tabd tabdi tabdis tabdisp tabi table tabodds tabodds_7 tabstat tabu tabul tabula tabulat tabulate te tempfile tempname tempvar tes test testnl testparm teststd tetrachoric time_it timer tis tob tobi tobit tobit_p tobit_sw token tokeni tokeniz tokenize tostring total translate translator transmap treat_ll treatr_p treatreg trim trimfill trnb_cons trnb_mean trpoiss_d2 trunc_ll truncr_p truncreg tsappend tset tsfill tsline tsline_ex tsreport tsrevar tsrline tsset tssmooth tsunab ttest ttesti tut_chk tut_wait tutorial tw tware_st two twoway twoway__fpfit_serset twoway__function_gen twoway__histogram_gen twoway__ipoint_serset twoway__ipoints_serset twoway__kdensity_gen twoway__lfit_serset twoway__normgen_gen twoway__pci_serset twoway__qfit_serset twoway__scatteri_serset twoway__sunflower_gen twoway_ksm_serset ty typ type typeof u|0 unab unabbrev unabcmd update us use uselabel var var_mkcompanion var_p varbasic varfcast vargranger varirf varirf_add varirf_cgraph varirf_create varirf_ctable varirf_describe varirf_dir varirf_drop varirf_erase varirf_graph varirf_ograph varirf_rename varirf_set varirf_table varlist varlmar varnorm varsoc varstable varstable_w varstable_w2 varwle vce vec vec_fevd vec_mkphi vec_p vec_p_w vecirf_create veclmar veclmar_w vecnorm vecnorm_w vecrank vecstable verinst vers versi versio version view viewsource vif vwls wdatetof webdescribe webseek webuse weib1_lf weib2_lf weib_lf weib_lf0 weibhet_glf weibhet_glf_sh weibhet_glfa weibhet_glfa_sh weibhet_gp weibhet_ilf weibhet_ilf_sh weibhet_ilfa weibhet_ilfa_sh weibhet_ip weibu_sw weibul_p weibull weibull_c weibull_s weibullhet wh whelp whi which whil while wilc_st wilcoxon win wind windo window winexec wntestb wntestb_7 wntestq xchart xchart_7 xcorr xcorr_7 xi xi_6 xmlsav xmlsave xmluse xpose xsh xshe xshel xshell xt_iis xt_tis xtab_p xtabond xtbin_p xtclog xtcloglog xtcloglog_8 xtcloglog_d2 xtcloglog_pa_p xtcloglog_re_p xtcnt_p xtcorr xtdata xtdes xtfront_p xtfrontier xtgee xtgee_elink xtgee_estat xtgee_makeivar xtgee_p xtgee_plink xtgls xtgls_p xthaus xthausman xtht_p xthtaylor xtile xtint_p xtintreg xtintreg_8 xtintreg_d2 xtintreg_p xtivp_1 xtivp_2 xtivreg xtline xtline_ex xtlogit xtlogit_8 xtlogit_d2 xtlogit_fe_p xtlogit_pa_p xtlogit_re_p xtmixed xtmixed_estat xtmixed_p xtnb_fe xtnb_lf xtnbreg xtnbreg_pa_p xtnbreg_refe_p xtpcse xtpcse_p xtpois xtpoisson xtpoisson_d2 xtpoisson_pa_p xtpoisson_refe_p xtpred xtprobit xtprobit_8 xtprobit_d2 xtprobit_re_p xtps_fe xtps_lf xtps_ren xtps_ren_8 xtrar_p xtrc xtrc_p xtrchh xtrefe_p xtreg xtreg_be xtreg_fe xtreg_ml xtreg_pa_p xtreg_re xtregar xtrere_p xtset xtsf_ll xtsf_llti xtsum xttab xttest0 xttobit xttobit_8 xttobit_p xttrans yx yxview__barlike_draw yxview_area_draw yxview_bar_draw yxview_dot_draw yxview_dropline_draw yxview_function_draw yxview_iarrow_draw yxview_ilabels_draw yxview_normal_draw yxview_pcarrow_draw yxview_pcbarrow_draw yxview_pccapsym_draw yxview_pcscatter_draw yxview_pcspike_draw yxview_rarea_draw yxview_rbar_draw yxview_rbarm_draw yxview_rcap_draw yxview_rcapsym_draw yxview_rconnected_draw yxview_rline_draw yxview_rscatter_draw yxview_rspike_draw yxview_spike_draw yxview_sunflower_draw zap_s zinb zinb_llf zinb_plf zip zip_llf zip_p zip_plf zt_ct_5 zt_hc_5 zt_hcd_5 zt_is_5 zt_iss_5 zt_sho_5 zt_smp_5 ztbase_5 ztcox_5 ztdes_5 ztereg_5 ztfill_5 ztgen_5 ztir_5 ztjoin_5 ztnb ztnb_p ztp ztp_p zts_5 ztset_5 ztspli_5 ztsum_5 zttoct_5 ztvary_5 ztweib_5","contains":[{"className":"symbol","begin":"`[a-zA-Z0-9_]+'"},{"className":"variable","begin":"\\$\\{?[a-zA-Z0-9_]+\\}?"},{"className":"string","variants":[{"begin":"`\"[^\r\n]*?\"'"},{"begin":"\"[^\r\n\"]*\""}]},{"className":"built_in","variants":[{"begin":"\\b(abs|acos|asin|atan|atan2|atanh|ceil|cloglog|comb|cos|digamma|exp|floor|invcloglog|invlogit|ln|lnfact|lnfactorial|lngamma|log|log10|max|min|mod|reldif|round|sign|sin|sqrt|sum|tan|tanh|trigamma|trunc|betaden|Binomial|binorm|binormal|chi2|chi2tail|dgammapda|dgammapdada|dgammapdadx|dgammapdx|dgammapdxdx|F|Fden|Ftail|gammaden|gammap|ibeta|invbinomial|invchi2|invchi2tail|invF|invFtail|invgammap|invibeta|invnchi2|invnFtail|invnibeta|invnorm|invnormal|invttail|nbetaden|nchi2|nFden|nFtail|nibeta|norm|normal|normalden|normd|npnchi2|tden|ttail|uniform|abbrev|char|index|indexnot|length|lower|ltrim|match|plural|proper|real|regexm|regexr|regexs|reverse|rtrim|string|strlen|strlower|strltrim|strmatch|strofreal|strpos|strproper|strreverse|strrtrim|strtrim|strupper|subinstr|subinword|substr|trim|upper|word|wordcount|_caller|autocode|byteorder|chop|clip|cond|e|epsdouble|epsfloat|group|inlist|inrange|irecode|matrix|maxbyte|maxdouble|maxfloat|maxint|maxlong|mi|minbyte|mindouble|minfloat|minint|minlong|missing|r|recode|replay|return|s|scalar|d|date|day|dow|doy|halfyear|mdy|month|quarter|week|year|d|daily|dofd|dofh|dofm|dofq|dofw|dofy|h|halfyearly|hofd|m|mofd|monthly|q|qofd|quarterly|tin|twithin|w|weekly|wofd|y|yearly|yh|ym|yofd|yq|yw|cholesky|colnumb|colsof|corr|det|diag|diag0cnt|el|get|hadamard|I|inv|invsym|issym|issymmetric|J|matmissing|matuniform|mreldif|nullmat|rownumb|rowsof|sweep|syminv|trace|vec|vecdiag)(?=\\(|$)"}]},{"className":"comment","begin":"^[ \t]*\\*.*$","end":false,"contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"//","end":"$","contains":[{"$ref":"#contains.4.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"/\\*","end":"\\*/","contains":[{"$ref":"#contains.4.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/step21.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/step21.json new file mode 100644 index 00000000..c2f2a067 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/step21.json @@ -0,0 +1 @@ +{"aliases":["p21","step","stp"],"case_insensitive":true,"lexemes":"[A-Z_][A-Z0-9_.]*","keywords":{"keyword":"HEADER ENDSEC DATA"},"contains":[{"className":"meta","begin":"ISO-10303-21;","relevance":10},{"className":"meta","begin":"END-ISO-10303-21;","relevance":10},{"className":"comment","begin":"//","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"/\\*","end":"\\*/","contains":[{"$ref":"#contains.2.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"/\\*\\*!","end":"\\*/","contains":[{"$ref":"#contains.2.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"number","begin":"(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)","relevance":0},{"className":"string","begin":"'","end":"'","illegal":null,"contains":[{"begin":"\\\\[\\s\\S]","relevance":0}]},{"className":"string","begin":"\"","end":"\"","illegal":null,"contains":[{"$ref":"#contains.6.contains.0"},{"className":"subst","begin":"\\\\[abfnrtv]\\|\\\\x[0-9a-fA-F]*\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]","relevance":0},{"className":"subst","begin":"\\\\[abfnrtv]\\|\\\\x[0-9a-fA-F]*\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]","relevance":0}]},{"className":"string","begin":"'","end":"'"},{"className":"symbol","variants":[{"begin":"#","end":"\\d+","illegal":"\\W"}]}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/stylus.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/stylus.json new file mode 100644 index 00000000..e049e869 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/stylus.json @@ -0,0 +1 @@ +{"aliases":["styl"],"case_insensitive":false,"keywords":"if else for in","illegal":"(\\?|(\\bReturn\\b)|(\\bEnd\\b)|(\\bend\\b)|(\\bdef\\b)|;|#\\s|\\*\\s|===\\s|\\||%)","contains":[{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0},{"className":"subst","begin":"\\\\[abfnrtv]\\|\\\\x[0-9a-fA-F]*\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]","relevance":0},{"className":"subst","begin":"\\\\[abfnrtv]\\|\\\\x[0-9a-fA-F]*\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]","relevance":0}]},{"className":"string","begin":"'","end":"'","illegal":"\\n","contains":[{"$ref":"#contains.0.contains.0"}]},{"className":"comment","begin":"//","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"/\\*","end":"\\*/","contains":[{"$ref":"#contains.2.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"number","begin":"#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})"},{"begin":"\\.[a-zA-Z][a-zA-Z0-9_-]*[\\.\\s\\n\\[\\:,]","returnBegin":true,"contains":[{"className":"selector-class","begin":"\\.[a-zA-Z][a-zA-Z0-9_-]*"}]},{"begin":"\\#[a-zA-Z][a-zA-Z0-9_-]*[\\.\\s\\n\\[\\:,]","returnBegin":true,"contains":[{"className":"selector-id","begin":"\\#[a-zA-Z][a-zA-Z0-9_-]*"}]},{"begin":"\\b(a|abbr|address|article|aside|audio|b|blockquote|body|button|canvas|caption|cite|code|dd|del|details|dfn|div|dl|dt|em|fieldset|figcaption|figure|footer|form|h1|h2|h3|h4|h5|h6|header|hgroup|html|i|iframe|img|input|ins|kbd|label|legend|li|mark|menu|nav|object|ol|p|q|quote|samp|section|span|strong|summary|sup|table|tbody|td|textarea|tfoot|th|thead|time|tr|ul|var|video)[\\.\\s\\n\\[\\:,]","returnBegin":true,"contains":[{"className":"selector-tag","begin":"\\b[a-zA-Z][a-zA-Z0-9_-]*"}]},{"begin":"&?:?:\\b(after|before|first-letter|first-line|active|first-child|focus|hover|lang|link|visited)[\\.\\s\\n\\[\\:,]"},{"begin":"@(charset|css|debug|extend|font-face|for|import|include|media|mixin|page|warn|while)\\b"},{"className":"variable","begin":"\\$[a-zA-Z]\\w*"},{"className":"number","begin":"\\b\\d+(\\.\\d+)?(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?","relevance":0},{"className":"number","begin":"\\b\\d+(\\.\\d+)?","relevance":0},{"className":"function","begin":"^[a-zA-Z][a-zA-Z0-9_-]*\\(.*\\)","illegal":"[\\n]","returnBegin":true,"contains":[{"className":"title","begin":"\\b[a-zA-Z][a-zA-Z0-9_-]*"},{"className":"params","begin":"\\(","end":"\\)","contains":[{"$ref":"#contains.4"},{"$ref":"#contains.10"},{"$ref":"#contains.1"},{"$ref":"#contains.11"},{"$ref":"#contains.12"},{"$ref":"#contains.0"}]}]},{"className":"attribute","begin":"\\b(z-index|word-wrap|word-spacing|word-break|width|widows|white-space|visibility|vertical-align|unicode-bidi|transition-timing-function|transition-property|transition-duration|transition-delay|transition|transform-style|transform-origin|transform|top|text-underline-position|text-transform|text-shadow|text-rendering|text-overflow|text-indent|text-decoration-style|text-decoration-line|text-decoration-color|text-decoration|text-align-last|text-align|table-layout|tab-size|right|resize|quotes|position|pointer-events|perspective-origin|perspective|page-break-inside|page-break-before|page-break-after|padding-top|padding-right|padding-left|padding-bottom|padding|overflow-y|overflow-x|overflow-wrap|overflow|outline-width|outline-style|outline-offset|outline-color|outline|orphans|order|opacity|object-position|object-fit|normal|none|nav-up|nav-right|nav-left|nav-index|nav-down|min-width|min-height|max-width|max-height|mask|marks|margin-top|margin-right|margin-left|margin-bottom|margin|list-style-type|list-style-position|list-style-image|list-style|line-height|letter-spacing|left|justify-content|initial|inherit|ime-mode|image-resolution|image-rendering|image-orientation|icon|hyphens|height|font-weight|font-variant-ligatures|font-variant|font-style|font-stretch|font-size-adjust|font-size|font-language-override|font-kerning|font-feature-settings|font-family|font|float|flex-wrap|flex-shrink|flex-grow|flex-flow|flex-direction|flex-basis|flex|filter|empty-cells|display|direction|cursor|counter-reset|counter-increment|content|columns|column-width|column-span|column-rule-width|column-rule-style|column-rule-color|column-rule|column-gap|column-fill|column-count|color|clip-path|clip|clear|caption-side|break-inside|break-before|break-after|box-sizing|box-shadow|box-decoration-break|bottom|border-width|border-top-width|border-top-style|border-top-right-radius|border-top-left-radius|border-top-color|border-top|border-style|border-spacing|border-right-width|border-right-style|border-right-color|border-right|border-radius|border-left-width|border-left-style|border-left-color|border-left|border-image-width|border-image-source|border-image-slice|border-image-repeat|border-image-outset|border-image|border-color|border-collapse|border-bottom-width|border-bottom-style|border-bottom-right-radius|border-bottom-left-radius|border-bottom-color|border-bottom|border|background-size|background-repeat|background-position|background-origin|background-image|background-color|background-clip|background-attachment|background|backface-visibility|auto|animation-timing-function|animation-play-state|animation-name|animation-iteration-count|animation-fill-mode|animation-duration|animation-direction|animation-delay|animation|align-self|align-items|align-content)\\b","starts":{"end":";|$","contains":[{"$ref":"#contains.4"},{"$ref":"#contains.10"},{"$ref":"#contains.1"},{"$ref":"#contains.0"},{"$ref":"#contains.11"},{"$ref":"#contains.12"},{"$ref":"#contains.3"}],"illegal":"\\.","relevance":0}}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/subunit.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/subunit.json new file mode 100644 index 00000000..8dcc6f6d --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/subunit.json @@ -0,0 +1 @@ +{"case_insensitive":true,"contains":[{"className":"string","begin":"\\[\n(multipart)?","end":"\\]\n"},{"className":"string","begin":"\\d{4}-\\d{2}-\\d{2}(\\s+)\\d{2}:\\d{2}:\\d{2}.\\d+Z"},{"className":"string","begin":"(\\+|-)\\d+"},{"className":"keyword","relevance":10,"variants":[{"begin":"^(test|testing|success|successful|failure|error|skip|xfail|uxsuccess)(:?)\\s+(test)?"},{"begin":"^progress(:?)(\\s+)?(pop|push)?"},{"begin":"^tags:"},{"begin":"^time:"}]}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/swift.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/swift.json new file mode 100644 index 00000000..b3ef0d23 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/swift.json @@ -0,0 +1 @@ +{"keywords":{"keyword":"#available #colorLiteral #column #else #elseif #endif #file #fileLiteral #function #if #imageLiteral #line #selector #sourceLocation _ __COLUMN__ __FILE__ __FUNCTION__ __LINE__ Any as as! as? associatedtype associativity break case catch class continue convenience default defer deinit didSet do dynamic dynamicType else enum extension fallthrough false fileprivate final for func get guard if import in indirect infix init inout internal is lazy left let mutating nil none nonmutating open operator optional override postfix precedence prefix private protocol Protocol public repeat required rethrows return right self Self set static struct subscript super switch throw throws true try try! try? Type typealias unowned var weak where while willSet","literal":"true false nil","built_in":"abs advance alignof alignofValue anyGenerator assert assertionFailure bridgeFromObjectiveC bridgeFromObjectiveCUnconditional bridgeToObjectiveC bridgeToObjectiveCUnconditional c contains count countElements countLeadingZeros debugPrint debugPrintln distance dropFirst dropLast dump encodeBitsAsWords enumerate equal fatalError filter find getBridgedObjectiveCType getVaList indices insertionSort isBridgedToObjectiveC isBridgedVerbatimToObjectiveC isUniquelyReferenced isUniquelyReferencedNonObjC join lazy lexicographicalCompare map max maxElement min minElement numericCast overlaps partition posix precondition preconditionFailure print println quickSort readLine reduce reflect reinterpretCast reverse roundUpToAlignment sizeof sizeofValue sort split startsWith stride strideof strideofValue swap toString transcode underestimateCount unsafeAddressOf unsafeBitCast unsafeDowncast unsafeUnwrap unsafeReflect withExtendedLifetime withObjectAtPlusZero withUnsafePointer withUnsafePointerToObject withUnsafeMutablePointer withUnsafeMutablePointers withUnsafePointer withUnsafePointers withVaList zip"},"contains":[{"className":"string","contains":[{"begin":"\\\\[\\s\\S]","relevance":0},{"className":"subst","begin":"\\\\\\(","end":"\\)","keywords":{"$ref":"#keywords"},"contains":[{"className":"number","begin":"\\b([\\d_]+(\\.[\\deE_]+)?|0x[a-fA-F0-9_]+(\\.[a-fA-F0-9p_]+)?|0b[01_]+|0o[0-7_]+)\\b","relevance":0}]}],"variants":[{"begin":"\"\"\"","end":"\"\"\""},{"begin":"\"","end":"\""}]},{"className":"comment","begin":"//","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"/\\*","end":"\\*/","contains":["self",{"$ref":"#contains.1.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"type","begin":"\\b[A-Z][\\wÀ-ʸ']*[!?]"},{"className":"type","begin":"\\b[A-Z][\\wÀ-ʸ']*","relevance":0},{"$ref":"#contains.0.contains.1.contains.0"},{"className":"function","beginKeywords":"func","end":"{","excludeEnd":true,"contains":[{"className":"title","begin":"[A-Za-z$_][0-9A-Za-z$_]*","relevance":0},{"begin":"<","end":">"},{"className":"params","begin":"\\(","end":"\\)","endsParent":true,"keywords":{"$ref":"#keywords"},"contains":["self",{"$ref":"#contains.0.contains.1.contains.0"},{"$ref":"#contains.0"},{"className":"comment","begin":"/\\*","end":"\\*/","contains":[{"$ref":"#contains.1.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"begin":":"}],"illegal":"[\"']"}],"illegal":"\\[|%"},{"className":"class","beginKeywords":"struct protocol class extension enum","keywords":{"$ref":"#keywords"},"end":"\\{","excludeEnd":true,"contains":[{"className":"title","begin":"[A-Za-z$_][\\x{00C0}-\\x{02B80}-9A-Za-z$_]*","relevance":0}]},{"className":"meta","begin":"(@discardableResult|@warn_unused_result|@exported|@lazy|@noescape|@NSCopying|@NSManaged|@objc|@objcMembers|@convention|@required|@noreturn|@IBAction|@IBDesignable|@IBInspectable|@IBOutlet|@infix|@prefix|@postfix|@autoclosure|@testable|@available|@nonobjc|@NSApplicationMain|@UIApplicationMain)"},{"beginKeywords":"import","end":"$","contains":[{"$ref":"#contains.1"},{"$ref":"#contains.2"}]}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/taggerscript.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/taggerscript.json new file mode 100644 index 00000000..d5fdacc1 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/taggerscript.json @@ -0,0 +1 @@ +{"contains":[{"className":"comment","begin":"\\$noop\\(","end":"\\)","contains":[{"begin":"\\(","end":"\\)","contains":["self",{"begin":"\\\\."}]}],"relevance":10},{"className":"keyword","begin":"\\$(?!noop)[a-zA-Z][_a-zA-Z0-9]*","end":"\\(","excludeEnd":true},{"className":"variable","begin":"%[_a-zA-Z0-9:]*","end":"%"},{"className":"symbol","begin":"\\\\."}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/tap.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/tap.json new file mode 100644 index 00000000..d2689d9b --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/tap.json @@ -0,0 +1 @@ +{"case_insensitive":true,"contains":[{"className":"comment","begin":"#","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"meta","variants":[{"begin":"^TAP version (\\d+)$"},{"begin":"^1\\.\\.(\\d+)$"}]},{"begin":"(s+)?---$","end":"\\.\\.\\.$","subLanguage":"yaml","relevance":0},{"className":"number","begin":" (\\d+) "},{"className":"symbol","variants":[{"begin":"^ok"},{"begin":"^not ok"}]}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/tcl.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/tcl.json new file mode 100644 index 00000000..cfdf76cb --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/tcl.json @@ -0,0 +1 @@ +{"aliases":["tk"],"keywords":"after append apply array auto_execok auto_import auto_load auto_mkindex auto_mkindex_old auto_qualify auto_reset bgerror binary break catch cd chan clock close concat continue dde dict encoding eof error eval exec exit expr fblocked fconfigure fcopy file fileevent filename flush for foreach format gets glob global history http if incr info interp join lappend|10 lassign|10 lindex|10 linsert|10 list llength|10 load lrange|10 lrepeat|10 lreplace|10 lreverse|10 lsearch|10 lset|10 lsort|10 mathfunc mathop memory msgcat namespace open package parray pid pkg::create pkg_mkIndex platform platform::shell proc puts pwd read refchan regexp registry regsub|10 rename return safe scan seek set socket source split string subst switch tcl_endOfWord tcl_findLibrary tcl_startOfNextWord tcl_startOfPreviousWord tcl_wordBreakAfter tcl_wordBreakBefore tcltest tclvars tell time tm trace unknown unload unset update uplevel upvar variable vwait while","contains":[{"className":"comment","begin":";[ \\t]*#","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"^[ \\t]*#","end":"$","contains":[{"$ref":"#contains.0.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"beginKeywords":"proc","end":"[\\{]","excludeEnd":true,"contains":[{"className":"title","begin":"[ \\t\\n\\r]+(::)?[a-zA-Z_]((::)?[a-zA-Z0-9_])*","end":"[ \\t\\n\\r]","endsWithParent":true,"excludeEnd":true}]},{"excludeEnd":true,"variants":[{"begin":"\\$(\\{)?(::)?[a-zA-Z_]((::)?[a-zA-Z0-9_])*\\(([a-zA-Z0-9_])*\\)","end":"[^a-zA-Z0-9_\\}\\$]"},{"begin":"\\$(\\{)?(::)?[a-zA-Z_]((::)?[a-zA-Z0-9_])*","end":"(\\))?[^a-zA-Z0-9_\\}\\$]"}]},{"className":"string","contains":[{"begin":"\\\\[\\s\\S]","relevance":0}],"variants":[{"className":"string","begin":"\"","end":"\"","illegal":null,"contains":[{"$ref":"#contains.4.contains.0"},{"className":"subst","begin":"\\\\[abfnrtv]\\|\\\\x[0-9a-fA-F]*\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]","relevance":0},{"className":"subst","begin":"\\\\[abfnrtv]\\|\\\\x[0-9a-fA-F]*\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]","relevance":0}]}]},{"className":"number","variants":[{"className":"number","begin":"\\b(0b[01]+)","relevance":0},{"className":"number","begin":"(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)","relevance":0}]}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/tex.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/tex.json new file mode 100644 index 00000000..916e09c4 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/tex.json @@ -0,0 +1 @@ +{"contains":[{"className":"tag","begin":"\\\\","relevance":0,"contains":[{"className":"name","variants":[{"begin":"[a-zA-Z\\x{0430}-\\x{044f}\\x{0410}-\\x{042f}]+[*]?"},{"begin":"[^a-zA-Z\\x{0430}-\\x{044f}\\x{0410}-\\x{042f0}-9]"}],"starts":{"endsWithParent":true,"relevance":0,"contains":[{"className":"string","variants":[{"begin":"\\[","end":"\\]"},{"begin":"\\{","end":"\\}"}]},{"begin":"\\s*=\\s*","endsWithParent":true,"relevance":0,"contains":[{"className":"number","begin":"-?\\d*\\.?\\d+(pt|pc|mm|cm|in|dd|cc|ex|em)?"}]}]}}]},{"className":"formula","contains":[{"$ref":"#contains.0"}],"relevance":0,"variants":[{"begin":"\\$\\$","end":"\\$\\$"},{"begin":"\\$","end":"\\$"}]},{"className":"comment","begin":"%","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}],"relevance":0}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/thrift.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/thrift.json new file mode 100644 index 00000000..71b9bc32 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/thrift.json @@ -0,0 +1 @@ +{"keywords":{"keyword":"namespace const typedef struct enum service exception void oneway set list map required optional","built_in":"bool byte i16 i32 i64 double string binary","literal":"true false"},"contains":[{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0},{"className":"subst","begin":"\\\\[abfnrtv]\\|\\\\x[0-9a-fA-F]*\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]","relevance":0},{"className":"subst","begin":"\\\\[abfnrtv]\\|\\\\x[0-9a-fA-F]*\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]","relevance":0}]},{"className":"number","begin":"\\b\\d+(\\.\\d+)?","relevance":0},{"className":"comment","begin":"//","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"/\\*","end":"\\*/","contains":[{"$ref":"#contains.2.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"class","beginKeywords":"struct enum service exception","end":"\\{","illegal":"\\n","contains":[{"className":"title","begin":"[a-zA-Z]\\w*","relevance":0,"starts":{"endsWithParent":true,"excludeEnd":true}}]},{"begin":"\\b(set|list|map)\\s*<","end":">","keywords":"bool byte i16 i32 i64 double string binary","contains":["self"]}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/tp.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/tp.json new file mode 100644 index 00000000..d26dd467 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/tp.json @@ -0,0 +1 @@ +{"keywords":{"keyword":"ABORT ACC ADJUST AND AP_LD BREAK CALL CNT COL CONDITION CONFIG DA DB DIV DETECT ELSE END ENDFOR ERR_NUM ERROR_PROG FINE FOR GP GUARD INC IF JMP LINEAR_MAX_SPEED LOCK MOD MONITOR OFFSET Offset OR OVERRIDE PAUSE PREG PTH RT_LD RUN SELECT SKIP Skip TA TB TO TOOL_OFFSET Tool_Offset UF UT UFRAME_NUM UTOOL_NUM UNLOCK WAIT X Y Z W P R STRLEN SUBSTR FINDSTR VOFFSET PROG ATTR MN POS","literal":"ON OFF max_speed LPOS JPOS ENABLE DISABLE START STOP RESET"},"contains":[{"className":"built_in","begin":"(AR|P|PAYLOAD|PR|R|SR|RSR|LBL|VR|UALM|MESSAGE|UTOOL|UFRAME|TIMER|TIMER_OVERFLOW|JOINT_MAX_SPEED|RESUME_PROG|DIAG_REC)\\[","end":"\\]","contains":["self",{"className":"number","begin":"[1-9][0-9]*","relevance":0},{"className":"symbol","begin":":[^\\]]+"}]},{"className":"built_in","begin":"(AI|AO|DI|DO|F|RI|RO|UI|UO|GI|GO|SI|SO)\\[","end":"\\]","contains":["self",{"$ref":"#contains.0.contains.1"},{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0},{"className":"subst","begin":"\\\\[abfnrtv]\\|\\\\x[0-9a-fA-F]*\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]","relevance":0},{"className":"subst","begin":"\\\\[abfnrtv]\\|\\\\x[0-9a-fA-F]*\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]","relevance":0}]},{"$ref":"#contains.0.contains.2"}]},{"className":"keyword","begin":"/(PROG|ATTR|MN|POS|END)\\b"},{"className":"keyword","begin":"(CALL|RUN|POINT_LOGIC|LBL)\\b"},{"className":"keyword","begin":"\\b(ACC|CNT|Skip|Offset|PSPD|RT_LD|AP_LD|Tool_Offset)"},{"className":"number","begin":"\\d+(sec|msec|mm/sec|cm/min|inch/min|deg/sec|mm|in|cm)?\\b","relevance":0},{"className":"comment","begin":"//","end":"[;$]","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"!","end":"[;$]","contains":[{"$ref":"#contains.6.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"--eg:","end":"$","contains":[{"$ref":"#contains.6.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"$ref":"#contains.1.contains.2"},{"className":"string","begin":"'","end":"'"},{"className":"number","begin":"(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)","relevance":0},{"className":"variable","begin":"\\$[A-Za-z0-9_]+"}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/twig.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/twig.json new file mode 100644 index 00000000..6607396b --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/twig.json @@ -0,0 +1 @@ +{"aliases":["craftcms"],"case_insensitive":true,"subLanguage":"xml","contains":[{"className":"comment","begin":"\\{#","end":"#}","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"template-tag","begin":"\\{%","end":"%}","contains":[{"className":"name","begin":"\\w+","keywords":"autoescape block do embed extends filter flush for if import include macro sandbox set spaceless use verbatim endautoescape endblock enddo endembed endextends endfilter endflush endfor endif endimport endinclude endmacro endsandbox endset endspaceless enduse endverbatim","starts":{"endsWithParent":true,"contains":[{"begin":"\\|[A-Za-z_]+:?","keywords":"abs batch capitalize convert_encoding date date_modify default escape first format join json_encode keys last length lower merge nl2br number_format raw replace reverse round slice sort split striptags title trim upper url_encode","contains":[{"beginKeywords":"attribute block constant cycle date dump include max min parent random range source template_from_string","keywords":{"name":"attribute block constant cycle date dump include max min parent random range source template_from_string"},"relevance":0,"contains":[{"className":"params","begin":"\\(","end":"\\)"}]}]},{"$ref":"#contains.1.contains.0.starts.contains.0.contains.0"}],"relevance":0}}]},{"className":"template-variable","begin":"\\{\\{","end":"}}","contains":["self",{"$ref":"#contains.1.contains.0.starts.contains.0"},{"$ref":"#contains.1.contains.0.starts.contains.0.contains.0"}]}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/typescript.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/typescript.json new file mode 100644 index 00000000..45eb0a78 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/typescript.json @@ -0,0 +1 @@ +{"aliases":["ts"],"keywords":{"keyword":"in if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const class public private protected get set super static implements enum export import declare type namespace abstract as from extends async await","literal":"true false null undefined NaN Infinity","built_in":"eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError TypeError URIError Number Math Date String RegExp Array Float32Array Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require module console window document any number boolean string void Promise"},"contains":[{"className":"meta","begin":"^\\s*['\"]use strict['\"]"},{"className":"string","begin":"'","end":"'","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0}]},{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"$ref":"#contains.1.contains.0"},{"className":"subst","begin":"\\\\[abfnrtv]\\|\\\\x[0-9a-fA-F]*\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]","relevance":0},{"className":"subst","begin":"\\\\[abfnrtv]\\|\\\\x[0-9a-fA-F]*\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]","relevance":0}]},{"begin":"html`","end":"","starts":{"end":"`","returnEnd":false,"contains":[{"$ref":"#contains.1.contains.0"},{"className":"subst","begin":"\\$\\{","end":"\\}","keywords":{"$ref":"#keywords"},"contains":[{"$ref":"#contains.1"},{"$ref":"#contains.2"},{"$ref":"#contains.3"},{"begin":"css`","end":"","starts":{"end":"`","returnEnd":false,"contains":[{"$ref":"#contains.1.contains.0"},{"$ref":"#contains.3.starts.contains.1"}],"subLanguage":"css"}},{"className":"string","begin":"`","end":"`","contains":[{"$ref":"#contains.1.contains.0"},{"$ref":"#contains.3.starts.contains.1"}]},{"className":"number","variants":[{"begin":"\\b(0[bB][01]+)"},{"begin":"\\b(0[oO][0-7]+)"},{"begin":"(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)"}],"relevance":0},{"className":"regexp","begin":"\\/","end":"\\/[gimuy]*","illegal":"\\n","contains":[{"$ref":"#contains.1.contains.0"},{"begin":"\\[","end":"\\]","relevance":0,"contains":[{"$ref":"#contains.1.contains.0"}]}]}]}],"subLanguage":"xml"}},{"$ref":"#contains.3.starts.contains.1.contains.3"},{"$ref":"#contains.3.starts.contains.1.contains.4"},{"className":"comment","begin":"//","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"/\\*","end":"\\*/","contains":[{"$ref":"#contains.6.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"$ref":"#contains.3.starts.contains.1.contains.5"},{"begin":"(!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~|\\b(case|return|throw)\\b)\\s*","keywords":"return throw case","contains":[{"$ref":"#contains.6"},{"$ref":"#contains.7"},{"$ref":"#contains.3.starts.contains.1.contains.6"},{"className":"function","begin":"(\\(.*?\\)|[a-zA-Z]\\w*)\\s*=>","returnBegin":true,"end":"\\s*=>","contains":[{"className":"params","variants":[{"begin":"[a-zA-Z]\\w*"},{"begin":"\\(\\s*\\)"},{"begin":"\\(","end":"\\)","excludeBegin":true,"excludeEnd":true,"keywords":{"$ref":"#keywords"},"contains":["self",{"$ref":"#contains.6"},{"$ref":"#contains.7"}]}]}]}],"relevance":0},{"className":"function","begin":"function","end":"[\\{;]","excludeEnd":true,"keywords":{"$ref":"#keywords"},"contains":["self",{"className":"title","begin":"[A-Za-z$_][0-9A-Za-z$_]*","relevance":0},{"className":"params","begin":"\\(","end":"\\)","excludeBegin":true,"excludeEnd":true,"keywords":{"$ref":"#keywords"},"contains":[{"$ref":"#contains.6"},{"$ref":"#contains.7"},{"className":"meta","begin":"@[A-Za-z$_][0-9A-Za-z$_]*"},{"begin":"\\(","end":"\\)","keywords":{"$ref":"#keywords"},"contains":["self",{"$ref":"#contains.2"},{"$ref":"#contains.1"},{"className":"number","begin":"\\b\\d+(\\.\\d+)?","relevance":0}]}]}],"illegal":"%","relevance":0},{"beginKeywords":"constructor","end":"\\{","excludeEnd":true,"contains":["self",{"$ref":"#contains.10.contains.2"}]},{"begin":"module\\.","keywords":{"built_in":"module"},"relevance":0},{"beginKeywords":"module","end":"\\{","excludeEnd":true},{"beginKeywords":"interface","end":"\\{","excludeEnd":true,"keywords":"interface extends"},{"begin":"\\$[(.]"},{"begin":"\\.[a-zA-Z]\\w*","relevance":0},{"$ref":"#contains.10.contains.2.contains.2"},{"$ref":"#contains.10.contains.2.contains.3"}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/vala.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/vala.json new file mode 100644 index 00000000..3c22e27f --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/vala.json @@ -0,0 +1 @@ +{"keywords":{"keyword":"char uchar unichar int uint long ulong short ushort int8 int16 int32 int64 uint8 uint16 uint32 uint64 float double bool struct enum string void weak unowned owned async signal static abstract interface override virtual delegate if while do for foreach else switch case break default return try catch public private protected internal using new this get set const stdout stdin stderr var","built_in":"DBus GLib CCode Gee Object Gtk Posix","literal":"false true null"},"contains":[{"className":"class","beginKeywords":"class interface namespace","end":"{","excludeEnd":true,"illegal":"[^,:\\n\\s\\.]","contains":[{"className":"title","begin":"[a-zA-Z_]\\w*","relevance":0}]},{"className":"comment","begin":"//","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"/\\*","end":"\\*/","contains":[{"$ref":"#contains.1.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"string","begin":"\"\"\"","end":"\"\"\"","relevance":5},{"className":"string","begin":"'","end":"'","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0}]},{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"$ref":"#contains.4.contains.0"},{"className":"subst","begin":"\\\\[abfnrtv]\\|\\\\x[0-9a-fA-F]*\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]","relevance":0},{"className":"subst","begin":"\\\\[abfnrtv]\\|\\\\x[0-9a-fA-F]*\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]","relevance":0}]},{"className":"number","begin":"(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)","relevance":0},{"className":"meta","begin":"^#","end":"$","relevance":2}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/vbnet.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/vbnet.json new file mode 100644 index 00000000..63057418 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/vbnet.json @@ -0,0 +1 @@ +{"aliases":["vb"],"case_insensitive":true,"keywords":{"keyword":"addhandler addressof alias and andalso aggregate ansi as assembly auto binary by byref byval call case catch class compare const continue custom declare default delegate dim distinct do each equals else elseif end enum erase error event exit explicit finally for friend from function get global goto group handles if implements imports in inherits interface into is isfalse isnot istrue join key let lib like loop me mid mod module mustinherit mustoverride mybase myclass namespace narrowing new next not notinheritable notoverridable of off on operator option optional or order orelse overloads overridable overrides paramarray partial preserve private property protected public raiseevent readonly redim rem removehandler resume return select set shadows shared skip static step stop structure strict sub synclock take text then throw to try unicode until using when where while widening with withevents writeonly xor","built_in":"boolean byte cbool cbyte cchar cdate cdec cdbl char cint clng cobj csbyte cshort csng cstr ctype date decimal directcast double gettype getxmlnamespace iif integer long object sbyte short single string trycast typeof uinteger ulong ushort","literal":"true false nothing"},"illegal":"//|{|}|endif|gosub|variant|wend|^\\$ ","contains":[{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"begin":"\"\""}]},{"className":"comment","begin":"'","end":"$","contains":[{"className":"doctag","begin":"'''|","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"}]},{"className":"doctag","begin":"","contains":[{"$ref":"#contains.1.contains.0.contains.0"}]},{"$ref":"#contains.1.contains.0.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}],"returnBegin":true},{"className":"number","begin":"(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)","relevance":0},{"className":"meta","begin":"#","end":"$","keywords":{"meta-keyword":"if else elseif end region externalsource"}}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/vbscript-html.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/vbscript-html.json new file mode 100644 index 00000000..6b83a37b --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/vbscript-html.json @@ -0,0 +1 @@ +{"subLanguage":"xml","contains":[{"begin":"<%","end":"%>","subLanguage":"vbscript"}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/vbscript.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/vbscript.json new file mode 100644 index 00000000..504b673c --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/vbscript.json @@ -0,0 +1 @@ +{"aliases":["vbs"],"case_insensitive":true,"keywords":{"keyword":"call class const dim do loop erase execute executeglobal exit for each next function if then else on error option explicit new private property let get public randomize redim rem select case set stop sub while wend with end to elseif is or xor and not class_initialize class_terminate default preserve in me byval byref step resume goto","built_in":"lcase month vartype instrrev ubound setlocale getobject rgb getref string weekdayname rnd dateadd monthname now day minute isarray cbool round formatcurrency conversions csng timevalue second year space abs clng timeserial fixs len asc isempty maths dateserial atn timer isobject filter weekday datevalue ccur isdate instr datediff formatdatetime replace isnull right sgn array snumeric log cdbl hex chr lbound msgbox ucase getlocale cos cdate cbyte rtrim join hour oct typename trim strcomp int createobject loadpicture tan formatnumber mid scriptenginebuildversion scriptengine split scriptengineminorversion cint sin datepart ltrim sqr scriptenginemajorversion time derived eval date formatpercent exp inputbox left ascw chrw regexp server response request cstr err","literal":"true false null nothing empty"},"illegal":"//","contains":[{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"begin":"\"\""}]},{"className":"comment","begin":"'","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}],"relevance":0},{"className":"number","begin":"(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)","relevance":0}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/verilog.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/verilog.json new file mode 100644 index 00000000..c5b37c55 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/verilog.json @@ -0,0 +1 @@ +{"aliases":["v","sv","svh"],"case_insensitive":false,"keywords":{"keyword":"accept_on alias always always_comb always_ff always_latch and assert assign assume automatic before begin bind bins binsof bit break buf|0 bufif0 bufif1 byte case casex casez cell chandle checker class clocking cmos config const constraint context continue cover covergroup coverpoint cross deassign default defparam design disable dist do edge else end endcase endchecker endclass endclocking endconfig endfunction endgenerate endgroup endinterface endmodule endpackage endprimitive endprogram endproperty endspecify endsequence endtable endtask enum event eventually expect export extends extern final first_match for force foreach forever fork forkjoin function generate|5 genvar global highz0 highz1 if iff ifnone ignore_bins illegal_bins implements implies import incdir include initial inout input inside instance int integer interconnect interface intersect join join_any join_none large let liblist library local localparam logic longint macromodule matches medium modport module nand negedge nettype new nexttime nmos nor noshowcancelled not notif0 notif1 or output package packed parameter pmos posedge primitive priority program property protected pull0 pull1 pulldown pullup pulsestyle_ondetect pulsestyle_onevent pure rand randc randcase randsequence rcmos real realtime ref reg reject_on release repeat restrict return rnmos rpmos rtran rtranif0 rtranif1 s_always s_eventually s_nexttime s_until s_until_with scalared sequence shortint shortreal showcancelled signed small soft solve specify specparam static string strong strong0 strong1 struct super supply0 supply1 sync_accept_on sync_reject_on table tagged task this throughout time timeprecision timeunit tran tranif0 tranif1 tri tri0 tri1 triand trior trireg type typedef union unique unique0 unsigned until until_with untyped use uwire var vectored virtual void wait wait_order wand weak weak0 weak1 while wildcard wire with within wor xnor xor","literal":"null","built_in":"$finish $stop $exit $fatal $error $warning $info $realtime $time $printtimescale $bitstoreal $bitstoshortreal $itor $signed $cast $bits $stime $timeformat $realtobits $shortrealtobits $rtoi $unsigned $asserton $assertkill $assertpasson $assertfailon $assertnonvacuouson $assertoff $assertcontrol $assertpassoff $assertfailoff $assertvacuousoff $isunbounded $sampled $fell $changed $past_gclk $fell_gclk $changed_gclk $rising_gclk $steady_gclk $coverage_control $coverage_get $coverage_save $set_coverage_db_name $rose $stable $past $rose_gclk $stable_gclk $future_gclk $falling_gclk $changing_gclk $display $coverage_get_max $coverage_merge $get_coverage $load_coverage_db $typename $unpacked_dimensions $left $low $increment $clog2 $ln $log10 $exp $sqrt $pow $floor $ceil $sin $cos $tan $countbits $onehot $isunknown $fatal $warning $dimensions $right $high $size $asin $acos $atan $atan2 $hypot $sinh $cosh $tanh $asinh $acosh $atanh $countones $onehot0 $error $info $random $dist_chi_square $dist_erlang $dist_exponential $dist_normal $dist_poisson $dist_t $dist_uniform $q_initialize $q_remove $q_exam $async$and$array $async$nand$array $async$or$array $async$nor$array $sync$and$array $sync$nand$array $sync$or$array $sync$nor$array $q_add $q_full $psprintf $async$and$plane $async$nand$plane $async$or$plane $async$nor$plane $sync$and$plane $sync$nand$plane $sync$or$plane $sync$nor$plane $system $display $displayb $displayh $displayo $strobe $strobeb $strobeh $strobeo $write $readmemb $readmemh $writememh $value$plusargs $dumpvars $dumpon $dumplimit $dumpports $dumpportson $dumpportslimit $writeb $writeh $writeo $monitor $monitorb $monitorh $monitoro $writememb $dumpfile $dumpoff $dumpall $dumpflush $dumpportsoff $dumpportsall $dumpportsflush $fclose $fdisplay $fdisplayb $fdisplayh $fdisplayo $fstrobe $fstrobeb $fstrobeh $fstrobeo $swrite $swriteb $swriteh $swriteo $fscanf $fread $fseek $fflush $feof $fopen $fwrite $fwriteb $fwriteh $fwriteo $fmonitor $fmonitorb $fmonitorh $fmonitoro $sformat $sformatf $fgetc $ungetc $fgets $sscanf $rewind $ftell $ferror"},"lexemes":"[\\w\\$]+","contains":[{"className":"comment","begin":"/\\*","end":"\\*/","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"//","end":"$","contains":[{"$ref":"#contains.0.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0},{"className":"subst","begin":"\\\\[abfnrtv]\\|\\\\x[0-9a-fA-F]*\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]","relevance":0},{"className":"subst","begin":"\\\\[abfnrtv]\\|\\\\x[0-9a-fA-F]*\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]","relevance":0}]},{"className":"number","contains":[{"$ref":"#contains.2.contains.0"}],"variants":[{"begin":"\\b((\\d+'(b|h|o|d|B|H|O|D))[0-9xzXZa-fA-F_]+)"},{"begin":"\\B(('(b|h|o|d|B|H|O|D))[0-9xzXZa-fA-F_]+)"},{"begin":"\\b([0-9_])+","relevance":0}]},{"className":"variable","variants":[{"begin":"#\\((?!parameter).+\\)"},{"begin":"\\.\\w+","relevance":0}]},{"className":"meta","begin":"`","end":"$","keywords":{"meta-keyword":"define __FILE__ __LINE__ begin_keywords celldefine default_nettype define else elsif end_keywords endcelldefine endif ifdef ifndef include line nounconnected_drive pragma resetall timescale unconnected_drive undef undefineall"},"relevance":0}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/vhdl.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/vhdl.json new file mode 100644 index 00000000..c880f72a --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/vhdl.json @@ -0,0 +1 @@ +{"case_insensitive":true,"keywords":{"keyword":"abs access after alias all and architecture array assert assume assume_guarantee attribute begin block body buffer bus case component configuration constant context cover disconnect downto default else elsif end entity exit fairness file for force function generate generic group guarded if impure in inertial inout is label library linkage literal loop map mod nand new next nor not null of on open or others out package parameter port postponed procedure process property protected pure range record register reject release rem report restrict restrict_guarantee return rol ror select sequence severity shared signal sla sll sra srl strong subtype then to transport type unaffected units until use variable view vmode vprop vunit wait when while with xnor xor","built_in":"boolean bit character integer time delay_length natural positive string bit_vector file_open_kind file_open_status std_logic std_logic_vector unsigned signed boolean_vector integer_vector std_ulogic std_ulogic_vector unresolved_unsigned u_unsigned unresolved_signed u_signed real_vector time_vector","literal":"false true note warning error failure line text side width"},"illegal":"{","contains":[{"className":"comment","begin":"/\\*","end":"\\*/","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"--","end":"$","contains":[{"$ref":"#contains.0.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0},{"className":"subst","begin":"\\\\[abfnrtv]\\|\\\\x[0-9a-fA-F]*\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]","relevance":0},{"className":"subst","begin":"\\\\[abfnrtv]\\|\\\\x[0-9a-fA-F]*\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]","relevance":0}]},{"className":"number","begin":"\\b(\\d(_|\\d)*#\\w+(\\.\\w+)?#([eE][-+]?\\d(_|\\d)*)?|\\d(_|\\d)*(\\.\\d(_|\\d)*)?([eE][-+]?\\d(_|\\d)*)?)","relevance":0},{"className":"string","begin":"'(U|X|0|1|Z|W|L|H|-)'","contains":[{"$ref":"#contains.2.contains.0"}]},{"className":"symbol","begin":"'[A-Za-z](_?[A-Za-z0-9])*","contains":[{"$ref":"#contains.2.contains.0"}]}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/vim.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/vim.json new file mode 100644 index 00000000..4633f08c --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/vim.json @@ -0,0 +1 @@ +{"lexemes":"[!#@\\w]+","keywords":{"keyword":"N|0 P|0 X|0 a|0 ab abc abo al am an|0 ar arga argd arge argdo argg argl argu as au aug aun b|0 bN ba bad bd be bel bf bl bm bn bo bp br brea breaka breakd breakl bro bufdo buffers bun bw c|0 cN cNf ca cabc caddb cad caddf cal cat cb cc ccl cd ce cex cf cfir cgetb cgete cg changes chd che checkt cl cla clo cm cmapc cme cn cnew cnf cno cnorea cnoreme co col colo com comc comp con conf cope cp cpf cq cr cs cst cu cuna cunme cw delm deb debugg delc delf dif diffg diffo diffp diffpu diffs diffthis dig di dl dell dj dli do doautoa dp dr ds dsp e|0 ea ec echoe echoh echom echon el elsei em en endfo endf endt endw ene ex exe exi exu f|0 files filet fin fina fini fir fix fo foldc foldd folddoc foldo for fu go gr grepa gu gv ha helpf helpg helpt hi hid his ia iabc if ij il im imapc ime ino inorea inoreme int is isp iu iuna iunme j|0 ju k|0 keepa kee keepj lN lNf l|0 lad laddb laddf la lan lat lb lc lch lcl lcs le lefta let lex lf lfir lgetb lgete lg lgr lgrepa lh ll lla lli lmak lm lmapc lne lnew lnf ln loadk lo loc lockv lol lope lp lpf lr ls lt lu lua luad luaf lv lvimgrepa lw m|0 ma mak map mapc marks mat me menut mes mk mks mksp mkv mkvie mod mz mzf nbc nb nbs new nm nmapc nme nn nnoreme noa no noh norea noreme norm nu nun nunme ol o|0 om omapc ome on ono onoreme opt ou ounme ow p|0 profd prof pro promptr pc ped pe perld po popu pp pre prev ps pt ptN ptf ptj ptl ptn ptp ptr pts pu pw py3 python3 py3d py3f py pyd pyf quita qa rec red redi redr redraws reg res ret retu rew ri rightb rub rubyd rubyf rund ru rv sN san sa sal sav sb sbN sba sbf sbl sbm sbn sbp sbr scrip scripte scs se setf setg setl sf sfir sh sim sig sil sl sla sm smap smapc sme sn sni sno snor snoreme sor so spelld spe spelli spellr spellu spellw sp spr sre st sta startg startr star stopi stj sts sun sunm sunme sus sv sw sy synti sync tN tabN tabc tabdo tabe tabf tabfir tabl tabm tabnew tabn tabo tabp tabr tabs tab ta tags tc tcld tclf te tf th tj tl tm tn to tp tr try ts tu u|0 undoj undol una unh unl unlo unm unme uns up ve verb vert vim vimgrepa vi viu vie vm vmapc vme vne vn vnoreme vs vu vunme windo w|0 wN wa wh wi winc winp wn wp wq wqa ws wu wv x|0 xa xmapc xm xme xn xnoreme xu xunme y|0 z|0 ~ Next Print append abbreviate abclear aboveleft all amenu anoremenu args argadd argdelete argedit argglobal arglocal argument ascii autocmd augroup aunmenu buffer bNext ball badd bdelete behave belowright bfirst blast bmodified bnext botright bprevious brewind break breakadd breakdel breaklist browse bunload bwipeout change cNext cNfile cabbrev cabclear caddbuffer caddexpr caddfile call catch cbuffer cclose center cexpr cfile cfirst cgetbuffer cgetexpr cgetfile chdir checkpath checktime clist clast close cmap cmapclear cmenu cnext cnewer cnfile cnoremap cnoreabbrev cnoremenu copy colder colorscheme command comclear compiler continue confirm copen cprevious cpfile cquit crewind cscope cstag cunmap cunabbrev cunmenu cwindow delete delmarks debug debuggreedy delcommand delfunction diffupdate diffget diffoff diffpatch diffput diffsplit digraphs display deletel djump dlist doautocmd doautoall deletep drop dsearch dsplit edit earlier echo echoerr echohl echomsg else elseif emenu endif endfor endfunction endtry endwhile enew execute exit exusage file filetype find finally finish first fixdel fold foldclose folddoopen folddoclosed foldopen function global goto grep grepadd gui gvim hardcopy help helpfind helpgrep helptags highlight hide history insert iabbrev iabclear ijump ilist imap imapclear imenu inoremap inoreabbrev inoremenu intro isearch isplit iunmap iunabbrev iunmenu join jumps keepalt keepmarks keepjumps lNext lNfile list laddexpr laddbuffer laddfile last language later lbuffer lcd lchdir lclose lcscope left leftabove lexpr lfile lfirst lgetbuffer lgetexpr lgetfile lgrep lgrepadd lhelpgrep llast llist lmake lmap lmapclear lnext lnewer lnfile lnoremap loadkeymap loadview lockmarks lockvar lolder lopen lprevious lpfile lrewind ltag lunmap luado luafile lvimgrep lvimgrepadd lwindow move mark make mapclear match menu menutranslate messages mkexrc mksession mkspell mkvimrc mkview mode mzscheme mzfile nbclose nbkey nbsart next nmap nmapclear nmenu nnoremap nnoremenu noautocmd noremap nohlsearch noreabbrev noremenu normal number nunmap nunmenu oldfiles open omap omapclear omenu only onoremap onoremenu options ounmap ounmenu ownsyntax print profdel profile promptfind promptrepl pclose pedit perl perldo pop popup ppop preserve previous psearch ptag ptNext ptfirst ptjump ptlast ptnext ptprevious ptrewind ptselect put pwd py3do py3file python pydo pyfile quit quitall qall read recover redo redir redraw redrawstatus registers resize retab return rewind right rightbelow ruby rubydo rubyfile rundo runtime rviminfo substitute sNext sandbox sargument sall saveas sbuffer sbNext sball sbfirst sblast sbmodified sbnext sbprevious sbrewind scriptnames scriptencoding scscope set setfiletype setglobal setlocal sfind sfirst shell simalt sign silent sleep slast smagic smapclear smenu snext sniff snomagic snoremap snoremenu sort source spelldump spellgood spellinfo spellrepall spellundo spellwrong split sprevious srewind stop stag startgreplace startreplace startinsert stopinsert stjump stselect sunhide sunmap sunmenu suspend sview swapname syntax syntime syncbind tNext tabNext tabclose tabedit tabfind tabfirst tablast tabmove tabnext tabonly tabprevious tabrewind tag tcl tcldo tclfile tearoff tfirst throw tjump tlast tmenu tnext topleft tprevious trewind tselect tunmenu undo undojoin undolist unabbreviate unhide unlet unlockvar unmap unmenu unsilent update vglobal version verbose vertical vimgrep vimgrepadd visual viusage view vmap vmapclear vmenu vnew vnoremap vnoremenu vsplit vunmap vunmenu write wNext wall while winsize wincmd winpos wnext wprevious wqall wsverb wundo wviminfo xit xall xmapclear xmap xmenu xnoremap xnoremenu xunmap xunmenu yank","built_in":"synIDtrans atan2 range matcharg did_filetype asin feedkeys xor argv complete_check add getwinposx getqflist getwinposy screencol clearmatches empty extend getcmdpos mzeval garbagecollect setreg ceil sqrt diff_hlID inputsecret get getfperm getpid filewritable shiftwidth max sinh isdirectory synID system inputrestore winline atan visualmode inputlist tabpagewinnr round getregtype mapcheck hasmapto histdel argidx findfile sha256 exists toupper getcmdline taglist string getmatches bufnr strftime winwidth bufexists strtrans tabpagebuflist setcmdpos remote_read printf setloclist getpos getline bufwinnr float2nr len getcmdtype diff_filler luaeval resolve libcallnr foldclosedend reverse filter has_key bufname str2float strlen setline getcharmod setbufvar index searchpos shellescape undofile foldclosed setqflist buflisted strchars str2nr virtcol floor remove undotree remote_expr winheight gettabwinvar reltime cursor tabpagenr finddir localtime acos getloclist search tanh matchend rename gettabvar strdisplaywidth type abs py3eval setwinvar tolower wildmenumode log10 spellsuggest bufloaded synconcealed nextnonblank server2client complete settabwinvar executable input wincol setmatches getftype hlID inputsave searchpair or screenrow line settabvar histadd deepcopy strpart remote_peek and eval getftime submatch screenchar winsaveview matchadd mkdir screenattr getfontname libcall reltimestr getfsize winnr invert pow getbufline byte2line soundfold repeat fnameescape tagfiles sin strwidth spellbadword trunc maparg log lispindent hostname setpos globpath remote_foreground getchar synIDattr fnamemodify cscope_connection stridx winbufnr indent min complete_add nr2char searchpairpos inputdialog values matchlist items hlexists strridx browsedir expand fmod pathshorten line2byte argc count getwinvar glob foldtextresult getreg foreground cosh matchdelete has char2nr simplify histget searchdecl iconv winrestcmd pumvisible writefile foldlevel haslocaldir keys cos matchstr foldtext histnr tan tempname getcwd byteidx getbufvar islocked escape eventhandler remote_send serverlist winrestview synstack pyeval prevnonblank readfile cindent filereadable changenr exp"},"illegal":";","contains":[{"className":"number","begin":"\\b\\d+(\\.\\d+)?","relevance":0},{"className":"string","begin":"'","end":"'","illegal":"\\n"},{"className":"string","begin":"\"(\\\\\"|\\n\\\\|[^\"\\n])*\""},{"className":"comment","begin":"\"","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"variable","begin":"[bwtglsav]:[\\w\\d_]*"},{"className":"function","beginKeywords":"function function!","end":"$","relevance":0,"contains":[{"className":"title","begin":"[a-zA-Z]\\w*","relevance":0},{"className":"params","begin":"\\(","end":"\\)"}]},{"className":"symbol","begin":"<[\\w-]+>"}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/x86asm.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/x86asm.json new file mode 100644 index 00000000..21ba66a2 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/x86asm.json @@ -0,0 +1 @@ +{"case_insensitive":true,"lexemes":"[.%]?[a-zA-Z]\\w*","keywords":{"keyword":"lock rep repe repz repne repnz xaquire xrelease bnd nobnd aaa aad aam aas adc add and arpl bb0_reset bb1_reset bound bsf bsr bswap bt btc btr bts call cbw cdq cdqe clc cld cli clts cmc cmp cmpsb cmpsd cmpsq cmpsw cmpxchg cmpxchg486 cmpxchg8b cmpxchg16b cpuid cpu_read cpu_write cqo cwd cwde daa das dec div dmint emms enter equ f2xm1 fabs fadd faddp fbld fbstp fchs fclex fcmovb fcmovbe fcmove fcmovnb fcmovnbe fcmovne fcmovnu fcmovu fcom fcomi fcomip fcomp fcompp fcos fdecstp fdisi fdiv fdivp fdivr fdivrp femms feni ffree ffreep fiadd ficom ficomp fidiv fidivr fild fimul fincstp finit fist fistp fisttp fisub fisubr fld fld1 fldcw fldenv fldl2e fldl2t fldlg2 fldln2 fldpi fldz fmul fmulp fnclex fndisi fneni fninit fnop fnsave fnstcw fnstenv fnstsw fpatan fprem fprem1 fptan frndint frstor fsave fscale fsetpm fsin fsincos fsqrt fst fstcw fstenv fstp fstsw fsub fsubp fsubr fsubrp ftst fucom fucomi fucomip fucomp fucompp fxam fxch fxtract fyl2x fyl2xp1 hlt ibts icebp idiv imul in inc incbin insb insd insw int int01 int1 int03 int3 into invd invpcid invlpg invlpga iret iretd iretq iretw jcxz jecxz jrcxz jmp jmpe lahf lar lds lea leave les lfence lfs lgdt lgs lidt lldt lmsw loadall loadall286 lodsb lodsd lodsq lodsw loop loope loopne loopnz loopz lsl lss ltr mfence monitor mov movd movq movsb movsd movsq movsw movsx movsxd movzx mul mwait neg nop not or out outsb outsd outsw packssdw packsswb packuswb paddb paddd paddsb paddsiw paddsw paddusb paddusw paddw pand pandn pause paveb pavgusb pcmpeqb pcmpeqd pcmpeqw pcmpgtb pcmpgtd pcmpgtw pdistib pf2id pfacc pfadd pfcmpeq pfcmpge pfcmpgt pfmax pfmin pfmul pfrcp pfrcpit1 pfrcpit2 pfrsqit1 pfrsqrt pfsub pfsubr pi2fd pmachriw pmaddwd pmagw pmulhriw pmulhrwa pmulhrwc pmulhw pmullw pmvgezb pmvlzb pmvnzb pmvzb pop popa popad popaw popf popfd popfq popfw por prefetch prefetchw pslld psllq psllw psrad psraw psrld psrlq psrlw psubb psubd psubsb psubsiw psubsw psubusb psubusw psubw punpckhbw punpckhdq punpckhwd punpcklbw punpckldq punpcklwd push pusha pushad pushaw pushf pushfd pushfq pushfw pxor rcl rcr rdshr rdmsr rdpmc rdtsc rdtscp ret retf retn rol ror rdm rsdc rsldt rsm rsts sahf sal salc sar sbb scasb scasd scasq scasw sfence sgdt shl shld shr shrd sidt sldt skinit smi smint smintold smsw stc std sti stosb stosd stosq stosw str sub svdc svldt svts swapgs syscall sysenter sysexit sysret test ud0 ud1 ud2b ud2 ud2a umov verr verw fwait wbinvd wrshr wrmsr xadd xbts xchg xlatb xlat xor cmove cmovz cmovne cmovnz cmova cmovnbe cmovae cmovnb cmovb cmovnae cmovbe cmovna cmovg cmovnle cmovge cmovnl cmovl cmovnge cmovle cmovng cmovc cmovnc cmovo cmovno cmovs cmovns cmovp cmovpe cmovnp cmovpo je jz jne jnz ja jnbe jae jnb jb jnae jbe jna jg jnle jge jnl jl jnge jle jng jc jnc jo jno js jns jpo jnp jpe jp sete setz setne setnz seta setnbe setae setnb setnc setb setnae setcset setbe setna setg setnle setge setnl setl setnge setle setng sets setns seto setno setpe setp setpo setnp addps addss andnps andps cmpeqps cmpeqss cmpleps cmpless cmpltps cmpltss cmpneqps cmpneqss cmpnleps cmpnless cmpnltps cmpnltss cmpordps cmpordss cmpunordps cmpunordss cmpps cmpss comiss cvtpi2ps cvtps2pi cvtsi2ss cvtss2si cvttps2pi cvttss2si divps divss ldmxcsr maxps maxss minps minss movaps movhps movlhps movlps movhlps movmskps movntps movss movups mulps mulss orps rcpps rcpss rsqrtps rsqrtss shufps sqrtps sqrtss stmxcsr subps subss ucomiss unpckhps unpcklps xorps fxrstor fxrstor64 fxsave fxsave64 xgetbv xsetbv xsave xsave64 xsaveopt xsaveopt64 xrstor xrstor64 prefetchnta prefetcht0 prefetcht1 prefetcht2 maskmovq movntq pavgb pavgw pextrw pinsrw pmaxsw pmaxub pminsw pminub pmovmskb pmulhuw psadbw pshufw pf2iw pfnacc pfpnacc pi2fw pswapd maskmovdqu clflush movntdq movnti movntpd movdqa movdqu movdq2q movq2dq paddq pmuludq pshufd pshufhw pshuflw pslldq psrldq psubq punpckhqdq punpcklqdq addpd addsd andnpd andpd cmpeqpd cmpeqsd cmplepd cmplesd cmpltpd cmpltsd cmpneqpd cmpneqsd cmpnlepd cmpnlesd cmpnltpd cmpnltsd cmpordpd cmpordsd cmpunordpd cmpunordsd cmppd comisd cvtdq2pd cvtdq2ps cvtpd2dq cvtpd2pi cvtpd2ps cvtpi2pd cvtps2dq cvtps2pd cvtsd2si cvtsd2ss cvtsi2sd cvtss2sd cvttpd2pi cvttpd2dq cvttps2dq cvttsd2si divpd divsd maxpd maxsd minpd minsd movapd movhpd movlpd movmskpd movupd mulpd mulsd orpd shufpd sqrtpd sqrtsd subpd subsd ucomisd unpckhpd unpcklpd xorpd addsubpd addsubps haddpd haddps hsubpd hsubps lddqu movddup movshdup movsldup clgi stgi vmcall vmclear vmfunc vmlaunch vmload vmmcall vmptrld vmptrst vmread vmresume vmrun vmsave vmwrite vmxoff vmxon invept invvpid pabsb pabsw pabsd palignr phaddw phaddd phaddsw phsubw phsubd phsubsw pmaddubsw pmulhrsw pshufb psignb psignw psignd extrq insertq movntsd movntss lzcnt blendpd blendps blendvpd blendvps dppd dpps extractps insertps movntdqa mpsadbw packusdw pblendvb pblendw pcmpeqq pextrb pextrd pextrq phminposuw pinsrb pinsrd pinsrq pmaxsb pmaxsd pmaxud pmaxuw pminsb pminsd pminud pminuw pmovsxbw pmovsxbd pmovsxbq pmovsxwd pmovsxwq pmovsxdq pmovzxbw pmovzxbd pmovzxbq pmovzxwd pmovzxwq pmovzxdq pmuldq pmulld ptest roundpd roundps roundsd roundss crc32 pcmpestri pcmpestrm pcmpistri pcmpistrm pcmpgtq popcnt getsec pfrcpv pfrsqrtv movbe aesenc aesenclast aesdec aesdeclast aesimc aeskeygenassist vaesenc vaesenclast vaesdec vaesdeclast vaesimc vaeskeygenassist vaddpd vaddps vaddsd vaddss vaddsubpd vaddsubps vandpd vandps vandnpd vandnps vblendpd vblendps vblendvpd vblendvps vbroadcastss vbroadcastsd vbroadcastf128 vcmpeq_ospd vcmpeqpd vcmplt_ospd vcmpltpd vcmple_ospd vcmplepd vcmpunord_qpd vcmpunordpd vcmpneq_uqpd vcmpneqpd vcmpnlt_uspd vcmpnltpd vcmpnle_uspd vcmpnlepd vcmpord_qpd vcmpordpd vcmpeq_uqpd vcmpnge_uspd vcmpngepd vcmpngt_uspd vcmpngtpd vcmpfalse_oqpd vcmpfalsepd vcmpneq_oqpd vcmpge_ospd vcmpgepd vcmpgt_ospd vcmpgtpd vcmptrue_uqpd vcmptruepd vcmplt_oqpd vcmple_oqpd vcmpunord_spd vcmpneq_uspd vcmpnlt_uqpd vcmpnle_uqpd vcmpord_spd vcmpeq_uspd vcmpnge_uqpd vcmpngt_uqpd vcmpfalse_ospd vcmpneq_ospd vcmpge_oqpd vcmpgt_oqpd vcmptrue_uspd vcmppd vcmpeq_osps vcmpeqps vcmplt_osps vcmpltps vcmple_osps vcmpleps vcmpunord_qps vcmpunordps vcmpneq_uqps vcmpneqps vcmpnlt_usps vcmpnltps vcmpnle_usps vcmpnleps vcmpord_qps vcmpordps vcmpeq_uqps vcmpnge_usps vcmpngeps vcmpngt_usps vcmpngtps vcmpfalse_oqps vcmpfalseps vcmpneq_oqps vcmpge_osps vcmpgeps vcmpgt_osps vcmpgtps vcmptrue_uqps vcmptrueps vcmplt_oqps vcmple_oqps vcmpunord_sps vcmpneq_usps vcmpnlt_uqps vcmpnle_uqps vcmpord_sps vcmpeq_usps vcmpnge_uqps vcmpngt_uqps vcmpfalse_osps vcmpneq_osps vcmpge_oqps vcmpgt_oqps vcmptrue_usps vcmpps vcmpeq_ossd vcmpeqsd vcmplt_ossd vcmpltsd vcmple_ossd vcmplesd vcmpunord_qsd vcmpunordsd vcmpneq_uqsd vcmpneqsd vcmpnlt_ussd vcmpnltsd vcmpnle_ussd vcmpnlesd vcmpord_qsd vcmpordsd vcmpeq_uqsd vcmpnge_ussd vcmpngesd vcmpngt_ussd vcmpngtsd vcmpfalse_oqsd vcmpfalsesd vcmpneq_oqsd vcmpge_ossd vcmpgesd vcmpgt_ossd vcmpgtsd vcmptrue_uqsd vcmptruesd vcmplt_oqsd vcmple_oqsd vcmpunord_ssd vcmpneq_ussd vcmpnlt_uqsd vcmpnle_uqsd vcmpord_ssd vcmpeq_ussd vcmpnge_uqsd vcmpngt_uqsd vcmpfalse_ossd vcmpneq_ossd vcmpge_oqsd vcmpgt_oqsd vcmptrue_ussd vcmpsd vcmpeq_osss vcmpeqss vcmplt_osss vcmpltss vcmple_osss vcmpless vcmpunord_qss vcmpunordss vcmpneq_uqss vcmpneqss vcmpnlt_usss vcmpnltss vcmpnle_usss vcmpnless vcmpord_qss vcmpordss vcmpeq_uqss vcmpnge_usss vcmpngess vcmpngt_usss vcmpngtss vcmpfalse_oqss vcmpfalsess vcmpneq_oqss vcmpge_osss vcmpgess vcmpgt_osss vcmpgtss vcmptrue_uqss vcmptruess vcmplt_oqss vcmple_oqss vcmpunord_sss vcmpneq_usss vcmpnlt_uqss vcmpnle_uqss vcmpord_sss vcmpeq_usss vcmpnge_uqss vcmpngt_uqss vcmpfalse_osss vcmpneq_osss vcmpge_oqss vcmpgt_oqss vcmptrue_usss vcmpss vcomisd vcomiss vcvtdq2pd vcvtdq2ps vcvtpd2dq vcvtpd2ps vcvtps2dq vcvtps2pd vcvtsd2si vcvtsd2ss vcvtsi2sd vcvtsi2ss vcvtss2sd vcvtss2si vcvttpd2dq vcvttps2dq vcvttsd2si vcvttss2si vdivpd vdivps vdivsd vdivss vdppd vdpps vextractf128 vextractps vhaddpd vhaddps vhsubpd vhsubps vinsertf128 vinsertps vlddqu vldqqu vldmxcsr vmaskmovdqu vmaskmovps vmaskmovpd vmaxpd vmaxps vmaxsd vmaxss vminpd vminps vminsd vminss vmovapd vmovaps vmovd vmovq vmovddup vmovdqa vmovqqa vmovdqu vmovqqu vmovhlps vmovhpd vmovhps vmovlhps vmovlpd vmovlps vmovmskpd vmovmskps vmovntdq vmovntqq vmovntdqa vmovntpd vmovntps vmovsd vmovshdup vmovsldup vmovss vmovupd vmovups vmpsadbw vmulpd vmulps vmulsd vmulss vorpd vorps vpabsb vpabsw vpabsd vpacksswb vpackssdw vpackuswb vpackusdw vpaddb vpaddw vpaddd vpaddq vpaddsb vpaddsw vpaddusb vpaddusw vpalignr vpand vpandn vpavgb vpavgw vpblendvb vpblendw vpcmpestri vpcmpestrm vpcmpistri vpcmpistrm vpcmpeqb vpcmpeqw vpcmpeqd vpcmpeqq vpcmpgtb vpcmpgtw vpcmpgtd vpcmpgtq vpermilpd vpermilps vperm2f128 vpextrb vpextrw vpextrd vpextrq vphaddw vphaddd vphaddsw vphminposuw vphsubw vphsubd vphsubsw vpinsrb vpinsrw vpinsrd vpinsrq vpmaddwd vpmaddubsw vpmaxsb vpmaxsw vpmaxsd vpmaxub vpmaxuw vpmaxud vpminsb vpminsw vpminsd vpminub vpminuw vpminud vpmovmskb vpmovsxbw vpmovsxbd vpmovsxbq vpmovsxwd vpmovsxwq vpmovsxdq vpmovzxbw vpmovzxbd vpmovzxbq vpmovzxwd vpmovzxwq vpmovzxdq vpmulhuw vpmulhrsw vpmulhw vpmullw vpmulld vpmuludq vpmuldq vpor vpsadbw vpshufb vpshufd vpshufhw vpshuflw vpsignb vpsignw vpsignd vpslldq vpsrldq vpsllw vpslld vpsllq vpsraw vpsrad vpsrlw vpsrld vpsrlq vptest vpsubb vpsubw vpsubd vpsubq vpsubsb vpsubsw vpsubusb vpsubusw vpunpckhbw vpunpckhwd vpunpckhdq vpunpckhqdq vpunpcklbw vpunpcklwd vpunpckldq vpunpcklqdq vpxor vrcpps vrcpss vrsqrtps vrsqrtss vroundpd vroundps vroundsd vroundss vshufpd vshufps vsqrtpd vsqrtps vsqrtsd vsqrtss vstmxcsr vsubpd vsubps vsubsd vsubss vtestps vtestpd vucomisd vucomiss vunpckhpd vunpckhps vunpcklpd vunpcklps vxorpd vxorps vzeroall vzeroupper pclmullqlqdq pclmulhqlqdq pclmullqhqdq pclmulhqhqdq pclmulqdq vpclmullqlqdq vpclmulhqlqdq vpclmullqhqdq vpclmulhqhqdq vpclmulqdq vfmadd132ps vfmadd132pd vfmadd312ps vfmadd312pd vfmadd213ps vfmadd213pd vfmadd123ps vfmadd123pd vfmadd231ps vfmadd231pd vfmadd321ps vfmadd321pd vfmaddsub132ps vfmaddsub132pd vfmaddsub312ps vfmaddsub312pd vfmaddsub213ps vfmaddsub213pd vfmaddsub123ps vfmaddsub123pd vfmaddsub231ps vfmaddsub231pd vfmaddsub321ps vfmaddsub321pd vfmsub132ps vfmsub132pd vfmsub312ps vfmsub312pd vfmsub213ps vfmsub213pd vfmsub123ps vfmsub123pd vfmsub231ps vfmsub231pd vfmsub321ps vfmsub321pd vfmsubadd132ps vfmsubadd132pd vfmsubadd312ps vfmsubadd312pd vfmsubadd213ps vfmsubadd213pd vfmsubadd123ps vfmsubadd123pd vfmsubadd231ps vfmsubadd231pd vfmsubadd321ps vfmsubadd321pd vfnmadd132ps vfnmadd132pd vfnmadd312ps vfnmadd312pd vfnmadd213ps vfnmadd213pd vfnmadd123ps vfnmadd123pd vfnmadd231ps vfnmadd231pd vfnmadd321ps vfnmadd321pd vfnmsub132ps vfnmsub132pd vfnmsub312ps vfnmsub312pd vfnmsub213ps vfnmsub213pd vfnmsub123ps vfnmsub123pd vfnmsub231ps vfnmsub231pd vfnmsub321ps vfnmsub321pd vfmadd132ss vfmadd132sd vfmadd312ss vfmadd312sd vfmadd213ss vfmadd213sd vfmadd123ss vfmadd123sd vfmadd231ss vfmadd231sd vfmadd321ss vfmadd321sd vfmsub132ss vfmsub132sd vfmsub312ss vfmsub312sd vfmsub213ss vfmsub213sd vfmsub123ss vfmsub123sd vfmsub231ss vfmsub231sd vfmsub321ss vfmsub321sd vfnmadd132ss vfnmadd132sd vfnmadd312ss vfnmadd312sd vfnmadd213ss vfnmadd213sd vfnmadd123ss vfnmadd123sd vfnmadd231ss vfnmadd231sd vfnmadd321ss vfnmadd321sd vfnmsub132ss vfnmsub132sd vfnmsub312ss vfnmsub312sd vfnmsub213ss vfnmsub213sd vfnmsub123ss vfnmsub123sd vfnmsub231ss vfnmsub231sd vfnmsub321ss vfnmsub321sd rdfsbase rdgsbase rdrand wrfsbase wrgsbase vcvtph2ps vcvtps2ph adcx adox rdseed clac stac xstore xcryptecb xcryptcbc xcryptctr xcryptcfb xcryptofb montmul xsha1 xsha256 llwpcb slwpcb lwpval lwpins vfmaddpd vfmaddps vfmaddsd vfmaddss vfmaddsubpd vfmaddsubps vfmsubaddpd vfmsubaddps vfmsubpd vfmsubps vfmsubsd vfmsubss vfnmaddpd vfnmaddps vfnmaddsd vfnmaddss vfnmsubpd vfnmsubps vfnmsubsd vfnmsubss vfrczpd vfrczps vfrczsd vfrczss vpcmov vpcomb vpcomd vpcomq vpcomub vpcomud vpcomuq vpcomuw vpcomw vphaddbd vphaddbq vphaddbw vphadddq vphaddubd vphaddubq vphaddubw vphaddudq vphadduwd vphadduwq vphaddwd vphaddwq vphsubbw vphsubdq vphsubwd vpmacsdd vpmacsdqh vpmacsdql vpmacssdd vpmacssdqh vpmacssdql vpmacsswd vpmacssww vpmacswd vpmacsww vpmadcsswd vpmadcswd vpperm vprotb vprotd vprotq vprotw vpshab vpshad vpshaq vpshaw vpshlb vpshld vpshlq vpshlw vbroadcasti128 vpblendd vpbroadcastb vpbroadcastw vpbroadcastd vpbroadcastq vpermd vpermpd vpermps vpermq vperm2i128 vextracti128 vinserti128 vpmaskmovd vpmaskmovq vpsllvd vpsllvq vpsravd vpsrlvd vpsrlvq vgatherdpd vgatherqpd vgatherdps vgatherqps vpgatherdd vpgatherqd vpgatherdq vpgatherqq xabort xbegin xend xtest andn bextr blci blcic blsi blsic blcfill blsfill blcmsk blsmsk blsr blcs bzhi mulx pdep pext rorx sarx shlx shrx tzcnt tzmsk t1mskc valignd valignq vblendmpd vblendmps vbroadcastf32x4 vbroadcastf64x4 vbroadcasti32x4 vbroadcasti64x4 vcompresspd vcompressps vcvtpd2udq vcvtps2udq vcvtsd2usi vcvtss2usi vcvttpd2udq vcvttps2udq vcvttsd2usi vcvttss2usi vcvtudq2pd vcvtudq2ps vcvtusi2sd vcvtusi2ss vexpandpd vexpandps vextractf32x4 vextractf64x4 vextracti32x4 vextracti64x4 vfixupimmpd vfixupimmps vfixupimmsd vfixupimmss vgetexppd vgetexpps vgetexpsd vgetexpss vgetmantpd vgetmantps vgetmantsd vgetmantss vinsertf32x4 vinsertf64x4 vinserti32x4 vinserti64x4 vmovdqa32 vmovdqa64 vmovdqu32 vmovdqu64 vpabsq vpandd vpandnd vpandnq vpandq vpblendmd vpblendmq vpcmpltd vpcmpled vpcmpneqd vpcmpnltd vpcmpnled vpcmpd vpcmpltq vpcmpleq vpcmpneqq vpcmpnltq vpcmpnleq vpcmpq vpcmpequd vpcmpltud vpcmpleud vpcmpnequd vpcmpnltud vpcmpnleud vpcmpud vpcmpequq vpcmpltuq vpcmpleuq vpcmpnequq vpcmpnltuq vpcmpnleuq vpcmpuq vpcompressd vpcompressq vpermi2d vpermi2pd vpermi2ps vpermi2q vpermt2d vpermt2pd vpermt2ps vpermt2q vpexpandd vpexpandq vpmaxsq vpmaxuq vpminsq vpminuq vpmovdb vpmovdw vpmovqb vpmovqd vpmovqw vpmovsdb vpmovsdw vpmovsqb vpmovsqd vpmovsqw vpmovusdb vpmovusdw vpmovusqb vpmovusqd vpmovusqw vpord vporq vprold vprolq vprolvd vprolvq vprord vprorq vprorvd vprorvq vpscatterdd vpscatterdq vpscatterqd vpscatterqq vpsraq vpsravq vpternlogd vpternlogq vptestmd vptestmq vptestnmd vptestnmq vpxord vpxorq vrcp14pd vrcp14ps vrcp14sd vrcp14ss vrndscalepd vrndscaleps vrndscalesd vrndscaless vrsqrt14pd vrsqrt14ps vrsqrt14sd vrsqrt14ss vscalefpd vscalefps vscalefsd vscalefss vscatterdpd vscatterdps vscatterqpd vscatterqps vshuff32x4 vshuff64x2 vshufi32x4 vshufi64x2 kandnw kandw kmovw knotw kortestw korw kshiftlw kshiftrw kunpckbw kxnorw kxorw vpbroadcastmb2q vpbroadcastmw2d vpconflictd vpconflictq vplzcntd vplzcntq vexp2pd vexp2ps vrcp28pd vrcp28ps vrcp28sd vrcp28ss vrsqrt28pd vrsqrt28ps vrsqrt28sd vrsqrt28ss vgatherpf0dpd vgatherpf0dps vgatherpf0qpd vgatherpf0qps vgatherpf1dpd vgatherpf1dps vgatherpf1qpd vgatherpf1qps vscatterpf0dpd vscatterpf0dps vscatterpf0qpd vscatterpf0qps vscatterpf1dpd vscatterpf1dps vscatterpf1qpd vscatterpf1qps prefetchwt1 bndmk bndcl bndcu bndcn bndmov bndldx bndstx sha1rnds4 sha1nexte sha1msg1 sha1msg2 sha256rnds2 sha256msg1 sha256msg2 hint_nop0 hint_nop1 hint_nop2 hint_nop3 hint_nop4 hint_nop5 hint_nop6 hint_nop7 hint_nop8 hint_nop9 hint_nop10 hint_nop11 hint_nop12 hint_nop13 hint_nop14 hint_nop15 hint_nop16 hint_nop17 hint_nop18 hint_nop19 hint_nop20 hint_nop21 hint_nop22 hint_nop23 hint_nop24 hint_nop25 hint_nop26 hint_nop27 hint_nop28 hint_nop29 hint_nop30 hint_nop31 hint_nop32 hint_nop33 hint_nop34 hint_nop35 hint_nop36 hint_nop37 hint_nop38 hint_nop39 hint_nop40 hint_nop41 hint_nop42 hint_nop43 hint_nop44 hint_nop45 hint_nop46 hint_nop47 hint_nop48 hint_nop49 hint_nop50 hint_nop51 hint_nop52 hint_nop53 hint_nop54 hint_nop55 hint_nop56 hint_nop57 hint_nop58 hint_nop59 hint_nop60 hint_nop61 hint_nop62 hint_nop63","built_in":"ip eip rip al ah bl bh cl ch dl dh sil dil bpl spl r8b r9b r10b r11b r12b r13b r14b r15b ax bx cx dx si di bp sp r8w r9w r10w r11w r12w r13w r14w r15w eax ebx ecx edx esi edi ebp esp eip r8d r9d r10d r11d r12d r13d r14d r15d rax rbx rcx rdx rsi rdi rbp rsp r8 r9 r10 r11 r12 r13 r14 r15 cs ds es fs gs ss st st0 st1 st2 st3 st4 st5 st6 st7 mm0 mm1 mm2 mm3 mm4 mm5 mm6 mm7 xmm0 xmm1 xmm2 xmm3 xmm4 xmm5 xmm6 xmm7 xmm8 xmm9 xmm10 xmm11 xmm12 xmm13 xmm14 xmm15 xmm16 xmm17 xmm18 xmm19 xmm20 xmm21 xmm22 xmm23 xmm24 xmm25 xmm26 xmm27 xmm28 xmm29 xmm30 xmm31 ymm0 ymm1 ymm2 ymm3 ymm4 ymm5 ymm6 ymm7 ymm8 ymm9 ymm10 ymm11 ymm12 ymm13 ymm14 ymm15 ymm16 ymm17 ymm18 ymm19 ymm20 ymm21 ymm22 ymm23 ymm24 ymm25 ymm26 ymm27 ymm28 ymm29 ymm30 ymm31 zmm0 zmm1 zmm2 zmm3 zmm4 zmm5 zmm6 zmm7 zmm8 zmm9 zmm10 zmm11 zmm12 zmm13 zmm14 zmm15 zmm16 zmm17 zmm18 zmm19 zmm20 zmm21 zmm22 zmm23 zmm24 zmm25 zmm26 zmm27 zmm28 zmm29 zmm30 zmm31 k0 k1 k2 k3 k4 k5 k6 k7 bnd0 bnd1 bnd2 bnd3 cr0 cr1 cr2 cr3 cr4 cr8 dr0 dr1 dr2 dr3 dr8 tr3 tr4 tr5 tr6 tr7 r0 r1 r2 r3 r4 r5 r6 r7 r0b r1b r2b r3b r4b r5b r6b r7b r0w r1w r2w r3w r4w r5w r6w r7w r0d r1d r2d r3d r4d r5d r6d r7d r0h r1h r2h r3h r0l r1l r2l r3l r4l r5l r6l r7l r8l r9l r10l r11l r12l r13l r14l r15l db dw dd dq dt ddq do dy dz resb resw resd resq rest resdq reso resy resz incbin equ times byte word dword qword nosplit rel abs seg wrt strict near far a32 ptr","meta":"%define %xdefine %+ %undef %defstr %deftok %assign %strcat %strlen %substr %rotate %elif %else %endif %if %ifmacro %ifctx %ifidn %ifidni %ifid %ifnum %ifstr %iftoken %ifempty %ifenv %error %warning %fatal %rep %endrep %include %push %pop %repl %pathsearch %depend %use %arg %stacksize %local %line %comment %endcomment .nolist __FILE__ __LINE__ __SECT__ __BITS__ __OUTPUT_FORMAT__ __DATE__ __TIME__ __DATE_NUM__ __TIME_NUM__ __UTC_DATE__ __UTC_TIME__ __UTC_DATE_NUM__ __UTC_TIME_NUM__ __PASS__ struc endstruc istruc at iend align alignb sectalign daz nodaz up down zero default option assume public bits use16 use32 use64 default section segment absolute extern global common cpu float __utf16__ __utf16le__ __utf16be__ __utf32__ __utf32le__ __utf32be__ __float8__ __float16__ __float32__ __float64__ __float80m__ __float80e__ __float128l__ __float128h__ __Infinity__ __QNaN__ __SNaN__ Inf NaN QNaN SNaN float8 float16 float32 float64 float80m float80e float128l float128h __FLOAT_DAZ__ __FLOAT_ROUND__ __FLOAT__"},"contains":[{"className":"comment","begin":";","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}],"relevance":0},{"className":"number","variants":[{"begin":"\\b(?:([0-9][0-9_]*)?\\.[0-9_]*(?:[eE][+-]?[0-9_]+)?|(0[Xx])?[0-9][0-9_]*\\.?[0-9_]*(?:[pP](?:[+-]?[0-9_]+)?)?)\\b","relevance":0},{"begin":"\\$[0-9][0-9A-Fa-f]*","relevance":0},{"begin":"\\b(?:[0-9A-Fa-f][0-9A-Fa-f_]*[Hh]|[0-9][0-9_]*[DdTt]?|[0-7][0-7_]*[QqOo]|[0-1][0-1_]*[BbYy])\\b"},{"begin":"\\b(?:0[Xx][0-9A-Fa-f_]+|0[DdTt][0-9_]+|0[QqOo][0-7_]+|0[BbYy][0-1_]+)\\b"}]},{"className":"string","begin":"\"","end":"\"","illegal":"\\n","contains":[{"begin":"\\\\[\\s\\S]","relevance":0},{"className":"subst","begin":"\\\\[abfnrtv]\\|\\\\x[0-9a-fA-F]*\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]","relevance":0},{"className":"subst","begin":"\\\\[abfnrtv]\\|\\\\x[0-9a-fA-F]*\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]","relevance":0}]},{"className":"string","variants":[{"begin":"'","end":"[^\\\\]'"},{"begin":"`","end":"[^\\\\]`"}],"relevance":0},{"className":"symbol","variants":[{"begin":"^\\s*[A-Za-z._?][A-Za-z0-9_$#@~.?]*(:|\\s+label)"},{"begin":"^\\s*%%[A-Za-z0-9_$#@~.?]*:"}],"relevance":0},{"className":"subst","begin":"%[0-9]+","relevance":0},{"className":"subst","begin":"%!S+","relevance":0},{"className":"meta","begin":"^\\s*\\.[\\w_-]+"}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/xl.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/xl.json new file mode 100644 index 00000000..6a338c71 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/xl.json @@ -0,0 +1 @@ +{"aliases":["tao"],"lexemes":"[a-zA-Z][a-zA-Z0-9_?]*","keywords":{"keyword":"if then else do while until for loop import with is as where when by data constant integer real text name boolean symbol infix prefix postfix block tree","literal":"true false nil","built_in":"in mod rem and or xor not abs sign floor ceil sqrt sin cos tan asin acos atan exp expm1 log log2 log10 log1p pi at text_length text_range text_find text_replace contains page slide basic_slide title_slide title subtitle fade_in fade_out fade_at clear_color color line_color line_width texture_wrap texture_transform texture scale_?x scale_?y scale_?z? translate_?x translate_?y translate_?z? rotate_?x rotate_?y rotate_?z? rectangle circle ellipse sphere path line_to move_to quad_to curve_to theme background contents locally time mouse_?x mouse_?y mouse_buttons ObjectLoader Animate MovieCredits Slides Filters Shading Materials LensFlare Mapping VLCAudioVideo StereoDecoder PointCloud NetworkAccess RemoteControl RegExp ChromaKey Snowfall NodeJS Speech Charts"},"contains":[{"className":"comment","begin":"//","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"/\\*","end":"\\*/","contains":[{"$ref":"#contains.0.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"string","begin":"\"","end":"\"","illegal":"\\n"},{"className":"string","begin":"'","end":"'","illegal":"\\n"},{"className":"string","begin":"<<","end":">>"},{"className":"function","begin":"[a-z][^\\n]*->","returnBegin":true,"end":"->","contains":[{"className":"title","begin":"[a-zA-Z]\\w*","relevance":0,"starts":{"endsWithParent":true,"keywords":{"$ref":"#keywords"}}}]},{"beginKeywords":"import","end":"$","keywords":{"$ref":"#keywords"},"contains":[{"$ref":"#contains.2"}]},{"className":"number","begin":"[0-9]+#[0-9A-Z_]+(\\.[0-9-A-Z_]+)?#?([Ee][+-]?[0-9]+)?"},{"className":"number","begin":"\\b\\d+(\\.\\d+)?","relevance":0}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/xml.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/xml.json new file mode 100644 index 00000000..6434a665 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/xml.json @@ -0,0 +1 @@ +{"aliases":["html","xhtml","rss","atom","xjb","xsd","xsl","plist","wsf"],"case_insensitive":true,"contains":[{"className":"meta","begin":"","relevance":10,"contains":[{"begin":"\\[","end":"\\]"}]},{"className":"comment","begin":"","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}],"relevance":10},{"begin":"<\\!\\[CDATA\\[","end":"\\]\\]>","relevance":10},{"className":"meta","begin":"<\\?xml","end":"\\?>","relevance":10},{"begin":"<\\?(php)?","end":"\\?>","subLanguage":"php","contains":[{"begin":"/\\*","end":"\\*/","skip":true},{"begin":"b\"","end":"\"","skip":true},{"begin":"b'","end":"'","skip":true},{"className":null,"begin":"'","end":"'","illegal":null,"contains":null,"skip":true},{"className":null,"begin":"\"","end":"\"","illegal":null,"contains":null,"skip":true}]},{"className":"tag","begin":"|$)","end":">","keywords":{"name":"style"},"contains":[{"endsWithParent":true,"illegal":"<","relevance":0,"contains":[{"className":"attr","begin":"[A-Za-z0-9\\._:-]+","relevance":0},{"begin":"=\\s*","relevance":0,"contains":[{"className":"string","endsParent":true,"variants":[{"begin":"\"","end":"\""},{"begin":"'","end":"'"},{"begin":"[^\\s\"'=<>`]+"}]}]}]}],"starts":{"end":"","returnEnd":true,"subLanguage":["css","xml"]}},{"className":"tag","begin":"|$)","end":">","keywords":{"name":"script"},"contains":[{"$ref":"#contains.5.contains.0"}],"starts":{"end":"","returnEnd":true,"subLanguage":["actionscript","javascript","handlebars","xml","vbscript"]}},{"className":"tag","begin":"","contains":[{"className":"name","begin":"[^\\/><\\s]+","relevance":0},{"$ref":"#contains.5.contains.0"}]}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/xquery.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/xquery.json new file mode 100644 index 00000000..3de2fb02 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/xquery.json @@ -0,0 +1 @@ +{"aliases":["xpath","xq"],"case_insensitive":false,"lexemes":"[a-zA-Z\\$][a-zA-Z0-9_:\\-]*","illegal":"(proc)|(abstract)|(extends)|(until)|(#)","keywords":{"keyword":"module schema namespace boundary-space preserve no-preserve strip default collation base-uri ordering context decimal-format decimal-separator copy-namespaces empty-sequence except exponent-separator external grouping-separator inherit no-inherit lax minus-sign per-mille percent schema-attribute schema-element strict unordered zero-digit declare import option function validate variable for at in let where order group by return if then else tumbling sliding window start when only end previous next stable ascending descending allowing empty greatest least some every satisfies switch case typeswitch try catch and or to union intersect instance of treat as castable cast map array delete insert into replace value rename copy modify update","type":"item document-node node attribute document element comment namespace namespace-node processing-instruction text construction xs:anyAtomicType xs:untypedAtomic xs:duration xs:time xs:decimal xs:float xs:double xs:gYearMonth xs:gYear xs:gMonthDay xs:gMonth xs:gDay xs:boolean xs:base64Binary xs:hexBinary xs:anyURI xs:QName xs:NOTATION xs:dateTime xs:dateTimeStamp xs:date xs:string xs:normalizedString xs:token xs:language xs:NMTOKEN xs:Name xs:NCName xs:ID xs:IDREF xs:ENTITY xs:integer xs:nonPositiveInteger xs:negativeInteger xs:long xs:int xs:short xs:byte xs:nonNegativeInteger xs:unisignedLong xs:unsignedInt xs:unsignedShort xs:unsignedByte xs:positiveInteger xs:yearMonthDuration xs:dayTimeDuration","literal":"eq ne lt le gt ge is self:: child:: descendant:: descendant-or-self:: attribute:: following:: following-sibling:: parent:: ancestor:: ancestor-or-self:: preceding:: preceding-sibling:: NaN"},"contains":[{"className":"variable","begin":"[\\$][\\w\\-:]+"},{"className":"built_in","variants":[{"begin":"\\barray\\:","end":"(?:append|filter|flatten|fold\\-(?:left|right)|for-each(?:\\-pair)?|get|head|insert\\-before|join|put|remove|reverse|size|sort|subarray|tail)\\b"},{"begin":"\\bmap\\:","end":"(?:contains|entry|find|for\\-each|get|keys|merge|put|remove|size)\\b"},{"begin":"\\bmath\\:","end":"(?:a(?:cos|sin|tan[2]?)|cos|exp(?:10)?|log(?:10)?|pi|pow|sin|sqrt|tan)\\b"},{"begin":"\\bop\\:","end":"\\(","excludeEnd":true},{"begin":"\\bfn\\:","end":"\\(","excludeEnd":true},{"begin":"[^<\\/\\$\\:'\"-]\\b(?:abs|accumulator\\-(?:after|before)|adjust\\-(?:date(?:Time)?|time)\\-to\\-timezone|analyze\\-string|apply|available\\-(?:environment\\-variables|system\\-properties)|avg|base\\-uri|boolean|ceiling|codepoints?\\-(?:equal|to\\-string)|collation\\-key|collection|compare|concat|contains(?:\\-token)?|copy\\-of|count|current(?:\\-)?(?:date(?:Time)?|time|group(?:ing\\-key)?|output\\-uri|merge\\-(?:group|key))?data|dateTime|days?\\-from\\-(?:date(?:Time)?|duration)|deep\\-equal|default\\-(?:collation|language)|distinct\\-values|document(?:\\-uri)?|doc(?:\\-available)?|element\\-(?:available|with\\-id)|empty|encode\\-for\\-uri|ends\\-with|environment\\-variable|error|escape\\-html\\-uri|exactly\\-one|exists|false|filter|floor|fold\\-(?:left|right)|for\\-each(?:\\-pair)?|format\\-(?:date(?:Time)?|time|integer|number)|function\\-(?:arity|available|lookup|name)|generate\\-id|has\\-children|head|hours\\-from\\-(?:dateTime|duration|time)|id(?:ref)?|implicit\\-timezone|in\\-scope\\-prefixes|index\\-of|innermost|insert\\-before|iri\\-to\\-uri|json\\-(?:doc|to\\-xml)|key|lang|last|load\\-xquery\\-module|local\\-name(?:\\-from\\-QName)?|(?:lower|upper)\\-case|matches|max|minutes\\-from\\-(?:dateTime|duration|time)|min|months?\\-from\\-(?:date(?:Time)?|duration)|name(?:space\\-uri\\-?(?:for\\-prefix|from\\-QName)?)?|nilled|node\\-name|normalize\\-(?:space|unicode)|not|number|one\\-or\\-more|outermost|parse\\-(?:ietf\\-date|json)|path|position|(?:prefix\\-from\\-)?QName|random\\-number\\-generator|regex\\-group|remove|replace|resolve\\-(?:QName|uri)|reverse|root|round(?:\\-half\\-to\\-even)?|seconds\\-from\\-(?:dateTime|duration|time)|snapshot|sort|starts\\-with|static\\-base\\-uri|stream\\-available|string\\-?(?:join|length|to\\-codepoints)?|subsequence|substring\\-?(?:after|before)?|sum|system\\-property|tail|timezone\\-from\\-(?:date(?:Time)?|time)|tokenize|trace|trans(?:form|late)|true|type\\-available|unordered|unparsed\\-(?:entity|text)?\\-?(?:public\\-id|uri|available|lines)?|uri\\-collection|xml\\-to\\-json|years?\\-from\\-(?:date(?:Time)?|duration)|zero\\-or\\-one)\\b"},{"begin":"\\blocal\\:","end":"\\(","excludeEnd":true},{"begin":"\\bzip\\:","end":"(?:zip\\-file|(?:xml|html|text|binary)\\-entry| (?:update\\-)?entries)\\b"},{"begin":"\\b(?:util|db|functx|app|xdmp|xmldb)\\:","end":"\\(","excludeEnd":true}]},{"className":"string","variants":[{"begin":"\"","end":"\"","contains":[{"begin":"\"\"","relevance":0}]},{"begin":"'","end":"'","contains":[{"begin":"''","relevance":0}]}]},{"className":"number","begin":"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b","relevance":0},{"className":"comment","begin":"\\(:","end":":\\)","relevance":10,"contains":[{"className":"doctag","begin":"@\\w+"}]},{"className":"meta","begin":"%[\\w\\-:]+"},{"className":"title","begin":"\\bxquery version \"[13]\\.[01]\"\\s?(?:encoding \".+\")?","end":";"},{"beginKeywords":"element attribute comment document processing-instruction","end":"{","excludeEnd":true},{"begin":"<([\\w\\._:\\-]+)((\\s*.*)=('|\").*('|\"))?>","end":"(\\/[\\w\\._:\\-]+>)","subLanguage":"xml","contains":[{"begin":"{","end":"}","subLanguage":"xquery"},"self"]}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/yaml.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/yaml.json new file mode 100644 index 00000000..3b42f789 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/yaml.json @@ -0,0 +1 @@ +{"case_insensitive":true,"aliases":["yml","YAML","yaml"],"contains":[{"className":"attr","variants":[{"begin":"^[ \\-]*[a-zA-Z_][\\w\\-]*:"},{"begin":"^[ \\-]*\"[a-zA-Z_][\\w\\-]*\":"},{"begin":"^[ \\-]*'[a-zA-Z_][\\w\\-]*':"}]},{"className":"meta","begin":"^---s*$","relevance":10},{"className":"string","begin":"[\\|>] *$","returnEnd":true,"contains":[{"begin":"\\\\[\\s\\S]","relevance":0},{"className":"template-variable","variants":[{"begin":"{{","end":"}}"},{"begin":"%{","end":"}"}]}],"end":"^[ \\-]*[a-zA-Z_][\\w\\-]*:"},{"begin":"<%[%=-]?","end":"[%-]?%>","subLanguage":"ruby","excludeBegin":true,"excludeEnd":true,"relevance":0},{"className":"type","begin":"![a-zA-Z_]\\w*"},{"className":"type","begin":"!![a-zA-Z_]\\w*"},{"className":"meta","begin":"&[a-zA-Z_]\\w*$"},{"className":"meta","begin":"\\*[a-zA-Z_]\\w*$"},{"className":"bullet","begin":"^ *-","relevance":0},{"className":"comment","begin":"#","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"beginKeywords":"true false yes no null","keywords":{"literal":"true false yes no null"}},{"className":"number","begin":"(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)","relevance":0},{"className":"string","relevance":0,"variants":[{"begin":"'","end":"'"},{"begin":"\"","end":"\""},{"begin":"\\S+"}],"contains":{"$ref":"#contains.2.contains"}}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/highlight/languages/zephir.json b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/zephir.json new file mode 100644 index 00000000..fbf71d52 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/highlight/languages/zephir.json @@ -0,0 +1 @@ +{"aliases":["zep"],"case_insensitive":true,"keywords":"and include_once list abstract global private echo interface as static endswitch array null if endwhile or const for endforeach self var let while isset public protected exit foreach throw elseif include __FILE__ empty require_once do xor return parent clone use __CLASS__ __LINE__ else break print eval new catch __METHOD__ case exception default die require __FUNCTION__ enddeclare final try switch continue endfor endif declare unset true false trait goto instanceof insteadof __DIR__ __NAMESPACE__ yield finally int uint long ulong char uchar double float bool boolean stringlikely unlikely","contains":[{"className":"comment","begin":"//","end":"$","contains":[{"begin":"\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"#","end":"$","contains":[{"$ref":"#contains.0.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"/\\*","end":"\\*/","contains":[{"className":"doctag","begin":"@[A-Za-z]+"},{"$ref":"#contains.0.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"comment","begin":"__halt_compiler.+?;","end":false,"contains":[{"$ref":"#contains.0.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}],"endsWithParent":true,"keywords":"__halt_compiler","lexemes":"[a-zA-Z_]\\w*"},{"className":"string","begin":"<<<['\"]?\\w+['\"]?$","end":"^\\w+;","contains":[{"begin":"\\\\[\\s\\S]","relevance":0}]},{"begin":"(::|->)+[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*"},{"className":"function","beginKeywords":"function","end":"[;{]","excludeEnd":true,"illegal":"\\$|\\[|%","contains":[{"className":"title","begin":"[a-zA-Z_]\\w*","relevance":0},{"className":"params","begin":"\\(","end":"\\)","contains":["self",{"className":"comment","begin":"/\\*","end":"\\*/","contains":[{"$ref":"#contains.0.contains.0"},{"className":"doctag","begin":"(?:TODO|FIXME|NOTE|BUG|XXX):","relevance":0}]},{"className":"string","contains":[{"$ref":"#contains.4.contains.0"}],"variants":[{"begin":"b\"","end":"\""},{"begin":"b'","end":"'"},{"className":"string","begin":"'","end":"'","illegal":null,"contains":[{"$ref":"#contains.4.contains.0"}]},{"className":"string","begin":"\"","end":"\"","illegal":null,"contains":[{"$ref":"#contains.4.contains.0"},{"className":"subst","begin":"\\\\[abfnrtv]\\|\\\\x[0-9a-fA-F]*\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]","relevance":0},{"className":"subst","begin":"\\\\[abfnrtv]\\|\\\\x[0-9a-fA-F]*\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]","relevance":0}]}]},{"variants":[{"className":"number","begin":"\\b(0b[01]+)","relevance":0},{"className":"number","begin":"(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)","relevance":0}]}]}]},{"className":"class","beginKeywords":"class interface","end":"{","excludeEnd":true,"illegal":"[:\\(\\$\"]","contains":[{"beginKeywords":"extends implements"},{"$ref":"#contains.6.contains.0"}]},{"beginKeywords":"namespace","end":";","illegal":"[\\.']","contains":[{"$ref":"#contains.6.contains.0"}]},{"beginKeywords":"use","end":";","contains":[{"$ref":"#contains.6.contains.0"}]},{"begin":"=>"},{"$ref":"#contains.6.contains.1.contains.2"},{"$ref":"#contains.6.contains.1.contains.3"}]} diff --git a/Sites/pages/components/com_pages/resources/vendor/markdown/Markdown.inc.php b/Sites/pages/components/com_pages/resources/vendor/markdown/Markdown.inc.php new file mode 100644 index 00000000..e2bd3808 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/markdown/Markdown.inc.php @@ -0,0 +1,10 @@ + + * @copyright 2004-2018 Michel Fortin + * @copyright (Original Markdown) 2004-2006 John Gruber + */ + +namespace Michelf; + +/** + * Markdown Parser Class + */ +class Markdown implements MarkdownInterface { + /** + * Define the package version + * @var string + */ + const MARKDOWNLIB_VERSION = "1.8.0"; + + /** + * Simple function interface - Initialize the parser and return the result + * of its transform method. This will work fine for derived classes too. + * + * @api + * + * @param string $text + * @return string + */ + public static function defaultTransform($text) { + // Take parser class on which this function was called. + $parser_class = \get_called_class(); + + // Try to take parser from the static parser list + static $parser_list; + $parser =& $parser_list[$parser_class]; + + // Create the parser it not already set + if (!$parser) { + $parser = new $parser_class; + } + + // Transform text using parser. + return $parser->transform($text); + } + + /** + * Configuration variables + */ + + /** + * Change to ">" for HTML output. + * @var string + */ + public $empty_element_suffix = " />"; + + /** + * The width of indentation of the output markup + * @var int + */ + public $tab_width = 4; + + /** + * Change to `true` to disallow markup or entities. + * @var boolean + */ + public $no_markup = false; + public $no_entities = false; + + + /** + * Change to `true` to enable line breaks on \n without two trailling spaces + * @var boolean + */ + public $hard_wrap = false; + + /** + * Predefined URLs and titles for reference links and images. + * @var array + */ + public $predef_urls = array(); + public $predef_titles = array(); + + /** + * Optional filter function for URLs + * @var callable + */ + public $url_filter_func = null; + + /** + * Optional header id="" generation callback function. + * @var callable + */ + public $header_id_func = null; + + /** + * Optional function for converting code block content to HTML + * @var callable + */ + public $code_block_content_func = null; + + /** + * Optional function for converting code span content to HTML. + * @var callable + */ + public $code_span_content_func = null; + + /** + * Class attribute to toggle "enhanced ordered list" behaviour + * setting this to true will allow ordered lists to start from the index + * number that is defined first. + * + * For example: + * 2. List item two + * 3. List item three + * + * Becomes: + *
        + *
      1. List item two
      2. + *
      3. List item three
      4. + *
      + * + * @var bool + */ + public $enhanced_ordered_list = false; + + /** + * Parser implementation + */ + + /** + * Regex to match balanced [brackets]. + * Needed to insert a maximum bracked depth while converting to PHP. + * @var int + */ + protected $nested_brackets_depth = 6; + protected $nested_brackets_re; + + protected $nested_url_parenthesis_depth = 4; + protected $nested_url_parenthesis_re; + + /** + * Table of hash values for escaped characters: + * @var string + */ + protected $escape_chars = '\`*_{}[]()>#+-.!'; + protected $escape_chars_re; + + /** + * Constructor function. Initialize appropriate member variables. + * @return void + */ + public function __construct() { + $this->_initDetab(); + $this->prepareItalicsAndBold(); + + $this->nested_brackets_re = + str_repeat('(?>[^\[\]]+|\[', $this->nested_brackets_depth). + str_repeat('\])*', $this->nested_brackets_depth); + + $this->nested_url_parenthesis_re = + str_repeat('(?>[^()\s]+|\(', $this->nested_url_parenthesis_depth). + str_repeat('(?>\)))*', $this->nested_url_parenthesis_depth); + + $this->escape_chars_re = '['.preg_quote($this->escape_chars).']'; + + // Sort document, block, and span gamut in ascendent priority order. + asort($this->document_gamut); + asort($this->block_gamut); + asort($this->span_gamut); + } + + + /** + * Internal hashes used during transformation. + * @var array + */ + protected $urls = array(); + protected $titles = array(); + protected $html_hashes = array(); + + /** + * Status flag to avoid invalid nesting. + * @var boolean + */ + protected $in_anchor = false; + + /** + * Status flag to avoid invalid nesting. + * @var boolean + */ + protected $in_emphasis_processing = false; + + /** + * Called before the transformation process starts to setup parser states. + * @return void + */ + protected function setup() { + // Clear global hashes. + $this->urls = $this->predef_urls; + $this->titles = $this->predef_titles; + $this->html_hashes = array(); + $this->in_anchor = false; + $this->in_emphasis_processing = false; + } + + /** + * Called after the transformation process to clear any variable which may + * be taking up memory unnecessarly. + * @return void + */ + protected function teardown() { + $this->urls = array(); + $this->titles = array(); + $this->html_hashes = array(); + } + + /** + * Main function. Performs some preprocessing on the input text and pass + * it through the document gamut. + * + * @api + * + * @param string $text + * @return string + */ + public function transform($text) { + $this->setup(); + + # Remove UTF-8 BOM and marker character in input, if present. + $text = preg_replace('{^\xEF\xBB\xBF|\x1A}', '', $text); + + # Standardize line endings: + # DOS to Unix and Mac to Unix + $text = preg_replace('{\r\n?}', "\n", $text); + + # Make sure $text ends with a couple of newlines: + $text .= "\n\n"; + + # Convert all tabs to spaces. + $text = $this->detab($text); + + # Turn block-level HTML blocks into hash entries + $text = $this->hashHTMLBlocks($text); + + # Strip any lines consisting only of spaces and tabs. + # This makes subsequent regexen easier to write, because we can + # match consecutive blank lines with /\n+/ instead of something + # contorted like /[ ]*\n+/ . + $text = preg_replace('/^[ ]+$/m', '', $text); + + # Run document gamut methods. + foreach ($this->document_gamut as $method => $priority) { + $text = $this->$method($text); + } + + $this->teardown(); + + return $text . "\n"; + } + + /** + * Define the document gamut + * @var array + */ + protected $document_gamut = array( + // Strip link definitions, store in hashes. + "stripLinkDefinitions" => 20, + "runBasicBlockGamut" => 30, + ); + + /** + * Strips link definitions from text, stores the URLs and titles in + * hash references + * @param string $text + * @return string + */ + protected function stripLinkDefinitions($text) { + + $less_than_tab = $this->tab_width - 1; + + // Link defs are in the form: ^[id]: url "optional title" + $text = preg_replace_callback('{ + ^[ ]{0,'.$less_than_tab.'}\[(.+)\][ ]?: # id = $1 + [ ]* + \n? # maybe *one* newline + [ ]* + (?: + <(.+?)> # url = $2 + | + (\S+?) # url = $3 + ) + [ ]* + \n? # maybe one newline + [ ]* + (?: + (?<=\s) # lookbehind for whitespace + ["(] + (.*?) # title = $4 + [")] + [ ]* + )? # title is optional + (?:\n+|\Z) + }xm', + array($this, '_stripLinkDefinitions_callback'), + $text + ); + return $text; + } + + /** + * The callback to strip link definitions + * @param array $matches + * @return string + */ + protected function _stripLinkDefinitions_callback($matches) { + $link_id = strtolower($matches[1]); + $url = $matches[2] == '' ? $matches[3] : $matches[2]; + $this->urls[$link_id] = $url; + $this->titles[$link_id] =& $matches[4]; + return ''; // String that will replace the block + } + + /** + * Hashify HTML blocks + * @param string $text + * @return string + */ + protected function hashHTMLBlocks($text) { + if ($this->no_markup) { + return $text; + } + + $less_than_tab = $this->tab_width - 1; + + /** + * Hashify HTML blocks: + * + * We only want to do this for block-level HTML tags, such as headers, + * lists, and tables. That's because we still want to wrap

      s around + * "paragraphs" that are wrapped in non-block-level tags, such as + * anchors, phrase emphasis, and spans. The list of tags we're looking + * for is hard-coded: + * + * * List "a" is made of tags which can be both inline or block-level. + * These will be treated block-level when the start tag is alone on + * its line, otherwise they're not matched here and will be taken as + * inline later. + * * List "b" is made of tags which are always block-level; + */ + $block_tags_a_re = 'ins|del'; + $block_tags_b_re = 'p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|address|'. + 'script|noscript|style|form|fieldset|iframe|math|svg|'. + 'article|section|nav|aside|hgroup|header|footer|'. + 'figure'; + + // Regular expression for the content of a block tag. + $nested_tags_level = 4; + $attr = ' + (?> # optional tag attributes + \s # starts with whitespace + (?> + [^>"/]+ # text outside quotes + | + /+(?!>) # slash not followed by ">" + | + "[^"]*" # text inside double quotes (tolerate ">") + | + \'[^\']*\' # text inside single quotes (tolerate ">") + )* + )? + '; + $content = + str_repeat(' + (?> + [^<]+ # content without tag + | + <\2 # nested opening tag + '.$attr.' # attributes + (?> + /> + | + >', $nested_tags_level). // end of opening tag + '.*?'. // last level nested tag content + str_repeat(' + # closing nested tag + ) + | + <(?!/\2\s*> # other tags with a different name + ) + )*', + $nested_tags_level); + $content2 = str_replace('\2', '\3', $content); + + /** + * First, look for nested blocks, e.g.: + *

      + *
      + * tags for inner block must be indented. + *
      + *
      + * + * The outermost tags must start at the left margin for this to match, + * and the inner nested divs must be indented. + * We need to do this before the next, more liberal match, because the + * next match will start at the first `
      ` and stop at the + * first `
      `. + */ + $text = preg_replace_callback('{(?> + (?> + (?<=\n) # Starting on its own line + | # or + \A\n? # the at beginning of the doc + ) + ( # save in $1 + + # Match from `\n` to `\n`, handling nested tags + # in between. + + [ ]{0,'.$less_than_tab.'} + <('.$block_tags_b_re.')# start tag = $2 + '.$attr.'> # attributes followed by > and \n + '.$content.' # content, support nesting + # the matching end tag + [ ]* # trailing spaces/tabs + (?=\n+|\Z) # followed by a newline or end of document + + | # Special version for tags of group a. + + [ ]{0,'.$less_than_tab.'} + <('.$block_tags_a_re.')# start tag = $3 + '.$attr.'>[ ]*\n # attributes followed by > + '.$content2.' # content, support nesting + # the matching end tag + [ ]* # trailing spaces/tabs + (?=\n+|\Z) # followed by a newline or end of document + + | # Special case just for
      . It was easier to make a special + # case than to make the other regex more complicated. + + [ ]{0,'.$less_than_tab.'} + <(hr) # start tag = $2 + '.$attr.' # attributes + /?> # the matching end tag + [ ]* + (?=\n{2,}|\Z) # followed by a blank line or end of document + + | # Special case for standalone HTML comments: + + [ ]{0,'.$less_than_tab.'} + (?s: + + ) + [ ]* + (?=\n{2,}|\Z) # followed by a blank line or end of document + + | # PHP and ASP-style processor instructions ( + ) + [ ]* + (?=\n{2,}|\Z) # followed by a blank line or end of document + + ) + )}Sxmi', + array($this, '_hashHTMLBlocks_callback'), + $text + ); + + return $text; + } + + /** + * The callback for hashing HTML blocks + * @param string $matches + * @return string + */ + protected function _hashHTMLBlocks_callback($matches) { + $text = $matches[1]; + $key = $this->hashBlock($text); + return "\n\n$key\n\n"; + } + + /** + * Called whenever a tag must be hashed when a function insert an atomic + * element in the text stream. Passing $text to through this function gives + * a unique text-token which will be reverted back when calling unhash. + * + * The $boundary argument specify what character should be used to surround + * the token. By convension, "B" is used for block elements that needs not + * to be wrapped into paragraph tags at the end, ":" is used for elements + * that are word separators and "X" is used in the general case. + * + * @param string $text + * @param string $boundary + * @return string + */ + protected function hashPart($text, $boundary = 'X') { + // Swap back any tag hash found in $text so we do not have to `unhash` + // multiple times at the end. + $text = $this->unhash($text); + + // Then hash the block. + static $i = 0; + $key = "$boundary\x1A" . ++$i . $boundary; + $this->html_hashes[$key] = $text; + return $key; // String that will replace the tag. + } + + /** + * Shortcut function for hashPart with block-level boundaries. + * @param string $text + * @return string + */ + protected function hashBlock($text) { + return $this->hashPart($text, 'B'); + } + + /** + * Define the block gamut - these are all the transformations that form + * block-level tags like paragraphs, headers, and list items. + * @var array + */ + protected $block_gamut = array( + "doHeaders" => 10, + "doHorizontalRules" => 20, + "doLists" => 40, + "doCodeBlocks" => 50, + "doBlockQuotes" => 60, + ); + + /** + * Run block gamut tranformations. + * + * We need to escape raw HTML in Markdown source before doing anything + * else. This need to be done for each block, and not only at the + * begining in the Markdown function since hashed blocks can be part of + * list items and could have been indented. Indented blocks would have + * been seen as a code block in a previous pass of hashHTMLBlocks. + * + * @param string $text + * @return string + */ + protected function runBlockGamut($text) { + $text = $this->hashHTMLBlocks($text); + return $this->runBasicBlockGamut($text); + } + + /** + * Run block gamut tranformations, without hashing HTML blocks. This is + * useful when HTML blocks are known to be already hashed, like in the first + * whole-document pass. + * + * @param string $text + * @return string + */ + protected function runBasicBlockGamut($text) { + + foreach ($this->block_gamut as $method => $priority) { + $text = $this->$method($text); + } + + // Finally form paragraph and restore hashed blocks. + $text = $this->formParagraphs($text); + + return $text; + } + + /** + * Convert horizontal rules + * @param string $text + * @return string + */ + protected function doHorizontalRules($text) { + return preg_replace( + '{ + ^[ ]{0,3} # Leading space + ([-*_]) # $1: First marker + (?> # Repeated marker group + [ ]{0,2} # Zero, one, or two spaces. + \1 # Marker character + ){2,} # Group repeated at least twice + [ ]* # Tailing spaces + $ # End of line. + }mx', + "\n".$this->hashBlock("empty_element_suffix")."\n", + $text + ); + } + + /** + * These are all the transformations that occur *within* block-level + * tags like paragraphs, headers, and list items. + * @var array + */ + protected $span_gamut = array( + // Process character escapes, code spans, and inline HTML + // in one shot. + "parseSpan" => -30, + // Process anchor and image tags. Images must come first, + // because ![foo][f] looks like an anchor. + "doImages" => 10, + "doAnchors" => 20, + // Make links out of things like `` + // Must come after doAnchors, because you can use < and > + // delimiters in inline links like [this](). + "doAutoLinks" => 30, + "encodeAmpsAndAngles" => 40, + "doItalicsAndBold" => 50, + "doHardBreaks" => 60, + ); + + /** + * Run span gamut transformations + * @param string $text + * @return string + */ + protected function runSpanGamut($text) { + foreach ($this->span_gamut as $method => $priority) { + $text = $this->$method($text); + } + + return $text; + } + + /** + * Do hard breaks + * @param string $text + * @return string + */ + protected function doHardBreaks($text) { + if ($this->hard_wrap) { + return preg_replace_callback('/ *\n/', + array($this, '_doHardBreaks_callback'), $text); + } else { + return preg_replace_callback('/ {2,}\n/', + array($this, '_doHardBreaks_callback'), $text); + } + } + + /** + * Trigger part hashing for the hard break (callback method) + * @param array $matches + * @return string + */ + protected function _doHardBreaks_callback($matches) { + return $this->hashPart("empty_element_suffix\n"); + } + + /** + * Turn Markdown link shortcuts into XHTML tags. + * @param string $text + * @return string + */ + protected function doAnchors($text) { + if ($this->in_anchor) { + return $text; + } + $this->in_anchor = true; + + // First, handle reference-style links: [link text] [id] + $text = preg_replace_callback('{ + ( # wrap whole match in $1 + \[ + ('.$this->nested_brackets_re.') # link text = $2 + \] + + [ ]? # one optional space + (?:\n[ ]*)? # one optional newline followed by spaces + + \[ + (.*?) # id = $3 + \] + ) + }xs', + array($this, '_doAnchors_reference_callback'), $text); + + // Next, inline-style links: [link text](url "optional title") + $text = preg_replace_callback('{ + ( # wrap whole match in $1 + \[ + ('.$this->nested_brackets_re.') # link text = $2 + \] + \( # literal paren + [ \n]* + (?: + <(.+?)> # href = $3 + | + ('.$this->nested_url_parenthesis_re.') # href = $4 + ) + [ \n]* + ( # $5 + ([\'"]) # quote char = $6 + (.*?) # Title = $7 + \6 # matching quote + [ \n]* # ignore any spaces/tabs between closing quote and ) + )? # title is optional + \) + ) + }xs', + array($this, '_doAnchors_inline_callback'), $text); + + // Last, handle reference-style shortcuts: [link text] + // These must come last in case you've also got [link text][1] + // or [link text](/foo) + $text = preg_replace_callback('{ + ( # wrap whole match in $1 + \[ + ([^\[\]]+) # link text = $2; can\'t contain [ or ] + \] + ) + }xs', + array($this, '_doAnchors_reference_callback'), $text); + + $this->in_anchor = false; + return $text; + } + + /** + * Callback method to parse referenced anchors + * @param string $matches + * @return string + */ + protected function _doAnchors_reference_callback($matches) { + $whole_match = $matches[1]; + $link_text = $matches[2]; + $link_id =& $matches[3]; + + if ($link_id == "") { + // for shortcut links like [this][] or [this]. + $link_id = $link_text; + } + + // lower-case and turn embedded newlines into spaces + $link_id = strtolower($link_id); + $link_id = preg_replace('{[ ]?\n}', ' ', $link_id); + + if (isset($this->urls[$link_id])) { + $url = $this->urls[$link_id]; + $url = $this->encodeURLAttribute($url); + + $result = "titles[$link_id] ) ) { + $title = $this->titles[$link_id]; + $title = $this->encodeAttribute($title); + $result .= " title=\"$title\""; + } + + $link_text = $this->runSpanGamut($link_text); + $result .= ">$link_text"; + $result = $this->hashPart($result); + } else { + $result = $whole_match; + } + return $result; + } + + /** + * Callback method to parse inline anchors + * @param string $matches + * @return string + */ + protected function _doAnchors_inline_callback($matches) { + $whole_match = $matches[1]; + $link_text = $this->runSpanGamut($matches[2]); + $url = $matches[3] == '' ? $matches[4] : $matches[3]; + $title =& $matches[7]; + + // If the URL was of the form it got caught by the HTML + // tag parser and hashed. Need to reverse the process before using + // the URL. + $unhashed = $this->unhash($url); + if ($unhashed != $url) + $url = preg_replace('/^<(.*)>$/', '\1', $unhashed); + + $url = $this->encodeURLAttribute($url); + + $result = "encodeAttribute($title); + $result .= " title=\"$title\""; + } + + $link_text = $this->runSpanGamut($link_text); + $result .= ">$link_text"; + + return $this->hashPart($result); + } + + /** + * Turn Markdown image shortcuts into tags. + * @param string $text + * @return string + */ + protected function doImages($text) { + // First, handle reference-style labeled images: ![alt text][id] + $text = preg_replace_callback('{ + ( # wrap whole match in $1 + !\[ + ('.$this->nested_brackets_re.') # alt text = $2 + \] + + [ ]? # one optional space + (?:\n[ ]*)? # one optional newline followed by spaces + + \[ + (.*?) # id = $3 + \] + + ) + }xs', + array($this, '_doImages_reference_callback'), $text); + + // Next, handle inline images: ![alt text](url "optional title") + // Don't forget: encode * and _ + $text = preg_replace_callback('{ + ( # wrap whole match in $1 + !\[ + ('.$this->nested_brackets_re.') # alt text = $2 + \] + \s? # One optional whitespace character + \( # literal paren + [ \n]* + (?: + <(\S*)> # src url = $3 + | + ('.$this->nested_url_parenthesis_re.') # src url = $4 + ) + [ \n]* + ( # $5 + ([\'"]) # quote char = $6 + (.*?) # title = $7 + \6 # matching quote + [ \n]* + )? # title is optional + \) + ) + }xs', + array($this, '_doImages_inline_callback'), $text); + + return $text; + } + + /** + * Callback to parse references image tags + * @param array $matches + * @return string + */ + protected function _doImages_reference_callback($matches) { + $whole_match = $matches[1]; + $alt_text = $matches[2]; + $link_id = strtolower($matches[3]); + + if ($link_id == "") { + $link_id = strtolower($alt_text); // for shortcut links like ![this][]. + } + + $alt_text = $this->encodeAttribute($alt_text); + if (isset($this->urls[$link_id])) { + $url = $this->encodeURLAttribute($this->urls[$link_id]); + $result = "\"$alt_text\"";titles[$link_id])) { + $title = $this->titles[$link_id]; + $title = $this->encodeAttribute($title); + $result .= " title=\"$title\""; + } + $result .= $this->empty_element_suffix; + $result = $this->hashPart($result); + } else { + // If there's no such link ID, leave intact: + $result = $whole_match; + } + + return $result; + } + + /** + * Callback to parse inline image tags + * @param array $matches + * @return string + */ + protected function _doImages_inline_callback($matches) { + $whole_match = $matches[1]; + $alt_text = $matches[2]; + $url = $matches[3] == '' ? $matches[4] : $matches[3]; + $title =& $matches[7]; + + $alt_text = $this->encodeAttribute($alt_text); + $url = $this->encodeURLAttribute($url); + $result = "\"$alt_text\"";encodeAttribute($title); + $result .= " title=\"$title\""; // $title already quoted + } + $result .= $this->empty_element_suffix; + + return $this->hashPart($result); + } + + /** + * Parse Markdown heading elements to HTML + * @param string $text + * @return string + */ + protected function doHeaders($text) { + /** + * Setext-style headers: + * Header 1 + * ======== + * + * Header 2 + * -------- + */ + $text = preg_replace_callback('{ ^(.+?)[ ]*\n(=+|-+)[ ]*\n+ }mx', + array($this, '_doHeaders_callback_setext'), $text); + + /** + * atx-style headers: + * # Header 1 + * ## Header 2 + * ## Header 2 with closing hashes ## + * ... + * ###### Header 6 + */ + $text = preg_replace_callback('{ + ^(\#{1,6}) # $1 = string of #\'s + [ ]* + (.+?) # $2 = Header text + [ ]* + \#* # optional closing #\'s (not counted) + \n+ + }xm', + array($this, '_doHeaders_callback_atx'), $text); + + return $text; + } + + /** + * Setext header parsing callback + * @param array $matches + * @return string + */ + protected function _doHeaders_callback_setext($matches) { + // Terrible hack to check we haven't found an empty list item. + if ($matches[2] == '-' && preg_match('{^-(?: |$)}', $matches[1])) { + return $matches[0]; + } + + $level = $matches[2]{0} == '=' ? 1 : 2; + + // ID attribute generation + $idAtt = $this->_generateIdFromHeaderValue($matches[1]); + + $block = "".$this->runSpanGamut($matches[1]).""; + return "\n" . $this->hashBlock($block) . "\n\n"; + } + + /** + * ATX header parsing callback + * @param array $matches + * @return string + */ + protected function _doHeaders_callback_atx($matches) { + // ID attribute generation + $idAtt = $this->_generateIdFromHeaderValue($matches[2]); + + $level = strlen($matches[1]); + $block = "".$this->runSpanGamut($matches[2]).""; + return "\n" . $this->hashBlock($block) . "\n\n"; + } + + /** + * If a header_id_func property is set, we can use it to automatically + * generate an id attribute. + * + * This method returns a string in the form id="foo", or an empty string + * otherwise. + * @param string $headerValue + * @return string + */ + protected function _generateIdFromHeaderValue($headerValue) { + if (!is_callable($this->header_id_func)) { + return ""; + } + + $idValue = call_user_func($this->header_id_func, $headerValue); + if (!$idValue) { + return ""; + } + + return ' id="' . $this->encodeAttribute($idValue) . '"'; + } + + /** + * Form HTML ordered (numbered) and unordered (bulleted) lists. + * @param string $text + * @return string + */ + protected function doLists($text) { + $less_than_tab = $this->tab_width - 1; + + // Re-usable patterns to match list item bullets and number markers: + $marker_ul_re = '[*+-]'; + $marker_ol_re = '\d+[\.]'; + + $markers_relist = array( + $marker_ul_re => $marker_ol_re, + $marker_ol_re => $marker_ul_re, + ); + + foreach ($markers_relist as $marker_re => $other_marker_re) { + // Re-usable pattern to match any entirel ul or ol list: + $whole_list_re = ' + ( # $1 = whole list + ( # $2 + ([ ]{0,'.$less_than_tab.'}) # $3 = number of spaces + ('.$marker_re.') # $4 = first list item marker + [ ]+ + ) + (?s:.+?) + ( # $5 + \z + | + \n{2,} + (?=\S) + (?! # Negative lookahead for another list item marker + [ ]* + '.$marker_re.'[ ]+ + ) + | + (?= # Lookahead for another kind of list + \n + \3 # Must have the same indentation + '.$other_marker_re.'[ ]+ + ) + ) + ) + '; // mx + + // We use a different prefix before nested lists than top-level lists. + //See extended comment in _ProcessListItems(). + + if ($this->list_level) { + $text = preg_replace_callback('{ + ^ + '.$whole_list_re.' + }mx', + array($this, '_doLists_callback'), $text); + } else { + $text = preg_replace_callback('{ + (?:(?<=\n)\n|\A\n?) # Must eat the newline + '.$whole_list_re.' + }mx', + array($this, '_doLists_callback'), $text); + } + } + + return $text; + } + + /** + * List parsing callback + * @param array $matches + * @return string + */ + protected function _doLists_callback($matches) { + // Re-usable patterns to match list item bullets and number markers: + $marker_ul_re = '[*+-]'; + $marker_ol_re = '\d+[\.]'; + $marker_any_re = "(?:$marker_ul_re|$marker_ol_re)"; + $marker_ol_start_re = '[0-9]+'; + + $list = $matches[1]; + $list_type = preg_match("/$marker_ul_re/", $matches[4]) ? "ul" : "ol"; + + $marker_any_re = ( $list_type == "ul" ? $marker_ul_re : $marker_ol_re ); + + $list .= "\n"; + $result = $this->processListItems($list, $marker_any_re); + + $ol_start = 1; + if ($this->enhanced_ordered_list) { + // Get the start number for ordered list. + if ($list_type == 'ol') { + $ol_start_array = array(); + $ol_start_check = preg_match("/$marker_ol_start_re/", $matches[4], $ol_start_array); + if ($ol_start_check){ + $ol_start = $ol_start_array[0]; + } + } + } + + if ($ol_start > 1 && $list_type == 'ol'){ + $result = $this->hashBlock("<$list_type start=\"$ol_start\">\n" . $result . ""); + } else { + $result = $this->hashBlock("<$list_type>\n" . $result . ""); + } + return "\n". $result ."\n\n"; + } + + /** + * Nesting tracker for list levels + * @var integer + */ + protected $list_level = 0; + + /** + * Process the contents of a single ordered or unordered list, splitting it + * into individual list items. + * @param string $list_str + * @param string $marker_any_re + * @return string + */ + protected function processListItems($list_str, $marker_any_re) { + /** + * The $this->list_level global keeps track of when we're inside a list. + * Each time we enter a list, we increment it; when we leave a list, + * we decrement. If it's zero, we're not in a list anymore. + * + * We do this because when we're not inside a list, we want to treat + * something like this: + * + * I recommend upgrading to version + * 8. Oops, now this line is treated + * as a sub-list. + * + * As a single paragraph, despite the fact that the second line starts + * with a digit-period-space sequence. + * + * Whereas when we're inside a list (or sub-list), that line will be + * treated as the start of a sub-list. What a kludge, huh? This is + * an aspect of Markdown's syntax that's hard to parse perfectly + * without resorting to mind-reading. Perhaps the solution is to + * change the syntax rules such that sub-lists must start with a + * starting cardinal number; e.g. "1." or "a.". + */ + $this->list_level++; + + // Trim trailing blank lines: + $list_str = preg_replace("/\n{2,}\\z/", "\n", $list_str); + + $list_str = preg_replace_callback('{ + (\n)? # leading line = $1 + (^[ ]*) # leading whitespace = $2 + ('.$marker_any_re.' # list marker and space = $3 + (?:[ ]+|(?=\n)) # space only required if item is not empty + ) + ((?s:.*?)) # list item text = $4 + (?:(\n+(?=\n))|\n) # tailing blank line = $5 + (?= \n* (\z | \2 ('.$marker_any_re.') (?:[ ]+|(?=\n)))) + }xm', + array($this, '_processListItems_callback'), $list_str); + + $this->list_level--; + return $list_str; + } + + /** + * List item parsing callback + * @param array $matches + * @return string + */ + protected function _processListItems_callback($matches) { + $item = $matches[4]; + $leading_line =& $matches[1]; + $leading_space =& $matches[2]; + $marker_space = $matches[3]; + $tailing_blank_line =& $matches[5]; + + if ($leading_line || $tailing_blank_line || + preg_match('/\n{2,}/', $item)) + { + // Replace marker with the appropriate whitespace indentation + $item = $leading_space . str_repeat(' ', strlen($marker_space)) . $item; + $item = $this->runBlockGamut($this->outdent($item)."\n"); + } else { + // Recursion for sub-lists: + $item = $this->doLists($this->outdent($item)); + $item = $this->formParagraphs($item, false); + } + + return "
    • " . $item . "
    • \n"; + } + + /** + * Process Markdown `
      ` blocks.
      +	 * @param  string $text
      +	 * @return string
      +	 */
      +	protected function doCodeBlocks($text) {
      +		$text = preg_replace_callback('{
      +				(?:\n\n|\A\n?)
      +				(	            # $1 = the code block -- one or more lines, starting with a space/tab
      +				  (?>
      +					[ ]{'.$this->tab_width.'}  # Lines must start with a tab or a tab-width of spaces
      +					.*\n+
      +				  )+
      +				)
      +				((?=^[ ]{0,'.$this->tab_width.'}\S)|\Z)	# Lookahead for non-space at line-start, or end of doc
      +			}xm',
      +			array($this, '_doCodeBlocks_callback'), $text);
      +
      +		return $text;
      +	}
      +
      +	/**
      +	 * Code block parsing callback
      +	 * @param  array $matches
      +	 * @return string
      +	 */
      +	protected function _doCodeBlocks_callback($matches) {
      +		$codeblock = $matches[1];
      +
      +		$codeblock = $this->outdent($codeblock);
      +		if ($this->code_block_content_func) {
      +			$codeblock = call_user_func($this->code_block_content_func, $codeblock, "");
      +		} else {
      +			$codeblock = htmlspecialchars($codeblock, ENT_NOQUOTES);
      +		}
      +
      +		# trim leading newlines and trailing newlines
      +		$codeblock = preg_replace('/\A\n+|\n+\z/', '', $codeblock);
      +
      +		$codeblock = "
      $codeblock\n
      "; + return "\n\n" . $this->hashBlock($codeblock) . "\n\n"; + } + + /** + * Create a code span markup for $code. Called from handleSpanToken. + * @param string $code + * @return string + */ + protected function makeCodeSpan($code) { + if ($this->code_span_content_func) { + $code = call_user_func($this->code_span_content_func, $code); + } else { + $code = htmlspecialchars(trim($code), ENT_NOQUOTES); + } + return $this->hashPart("$code"); + } + + /** + * Define the emphasis operators with their regex matches + * @var array + */ + protected $em_relist = array( + '' => '(?:(? '(? '(? '(?:(? '(? '(? '(?:(? '(? '(?em_relist as $em => $em_re) { + foreach ($this->strong_relist as $strong => $strong_re) { + // Construct list of allowed token expressions. + $token_relist = array(); + if (isset($this->em_strong_relist["$em$strong"])) { + $token_relist[] = $this->em_strong_relist["$em$strong"]; + } + $token_relist[] = $em_re; + $token_relist[] = $strong_re; + + // Construct master expression from list. + $token_re = '{(' . implode('|', $token_relist) . ')}'; + $this->em_strong_prepared_relist["$em$strong"] = $token_re; + } + } + } + + /** + * Convert Markdown italics (emphasis) and bold (strong) to HTML + * @param string $text + * @return string + */ + protected function doItalicsAndBold($text) { + if ($this->in_emphasis_processing) { + return $text; // avoid reentrency + } + $this->in_emphasis_processing = true; + + $token_stack = array(''); + $text_stack = array(''); + $em = ''; + $strong = ''; + $tree_char_em = false; + + while (1) { + // Get prepared regular expression for seraching emphasis tokens + // in current context. + $token_re = $this->em_strong_prepared_relist["$em$strong"]; + + // Each loop iteration search for the next emphasis token. + // Each token is then passed to handleSpanToken. + $parts = preg_split($token_re, $text, 2, PREG_SPLIT_DELIM_CAPTURE); + $text_stack[0] .= $parts[0]; + $token =& $parts[1]; + $text =& $parts[2]; + + if (empty($token)) { + // Reached end of text span: empty stack without emitting. + // any more emphasis. + while ($token_stack[0]) { + $text_stack[1] .= array_shift($token_stack); + $text_stack[0] .= array_shift($text_stack); + } + break; + } + + $token_len = strlen($token); + if ($tree_char_em) { + // Reached closing marker while inside a three-char emphasis. + if ($token_len == 3) { + // Three-char closing marker, close em and strong. + array_shift($token_stack); + $span = array_shift($text_stack); + $span = $this->runSpanGamut($span); + $span = "$span"; + $text_stack[0] .= $this->hashPart($span); + $em = ''; + $strong = ''; + } else { + // Other closing marker: close one em or strong and + // change current token state to match the other + $token_stack[0] = str_repeat($token{0}, 3-$token_len); + $tag = $token_len == 2 ? "strong" : "em"; + $span = $text_stack[0]; + $span = $this->runSpanGamut($span); + $span = "<$tag>$span"; + $text_stack[0] = $this->hashPart($span); + $$tag = ''; // $$tag stands for $em or $strong + } + $tree_char_em = false; + } else if ($token_len == 3) { + if ($em) { + // Reached closing marker for both em and strong. + // Closing strong marker: + for ($i = 0; $i < 2; ++$i) { + $shifted_token = array_shift($token_stack); + $tag = strlen($shifted_token) == 2 ? "strong" : "em"; + $span = array_shift($text_stack); + $span = $this->runSpanGamut($span); + $span = "<$tag>$span"; + $text_stack[0] .= $this->hashPart($span); + $$tag = ''; // $$tag stands for $em or $strong + } + } else { + // Reached opening three-char emphasis marker. Push on token + // stack; will be handled by the special condition above. + $em = $token{0}; + $strong = "$em$em"; + array_unshift($token_stack, $token); + array_unshift($text_stack, ''); + $tree_char_em = true; + } + } else if ($token_len == 2) { + if ($strong) { + // Unwind any dangling emphasis marker: + if (strlen($token_stack[0]) == 1) { + $text_stack[1] .= array_shift($token_stack); + $text_stack[0] .= array_shift($text_stack); + $em = ''; + } + // Closing strong marker: + array_shift($token_stack); + $span = array_shift($text_stack); + $span = $this->runSpanGamut($span); + $span = "$span"; + $text_stack[0] .= $this->hashPart($span); + $strong = ''; + } else { + array_unshift($token_stack, $token); + array_unshift($text_stack, ''); + $strong = $token; + } + } else { + // Here $token_len == 1 + if ($em) { + if (strlen($token_stack[0]) == 1) { + // Closing emphasis marker: + array_shift($token_stack); + $span = array_shift($text_stack); + $span = $this->runSpanGamut($span); + $span = "$span"; + $text_stack[0] .= $this->hashPart($span); + $em = ''; + } else { + $text_stack[0] .= $token; + } + } else { + array_unshift($token_stack, $token); + array_unshift($text_stack, ''); + $em = $token; + } + } + } + $this->in_emphasis_processing = false; + return $text_stack[0]; + } + + /** + * Parse Markdown blockquotes to HTML + * @param string $text + * @return string + */ + protected function doBlockQuotes($text) { + $text = preg_replace_callback('/ + ( # Wrap whole match in $1 + (?> + ^[ ]*>[ ]? # ">" at the start of a line + .+\n # rest of the first line + (.+\n)* # subsequent consecutive lines + \n* # blanks + )+ + ) + /xm', + array($this, '_doBlockQuotes_callback'), $text); + + return $text; + } + + /** + * Blockquote parsing callback + * @param array $matches + * @return string + */ + protected function _doBlockQuotes_callback($matches) { + $bq = $matches[1]; + // trim one level of quoting - trim whitespace-only lines + $bq = preg_replace('/^[ ]*>[ ]?|^[ ]+$/m', '', $bq); + $bq = $this->runBlockGamut($bq); // recurse + + $bq = preg_replace('/^/m', " ", $bq); + // These leading spaces cause problem with
       content,
      +		// so we need to fix that:
      +		$bq = preg_replace_callback('{(\s*
      .+?
      )}sx', + array($this, '_doBlockQuotes_callback2'), $bq); + + return "\n" . $this->hashBlock("
      \n$bq\n
      ") . "\n\n"; + } + + /** + * Blockquote parsing callback + * @param array $matches + * @return string + */ + protected function _doBlockQuotes_callback2($matches) { + $pre = $matches[1]; + $pre = preg_replace('/^ /m', '', $pre); + return $pre; + } + + /** + * Parse paragraphs + * + * @param string $text String to process in paragraphs + * @param boolean $wrap_in_p Whether paragraphs should be wrapped in

      tags + * @return string + */ + protected function formParagraphs($text, $wrap_in_p = true) { + // Strip leading and trailing lines: + $text = preg_replace('/\A\n+|\n+\z/', '', $text); + + $grafs = preg_split('/\n{2,}/', $text, -1, PREG_SPLIT_NO_EMPTY); + + // Wrap

      tags and unhashify HTML blocks + foreach ($grafs as $key => $value) { + if (!preg_match('/^B\x1A[0-9]+B$/', $value)) { + // Is a paragraph. + $value = $this->runSpanGamut($value); + if ($wrap_in_p) { + $value = preg_replace('/^([ ]*)/', "

      ", $value); + $value .= "

      "; + } + $grafs[$key] = $this->unhash($value); + } else { + // Is a block. + // Modify elements of @grafs in-place... + $graf = $value; + $block = $this->html_hashes[$graf]; + $graf = $block; +// if (preg_match('{ +// \A +// ( # $1 =
      tag +//
      ]* +// \b +// markdown\s*=\s* ([\'"]) # $2 = attr quote char +// 1 +// \2 +// [^>]* +// > +// ) +// ( # $3 = contents +// .* +// ) +// (
      ) # $4 = closing tag +// \z +// }xs', $block, $matches)) +// { +// list(, $div_open, , $div_content, $div_close) = $matches; +// +// // We can't call Markdown(), because that resets the hash; +// // that initialization code should be pulled into its own sub, though. +// $div_content = $this->hashHTMLBlocks($div_content); +// +// // Run document gamut methods on the content. +// foreach ($this->document_gamut as $method => $priority) { +// $div_content = $this->$method($div_content); +// } +// +// $div_open = preg_replace( +// '{\smarkdown\s*=\s*([\'"]).+?\1}', '', $div_open); +// +// $graf = $div_open . "\n" . $div_content . "\n" . $div_close; +// } + $grafs[$key] = $graf; + } + } + + return implode("\n\n", $grafs); + } + + /** + * Encode text for a double-quoted HTML attribute. This function + * is *not* suitable for attributes enclosed in single quotes. + * @param string $text + * @return string + */ + protected function encodeAttribute($text) { + $text = $this->encodeAmpsAndAngles($text); + $text = str_replace('"', '"', $text); + return $text; + } + + /** + * Encode text for a double-quoted HTML attribute containing a URL, + * applying the URL filter if set. Also generates the textual + * representation for the URL (removing mailto: or tel:) storing it in $text. + * This function is *not* suitable for attributes enclosed in single quotes. + * + * @param string $url + * @param string &$text Passed by reference + * @return string URL + */ + protected function encodeURLAttribute($url, &$text = null) { + if ($this->url_filter_func) { + $url = call_user_func($this->url_filter_func, $url); + } + + if (preg_match('{^mailto:}i', $url)) { + $url = $this->encodeEntityObfuscatedAttribute($url, $text, 7); + } else if (preg_match('{^tel:}i', $url)) { + $url = $this->encodeAttribute($url); + $text = substr($url, 4); + } else { + $url = $this->encodeAttribute($url); + $text = $url; + } + + return $url; + } + + /** + * Smart processing for ampersands and angle brackets that need to + * be encoded. Valid character entities are left alone unless the + * no-entities mode is set. + * @param string $text + * @return string + */ + protected function encodeAmpsAndAngles($text) { + if ($this->no_entities) { + $text = str_replace('&', '&', $text); + } else { + // Ampersand-encoding based entirely on Nat Irons's Amputator + // MT plugin: + $text = preg_replace('/&(?!#?[xX]?(?:[0-9a-fA-F]+|\w+);)/', + '&', $text); + } + // Encode remaining <'s + $text = str_replace('<', '<', $text); + + return $text; + } + + /** + * Parse Markdown automatic links to anchor HTML tags + * @param string $text + * @return string + */ + protected function doAutoLinks($text) { + $text = preg_replace_callback('{<((https?|ftp|dict|tel):[^\'">\s]+)>}i', + array($this, '_doAutoLinks_url_callback'), $text); + + // Email addresses: + $text = preg_replace_callback('{ + < + (?:mailto:)? + ( + (?: + [-!#$%&\'*+/=?^_`.{|}~\w\x80-\xFF]+ + | + ".*?" + ) + \@ + (?: + [-a-z0-9\x80-\xFF]+(\.[-a-z0-9\x80-\xFF]+)*\.[a-z]+ + | + \[[\d.a-fA-F:]+\] # IPv4 & IPv6 + ) + ) + > + }xi', + array($this, '_doAutoLinks_email_callback'), $text); + + return $text; + } + + /** + * Parse URL callback + * @param array $matches + * @return string + */ + protected function _doAutoLinks_url_callback($matches) { + $url = $this->encodeURLAttribute($matches[1], $text); + $link = "$text"; + return $this->hashPart($link); + } + + /** + * Parse email address callback + * @param array $matches + * @return string + */ + protected function _doAutoLinks_email_callback($matches) { + $addr = $matches[1]; + $url = $this->encodeURLAttribute("mailto:$addr", $text); + $link = "$text"; + return $this->hashPart($link); + } + + /** + * Input: some text to obfuscate, e.g. "mailto:foo@example.com" + * + * Output: the same text but with most characters encoded as either a + * decimal or hex entity, in the hopes of foiling most address + * harvesting spam bots. E.g.: + * + * mailto:foo + * @example.co + * m + * + * Note: the additional output $tail is assigned the same value as the + * ouput, minus the number of characters specified by $head_length. + * + * Based by a filter by Matthew Wickline, posted to BBEdit-Talk. + * With some optimizations by Milian Wolff. Forced encoding of HTML + * attribute special characters by Allan Odgaard. + * + * @param string $text + * @param string &$tail + * @param integer $head_length + * @return string + */ + protected function encodeEntityObfuscatedAttribute($text, &$tail = null, $head_length = 0) { + if ($text == "") { + return $tail = ""; + } + + $chars = preg_split('/(? $char) { + $ord = ord($char); + // Ignore non-ascii chars. + if ($ord < 128) { + $r = ($seed * (1 + $key)) % 100; // Pseudo-random function. + // roughly 10% raw, 45% hex, 45% dec + // '@' *must* be encoded. I insist. + // '"' and '>' have to be encoded inside the attribute + if ($r > 90 && strpos('@"&>', $char) === false) { + /* do nothing */ + } else if ($r < 45) { + $chars[$key] = '&#x'.dechex($ord).';'; + } else { + $chars[$key] = '&#'.$ord.';'; + } + } + } + + $text = implode('', $chars); + $tail = $head_length ? implode('', array_slice($chars, $head_length)) : $text; + + return $text; + } + + /** + * Take the string $str and parse it into tokens, hashing embeded HTML, + * escaped characters and handling code spans. + * @param string $str + * @return string + */ + protected function parseSpan($str) { + $output = ''; + + $span_re = '{ + ( + \\\\'.$this->escape_chars_re.' + | + (?no_markup ? '' : ' + | + # comment + | + <\?.*?\?> | <%.*?%> # processing instruction + | + <[!$]?[-a-zA-Z0-9:_]+ # regular tags + (?> + \s + (?>[^"\'>]+|"[^"]*"|\'[^\']*\')* + )? + > + | + <[-a-zA-Z0-9:_]+\s*/> # xml-style empty tag + | + # closing tag + ').' + ) + }xs'; + + while (1) { + // Each loop iteration seach for either the next tag, the next + // openning code span marker, or the next escaped character. + // Each token is then passed to handleSpanToken. + $parts = preg_split($span_re, $str, 2, PREG_SPLIT_DELIM_CAPTURE); + + // Create token from text preceding tag. + if ($parts[0] != "") { + $output .= $parts[0]; + } + + // Check if we reach the end. + if (isset($parts[1])) { + $output .= $this->handleSpanToken($parts[1], $parts[2]); + $str = $parts[2]; + } else { + break; + } + } + + return $output; + } + + /** + * Handle $token provided by parseSpan by determining its nature and + * returning the corresponding value that should replace it. + * @param string $token + * @param string &$str + * @return string + */ + protected function handleSpanToken($token, &$str) { + switch ($token{0}) { + case "\\": + return $this->hashPart("&#". ord($token{1}). ";"); + case "`": + // Search for end marker in remaining text. + if (preg_match('/^(.*?[^`])'.preg_quote($token).'(?!`)(.*)$/sm', + $str, $matches)) + { + $str = $matches[2]; + $codespan = $this->makeCodeSpan($matches[1]); + return $this->hashPart($codespan); + } + return $token; // Return as text since no ending marker found. + default: + return $this->hashPart($token); + } + } + + /** + * Remove one level of line-leading tabs or spaces + * @param string $text + * @return string + */ + protected function outdent($text) { + return preg_replace('/^(\t|[ ]{1,' . $this->tab_width . '})/m', '', $text); + } + + + /** + * String length function for detab. `_initDetab` will create a function to + * handle UTF-8 if the default function does not exist. + * @var string + */ + protected $utf8_strlen = 'mb_strlen'; + + /** + * Replace tabs with the appropriate amount of spaces. + * + * For each line we separate the line in blocks delemited by tab characters. + * Then we reconstruct every line by adding the appropriate number of space + * between each blocks. + * + * @param string $text + * @return string + */ + protected function detab($text) { + $text = preg_replace_callback('/^.*\t.*$/m', + array($this, '_detab_callback'), $text); + + return $text; + } + + /** + * Replace tabs callback + * @param string $matches + * @return string + */ + protected function _detab_callback($matches) { + $line = $matches[0]; + $strlen = $this->utf8_strlen; // strlen function for UTF-8. + + // Split in blocks. + $blocks = explode("\t", $line); + // Add each blocks to the line. + $line = $blocks[0]; + unset($blocks[0]); // Do not add first block twice. + foreach ($blocks as $block) { + // Calculate amount of space, insert spaces, insert block. + $amount = $this->tab_width - + $strlen($line, 'UTF-8') % $this->tab_width; + $line .= str_repeat(" ", $amount) . $block; + } + return $line; + } + + /** + * Check for the availability of the function in the `utf8_strlen` property + * (initially `mb_strlen`). If the function is not available, create a + * function that will loosely count the number of UTF-8 characters with a + * regular expression. + * @return void + */ + protected function _initDetab() { + + if (function_exists($this->utf8_strlen)) { + return; + } + + $this->utf8_strlen = function($text) { + return preg_match_all('/[\x00-\xBF]|[\xC0-\xFF][\x80-\xBF]*/', $text, $m); + }; + } + + /** + * Swap back in all the tags hashed by _HashHTMLBlocks. + * @param string $text + * @return string + */ + protected function unhash($text) { + return preg_replace_callback('/(.)\x1A[0-9]+\1/', + array($this, '_unhash_callback'), $text); + } + + /** + * Unhashing callback + * @param array $matches + * @return string + */ + protected function _unhash_callback($matches) { + return $this->html_hashes[$matches[0]]; + } +} diff --git a/Sites/pages/components/com_pages/resources/vendor/markdown/MarkdownExtra.inc.php b/Sites/pages/components/com_pages/resources/vendor/markdown/MarkdownExtra.inc.php new file mode 100644 index 00000000..d09bd7a4 --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/markdown/MarkdownExtra.inc.php @@ -0,0 +1,11 @@ + + * @copyright 2004-2018 Michel Fortin + * @copyright (Original Markdown) 2004-2006 John Gruber + */ + +namespace Michelf; + +/** + * Markdown Extra Parser Class + */ +class MarkdownExtra extends \Michelf\Markdown { + /** + * Configuration variables + */ + + /** + * Prefix for footnote ids. + * @var string + */ + public $fn_id_prefix = ""; + + /** + * Optional title attribute for footnote links and backlinks. + * @var string + */ + public $fn_link_title = ""; + public $fn_backlink_title = ""; + + /** + * Optional class attribute for footnote links and backlinks. + * @var string + */ + public $fn_link_class = "footnote-ref"; + public $fn_backlink_class = "footnote-backref"; + + /** + * Content to be displayed within footnote backlinks. The default is '↩'; + * the U+FE0E on the end is a Unicode variant selector used to prevent iOS + * from displaying the arrow character as an emoji. + * @var string + */ + public $fn_backlink_html = '↩︎'; + + /** + * Class name for table cell alignment (%% replaced left/center/right) + * For instance: 'go-%%' becomes 'go-left' or 'go-right' or 'go-center' + * If empty, the align attribute is used instead of a class name. + * @var string + */ + public $table_align_class_tmpl = ''; + + /** + * Optional class prefix for fenced code block. + * @var string + */ + public $code_class_prefix = ""; + + /** + * Class attribute for code blocks goes on the `code` tag; + * setting this to true will put attributes on the `pre` tag instead. + * @var boolean + */ + public $code_attr_on_pre = false; + + /** + * Predefined abbreviations. + * @var array + */ + public $predef_abbr = array(); + + /** + * Only convert atx-style headers if there's a space between the header and # + * @var boolean + */ + public $hashtag_protection = false; + + /** + * Parser implementation + */ + + /** + * Constructor function. Initialize the parser object. + * @return void + */ + public function __construct() { + // Add extra escapable characters before parent constructor + // initialize the table. + $this->escape_chars .= ':|'; + + // Insert extra document, block, and span transformations. + // Parent constructor will do the sorting. + $this->document_gamut += array( + "doFencedCodeBlocks" => 5, + "stripFootnotes" => 15, + "stripAbbreviations" => 25, + "appendFootnotes" => 50, + ); + $this->block_gamut += array( + "doFencedCodeBlocks" => 5, + "doTables" => 15, + "doDefLists" => 45, + ); + $this->span_gamut += array( + "doFootnotes" => 5, + "doAbbreviations" => 70, + ); + + $this->enhanced_ordered_list = true; + parent::__construct(); + } + + + /** + * Extra variables used during extra transformations. + * @var array + */ + protected $footnotes = array(); + protected $footnotes_ordered = array(); + protected $footnotes_ref_count = array(); + protected $footnotes_numbers = array(); + protected $abbr_desciptions = array(); + /** @var string */ + protected $abbr_word_re = ''; + + /** + * Give the current footnote number. + * @var integer + */ + protected $footnote_counter = 1; + + /** + * Setting up Extra-specific variables. + */ + protected function setup() { + parent::setup(); + + $this->footnotes = array(); + $this->footnotes_ordered = array(); + $this->footnotes_ref_count = array(); + $this->footnotes_numbers = array(); + $this->abbr_desciptions = array(); + $this->abbr_word_re = ''; + $this->footnote_counter = 1; + + foreach ($this->predef_abbr as $abbr_word => $abbr_desc) { + if ($this->abbr_word_re) + $this->abbr_word_re .= '|'; + $this->abbr_word_re .= preg_quote($abbr_word); + $this->abbr_desciptions[$abbr_word] = trim($abbr_desc); + } + } + + /** + * Clearing Extra-specific variables. + */ + protected function teardown() { + $this->footnotes = array(); + $this->footnotes_ordered = array(); + $this->footnotes_ref_count = array(); + $this->footnotes_numbers = array(); + $this->abbr_desciptions = array(); + $this->abbr_word_re = ''; + + parent::teardown(); + } + + + /** + * Extra attribute parser + */ + + /** + * Expression to use to catch attributes (includes the braces) + * @var string + */ + protected $id_class_attr_catch_re = '\{((?>[ ]*[#.a-z][-_:a-zA-Z0-9=]+){1,})[ ]*\}'; + + /** + * Expression to use when parsing in a context when no capture is desired + * @var string + */ + protected $id_class_attr_nocatch_re = '\{(?>[ ]*[#.a-z][-_:a-zA-Z0-9=]+){1,}[ ]*\}'; + + /** + * Parse attributes caught by the $this->id_class_attr_catch_re expression + * and return the HTML-formatted list of attributes. + * + * Currently supported attributes are .class and #id. + * + * In addition, this method also supports supplying a default Id value, + * which will be used to populate the id attribute in case it was not + * overridden. + * @param string $tag_name + * @param string $attr + * @param mixed $defaultIdValue + * @param array $classes + * @return string + */ + protected function doExtraAttributes($tag_name, $attr, $defaultIdValue = null, $classes = array()) { + if (empty($attr) && !$defaultIdValue && empty($classes)) return ""; + + // Split on components + preg_match_all('/[#.a-z][-_:a-zA-Z0-9=]+/', $attr, $matches); + $elements = $matches[0]; + + // Handle classes and IDs (only first ID taken into account) + $attributes = array(); + $id = false; + foreach ($elements as $element) { + if ($element{0} == '.') { + $classes[] = substr($element, 1); + } else if ($element{0} == '#') { + if ($id === false) $id = substr($element, 1); + } else if (strpos($element, '=') > 0) { + $parts = explode('=', $element, 2); + $attributes[] = $parts[0] . '="' . $parts[1] . '"'; + } + } + + if (!$id) $id = $defaultIdValue; + + // Compose attributes as string + $attr_str = ""; + if (!empty($id)) { + $attr_str .= ' id="'.$this->encodeAttribute($id) .'"'; + } + if (!empty($classes)) { + $attr_str .= ' class="'. implode(" ", $classes) . '"'; + } + if (!$this->no_markup && !empty($attributes)) { + $attr_str .= ' '.implode(" ", $attributes); + } + return $attr_str; + } + + /** + * Strips link definitions from text, stores the URLs and titles in + * hash references. + * @param string $text + * @return string + */ + protected function stripLinkDefinitions($text) { + $less_than_tab = $this->tab_width - 1; + + // Link defs are in the form: ^[id]: url "optional title" + $text = preg_replace_callback('{ + ^[ ]{0,'.$less_than_tab.'}\[(.+)\][ ]?: # id = $1 + [ ]* + \n? # maybe *one* newline + [ ]* + (?: + <(.+?)> # url = $2 + | + (\S+?) # url = $3 + ) + [ ]* + \n? # maybe one newline + [ ]* + (?: + (?<=\s) # lookbehind for whitespace + ["(] + (.*?) # title = $4 + [")] + [ ]* + )? # title is optional + (?:[ ]* '.$this->id_class_attr_catch_re.' )? # $5 = extra id & class attr + (?:\n+|\Z) + }xm', + array($this, '_stripLinkDefinitions_callback'), + $text); + return $text; + } + + /** + * Strip link definition callback + * @param array $matches + * @return string + */ + protected function _stripLinkDefinitions_callback($matches) { + $link_id = strtolower($matches[1]); + $url = $matches[2] == '' ? $matches[3] : $matches[2]; + $this->urls[$link_id] = $url; + $this->titles[$link_id] =& $matches[4]; + $this->ref_attr[$link_id] = $this->doExtraAttributes("", $dummy =& $matches[5]); + return ''; // String that will replace the block + } + + + /** + * HTML block parser + */ + + /** + * Tags that are always treated as block tags + * @var string + */ + protected $block_tags_re = 'p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|address|form|fieldset|iframe|hr|legend|article|section|nav|aside|hgroup|header|footer|figcaption|figure'; + + /** + * Tags treated as block tags only if the opening tag is alone on its line + * @var string + */ + protected $context_block_tags_re = 'script|noscript|style|ins|del|iframe|object|source|track|param|math|svg|canvas|audio|video'; + + /** + * Tags where markdown="1" default to span mode: + * @var string + */ + protected $contain_span_tags_re = 'p|h[1-6]|li|dd|dt|td|th|legend|address'; + + /** + * Tags which must not have their contents modified, no matter where + * they appear + * @var string + */ + protected $clean_tags_re = 'script|style|math|svg'; + + /** + * Tags that do not need to be closed. + * @var string + */ + protected $auto_close_tags_re = 'hr|img|param|source|track'; + + /** + * Hashify HTML Blocks and "clean tags". + * + * We only want to do this for block-level HTML tags, such as headers, + * lists, and tables. That's because we still want to wrap

      s around + * "paragraphs" that are wrapped in non-block-level tags, such as anchors, + * phrase emphasis, and spans. The list of tags we're looking for is + * hard-coded. + * + * This works by calling _HashHTMLBlocks_InMarkdown, which then calls + * _HashHTMLBlocks_InHTML when it encounter block tags. When the markdown="1" + * attribute is found within a tag, _HashHTMLBlocks_InHTML calls back + * _HashHTMLBlocks_InMarkdown to handle the Markdown syntax within the tag. + * These two functions are calling each other. It's recursive! + * @param string $text + * @return string + */ + protected function hashHTMLBlocks($text) { + if ($this->no_markup) { + return $text; + } + + // Call the HTML-in-Markdown hasher. + list($text, ) = $this->_hashHTMLBlocks_inMarkdown($text); + + return $text; + } + + /** + * Parse markdown text, calling _HashHTMLBlocks_InHTML for block tags. + * + * * $indent is the number of space to be ignored when checking for code + * blocks. This is important because if we don't take the indent into + * account, something like this (which looks right) won't work as expected: + * + *

      + *
      + * Hello World. <-- Is this a Markdown code block or text? + *
      <-- Is this a Markdown code block or a real tag? + *
      + * + * If you don't like this, just don't indent the tag on which + * you apply the markdown="1" attribute. + * + * * If $enclosing_tag_re is not empty, stops at the first unmatched closing + * tag with that name. Nested tags supported. + * + * * If $span is true, text inside must treated as span. So any double + * newline will be replaced by a single newline so that it does not create + * paragraphs. + * + * Returns an array of that form: ( processed text , remaining text ) + * + * @param string $text + * @param integer $indent + * @param string $enclosing_tag_re + * @param boolean $span + * @return array + */ + protected function _hashHTMLBlocks_inMarkdown($text, $indent = 0, + $enclosing_tag_re = '', $span = false) + { + + if ($text === '') return array('', ''); + + // Regex to check for the presense of newlines around a block tag. + $newline_before_re = '/(?:^\n?|\n\n)*$/'; + $newline_after_re = + '{ + ^ # Start of text following the tag. + (?>[ ]*)? # Optional comment. + [ ]*\n # Must be followed by newline. + }xs'; + + // Regex to match any tag. + $block_tag_re = + '{ + ( # $2: Capture whole tag. + # Tag name. + ' . $this->block_tags_re . ' | + ' . $this->context_block_tags_re . ' | + ' . $this->clean_tags_re . ' | + (?!\s)'.$enclosing_tag_re . ' + ) + (?: + (?=[\s"\'/a-zA-Z0-9]) # Allowed characters after tag name. + (?> + ".*?" | # Double quotes (can contain `>`) + \'.*?\' | # Single quotes (can contain `>`) + .+? # Anything but quotes and `>`. + )*? + )? + > # End of tag. + | + # HTML Comment + | + <\?.*?\?> | <%.*?%> # Processing instruction + | + # CData Block + ' . ( !$span ? ' # If not in span. + | + # Indented code block + (?: ^[ ]*\n | ^ | \n[ ]*\n ) + [ ]{' . ($indent + 4) . '}[^\n]* \n + (?> + (?: [ ]{' . ($indent + 4) . '}[^\n]* | [ ]* ) \n + )* + | + # Fenced code block marker + (?<= ^ | \n ) + [ ]{0,' . ($indent + 3) . '}(?:~{3,}|`{3,}) + [ ]* + (?: \.?[-_:a-zA-Z0-9]+ )? # standalone class name + [ ]* + (?: ' . $this->id_class_attr_nocatch_re . ' )? # extra attributes + [ ]* + (?= \n ) + ' : '' ) . ' # End (if not is span). + | + # Code span marker + # Note, this regex needs to go after backtick fenced + # code blocks but it should also be kept outside of the + # "if not in span" condition adding backticks to the parser + `+ + ) + }xs'; + + + $depth = 0; // Current depth inside the tag tree. + $parsed = ""; // Parsed text that will be returned. + + // Loop through every tag until we find the closing tag of the parent + // or loop until reaching the end of text if no parent tag specified. + do { + // Split the text using the first $tag_match pattern found. + // Text before pattern will be first in the array, text after + // pattern will be at the end, and between will be any catches made + // by the pattern. + $parts = preg_split($block_tag_re, $text, 2, + PREG_SPLIT_DELIM_CAPTURE); + + // If in Markdown span mode, add a empty-string span-level hash + // after each newline to prevent triggering any block element. + if ($span) { + $void = $this->hashPart("", ':'); + $newline = "\n$void"; + $parts[0] = $void . str_replace("\n", $newline, $parts[0]) . $void; + } + + $parsed .= $parts[0]; // Text before current tag. + + // If end of $text has been reached. Stop loop. + if (count($parts) < 3) { + $text = ""; + break; + } + + $tag = $parts[1]; // Tag to handle. + $text = $parts[2]; // Remaining text after current tag. + $tag_re = preg_quote($tag); // For use in a regular expression. + + // Check for: Fenced code block marker. + // Note: need to recheck the whole tag to disambiguate backtick + // fences from code spans + if (preg_match('{^\n?([ ]{0,' . ($indent + 3) . '})(~{3,}|`{3,})[ ]*(?:\.?[-_:a-zA-Z0-9]+)?[ ]*(?:' . $this->id_class_attr_nocatch_re . ')?[ ]*\n?$}', $tag, $capture)) { + // Fenced code block marker: find matching end marker. + $fence_indent = strlen($capture[1]); // use captured indent in re + $fence_re = $capture[2]; // use captured fence in re + if (preg_match('{^(?>.*\n)*?[ ]{' . ($fence_indent) . '}' . $fence_re . '[ ]*(?:\n|$)}', $text, + $matches)) + { + // End marker found: pass text unchanged until marker. + $parsed .= $tag . $matches[0]; + $text = substr($text, strlen($matches[0])); + } + else { + // No end marker: just skip it. + $parsed .= $tag; + } + } + // Check for: Indented code block. + else if ($tag{0} == "\n" || $tag{0} == " ") { + // Indented code block: pass it unchanged, will be handled + // later. + $parsed .= $tag; + } + // Check for: Code span marker + // Note: need to check this after backtick fenced code blocks + else if ($tag{0} == "`") { + // Find corresponding end marker. + $tag_re = preg_quote($tag); + if (preg_match('{^(?>.+?|\n(?!\n))*?(?block_tags_re . ')\b}', $tag) || + ( preg_match('{^<(?:' . $this->context_block_tags_re . ')\b}', $tag) && + preg_match($newline_before_re, $parsed) && + preg_match($newline_after_re, $text) ) + ) + { + // Need to parse tag and following text using the HTML parser. + list($block_text, $text) = + $this->_hashHTMLBlocks_inHTML($tag . $text, "hashBlock", true); + + // Make sure it stays outside of any paragraph by adding newlines. + $parsed .= "\n\n$block_text\n\n"; + } + // Check for: Clean tag (like script, math) + // HTML Comments, processing instructions. + else if (preg_match('{^<(?:' . $this->clean_tags_re . ')\b}', $tag) || + $tag{1} == '!' || $tag{1} == '?') + { + // Need to parse tag and following text using the HTML parser. + // (don't check for markdown attribute) + list($block_text, $text) = + $this->_hashHTMLBlocks_inHTML($tag . $text, "hashClean", false); + + $parsed .= $block_text; + } + // Check for: Tag with same name as enclosing tag. + else if ($enclosing_tag_re !== '' && + // Same name as enclosing tag. + preg_match('{^= 0); + + return array($parsed, $text); + } + + /** + * Parse HTML, calling _HashHTMLBlocks_InMarkdown for block tags. + * + * * Calls $hash_method to convert any blocks. + * * Stops when the first opening tag closes. + * * $md_attr indicate if the use of the `markdown="1"` attribute is allowed. + * (it is not inside clean tags) + * + * Returns an array of that form: ( processed text , remaining text ) + * @param string $text + * @param string $hash_method + * @param string $md_attr + * @return array + */ + protected function _hashHTMLBlocks_inHTML($text, $hash_method, $md_attr) { + if ($text === '') return array('', ''); + + // Regex to match `markdown` attribute inside of a tag. + $markdown_attr_re = ' + { + \s* # Eat whitespace before the `markdown` attribute + markdown + \s*=\s* + (?> + (["\']) # $1: quote delimiter + (.*?) # $2: attribute value + \1 # matching delimiter + | + ([^\s>]*) # $3: unquoted attribute value + ) + () # $4: make $3 always defined (avoid warnings) + }xs'; + + // Regex to match any tag. + $tag_re = '{ + ( # $2: Capture whole tag. + + ".*?" | # Double quotes (can contain `>`) + \'.*?\' | # Single quotes (can contain `>`) + .+? # Anything but quotes and `>`. + )*? + )? + > # End of tag. + | + # HTML Comment + | + <\?.*?\?> | <%.*?%> # Processing instruction + | + # CData Block + ) + }xs'; + + $original_text = $text; // Save original text in case of faliure. + + $depth = 0; // Current depth inside the tag tree. + $block_text = ""; // Temporary text holder for current text. + $parsed = ""; // Parsed text that will be returned. + + // Get the name of the starting tag. + // (This pattern makes $base_tag_name_re safe without quoting.) + if (preg_match('/^<([\w:$]*)\b/', $text, $matches)) + $base_tag_name_re = $matches[1]; + + // Loop through every tag until we find the corresponding closing tag. + do { + // Split the text using the first $tag_match pattern found. + // Text before pattern will be first in the array, text after + // pattern will be at the end, and between will be any catches made + // by the pattern. + $parts = preg_split($tag_re, $text, 2, PREG_SPLIT_DELIM_CAPTURE); + + if (count($parts) < 3) { + // End of $text reached with unbalenced tag(s). + // In that case, we return original text unchanged and pass the + // first character as filtered to prevent an infinite loop in the + // parent function. + return array($original_text{0}, substr($original_text, 1)); + } + + $block_text .= $parts[0]; // Text before current tag. + $tag = $parts[1]; // Tag to handle. + $text = $parts[2]; // Remaining text after current tag. + + // Check for: Auto-close tag (like
      ) + // Comments and Processing Instructions. + if (preg_match('{^auto_close_tags_re . ')\b}', $tag) || + $tag{1} == '!' || $tag{1} == '?') + { + // Just add the tag to the block as if it was text. + $block_text .= $tag; + } + else { + // Increase/decrease nested tag count. Only do so if + // the tag's name match base tag's. + if (preg_match('{^mode = $attr_m[2] . $attr_m[3]; + $span_mode = $this->mode == 'span' || $this->mode != 'block' && + preg_match('{^<(?:' . $this->contain_span_tags_re . ')\b}', $tag); + + // Calculate indent before tag. + if (preg_match('/(?:^|\n)( *?)(?! ).*?$/', $block_text, $matches)) { + $strlen = $this->utf8_strlen; + $indent = $strlen($matches[1], 'UTF-8'); + } else { + $indent = 0; + } + + // End preceding block with this tag. + $block_text .= $tag; + $parsed .= $this->$hash_method($block_text); + + // Get enclosing tag name for the ParseMarkdown function. + // (This pattern makes $tag_name_re safe without quoting.) + preg_match('/^<([\w:$]*)\b/', $tag, $matches); + $tag_name_re = $matches[1]; + + // Parse the content using the HTML-in-Markdown parser. + list ($block_text, $text) + = $this->_hashHTMLBlocks_inMarkdown($text, $indent, + $tag_name_re, $span_mode); + + // Outdent markdown text. + if ($indent > 0) { + $block_text = preg_replace("/^[ ]{1,$indent}/m", "", + $block_text); + } + + // Append tag content to parsed text. + if (!$span_mode) $parsed .= "\n\n$block_text\n\n"; + else $parsed .= "$block_text"; + + // Start over with a new block. + $block_text = ""; + } + else $block_text .= $tag; + } + + } while ($depth > 0); + + // Hash last block text that wasn't processed inside the loop. + $parsed .= $this->$hash_method($block_text); + + return array($parsed, $text); + } + + /** + * Called whenever a tag must be hashed when a function inserts a "clean" tag + * in $text, it passes through this function and is automaticaly escaped, + * blocking invalid nested overlap. + * @param string $text + * @return string + */ + protected function hashClean($text) { + return $this->hashPart($text, 'C'); + } + + /** + * Turn Markdown link shortcuts into XHTML tags. + * @param string $text + * @return string + */ + protected function doAnchors($text) { + if ($this->in_anchor) { + return $text; + } + $this->in_anchor = true; + + // First, handle reference-style links: [link text] [id] + $text = preg_replace_callback('{ + ( # wrap whole match in $1 + \[ + (' . $this->nested_brackets_re . ') # link text = $2 + \] + + [ ]? # one optional space + (?:\n[ ]*)? # one optional newline followed by spaces + + \[ + (.*?) # id = $3 + \] + ) + }xs', + array($this, '_doAnchors_reference_callback'), $text); + + // Next, inline-style links: [link text](url "optional title") + $text = preg_replace_callback('{ + ( # wrap whole match in $1 + \[ + (' . $this->nested_brackets_re . ') # link text = $2 + \] + \( # literal paren + [ \n]* + (?: + <(.+?)> # href = $3 + | + (' . $this->nested_url_parenthesis_re . ') # href = $4 + ) + [ \n]* + ( # $5 + ([\'"]) # quote char = $6 + (.*?) # Title = $7 + \6 # matching quote + [ \n]* # ignore any spaces/tabs between closing quote and ) + )? # title is optional + \) + (?:[ ]? ' . $this->id_class_attr_catch_re . ' )? # $8 = id/class attributes + ) + }xs', + array($this, '_doAnchors_inline_callback'), $text); + + // Last, handle reference-style shortcuts: [link text] + // These must come last in case you've also got [link text][1] + // or [link text](/foo) + $text = preg_replace_callback('{ + ( # wrap whole match in $1 + \[ + ([^\[\]]+) # link text = $2; can\'t contain [ or ] + \] + ) + }xs', + array($this, '_doAnchors_reference_callback'), $text); + + $this->in_anchor = false; + return $text; + } + + /** + * Callback for reference anchors + * @param array $matches + * @return string + */ + protected function _doAnchors_reference_callback($matches) { + $whole_match = $matches[1]; + $link_text = $matches[2]; + $link_id =& $matches[3]; + + if ($link_id == "") { + // for shortcut links like [this][] or [this]. + $link_id = $link_text; + } + + // lower-case and turn embedded newlines into spaces + $link_id = strtolower($link_id); + $link_id = preg_replace('{[ ]?\n}', ' ', $link_id); + + if (isset($this->urls[$link_id])) { + $url = $this->urls[$link_id]; + $url = $this->encodeURLAttribute($url); + + $result = "titles[$link_id] ) ) { + $title = $this->titles[$link_id]; + $title = $this->encodeAttribute($title); + $result .= " title=\"$title\""; + } + if (isset($this->ref_attr[$link_id])) + $result .= $this->ref_attr[$link_id]; + + $link_text = $this->runSpanGamut($link_text); + $result .= ">$link_text"; + $result = $this->hashPart($result); + } + else { + $result = $whole_match; + } + return $result; + } + + /** + * Callback for inline anchors + * @param array $matches + * @return string + */ + protected function _doAnchors_inline_callback($matches) { + $whole_match = $matches[1]; + $link_text = $this->runSpanGamut($matches[2]); + $url = $matches[3] == '' ? $matches[4] : $matches[3]; + $title =& $matches[7]; + $attr = $this->doExtraAttributes("a", $dummy =& $matches[8]); + + // if the URL was of the form it got caught by the HTML + // tag parser and hashed. Need to reverse the process before using the URL. + $unhashed = $this->unhash($url); + if ($unhashed != $url) + $url = preg_replace('/^<(.*)>$/', '\1', $unhashed); + + $url = $this->encodeURLAttribute($url); + + $result = "encodeAttribute($title); + $result .= " title=\"$title\""; + } + $result .= $attr; + + $link_text = $this->runSpanGamut($link_text); + $result .= ">$link_text"; + + return $this->hashPart($result); + } + + /** + * Turn Markdown image shortcuts into tags. + * @param string $text + * @return string + */ + protected function doImages($text) { + // First, handle reference-style labeled images: ![alt text][id] + $text = preg_replace_callback('{ + ( # wrap whole match in $1 + !\[ + (' . $this->nested_brackets_re . ') # alt text = $2 + \] + + [ ]? # one optional space + (?:\n[ ]*)? # one optional newline followed by spaces + + \[ + (.*?) # id = $3 + \] + + ) + }xs', + array($this, '_doImages_reference_callback'), $text); + + // Next, handle inline images: ![alt text](url "optional title") + // Don't forget: encode * and _ + $text = preg_replace_callback('{ + ( # wrap whole match in $1 + !\[ + (' . $this->nested_brackets_re . ') # alt text = $2 + \] + \s? # One optional whitespace character + \( # literal paren + [ \n]* + (?: + <(\S*)> # src url = $3 + | + (' . $this->nested_url_parenthesis_re . ') # src url = $4 + ) + [ \n]* + ( # $5 + ([\'"]) # quote char = $6 + (.*?) # title = $7 + \6 # matching quote + [ \n]* + )? # title is optional + \) + (?:[ ]? ' . $this->id_class_attr_catch_re . ' )? # $8 = id/class attributes + ) + }xs', + array($this, '_doImages_inline_callback'), $text); + + return $text; + } + + /** + * Callback for referenced images + * @param array $matches + * @return string + */ + protected function _doImages_reference_callback($matches) { + $whole_match = $matches[1]; + $alt_text = $matches[2]; + $link_id = strtolower($matches[3]); + + if ($link_id == "") { + $link_id = strtolower($alt_text); // for shortcut links like ![this][]. + } + + $alt_text = $this->encodeAttribute($alt_text); + if (isset($this->urls[$link_id])) { + $url = $this->encodeURLAttribute($this->urls[$link_id]); + $result = "\"$alt_text\"";titles[$link_id])) { + $title = $this->titles[$link_id]; + $title = $this->encodeAttribute($title); + $result .= " title=\"$title\""; + } + if (isset($this->ref_attr[$link_id])) + $result .= $this->ref_attr[$link_id]; + $result .= $this->empty_element_suffix; + $result = $this->hashPart($result); + } + else { + // If there's no such link ID, leave intact: + $result = $whole_match; + } + + return $result; + } + + /** + * Callback for inline images + * @param array $matches + * @return string + */ + protected function _doImages_inline_callback($matches) { + $whole_match = $matches[1]; + $alt_text = $matches[2]; + $url = $matches[3] == '' ? $matches[4] : $matches[3]; + $title =& $matches[7]; + $attr = $this->doExtraAttributes("img", $dummy =& $matches[8]); + + $alt_text = $this->encodeAttribute($alt_text); + $url = $this->encodeURLAttribute($url); + $result = "\"$alt_text\"";encodeAttribute($title); + $result .= " title=\"$title\""; // $title already quoted + } + $result .= $attr; + $result .= $this->empty_element_suffix; + + return $this->hashPart($result); + } + + /** + * Process markdown headers. Redefined to add ID and class attribute support. + * @param string $text + * @return string + */ + protected function doHeaders($text) { + // Setext-style headers: + // Header 1 {#header1} + // ======== + // + // Header 2 {#header2 .class1 .class2} + // -------- + // + $text = preg_replace_callback( + '{ + (^.+?) # $1: Header text + (?:[ ]+ ' . $this->id_class_attr_catch_re . ' )? # $3 = id/class attributes + [ ]*\n(=+|-+)[ ]*\n+ # $3: Header footer + }mx', + array($this, '_doHeaders_callback_setext'), $text); + + // atx-style headers: + // # Header 1 {#header1} + // ## Header 2 {#header2} + // ## Header 2 with closing hashes ## {#header3.class1.class2} + // ... + // ###### Header 6 {.class2} + // + $text = preg_replace_callback('{ + ^(\#{1,6}) # $1 = string of #\'s + [ ]'.($this->hashtag_protection ? '+' : '*').' + (.+?) # $2 = Header text + [ ]* + \#* # optional closing #\'s (not counted) + (?:[ ]+ ' . $this->id_class_attr_catch_re . ' )? # $3 = id/class attributes + [ ]* + \n+ + }xm', + array($this, '_doHeaders_callback_atx'), $text); + + return $text; + } + + /** + * Callback for setext headers + * @param array $matches + * @return string + */ + protected function _doHeaders_callback_setext($matches) { + if ($matches[3] == '-' && preg_match('{^- }', $matches[1])) { + return $matches[0]; + } + + $level = $matches[3]{0} == '=' ? 1 : 2; + + $defaultId = is_callable($this->header_id_func) ? call_user_func($this->header_id_func, $matches[1]) : null; + + $attr = $this->doExtraAttributes("h$level", $dummy =& $matches[2], $defaultId); + $block = "" . $this->runSpanGamut($matches[1]) . ""; + return "\n" . $this->hashBlock($block) . "\n\n"; + } + + /** + * Callback for atx headers + * @param array $matches + * @return string + */ + protected function _doHeaders_callback_atx($matches) { + $level = strlen($matches[1]); + + $defaultId = is_callable($this->header_id_func) ? call_user_func($this->header_id_func, $matches[2]) : null; + $attr = $this->doExtraAttributes("h$level", $dummy =& $matches[3], $defaultId); + $block = "" . $this->runSpanGamut($matches[2]) . ""; + return "\n" . $this->hashBlock($block) . "\n\n"; + } + + /** + * Form HTML tables. + * @param string $text + * @return string + */ + protected function doTables($text) { + $less_than_tab = $this->tab_width - 1; + // Find tables with leading pipe. + // + // | Header 1 | Header 2 + // | -------- | -------- + // | Cell 1 | Cell 2 + // | Cell 3 | Cell 4 + $text = preg_replace_callback(' + { + ^ # Start of a line + [ ]{0,' . $less_than_tab . '} # Allowed whitespace. + [|] # Optional leading pipe (present) + (.+) \n # $1: Header row (at least one pipe) + + [ ]{0,' . $less_than_tab . '} # Allowed whitespace. + [|] ([ ]*[-:]+[-| :]*) \n # $2: Header underline + + ( # $3: Cells + (?> + [ ]* # Allowed whitespace. + [|] .* \n # Row content. + )* + ) + (?=\n|\Z) # Stop at final double newline. + }xm', + array($this, '_doTable_leadingPipe_callback'), $text); + + // Find tables without leading pipe. + // + // Header 1 | Header 2 + // -------- | -------- + // Cell 1 | Cell 2 + // Cell 3 | Cell 4 + $text = preg_replace_callback(' + { + ^ # Start of a line + [ ]{0,' . $less_than_tab . '} # Allowed whitespace. + (\S.*[|].*) \n # $1: Header row (at least one pipe) + + [ ]{0,' . $less_than_tab . '} # Allowed whitespace. + ([-:]+[ ]*[|][-| :]*) \n # $2: Header underline + + ( # $3: Cells + (?> + .* [|] .* \n # Row content + )* + ) + (?=\n|\Z) # Stop at final double newline. + }xm', + array($this, '_DoTable_callback'), $text); + + return $text; + } + + /** + * Callback for removing the leading pipe for each row + * @param array $matches + * @return string + */ + protected function _doTable_leadingPipe_callback($matches) { + $head = $matches[1]; + $underline = $matches[2]; + $content = $matches[3]; + + $content = preg_replace('/^ *[|]/m', '', $content); + + return $this->_doTable_callback(array($matches[0], $head, $underline, $content)); + } + + /** + * Make the align attribute in a table + * @param string $alignname + * @return string + */ + protected function _doTable_makeAlignAttr($alignname) + { + if (empty($this->table_align_class_tmpl)) { + return " align=\"$alignname\""; + } + + $classname = str_replace('%%', $alignname, $this->table_align_class_tmpl); + return " class=\"$classname\""; + } + + /** + * Calback for processing tables + * @param array $matches + * @return string + */ + protected function _doTable_callback($matches) { + $head = $matches[1]; + $underline = $matches[2]; + $content = $matches[3]; + + // Remove any tailing pipes for each line. + $head = preg_replace('/[|] *$/m', '', $head); + $underline = preg_replace('/[|] *$/m', '', $underline); + $content = preg_replace('/[|] *$/m', '', $content); + + // Reading alignement from header underline. + $separators = preg_split('/ *[|] */', $underline); + foreach ($separators as $n => $s) { + if (preg_match('/^ *-+: *$/', $s)) + $attr[$n] = $this->_doTable_makeAlignAttr('right'); + else if (preg_match('/^ *:-+: *$/', $s)) + $attr[$n] = $this->_doTable_makeAlignAttr('center'); + else if (preg_match('/^ *:-+ *$/', $s)) + $attr[$n] = $this->_doTable_makeAlignAttr('left'); + else + $attr[$n] = ''; + } + + // Parsing span elements, including code spans, character escapes, + // and inline HTML tags, so that pipes inside those gets ignored. + $head = $this->parseSpan($head); + $headers = preg_split('/ *[|] */', $head); + $col_count = count($headers); + $attr = array_pad($attr, $col_count, ''); + + // Write column headers. + $text = "\n"; + $text .= "\n"; + $text .= "\n"; + foreach ($headers as $n => $header) + $text .= " " . $this->runSpanGamut(trim($header)) . "\n"; + $text .= "\n"; + $text .= "\n"; + + // Split content by row. + $rows = explode("\n", trim($content, "\n")); + + $text .= "\n"; + foreach ($rows as $row) { + // Parsing span elements, including code spans, character escapes, + // and inline HTML tags, so that pipes inside those gets ignored. + $row = $this->parseSpan($row); + + // Split row by cell. + $row_cells = preg_split('/ *[|] */', $row, $col_count); + $row_cells = array_pad($row_cells, $col_count, ''); + + $text .= "\n"; + foreach ($row_cells as $n => $cell) + $text .= " " . $this->runSpanGamut(trim($cell)) . "\n"; + $text .= "\n"; + } + $text .= "\n"; + $text .= "
      "; + + return $this->hashBlock($text) . "\n"; + } + + /** + * Form HTML definition lists. + * @param string $text + * @return string + */ + protected function doDefLists($text) { + $less_than_tab = $this->tab_width - 1; + + // Re-usable pattern to match any entire dl list: + $whole_list_re = '(?> + ( # $1 = whole list + ( # $2 + [ ]{0,' . $less_than_tab . '} + ((?>.*\S.*\n)+) # $3 = defined term + \n? + [ ]{0,' . $less_than_tab . '}:[ ]+ # colon starting definition + ) + (?s:.+?) + ( # $4 + \z + | + \n{2,} + (?=\S) + (?! # Negative lookahead for another term + [ ]{0,' . $less_than_tab . '} + (?: \S.*\n )+? # defined term + \n? + [ ]{0,' . $less_than_tab . '}:[ ]+ # colon starting definition + ) + (?! # Negative lookahead for another definition + [ ]{0,' . $less_than_tab . '}:[ ]+ # colon starting definition + ) + ) + ) + )'; // mx + + $text = preg_replace_callback('{ + (?>\A\n?|(?<=\n\n)) + ' . $whole_list_re . ' + }mx', + array($this, '_doDefLists_callback'), $text); + + return $text; + } + + /** + * Callback for processing definition lists + * @param array $matches + * @return string + */ + protected function _doDefLists_callback($matches) { + // Re-usable patterns to match list item bullets and number markers: + $list = $matches[1]; + + // Turn double returns into triple returns, so that we can make a + // paragraph for the last item in a list, if necessary: + $result = trim($this->processDefListItems($list)); + $result = "
      \n" . $result . "\n
      "; + return $this->hashBlock($result) . "\n\n"; + } + + /** + * Process the contents of a single definition list, splitting it + * into individual term and definition list items. + * @param string $list_str + * @return string + */ + protected function processDefListItems($list_str) { + + $less_than_tab = $this->tab_width - 1; + + // Trim trailing blank lines: + $list_str = preg_replace("/\n{2,}\\z/", "\n", $list_str); + + // Process definition terms. + $list_str = preg_replace_callback('{ + (?>\A\n?|\n\n+) # leading line + ( # definition terms = $1 + [ ]{0,' . $less_than_tab . '} # leading whitespace + (?!\:[ ]|[ ]) # negative lookahead for a definition + # mark (colon) or more whitespace. + (?> \S.* \n)+? # actual term (not whitespace). + ) + (?=\n?[ ]{0,3}:[ ]) # lookahead for following line feed + # with a definition mark. + }xm', + array($this, '_processDefListItems_callback_dt'), $list_str); + + // Process actual definitions. + $list_str = preg_replace_callback('{ + \n(\n+)? # leading line = $1 + ( # marker space = $2 + [ ]{0,' . $less_than_tab . '} # whitespace before colon + \:[ ]+ # definition mark (colon) + ) + ((?s:.+?)) # definition text = $3 + (?= \n+ # stop at next definition mark, + (?: # next term or end of text + [ ]{0,' . $less_than_tab . '} \:[ ] | +
      | \z + ) + ) + }xm', + array($this, '_processDefListItems_callback_dd'), $list_str); + + return $list_str; + } + + /** + * Callback for
      elements in definition lists + * @param array $matches + * @return string + */ + protected function _processDefListItems_callback_dt($matches) { + $terms = explode("\n", trim($matches[1])); + $text = ''; + foreach ($terms as $term) { + $term = $this->runSpanGamut(trim($term)); + $text .= "\n
      " . $term . "
      "; + } + return $text . "\n"; + } + + /** + * Callback for
      elements in definition lists + * @param array $matches + * @return string + */ + protected function _processDefListItems_callback_dd($matches) { + $leading_line = $matches[1]; + $marker_space = $matches[2]; + $def = $matches[3]; + + if ($leading_line || preg_match('/\n{2,}/', $def)) { + // Replace marker with the appropriate whitespace indentation + $def = str_repeat(' ', strlen($marker_space)) . $def; + $def = $this->runBlockGamut($this->outdent($def . "\n\n")); + $def = "\n". $def ."\n"; + } + else { + $def = rtrim($def); + $def = $this->runSpanGamut($this->outdent($def)); + } + + return "\n
      " . $def . "
      \n"; + } + + /** + * Adding the fenced code block syntax to regular Markdown: + * + * ~~~ + * Code block + * ~~~ + * + * @param string $text + * @return string + */ + protected function doFencedCodeBlocks($text) { + + $less_than_tab = $this->tab_width; + + $text = preg_replace_callback('{ + (?:\n|\A) + # 1: Opening marker + ( + (?:~{3,}|`{3,}) # 3 or more tildes/backticks. + ) + [ ]* + (?: + \.?([-_:a-zA-Z0-9]+) # 2: standalone class name + )? + [ ]* + (?: + ' . $this->id_class_attr_catch_re . ' # 3: Extra attributes + )? + [ ]* \n # Whitespace and newline following marker. + + # 4: Content + ( + (?> + (?!\1 [ ]* \n) # Not a closing marker. + .*\n+ + )+ + ) + + # Closing marker. + \1 [ ]* (?= \n ) + }xm', + array($this, '_doFencedCodeBlocks_callback'), $text); + + return $text; + } + + /** + * Callback to process fenced code blocks + * @param array $matches + * @return string + */ + protected function _doFencedCodeBlocks_callback($matches) { + $classname =& $matches[2]; + $attrs =& $matches[3]; + $codeblock = $matches[4]; + + if ($this->code_block_content_func) { + $codeblock = call_user_func($this->code_block_content_func, $codeblock, $classname); + } else { + $codeblock = htmlspecialchars($codeblock, ENT_NOQUOTES); + } + + $codeblock = preg_replace_callback('/^\n+/', + array($this, '_doFencedCodeBlocks_newlines'), $codeblock); + + $classes = array(); + if ($classname != "") { + if ($classname{0} == '.') + $classname = substr($classname, 1); + $classes[] = $this->code_class_prefix . $classname; + } + $attr_str = $this->doExtraAttributes($this->code_attr_on_pre ? "pre" : "code", $attrs, null, $classes); + $pre_attr_str = $this->code_attr_on_pre ? $attr_str : ''; + $code_attr_str = $this->code_attr_on_pre ? '' : $attr_str; + $codeblock = "$codeblock
      "; + + return "\n\n".$this->hashBlock($codeblock)."\n\n"; + } + + /** + * Replace new lines in fenced code blocks + * @param array $matches + * @return string + */ + protected function _doFencedCodeBlocks_newlines($matches) { + return str_repeat("empty_element_suffix", + strlen($matches[0])); + } + + /** + * Redefining emphasis markers so that emphasis by underscore does not + * work in the middle of a word. + * @var array + */ + protected $em_relist = array( + '' => '(?:(? '(? '(? '(?:(? '(? '(? '(?:(? '(? '(? tags + * @return string HTML output + */ + protected function formParagraphs($text, $wrap_in_p = true) { + // Strip leading and trailing lines: + $text = preg_replace('/\A\n+|\n+\z/', '', $text); + + $grafs = preg_split('/\n{2,}/', $text, -1, PREG_SPLIT_NO_EMPTY); + + // Wrap

      tags and unhashify HTML blocks + foreach ($grafs as $key => $value) { + $value = trim($this->runSpanGamut($value)); + + // Check if this should be enclosed in a paragraph. + // Clean tag hashes & block tag hashes are left alone. + $is_p = $wrap_in_p && !preg_match('/^B\x1A[0-9]+B|^C\x1A[0-9]+C$/', $value); + + if ($is_p) { + $value = "

      $value

      "; + } + $grafs[$key] = $value; + } + + // Join grafs in one text, then unhash HTML tags. + $text = implode("\n\n", $grafs); + + // Finish by removing any tag hashes still present in $text. + $text = $this->unhash($text); + + return $text; + } + + + /** + * Footnotes - Strips link definitions from text, stores the URLs and + * titles in hash references. + * @param string $text + * @return string + */ + protected function stripFootnotes($text) { + $less_than_tab = $this->tab_width - 1; + + // Link defs are in the form: [^id]: url "optional title" + $text = preg_replace_callback('{ + ^[ ]{0,' . $less_than_tab . '}\[\^(.+?)\][ ]?: # note_id = $1 + [ ]* + \n? # maybe *one* newline + ( # text = $2 (no blank lines allowed) + (?: + .+ # actual text + | + \n # newlines but + (?!\[.+?\][ ]?:\s)# negative lookahead for footnote or link definition marker. + (?!\n+[ ]{0,3}\S)# ensure line is not blank and followed + # by non-indented content + )* + ) + }xm', + array($this, '_stripFootnotes_callback'), + $text); + return $text; + } + + /** + * Callback for stripping footnotes + * @param array $matches + * @return string + */ + protected function _stripFootnotes_callback($matches) { + $note_id = $this->fn_id_prefix . $matches[1]; + $this->footnotes[$note_id] = $this->outdent($matches[2]); + return ''; // String that will replace the block + } + + /** + * Replace footnote references in $text [^id] with a special text-token + * which will be replaced by the actual footnote marker in appendFootnotes. + * @param string $text + * @return string + */ + protected function doFootnotes($text) { + if (!$this->in_anchor) { + $text = preg_replace('{\[\^(.+?)\]}', "F\x1Afn:\\1\x1A:", $text); + } + return $text; + } + + /** + * Append footnote list to text + * @param string $text + * @return string + */ + protected function appendFootnotes($text) { + $text = preg_replace_callback('{F\x1Afn:(.*?)\x1A:}', + array($this, '_appendFootnotes_callback'), $text); + + if (!empty($this->footnotes_ordered)) { + $text .= "\n\n"; + $text .= "
      \n"; + $text .= "empty_element_suffix . "\n"; + $text .= "
        \n\n"; + + $attr = ""; + if ($this->fn_backlink_class != "") { + $class = $this->fn_backlink_class; + $class = $this->encodeAttribute($class); + $attr .= " class=\"$class\""; + } + if ($this->fn_backlink_title != "") { + $title = $this->fn_backlink_title; + $title = $this->encodeAttribute($title); + $attr .= " title=\"$title\""; + $attr .= " aria-label=\"$title\""; + } + $attr .= " role=\"doc-backlink\""; + $backlink_text = $this->fn_backlink_html; + $num = 0; + + while (!empty($this->footnotes_ordered)) { + $footnote = reset($this->footnotes_ordered); + $note_id = key($this->footnotes_ordered); + unset($this->footnotes_ordered[$note_id]); + $ref_count = $this->footnotes_ref_count[$note_id]; + unset($this->footnotes_ref_count[$note_id]); + unset($this->footnotes[$note_id]); + + $footnote .= "\n"; // Need to append newline before parsing. + $footnote = $this->runBlockGamut("$footnote\n"); + $footnote = preg_replace_callback('{F\x1Afn:(.*?)\x1A:}', + array($this, '_appendFootnotes_callback'), $footnote); + + $attr = str_replace("%%", ++$num, $attr); + $note_id = $this->encodeAttribute($note_id); + + // Prepare backlink, multiple backlinks if multiple references + $backlink = "$backlink_text"; + for ($ref_num = 2; $ref_num <= $ref_count; ++$ref_num) { + $backlink .= " $backlink_text"; + } + // Add backlink to last paragraph; create new paragraph if needed. + if (preg_match('{

        $}', $footnote)) { + $footnote = substr($footnote, 0, -4) . " $backlink

        "; + } else { + $footnote .= "\n\n

        $backlink

        "; + } + + $text .= "
      1. \n"; + $text .= $footnote . "\n"; + $text .= "
      2. \n\n"; + } + + $text .= "
      \n"; + $text .= "
      "; + } + return $text; + } + + /** + * Callback for appending footnotes + * @param array $matches + * @return string + */ + protected function _appendFootnotes_callback($matches) { + $node_id = $this->fn_id_prefix . $matches[1]; + + // Create footnote marker only if it has a corresponding footnote *and* + // the footnote hasn't been used by another marker. + if (isset($this->footnotes[$node_id])) { + $num =& $this->footnotes_numbers[$node_id]; + if (!isset($num)) { + // Transfer footnote content to the ordered list and give it its + // number + $this->footnotes_ordered[$node_id] = $this->footnotes[$node_id]; + $this->footnotes_ref_count[$node_id] = 1; + $num = $this->footnote_counter++; + $ref_count_mark = ''; + } else { + $ref_count_mark = $this->footnotes_ref_count[$node_id] += 1; + } + + $attr = ""; + if ($this->fn_link_class != "") { + $class = $this->fn_link_class; + $class = $this->encodeAttribute($class); + $attr .= " class=\"$class\""; + } + if ($this->fn_link_title != "") { + $title = $this->fn_link_title; + $title = $this->encodeAttribute($title); + $attr .= " title=\"$title\""; + } + $attr .= " role=\"doc-noteref\""; + + $attr = str_replace("%%", $num, $attr); + $node_id = $this->encodeAttribute($node_id); + + return + "". + "$num". + ""; + } + + return "[^" . $matches[1] . "]"; + } + + + /** + * Abbreviations - strips abbreviations from text, stores titles in hash + * references. + * @param string $text + * @return string + */ + protected function stripAbbreviations($text) { + $less_than_tab = $this->tab_width - 1; + + // Link defs are in the form: [id]*: url "optional title" + $text = preg_replace_callback('{ + ^[ ]{0,' . $less_than_tab . '}\*\[(.+?)\][ ]?: # abbr_id = $1 + (.*) # text = $2 (no blank lines allowed) + }xm', + array($this, '_stripAbbreviations_callback'), + $text); + return $text; + } + + /** + * Callback for stripping abbreviations + * @param array $matches + * @return string + */ + protected function _stripAbbreviations_callback($matches) { + $abbr_word = $matches[1]; + $abbr_desc = $matches[2]; + if ($this->abbr_word_re) { + $this->abbr_word_re .= '|'; + } + $this->abbr_word_re .= preg_quote($abbr_word); + $this->abbr_desciptions[$abbr_word] = trim($abbr_desc); + return ''; // String that will replace the block + } + + /** + * Find defined abbreviations in text and wrap them in elements. + * @param string $text + * @return string + */ + protected function doAbbreviations($text) { + if ($this->abbr_word_re) { + // cannot use the /x modifier because abbr_word_re may + // contain significant spaces: + $text = preg_replace_callback('{' . + '(?abbr_word_re . ')' . + '(?![\w\x1A])' . + '}', + array($this, '_doAbbreviations_callback'), $text); + } + return $text; + } + + /** + * Callback for processing abbreviations + * @param array $matches + * @return string + */ + protected function _doAbbreviations_callback($matches) { + $abbr = $matches[0]; + if (isset($this->abbr_desciptions[$abbr])) { + $desc = $this->abbr_desciptions[$abbr]; + if (empty($desc)) { + return $this->hashPart("$abbr"); + } else { + $desc = $this->encodeAttribute($desc); + return $this->hashPart("$abbr"); + } + } else { + return $matches[0]; + } + } +} diff --git a/Sites/pages/components/com_pages/resources/vendor/markdown/MarkdownInterface.inc.php b/Sites/pages/components/com_pages/resources/vendor/markdown/MarkdownInterface.inc.php new file mode 100644 index 00000000..c4e9ac7f --- /dev/null +++ b/Sites/pages/components/com_pages/resources/vendor/markdown/MarkdownInterface.inc.php @@ -0,0 +1,9 @@ + + * @copyright 2004-2018 Michel Fortin + * @copyright (Original Markdown) 2004-2006 John Gruber + */ + +namespace Michelf; + +/** + * Markdown Parser Interface + */ +interface MarkdownInterface { + /** + * Initialize the parser and return the result of its transform method. + * This will work fine for derived classes too. + * + * @api + * + * @param string $text + * @return string + */ + public static function defaultTransform($text); + + /** + * Main function. Performs some preprocessing on the input text + * and pass it through the document gamut. + * + * @api + * + * @param string $text + * @return string + */ + public function transform($text); +} diff --git a/Sites/pages/components/com_pages/template/default.php b/Sites/pages/components/com_pages/template/default.php new file mode 100644 index 00000000..d3626c95 --- /dev/null +++ b/Sites/pages/components/com_pages/template/default.php @@ -0,0 +1,349 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesTemplateDefault extends KTemplate +{ + protected $_layout; + protected $_type; + + private $__helpers = array(); + + public function __construct(KObjectConfig $config) + { + parent::__construct($config); + + //Intercept template exception + $this->getObject('exception.handler')->addExceptionCallback(array($this, 'handleException'), true); + + //Re-register the helper() template function + $this->registerFunction('helper', [$this, 'invokeHelper']); + } + + protected function _initialize(KObjectConfig $config) + { + $config->append([ + 'filters' => ['partial'], + 'functions' => [ + 'date' => [$this, '_formatDate'], + 'data' => [$this, '_fetchData'], + 'slug' => [$this, '_createSlug'], + 'attributes' => [$this, '_createAttributes'], + 'config' => [$this, '_getConfig'], + 'unbox' => [$this, '_unboxObject'] + ], + 'cache' => false, + 'cache_namespace' => 'pages', + 'excluded_types' => ['html', 'txt', 'svg', 'css', 'js'], + ]); + + parent::_initialize($config); + } + + public function loadFile($url) + { + //Qualify the layout + if(!parse_url($url, PHP_URL_SCHEME)) { + $url = 'page://layouts/'.$url; + } + + if(parse_url($url, PHP_URL_SCHEME) == 'page') + { + //Locate the template + if(!$file = $this->getObject('template.locator.factory')->locate($url)) { + throw new RuntimeException(sprintf('Cannot find layout: "%s"', $url)); + } + + //Load the template + $template = (new ComPagesObjectConfigFrontmatter())->fromFile($file); + + //Set the parent layout + if($template->has('layout')) + { + if(is_string($template->layout)) { + $layout = ['path' => $template->layout]; + } else { + $layout = $template->layout; + } + + $this->_layout = new ComPagesObjectConfig($layout); + } + else $this->_layout = false; + + //Store the data and remove the layout + $this->_data = KObjectConfig::unbox($template->remove('layout')); + + //Store the type + $this->_type = pathinfo($file, PATHINFO_EXTENSION); + + if(!in_array($this->_type, $this->_excluded_types)) + { + //Create the template engine + $config = array( + 'template' => $this, + 'functions' => $this->_functions + ); + + $this->_source = $this->getObject('template.engine.factory')->createEngine($this->_type, $config); + + if($cache = $this->_source->isCached(crc32($url))) + { + if($this->_source->getConfig()->cache_reload && filemtime($cache) < filemtime($file)) { + unlink($cache); + } + } + + $this->_source->loadString($template->getContent(), $url); + } + else $this->_source = $template->getContent(); + } + else $result = parent::loadFile($url); + + return $this; + } + + public function getLayout() + { + return $this->_layout; + } + + public function render(array $data = array()) + { + unset($data['layout']); + + //$display_errors = ini_get('display_errors'); + //ini_set('display_errors', false); + + $result = parent::render($data); + + //Exception for html files + if($this->_type == 'html') { + $result = $this->filter(); + } + + //ini_set('display_errors', $display_errors); + + return $result; + } + + public function invokeHelper($identifier, ...$params) + { + //Get the function and helper based on the identifier + if(strpos($identifier, '.') === false) { + $identifier = $identifier.'.__invoke'; + } + + //Get the function and helper based on the identifier + $parts = explode('.', $identifier); + $function = array_pop($parts); + $identifier = array_pop($parts); + + //Handle schema:package.helper.function identifiers + if(!empty($parts)) { + $identifier = implode('.', $parts).'.template.helper.'.$identifier; + } + + $helper = $this->createHelper($identifier); + + //Call the helper function + if (!is_callable(array($helper, $function))) { + throw new BadMethodCallException(get_class($helper) . '::' . $function . ' not supported.'); + } + + //Merge the parameters if helper asks for it + if ($helper instanceof KTemplateHelperParameterizable) { + $params = array_merge($this->getParameters()->toArray(), $params); + } + + if(is_numeric(key($params))) { + $result = $helper->$function(...$params); + } else { + $result = $helper->$function($params); + } + + return $result; + } + + public function createHelper($helper, $config = array()) + { + if(!isset($this->__helpers[$helper])) { + $this->__helpers[$helper] = parent::createHelper($helper, $config); + } + + return $this->__helpers[$helper]; + } + + public function registerFunction($name, $function) + { + if (!is_callable($function)) + { + if(file_exists($function)) { + $function = include $function; + } + } + + return parent::registerFunction($name, $function); + } + + public function handleException(Exception &$exception) + { + if($exception instanceof KTemplateExceptionError) + { + $file = file($exception->getFile()); + $buffer = file($exception->getPrevious()->getFile()); + + //Estimate the location of the error in the source file + $line = count($file) - count($buffer) + $exception->getLine() - 1; + + //Try to find the specific line in the source file + foreach($file as $l => $text) + { + if($text == $buffer[$exception->getPrevious()->getLine()]) { + $line = $l; + break; + } + } + + $exception = new KTemplateExceptionError( + $exception->getMessage(), + $exception->getCode(), + $exception->getSeverity(), + $exception->getFile(), + $line, + $exception->getPrevious() + ); + } + } + + protected function _formatDate($date, $format = '') + { + if(!$date instanceof KDate) + { + if(empty($format)) { + $format = $this->getObject('translator')->translate('DATE_FORMAT_LC3'); + } + + $result = $this->createHelper('date')->format(array('date' => $date, 'format' => $format)); + } + else $result = $date->format($format); + + return $result; + } + + protected function _createSlug($string) + { + return $this->getObject('filter.factory')->createFilter('slug')->sanitize($string); + } + + protected function _createAttributes($name, $value = null) + { + $result = ''; + + if(!is_array($name) && $value) { + $name = array($name => $value); + } + + if($name instanceof KObjectConfig) { + $name = KObjectConfig::unbox($name); + } + + if(is_array($name)) + { + $output = array(); + foreach($name as $key => $item) + { + if(is_array($item)) + { + foreach($item as $k => $v) + { + if(empty($v)) { + unset($item[$k]); + } + } + + $item = implode(' ', $item); + } + + if (is_bool($item)) + { + if ($item === false) continue; + $item = $key; + } + + $output[] = $key.'="'.str_replace('"', '"', $item).'"'; + } + + $result = ' '.implode(' ', $output); + } + + return $result; + } + + protected function _fetchData($path, $cache = true) + { + $result = false; + if(is_array($path)) + { + if(is_numeric(key($path))) + { + foreach($path as $directory) + { + if (!$result instanceof ComPagesDataObject) { + $result = $this->getObject('data.registry')->fromPath($directory); + } else { + $result->append($this->getObject('data.registry')->fromPath($directory)); + } + } + } + else + { + $class = $this->getObject('manager')->getClass('com://site/pages.data.object'); + $result = new $class($path); + } + + } + else + { + $namespace = parse_url($path, PHP_URL_SCHEME); + + if(!in_array($namespace, ['http', 'https'])) { + $result = $this->getObject('data.registry')->fromPath($path); + } else { + $result = $this->getObject('data.registry')->fromUrl($path, $cache); + } + } + + return $result; + } + + protected function _getConfig($identifier = 'com://site/pages.config') + { + if (is_string($identifier) && strpos($identifier, ':') === false) { + $identifier = 'com://site/pages.'.$identifier; + } + + return clone $this->getObject($identifier)->getConfig(); + } + + protected function _unboxObject($object) + { + if(is_object($object)) + { + if(method_exists($object, 'toArray')) { + $properties = $object->toArray(); + } elseif($object instanceof Traversable) { + $properties = iterator_to_array($object); + } else { + $properties = get_object_vars($object); + } + } + else $properties = $object; + + return $properties; + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/template/filter/abstract.php b/Sites/pages/components/com_pages/template/filter/abstract.php new file mode 100644 index 00000000..4336eba2 --- /dev/null +++ b/Sites/pages/components/com_pages/template/filter/abstract.php @@ -0,0 +1,13 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +abstract class ComPagesTemplateFilterAbstract extends KTemplateFilterAbstract +{ + +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/template/filter/asset.php b/Sites/pages/components/com_pages/template/filter/asset.php new file mode 100644 index 00000000..0341633d --- /dev/null +++ b/Sites/pages/components/com_pages/template/filter/asset.php @@ -0,0 +1,27 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesTemplateFilterAsset extends ComKoowaTemplateFilterAsset +{ + protected function _initialize(KObjectConfig $config) + { + $site_path = $this->getObject('com://site/pages.config')->getSitePath(); + $root_path = Koowa::getInstance()->getRootPath(); + + $config->append(array( + 'priority' => self::PRIORITY_LOW, + 'schemes' => array( + 'theme://' => 'site://theme/', + 'site://' => 'base://'.trim(str_replace($root_path, '', $site_path), '/').'/', + ), + )); + + parent::_initialize($config); + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/template/filter/form.php b/Sites/pages/components/com_pages/template/filter/form.php new file mode 100644 index 00000000..d16ddb8e --- /dev/null +++ b/Sites/pages/components/com_pages/template/filter/form.php @@ -0,0 +1,26 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesTemplateFilterForm extends KTemplateFilterForm +{ + public function filter(&$text) + { + if($this->getTemplate()->page()->isForm()) { + parent::filter($text); + } + + return $this; + } + + protected function _addAction(&$text) + { + //Action can be empty in HTML5 forms + return $this; + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/template/filter/highlight.php b/Sites/pages/components/com_pages/template/filter/highlight.php new file mode 100644 index 00000000..36e60c27 --- /dev/null +++ b/Sites/pages/components/com_pages/template/filter/highlight.php @@ -0,0 +1,88 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesTemplateFilterHighlight extends ComPagesTemplateFilterAbstract +{ + protected $_highlighter; + + public function __construct(KObjectConfig $config) + { + parent::__construct($config); + + //Set the markdown compiler + if($config->highlighter) { + $this->setHighlighter($config->highlighter); + } + } + + protected function _initialize(KObjectConfig $config) + { + $config->append(array( + 'debug' => JDEBUG ? true : false, + 'highlighter' => null, + 'default_language' => 'php', + )); + + parent::_initialize($config); + } + + public function filter(&$text) + { + if(preg_match_all('#
      \s*]*)>(.*)<\/code>\s*
      #siU', $text, $matches)) + { + foreach($matches[2] as $key => $code) + { + //Create attributes array + $attributes = array( + 'class' => $this->getConfig()->default_language, + ); + + $attributes = array_merge($attributes, $this->parseAttributes($matches[1][$key])); + + //Ensure entities are not encoded when passing to the highlighter. + $code = htmlspecialchars_decode($code, ENT_HTML5); + + if($result = $this->_highlight(trim($code), $attributes['class'])) + { + $html = ''; + $html .= '
      ';
      +                    $html .=  $result;
      +                    $html .= '
      '; + + $text = str_replace($matches[0][$key], $html, $text); + } + } + } + } + + public function getHighlighter() + { + return $this->_highlighter; + } + + public function setHighlighter(callable $highlighter) + { + $this->_highlighter = $highlighter; + return $this; + } + + protected function _highlight($source, $language = 'php') + { + $result = false; + if(is_callable($this->_highlighter)) + { + try { + $result = call_user_func($this->_highlighter, $source, $language); + } + catch (DomainException $e) {}; + } + + return $result; + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/template/filter/markdown.php b/Sites/pages/components/com_pages/template/filter/markdown.php new file mode 100644 index 00000000..8e7282df --- /dev/null +++ b/Sites/pages/components/com_pages/template/filter/markdown.php @@ -0,0 +1,28 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesTemplateFilterMarkdown extends ComPagesTemplateFilterAbstract +{ + protected function _initialize(KObjectConfig $config) + { + $config->append(array( + 'priority' => self::PRIORITY_HIGH, + )); + + parent::_initialize($config); + } + + public function filter(&$text) + { + $engine = $this->getObject('template.engine.factory') + ->createEngine('markdown', array('template' => $this->getTemplate())); + + $text = $engine->loadString($text)->render(); + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/template/filter/meta.php b/Sites/pages/components/com_pages/template/filter/meta.php new file mode 100644 index 00000000..4eb2813f --- /dev/null +++ b/Sites/pages/components/com_pages/template/filter/meta.php @@ -0,0 +1,103 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesTemplateFilterMeta extends ComPagesTemplateFilterAbstract +{ + public function filter(&$text) + { + static $included; + + //Ensure we are only including the page metadata once and do not include metadata if the page is empty + if(!$included && !empty($text)) + { + $meta = array(); + + foreach($this->_getMetadata() as $name => $content) + { + if($content) + { + $content = is_array($content) ? implode(', ', $content) : $content; + $content = htmlspecialchars($content, ENT_HTML5 | ENT_SUBSTITUTE, 'UTF-8', false); + + if(strpos($name, 'og:') === 0) { + $meta[] = sprintf('', $name, $content); + } else { + $meta[] = sprintf('', $name, $content); + } + } + } + + $meta[] = $this->_getCanonical(); + + $text = implode("", $meta).$text; + + $included = true; + } + } + + protected function _getMetadata() + { + $metadata = array(); + if($page = $this->getTemplate()->page()) + { + if($page->metadata) + { + if($page->isCollection() && $this->getTemplate()->state()->isUnique()) + { + if($metadata = $this->getTemplate()->collection()->metadata) { + $metadata->append($page->metadata); + } else { + $metadata = $page->metadata; + } + } + else $metadata = $page->metadata; + + $metadata = KObjectConfig::unbox($metadata); + + if(isset($metadata['og:type']) && $metadata['og:type']) + { + if (strpos($metadata['og:image'], 'http') === false) + { + $this->getTemplate()->getFilter('asset')->filter($metadata['og:image']); + $metadata['og:image'] = (string)$this->getTemplate()->url($metadata['og:image']); + } + + if (!$metadata['og:url']) { + $metadata['og:url'] = (string)$this->getTemplate()->route($page); + } + + if (strpos($metadata['og:url'], 'http') === false) { + $metadata['og:url'] = (string)$this->getTemplate()->url($metadata['og:url']); + } + } + } + } + + return $metadata; + } + + protected function _getCanonical() + { + $canonical = ''; + if($page = $this->getTemplate()->page()) + { + $canonical = $page->canonical ?: ''; + + if($page->isCollection() && $this->getTemplate()->state()->isUnique()) { + $canonical = $this->getTemplate()->collection()->get('canonical', $canonical); + } + + if($canonical) { + $canonical = sprintf('', $canonical); + } + } + + return $canonical; + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/template/filter/partial.php b/Sites/pages/components/com_pages/template/filter/partial.php new file mode 100644 index 00000000..40b15c25 --- /dev/null +++ b/Sites/pages/components/com_pages/template/filter/partial.php @@ -0,0 +1,32 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesTemplateFilterPartial extends ComPagesTemplateFilterAbstract +{ + public function filter(&$text) + { + $types = $this->getObject('template.engine.factory')->getFileTypes(); + $types = implode('|', $types); + + $matches = array(); + if(preg_match_all('#(.*)<\/ktml:partial>#siU', $text, $matches)) + { + foreach($matches[0] as $key => $match) + { + $engine = $this->getObject('template.engine.factory') + ->createEngine($matches[1][$key], array('template' => $this->getTemplate())); + + $result = $engine->loadString(trim($matches[2][$key]))->render(); + + $text = str_replace($match, $result, $text); + + } + } + } +} diff --git a/Sites/pages/components/com_pages/template/filter/plugins.php b/Sites/pages/components/com_pages/template/filter/plugins.php new file mode 100644 index 00000000..91af5d6a --- /dev/null +++ b/Sites/pages/components/com_pages/template/filter/plugins.php @@ -0,0 +1,54 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesTemplateFilterPlugins extends ComPagesTemplateFilterAbstract +{ + public function filter(&$text) + { + $matches = array(); + if(preg_match_all('#(.*)<\/ktml:plugins>#siU', $text, $matches)) + { + $page = $this->getTemplate()->page(); + + foreach($matches[0] as $key => $match) + { + $content = new stdClass; + $content->text = $matches[1][$key]; + + $params = (object) $page->getProperties(); + + //Trigger onContentBeforeDisplay + $results = array(); + $results[] = $this->getTemplate()->createHelper('event')->trigger(array( + 'name' => 'onContentBeforeDisplay', + 'import_group' => 'content', + 'attributes' => array('com_pages.page', &$content, &$params) + )); + + //Trigger onContentPrepare + $results[] = $this->getTemplate()->createHelper('event')->trigger(array( + 'name' => 'onContentPrepare', + 'import_group' => 'content', + 'attributes' => array('com_pages.page', &$content, &$params) + )); + + //Trigger onContentAfterDisplay + $results[] = $this->getTemplate()->createHelper('event')->trigger(array( + 'name' => 'onContentAfterDisplay', + 'import_group' => 'content', + 'attributes' => array('com_pages.page', &$content, &$params) + )); + + $result = trim(implode("\n", $results)); + + $text = str_replace($match, $result, $text); + } + } + } +} diff --git a/Sites/pages/components/com_pages/template/filter/toc.php b/Sites/pages/components/com_pages/template/filter/toc.php new file mode 100644 index 00000000..b1ef53fa --- /dev/null +++ b/Sites/pages/components/com_pages/template/filter/toc.php @@ -0,0 +1,127 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesTemplateFilterToc extends ComPagesTemplateFilterAbstract +{ + protected function _initialize(KObjectConfig $config) + { + $config->append(array( + 'min_level' => 1, + 'max_level' => 6, + 'anchor' => [ + 'enabled' => true, + 'options' => [ + 'placement' => 'right', + 'visibale' => 'hover', + 'icon' => "", + 'class' => null, + 'truncate' => null, + 'arialabel' => 'Anchor', + ], + 'selector' => 'article h2, article h3, article h4, article h5, article h6', + ], + )); + + parent::_initialize($config); + } + + public function filter(&$text) + { + $toc = ''; + + //Create attributes array + $attributes = array( + 'min' => $this->getConfig()->min_level, + 'max' => $this->getConfig()->max_level, + ); + + /* + * Headings + */ + + $matches = array(); + if(preg_match_all('#]*>(.+?)#is', $text, $headers)) + { + $toc = '
        '; + foreach($headers[1] as $key => $level) + { + $content = $headers[2][$key]; + $id = $this->_generateId($content); + + $result = ''.$content.''; + $text = str_replace($headers[0][$key], $result, $text); + + if($this->getConfig()->anchor->enabled) { + $text .= $this->getTemplate()->helper('behavior.anchor', KObjectConfig::unbox($this->getConfig()->anchor)); + } + } + } + + /* + * Table of content + */ + $matches = array(); + if(preg_match_all('#]*)>#siU', $text, $matches)) + { + foreach($matches[0] as $key => $match) + { + $attributes = array_merge($attributes, $this->parseAttributes($matches[1][$key])); + + $headers = array(); + if(preg_match_all('#]*>(.+?)#is', $text, $headers)) + { + $toc = '
          '; + + foreach($headers[1] as $key => $level) + { + $content = $headers[2][$key]; + $id = $this->_generateId($content); + + $toc .= '
        • '.$content.''; + + if(isset($headers[1][$key + 1])) { + $next = $headers[1][$key + 1]; + } else { + $next = $headers[1][0]; + } + + if($next > $level) { + $toc .= '
            '; + } + + if($next < $level) { + $toc .= str_repeat('
          ', $level - $next); + } + + if($next == $level) { + $toc .= '
        • '; + } + } + + $toc .= '
        '; + } + + //Remove the tags + $text = str_replace($match, $toc, $text); + + } + } + } + + protected function _generateId($text) + { + // Lowercase the string and convert a few characters. + $id = strtr(strtolower($text), array(' ' => '-', '_' => '-', '[' => '-', ']' => '')); + + // Remove invalid id characters. + $id = preg_replace('/[^A-Za-z0-9\-_]/', '', $id); + + return $id; + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/template/helper/abstract.php b/Sites/pages/components/com_pages/template/helper/abstract.php new file mode 100644 index 00000000..d1fe6efe --- /dev/null +++ b/Sites/pages/components/com_pages/template/helper/abstract.php @@ -0,0 +1,13 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +abstract class ComPagesTemplateHelperAbstract extends KTemplateHelperAbstract +{ + +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/template/helper/behavior.php b/Sites/pages/components/com_pages/template/helper/behavior.php new file mode 100644 index 00000000..0fcb757f --- /dev/null +++ b/Sites/pages/components/com_pages/template/helper/behavior.php @@ -0,0 +1,76 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesTemplateHelperBehavior extends ComKoowaTemplateHelperBehavior +{ + public function anchor($config = array()) + { + $config = new ComPagesObjectConfig($config); + $config->append(array( + 'debug' => JFactory::getApplication()->getCfg('debug'), + 'options' => array( + 'placement' => 'right', + 'visibale' => 'hover', + 'icon' => "", + 'class' => null, + 'truncate' => null, + 'arialabel' => 'Anchor', + ), + 'selector' => 'article h2, article h3, article h4, article h5, article h6', + )); + + $html = ''; + if (!static::isLoaded('anchor')) + { + $selector = json_encode($config->selector); + + $html .= ''; + $html .= << +document.addEventListener("DOMContentLoaded", function(event) { + anchors.options = $config->options + anchors.add($selector);if(document.querySelector('.no-anchor')!==null){anchors.remove('.no-anchor');} +}) + +ANCHOR; + + static::setLoaded('anchor'); + } + + return $html; + } + + public function prefetcher($config = array()) + { + $config = new KObjectConfigJson($config); + $config->append(array( + 'debug' => JFactory::getApplication()->getCfg('debug'), + 'selector' => 'a.prefetch', + 'onload' => true, + 'onhover' => true, + )); + + $html = ''; + if (!static::isLoaded('prefetcher')) + { + $html .= ''; + $html .= << +document.addEventListener("DOMContentLoaded", () => { + new Prefetcher($config) +}) + +PREFETCHER; + + static::setLoaded('prefetcher'); + } + + return $html; + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/template/helper/form.php b/Sites/pages/components/com_pages/template/helper/form.php new file mode 100644 index 00000000..fc33d176 --- /dev/null +++ b/Sites/pages/components/com_pages/template/helper/form.php @@ -0,0 +1,33 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesTemplateHelperForm extends ComPagesTemplateHelperAbstract +{ + public function __construct(KObjectConfig $config) + { + parent::__construct($config); + + $this->getTemplate()->helper('snippet.define', 'form.honeypot', + '
        + +
        ' + ); + } + + public function honeypot(string $name) + { + $config = new ComPagesObjectConfig(); + $config->append(array( + 'name' => $name, + 'snippet' => 'form.honeypot', + )); + + return $this->getTemplate()->helper('snippet.expand', $config->snippet, $config->toArray()); + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/template/helper/paginator.php b/Sites/pages/components/com_pages/template/helper/paginator.php new file mode 100644 index 00000000..4416044e --- /dev/null +++ b/Sites/pages/components/com_pages/template/helper/paginator.php @@ -0,0 +1,46 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesTemplateHelperPaginator extends KTemplateHelperPaginator +{ + public function pagination($config = array()) + { + $html = ''; + + //If the limit is hardcoded in the collection dont allow it to be changed. + if($collection = $this->getTemplate()->page()->collection) + { + if($collection->state->limit) { + $config['show_limit'] = false; + } + + $html = parent::pagination($config); + } + + return $html; + } + + protected function _link($page, $title) + { + $query = (array( + 'limit' => $page->limit, + 'offset' => $page->offset, + )); + + $route = $this->getTemplate()->route($this->getTemplate()->page(), $query); + + if ($page->active && !$page->current) { + $html = ''.$this->getObject('translator')->translate($title).''; + } else { + $html = ''.$this->getObject('translator')->translate($title).''; + } + + return $html; + } +} diff --git a/Sites/pages/components/com_pages/template/helper/snippet.php b/Sites/pages/components/com_pages/template/helper/snippet.php new file mode 100644 index 00000000..f8dace87 --- /dev/null +++ b/Sites/pages/components/com_pages/template/helper/snippet.php @@ -0,0 +1,77 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesTemplateHelperSnippet extends ComPagesTemplateHelperAbstract +{ + private $__snippets = array(); + + public function __invoke($name, $snippet) + { + if(is_string($snippet)) { + $result = $this->define($name, $snippet); + } else { + $result = $this->expand($name, $snippet); + } + + return $result; + } + + public function define(string $name, string $snippet, $overwrite = false) + { + $result = false; + + if(!isset($this->__snippets[$name]) || $overwrite) + { + $this->__snippets[$name] = $snippet; + $result = true; + } + + return $result; + } + + public function expand(string $name, array $variables = array()) + { + $result = false; + + if($this->exists($name)) + { + $snippet = $this->__snippets[$name]; + + //Use the php template engine to evaluate + $str = "getObject('template.engine.factory') + ->createEngine('php') + ->loadString($str) + ->render($variables); + + //Find single whitespace before " or before > in html tags and remove it + preg_match_all('#<\s*\w.*?>#', $result, $tags); + + foreach($tags as $tag) { + $result = str_replace($tag, str_replace(array(' >', ' "'), array('>', '"'), $tag), $result); + } + } + else throw new RuntimeException('Snippet: '.$name.' does not exist'); + + return $result; + } + + public function exists(string $name) + { + $result = false; + + if(isset($this->__snippets[$name])) { + $result = true; + } + + return $result; + } +} + diff --git a/Sites/pages/components/com_pages/template/locator/theme.php b/Sites/pages/components/com_pages/template/locator/theme.php new file mode 100644 index 00000000..5396b1b8 --- /dev/null +++ b/Sites/pages/components/com_pages/template/locator/theme.php @@ -0,0 +1,22 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesTemplateLocatorTheme extends KTemplateLocatorFile +{ + protected static $_name = 'theme'; + + protected function _initialize(KObjectConfig $config) + { + $config->append([ + 'base_path' => $this->getObject('com://site/pages.config')->getSitePath('theme') + ]); + + parent::_initialize($config); + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/view/behavior/layoutable.php b/Sites/pages/components/com_pages/view/behavior/layoutable.php new file mode 100644 index 00000000..638ac57a --- /dev/null +++ b/Sites/pages/components/com_pages/view/behavior/layoutable.php @@ -0,0 +1,112 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesViewBehaviorLayoutable extends KViewBehaviorAbstract +{ + protected function _beforeRender(KViewContext $context) + { + if($layout = $context->subject->getLayout()) + { + //Merge the layout + $mergeLayout = function($context, $layout) use(&$mergeLayout) + { + //Qualify the layout path + if(!parse_url($layout, PHP_URL_SCHEME)) { + $layout = 'page://layouts/'.$layout; + } + + //Locate the layout + if(!$file = $this->getObject('template.locator.factory')->locate($layout)) { + throw new RuntimeException(sprintf('Cannot find layout: "%s"', $layout)); + } + + //Load the template + $template = (new ComPagesObjectConfigFrontmatter())->fromFile($file); + + //Set the parent layout + if($layout = $template->get('layout')) + { + if(!is_string($layout)) { + $layout = $layout->path; + } + } + + //Append the template layout data + // + //Do not overwrite existing data, only add it not defined yet + $context->subject->getLayout()->append($template->remove('layout')); + + //Handle recursive layout + if($layout) { + $mergeLayout($context, $layout); + } + }; + + Closure::bind($mergeLayout, $this, get_class()); + $mergeLayout($context, $layout->path); + + //Merge the process (excluding the filters) + if($process = $context->subject->getLayout()->get('process')) + { + $process = clone $process; + + $context->subject->getPage()->process->append($process->remove('filters')); + //$context->subject->getLayout()->remove('process'); + } + } + } + + protected function _afterRender(KViewContext $context) + { + if($layout = $context->subject->getLayout()) + { + //Render the layout + $renderLayout = function($context, $layout) use(&$renderLayout) + { + $template = clone $this->getTemplate(); + + //Load layout + $template->loadFile($layout->path); + + //Add layout filters (only for active layout) + if($filters = $layout->get('process/filters')) { + $template->addFilters((array) KObjectConfig::unbox($filters)); + } + + //Append the template layout data + // + //Do not overwrite existing data, only add it not defined yet + //$context->subject->getLayout()->append($template->getData()); + + //Merge the page layout data + // + //Allow the layout data to be modified during template rendering + $context->data->merge($context->subject->getLayout()); + + //Render the template + $this->setContent($template->render(KObjectConfig::unbox($context->data))); + + //Handle recursive layout + if($layout = $template->getLayout()) { + $renderLayout($context, $layout); + } + }; + + Closure::bind($renderLayout, $this, get_class()); + $renderLayout($context, $layout); + } + + $context->result = $this->getContent(); + } + + public function isSupported() + { + return $this->getMixer() instanceof KViewTemplate; + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/view/collection/metadata.xml b/Sites/pages/components/com_pages/view/collection/metadata.xml new file mode 100644 index 00000000..ec886915 --- /dev/null +++ b/Sites/pages/components/com_pages/view/collection/metadata.xml @@ -0,0 +1,4 @@ + + + \ No newline at end of file diff --git a/Sites/pages/components/com_pages/view/collection/tmpl/newsfeed.rss.php b/Sites/pages/components/com_pages/view/collection/tmpl/newsfeed.rss.php new file mode 100644 index 00000000..32a195e6 --- /dev/null +++ b/Sites/pages/components/com_pages/view/collection/tmpl/newsfeed.rss.php @@ -0,0 +1,58 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +defined('KOOWA') or die; ?> + + + + + <?= page()->title ?> + metadata->get('description')) : ?> + + + + image): ?> + + image->url) ?> + <?= page()->image->alt ? page()->image->alt : page()->title ?> + path) ?> + image->caption) : ?> + + + + + top()->date->format(DateTime::RSS) : '' ?> + + + get('update_period', $update_period) ?> + get('update_frequency', $update_frequency) ?> + + + + <?= escape($item->title); ?> + path) : ?> + path); ?> + path); ?> + + image): ?> + + + summary) ?> + category): ?> + category instanceof ComPagesModelEntityInterface ? $item->category->title : $item->category ?> + + + date->format(DateTime::RSS) ?> + + + + \ No newline at end of file diff --git a/Sites/pages/components/com_pages/view/collection/tmpl/sitemap.xml.php b/Sites/pages/components/com_pages/view/collection/tmpl/sitemap.xml.php new file mode 100644 index 00000000..2bf79b88 --- /dev/null +++ b/Sites/pages/components/com_pages/view/collection/tmpl/sitemap.xml.php @@ -0,0 +1,23 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +defined('KOOWA') or die; ?> + + + + + metadata->has('robots') || !in_array('noindex', (array) KObjectConfig::unbox($page->metadata->robots))): ?> + + + date->format(DateTime::ATOM) ?> + + + + + \ No newline at end of file diff --git a/Sites/pages/components/com_pages/view/csv.php b/Sites/pages/components/com_pages/view/csv.php new file mode 100644 index 00000000..eb6f7ad5 --- /dev/null +++ b/Sites/pages/components/com_pages/view/csv.php @@ -0,0 +1,18 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesViewCsv extends KViewCsv +{ + use ComPagesViewTraitPage, ComPagesViewTraitUrl, ComPagesViewTraitRoute; + + protected function _fetchData(KViewContext $context) + { + $context->parameters = $this->getState()->getValues(); + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/view/decorator/html.php b/Sites/pages/components/com_pages/view/decorator/html.php new file mode 100644 index 00000000..e37873aa --- /dev/null +++ b/Sites/pages/components/com_pages/view/decorator/html.php @@ -0,0 +1,18 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesViewDecoratorHtml extends ComPagesViewHtml +{ + protected function _actionRender(KViewContext $context) + { + $context->layout = 'page://pages/'.$this->getPage()->path; + + return parent::_actionRender($context); + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/view/decorator/metadata.xml b/Sites/pages/components/com_pages/view/decorator/metadata.xml new file mode 100644 index 00000000..ec886915 --- /dev/null +++ b/Sites/pages/components/com_pages/view/decorator/metadata.xml @@ -0,0 +1,4 @@ + + + \ No newline at end of file diff --git a/Sites/pages/components/com_pages/view/html.php b/Sites/pages/components/com_pages/view/html.php new file mode 100644 index 00000000..7dc2c10c --- /dev/null +++ b/Sites/pages/components/com_pages/view/html.php @@ -0,0 +1,66 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesViewHtml extends ComKoowaViewHtml +{ + use ComPagesViewTraitPage, ComPagesViewTraitUrl, ComPagesViewTraitRoute; + + protected function _initialize(KObjectConfig $config) + { + $config->append([ + 'behaviors' => ['layoutable'], + 'auto_fetch' => false, + 'template_filters' => ['asset', 'meta'], + 'template_functions' => [ + 'page' => [$this, 'getPage'], + 'layout' => [$this, 'getLayout'], + 'collection' => [$this, 'getCollection'], + 'state' => [$this, 'getState'], + 'direction' => [$this, 'getDirection'], + 'language' => [$this, 'getLanguage'], + ], + ]); + + parent::_initialize($config); + } + + public function getLayout() + { + return $this->getPage()->get('layout'); + } + + protected function _actionRender(KViewContext $context) + { + $template = clone $this->getTemplate()->setParameters($context->parameters); + + //Add page filters + if($filters = $this->getPage()->get('process/filters')) { + $template->addFilters((array) KObjectConfig::unbox($filters)); + } + + //Load the page + $template->loadFile('page://pages/'.$this->getPage()->path); + + //Render page + $content = $template->render(KObjectConfig::unbox($context->data->append($template->getData()))); + + //Set the rendered page in the view to allow for view decoration + $this->setContent($content); + + //Set the content in the object + $this->getPage()->content = $content; + + return trim($content); + } + + protected function _fetchData(KViewContext $context) + { + $context->parameters = $this->getState()->getValues(); + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/view/json.php b/Sites/pages/components/com_pages/view/json.php new file mode 100644 index 00000000..c1d12db0 --- /dev/null +++ b/Sites/pages/components/com_pages/view/json.php @@ -0,0 +1,330 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesViewJson extends KViewAbstract +{ + use ComPagesViewTraitUrl, ComPagesViewTraitRoute, ComPagesViewTraitPage; + + /** + * JSON API version + * + * @var string + */ + protected $_version; + + /** + * Constructor + * + * @param KObjectConfig $config Configuration options + */ + public function __construct(KObjectConfig $config) + { + parent::__construct($config); + + $this->_version = $config->version; + } + + /** + * Initializes the config for the object + * + * Called from {@link __construct()} as a first step of object instantiation. + * + * @param KObjectConfig $config Configuration options + * @return void + */ + protected function _initialize(KObjectConfig $config) + { + $config->append([ + 'version' => '1.0', + ]); + + parent::_initialize($config); + } + + /** + * Check if we are rendering an entity collection + * + * @return bool + */ + public function isCollection() + { + return (bool) !$this->getModel()->getState()->isUnique(); + } + + /** + * Render and return the views output + * + * If the view 'content' is empty the output will be generated based on the model data, if it set it will + * be returned instead. + * + * @param KViewContext $context A view context object + * @return string A RFC4627-compliant JSON string, which may also be embedded into HTML. + */ + protected function _actionRender(KViewContext $context) + { + //Get the content + $content = $context->content; + + if (is_array($content) || $content instanceof \Traversable) { + $content = new ComPagesObjectConfigJson($content); + } + + $this->setContent($content); + + return $content; + } + /** + * Returns the JSON data + * + * It converts relative URLs in the content to relative before returning the result + * + * @see http://jsonapi.org/format/#document-structure + * + * @param KModelEntityInterface $entity + * @return array + */ + protected function _fetchData(KViewContext $context) + { + $route = $this->getRoute(); + + $document = new \ArrayObject(array( + 'jsonapi' => array('version' => $this->_version), + 'links' => array('self' => (string) $this->getRoute($route)), + 'data' => array() + )); + + if ($this->isCollection()) + { + $context->parameters->total = $this->getModel()->count(); + + foreach ($this->getModel()->fetch() as $entity) { + $document['data'][] = $this->_createResource($entity); + } + + $page = $this->getPage(); + + $document['meta'] = array(); + $document['meta']['total'] = $this->getModel()->count(); + + if($title = $page->title) { + $document['meta']['title'] = $title; + } + + if($description = $page->metadata->get('description')) { + $document['meta']['description'] = $description; + } + + if($page->image && $url = $page->image->url) { + $document['meta']['image'] = (string) $this->getUrl($url); + } + + if($language = $page->language) { + $document['meta']['language'] = $language; + } + + if($this->getModel()->isPaginatable()) + { + $paginator = $this->getModel()->getPaginator(); + + $total = (int) $paginator->total; + $limit = (int) $paginator->limit; + $offset = (int) $paginator->offset; + + $document['meta']['offset'] = $offset; + $document['meta']['limit'] = $limit; + + if ($limit && $total > count($this->getModel()->fetch())) { + $document['links']['first'] = (string) $this->getRoute($route, array('offset' => 0)); + } + + if ($limit && $total-($limit + $offset) > 0) { + $document['links']['next'] = (string) $this->getRoute($route, array('offset' => $limit+$offset)); + } + + if ($limit && $offset && $offset >= $limit) { + $document['links']['prev'] = (string) $this->getRoute($route, array('offset' => max($offset-$limit, 0))); + } + } + } + else $document['data'] = $this->_createResource($entity = $this->getModel()->fetch()->top()); + + $context->content = $document; + } + + /** + * Creates a resource object specified by JSON API + * + * @see http://jsonapi.org/format/#document-resource-objects + * + * @param KModelEntityInterface $entity Document row + * @param array $config Resource configuration. + * @return array The array with data to be encoded to json + */ + protected function _createResource(KModelEntityInterface $entity) + { + //Data + $resource = [ + 'type' => $this->_getEntityType($entity), + 'id' => $this->_getEntityId($entity), + 'attributes' => $this->_getEntityAttributes($entity), + ]; + + //Links + if($links = $this->_getEntityLinks($entity)) { + $resource['links'] = $links; + } + + //Relationships + if ( $relationships = $this->_getEntityRelationships($entity)) { + $resource['relationships'] = $relationships; + } + + return $resource; + } + + /** + * Get the entity id + * + * @param KModelEntityInterface $entity + * @return string + */ + protected function _getEntityId(KModelEntityInterface $entity) + { + $values = array(); + + if($keys = $this->getModel()->getPrimaryKey()) + { + foreach($keys as $key){ + $values[] = $entity->{$key}; + } + + $id = implode('/', $values); + } + else $id = $entity->getProperty($entity->getIdentityKey(), ''); + + return $id; + } + + /** + * Get the entity type + * + * @param KModelEntityInterface $entity + * @return string + */ + protected function _getEntityType(KModelEntityInterface $entity) + { + return $this->getModel()->getType(); + } + + /** + * Get the entity attributes + * + * @param KModelEntityInterface $entity + * @return array + */ + protected function _getEntityAttributes(KModelEntityInterface $entity) + { + $attributes = $entity->toArray(); + + //Recursively serialize the attributes + array_walk_recursive($attributes, function(&$value) + { + if(!$value instanceof KModelEntityInterface) + { + //Qualify the url's + if($value instanceof KHttpUrlInterface) { + $value = $this->getUrl($value); + } + + if(is_object($value)) + { + if(!method_exists($value, '__toString')) { + $value = null; + } else { + $value = (string) $value; + } + } + } + else $value = $this->_getEntityAttributes($value); + }); + + //Remove NULL values + $filter = function($attributes) use (&$filter) + { + foreach($attributes as $k => $v) + { + if(!is_array($v)) + { + if(is_null($v)) { + unset($attributes[$k]); + } + } + else $attributes[$k] = $filter($v); + } + + return $attributes; + }; + + $attributes = $filter($attributes); + + //Remove the identity key from the attributes + $key = $entity->getIdentityKey(); + if(isset($attributes[$key])) { + unset($attributes[$key]); + } + + if(!$this->isCollection() && method_exists($entity, 'getContent')) + { + $attributes['content'] = [ + 'body' => $entity->getContent(), + 'type' => $entity->getContentType(), + ]; + } + + return $attributes; + } + + /** + * Get the entity links + * + * @param KModelEntityInterface $entity + * @return array + */ + protected function _getEntityLinks(KModelEntityInterface $entity) + { + $links = array(); + + if($this->isCollection()) + { + $query = array(); + foreach($this->getModel()->getPrimaryKey() as $key){ + $query[$key] = $entity->{$key}; + } + + if(!empty($query)) + { + $url = $this->getRoute($this->getPage(), $query); + $links = ['self' => (string) $url]; + } + } + + return $links; + } + + /** + * Get the entity relationships + * + * @param KModelEntityInterface $entity + * @return array + */ + protected function _getEntityRelationships(KModelEntityInterface $entity) + { + return array(); + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/view/page/html.php b/Sites/pages/components/com_pages/view/page/html.php new file mode 100644 index 00000000..e5ed07c9 --- /dev/null +++ b/Sites/pages/components/com_pages/view/page/html.php @@ -0,0 +1,13 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesViewPageHtml extends ComPagesViewHtml +{ + +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/view/page/metadata.xml b/Sites/pages/components/com_pages/view/page/metadata.xml new file mode 100644 index 00000000..11684f1d --- /dev/null +++ b/Sites/pages/components/com_pages/view/page/metadata.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Sites/pages/components/com_pages/view/page/tmpl/default.xml b/Sites/pages/components/com_pages/view/page/tmpl/default.xml new file mode 100644 index 00000000..11684f1d --- /dev/null +++ b/Sites/pages/components/com_pages/view/page/tmpl/default.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Sites/pages/components/com_pages/view/rss.php b/Sites/pages/components/com_pages/view/rss.php new file mode 100644 index 00000000..0fd6df43 --- /dev/null +++ b/Sites/pages/components/com_pages/view/rss.php @@ -0,0 +1,23 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesViewRss extends ComPagesViewXml +{ + protected function _initialize(KObjectConfig $config) + { + $config->append(array( + 'data' => array( + 'update_period' => 'daily', + 'update_frequency' => 1 + ) + )); + + parent::_initialize($config); + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/view/trait/collection.php b/Sites/pages/components/com_pages/view/trait/collection.php new file mode 100644 index 00000000..43bcdd77 --- /dev/null +++ b/Sites/pages/components/com_pages/view/trait/collection.php @@ -0,0 +1,32 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +trait ComPagesViewTraitCollection +{ + public function getCollection($model = '', $state = array()) + { + if($model) { + $result = $this->getObject('model.factory')->createModel($model, $state)->fetch(); + } else { + $result = $this->getModel()->fetch(); + } + + return $result; + } + + public function getState() + { + return $this->getModel()->getState(); + } + + public function isCollection() + { + return (bool) !$this->getState()->isUnique(); + } +} diff --git a/Sites/pages/components/com_pages/view/trait/page.php b/Sites/pages/components/com_pages/view/trait/page.php new file mode 100644 index 00000000..56eb1a7c --- /dev/null +++ b/Sites/pages/components/com_pages/view/trait/page.php @@ -0,0 +1,56 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +trait ComPagesViewTraitPage +{ + use ComPagesPageTrait, ComPagesViewTraitCollection; + + public function getTitle() + { + $title = ''; + if($page = $this->getPage()) { + $title = $page->title ?: ''; + } + + if($this->getState()->isUnique()) { + $title = $this->getCollection()->get('title', $title); + } + + return $title; + } + + public function getDirection() + { + $direction = 'auto'; + + if($page = $this->getPage()) { + $direction = $page->direction ?: 'auto'; + } + + if($this->getModel()->getState()->isUnique()) { + $direction = $this->getCollection()->get('direction', $direction); + } + + return $direction; + } + + public function getLanguage() + { + $language = 'en-GB'; + if($page = $this->getPage()) { + $language = $page->language ?: 'en-GB'; + } + + if($this->getModel()->getState()->isUnique()) { + $language = $this->getCollection()->get('language', $language); + } + + return $language; + } +} diff --git a/Sites/pages/components/com_pages/view/trait/route.php b/Sites/pages/components/com_pages/view/trait/route.php new file mode 100644 index 00000000..98582235 --- /dev/null +++ b/Sites/pages/components/com_pages/view/trait/route.php @@ -0,0 +1,41 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +trait ComPagesViewTraitRoute +{ + public function getRoute($route = null, $query = array(), $escape = null) + { + $result = null; + + //Determine if we should escape the route + if($escape === null && $this->getFormat() !== 'json') { + $escape = true; + } + + if($route) + { + //Prepend the route with the package + if(is_string($route) && strpos($route, ':') === false) { + $route = $this->getIdentifier()->getPackage().':'.$route; + } + + //Generate the route + $router = $this->getObject('router'); + + if($route = $router->generate($route, $query)) + { + $route = $router->qualify($route)->setEscape($escape); + $result = $route->toString($this->getFormat() !== 'html' ? KHttpUrl::FULL : KHttpUrl::PATH + KHttpUrl::QUERY + KHttpUrl::FRAGMENT); + } + } + else $result = $this->getObject('dispatcher')->getRoute(); + + return $result; + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/view/trait/url.php b/Sites/pages/components/com_pages/view/trait/url.php new file mode 100644 index 00000000..875892ba --- /dev/null +++ b/Sites/pages/components/com_pages/view/trait/url.php @@ -0,0 +1,36 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +trait ComPagesViewTraitUrl +{ + public function getUrl($url = null, $escape = null) + { + if(!empty($url)) + { + if($url instanceof KHttpUrlInterface) + { + $result = clone $url; + $result->setUrl(parent::getUrl()->toString(KHttpUrl::AUTHORITY)); + } + else + { + $result = clone parent::getUrl();; + $result->setUrl($url); + } + } + else $result = clone parent::getUrl(); + + //Determine if we should escape the url + if($escape === null && $this->getFormat() !== 'json') { + $result->setEscape(true); + } + + return $result; + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_pages/view/xml.php b/Sites/pages/components/com_pages/view/xml.php new file mode 100644 index 00000000..3022cccb --- /dev/null +++ b/Sites/pages/components/com_pages/view/xml.php @@ -0,0 +1,66 @@ + + * @link https://github.com/joomlatools/joomlatools-pages for the canonical source repository + */ + +class ComPagesViewXml extends KViewTemplate +{ + use ComPagesViewTraitPage, ComPagesViewTraitUrl, ComPagesViewTraitRoute; + + protected function _initialize(KObjectConfig $config) + { + $config->append([ + 'behaviors' => ['layoutable'], + 'auto_fetch' => false, + 'template_functions' => [ + 'page' => [$this, 'getPage'], + 'layout' => [$this, 'getLayout'], + 'collection' => [$this, 'getCollection'], + 'state' => [$this, 'getState'], + 'direction' => [$this, 'getDirection'], + 'language' => [$this, 'getLanguage'], + ], + ]); + + parent::_initialize($config); + } + + public function getLayout() + { + return $this->getPage()->get('layout'); + } + + protected function _actionRender(KViewContext $context) + { + $template = clone $this->getTemplate()->setParameters($context->parameters); + + //Add page filters + if($filters = $this->getPage()->get('process/filters')) { + $template->addFilters((array) KObjectConfig::unbox($filters)); + } + + //Load the page + $template->loadFile('page://pages/'.$this->getPage()->path); + + //Render page + $content = ''."\n"; + $content = $template->render(KObjectConfig::unbox($context->data->append($template->getData()))); + + //Set the rendered page in the view to allow for view decoration + $this->setContent($content); + + //Set the content in the object + $this->getPage()->content = $content; + + return trim($content); + } + + protected function _fetchData(KViewContext $context) + { + $context->parameters = $this->getState()->getValues(); + } +} \ No newline at end of file diff --git a/Sites/pages/components/com_privacy/controller.php b/Sites/pages/components/com_privacy/controller.php new file mode 100644 index 00000000..8dd87d91 --- /dev/null +++ b/Sites/pages/components/com_privacy/controller.php @@ -0,0 +1,51 @@ +input->get('view', $this->default_view); + + // Submitting information requests through the frontend is restricted to authenticated users at this time + if ($view === 'request' && JFactory::getUser()->guest) + { + $this->setRedirect( + JRoute::_('index.php?option=com_users&view=login&return=' . base64_encode('index.php?option=com_privacy&view=request'), false) + ); + + return $this; + } + + // Set a Referrer-Policy header for views which require it + if (in_array($view, array('confirm', 'remind'))) + { + JFactory::getApplication()->setHeader('Referrer-Policy', 'no-referrer', true); + } + + return parent::display($cachable, $urlparams); + } +} diff --git a/Sites/pages/components/com_privacy/controllers/request.php b/Sites/pages/components/com_privacy/controllers/request.php new file mode 100644 index 00000000..81a15143 --- /dev/null +++ b/Sites/pages/components/com_privacy/controllers/request.php @@ -0,0 +1,180 @@ +checkToken('post'); + + /** @var PrivacyModelConfirm $model */ + $model = $this->getModel('Confirm', 'PrivacyModel'); + $data = $this->input->post->get('jform', array(), 'array'); + + $return = $model->confirmRequest($data); + + // Check for a hard error. + if ($return instanceof Exception) + { + // Get the error message to display. + if (JFactory::getApplication()->get('error_reporting')) + { + $message = $return->getMessage(); + } + else + { + $message = JText::_('COM_PRIVACY_ERROR_CONFIRMING_REQUEST'); + } + + // Go back to the confirm form. + $this->setRedirect(JRoute::_('index.php?option=com_privacy&view=confirm', false), $message, 'error'); + + return false; + } + elseif ($return === false) + { + // Confirm failed. + // Go back to the confirm form. + $message = JText::sprintf('COM_PRIVACY_ERROR_CONFIRMING_REQUEST_FAILED', $model->getError()); + $this->setRedirect(JRoute::_('index.php?option=com_privacy&view=confirm', false), $message, 'notice'); + + return false; + } + else + { + // Confirm succeeded. + $this->setRedirect(JRoute::_(JUri::root()), JText::_('COM_PRIVACY_CONFIRM_REQUEST_SUCCEEDED'), 'info'); + + return true; + } + } + + /** + * Method to submit an information request. + * + * @return boolean + * + * @since 3.9.0 + */ + public function submit() + { + // Check the request token. + $this->checkToken('post'); + + /** @var PrivacyModelRequest $model */ + $model = $this->getModel('Request', 'PrivacyModel'); + $data = $this->input->post->get('jform', array(), 'array'); + + $return = $model->createRequest($data); + + // Check for a hard error. + if ($return instanceof Exception) + { + // Get the error message to display. + if (JFactory::getApplication()->get('error_reporting')) + { + $message = $return->getMessage(); + } + else + { + $message = JText::_('COM_PRIVACY_ERROR_CREATING_REQUEST'); + } + + // Go back to the confirm form. + $this->setRedirect(JRoute::_('index.php?option=com_privacy&view=request', false), $message, 'error'); + + return false; + } + elseif ($return === false) + { + // Confirm failed. + // Go back to the confirm form. + $message = JText::sprintf('COM_PRIVACY_ERROR_CREATING_REQUEST_FAILED', $model->getError()); + $this->setRedirect(JRoute::_('index.php?option=com_privacy&view=request', false), $message, 'notice'); + + return false; + } + else + { + // Confirm succeeded. + $this->setRedirect(JRoute::_(JUri::root()), JText::_('COM_PRIVACY_CREATE_REQUEST_SUCCEEDED'), 'info'); + + return true; + } + } + + /** + * Method to extend the privacy consent. + * + * @return boolean + * + * @since 3.9.0 + */ + public function remind() + { + // Check the request token. + $this->checkToken('post'); + + /** @var PrivacyModelConfirm $model */ + $model = $this->getModel('Remind', 'PrivacyModel'); + $data = $this->input->post->get('jform', array(), 'array'); + + $return = $model->remindRequest($data); + + // Check for a hard error. + if ($return instanceof Exception) + { + // Get the error message to display. + if (JFactory::getApplication()->get('error_reporting')) + { + $message = $return->getMessage(); + } + else + { + $message = JText::_('COM_PRIVACY_ERROR_REMIND_REQUEST'); + } + + // Go back to the confirm form. + $this->setRedirect(JRoute::_('index.php?option=com_privacy&view=remind', false), $message, 'error'); + + return false; + } + elseif ($return === false) + { + // Confirm failed. + // Go back to the confirm form. + $message = JText::sprintf('COM_PRIVACY_ERROR_CONFIRMING_REMIND_FAILED', $model->getError()); + $this->setRedirect(JRoute::_('index.php?option=com_privacy&view=remind', false), $message, 'notice'); + + return false; + } + else + { + // Confirm succeeded. + $this->setRedirect(JRoute::_(JUri::root()), JText::_('COM_PRIVACY_CONFIRM_REMIND_SUCCEEDED'), 'info'); + + return true; + } + } +} diff --git a/Sites/pages/components/com_privacy/models/confirm.php b/Sites/pages/components/com_privacy/models/confirm.php new file mode 100644 index 00000000..cf14da1c --- /dev/null +++ b/Sites/pages/components/com_privacy/models/confirm.php @@ -0,0 +1,222 @@ +getForm(); + $data['email'] = JStringPunycode::emailToPunycode($data['email']); + + // Check for an error. + if ($form instanceof Exception) + { + return $form; + } + + // Filter and validate the form data. + $data = $form->filter($data); + $return = $form->validate($data); + + // Check for an error. + if ($return instanceof Exception) + { + return $return; + } + + // Check the validation results. + if ($return === false) + { + // Get the validation messages from the form. + foreach ($form->getErrors() as $formError) + { + $this->setError($formError->getMessage()); + } + + return false; + } + + // Search for the information request + /** @var PrivacyTableRequest $table */ + $table = $this->getTable(); + + if (!$table->load(array('email' => $data['email'], 'status' => 0))) + { + $this->setError(JText::_('COM_PRIVACY_ERROR_NO_PENDING_REQUESTS')); + + return false; + } + + // A request can only be confirmed if it is in a pending status and has a confirmation token + if ($table->status != '0' || !$table->confirm_token) + { + $this->setError(JText::_('COM_PRIVACY_ERROR_NO_PENDING_REQUESTS')); + + return false; + } + + // A request can only be confirmed if the token is less than 24 hours old + $confirmTokenCreatedAt = new JDate($table->confirm_token_created_at); + $confirmTokenCreatedAt->add(new DateInterval('P1D')); + + $now = new JDate('now'); + + if ($now > $confirmTokenCreatedAt) + { + // Invalidate the request + $table->status = -1; + $table->confirm_token = ''; + + try + { + $table->store(); + } + catch (JDatabaseException $exception) + { + // The error will be logged in the database API, we just need to catch it here to not let things fatal out + } + + $this->setError(JText::_('COM_PRIVACY_ERROR_CONFIRM_TOKEN_EXPIRED')); + + return false; + } + + // Verify the token + if (!JUserHelper::verifyPassword($data['confirm_token'], $table->confirm_token)) + { + $this->setError(JText::_('COM_PRIVACY_ERROR_NO_PENDING_REQUESTS')); + + return false; + } + + // Everything is good to go, transition the request to confirmed + $saved = $this->save( + array( + 'id' => $table->id, + 'status' => 1, + 'confirm_token' => '', + ) + ); + + if (!$saved) + { + // Error was set by the save method + return false; + } + + // Push a notification to the site's super users, deliberately ignoring if this process fails so the below message goes out + JModelLegacy::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_messages/models', 'MessagesModel'); + JTable::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_messages/tables'); + + /** @var MessagesModelMessage $messageModel */ + $messageModel = JModelLegacy::getInstance('Message', 'MessagesModel'); + + $messageModel->notifySuperUsers( + JText::_('COM_PRIVACY_ADMIN_NOTIFICATION_USER_CONFIRMED_REQUEST_SUBJECT'), + JText::sprintf('COM_PRIVACY_ADMIN_NOTIFICATION_USER_CONFIRMED_REQUEST_MESSAGE', $table->email) + ); + + JModelLegacy::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_actionlogs/models', 'ActionlogsModel'); + + $message = array( + 'action' => 'request-confirmed', + 'subjectemail' => $table->email, + 'id' => $table->id, + 'itemlink' => 'index.php?option=com_privacy&view=request&id=' . $table->id, + ); + + /** @var ActionlogsModelActionlog $model */ + $model = JModelLegacy::getInstance('Actionlog', 'ActionlogsModel'); + $model->addLog(array($message), 'COM_PRIVACY_ACTION_LOG_CONFIRMED_REQUEST', 'com_privacy.request'); + + return true; + } + + /** + * Method for getting the form from the model. + * + * @param array $data Data for the form. + * @param boolean $loadData True if the form is to load its own data (default case), false if not. + * + * @return JForm|boolean A JForm object on success, false on failure + * + * @since 3.9.0 + */ + public function getForm($data = array(), $loadData = true) + { + // Get the form. + $form = $this->loadForm('com_privacy.confirm', 'confirm', array('control' => 'jform')); + + if (empty($form)) + { + return false; + } + + $input = JFactory::getApplication()->input; + + if ($input->getMethod() === 'GET') + { + $form->setValue('confirm_token', '', $input->get->getAlnum('confirm_token')); + } + + return $form; + } + + /** + * Method to get a table object, load it if necessary. + * + * @param string $name The table name. Optional. + * @param string $prefix The class prefix. Optional. + * @param array $options Configuration array for model. Optional. + * + * @return JTable A JTable object + * + * @since 3.9.0 + * @throws \Exception + */ + public function getTable($name = 'Request', $prefix = 'PrivacyTable', $options = array()) + { + return parent::getTable($name, $prefix, $options); + } + + /** + * Method to auto-populate the model state. + * + * Note. Calling getState in this method will result in recursion. + * + * @return void + * + * @since 3.9.0 + */ + protected function populateState() + { + // Get the application object. + $params = JFactory::getApplication()->getParams('com_privacy'); + + // Load the parameters. + $this->setState('params', $params); + } +} diff --git a/Sites/pages/components/com_privacy/models/forms/confirm.xml b/Sites/pages/components/com_privacy/models/forms/confirm.xml new file mode 100644 index 00000000..6113c060 --- /dev/null +++ b/Sites/pages/components/com_privacy/models/forms/confirm.xml @@ -0,0 +1,24 @@ + +
        +
        + + + +
        +
        diff --git a/Sites/pages/components/com_privacy/models/forms/remind.xml b/Sites/pages/components/com_privacy/models/forms/remind.xml new file mode 100644 index 00000000..f9792639 --- /dev/null +++ b/Sites/pages/components/com_privacy/models/forms/remind.xml @@ -0,0 +1,24 @@ + +
        +
        + + + +
        +
        diff --git a/Sites/pages/components/com_privacy/models/forms/request.xml b/Sites/pages/components/com_privacy/models/forms/request.xml new file mode 100644 index 00000000..195e7c79 --- /dev/null +++ b/Sites/pages/components/com_privacy/models/forms/request.xml @@ -0,0 +1,27 @@ + +
        +
        + + + + + + +
        +
        diff --git a/Sites/pages/components/com_privacy/models/remind.php b/Sites/pages/components/com_privacy/models/remind.php new file mode 100644 index 00000000..c96ed8ba --- /dev/null +++ b/Sites/pages/components/com_privacy/models/remind.php @@ -0,0 +1,183 @@ +getForm(); + $data['email'] = JStringPunycode::emailToPunycode($data['email']); + + // Check for an error. + if ($form instanceof Exception) + { + return $form; + } + + // Filter and validate the form data. + $data = $form->filter($data); + $return = $form->validate($data); + + // Check for an error. + if ($return instanceof Exception) + { + return $return; + } + + // Check the validation results. + if ($return === false) + { + // Get the validation messages from the form. + foreach ($form->getErrors() as $formError) + { + $this->setError($formError->getMessage()); + } + + return false; + } + + /** @var PrivacyTableConsent $table */ + $table = $this->getTable(); + + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select($db->quoteName(array('r.id', 'r.user_id', 'r.token'))); + $query->from($db->quoteName('#__privacy_consents', 'r')); + $query->join('LEFT', $db->quoteName('#__users', 'u') . ' ON u.id = r.user_id'); + $query->where($db->quoteName('u.email') . ' = ' . $db->quote($data['email'])); + $query->where($db->quoteName('r.remind') . ' = 1'); + $db->setQuery($query); + + try + { + $remind = $db->loadObject(); + } + catch (RuntimeException $e) + { + $this->setError(JText::_('COM_PRIVACY_ERROR_NO_PENDING_REMIND')); + + return false; + } + + if (!$remind) + { + $this->setError(JText::_('COM_PRIVACY_ERROR_NO_PENDING_REMIND')); + + return false; + } + + // Verify the token + if (!JUserHelper::verifyPassword($data['remind_token'], $remind->token)) + { + $this->setError(JText::_('COM_PRIVACY_ERROR_NO_REMIND_REQUESTS')); + + return false; + } + + // Everything is good to go, transition the request to extended + $saved = $this->save( + array( + 'id' => $remind->id, + 'remind' => 0, + 'token' => '', + 'created' => JFactory::getDate()->toSql(), + ) + ); + + if (!$saved) + { + // Error was set by the save method + return false; + } + + return true; + } + + /** + * Method for getting the form from the model. + * + * @param array $data Data for the form. + * @param boolean $loadData True if the form is to load its own data (default case), false if not. + * + * @return JForm|boolean A JForm object on success, false on failure + * + * @since 3.9.0 + */ + public function getForm($data = array(), $loadData = true) + { + // Get the form. + $form = $this->loadForm('com_privacy.remind', 'remind', array('control' => 'jform')); + + if (empty($form)) + { + return false; + } + + $input = JFactory::getApplication()->input; + + if ($input->getMethod() === 'GET') + { + $form->setValue('remind_token', '', $input->get->getAlnum('remind_token')); + } + + return $form; + } + + /** + * Method to get a table object, load it if necessary. + * + * @param string $name The table name. Optional. + * @param string $prefix The class prefix. Optional. + * @param array $options Configuration array for model. Optional. + * + * @return JTable A JTable object + * + * @since 3.9.0 + * @throws \Exception + */ + public function getTable($name = 'Consent', $prefix = 'PrivacyTable', $options = array()) + { + return parent::getTable($name, $prefix, $options); + } + + /** + * Method to auto-populate the model state. + * + * Note. Calling getState in this method will result in recursion. + * + * @return void + * + * @since 3.9.0 + */ + protected function populateState() + { + // Get the application object. + $params = JFactory::getApplication()->getParams('com_privacy'); + + // Load the parameters. + $this->setState('params', $params); + } +} diff --git a/Sites/pages/components/com_privacy/models/request.php b/Sites/pages/components/com_privacy/models/request.php new file mode 100644 index 00000000..7c08b912 --- /dev/null +++ b/Sites/pages/components/com_privacy/models/request.php @@ -0,0 +1,271 @@ +get('mailonline', 1)) + { + $this->setError(JText::_('COM_PRIVACY_ERROR_CANNOT_CREATE_REQUEST_WHEN_SENDMAIL_DISABLED')); + + return false; + } + + // Get the form. + $form = $this->getForm(); + $data['email'] = JStringPunycode::emailToPunycode($data['email']); + + // Check for an error. + if ($form instanceof Exception) + { + return $form; + } + + // Filter and validate the form data. + $data = $form->filter($data); + $return = $form->validate($data); + + // Check for an error. + if ($return instanceof Exception) + { + return $return; + } + + // Check the validation results. + if ($return === false) + { + // Get the validation messages from the form. + foreach ($form->getErrors() as $formError) + { + $this->setError($formError->getMessage()); + } + + return false; + } + + // Search for an open information request matching the email and type + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select('COUNT(id)') + ->from('#__privacy_requests') + ->where('email = ' . $db->quote($data['email'])) + ->where('request_type = ' . $db->quote($data['request_type'])) + ->where('status IN (0, 1)'); + + try + { + $result = (int) $db->setQuery($query)->loadResult(); + } + catch (JDatabaseException $exception) + { + // Can't check for existing requests, so don't create a new one + $this->setError(JText::_('COM_PRIVACY_ERROR_CHECKING_FOR_EXISTING_REQUESTS')); + + return false; + } + + if ($result > 0) + { + $this->setError(JText::_('COM_PRIVACY_ERROR_PENDING_REQUEST_OPEN')); + + return false; + } + + // Everything is good to go, create the request + $token = JApplicationHelper::getHash(JUserHelper::genRandomPassword()); + $hashedToken = JUserHelper::hashPassword($token); + + $data['confirm_token'] = $hashedToken; + $data['confirm_token_created_at'] = JFactory::getDate()->toSql(); + + if (!$this->save($data)) + { + // The save function will set the error message, so just return here + return false; + } + + // Push a notification to the site's super users, deliberately ignoring if this process fails so the below message goes out + JModelLegacy::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_messages/models', 'MessagesModel'); + JTable::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_messages/tables'); + + /** @var MessagesModelMessage $messageModel */ + $messageModel = JModelLegacy::getInstance('Message', 'MessagesModel'); + + $messageModel->notifySuperUsers( + JText::_('COM_PRIVACY_ADMIN_NOTIFICATION_USER_CREATED_REQUEST_SUBJECT'), + JText::sprintf('COM_PRIVACY_ADMIN_NOTIFICATION_USER_CREATED_REQUEST_MESSAGE', $data['email']) + ); + + // The mailer can be set to either throw Exceptions or return boolean false, account for both + try + { + $app = JFactory::getApplication(); + + $linkMode = $app->get('force_ssl', 0) == 2 ? Route::TLS_FORCE : Route::TLS_IGNORE; + + $substitutions = array( + '[SITENAME]' => $app->get('sitename'), + '[URL]' => JUri::root(), + '[TOKENURL]' => JRoute::link('site', 'index.php?option=com_privacy&view=confirm&confirm_token=' . $token, false, $linkMode, true), + '[FORMURL]' => JRoute::link('site', 'index.php?option=com_privacy&view=confirm', false, $linkMode, true), + '[TOKEN]' => $token, + '\\n' => "\n", + ); + + switch ($data['request_type']) + { + case 'export': + $emailSubject = JText::_('COM_PRIVACY_EMAIL_REQUEST_SUBJECT_EXPORT_REQUEST'); + $emailBody = JText::_('COM_PRIVACY_EMAIL_REQUEST_BODY_EXPORT_REQUEST'); + + break; + + case 'remove': + $emailSubject = JText::_('COM_PRIVACY_EMAIL_REQUEST_SUBJECT_REMOVE_REQUEST'); + $emailBody = JText::_('COM_PRIVACY_EMAIL_REQUEST_BODY_REMOVE_REQUEST'); + + break; + + default: + $this->setError(JText::_('COM_PRIVACY_ERROR_UNKNOWN_REQUEST_TYPE')); + + return false; + } + + foreach ($substitutions as $k => $v) + { + $emailSubject = str_replace($k, $v, $emailSubject); + $emailBody = str_replace($k, $v, $emailBody); + } + + $mailer = JFactory::getMailer(); + $mailer->setSubject($emailSubject); + $mailer->setBody($emailBody); + $mailer->addRecipient($data['email']); + + $mailResult = $mailer->Send(); + + if ($mailResult instanceof JException) + { + // JError was already called so we just need to return now + return false; + } + elseif ($mailResult === false) + { + $this->setError($mailer->ErrorInfo); + + return false; + } + + /** @var PrivacyTableRequest $table */ + $table = $this->getTable(); + + if (!$table->load($this->getState($this->getName() . '.id'))) + { + $this->setError($table->getError()); + + return false; + } + + // Log the request's creation + JModelLegacy::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_actionlogs/models', 'ActionlogsModel'); + + $message = array( + 'action' => 'request-created', + 'requesttype' => $table->request_type, + 'subjectemail' => $table->email, + 'id' => $table->id, + 'itemlink' => 'index.php?option=com_privacy&view=request&id=' . $table->id, + ); + + /** @var ActionlogsModelActionlog $model */ + $model = JModelLegacy::getInstance('Actionlog', 'ActionlogsModel'); + $model->addLog(array($message), 'COM_PRIVACY_ACTION_LOG_CREATED_REQUEST', 'com_privacy.request'); + + // The email sent and the record is saved, everything is good to go from here + return true; + } + catch (phpmailerException $exception) + { + $this->setError($exception->getMessage()); + + return false; + } + } + + /** + * Method for getting the form from the model. + * + * @param array $data Data for the form. + * @param boolean $loadData True if the form is to load its own data (default case), false if not. + * + * @return JForm|boolean A JForm object on success, false on failure + * + * @since 3.9.0 + */ + public function getForm($data = array(), $loadData = true) + { + return $this->loadForm('com_privacy.request', 'request', array('control' => 'jform')); + } + + /** + * Method to get a table object, load it if necessary. + * + * @param string $name The table name. Optional. + * @param string $prefix The class prefix. Optional. + * @param array $options Configuration array for model. Optional. + * + * @return JTable A JTable object + * + * @since 3.9.0 + * @throws \Exception + */ + public function getTable($name = 'Request', $prefix = 'PrivacyTable', $options = array()) + { + return parent::getTable($name, $prefix, $options); + } + + /** + * Method to auto-populate the model state. + * + * Note. Calling getState in this method will result in recursion. + * + * @return void + * + * @since 3.9.0 + */ + protected function populateState() + { + // Get the application object. + $params = JFactory::getApplication()->getParams('com_privacy'); + + // Load the parameters. + $this->setState('params', $params); + } +} diff --git a/Sites/pages/components/com_privacy/privacy.php b/Sites/pages/components/com_privacy/privacy.php new file mode 100644 index 00000000..4c837b8e --- /dev/null +++ b/Sites/pages/components/com_privacy/privacy.php @@ -0,0 +1,14 @@ +execute(JFactory::getApplication()->input->get('task')); +$controller->redirect(); diff --git a/Sites/pages/components/com_privacy/router.php b/Sites/pages/components/com_privacy/router.php new file mode 100644 index 00000000..790bf549 --- /dev/null +++ b/Sites/pages/components/com_privacy/router.php @@ -0,0 +1,78 @@ +registerView(new JComponentRouterViewconfiguration('confirm')); + $this->registerView(new JComponentRouterViewconfiguration('request')); + $this->registerView(new JComponentRouterViewconfiguration('remind')); + + parent::__construct($app, $menu); + + $this->attachRule(new JComponentRouterRulesMenu($this)); + $this->attachRule(new JComponentRouterRulesStandard($this)); + $this->attachRule(new JComponentRouterRulesNomenu($this)); + } +} + +/** + * Privacy router functions + * + * These functions are proxies for the new router interface + * for old SEF extensions. + * + * @param array &$query REQUEST query + * + * @return array Segments of the SEF url + * + * @since 3.9.0 + * @deprecated 4.0 Use Class based routers instead + */ +function privacyBuildRoute(&$query) +{ + $app = JFactory::getApplication(); + $router = new PrivacyRouter($app, $app->getMenu()); + + return $router->build($query); +} + +/** + * Convert SEF URL segments into query variables + * + * @param array $segments Segments in the current URL + * + * @return array Query variables + * + * @since 3.9.0 + * @deprecated 4.0 Use Class based routers instead + */ +function privacyParseRoute($segments) +{ + $app = JFactory::getApplication(); + $router = new PrivacyRouter($app, $app->getMenu()); + + return $router->parse($segments); +} diff --git a/Sites/pages/components/com_privacy/views/confirm/tmpl/default.php b/Sites/pages/components/com_privacy/views/confirm/tmpl/default.php new file mode 100644 index 00000000..bdcc9823 --- /dev/null +++ b/Sites/pages/components/com_privacy/views/confirm/tmpl/default.php @@ -0,0 +1,44 @@ + +
        + params->get('show_page_heading')) : ?> + + +
        + form->getFieldsets() as $fieldset) : ?> +
        + label)) : ?> + label); ?> + + form->renderFieldset($fieldset->name); ?> +
        + +
        +
        + +
        +
        + +
        +
        diff --git a/Sites/pages/components/com_privacy/views/confirm/tmpl/default.xml b/Sites/pages/components/com_privacy/views/confirm/tmpl/default.xml new file mode 100644 index 00000000..7aa69b24 --- /dev/null +++ b/Sites/pages/components/com_privacy/views/confirm/tmpl/default.xml @@ -0,0 +1,11 @@ + + + + + + + + + diff --git a/Sites/pages/components/com_privacy/views/confirm/view.html.php b/Sites/pages/components/com_privacy/views/confirm/view.html.php new file mode 100644 index 00000000..72a19f92 --- /dev/null +++ b/Sites/pages/components/com_privacy/views/confirm/view.html.php @@ -0,0 +1,143 @@ +form = $this->get('Form'); + $this->state = $this->get('State'); + $this->params = $this->state->params; + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + // Escape strings for HTML output + $this->pageclass_sfx = htmlspecialchars($this->params->get('pageclass_sfx'), ENT_COMPAT, 'UTF-8'); + + $this->prepareDocument(); + + return parent::display($tpl); + } + + /** + * Prepares the document. + * + * @return void + * + * @since 3.9.0 + */ + protected function prepareDocument() + { + $app = JFactory::getApplication(); + $menus = $app->getMenu(); + $title = null; + + // Because the application sets a default page title, + // we need to get it from the menu item itself + $menu = $menus->getActive(); + + if ($menu) + { + $this->params->def('page_heading', $this->params->get('page_title', $menu->title)); + } + else + { + $this->params->def('page_heading', JText::_('COM_PRIVACY_VIEW_CONFIRM_PAGE_TITLE')); + } + + $title = $this->params->get('page_title', ''); + + if (empty($title)) + { + $title = $app->get('sitename'); + } + elseif ($app->get('sitename_pagetitles', 0) == 1) + { + $title = JText::sprintf('JPAGETITLE', $app->get('sitename'), $title); + } + elseif ($app->get('sitename_pagetitles', 0) == 2) + { + $title = JText::sprintf('JPAGETITLE', $title, $app->get('sitename')); + } + + $this->document->setTitle($title); + + if ($this->params->get('menu-meta_description')) + { + $this->document->setDescription($this->params->get('menu-meta_description')); + } + + if ($this->params->get('menu-meta_keywords')) + { + $this->document->setMetadata('keywords', $this->params->get('menu-meta_keywords')); + } + + if ($this->params->get('robots')) + { + $this->document->setMetadata('robots', $this->params->get('robots')); + } + } +} diff --git a/Sites/pages/components/com_privacy/views/remind/tmpl/default.php b/Sites/pages/components/com_privacy/views/remind/tmpl/default.php new file mode 100644 index 00000000..5d3e2ba1 --- /dev/null +++ b/Sites/pages/components/com_privacy/views/remind/tmpl/default.php @@ -0,0 +1,44 @@ + +
        + params->get('show_page_heading')) : ?> + + +
        + form->getFieldsets() as $fieldset) : ?> +
        + label)) : ?> + label); ?> + + form->renderFieldset($fieldset->name); ?> +
        + +
        +
        + +
        +
        + +
        +
        diff --git a/Sites/pages/components/com_privacy/views/remind/tmpl/default.xml b/Sites/pages/components/com_privacy/views/remind/tmpl/default.xml new file mode 100644 index 00000000..cce3d29f --- /dev/null +++ b/Sites/pages/components/com_privacy/views/remind/tmpl/default.xml @@ -0,0 +1,11 @@ + + + + + + + + + diff --git a/Sites/pages/components/com_privacy/views/remind/view.html.php b/Sites/pages/components/com_privacy/views/remind/view.html.php new file mode 100644 index 00000000..8961586b --- /dev/null +++ b/Sites/pages/components/com_privacy/views/remind/view.html.php @@ -0,0 +1,143 @@ +form = $this->get('Form'); + $this->state = $this->get('State'); + $this->params = $this->state->params; + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + // Escape strings for HTML output + $this->pageclass_sfx = htmlspecialchars($this->params->get('pageclass_sfx'), ENT_COMPAT, 'UTF-8'); + + $this->prepareDocument(); + + return parent::display($tpl); + } + + /** + * Prepares the document. + * + * @return void + * + * @since 3.9.0 + */ + protected function prepareDocument() + { + $app = JFactory::getApplication(); + $menus = $app->getMenu(); + $title = null; + + // Because the application sets a default page title, + // we need to get it from the menu item itself + $menu = $menus->getActive(); + + if ($menu) + { + $this->params->def('page_heading', $this->params->get('page_title', $menu->title)); + } + else + { + $this->params->def('page_heading', JText::_('COM_PRIVACY_VIEW_REMIND_PAGE_TITLE')); + } + + $title = $this->params->get('page_title', ''); + + if (empty($title)) + { + $title = $app->get('sitename'); + } + elseif ($app->get('sitename_pagetitles', 0) == 1) + { + $title = JText::sprintf('JPAGETITLE', $app->get('sitename'), $title); + } + elseif ($app->get('sitename_pagetitles', 0) == 2) + { + $title = JText::sprintf('JPAGETITLE', $title, $app->get('sitename')); + } + + $this->document->setTitle($title); + + if ($this->params->get('menu-meta_description')) + { + $this->document->setDescription($this->params->get('menu-meta_description')); + } + + if ($this->params->get('menu-meta_keywords')) + { + $this->document->setMetadata('keywords', $this->params->get('menu-meta_keywords')); + } + + if ($this->params->get('robots')) + { + $this->document->setMetadata('robots', $this->params->get('robots')); + } + } +} diff --git a/Sites/pages/components/com_privacy/views/request/tmpl/default.php b/Sites/pages/components/com_privacy/views/request/tmpl/default.php new file mode 100644 index 00000000..a027f5bb --- /dev/null +++ b/Sites/pages/components/com_privacy/views/request/tmpl/default.php @@ -0,0 +1,51 @@ + +
        + params->get('show_page_heading')) : ?> + + + sendMailEnabled) : ?> +
        + form->getFieldsets() as $fieldset) : ?> +
        + label)) : ?> + label); ?> + + form->renderFieldset($fieldset->name); ?> +
        + +
        +
        + +
        +
        + +
        + +
        +

        +
        + +
        diff --git a/Sites/pages/components/com_privacy/views/request/tmpl/default.xml b/Sites/pages/components/com_privacy/views/request/tmpl/default.xml new file mode 100644 index 00000000..b7a15c21 --- /dev/null +++ b/Sites/pages/components/com_privacy/views/request/tmpl/default.xml @@ -0,0 +1,11 @@ + + + + + + + + + diff --git a/Sites/pages/components/com_privacy/views/request/view.html.php b/Sites/pages/components/com_privacy/views/request/view.html.php new file mode 100644 index 00000000..c9523d3d --- /dev/null +++ b/Sites/pages/components/com_privacy/views/request/view.html.php @@ -0,0 +1,152 @@ +form = $this->get('Form'); + $this->state = $this->get('State'); + $this->params = $this->state->params; + $this->sendMailEnabled = (bool) JFactory::getConfig()->get('mailonline', 1); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + // Escape strings for HTML output + $this->pageclass_sfx = htmlspecialchars($this->params->get('pageclass_sfx'), ENT_COMPAT, 'UTF-8'); + + $this->prepareDocument(); + + return parent::display($tpl); + } + + /** + * Prepares the document. + * + * @return void + * + * @since 3.9.0 + */ + protected function prepareDocument() + { + $app = JFactory::getApplication(); + $menus = $app->getMenu(); + $title = null; + + // Because the application sets a default page title, + // we need to get it from the menu item itself + $menu = $menus->getActive(); + + if ($menu) + { + $this->params->def('page_heading', $this->params->get('page_title', $menu->title)); + } + else + { + $this->params->def('page_heading', JText::_('COM_PRIVACY_VIEW_REQUEST_PAGE_TITLE')); + } + + $title = $this->params->get('page_title', ''); + + if (empty($title)) + { + $title = $app->get('sitename'); + } + elseif ($app->get('sitename_pagetitles', 0) == 1) + { + $title = JText::sprintf('JPAGETITLE', $app->get('sitename'), $title); + } + elseif ($app->get('sitename_pagetitles', 0) == 2) + { + $title = JText::sprintf('JPAGETITLE', $title, $app->get('sitename')); + } + + $this->document->setTitle($title); + + if ($this->params->get('menu-meta_description')) + { + $this->document->setDescription($this->params->get('menu-meta_description')); + } + + if ($this->params->get('menu-meta_keywords')) + { + $this->document->setMetadata('keywords', $this->params->get('menu-meta_keywords')); + } + + if ($this->params->get('robots')) + { + $this->document->setMetadata('robots', $this->params->get('robots')); + } + } +} diff --git a/Sites/pages/components/com_search/controller.php b/Sites/pages/components/com_search/controller.php new file mode 100644 index 00000000..9011f673 --- /dev/null +++ b/Sites/pages/components/com_search/controller.php @@ -0,0 +1,109 @@ +input->set('view', 'search'); + + return parent::display($cachable, $urlparams); + } + + /** + * Search + * + * @return void + * + * @throws Exception + */ + public function search() + { + // Slashes cause errors, <> get stripped anyway later on. # causes problems. + $badchars = array('#', '>', '<', '\\'); + $searchword = trim(str_replace($badchars, '', $this->input->post->getString('searchword'))); + + // If searchword enclosed in double quotes, strip quotes and do exact match + if (substr($searchword, 0, 1) === '"' && substr($searchword, -1) === '"') + { + $post['searchword'] = substr($searchword, 1, -1); + $this->input->set('searchphrase', 'exact'); + } + else + { + $post['searchword'] = $searchword; + } + + $post['ordering'] = $this->input->post->getWord('ordering'); + $post['searchphrase'] = $this->input->post->getWord('searchphrase', 'all'); + $post['limit'] = $this->input->post->getUInt('limit'); + + if ($post['limit'] === null) + { + unset($post['limit']); + } + + $areas = $this->input->post->get('areas', null, 'array'); + + if ($areas) + { + foreach ($areas as $area) + { + $post['areas'][] = JFilterInput::getInstance()->clean($area, 'cmd'); + } + } + + // The Itemid from the request, we will use this if it's a search page or if there is no search page available + $post['Itemid'] = $this->input->getInt('Itemid'); + + // Set Itemid id for links from menu + $app = JFactory::getApplication(); + $menu = $app->getMenu(); + $item = $menu->getItem($post['Itemid']); + + // The requested Item is not a search page so we need to find one + if ($item && ($item->component !== 'com_search' || $item->query['view'] !== 'search')) + { + // Get item based on component, not link. link is not reliable. + $item = $menu->getItems('component', 'com_search', true); + + // If we found a search page, use that. + if (!empty($item)) + { + $post['Itemid'] = $item->id; + } + } + + unset($post['task'], $post['submit']); + + $uri = JUri::getInstance(); + $uri->setQuery($post); + $uri->setVar('option', 'com_search'); + + $this->setRedirect(JRoute::_('index.php' . $uri->toString(array('query', 'fragment')), false)); + } +} diff --git a/Sites/pages/components/com_search/models/search.php b/Sites/pages/components/com_search/models/search.php new file mode 100644 index 00000000..b75983b1 --- /dev/null +++ b/Sites/pages/components/com_search/models/search.php @@ -0,0 +1,247 @@ +setState('limit', $app->getUserStateFromRequest('com_search.limit', 'limit', $config->get('list_limit'), 'uint')); + $this->setState('limitstart', $app->input->get('limitstart', 0, 'uint')); + + // Get parameters. + $params = $app->getParams(); + + if ($params->get('searchphrase') == 1) + { + $searchphrase = 'any'; + } + elseif ($params->get('searchphrase') == 2) + { + $searchphrase = 'exact'; + } + else + { + $searchphrase = 'all'; + } + + // Set the search parameters + $keyword = urldecode($app->input->getString('searchword')); + $match = $app->input->get('searchphrase', $searchphrase, 'word'); + $ordering = $app->input->get('ordering', $params->get('ordering', 'newest'), 'word'); + $this->setSearch($keyword, $match, $ordering); + + // Set the search areas + $areas = $app->input->get('areas', null, 'array'); + $this->setAreas($areas); + } + + /** + * Method to set the search parameters + * + * @param string $keyword string search string + * @param string $match matching option, exact|any|all + * @param string $ordering option, newest|oldest|popular|alpha|category + * + * @access public + * + * @return void + */ + public function setSearch($keyword, $match = 'all', $ordering = 'newest') + { + if (isset($keyword)) + { + $this->setState('origkeyword', $keyword); + + if ($match !== 'exact') + { + $keyword = preg_replace('#\xE3\x80\x80#', ' ', $keyword); + } + + $this->setState('keyword', $keyword); + } + + if (isset($match)) + { + $this->setState('match', $match); + } + + if (isset($ordering)) + { + $this->setState('ordering', $ordering); + } + } + + /** + * Method to get weblink item data for the category + * + * @access public + * @return array + */ + public function getData() + { + // Lets load the content if it doesn't already exist + if (empty($this->_data)) + { + $areas = $this->getAreas(); + + JPluginHelper::importPlugin('search'); + $dispatcher = JEventDispatcher::getInstance(); + $results = $dispatcher->trigger('onContentSearch', array( + $this->getState('keyword'), + $this->getState('match'), + $this->getState('ordering'), + $areas['active']) + ); + + $rows = array(); + + foreach ($results as $result) + { + $rows = array_merge((array) $rows, (array) $result); + } + + $this->_total = count($rows); + + if ($this->getState('limit') > 0) + { + $this->_data = array_splice($rows, $this->getState('limitstart'), $this->getState('limit')); + } + else + { + $this->_data = $rows; + } + } + + return $this->_data; + } + + /** + * Method to get the total number of weblink items for the category + * + * @access public + * + * @return integer + */ + public function getTotal() + { + return $this->_total; + } + + /** + * Method to set the search areas + * + * @param array $active areas + * @param array $search areas + * + * @return void + * + * @access public + */ + public function setAreas($active = array(), $search = array()) + { + $this->_areas['active'] = $active; + $this->_areas['search'] = $search; + } + + /** + * Method to get a pagination object of the weblink items for the category + * + * @access public + * @return integer + */ + public function getPagination() + { + // Lets load the content if it doesn't already exist + if (empty($this->_pagination)) + { + $this->_pagination = new JPagination($this->getTotal(), $this->getState('limitstart'), $this->getState('limit')); + } + + return $this->_pagination; + } + + /** + * Method to get the search areas + * + * @return integer + * + * @since 1.5 + */ + public function getAreas() + { + // Load the Category data + if (empty($this->_areas['search'])) + { + $areas = array(); + + JPluginHelper::importPlugin('search'); + $dispatcher = JEventDispatcher::getInstance(); + $searchareas = $dispatcher->trigger('onContentSearchAreas'); + + foreach ($searchareas as $area) + { + if (is_array($area)) + { + $areas = array_merge($areas, $area); + } + } + + $this->_areas['search'] = $areas; + } + + return $this->_areas; + } +} diff --git a/Sites/pages/components/com_search/router.php b/Sites/pages/components/com_search/router.php new file mode 100644 index 00000000..83cfb11d --- /dev/null +++ b/Sites/pages/components/com_search/router.php @@ -0,0 +1,107 @@ +build($query); +} + +/** + * searchParseRoute + * + * These functions are proxies for the new router interface + * for old SEF extensions. + * + * @param array $segments The segments of the URL to parse. + * + * @return array + * + * @deprecated 4.0 Use Class based routers instead + */ +function searchParseRoute($segments) +{ + $router = new SearchRouter; + + return $router->parse($segments); +} diff --git a/Sites/pages/components/com_search/search.php b/Sites/pages/components/com_search/search.php new file mode 100644 index 00000000..69e8d718 --- /dev/null +++ b/Sites/pages/components/com_search/search.php @@ -0,0 +1,14 @@ +execute(JFactory::getApplication()->input->get('task')); +$controller->redirect(); diff --git a/Sites/pages/components/com_search/views/search/tmpl/default.php b/Sites/pages/components/com_search/views/search/tmpl/default.php new file mode 100644 index 00000000..b613c848 --- /dev/null +++ b/Sites/pages/components/com_search/views/search/tmpl/default.php @@ -0,0 +1,29 @@ + +
        + params->get('show_page_heading')) : ?> +

        + escape($this->params->get('page_heading'))) : ?> + escape($this->params->get('page_heading')); ?> + + escape($this->params->get('page_title')); ?> + +

        + + loadTemplate('form'); ?> + error == null && count($this->results) > 0) : ?> + loadTemplate('results'); ?> + + loadTemplate('error'); ?> + +
        diff --git a/Sites/pages/components/com_search/views/search/tmpl/default.xml b/Sites/pages/components/com_search/views/search/tmpl/default.xml new file mode 100644 index 00000000..53c0af65 --- /dev/null +++ b/Sites/pages/components/com_search/views/search/tmpl/default.xml @@ -0,0 +1,103 @@ + + + + + + + + + + + +
        + + +
        +
        + + + + +
        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        +
        +
        diff --git a/Sites/pages/components/com_search/views/search/tmpl/default_error.php b/Sites/pages/components/com_search/views/search/tmpl/default_error.php new file mode 100644 index 00000000..aac4e246 --- /dev/null +++ b/Sites/pages/components/com_search/views/search/tmpl/default_error.php @@ -0,0 +1,17 @@ + +error) : ?> +
        + escape($this->error); ?> +
        + diff --git a/Sites/pages/components/com_search/views/search/tmpl/default_form.php b/Sites/pages/components/com_search/views/search/tmpl/default_form.php new file mode 100644 index 00000000..302468e1 --- /dev/null +++ b/Sites/pages/components/com_search/views/search/tmpl/default_form.php @@ -0,0 +1,83 @@ +getUpperLimitSearchWord(); + +?> +
        +
        +
        + + +
        +
        + +
        + +
        +
        +
        + searchword)) : ?> +

        + ' . $this->total . ''); ?> +

        + +
        + params->get('search_phrases', 1)) : ?> +
        + + + +
        + lists['searchphrase']; ?> +
        +
        + + lists['ordering']; ?> +
        +
        + + params->get('search_areas', 1)) : ?> +
        + + + + searchareas['search'] as $val => $txt) : ?> + searchareas['active']) && in_array($val, $this->searchareas['active']) ? 'checked="checked"' : ''; ?> + + +
        + + total > 0) : ?> +
        + + pagination->getLimitBox(); ?> +
        +

        + pagination->getPagesCounter(); ?> +

        + +
        diff --git a/Sites/pages/components/com_search/views/search/tmpl/default_results.php b/Sites/pages/components/com_search/views/search/tmpl/default_results.php new file mode 100644 index 00000000..49269967 --- /dev/null +++ b/Sites/pages/components/com_search/views/search/tmpl/default_results.php @@ -0,0 +1,48 @@ + +
        +results as $result) : ?> +
        + pagination->limitstart + $result->count . '. '; ?> + href) : ?> + browsernav == 1) : ?> target="_blank"> + title should not be escaped in this case, as it may ?> + + + title; ?> + + + title ?> + title; ?> + +
        + section) : ?> +
        + + (escape($result->section); ?>) + +
        + +
        + text; ?> +
        + params->get('show_date')) : ?> +
        + created); ?> +
        + + +
        + diff --git a/Sites/pages/components/com_search/views/search/view.html.php b/Sites/pages/components/com_search/views/search/view.html.php new file mode 100644 index 00000000..58fce745 --- /dev/null +++ b/Sites/pages/components/com_search/views/search/view.html.php @@ -0,0 +1,314 @@ +get('areas'); + $state = $this->get('state'); + $searchWord = $state->get('keyword'); + $params = $app->getParams(); + + if (!$app->getMenu()->getActive()) + { + $params->set('page_title', JText::_('COM_SEARCH_SEARCH')); + } + + $title = $params->get('page_title'); + + if ($app->get('sitename_pagetitles', 0) == 1) + { + $title = JText::sprintf('JPAGETITLE', $app->get('sitename'), $title); + } + elseif ($app->get('sitename_pagetitles', 0) == 2) + { + $title = JText::sprintf('JPAGETITLE', $title, $app->get('sitename')); + } + + $this->document->setTitle($title); + + if ($params->get('menu-meta_description')) + { + $this->document->setDescription($params->get('menu-meta_description')); + } + + if ($params->get('menu-meta_keywords')) + { + $this->document->setMetadata('keywords', $params->get('menu-meta_keywords')); + } + + if ($params->get('robots')) + { + $this->document->setMetadata('robots', $params->get('robots')); + } + + // Built select lists + $orders = array(); + $orders[] = JHtml::_('select.option', 'newest', JText::_('COM_SEARCH_NEWEST_FIRST')); + $orders[] = JHtml::_('select.option', 'oldest', JText::_('COM_SEARCH_OLDEST_FIRST')); + $orders[] = JHtml::_('select.option', 'popular', JText::_('COM_SEARCH_MOST_POPULAR')); + $orders[] = JHtml::_('select.option', 'alpha', JText::_('COM_SEARCH_ALPHABETICAL')); + $orders[] = JHtml::_('select.option', 'category', JText::_('JCATEGORY')); + + $lists = array(); + $lists['ordering'] = JHtml::_('select.genericlist', $orders, 'ordering', 'class="inputbox"', 'value', 'text', $state->get('ordering')); + + $searchphrases = array(); + $searchphrases[] = JHtml::_('select.option', 'all', JText::_('COM_SEARCH_ALL_WORDS')); + $searchphrases[] = JHtml::_('select.option', 'any', JText::_('COM_SEARCH_ANY_WORDS')); + $searchphrases[] = JHtml::_('select.option', 'exact', JText::_('COM_SEARCH_EXACT_PHRASE')); + $lists['searchphrase'] = JHtml::_('select.radiolist', $searchphrases, 'searchphrase', '', 'value', 'text', $state->get('match')); + + // Log the search + \Joomla\CMS\Helper\SearchHelper::logSearch($searchWord, 'com_search'); + + // Limit search-word + $lang = JFactory::getLanguage(); + $upper_limit = $lang->getUpperLimitSearchWord(); + $lower_limit = $lang->getLowerLimitSearchWord(); + + if (SearchHelper::limitSearchWord($searchWord)) + { + $error = JText::sprintf('COM_SEARCH_ERROR_SEARCH_MESSAGE', $lower_limit, $upper_limit); + } + + // Sanitise search-word + if (SearchHelper::santiseSearchWord($searchWord, $state->get('match'))) + { + $error = JText::_('COM_SEARCH_ERROR_IGNOREKEYWORD'); + } + + if (!$searchWord && !empty($this->input) && count($this->input->post)) + { + // $error = JText::_('COM_SEARCH_ERROR_ENTERKEYWORD'); + } + + // Put the filtered results back into the model + // for next release, the checks should be done in the model perhaps... + $state->set('keyword', $searchWord); + + if ($error === null) + { + $results = $this->get('data'); + $total = $this->get('total'); + $pagination = $this->get('pagination'); + + // Flag indicates to not add limitstart=0 to URL + $pagination->hideEmptyLimitstart = true; + + if ($state->get('match') === 'exact') + { + $searchWords = array($searchWord); + $needle = $searchWord; + } + else + { + $searchWordA = preg_replace('#\xE3\x80\x80#', ' ', $searchWord); + $searchWords = preg_split("/\s+/u", $searchWordA); + $needle = $searchWords[0]; + } + + JLoader::register('ContentHelperRoute', JPATH_SITE . '/components/com_content/helpers/route.php'); + + // Make sure there are no slashes in the needle + $needle = str_replace('/', '\/', $needle); + + for ($i = 0, $count = count($results); $i < $count; ++$i) + { + $rowTitle = &$results[$i]->title; + $rowTitleHighLighted = $this->highLight($rowTitle, $needle, $searchWords); + $rowText = &$results[$i]->text; + $rowTextHighLighted = $this->highLight($rowText, $needle, $searchWords); + + $result = &$results[$i]; + $created = ''; + + if ($result->created) + { + $created = JHtml::_('date', $result->created, JText::_('DATE_FORMAT_LC3')); + } + + $result->title = $rowTitleHighLighted; + $result->text = JHtml::_('content.prepare', $rowTextHighLighted, '', 'com_search.search'); + $result->created = $created; + $result->count = $i + 1; + } + } + + // Check for layout override + $active = JFactory::getApplication()->getMenu()->getActive(); + + if (isset($active->query['layout'])) + { + $this->setLayout($active->query['layout']); + } + + // Escape strings for HTML output + $this->pageclass_sfx = htmlspecialchars($params->get('pageclass_sfx')); + $this->pagination = &$pagination; + $this->results = &$results; + $this->lists = &$lists; + $this->params = &$params; + $this->ordering = $state->get('ordering'); + $this->searchword = $searchWord; + $this->origkeyword = $state->get('origkeyword'); + $this->searchphrase = $state->get('match'); + $this->searchareas = $areas; + $this->total = $total; + $this->error = $error; + $this->action = $uri; + + parent::display($tpl); + } + + /** + * Method to control the highlighting of keywords + * + * @param string $string text to be searched + * @param string $needle text to search for + * @param string $searchWords words to be searched + * + * @return mixed A string. + * + * @since 3.8.4 + */ + public function highLight($string, $needle, $searchWords) + { + $hl1 = ''; + $hl2 = ''; + $mbString = extension_loaded('mbstring'); + $highlighterLen = strlen($hl1 . $hl2); + + // Doing HTML entity decoding here, just in case we get any HTML entities here. + $quoteStyle = version_compare(PHP_VERSION, '5.4', '>=') ? ENT_NOQUOTES | ENT_HTML401 : ENT_NOQUOTES; + $row = html_entity_decode($string, $quoteStyle, 'UTF-8'); + $row = SearchHelper::prepareSearchContent($row, $needle); + $searchWords = array_values(array_unique($searchWords)); + $lowerCaseRow = $mbString ? mb_strtolower($row) : StringHelper::strtolower($row); + + $transliteratedLowerCaseRow = SearchHelper::remove_accents($lowerCaseRow); + + $posCollector = array(); + + foreach ($searchWords as $highlightWord) + { + $found = false; + + if ($mbString) + { + $lowerCaseHighlightWord = mb_strtolower($highlightWord); + + if (($pos = mb_strpos($lowerCaseRow, $lowerCaseHighlightWord)) !== false) + { + $found = true; + } + elseif (($pos = mb_strpos($transliteratedLowerCaseRow, $lowerCaseHighlightWord)) !== false) + { + $found = true; + } + } + else + { + $lowerCaseHighlightWord = StringHelper::strtolower($highlightWord); + + if (($pos = StringHelper::strpos($lowerCaseRow, $lowerCaseHighlightWord)) !== false) + { + $found = true; + } + elseif (($pos = StringHelper::strpos($transliteratedLowerCaseRow, $lowerCaseHighlightWord)) !== false) + { + $found = true; + } + } + + if ($found === true) + { + // Iconv transliterates '€' to 'EUR' + // TODO: add other expanding translations? + $eur_compensation = $pos > 0 ? substr_count($row, "\xE2\x82\xAC", 0, $pos) * 2 : 0; + $pos -= $eur_compensation; + + // Collect pos and search-word + $posCollector[$pos] = $highlightWord; + } + } + + if (count($posCollector)) + { + // Sort by pos. Easier to handle overlapping highlighter-spans + ksort($posCollector); + $cnt = 0; + $lastHighlighterEnd = -1; + + foreach ($posCollector as $pos => $highlightWord) + { + $pos += $cnt * $highlighterLen; + + /* + * Avoid overlapping/corrupted highlighter-spans + * TODO $chkOverlap could be used to highlight remaining part + * of search-word outside last highlighter-span. + * At the moment no additional highlighter is set. + */ + $chkOverlap = $pos - $lastHighlighterEnd; + + if ($chkOverlap >= 0) + { + // Set highlighter around search-word + if ($mbString) + { + $highlightWordLen = mb_strlen($highlightWord); + $row = mb_substr($row, 0, $pos) . $hl1 . mb_substr($row, $pos, $highlightWordLen) + . $hl2 . mb_substr($row, $pos + $highlightWordLen); + } + else + { + $highlightWordLen = StringHelper::strlen($highlightWord); + $row = StringHelper::substr($row, 0, $pos) + . $hl1 . StringHelper::substr($row, $pos, StringHelper::strlen($highlightWord)) + . $hl2 . StringHelper::substr($row, $pos + StringHelper::strlen($highlightWord)); + } + + $cnt++; + $lastHighlighterEnd = $pos + $highlightWordLen + $highlighterLen; + } + } + } + + return $row; + } +} diff --git a/Sites/pages/components/com_search/views/search/view.opensearch.php b/Sites/pages/components/com_search/views/search/view.opensearch.php new file mode 100644 index 00000000..c3ef5ba0 --- /dev/null +++ b/Sites/pages/components/com_search/views/search/view.opensearch.php @@ -0,0 +1,52 @@ +setShortName($params->get('opensearch_name', $app->get('sitename'))); + $doc->setDescription($params->get('opensearch_description', $app->get('MetaDesc'))); + + // Add the URL for the search + $searchUri = JUri::base() . 'index.php?option=com_search&searchword={searchTerms}'; + + // Find the menu item for the search + $menu = $app->getMenu(); + $items = $menu->getItems('link', 'index.php?option=com_search&view=search'); + + if (isset($items[0])) + { + $searchUri .= '&Itemid=' . $items[0]->id; + } + + $htmlSearch = new JOpenSearchUrl; + $htmlSearch->template = JRoute::_($searchUri); + $doc->addUrl($htmlSearch); + } +} diff --git a/Sites/pages/components/com_tags/controller.php b/Sites/pages/components/com_tags/controller.php new file mode 100644 index 00000000..2577a8df --- /dev/null +++ b/Sites/pages/components/com_tags/controller.php @@ -0,0 +1,54 @@ +input->get('view', 'tags'); + $this->input->set('view', $vName); + + if ($user->get('id') || ($this->input->getMethod() === 'POST' && $vName === 'tags')) + { + $cachable = false; + } + + $safeurlparams = array( + 'id' => 'ARRAY', + 'type' => 'ARRAY', + 'limit' => 'UINT', + 'limitstart' => 'UINT', + 'filter_order' => 'CMD', + 'filter_order_Dir' => 'CMD', + 'lang' => 'CMD' + ); + + return parent::display($cachable, $safeurlparams); + } +} diff --git a/Sites/pages/components/com_tags/controllers/tags.php b/Sites/pages/components/com_tags/controllers/tags.php new file mode 100644 index 00000000..722c49dc --- /dev/null +++ b/Sites/pages/components/com_tags/controllers/tags.php @@ -0,0 +1,56 @@ + trim($app->input->get('like', null, 'string')), + 'title' => trim($app->input->get('title', null, 'string')), + 'flanguage' => $app->input->get('flanguage', null, 'word'), + 'published' => $app->input->get('published', 1, 'int'), + 'parent_id' => $app->input->get('parent_id', 0, 'int'), + 'access' => $user->getAuthorisedViewLevels(), + ); + + if ((!$user->authorise('core.edit.state', 'com_tags')) && (!$user->authorise('core.edit', 'com_tags'))) + { + // Filter on published for those who do not have edit or edit.state rights. + $filters['published'] = 1; + } + + $results = JHelperTags::searchTags($filters); + + if ($results) + { + // Output a JSON object + echo json_encode($results); + } + + $app->close(); + } +} diff --git a/Sites/pages/components/com_tags/helpers/route.php b/Sites/pages/components/com_tags/helpers/route.php new file mode 100644 index 00000000..6ba264c2 --- /dev/null +++ b/Sites/pages/components/com_tags/helpers/route.php @@ -0,0 +1,225 @@ +getRoute($contentItemId, $typeAlias, $link, $language, $contentCatId); + } + + return $link; + } + + /** + * Tries to load the router for the component and calls it. Otherwise calls getRoute. + * + * @param integer $id The ID of the tag + * + * @return string URL link to pass to JRoute + * + * @since 3.1 + */ + public static function getTagRoute($id) + { + $needles = array( + 'tag' => array((int) $id) + ); + + if ($id < 1) + { + $link = ''; + } + else + { + $link = 'index.php?option=com_tags&view=tag&id=' . $id; + + if ($item = self::_findItem($needles)) + { + $link .= '&Itemid=' . $item; + } + else + { + $needles = array('tags' => array(1, 0)); + + if ($item = self::_findItem($needles)) + { + $link .= '&Itemid=' . $item; + } + } + } + + return $link; + } + + /** + * Tries to load the router for the tags view. + * + * @return string URL link to pass to JRoute + * + * @since 3.7 + */ + public static function getTagsRoute() + { + $needles = array( + 'tags' => array(0) + ); + + $link = 'index.php?option=com_tags&view=tags'; + + if ($item = self::_findItem($needles)) + { + $link .= '&Itemid=' . $item; + } + + return $link; + } + + /** + * Find Item static function + * + * @param array $needles Array used to get the language value + * + * @return null + * + * @throws Exception + */ + protected static function _findItem($needles = null) + { + $app = JFactory::getApplication(); + $menus = $app->getMenu('site'); + $language = isset($needles['language']) ? $needles['language'] : '*'; + + // Prepare the reverse lookup array. + if (self::$lookup === null) + { + self::$lookup = array(); + + $component = JComponentHelper::getComponent('com_tags'); + $items = $menus->getItems('component_id', $component->id); + + if ($items) + { + foreach ($items as $item) + { + if (isset($item->query, $item->query['view'])) + { + $lang = ($item->language != '' ? $item->language : '*'); + + if (!isset(self::$lookup[$lang])) + { + self::$lookup[$lang] = array(); + } + + $view = $item->query['view']; + + if (!isset(self::$lookup[$lang][$view])) + { + self::$lookup[$lang][$view] = array(); + } + + // Only match menu items that list one tag + if (isset($item->query['id']) && is_array($item->query['id'])) + { + foreach ($item->query['id'] as $position => $tagId) + { + if (!isset(self::$lookup[$lang][$view][$item->query['id'][$position]]) || count($item->query['id']) == 1) + { + self::$lookup[$lang][$view][$item->query['id'][$position]] = $item->id; + } + } + } + elseif ($view == 'tags') + { + self::$lookup[$lang]['tags'][] = $item->id; + } + } + } + } + } + + if ($needles) + { + foreach ($needles as $view => $ids) + { + if (isset(self::$lookup[$language][$view])) + { + foreach ($ids as $id) + { + if (isset(self::$lookup[$language][$view][(int) $id])) + { + return self::$lookup[$language][$view][(int) $id]; + } + } + } + } + } + else + { + $active = $menus->getActive(); + + if ($active) + { + return $active->id; + } + } + + return null; + } +} diff --git a/Sites/pages/components/com_tags/models/tag.php b/Sites/pages/components/com_tags/models/tag.php new file mode 100644 index 00000000..709281ac --- /dev/null +++ b/Sites/pages/components/com_tags/models/tag.php @@ -0,0 +1,356 @@ +link = TagsHelperRoute::getItemRoute( + $item->content_item_id, + $item->core_alias, + $item->core_catid, + $item->core_language, + $item->type_alias, + $item->router + ); + + // Get display date + switch ($this->state->params->get('tag_list_show_date')) + { + case 'modified': + $item->displayDate = $item->core_modified_time; + break; + + case 'created': + $item->displayDate = $item->core_created_time; + break; + + default: + case 'published': + $item->displayDate = ($item->core_publish_up == 0) ? $item->core_created_time : $item->core_publish_up; + break; + } + } + } + + return $items; + } + + /** + * Method to build an SQL query to load the list data of all items with a given tag. + * + * @return string An SQL query + * + * @since 3.1 + */ + protected function getListQuery() + { + $tagId = $this->getState('tag.id') ? : ''; + + $typesr = $this->getState('tag.typesr'); + $orderByOption = $this->getState('list.ordering', 'c.core_title'); + $includeChildren = $this->state->params->get('include_children', 0); + $orderDir = $this->getState('list.direction', 'ASC'); + $matchAll = $this->getState('params')->get('return_any_or_all', 1); + $language = $this->getState('tag.language'); + $stateFilter = $this->getState('tag.state'); + + // Optionally filter on language + if (empty($language)) + { + $language = JComponentHelper::getParams('com_tags')->get('tag_list_language_filter', 'all'); + } + + $tagsHelper = new JHelperTags; + $query = $tagsHelper->getTagItemsQuery($tagId, $typesr, $includeChildren, $orderByOption, $orderDir, $matchAll, $language, $stateFilter); + + if ($this->state->get('list.filter')) + { + $query->where($this->_db->quoteName('c.core_title') . ' LIKE ' . $this->_db->quote('%' . $this->state->get('list.filter') . '%')); + } + + return $query; + } + + /** + * Method to auto-populate the model state. + * + * Note. Calling getState in this method will result in recursion. + * + * @param string $ordering An optional ordering field. + * @param string $direction An optional direction (asc|desc). + * + * @return void + * + * @since 3.1 + */ + protected function populateState($ordering = 'c.core_title', $direction = 'ASC') + { + $app = JFactory::getApplication(); + + // Load the parameters. + $params = $app->isClient('administrator') ? JComponentHelper::getParams('com_tags') : $app->getParams(); + + $this->setState('params', $params); + + // Load state from the request. + $ids = $app->input->get('id', array(), 'array'); + + if (count($ids) == 1) + { + $ids = explode(',', $ids[0]); + } + + $ids = ArrayHelper::toInteger($ids); + + $pkString = implode(',', $ids); + + $this->setState('tag.id', $pkString); + + // Get the selected list of types from the request. If none are specified all are used. + $typesr = $app->input->get('types', array(), 'array'); + + if ($typesr) + { + // Implode is needed because the array can contain a string with a coma separated list of ids + $typesr = implode(',', $typesr); + + // Sanitise + $typesr = explode(',', $typesr); + $typesr = ArrayHelper::toInteger($typesr); + + $this->setState('tag.typesr', $typesr); + } + + $language = $app->input->getString('tag_list_language_filter'); + $this->setState('tag.language', $language); + + // List state information + $format = $app->input->getWord('format'); + + if ($format === 'feed') + { + $limit = $app->get('feed_limit'); + } + else + { + $limit = $params->get('display_num', $app->get('list_limit', 20)); + $limit = $app->getUserStateFromRequest('global.list.limit', 'limit', $limit, 'uint'); + } + + $this->setState('list.limit', $limit); + + $offset = $app->input->get('limitstart', 0, 'uint'); + $this->setState('list.start', $offset); + + $itemid = $pkString . ':' . $app->input->get('Itemid', 0, 'int'); + $orderCol = $app->getUserStateFromRequest('com_tags.tag.list.' . $itemid . '.filter_order', 'filter_order', '', 'string'); + $orderCol = !$orderCol ? $this->state->params->get('tag_list_orderby', 'c.core_title') : $orderCol; + + if (!in_array($orderCol, $this->filter_fields)) + { + $orderCol = 'c.core_title'; + } + + $this->setState('list.ordering', $orderCol); + + $listOrder = $app->getUserStateFromRequest('com_tags.tag.list.' . $itemid . '.filter_order_direction', 'filter_order_Dir', '', 'string'); + $listOrder = !$listOrder ? $this->state->params->get('tag_list_orderby_direction', 'ASC') : $listOrder; + + if (!in_array(strtoupper($listOrder), array('ASC', 'DESC', ''))) + { + $listOrder = 'ASC'; + } + + $this->setState('list.direction', $listOrder); + + $this->setState('tag.state', 1); + + // Optional filter text + $filterSearch = $app->getUserStateFromRequest('com_tags.tag.list.' . $itemid . '.filter_search', 'filter-search', '', 'string'); + $this->setState('list.filter', $filterSearch); + } + + /** + * Method to get tag data for the current tag or tags + * + * @param integer $pk An optional ID + * + * @return object + * + * @since 3.1 + */ + public function getItem($pk = null) + { + if (!isset($this->item)) + { + $this->item = false; + + if (empty($pk)) + { + $pk = $this->getState('tag.id'); + } + + // Get a level row instance. + $table = JTable::getInstance('Tag', 'TagsTable'); + + $idsArray = explode(',', $pk); + + // Attempt to load the rows into an array. + foreach ($idsArray as $id) + { + try + { + $table->load($id); + + // Check published state. + if ($published = $this->getState('tag.state')) + { + if ($table->published != $published) + { + continue; + } + } + + if (!in_array($table->access, JFactory::getUser()->getAuthorisedViewLevels())) + { + continue; + } + + // Convert the JTable to a clean JObject. + $properties = $table->getProperties(1); + $this->item[] = ArrayHelper::toObject($properties, 'JObject'); + } + catch (RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + } + } + + if (!$this->item) + { + return JError::raiseError(404, JText::_('COM_TAGS_TAG_NOT_FOUND')); + } + + return $this->item; + } + + /** + * Increment the hit counter. + * + * @param integer $pk Optional primary key of the article to increment. + * + * @return boolean True if successful; false otherwise and internal error set. + * + * @since 3.2 + */ + public function hit($pk = 0) + { + $input = JFactory::getApplication()->input; + $hitcount = $input->getInt('hitcount', 1); + + if ($hitcount) + { + $pk = (!empty($pk)) ? $pk : (int) $this->getState('tag.id'); + $table = JTable::getInstance('Tag', 'TagsTable'); + $table->hit($pk); + + // Load the table data for later + $table->load($pk); + + if (!$table->hasPrimaryKey()) + { + JError::raiseError(404, JText::_('COM_TAGS_TAG_NOT_FOUND')); + } + } + + return true; + } +} diff --git a/Sites/pages/components/com_tags/models/tags.php b/Sites/pages/components/com_tags/models/tags.php new file mode 100644 index 00000000..a0e38204 --- /dev/null +++ b/Sites/pages/components/com_tags/models/tags.php @@ -0,0 +1,165 @@ +input->getInt('parent_id'); + $this->setState('tag.parent_id', $pid); + + $language = $app->input->getString('tag_list_language_filter'); + $this->setState('tag.language', $language); + + $offset = $app->input->get('limitstart', 0, 'uint'); + $this->setState('list.offset', $offset); + $app = JFactory::getApplication(); + + $params = $app->getParams(); + $this->setState('params', $params); + + $this->setState('list.limit', $params->get('maximum', 200)); + + $this->setState('filter.published', 1); + $this->setState('filter.access', true); + + $user = JFactory::getUser(); + + if ((!$user->authorise('core.edit.state', 'com_tags')) && (!$user->authorise('core.edit', 'com_tags'))) + { + $this->setState('filter.published', 1); + } + + // Optional filter text + $itemid = $pid . ':' . $app->input->getInt('Itemid', 0); + $filterSearch = $app->getUserStateFromRequest('com_tags.tags.list.' . $itemid . '.filter_search', 'filter-search', '', 'string'); + $this->setState('list.filter', $filterSearch); + } + + /** + * Method to build an SQL query to load the list data. + * + * @return string An SQL query + * + * @since 1.6 + */ + protected function getListQuery() + { + $app = JFactory::getApplication('site'); + $user = JFactory::getUser(); + $groups = implode(',', $user->getAuthorisedViewLevels()); + $pid = $this->getState('tag.parent_id'); + $orderby = $this->state->params->get('all_tags_orderby', 'title'); + $published = $this->state->params->get('published', 1); + $orderDirection = $this->state->params->get('all_tags_orderby_direction', 'ASC'); + $language = $this->getState('tag.language'); + + // Create a new query object. + $db = $this->getDbo(); + $query = $db->getQuery(true); + + // Select required fields from the tags. + $query->select('a.*, u.name as created_by_user_name, u.email') + ->from($db->quoteName('#__tags') . ' AS a') + ->join('LEFT', '#__users AS u ON a.created_user_id = u.id') + ->where($db->quoteName('a.access') . ' IN (' . $groups . ')'); + + if (!empty($pid)) + { + $query->where($db->quoteName('a.parent_id') . ' = ' . $pid); + } + + // Exclude the root. + $query->where($db->quoteName('a.parent_id') . ' <> 0'); + + // Optionally filter on language + if (empty($language)) + { + $language = JComponentHelper::getParams('com_tags')->get('tag_list_language_filter', 'all'); + } + + if ($language !== 'all') + { + if ($language === 'current_language') + { + $language = JHelperContent::getCurrentLanguage(); + } + + $query->where($db->quoteName('language') . ' IN (' . $db->quote($language) . ', ' . $db->quote('*') . ')'); + } + + // List state information + $format = $app->input->getWord('format'); + + if ($format === 'feed') + { + $limit = $app->get('feed_limit'); + } + else + { + if ($this->state->params->get('show_pagination_limit')) + { + $limit = $app->getUserStateFromRequest('global.list.limit', 'limit', $app->get('list_limit'), 'uint'); + } + else + { + $limit = $this->state->params->get('maximum', 20); + } + } + + $this->setState('list.limit', $limit); + + $offset = $app->input->get('limitstart', 0, 'uint'); + $this->setState('list.start', $offset); + + // Optionally filter on entered value + if ($this->state->get('list.filter')) + { + $query->where($db->quoteName('a.title') . ' LIKE ' . $db->quote('%' . $this->state->get('list.filter') . '%')); + } + + $query->where($db->quoteName('a.published') . ' = ' . $published); + + $query->order($db->quoteName($orderby) . ' ' . $orderDirection . ', a.title ASC'); + + return $query; + } +} diff --git a/Sites/pages/components/com_tags/router.php b/Sites/pages/components/com_tags/router.php new file mode 100644 index 00000000..d42e8000 --- /dev/null +++ b/Sites/pages/components/com_tags/router.php @@ -0,0 +1,220 @@ +menu->getActive(); + } + else + { + $menuItem = $this->menu->getItem($query['Itemid']); + } + + $mView = empty($menuItem->query['view']) ? null : $menuItem->query['view']; + $mId = empty($menuItem->query['id']) ? null : $menuItem->query['id']; + + if (is_array($mId)) + { + $mId = ArrayHelper::toInteger($mId); + } + + $view = ''; + + if (isset($query['view'])) + { + $view = $query['view']; + + if (empty($query['Itemid'])) + { + $segments[] = $view; + } + + unset($query['view']); + } + + // Are we dealing with a tag that is attached to a menu item? + if ($mView == $view && isset($query['id']) && $mId == $query['id']) + { + unset($query['id']); + + return $segments; + } + + if ($view === 'tag') + { + $notActiveTag = is_array($mId) ? (count($mId) > 1 || $mId[0] != (int) $query['id']) : ($mId != (int) $query['id']); + + if ($notActiveTag || $mView != $view) + { + // ID in com_tags can be either an integer, a string or an array of IDs + $id = is_array($query['id']) ? implode(',', $query['id']) : $query['id']; + $segments[] = $id; + } + + unset($query['id']); + } + + if (isset($query['layout'])) + { + if ((!empty($query['Itemid']) && isset($menuItem->query['layout']) + && $query['layout'] == $menuItem->query['layout']) + || $query['layout'] === 'default') + { + unset($query['layout']); + } + } + + $total = count($segments); + + for ($i = 0; $i < $total; $i++) + { + $segments[$i] = str_replace(':', '-', $segments[$i]); + $position = strpos($segments[$i], '-'); + + if ($position) + { + // Remove id from segment + $segments[$i] = substr($segments[$i], $position + 1); + } + } + + return $segments; + } + + /** + * Parse the segments of a URL. + * + * @param array &$segments The segments of the URL to parse. + * + * @return array The URL attributes to be used by the application. + * + * @since 3.3 + */ + public function parse(&$segments) + { + $total = count($segments); + $vars = array(); + + for ($i = 0; $i < $total; $i++) + { + $segments[$i] = preg_replace('/-/', ':', $segments[$i], 1); + } + + // Get the active menu item. + $item = $this->menu->getActive(); + + // Count route segments + $count = count($segments); + + // Standard routing for tags. + if (!isset($item)) + { + $vars['view'] = $segments[0]; + $vars['id'] = $this->fixSegment($segments[$count - 1]); + + return $vars; + } + + $vars['id'] = $this->fixSegment($segments[0]); + $vars['view'] = 'tag'; + + return $vars; + } + + /** + * Try to add missing id to segment + * + * @param string $segment One piece of segment of the URL to parse + * + * @return string The segment with founded id + * + * @since 3.7 + */ + protected function fixSegment($segment) + { + $db = JFactory::getDbo(); + + // Try to find tag id + $alias = str_replace(':', '-', $segment); + + $query = $db->getQuery(true) + ->select('id') + ->from($db->quoteName('#__tags')) + ->where($db->quoteName('alias') . " = " . $db->quote($alias)); + + $id = $db->setQuery($query)->loadResult(); + + if ($id) + { + $segment = "$id:$alias"; + } + + return $segment; + } +} + +/** + * Tags router functions. These functions are proxys for the new router interface or old SEF extensions. + * + * @param array &$query An array of URL arguments. + * + * @return array + * + * @deprecated 4.0 Use Class based routers instead + */ +function tagsBuildRoute(&$query) +{ + $router = new TagsRouter; + + return $router->build($query); +} + +/** + * Parse the segments of a URL. These functions are proxys for the new router interface or old SEF extensions. + * + * @param array $segments The segments of the URL to parse. + * + * @return array The URL attributes to be used by the application. + * + * @deprecated 4.0 Use Class based routers instead + */ +function tagsParseRoute($segments) +{ + $router = new TagsRouter; + + return $router->parse($segments); +} diff --git a/Sites/pages/components/com_tags/tags.php b/Sites/pages/components/com_tags/tags.php new file mode 100644 index 00000000..4e90341e --- /dev/null +++ b/Sites/pages/components/com_tags/tags.php @@ -0,0 +1,16 @@ +execute(JFactory::getApplication()->input->get('task')); +$controller->redirect(); diff --git a/Sites/pages/components/com_tags/views/tag/tmpl/default.php b/Sites/pages/components/com_tags/views/tag/tmpl/default.php new file mode 100644 index 00000000..c709309d --- /dev/null +++ b/Sites/pages/components/com_tags/views/tag/tmpl/default.php @@ -0,0 +1,61 @@ +item) === 1; + +?> +
        + params->get('show_page_heading')) : ?> +

        + escape($this->params->get('page_heading')); ?> +

        + + params->get('show_tag_title', 1)) : ?> +

        + tags_title, '', 'com_tag.tag'); ?> +

        + + + item) === 1 && ($this->params->get('tag_list_show_tag_image', 1) || $this->params->get('tag_list_show_tag_description', 1))) : ?> +
        + item[0]->images); ?> + params->get('tag_list_show_tag_image', 1) == 1 && !empty($images->image_fulltext)) : ?> + <?php echo htmlspecialchars($images->image_fulltext_alt, ENT_QUOTES, 'UTF-8'); ?> + + params->get('tag_list_show_tag_description') == 1 && $this->item[0]->description) : ?> + item[0]->description, '', 'com_tags.tag'); ?> + +
        +
        + + + params->get('tag_list_show_tag_description', 1) || $this->params->get('show_description_image', 1)) : ?> + params->get('show_description_image', 1) == 1 && $this->params->get('tag_list_image')) : ?> + + + params->get('tag_list_description', '') > '') : ?> + params->get('tag_list_description'), '', 'com_tags.tag'); ?> + + + loadTemplate('items'); ?> + params->def('show_pagination', 1) == 1 || ($this->params->get('show_pagination') == 2)) && ($this->pagination->get('pages.total') > 1)) : ?> + + +
        diff --git a/Sites/pages/components/com_tags/views/tag/tmpl/default.xml b/Sites/pages/components/com_tags/views/tag/tmpl/default.xml new file mode 100644 index 00000000..611516ad --- /dev/null +++ b/Sites/pages/components/com_tags/views/tag/tmpl/default.xml @@ -0,0 +1,275 @@ + + + + + + + + + + + +
        + + + + + + + + + + +
        +
        + + + +
        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + +
        + + + + + + + + + + + + + + + + + + + +
        + +
        + + + + + + + + + + + + + + + + + +
        + +
        + + + + + + + + + + + +
        + +
        + + + + + + +
        +
        +
        diff --git a/Sites/pages/components/com_tags/views/tag/tmpl/default_items.php b/Sites/pages/components/com_tags/views/tag/tmpl/default_items.php new file mode 100644 index 00000000..9fc790a3 --- /dev/null +++ b/Sites/pages/components/com_tags/views/tag/tmpl/default_items.php @@ -0,0 +1,105 @@ +authorise('core.edit', 'com_tags'); +$canCreate = $user->authorise('core.create', 'com_tags'); +$canEditState = $user->authorise('core.edit.state', 'com_tags'); + +JFactory::getDocument()->addScriptDeclaration(" + var resetFilter = function() { + document.getElementById('filter-search').value = ''; + } +"); + +?> +
        + params->get('show_headings') || $this->params->get('filter_field') || $this->params->get('show_pagination_limit')) : ?> +
        + params->get('filter_field')) : ?> +
        + + + + +
        + + params->get('show_pagination_limit')) : ?> +
        + + pagination->getLimitBox(); ?> +
        + + + + + +
        +
        + + items)) : ?> +

        + +
          + items as $i => $item) : ?> + core_state == 0) : ?> +
        • + +
        • + + type_alias === 'com_users.category') || ($item->type_alias === 'com_banners.category')) : ?> +

          + escape($item->core_title); ?> +

          + +

          + + escape($item->core_title); ?> + +

          + + + event->afterDisplayTitle; ?> + core_images); ?> + params->get('tag_list_show_item_image', 1) == 1 && !empty($images->image_intro)) : ?> + + <?php echo htmlspecialchars($images->image_intro_alt); ?> + + + params->get('tag_list_show_item_description', 1)) : ?> + + event->beforeDisplayContent; ?> + + core_body, $this->params->get('tag_list_item_maximum_characters')); ?> + + + event->afterDisplayContent; ?> + +
        • + +
        + +
        diff --git a/Sites/pages/components/com_tags/views/tag/tmpl/list.php b/Sites/pages/components/com_tags/views/tag/tmpl/list.php new file mode 100644 index 00000000..3da445d5 --- /dev/null +++ b/Sites/pages/components/com_tags/views/tag/tmpl/list.php @@ -0,0 +1,52 @@ +items); + +?> +
        + params->get('show_page_heading')) : ?> +

        + escape($this->params->get('page_heading')); ?> +

        + + params->get('show_tag_title', 1)) : ?> +

        + tags_title, '', 'com_tag.tag'); ?> +

        + + + item) === 1 && ($this->params->get('tag_list_show_tag_image', 1) || $this->params->get('tag_list_show_tag_description', 1))) : ?> +
        + item[0]->images); ?> + params->get('tag_list_show_tag_image', 1) == 1 && !empty($images->image_fulltext)) : ?> + + + params->get('tag_list_show_tag_description') == 1 && $this->item[0]->description) : ?> + item[0]->description, '', 'com_tags.tag'); ?> + +
        +
        + + + params->get('tag_list_show_tag_description', 1) || $this->params->get('show_description_image', 1)) : ?> + params->get('show_description_image', 1) == 1 && $this->params->get('tag_list_image')) : ?> + + + params->get('tag_list_description', '') > '') : ?> + params->get('tag_list_description'), '', 'com_tags.tag'); ?> + + + loadTemplate('items'); ?> +
        diff --git a/Sites/pages/components/com_tags/views/tag/tmpl/list.xml b/Sites/pages/components/com_tags/views/tag/tmpl/list.xml new file mode 100644 index 00000000..5176042b --- /dev/null +++ b/Sites/pages/components/com_tags/views/tag/tmpl/list.xml @@ -0,0 +1,312 @@ + + + + + + + + + + + +
        + + + + + + + + + + +
        +
        + + +
        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + +
        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + +
        + + + + + + + + + + + +
        + +
        + + + + + + +
        +
        +
        diff --git a/Sites/pages/components/com_tags/views/tag/tmpl/list_items.php b/Sites/pages/components/com_tags/views/tag/tmpl/list_items.php new file mode 100644 index 00000000..f96bf694 --- /dev/null +++ b/Sites/pages/components/com_tags/views/tag/tmpl/list_items.php @@ -0,0 +1,123 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); + +JFactory::getDocument()->addScriptDeclaration(" + var resetFilter = function() { + document.getElementById('filter-search').value = ''; + } +"); + +?> +
        + params->get('filter_field') || $this->params->get('show_pagination_limit')) : ?> +
        + params->get('filter_field')) : ?> +
        + + + + +
        + + params->get('show_pagination_limit')) : ?> +
        + + pagination->getLimitBox(); ?> +
        + + + + + +
        +
        + + items)) : ?> +

        + + + params->get('show_headings')) : ?> + + + + params->get('tag_list_show_date')) : ?> + + + + + + + items as $i => $item) : ?> + core_state == 0) : ?> + + + + + + params->get('tag_list_show_date')) : ?> + + + + + +
        + + + + + + + + + +
        params->get('show_headings')) echo "headers=\"categorylist_header_title\""; ?> class="list-title"> + + escape($item->core_title); ?> + + core_state == 0) : ?> + + + + + + displayDate, + $this->escape($this->params->get('date_format', JText::_('DATE_FORMAT_LC3'))) + ); ?> +
        + + params->def('show_pagination', 2) == 1 || ($this->params->get('show_pagination') == 2)) && ($this->pagination->pagesTotal > 1)) : ?> + + + +
        diff --git a/Sites/pages/components/com_tags/views/tag/view.feed.php b/Sites/pages/components/com_tags/views/tag/view.feed.php new file mode 100644 index 00000000..8aa641ef --- /dev/null +++ b/Sites/pages/components/com_tags/views/tag/view.feed.php @@ -0,0 +1,99 @@ +input->get('id', array(), 'array'); + $i = 0; + $tagIds = ''; + $filter = new JFilterInput; + + foreach ($ids as $id) + { + if ($i !== 0) + { + $tagIds .= '&'; + } + + $tagIds .= 'id[' . $i . ']=' . $filter->clean($id, 'INT'); + + $i++; + } + + $document->link = JRoute::_('index.php?option=com_tags&view=tag&' . $tagIds); + + $app->input->set('limit', $app->get('feed_limit')); + $siteEmail = $app->get('mailfrom'); + $fromName = $app->get('fromname'); + $feedEmail = $app->get('feed_email', 'none'); + $document->editor = $fromName; + + if ($feedEmail !== 'none') + { + $document->editorEmail = $siteEmail; + } + + // Get some data from the model + $items = $this->get('Items'); + + if ($items !== false) + { + foreach ($items as $item) + { + // Strip HTML from feed item title + $title = $this->escape($item->core_title); + $title = html_entity_decode($title, ENT_COMPAT, 'UTF-8'); + + // Strip HTML from feed item description text + $description = $item->core_body; + $author = $item->core_created_by_alias ?: $item->author; + $date = ($item->displayDate ? date('r', strtotime($item->displayDate)) : ''); + + // Load individual item creator class + $feeditem = new JFeedItem; + $feeditem->title = $title; + $feeditem->link = JRoute::_($item->link); + $feeditem->description = $description; + $feeditem->date = $date; + $feeditem->category = $title; + $feeditem->author = $author; + + if ($feedEmail === 'site') + { + $item->authorEmail = $siteEmail; + } + elseif ($feedEmail === 'author') + { + $item->authorEmail = $item->author_email; + } + + // Loads item info into RSS array + $document->addItem($feeditem); + } + } + } +} diff --git a/Sites/pages/components/com_tags/views/tag/view.html.php b/Sites/pages/components/com_tags/views/tag/view.html.php new file mode 100644 index 00000000..e7f96afd --- /dev/null +++ b/Sites/pages/components/com_tags/views/tag/view.html.php @@ -0,0 +1,370 @@ +getParams(); + + // Get some data from the models + $state = $this->get('State'); + $items = $this->get('Items'); + $item = $this->get('Item'); + $children = $this->get('Children'); + $parent = $this->get('Parent'); + $pagination = $this->get('Pagination'); + + // Flag indicates to not add limitstart=0 to URL + $pagination->hideEmptyLimitstart = true; + + // Check whether access level allows access. + // @TODO: Should already be computed in $item->params->get('access-view') + $user = JFactory::getUser(); + $groups = $user->getAuthorisedViewLevels(); + + foreach ($item as $itemElement) + { + if (!in_array($itemElement->access, $groups)) + { + unset($itemElement); + } + + // Prepare the data. + if (!empty($itemElement)) + { + $temp = new Registry($itemElement->params); + $itemElement->params = clone $params; + $itemElement->params->merge($temp); + $itemElement->params = (array) json_decode($itemElement->params); + $itemElement->metadata = new Registry($itemElement->metadata); + } + } + + if ($items !== false) + { + JPluginHelper::importPlugin('content'); + + foreach ($items as $itemElement) + { + $itemElement->event = new stdClass; + + // For some plugins. + !empty($itemElement->core_body) ? $itemElement->text = $itemElement->core_body : $itemElement->text = null; + + $itemElement->core_params = new Registry($itemElement->core_params); + + $dispatcher = JEventDispatcher::getInstance(); + + $dispatcher->trigger('onContentPrepare', array ('com_tags.tag', &$itemElement, &$itemElement->core_params, 0)); + + $results = $dispatcher->trigger('onContentAfterTitle', array('com_tags.tag', &$itemElement, &$itemElement->core_params, 0)); + $itemElement->event->afterDisplayTitle = trim(implode("\n", $results)); + + $results = $dispatcher->trigger('onContentBeforeDisplay', array('com_tags.tag', &$itemElement, &$itemElement->core_params, 0)); + $itemElement->event->beforeDisplayContent = trim(implode("\n", $results)); + + $results = $dispatcher->trigger('onContentAfterDisplay', array('com_tags.tag', &$itemElement, &$itemElement->core_params, 0)); + $itemElement->event->afterDisplayContent = trim(implode("\n", $results)); + + // Write the results back into the body + if (!empty($itemElement->core_body)) + { + $itemElement->core_body = $itemElement->text; + } + + // Categories store the images differently so lets re-map it so the display is correct + if ($itemElement->type_alias === 'com_content.category') + { + $itemElement->core_images = json_encode( + array( + 'image_intro' => $itemElement->core_params->get('image', ''), + 'image_intro_alt' => $itemElement->core_params->get('image_alt', '') + ) + ); + } + } + } + + $this->state = $state; + $this->items = $items; + $this->children = $children; + $this->parent = $parent; + $this->pagination = $pagination; + $this->user = $user; + $this->item = $item; + + // Escape strings for HTML output + $this->pageclass_sfx = htmlspecialchars($params->get('pageclass_sfx')); + + // Merge tag params. If this is single-tag view, menu params override tag params + // Otherwise, article params override menu item params + $this->params = $this->state->get('params'); + $active = $app->getMenu()->getActive(); + $temp = clone $this->params; + + // Convert item params to a Registry object + $item[0]->params = new Registry($item[0]->params); + + // Check to see which parameters should take priority + if ($active) + { + $currentLink = $active->link; + + // If the current view is the active item and a tag view for one tag, then the menu item params take priority + if (strpos($currentLink, 'view=tag') && strpos($currentLink, '&id[0]=' . (string) $item[0]->id)) + { + // $item[0]->params are the tag params, $temp are the menu item params + // Merge so that the menu item params take priority + $item[0]->params->merge($temp); + + // Load layout from active query (in case it is an alternative menu item) + if (isset($active->query['layout'])) + { + $this->setLayout($active->query['layout']); + } + } + else + { + // Current menuitem is not a single tag view, so the tag params take priority. + // Merge the menu item params with the tag params so that the tag params take priority + $temp->merge($item[0]->params); + $item[0]->params = $temp; + + // Check for alternative layouts (since we are not in a single-article menu item) + // Single-article menu item layout takes priority over alt layout for an article + if ($layout = $item[0]->params->get('tag_layout')) + { + $this->setLayout($layout); + } + } + } + else + { + // Merge so that item params take priority + $temp->merge($item[0]->params); + $item[0]->params = $temp; + + // Check for alternative layouts (since we are not in a single-tag menu item) + // Single-tag menu item layout takes priority over alt layout for an article + if ($layout = $item[0]->params->get('tag_layout')) + { + $this->setLayout($layout); + } + } + + // Increment the hit counter + $model = $this->getModel(); + $model->hit(); + + $this->_prepareDocument(); + + parent::display($tpl); + } + + /** + * Prepares the document. + * + * @return void + */ + protected function _prepareDocument() + { + $app = JFactory::getApplication(); + $menu = $app->getMenu()->getActive(); + $this->tags_title = $this->getTagsTitle(); + $pathway = $app->getPathway(); + $title = ''; + + // Highest priority for "Browser Page Title". + if ($menu) + { + $title = $menu->params->get('page_title', ''); + } + + if ($this->tags_title) + { + $this->params->def('page_heading', $this->tags_title); + $title = $title ?: $this->tags_title; + } + elseif ($menu) + { + $this->params->def('page_heading', $this->params->get('page_title', $menu->title)); + $title = $title ?: $this->params->get('page_title', $menu->title); + + if (!isset($menu->query['option']) || $menu->query['option'] !== 'com_tags') + { + $this->params->set('page_subheading', $menu->title); + } + } + + if (empty($title)) + { + $title = $app->get('sitename'); + } + elseif ($app->get('sitename_pagetitles', 0) == 1) + { + $title = JText::sprintf('JPAGETITLE', $app->get('sitename'), $title); + } + elseif ($app->get('sitename_pagetitles', 0) == 2) + { + $title = JText::sprintf('JPAGETITLE', $title, $app->get('sitename')); + } + + $this->document->setTitle($title); + + $pathway->addItem($title); + + foreach ($this->item as $itemElement) + { + if ($itemElement->metadesc) + { + $this->document->setDescription($itemElement->metadesc); + } + elseif ($this->params->get('menu-meta_description')) + { + $this->document->setDescription($this->params->get('menu-meta_description')); + } + + if ($itemElement->metakey) + { + $this->document->setMetadata('keywords', $itemElement->metakey); + } + elseif ($this->params->get('menu-meta_keywords')) + { + $this->document->setMetadata('keywords', $this->params->get('menu-meta_keywords')); + } + + if ($this->params->get('robots')) + { + $this->document->setMetadata('robots', $this->params->get('robots')); + } + } + + if (count($this->item) === 1) + { + foreach ($this->item[0]->metadata->toArray() as $k => $v) + { + if ($v) + { + $this->document->setMetadata($k, $v); + } + } + } + + if ($this->params->get('show_feed_link', 1) == 1) + { + $link = '&format=feed&limitstart='; + $attribs = array('type' => 'application/rss+xml', 'title' => 'RSS 2.0'); + $this->document->addHeadLink(JRoute::_($link . '&type=rss'), 'alternate', 'rel', $attribs); + $attribs = array('type' => 'application/atom+xml', 'title' => 'Atom 1.0'); + $this->document->addHeadLink(JRoute::_($link . '&type=atom'), 'alternate', 'rel', $attribs); + } + } + + /** + * Creates the tags title for the output + * + * @return boolean + */ + protected function getTagsTitle() + { + $tags_title = array(); + + if (!empty($this->item)) + { + $user = JFactory::getUser(); + $groups = $user->getAuthorisedViewLevels(); + + foreach ($this->item as $item) + { + if (in_array($item->access, $groups)) + { + $tags_title[] = $item->title; + } + } + } + + return implode(' ', $tags_title); + } +} diff --git a/Sites/pages/components/com_tags/views/tags/tmpl/default.php b/Sites/pages/components/com_tags/views/tags/tmpl/default.php new file mode 100644 index 00000000..23d36d93 --- /dev/null +++ b/Sites/pages/components/com_tags/views/tags/tmpl/default.php @@ -0,0 +1,36 @@ +params->get('all_tags_description'); +$descriptionImage = $this->params->get('all_tags_description_image'); + +?> +
        + params->get('show_page_heading')) : ?> +

        + escape($this->params->get('page_heading')); ?> +

        + + params->get('all_tags_show_description_image') && !empty($descriptionImage)) : ?> +
        + +
        + + +
        + +
        + + loadTemplate('items'); ?> +
        diff --git a/Sites/pages/components/com_tags/views/tags/tmpl/default.xml b/Sites/pages/components/com_tags/views/tags/tmpl/default.xml new file mode 100644 index 00000000..34f7880c --- /dev/null +++ b/Sites/pages/components/com_tags/views/tags/tmpl/default.xml @@ -0,0 +1,232 @@ + + + + + + + + + + +
        + + + + + + + + + + + +
        +
        + + +
        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        +
        + + + + + + + + + + + + + + + + + + + + + + + + +
        +
        + + + + + +
        +
        +
        diff --git a/Sites/pages/components/com_tags/views/tags/tmpl/default_items.php b/Sites/pages/components/com_tags/views/tags/tmpl/default_items.php new file mode 100644 index 00000000..095d0ba5 --- /dev/null +++ b/Sites/pages/components/com_tags/views/tags/tmpl/default_items.php @@ -0,0 +1,146 @@ +authorise('core.edit', 'com_tags'); +$canCreate = $user->authorise('core.create', 'com_tags'); +$canEditState = $user->authorise('core.edit.state', 'com_tags'); + +$columns = $this->params->get('tag_columns', 1); + +// Avoid division by 0 and negative columns. +if ($columns < 1) +{ + $columns = 1; +} + +$bsspans = floor(12 / $columns); + +if ($bsspans < 1) +{ + $bsspans = 1; +} + +$bscolumns = min($columns, floor(12 / $bsspans)); +$n = count($this->items); + +JFactory::getDocument()->addScriptDeclaration(" + var resetFilter = function() { + document.getElementById('filter-search').value = ''; + } +"); + +?> +
        + params->get('filter_field') || $this->params->get('show_pagination_limit')) : ?> +
        + params->get('filter_field')) : ?> +
        + + + + +
        + + params->get('show_pagination_limit')) : ?> +
        + + pagination->getLimitBox(); ?> +
        + + + + + +
        +
        + + items == false || $n === 0) : ?> +

        + + items as $i => $item) : ?> + +
          + + access)) && in_array($item->access, $this->user->getAuthorisedViewLevels())) : ?> +
        • +

          + + escape($item->title); ?> + +

          + + params->get('all_tags_show_tag_image') && !empty($item->images)) : ?> + images); ?> + + image_intro)) : ?> + float_intro) ? $this->params->get('float_intro') : $images->float_intro; ?> +
          + image_intro_caption) : ?> + image_intro_caption, ENT_QUOTES, 'UTF-8') . '"'; ?> + + src="image_intro, ENT_QUOTES, 'UTF-8'); ?>" + alt="image_intro_alt, ENT_QUOTES, 'UTF-8'); ?>" /> +
          + +
          + + params->get('all_tags_show_tag_description', 1) && !empty($item->description)) || $this->params->get('all_tags_show_tag_hits')) : ?> +
          + params->get('all_tags_show_tag_description', 1) && !empty($item->description)) : ?> + + description, $this->params->get('all_tags_tag_maximum_characters')); ?> + + + params->get('all_tags_show_tag_hits')) : ?> + + hits); ?> + + +
          + +
        • + +
        + + + + + items)) : ?> + params->def('show_pagination', 2) == 1 || ($this->params->get('show_pagination') == 2)) && ($this->pagination->pagesTotal > 1)) : ?> + + + +
        diff --git a/Sites/pages/components/com_tags/views/tags/view.feed.php b/Sites/pages/components/com_tags/views/tags/view.feed.php new file mode 100644 index 00000000..f9f01a14 --- /dev/null +++ b/Sites/pages/components/com_tags/views/tags/view.feed.php @@ -0,0 +1,80 @@ +link = JRoute::_('index.php?option=com_tags&view=tags'); + + $app->input->set('limit', $app->get('feed_limit')); + $siteEmail = $app->get('mailfrom'); + $fromName = $app->get('fromname'); + $feedEmail = $app->get('feed_email', 'none'); + $document->editor = $fromName; + + if ($feedEmail !== 'none') + { + $document->editorEmail = $siteEmail; + } + + // Get some data from the model + $items = $this->get('Items'); + + foreach ($items as $item) + { + // Strip HTML from feed item title + $title = $this->escape($item->title); + $title = html_entity_decode($title, ENT_COMPAT, 'UTF-8'); + + // Strip HTML from feed item description text + $description = $item->description; + $author = $item->created_by_alias ?: $item->created_by_user_name; + $date = $item->created_time ? date('r', strtotime($item->created_time)) : ''; + + // Load individual item creator class + $feeditem = new JFeedItem; + $feeditem->title = $title; + $feeditem->link = '/index.php?option=com_tags&view=tag&id=' . (int) $item->id; + $feeditem->description = $description; + $feeditem->date = $date; + $feeditem->category = 'All Tags'; + $feeditem->author = $author; + + if ($feedEmail === 'site') + { + $feeditem->authorEmail = $siteEmail; + } + + if ($feedEmail === 'author') + { + $feeditem->authorEmail = $item->email; + } + + // Loads item info into RSS array + $document->addItem($feeditem); + } + } +} diff --git a/Sites/pages/components/com_tags/views/tags/view.html.php b/Sites/pages/components/com_tags/views/tags/view.html.php new file mode 100644 index 00000000..f276452d --- /dev/null +++ b/Sites/pages/components/com_tags/views/tags/view.html.php @@ -0,0 +1,252 @@ +state = $this->get('State'); + $this->items = $this->get('Items'); + $this->pagination = $this->get('Pagination'); + $this->params = $this->state->get('params'); + $this->user = JFactory::getUser(); + + // Flag indicates to not add limitstart=0 to URL + $this->pagination->hideEmptyLimitstart = true; + + /* + * // Change to catch + * if (count($errors = $this->get('Errors'))) { + * JError::raiseError(500, implode("\n", $errors)); + * return false; + */ + + // Check whether access level allows access. + // @todo: Should already be computed in $item->params->get('access-view') + $groups = $this->user->getAuthorisedViewLevels(); + + if (!empty($this->items)) + { + foreach ($this->items as $itemElement) + { + if (!in_array($itemElement->access, $groups)) + { + unset($itemElement); + } + + // Prepare the data. + $temp = new Registry($itemElement->params); + $itemElement->params = clone $this->params; + $itemElement->params->merge($temp); + $itemElement->params = (array) json_decode($itemElement->params); + } + } + + // Escape strings for HTML output + $this->pageclass_sfx = htmlspecialchars($this->params->get('pageclass_sfx')); + + $active = JFactory::getApplication()->getMenu()->getActive(); + + // Load layout from active query (in case it is an alternative menu item) + if ($active && isset($active->query['option']) && $active->query['option'] === 'com_tags' && $active->query['view'] === 'tags') + { + if (isset($active->query['layout'])) + { + $this->setLayout($active->query['layout']); + } + } + else + { + // Load default All Tags layout from component + if ($layout = $this->params->get('tags_layout')) + { + $this->setLayout($layout); + } + } + + $this->_prepareDocument(); + + parent::display($tpl); + } + + /** + * Prepares the document + * + * @return void + */ + protected function _prepareDocument() + { + $app = JFactory::getApplication(); + $menus = $app->getMenu(); + $title = null; + + // Because the application sets a default page title, + // we need to get it from the menu item itself + $menu = $menus->getActive(); + + if ($menu) + { + $this->params->def('page_heading', $this->params->get('page_title', $menu->title)); + } + else + { + $this->params->def('page_heading', JText::_('COM_TAGS_DEFAULT_PAGE_TITLE')); + } + + if ($menu && (!isset($menu->query['option']) || $menu->query['option'] !== 'com_tags')) + { + $this->params->set('page_subheading', $menu->title); + } + + // Set metadata for all tags menu item + if ($this->params->get('menu-meta_description')) + { + $this->document->setDescription($this->params->get('menu-meta_description')); + } + + if ($this->params->get('menu-meta_keywords')) + { + $this->document->setMetadata('keywords', $this->params->get('menu-meta_keywords')); + } + + if ($this->params->get('robots')) + { + $this->document->setMetadata('robots', $this->params->get('robots')); + } + + // If this is not a single tag menu item, set the page title to the tag titles + $title = ''; + + if (!empty($this->item)) + { + foreach ($this->item as $i => $itemElement) + { + if ($itemElement->title) + { + if ($i != 0) + { + $title .= ', '; + } + + $title .= $itemElement->title; + } + } + + if (empty($title)) + { + $title = $app->get('sitename'); + } + elseif ($app->get('sitename_pagetitles', 0) == 1) + { + $title = JText::sprintf('JPAGETITLE', $app->get('sitename'), $title); + } + elseif ($app->get('sitename_pagetitles', 0) == 2) + { + $title = JText::sprintf('JPAGETITLE', $title, $app->get('sitename')); + } + + $this->document->setTitle($title); + + foreach ($this->item as $itemElement) + { + if ($itemElement->metadesc) + { + $this->document->setDescription($this->item->metadesc); + } + elseif ($this->params->get('menu-meta_description')) + { + $this->document->setDescription($this->params->get('menu-meta_description')); + } + + if ($itemElement->metakey) + { + $this->document->setMetadata('keywords', $this->tag->metakey); + } + elseif ($this->params->get('menu-meta_keywords')) + { + $this->document->setMetadata('keywords', $this->params->get('menu-meta_keywords')); + } + + if ($this->params->get('robots')) + { + $this->document->setMetadata('robots', $this->params->get('robots')); + } + + if ($app->get('MetaAuthor') == '1') + { + $this->document->setMetaData('author', $itemElement->created_user_id); + } + + $mdata = $this->item->metadata->toArray(); + + foreach ($mdata as $k => $v) + { + if ($v) + { + $this->document->setMetadata($k, $v); + } + } + } + } + + // Respect configuration Sitename Before/After for TITLE in views All Tags. + if (!$title && ($pos = $app->get('sitename_pagetitles', 0))) + { + $title = $this->document->getTitle(); + + if ($pos == 1) + { + $title = JText::sprintf('JPAGETITLE', $app->get('sitename'), $title); + } + else + { + $title = JText::sprintf('JPAGETITLE', $title, $app->get('sitename')); + } + + $this->document->setTitle($title); + } + + // Add alternative feed link + if ($this->params->get('show_feed_link', 1) == 1) + { + $link = '&format=feed&limitstart='; + $attribs = array('type' => 'application/rss+xml', 'title' => 'RSS 2.0'); + $this->document->addHeadLink(JRoute::_($link . '&type=rss'), 'alternate', 'rel', $attribs); + $attribs = array('type' => 'application/atom+xml', 'title' => 'Atom 1.0'); + $this->document->addHeadLink(JRoute::_($link . '&type=atom'), 'alternate', 'rel', $attribs); + } + } +} diff --git a/Sites/pages/components/com_users/controller.php b/Sites/pages/components/com_users/controller.php new file mode 100644 index 00000000..4fb91a89 --- /dev/null +++ b/Sites/pages/components/com_users/controller.php @@ -0,0 +1,142 @@ +input->getCmd('view', 'login'); + $vFormat = $document->getType(); + $lName = $this->input->getCmd('layout', 'default'); + + if ($view = $this->getView($vName, $vFormat)) + { + // Do any specific processing by view. + switch ($vName) + { + case 'registration': + // If the user is already logged in, redirect to the profile page. + $user = JFactory::getUser(); + + if ($user->get('guest') != 1) + { + // Redirect to profile page. + $this->setRedirect(JRoute::_('index.php?option=com_users&view=profile', false)); + + return; + } + + // Check if user registration is enabled + if (JComponentHelper::getParams('com_users')->get('allowUserRegistration') == 0) + { + // Registration is disabled - Redirect to login page. + $this->setRedirect(JRoute::_('index.php?option=com_users&view=login', false)); + + return; + } + + // The user is a guest, load the registration model and show the registration page. + $model = $this->getModel('Registration'); + break; + + // Handle view specific models. + case 'profile': + + // If the user is a guest, redirect to the login page. + $user = JFactory::getUser(); + + if ($user->get('guest') == 1) + { + // Redirect to login page. + $this->setRedirect(JRoute::_('index.php?option=com_users&view=login', false)); + + return; + } + + $model = $this->getModel($vName); + break; + + // Handle the default views. + case 'login': + $model = $this->getModel($vName); + break; + + case 'reset': + // If the user is already logged in, redirect to the profile page. + $user = JFactory::getUser(); + + if ($user->get('guest') != 1) + { + // Redirect to profile page. + $this->setRedirect(JRoute::_('index.php?option=com_users&view=profile', false)); + + return; + } + + $model = $this->getModel($vName); + break; + + case 'remind': + // If the user is already logged in, redirect to the profile page. + $user = JFactory::getUser(); + + if ($user->get('guest') != 1) + { + // Redirect to profile page. + $this->setRedirect(JRoute::_('index.php?option=com_users&view=profile', false)); + + return; + } + + $model = $this->getModel($vName); + break; + + default: + $model = $this->getModel('Login'); + break; + } + + // Make sure we don't send a referer + if (in_array($vName, array('remind', 'reset'))) + { + JFactory::getApplication()->setHeader('Referrer-Policy', 'no-referrer', true); + } + + // Push the model into the view (as default). + $view->setModel($model, true); + $view->setLayout($lName); + + // Push document object into the view. + $view->document = $document; + + $view->display(); + } + } +} diff --git a/Sites/pages/components/com_users/controllers/profile.php b/Sites/pages/components/com_users/controllers/profile.php new file mode 100644 index 00000000..610fc783 --- /dev/null +++ b/Sites/pages/components/com_users/controllers/profile.php @@ -0,0 +1,237 @@ +get('id'); + + // Get the previous user id (if any) and the current user id. + $previousId = (int) $app->getUserState('com_users.edit.profile.id'); + $userId = $this->input->getInt('user_id'); + + // Check if the user is trying to edit another users profile. + if ($userId != $loginUserId) + { + $app->enqueueMessage(JText::_('JERROR_ALERTNOAUTHOR'), 'error'); + $app->setHeader('status', 403, true); + + return false; + } + + $cookieLogin = $user->get('cookieLogin'); + + // Check if the user logged in with a cookie + if (!empty($cookieLogin)) + { + // If so, the user must login to edit the password and other data. + $app->enqueueMessage(JText::_('JGLOBAL_REMEMBER_MUST_LOGIN'), 'message'); + $this->setRedirect(JRoute::_('index.php?option=com_users&view=login', false)); + + return false; + } + + // Set the user id for the user to edit in the session. + $app->setUserState('com_users.edit.profile.id', $userId); + + // Get the model. + $model = $this->getModel('Profile', 'UsersModel'); + + // Check out the user. + if ($userId) + { + $model->checkout($userId); + } + + // Check in the previous user. + if ($previousId) + { + $model->checkin($previousId); + } + + // Redirect to the edit screen. + $this->setRedirect(JRoute::_('index.php?option=com_users&view=profile&layout=edit', false)); + + return true; + } + + /** + * Method to save a user's profile data. + * + * @return void + * + * @since 1.6 + */ + public function save() + { + // Check for request forgeries. + $this->checkToken(); + + $app = JFactory::getApplication(); + $model = $this->getModel('Profile', 'UsersModel'); + $user = JFactory::getUser(); + $userId = (int) $user->get('id'); + + // Get the user data. + $requestData = $app->input->post->get('jform', array(), 'array'); + + // Force the ID to this user. + $requestData['id'] = $userId; + + // Validate the posted data. + $form = $model->getForm(); + + if (!$form) + { + JError::raiseError(500, $model->getError()); + + return false; + } + + // Send an object which can be modified through the plugin event + $objData = (object) $requestData; + $app->triggerEvent( + 'onContentNormaliseRequestData', + array('com_users.user', $objData, $form) + ); + $requestData = (array) $objData; + + // Validate the posted data. + $data = $model->validate($form, $requestData); + + // Check for errors. + if ($data === false) + { + // Get the validation messages. + $errors = $model->getErrors(); + + // Push up to three validation messages out to the user. + for ($i = 0, $n = count($errors); $i < $n && $i < 3; $i++) + { + if ($errors[$i] instanceof Exception) + { + $app->enqueueMessage($errors[$i]->getMessage(), 'warning'); + } + else + { + $app->enqueueMessage($errors[$i], 'warning'); + } + } + + // Unset the passwords. + unset($requestData['password1'], $requestData['password2']); + + // Save the data in the session. + $app->setUserState('com_users.edit.profile.data', $requestData); + + // Redirect back to the edit screen. + $userId = (int) $app->getUserState('com_users.edit.profile.id'); + $this->setRedirect(JRoute::_('index.php?option=com_users&view=profile&layout=edit&user_id=' . $userId, false)); + + return false; + } + + // Attempt to save the data. + $return = $model->save($data); + + // Check for errors. + if ($return === false) + { + // Save the data in the session. + $app->setUserState('com_users.edit.profile.data', $data); + + // Redirect back to the edit screen. + $userId = (int) $app->getUserState('com_users.edit.profile.id'); + $this->setMessage(JText::sprintf('COM_USERS_PROFILE_SAVE_FAILED', $model->getError()), 'warning'); + $this->setRedirect(JRoute::_('index.php?option=com_users&view=profile&layout=edit&user_id=' . $userId, false)); + + return false; + } + + // Redirect the user and adjust session state based on the chosen task. + switch ($this->getTask()) + { + case 'apply': + // Check out the profile. + $app->setUserState('com_users.edit.profile.id', $return); + $model->checkout($return); + + // Redirect back to the edit screen. + $this->setMessage(JText::_('COM_USERS_PROFILE_SAVE_SUCCESS')); + + $redirect = $app->getUserState('com_users.edit.profile.redirect'); + + // Don't redirect to an external URL. + if (!JUri::isInternal($redirect)) + { + $redirect = null; + } + + if (!$redirect) + { + $redirect = 'index.php?option=com_users&view=profile&layout=edit&hidemainmenu=1'; + } + + $this->setRedirect(JRoute::_($redirect, false)); + break; + + default: + // Check in the profile. + $userId = (int) $app->getUserState('com_users.edit.profile.id'); + + if ($userId) + { + $model->checkin($userId); + } + + // Clear the profile id from the session. + $app->setUserState('com_users.edit.profile.id', null); + + $redirect = $app->getUserState('com_users.edit.profile.redirect'); + + // Don't redirect to an external URL. + if (!JUri::isInternal($redirect)) + { + $redirect = null; + } + + if (!$redirect) + { + $redirect = 'index.php?option=com_users&view=profile&user_id=' . $return; + } + + // Redirect to the list screen. + $this->setMessage(JText::_('COM_USERS_PROFILE_SAVE_SUCCESS')); + $this->setRedirect(JRoute::_($redirect, false)); + break; + } + + // Flush the data from the session. + $app->setUserState('com_users.edit.profile.data', null); + } +} diff --git a/Sites/pages/components/com_users/controllers/registration.php b/Sites/pages/components/com_users/controllers/registration.php new file mode 100644 index 00000000..95789af4 --- /dev/null +++ b/Sites/pages/components/com_users/controllers/registration.php @@ -0,0 +1,243 @@ +input; + $uParams = JComponentHelper::getParams('com_users'); + + // Check for admin activation. Don't allow non-super-admin to delete a super admin + if ($uParams->get('useractivation') != 2 && $user->get('id')) + { + $this->setRedirect('index.php'); + + return true; + } + + // If user registration or account activation is disabled, throw a 403. + if ($uParams->get('useractivation') == 0 || $uParams->get('allowUserRegistration') == 0) + { + JError::raiseError(403, JText::_('JLIB_APPLICATION_ERROR_ACCESS_FORBIDDEN')); + + return false; + } + + $model = $this->getModel('Registration', 'UsersModel'); + $token = $input->getAlnum('token'); + + // Check that the token is in a valid format. + if ($token === null || strlen($token) !== 32) + { + JError::raiseError(403, JText::_('JINVALID_TOKEN')); + + return false; + } + + // Get the User ID + $userIdToActivate = $model->getUserIdFromToken($token); + + if (!$userIdToActivate) + { + JError::raiseError(403, JText::_('COM_USERS_ACTIVATION_TOKEN_NOT_FOUND')); + + return false; + } + + // Get the user we want to activate + $userToActivate = JFactory::getUser($userIdToActivate); + + // Admin activation is on and admin is activating the account + if (($uParams->get('useractivation') == 2) && $userToActivate->getParam('activate', 0)) + { + // If a user admin is not logged in, redirect them to the login page with an error message + if (!$user->authorise('core.create', 'com_users') || !$user->authorise('core.manage', 'com_users')) + { + $activationUrl = 'index.php?option=com_users&task=registration.activate&token=' . $token; + $loginUrl = 'index.php?option=com_users&view=login&return=' . base64_encode($activationUrl); + + // In case we still run into this in the second step the user does not have the right permissions + $message = JText::_('COM_USERS_REGISTRATION_ACL_ADMIN_ACTIVATION_PERMISSIONS'); + + // When we are not logged in we should login + if ($user->guest) + { + $message = JText::_('COM_USERS_REGISTRATION_ACL_ADMIN_ACTIVATION'); + } + + $this->setMessage($message); + $this->setRedirect(JRoute::_($loginUrl, false)); + + return false; + } + } + + // Attempt to activate the user. + $return = $model->activate($token); + + // Check for errors. + if ($return === false) + { + // Redirect back to the home page. + $this->setMessage(JText::sprintf('COM_USERS_REGISTRATION_SAVE_FAILED', $model->getError()), 'error'); + $this->setRedirect('index.php'); + + return false; + } + + $useractivation = $uParams->get('useractivation'); + + // Redirect to the login screen. + if ($useractivation == 0) + { + $this->setMessage(JText::_('COM_USERS_REGISTRATION_SAVE_SUCCESS')); + $this->setRedirect(JRoute::_('index.php?option=com_users&view=login', false)); + } + elseif ($useractivation == 1) + { + $this->setMessage(JText::_('COM_USERS_REGISTRATION_ACTIVATE_SUCCESS')); + $this->setRedirect(JRoute::_('index.php?option=com_users&view=login', false)); + } + elseif ($return->getParam('activate')) + { + $this->setMessage(JText::_('COM_USERS_REGISTRATION_VERIFY_SUCCESS')); + $this->setRedirect(JRoute::_('index.php?option=com_users&view=registration&layout=complete', false)); + } + else + { + $this->setMessage(JText::_('COM_USERS_REGISTRATION_ADMINACTIVATE_SUCCESS')); + $this->setRedirect(JRoute::_('index.php?option=com_users&view=registration&layout=complete', false)); + } + + return true; + } + + /** + * Method to register a user. + * + * @return boolean True on success, false on failure. + * + * @since 1.6 + */ + public function register() + { + // Check for request forgeries. + $this->checkToken(); + + // If registration is disabled - Redirect to login page. + if (JComponentHelper::getParams('com_users')->get('allowUserRegistration') == 0) + { + $this->setRedirect(JRoute::_('index.php?option=com_users&view=login', false)); + + return false; + } + + $app = JFactory::getApplication(); + $model = $this->getModel('Registration', 'UsersModel'); + + // Get the user data. + $requestData = $this->input->post->get('jform', array(), 'array'); + + // Validate the posted data. + $form = $model->getForm(); + + if (!$form) + { + JError::raiseError(500, $model->getError()); + + return false; + } + + $data = $model->validate($form, $requestData); + + // Check for validation errors. + if ($data === false) + { + // Get the validation messages. + $errors = $model->getErrors(); + + // Push up to three validation messages out to the user. + for ($i = 0, $n = count($errors); $i < $n && $i < 3; $i++) + { + if ($errors[$i] instanceof Exception) + { + $app->enqueueMessage($errors[$i]->getMessage(), 'error'); + } + else + { + $app->enqueueMessage($errors[$i], 'error'); + } + } + + // Save the data in the session. + $app->setUserState('com_users.registration.data', $requestData); + + // Redirect back to the registration screen. + $this->setRedirect(JRoute::_('index.php?option=com_users&view=registration', false)); + + return false; + } + + // Attempt to save the data. + $return = $model->register($data); + + // Check for errors. + if ($return === false) + { + // Save the data in the session. + $app->setUserState('com_users.registration.data', $data); + + // Redirect back to the edit screen. + $this->setMessage($model->getError(), 'error'); + $this->setRedirect(JRoute::_('index.php?option=com_users&view=registration', false)); + + return false; + } + + // Flush the data from the session. + $app->setUserState('com_users.registration.data', null); + + // Redirect to the profile screen. + if ($return === 'adminactivate') + { + $this->setMessage(JText::_('COM_USERS_REGISTRATION_COMPLETE_VERIFY')); + $this->setRedirect(JRoute::_('index.php?option=com_users&view=registration&layout=complete', false)); + } + elseif ($return === 'useractivate') + { + $this->setMessage(JText::_('COM_USERS_REGISTRATION_COMPLETE_ACTIVATE')); + $this->setRedirect(JRoute::_('index.php?option=com_users&view=registration&layout=complete', false)); + } + else + { + $this->setMessage(JText::_('COM_USERS_REGISTRATION_SAVE_SUCCESS')); + $this->setRedirect(JRoute::_('index.php?option=com_users&view=login', false)); + } + + return true; + } +} diff --git a/Sites/pages/components/com_users/controllers/remind.php b/Sites/pages/components/com_users/controllers/remind.php new file mode 100644 index 00000000..1b1848a5 --- /dev/null +++ b/Sites/pages/components/com_users/controllers/remind.php @@ -0,0 +1,59 @@ +checkToken('post'); + + $model = $this->getModel('Remind', 'UsersModel'); + $data = $this->input->post->get('jform', array(), 'array'); + + // Submit the password reset request. + $return = $model->processRemindRequest($data); + + // Check for a hard error. + if ($return == false) + { + // The request failed. + // Go back to the request form. + $message = JText::sprintf('COM_USERS_REMIND_REQUEST_FAILED', $model->getError()); + $this->setRedirect(JRoute::_('index.php?option=com_users&view=remind', false), $message, 'notice'); + + return false; + } + else + { + // The request succeeded. + // Proceed to step two. + $message = JText::_('COM_USERS_REMIND_REQUEST_SUCCESS'); + $this->setRedirect(JRoute::_('index.php?option=com_users&view=login', false), $message); + + return true; + } + } +} diff --git a/Sites/pages/components/com_users/controllers/reset.php b/Sites/pages/components/com_users/controllers/reset.php new file mode 100644 index 00000000..ab0fde67 --- /dev/null +++ b/Sites/pages/components/com_users/controllers/reset.php @@ -0,0 +1,190 @@ +checkToken('post'); + + $app = JFactory::getApplication(); + $model = $this->getModel('Reset', 'UsersModel'); + $data = $this->input->post->get('jform', array(), 'array'); + + // Submit the password reset request. + $return = $model->processResetRequest($data); + + // Check for a hard error. + if ($return instanceof Exception) + { + // Get the error message to display. + if ($app->get('error_reporting')) + { + $message = $return->getMessage(); + } + else + { + $message = JText::_('COM_USERS_RESET_REQUEST_ERROR'); + } + + // Go back to the request form. + $this->setRedirect(JRoute::_('index.php?option=com_users&view=reset', false), $message, 'error'); + + return false; + } + elseif ($return === false) + { + // The request failed. + // Go back to the request form. + $message = JText::sprintf('COM_USERS_RESET_REQUEST_FAILED', $model->getError()); + $this->setRedirect(JRoute::_('index.php?option=com_users&view=reset', false), $message, 'notice'); + + return false; + } + else + { + // The request succeeded. + // Proceed to step two. + $this->setRedirect(JRoute::_('index.php?option=com_users&view=reset&layout=confirm', false)); + + return true; + } + } + + /** + * Method to confirm the password request. + * + * @return boolean + * + * @access public + * @since 1.6 + */ + public function confirm() + { + // Check the request token. + $this->checkToken('request'); + + $app = JFactory::getApplication(); + $model = $this->getModel('Reset', 'UsersModel'); + $data = $this->input->get('jform', array(), 'array'); + + // Confirm the password reset request. + $return = $model->processResetConfirm($data); + + // Check for a hard error. + if ($return instanceof Exception) + { + // Get the error message to display. + if ($app->get('error_reporting')) + { + $message = $return->getMessage(); + } + else + { + $message = JText::_('COM_USERS_RESET_CONFIRM_ERROR'); + } + + // Go back to the confirm form. + $this->setRedirect(JRoute::_('index.php?option=com_users&view=reset&layout=confirm', false), $message, 'error'); + + return false; + } + elseif ($return === false) + { + // Confirm failed. + // Go back to the confirm form. + $message = JText::sprintf('COM_USERS_RESET_CONFIRM_FAILED', $model->getError()); + $this->setRedirect(JRoute::_('index.php?option=com_users&view=reset&layout=confirm', false), $message, 'notice'); + + return false; + } + else + { + // Confirm succeeded. + // Proceed to step three. + $this->setRedirect(JRoute::_('index.php?option=com_users&view=reset&layout=complete', false)); + + return true; + } + } + + /** + * Method to complete the password reset process. + * + * @return boolean + * + * @since 1.6 + */ + public function complete() + { + // Check for request forgeries + $this->checkToken('post'); + + $app = JFactory::getApplication(); + $model = $this->getModel('Reset', 'UsersModel'); + $data = $this->input->post->get('jform', array(), 'array'); + + // Complete the password reset request. + $return = $model->processResetComplete($data); + + // Check for a hard error. + if ($return instanceof Exception) + { + // Get the error message to display. + if ($app->get('error_reporting')) + { + $message = $return->getMessage(); + } + else + { + $message = JText::_('COM_USERS_RESET_COMPLETE_ERROR'); + } + + // Go back to the complete form. + $this->setRedirect(JRoute::_('index.php?option=com_users&view=reset&layout=complete', false), $message, 'error'); + + return false; + } + elseif ($return === false) + { + // Complete failed. + // Go back to the complete form. + $message = JText::sprintf('COM_USERS_RESET_COMPLETE_FAILED', $model->getError()); + $this->setRedirect(JRoute::_('index.php?option=com_users&view=reset&layout=complete', false), $message, 'notice'); + + return false; + } + else + { + // Complete succeeded. + // Proceed to the login form. + $message = JText::_('COM_USERS_RESET_COMPLETE_SUCCESS'); + $this->setRedirect(JRoute::_('index.php?option=com_users&view=login', false), $message); + + return true; + } + } +} diff --git a/Sites/pages/components/com_users/controllers/user.php b/Sites/pages/components/com_users/controllers/user.php new file mode 100644 index 00000000..eb952dbc --- /dev/null +++ b/Sites/pages/components/com_users/controllers/user.php @@ -0,0 +1,372 @@ +checkToken('post'); + + $app = JFactory::getApplication(); + $input = $app->input->getInputForRequestMethod(); + + // Populate the data array: + $data = array(); + + $data['return'] = base64_decode($input->get('return', '', 'BASE64')); + $data['username'] = $input->get('username', '', 'USERNAME'); + $data['password'] = $input->get('password', '', 'RAW'); + $data['secretkey'] = $input->get('secretkey', '', 'RAW'); + + // Check for a simple menu item id + if (is_numeric($data['return'])) + { + if (JLanguageMultilang::isEnabled()) + { + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->select('language') + ->from($db->quoteName('#__menu')) + ->where('client_id = 0') + ->where('id =' . $data['return']); + + $db->setQuery($query); + + try + { + $language = $db->loadResult(); + } + catch (RuntimeException $e) + { + return; + } + + if ($language !== '*') + { + $lang = '&lang=' . $language; + } + else + { + $lang = ''; + } + } + else + { + $lang = ''; + } + + $data['return'] = 'index.php?Itemid=' . $data['return'] . $lang; + } + else + { + // Don't redirect to an external URL. + if (!JUri::isInternal($data['return'])) + { + $data['return'] = ''; + } + } + + // Set the return URL if empty. + if (empty($data['return'])) + { + $data['return'] = 'index.php?option=com_users&view=profile'; + } + + // Set the return URL in the user state to allow modification by plugins + $app->setUserState('users.login.form.return', $data['return']); + + // Get the log in options. + $options = array(); + $options['remember'] = $this->input->getBool('remember', false); + $options['return'] = $data['return']; + + // Get the log in credentials. + $credentials = array(); + $credentials['username'] = $data['username']; + $credentials['password'] = $data['password']; + $credentials['secretkey'] = $data['secretkey']; + + // Perform the log in. + if (true !== $app->login($credentials, $options)) + { + // Login failed ! + // Clear user name, password and secret key before sending the login form back to the user. + $data['remember'] = (int) $options['remember']; + $data['username'] = ''; + $data['password'] = ''; + $data['secretkey'] = ''; + $app->setUserState('users.login.form.data', $data); + $app->redirect(JRoute::_('index.php?option=com_users&view=login', false)); + } + + // Success + if ($options['remember'] == true) + { + $app->setUserState('rememberLogin', true); + } + + $app->setUserState('users.login.form.data', array()); + $app->redirect(JRoute::_($app->getUserState('users.login.form.return'), false)); + } + + /** + * Method to log out a user. + * + * @return void + * + * @since 1.6 + */ + public function logout() + { + $this->checkToken('request'); + + $app = JFactory::getApplication(); + + // Prepare the logout options. + $options = array( + 'clientid' => $app->get('shared_session', '0') ? null : 0, + ); + + // Perform the log out. + $error = $app->logout(null, $options); + $input = $app->input->getInputForRequestMethod(); + + // Check if the log out succeeded. + if ($error instanceof Exception) + { + $app->redirect(JRoute::_('index.php?option=com_users&view=login', false)); + } + + // Get the return URL from the request and validate that it is internal. + $return = $input->get('return', '', 'BASE64'); + $return = base64_decode($return); + + // Check for a simple menu item id + if (is_numeric($return)) + { + if (JLanguageMultilang::isEnabled()) + { + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->select('language') + ->from($db->quoteName('#__menu')) + ->where('client_id = 0') + ->where('id =' . $return); + + $db->setQuery($query); + + try + { + $language = $db->loadResult(); + } + catch (RuntimeException $e) + { + return; + } + + if ($language !== '*') + { + $lang = '&lang=' . $language; + } + else + { + $lang = ''; + } + } + else + { + $lang = ''; + } + + $return = 'index.php?Itemid=' . $return . $lang; + } + else + { + // Don't redirect to an external URL. + if (!JUri::isInternal($return)) + { + $return = ''; + } + } + + // In case redirect url is not set, redirect user to homepage + if (empty($return)) + { + $return = JUri::root(); + } + + // Redirect the user. + $app->redirect(JRoute::_($return, false)); + } + + /** + * Method to logout directly and redirect to page. + * + * @return void + * + * @since 3.5 + */ + public function menulogout() + { + // Get the ItemID of the page to redirect after logout + $app = JFactory::getApplication(); + $active = $app->getMenu()->getActive(); + $itemid = $active ? $active->getParams()->get('logout') : 0; + + // Get the language of the page when multilang is on + if (JLanguageMultilang::isEnabled()) + { + if ($itemid) + { + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->select('language') + ->from($db->quoteName('#__menu')) + ->where('client_id = 0') + ->where('id =' . $itemid); + + $db->setQuery($query); + + try + { + $language = $db->loadResult(); + } + catch (RuntimeException $e) + { + return; + } + + if ($language !== '*') + { + $lang = '&lang=' . $language; + } + else + { + $lang = ''; + } + + // URL to redirect after logout + $url = 'index.php?Itemid=' . $itemid . $lang; + } + else + { + // Logout is set to default. Get the home page ItemID + $lang_code = $app->input->cookie->getString(JApplicationHelper::getHash('language')); + $item = $app->getMenu()->getDefault($lang_code); + $itemid = $item->id; + + // Redirect to Home page after logout + $url = 'index.php?Itemid=' . $itemid; + } + } + else + { + // URL to redirect after logout, default page if no ItemID is set + $url = $itemid ? 'index.php?Itemid=' . $itemid : JUri::root(); + } + + // Logout and redirect + $this->setRedirect('index.php?option=com_users&task=user.logout&' . JSession::getFormToken() . '=1&return=' . base64_encode($url)); + } + + /** + * Method to request a username reminder. + * + * @return boolean + * + * @since 1.6 + */ + public function remind() + { + // Check the request token. + $this->checkToken('post'); + + $app = JFactory::getApplication(); + $model = $this->getModel('User', 'UsersModel'); + $data = $this->input->post->get('jform', array(), 'array'); + + // Submit the username remind request. + $return = $model->processRemindRequest($data); + + // Check for a hard error. + if ($return instanceof Exception) + { + // Get the error message to display. + $message = $app->get('error_reporting') + ? $return->getMessage() + : JText::_('COM_USERS_REMIND_REQUEST_ERROR'); + + // Get the route to the next page. + $itemid = UsersHelperRoute::getRemindRoute(); + $itemid = $itemid !== null ? '&Itemid=' . $itemid : ''; + $route = 'index.php?option=com_users&view=remind' . $itemid; + + // Go back to the complete form. + $this->setRedirect(JRoute::_($route, false), $message, 'error'); + + return false; + } + + if ($return === false) + { + // Complete failed. + // Get the route to the next page. + $itemid = UsersHelperRoute::getRemindRoute(); + $itemid = $itemid !== null ? '&Itemid=' . $itemid : ''; + $route = 'index.php?option=com_users&view=remind' . $itemid; + + // Go back to the complete form. + $message = JText::sprintf('COM_USERS_REMIND_REQUEST_FAILED', $model->getError()); + $this->setRedirect(JRoute::_($route, false), $message, 'notice'); + + return false; + } + + // Complete succeeded. + // Get the route to the next page. + $itemid = UsersHelperRoute::getLoginRoute(); + $itemid = $itemid !== null ? '&Itemid=' . $itemid : ''; + $route = 'index.php?option=com_users&view=login' . $itemid; + + // Proceed to the login form. + $message = JText::_('COM_USERS_REMIND_REQUEST_SUCCESS'); + $this->setRedirect(JRoute::_($route, false), $message); + + return true; + } + + /** + * Method to resend a user. + * + * @return void + * + * @since 1.6 + */ + public function resend() + { + // Check for request forgeries + // $this->checkToken('post'); + } +} diff --git a/Sites/pages/components/com_users/helpers/html/users.php b/Sites/pages/components/com_users/helpers/html/users.php new file mode 100644 index 00000000..3d92546a --- /dev/null +++ b/Sites/pages/components/com_users/helpers/html/users.php @@ -0,0 +1,251 @@ +sites->site as $site) + { + if ((string) $site->attributes()->url == $value) + { + $text = (string) $site; + break; + } + } + } + + $value = htmlspecialchars($value, ENT_COMPAT, 'UTF-8'); + + if (strpos($value, 'http') === 0) + { + return '' . $text . ''; + } + + return '' . $text . ''; + } + + /** + * Get the sanitized template style + * + * @param mixed $value Value of the field + * + * @return mixed String/void + * + * @since 1.6 + */ + public static function templatestyle($value) + { + if (empty($value)) + { + return static::value($value); + } + else + { + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->select('title') + ->from('#__template_styles') + ->where('id = ' . $db->quote($value)); + $db->setQuery($query); + $title = $db->loadResult(); + + if ($title) + { + return htmlspecialchars($title, ENT_COMPAT, 'UTF-8'); + } + else + { + return static::value(''); + } + } + } + + /** + * Get the sanitized language + * + * @param mixed $value Value of the field + * + * @return mixed String/void + * + * @since 1.6 + */ + public static function admin_language($value) + { + if (empty($value)) + { + return static::value($value); + } + else + { + $file = JLanguageHelper::getLanguagePath(JPATH_ADMINISTRATOR, $value) . '/' . $value . '.xml'; + + $result = null; + + if (is_file($file)) + { + $result = JLanguageHelper::parseXMLLanguageFile($file); + } + + if ($result) + { + return htmlspecialchars($result['name'], ENT_COMPAT, 'UTF-8'); + } + else + { + return static::value(''); + } + } + } + + /** + * Get the sanitized language + * + * @param mixed $value Value of the field + * + * @return mixed String/void + * + * @since 1.6 + */ + public static function language($value) + { + if (empty($value)) + { + return static::value($value); + } + else + { + $file = JLanguageHelper::getLanguagePath(JPATH_SITE, $value) . '/' . $value . '.xml'; + + $result = null; + + if (is_file($file)) + { + $result = JLanguageHelper::parseXMLLanguageFile($file); + } + + if ($result) + { + return htmlspecialchars($result['name'], ENT_COMPAT, 'UTF-8'); + } + else + { + return static::value(''); + } + } + } + + /** + * Get the sanitized editor name + * + * @param mixed $value Value of the field + * + * @return mixed String/void + * + * @since 1.6 + */ + public static function editor($value) + { + if (empty($value)) + { + return static::value($value); + } + else + { + $db = JFactory::getDbo(); + $lang = JFactory::getLanguage(); + $query = $db->getQuery(true) + ->select('name') + ->from('#__extensions') + ->where('element = ' . $db->quote($value)) + ->where('folder = ' . $db->quote('editors')); + $db->setQuery($query); + $title = $db->loadResult(); + + if ($title) + { + $lang->load("plg_editors_$value.sys", JPATH_ADMINISTRATOR, null, false, true) + || $lang->load("plg_editors_$value.sys", JPATH_PLUGINS . '/editors/' . $value, null, false, true); + $lang->load($title . '.sys'); + + return JText::_($title); + } + else + { + return static::value(''); + } + } + } +} diff --git a/Sites/pages/components/com_users/helpers/legacyrouter.php b/Sites/pages/components/com_users/helpers/legacyrouter.php new file mode 100644 index 00000000..544037b7 --- /dev/null +++ b/Sites/pages/components/com_users/helpers/legacyrouter.php @@ -0,0 +1,309 @@ +router = $router; + } + + /** + * Preprocess the route for the com_users component + * + * @param array &$query An array of URL arguments + * + * @return void + * + * @since 3.6 + * @deprecated 4.0 + */ + public function preprocess(&$query) + { + } + + /** + * Build the route for the com_users component + * + * @param array &$query An array of URL arguments + * @param array &$segments The URL arguments to use to assemble the subsequent URL. + * + * @return void + * + * @since 3.6 + * @deprecated 4.0 + */ + public function build(&$query, &$segments) + { + // Declare static variables. + static $items; + static $default; + static $registration; + static $profile; + static $login; + static $remind; + static $resend; + static $reset; + + // Get the relevant menu items if not loaded. + if (empty($items)) + { + // Get all relevant menu items. + $items = $this->router->menu->getItems('component', 'com_users'); + + // Build an array of serialized query strings to menu item id mappings. + foreach ($items as $item) + { + if (empty($item->query['view'])) + { + continue; + } + + // Check to see if we have found the resend menu item. + if (empty($resend) && $item->query['view'] === 'resend') + { + $resend = $item->id; + + continue; + } + + // Check to see if we have found the reset menu item. + if (empty($reset) && $item->query['view'] === 'reset') + { + $reset = $item->id; + + continue; + } + + // Check to see if we have found the remind menu item. + if (empty($remind) && $item->query['view'] === 'remind') + { + $remind = $item->id; + + continue; + } + + // Check to see if we have found the login menu item. + if (empty($login) && $item->query['view'] === 'login' && (empty($item->query['layout']) || $item->query['layout'] === 'default')) + { + $login = $item->id; + + continue; + } + + // Check to see if we have found the registration menu item. + if (empty($registration) && $item->query['view'] === 'registration') + { + $registration = $item->id; + + continue; + } + + // Check to see if we have found the profile menu item. + if (empty($profile) && $item->query['view'] === 'profile') + { + $profile = $item->id; + } + } + + // Set the default menu item to use for com_users if possible. + if ($profile) + { + $default = $profile; + } + elseif ($registration) + { + $default = $registration; + } + elseif ($login) + { + $default = $login; + } + } + + if (!empty($query['view'])) + { + switch ($query['view']) + { + case 'reset': + if ($query['Itemid'] = $reset) + { + unset($query['view']); + } + else + { + $query['Itemid'] = $default; + } + break; + + case 'resend': + if ($query['Itemid'] = $resend) + { + unset($query['view']); + } + else + { + $query['Itemid'] = $default; + } + break; + + case 'remind': + if ($query['Itemid'] = $remind) + { + unset($query['view']); + } + else + { + $query['Itemid'] = $default; + } + break; + + case 'login': + if ($query['Itemid'] = $login) + { + unset($query['view']); + } + else + { + $query['Itemid'] = $default; + } + break; + + case 'registration': + if ($query['Itemid'] = $registration) + { + unset($query['view']); + } + else + { + $query['Itemid'] = $default; + } + break; + + default: + case 'profile': + if (!empty($query['view'])) + { + $segments[] = $query['view']; + } + + unset($query['view']); + + if ($query['Itemid'] = $profile) + { + unset($query['view']); + } + else + { + $query['Itemid'] = $default; + } + + // Only append the user id if not "me". + $user = JFactory::getUser(); + + if (!empty($query['user_id']) && ($query['user_id'] != $user->id)) + { + $segments[] = $query['user_id']; + } + + unset($query['user_id']); + + break; + } + } + + $total = count($segments); + + for ($i = 0; $i < $total; $i++) + { + $segments[$i] = str_replace(':', '-', $segments[$i]); + } + } + + /** + * Parse the segments of a URL. + * + * @param array &$segments The segments of the URL to parse. + * @param array &$vars The URL attributes to be used by the application. + * + * @return void + * + * @since 3.6 + * @deprecated 4.0 + */ + public function parse(&$segments, &$vars) + { + $total = count($segments); + + for ($i = 0; $i < $total; $i++) + { + $segments[$i] = preg_replace('/-/', ':', $segments[$i], 1); + } + + // Only run routine if there are segments to parse. + if (count($segments) < 1) + { + return; + } + + // Get the package from the route segments. + $userId = array_pop($segments); + + if (!is_numeric($userId)) + { + $vars['view'] = 'profile'; + + return; + } + + if (is_numeric($userId)) + { + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->select($db->quoteName('id')) + ->from($db->quoteName('#__users')) + ->where($db->quoteName('id') . ' = ' . (int) $userId); + $db->setQuery($query); + $userId = $db->loadResult(); + } + + // Set the package id if present. + if ($userId) + { + // Set the package id. + $vars['user_id'] = (int) $userId; + + // Set the view to package if not already set. + if (empty($vars['view'])) + { + $vars['view'] = 'profile'; + } + } + else + { + JError::raiseError(404, JText::_('JGLOBAL_RESOURCE_NOT_FOUND')); + } + } +} diff --git a/Sites/pages/components/com_users/helpers/route.php b/Sites/pages/components/com_users/helpers/route.php new file mode 100644 index 00000000..2ab46d58 --- /dev/null +++ b/Sites/pages/components/com_users/helpers/route.php @@ -0,0 +1,199 @@ +getMenu()->getItems('component_id', $component->id); + + // If no items found, set to empty array. + if (!$items) + { + $items = array(); + } + } + + return $items; + } + + /** + * Method to get a route configuration for the login view. + * + * @return mixed Integer menu id on success, null on failure. + * + * @since 1.6 + * @deprecated 4.0 + */ + public static function getLoginRoute() + { + // Get the items. + $items = self::getItems(); + + // Search for a suitable menu id. + foreach ($items as $item) + { + if (isset($item->query['view']) && $item->query['view'] === 'login' && (empty($item->query['layout']) || $item->query['layout'] === 'default')) + { + return $item->id; + } + } + + return null; + } + + /** + * Method to get a route configuration for the profile view. + * + * @return mixed Integer menu id on success, null on failure. + * + * @since 1.6 + * @deprecated 4.0 + */ + public static function getProfileRoute() + { + // Get the items. + $items = self::getItems(); + + // Search for a suitable menu id. + // Menu link can only go to users own profile. + + foreach ($items as $item) + { + if (isset($item->query['view']) && $item->query['view'] === 'profile') + { + return $item->id; + } + } + + return null; + } + + /** + * Method to get a route configuration for the registration view. + * + * @return mixed Integer menu id on success, null on failure. + * + * @since 1.6 + * @deprecated 4.0 + */ + public static function getRegistrationRoute() + { + // Get the items. + $items = self::getItems(); + + // Search for a suitable menu id. + foreach ($items as $item) + { + if (isset($item->query['view']) && $item->query['view'] === 'registration') + { + return $item->id; + } + } + + return null; + } + + /** + * Method to get a route configuration for the remind view. + * + * @return mixed Integer menu id on success, null on failure. + * + * @since 1.6 + * @deprecated 4.0 + */ + public static function getRemindRoute() + { + // Get the items. + $items = self::getItems(); + + // Search for a suitable menu id. + foreach ($items as $item) + { + if (isset($item->query['view']) && $item->query['view'] === 'remind') + { + return $item->id; + } + } + + return null; + } + + /** + * Method to get a route configuration for the resend view. + * + * @return mixed Integer menu id on success, null on failure. + * + * @since 1.6 + * @deprecated 4.0 + */ + public static function getResendRoute() + { + // Get the items. + $items = self::getItems(); + + // Search for a suitable menu id. + foreach ($items as $item) + { + if (isset($item->query['view']) && $item->query['view'] === 'resend') + { + return $item->id; + } + } + + return null; + } + + /** + * Method to get a route configuration for the reset view. + * + * @return mixed Integer menu id on success, null on failure. + * + * @since 1.6 + * @deprecated 4.0 + */ + public static function getResetRoute() + { + // Get the items. + $items = self::getItems(); + + // Search for a suitable menu id. + foreach ($items as $item) + { + if (isset($item->query['view']) && $item->query['view'] === 'reset') + { + return $item->id; + } + } + + return null; + } +} diff --git a/Sites/pages/components/com_users/layouts/joomla/form/renderfield.php b/Sites/pages/components/com_users/layouts/joomla/form/renderfield.php new file mode 100644 index 00000000..3d995815 --- /dev/null +++ b/Sites/pages/components/com_users/layouts/joomla/form/renderfield.php @@ -0,0 +1,60 @@ + 'auto', 'relative' => true)); +} + +$class = empty($options['class']) ? '' : ' ' . $options['class']; +$rel = empty($options['rel']) ? '' : ' ' . $options['rel']; + +/** + * @TODO: + * + * As mentioned in #8473 (https://github.com/joomla/joomla-cms/pull/8473), ... + * as long as we cannot access the field properties properly, this seems to + * be the way to go for now. + * + * On a side note: Parsing html is seldom a good idea. + * https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/1732454#1732454 + */ +preg_match('/class=\"([^\"]+)\"/i', $input, $match); + +$required = (strpos($input, 'aria-required="true"') !== false || (!empty($match[1]) && strpos($match[1], 'required') !== false)); +$typeOfSpacer = (strpos($label, 'spacer-lbl') !== false); + +?> + +
        > + +
        + + + + +
        + +
        + +
        +
        diff --git a/Sites/pages/components/com_users/models/forms/frontend.xml b/Sites/pages/components/com_users/models/forms/frontend.xml new file mode 100644 index 00000000..2976f671 --- /dev/null +++ b/Sites/pages/components/com_users/models/forms/frontend.xml @@ -0,0 +1,38 @@ + +
        + + +
        + + + + + + + + + + + +
        +
        +
        diff --git a/Sites/pages/components/com_users/models/forms/frontend_admin.xml b/Sites/pages/components/com_users/models/forms/frontend_admin.xml new file mode 100644 index 00000000..c9e58e46 --- /dev/null +++ b/Sites/pages/components/com_users/models/forms/frontend_admin.xml @@ -0,0 +1,30 @@ + +
        + + +
        + + + + + + + + +
        +
        +
        diff --git a/Sites/pages/components/com_users/models/forms/login.xml b/Sites/pages/components/com_users/models/forms/login.xml new file mode 100644 index 00000000..7630e4a7 --- /dev/null +++ b/Sites/pages/components/com_users/models/forms/login.xml @@ -0,0 +1,43 @@ + +
        +
        + + + +
        + + + +
        + +
        + diff --git a/Sites/pages/components/com_users/models/forms/profile.xml b/Sites/pages/components/com_users/models/forms/profile.xml new file mode 100644 index 00000000..92d1d642 --- /dev/null +++ b/Sites/pages/components/com_users/models/forms/profile.xml @@ -0,0 +1,92 @@ + +
        +
        + + + + + + + + + + + + + +
        + + + + diff --git a/Sites/pages/components/com_users/models/forms/registration.xml b/Sites/pages/components/com_users/models/forms/registration.xml new file mode 100644 index 00000000..0a648ffe --- /dev/null +++ b/Sites/pages/components/com_users/models/forms/registration.xml @@ -0,0 +1,99 @@ + +
        +
        + + + + + + + + + + + + + + + +
        +
        diff --git a/Sites/pages/components/com_users/models/forms/remind.xml b/Sites/pages/components/com_users/models/forms/remind.xml new file mode 100644 index 00000000..6ca81396 --- /dev/null +++ b/Sites/pages/components/com_users/models/forms/remind.xml @@ -0,0 +1,23 @@ + +
        +
        + + + +
        +
        \ No newline at end of file diff --git a/Sites/pages/components/com_users/models/forms/reset_complete.xml b/Sites/pages/components/com_users/models/forms/reset_complete.xml new file mode 100644 index 00000000..d33bbaaf --- /dev/null +++ b/Sites/pages/components/com_users/models/forms/reset_complete.xml @@ -0,0 +1,31 @@ + +
        +
        + + +
        +
        \ No newline at end of file diff --git a/Sites/pages/components/com_users/models/forms/reset_confirm.xml b/Sites/pages/components/com_users/models/forms/reset_confirm.xml new file mode 100644 index 00000000..2be151e2 --- /dev/null +++ b/Sites/pages/components/com_users/models/forms/reset_confirm.xml @@ -0,0 +1,24 @@ + +
        +
        + + + +
        +
        diff --git a/Sites/pages/components/com_users/models/forms/reset_request.xml b/Sites/pages/components/com_users/models/forms/reset_request.xml new file mode 100644 index 00000000..df9297e3 --- /dev/null +++ b/Sites/pages/components/com_users/models/forms/reset_request.xml @@ -0,0 +1,23 @@ + +
        +
        + + + +
        +
        \ No newline at end of file diff --git a/Sites/pages/components/com_users/models/forms/sitelang.xml b/Sites/pages/components/com_users/models/forms/sitelang.xml new file mode 100644 index 00000000..9db913f9 --- /dev/null +++ b/Sites/pages/components/com_users/models/forms/sitelang.xml @@ -0,0 +1,16 @@ + +
        + +
        + +
        +
        +
        \ No newline at end of file diff --git a/Sites/pages/components/com_users/models/login.php b/Sites/pages/components/com_users/models/login.php new file mode 100644 index 00000000..b1f6d908 --- /dev/null +++ b/Sites/pages/components/com_users/models/login.php @@ -0,0 +1,112 @@ +loadForm('com_users.login', 'login', array('load_data' => $loadData)); + + if (empty($form)) + { + return false; + } + + return $form; + } + + /** + * Method to get the data that should be injected in the form. + * + * @return array The default data is an empty array. + * + * @since 1.6 + */ + protected function loadFormData() + { + // Check the session for previously entered login form data. + $app = JFactory::getApplication(); + $data = $app->getUserState('users.login.form.data', array()); + + $input = $app->input->getInputForRequestMethod(); + + // Check for return URL from the request first + if ($return = $input->get('return', '', 'BASE64')) + { + $data['return'] = base64_decode($return); + + if (!JUri::isInternal($data['return'])) + { + $data['return'] = ''; + } + } + + $app->setUserState('users.login.form.data', $data); + + $this->preprocessData('com_users.login', $data); + + return $data; + } + + /** + * Method to auto-populate the model state. + * + * Calling getState in this method will result in recursion. + * + * @return void + * + * @since 1.6 + */ + protected function populateState() + { + // Get the application object. + $params = JFactory::getApplication()->getParams('com_users'); + + // Load the parameters. + $this->setState('params', $params); + } + + /** + * Override JModelAdmin::preprocessForm to ensure the correct plugin group is loaded. + * + * @param JForm $form A JForm object. + * @param mixed $data The data expected for the form. + * @param string $group The name of the plugin group to import (defaults to "content"). + * + * @return void + * + * @since 1.6 + * @throws Exception if there is an error in the form event. + */ + protected function preprocessForm(JForm $form, $data, $group = 'user') + { + parent::preprocessForm($form, $data, $group); + } +} diff --git a/Sites/pages/components/com_users/models/profile.php b/Sites/pages/components/com_users/models/profile.php new file mode 100644 index 00000000..16d16520 --- /dev/null +++ b/Sites/pages/components/com_users/models/profile.php @@ -0,0 +1,438 @@ + array('validate' => 'user') + ), $config + ); + + parent::__construct($config); + + // Load the helper and model used for two factor authentication + JLoader::register('UsersModelUser', JPATH_ADMINISTRATOR . '/components/com_users/models/user.php'); + JLoader::register('UsersHelper', JPATH_ADMINISTRATOR . '/components/com_users/helpers/users.php'); + } + + /** + * Method to check in a user. + * + * @param integer $userId The id of the row to check out. + * + * @return boolean True on success, false on failure. + * + * @since 1.6 + */ + public function checkin($userId = null) + { + // Get the user id. + $userId = (!empty($userId)) ? $userId : (int) $this->getState('user.id'); + + if ($userId) + { + // Initialise the table with JUser. + $table = JTable::getInstance('User'); + + // Attempt to check the row in. + if (!$table->checkin($userId)) + { + $this->setError($table->getError()); + + return false; + } + } + + return true; + } + + /** + * Method to check out a user for editing. + * + * @param integer $userId The id of the row to check out. + * + * @return boolean True on success, false on failure. + * + * @since 1.6 + */ + public function checkout($userId = null) + { + // Get the user id. + $userId = (!empty($userId)) ? $userId : (int) $this->getState('user.id'); + + if ($userId) + { + // Initialise the table with JUser. + $table = JTable::getInstance('User'); + + // Get the current user object. + $user = JFactory::getUser(); + + // Attempt to check the row out. + if (!$table->checkout($user->get('id'), $userId)) + { + $this->setError($table->getError()); + + return false; + } + } + + return true; + } + + /** + * Method to get the profile form data. + * + * The base form data is loaded and then an event is fired + * for users plugins to extend the data. + * + * @return mixed Data object on success, false on failure. + * + * @since 1.6 + */ + public function getData() + { + if ($this->data === null) + { + $userId = $this->getState('user.id'); + + // Initialise the table with JUser. + $this->data = new JUser($userId); + + // Set the base user data. + $this->data->email1 = $this->data->get('email'); + $this->data->email2 = $this->data->get('email'); + + // Override the base user data with any data in the session. + $temp = (array) JFactory::getApplication()->getUserState('com_users.edit.profile.data', array()); + + foreach ($temp as $k => $v) + { + $this->data->$k = $v; + } + + // Unset the passwords. + unset($this->data->password1, $this->data->password2); + + $registry = new Registry($this->data->params); + $this->data->params = $registry->toArray(); + } + + return $this->data; + } + + /** + * Method to get the profile form. + * + * The base form is loaded from XML and then an event is fired + * for users plugins to extend the form with extra fields. + * + * @param array $data An optional array of data for the form to interrogate. + * @param boolean $loadData True if the form is to load its own data (default case), false if not. + * + * @return JForm A JForm object on success, false on failure + * + * @since 1.6 + */ + public function getForm($data = array(), $loadData = true) + { + // Get the form. + $form = $this->loadForm('com_users.profile', 'profile', array('control' => 'jform', 'load_data' => $loadData)); + + if (empty($form)) + { + return false; + } + + // Check for username compliance and parameter set + $isUsernameCompliant = true; + $username = $loadData ? $form->getValue('username') : $this->loadFormData()->username; + + if ($username) + { + $isUsernameCompliant = !(preg_match('#[<>"\'%;()&\\\\]|\\.\\./#', $username) || strlen(utf8_decode($username)) < 2 + || trim($username) !== $username); + } + + $this->setState('user.username.compliant', $isUsernameCompliant); + + if ($isUsernameCompliant && !JComponentHelper::getParams('com_users')->get('change_login_name')) + { + $form->setFieldAttribute('username', 'class', ''); + $form->setFieldAttribute('username', 'filter', ''); + $form->setFieldAttribute('username', 'description', 'COM_USERS_PROFILE_NOCHANGE_USERNAME_DESC'); + $form->setFieldAttribute('username', 'validate', ''); + $form->setFieldAttribute('username', 'message', ''); + $form->setFieldAttribute('username', 'readonly', 'true'); + $form->setFieldAttribute('username', 'required', 'false'); + } + + // When multilanguage is set, a user's default site language should also be a Content Language + if (JLanguageMultilang::isEnabled()) + { + $form->setFieldAttribute('language', 'type', 'frontend_language', 'params'); + } + + // If the user needs to change their password, mark the password fields as required + if (JFactory::getUser()->requireReset) + { + $form->setFieldAttribute('password1', 'required', 'true'); + $form->setFieldAttribute('password2', 'required', 'true'); + } + + return $form; + } + + /** + * Method to get the data that should be injected in the form. + * + * @return mixed The data for the form. + * + * @since 1.6 + */ + protected function loadFormData() + { + $data = $this->getData(); + + $this->preprocessData('com_users.profile', $data, 'user'); + + return $data; + } + + /** + * Override preprocessForm to load the user plugin group instead of content. + * + * @param JForm $form A JForm object. + * @param mixed $data The data expected for the form. + * @param string $group The name of the plugin group to import (defaults to "content"). + * + * @return void + * + * @throws Exception if there is an error in the form event. + * + * @since 1.6 + */ + protected function preprocessForm(JForm $form, $data, $group = 'user') + { + if (JComponentHelper::getParams('com_users')->get('frontend_userparams')) + { + $form->loadFile('frontend', false); + + if (JFactory::getUser()->authorise('core.login.admin')) + { + $form->loadFile('frontend_admin', false); + } + } + + parent::preprocessForm($form, $data, $group); + } + + /** + * Method to auto-populate the model state. + * + * Note. Calling getState in this method will result in recursion. + * + * @return void + * + * @since 1.6 + */ + protected function populateState() + { + // Get the application object. + $params = JFactory::getApplication()->getParams('com_users'); + + // Get the user id. + $userId = JFactory::getApplication()->getUserState('com_users.edit.profile.id'); + $userId = !empty($userId) ? $userId : (int) JFactory::getUser()->get('id'); + + // Set the user id. + $this->setState('user.id', $userId); + + // Load the parameters. + $this->setState('params', $params); + } + + /** + * Method to save the form data. + * + * @param array $data The form data. + * + * @return mixed The user id on success, false on failure. + * + * @since 1.6 + */ + public function save($data) + { + $userId = (!empty($data['id'])) ? $data['id'] : (int) $this->getState('user.id'); + + $user = new JUser($userId); + + // Prepare the data for the user object. + $data['email'] = JStringPunycode::emailToPunycode($data['email1']); + $data['password'] = $data['password1']; + + // Unset the username if it should not be overwritten + $isUsernameCompliant = $this->getState('user.username.compliant'); + + if ($isUsernameCompliant && !JComponentHelper::getParams('com_users')->get('change_login_name')) + { + unset($data['username']); + } + + // Unset block and sendEmail so they do not get overwritten + unset($data['block'], $data['sendEmail']); + + // Handle the two factor authentication setup + if (array_key_exists('twofactor', $data)) + { + $model = new UsersModelUser; + + $twoFactorMethod = $data['twofactor']['method']; + + // Get the current One Time Password (two factor auth) configuration + $otpConfig = $model->getOtpConfig($userId); + + if ($twoFactorMethod !== 'none') + { + // Run the plugins + FOFPlatform::getInstance()->importPlugin('twofactorauth'); + $otpConfigReplies = FOFPlatform::getInstance()->runPlugins('onUserTwofactorApplyConfiguration', array($twoFactorMethod)); + + // Look for a valid reply + foreach ($otpConfigReplies as $reply) + { + if (!is_object($reply) || empty($reply->method) || ($reply->method != $twoFactorMethod)) + { + continue; + } + + $otpConfig->method = $reply->method; + $otpConfig->config = $reply->config; + + break; + } + + // Save OTP configuration. + $model->setOtpConfig($userId, $otpConfig); + + // Generate one time emergency passwords if required (depleted or not set) + if (empty($otpConfig->otep)) + { + $model->generateOteps($userId); + } + } + else + { + $otpConfig->method = 'none'; + $otpConfig->config = array(); + $model->setOtpConfig($userId, $otpConfig); + } + + // Unset the raw data + unset($data['twofactor']); + + // Reload the user record with the updated OTP configuration + $user->load($userId); + } + + // Bind the data. + if (!$user->bind($data)) + { + $this->setError(JText::sprintf('COM_USERS_PROFILE_BIND_FAILED', $user->getError())); + + return false; + } + + // Load the users plugin group. + JPluginHelper::importPlugin('user'); + + // Retrieve the user groups so they don't get overwritten + unset($user->groups); + $user->groups = JAccess::getGroupsByUser($user->id, false); + + // Store the data. + if (!$user->save()) + { + $this->setError($user->getError()); + + return false; + } + + return $user->id; + } + + /** + * Gets the configuration forms for all two-factor authentication methods + * in an array. + * + * @param integer $userId The user ID to load the forms for (optional) + * + * @return array + * + * @since 3.2 + */ + public function getTwofactorform($userId = null) + { + $userId = (!empty($userId)) ? $userId : (int) $this->getState('user.id'); + + $model = new UsersModelUser; + + $otpConfig = $model->getOtpConfig($userId); + + FOFPlatform::getInstance()->importPlugin('twofactorauth'); + + return FOFPlatform::getInstance()->runPlugins('onUserTwofactorShowConfiguration', array($otpConfig, $userId)); + } + + /** + * Returns the one time password (OTP) – a.k.a. two factor authentication – + * configuration for a particular user. + * + * @param integer $userId The numeric ID of the user + * + * @return stdClass An object holding the OTP configuration for this user + * + * @since 3.2 + */ + public function getOtpConfig($userId = null) + { + $userId = (!empty($userId)) ? $userId : (int) $this->getState('user.id'); + + $model = new UsersModelUser; + + return $model->getOtpConfig($userId); + } +} diff --git a/Sites/pages/components/com_users/models/registration.php b/Sites/pages/components/com_users/models/registration.php new file mode 100644 index 00000000..f34bc782 --- /dev/null +++ b/Sites/pages/components/com_users/models/registration.php @@ -0,0 +1,723 @@ + array('validate' => 'user') + ), $config + ); + + parent::__construct($config); + } + + /** + * Method to get the user ID from the given token + * + * @param string $token The activation token. + * + * @return mixed False on failure, id of the user on success + * + * @since 3.8.13 + */ + public function getUserIdFromToken($token) + { + $db = $this->getDbo(); + + // Get the user id based on the token. + $query = $db->getQuery(true); + $query->select($db->quoteName('id')) + ->from($db->quoteName('#__users')) + ->where($db->quoteName('activation') . ' = ' . $db->quote($token)) + ->where($db->quoteName('block') . ' = ' . 1) + ->where($db->quoteName('lastvisitDate') . ' = ' . $db->quote($db->getNullDate())); + $db->setQuery($query); + + try + { + return (int) $db->loadResult(); + } + catch (RuntimeException $e) + { + $this->setError(JText::sprintf('COM_USERS_DATABASE_ERROR', $e->getMessage()), 500); + + return false; + } + } + + /** + * Method to activate a user account. + * + * @param string $token The activation token. + * + * @return mixed False on failure, user object on success. + * + * @since 1.6 + */ + public function activate($token) + { + $config = JFactory::getConfig(); + $userParams = JComponentHelper::getParams('com_users'); + $userId = $this->getUserIdFromToken($token); + + // Check for a valid user id. + if (!$userId) + { + $this->setError(JText::_('COM_USERS_ACTIVATION_TOKEN_NOT_FOUND')); + + return false; + } + + // Load the users plugin group. + JPluginHelper::importPlugin('user'); + + // Activate the user. + $user = JFactory::getUser($userId); + + // Admin activation is on and user is verifying their email + if (($userParams->get('useractivation') == 2) && !$user->getParam('activate', 0)) + { + $linkMode = $config->get('force_ssl', 0) == 2 ? Route::TLS_FORCE : Route::TLS_IGNORE; + + // Compile the admin notification mail values. + $data = $user->getProperties(); + $data['activation'] = JApplicationHelper::getHash(JUserHelper::genRandomPassword()); + $user->set('activation', $data['activation']); + $data['siteurl'] = JUri::base(); + $data['activate'] = JRoute::link( + 'site', + 'index.php?option=com_users&task=registration.activate&token=' . $data['activation'], + false, + $linkMode, + true + ); + + $data['fromname'] = $config->get('fromname'); + $data['mailfrom'] = $config->get('mailfrom'); + $data['sitename'] = $config->get('sitename'); + $user->setParam('activate', 1); + $emailSubject = JText::sprintf( + 'COM_USERS_EMAIL_ACTIVATE_WITH_ADMIN_ACTIVATION_SUBJECT', + $data['name'], + $data['sitename'] + ); + + $emailBody = JText::sprintf( + 'COM_USERS_EMAIL_ACTIVATE_WITH_ADMIN_ACTIVATION_BODY', + $data['sitename'], + $data['name'], + $data['email'], + $data['username'], + $data['activate'] + ); + + // Get all admin users + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select($db->quoteName(array('name', 'email', 'sendEmail', 'id'))) + ->from($db->quoteName('#__users')) + ->where($db->quoteName('sendEmail') . ' = 1') + ->where($db->quoteName('block') . ' = 0'); + + $db->setQuery($query); + + try + { + $rows = $db->loadObjectList(); + } + catch (RuntimeException $e) + { + $this->setError(JText::sprintf('COM_USERS_DATABASE_ERROR', $e->getMessage()), 500); + + return false; + } + + // Send mail to all users with users creating permissions and receiving system emails + foreach ($rows as $row) + { + $usercreator = JFactory::getUser($row->id); + + if ($usercreator->authorise('core.create', 'com_users') && $usercreator->authorise('core.manage', 'com_users')) + { + $return = JFactory::getMailer()->sendMail($data['mailfrom'], $data['fromname'], $row->email, $emailSubject, $emailBody); + + // Check for an error. + if ($return !== true) + { + $this->setError(JText::_('COM_USERS_REGISTRATION_ACTIVATION_NOTIFY_SEND_MAIL_FAILED')); + + return false; + } + } + } + } + // Admin activation is on and admin is activating the account + elseif (($userParams->get('useractivation') == 2) && $user->getParam('activate', 0)) + { + $user->set('activation', ''); + $user->set('block', '0'); + + // Compile the user activated notification mail values. + $data = $user->getProperties(); + $user->setParam('activate', 0); + $data['fromname'] = $config->get('fromname'); + $data['mailfrom'] = $config->get('mailfrom'); + $data['sitename'] = $config->get('sitename'); + $data['siteurl'] = JUri::base(); + $emailSubject = JText::sprintf( + 'COM_USERS_EMAIL_ACTIVATED_BY_ADMIN_ACTIVATION_SUBJECT', + $data['name'], + $data['sitename'] + ); + + $emailBody = JText::sprintf( + 'COM_USERS_EMAIL_ACTIVATED_BY_ADMIN_ACTIVATION_BODY', + $data['name'], + $data['siteurl'], + $data['username'] + ); + + $return = JFactory::getMailer()->sendMail($data['mailfrom'], $data['fromname'], $data['email'], $emailSubject, $emailBody); + + // Check for an error. + if ($return !== true) + { + $this->setError(JText::_('COM_USERS_REGISTRATION_ACTIVATION_NOTIFY_SEND_MAIL_FAILED')); + + return false; + } + } + else + { + $user->set('activation', ''); + $user->set('block', '0'); + } + + // Store the user object. + if (!$user->save()) + { + $this->setError(JText::sprintf('COM_USERS_REGISTRATION_ACTIVATION_SAVE_FAILED', $user->getError())); + + return false; + } + + return $user; + } + + /** + * Method to get the registration form data. + * + * The base form data is loaded and then an event is fired + * for users plugins to extend the data. + * + * @return mixed Data object on success, false on failure. + * + * @since 1.6 + */ + public function getData() + { + if ($this->data === null) + { + $this->data = new stdClass; + $app = JFactory::getApplication(); + $params = JComponentHelper::getParams('com_users'); + + // Override the base user data with any data in the session. + $temp = (array) $app->getUserState('com_users.registration.data', array()); + + // Don't load the data in this getForm call, or we'll call ourself + $form = $this->getForm(array(), false); + + foreach ($temp as $k => $v) + { + // Here we could have a grouped field, let's check it + if (is_array($v)) + { + $this->data->$k = new stdClass; + + foreach ($v as $key => $val) + { + if ($form->getField($key, $k) !== false) + { + $this->data->$k->$key = $val; + } + } + } + // Only merge the field if it exists in the form. + elseif ($form->getField($k) !== false) + { + $this->data->$k = $v; + } + } + + // Get the groups the user should be added to after registration. + $this->data->groups = array(); + + // Get the default new user group, guest or public group if not specified. + $system = $params->get('new_usertype', $params->get('guest_usergroup', 1)); + + $this->data->groups[] = $system; + + // Unset the passwords. + unset($this->data->password1, $this->data->password2); + + // Get the dispatcher and load the users plugins. + $dispatcher = JEventDispatcher::getInstance(); + JPluginHelper::importPlugin('user'); + + // Trigger the data preparation event. + $results = $dispatcher->trigger('onContentPrepareData', array('com_users.registration', $this->data)); + + // Check for errors encountered while preparing the data. + if (count($results) && in_array(false, $results, true)) + { + $this->setError($dispatcher->getError()); + $this->data = false; + } + } + + return $this->data; + } + + /** + * Method to get the registration form. + * + * The base form is loaded from XML and then an event is fired + * for users plugins to extend the form with extra fields. + * + * @param array $data An optional array of data for the form to interrogate. + * @param boolean $loadData True if the form is to load its own data (default case), false if not. + * + * @return JForm A JForm object on success, false on failure + * + * @since 1.6 + */ + public function getForm($data = array(), $loadData = true) + { + // Get the form. + $form = $this->loadForm('com_users.registration', 'registration', array('control' => 'jform', 'load_data' => $loadData)); + + if (empty($form)) + { + return false; + } + + // When multilanguage is set, a user's default site language should also be a Content Language + if (JLanguageMultilang::isEnabled()) + { + $form->setFieldAttribute('language', 'type', 'frontend_language', 'params'); + } + + return $form; + } + + /** + * Method to get the data that should be injected in the form. + * + * @return mixed The data for the form. + * + * @since 1.6 + */ + protected function loadFormData() + { + $data = $this->getData(); + + if (JLanguageMultilang::isEnabled() && empty($data->language)) + { + $data->language = JFactory::getLanguage()->getTag(); + } + + $this->preprocessData('com_users.registration', $data); + + return $data; + } + + /** + * Override preprocessForm to load the user plugin group instead of content. + * + * @param JForm $form A JForm object. + * @param mixed $data The data expected for the form. + * @param string $group The name of the plugin group to import (defaults to "content"). + * + * @return void + * + * @since 1.6 + * @throws Exception if there is an error in the form event. + */ + protected function preprocessForm(JForm $form, $data, $group = 'user') + { + $userParams = JComponentHelper::getParams('com_users'); + + // Add the choice for site language at registration time + if ($userParams->get('site_language') == 1 && $userParams->get('frontend_userparams') == 1) + { + $form->loadFile('sitelang', false); + } + + parent::preprocessForm($form, $data, $group); + } + + /** + * Method to auto-populate the model state. + * + * Note. Calling getState in this method will result in recursion. + * + * @return void + * + * @since 1.6 + */ + protected function populateState() + { + // Get the application object. + $app = JFactory::getApplication(); + $params = $app->getParams('com_users'); + + // Load the parameters. + $this->setState('params', $params); + } + + /** + * Method to save the form data. + * + * @param array $temp The form data. + * + * @return mixed The user id on success, false on failure. + * + * @since 1.6 + */ + public function register($temp) + { + $params = JComponentHelper::getParams('com_users'); + + // Initialise the table with JUser. + $user = new JUser; + $data = (array) $this->getData(); + + // Merge in the registration data. + foreach ($temp as $k => $v) + { + $data[$k] = $v; + } + + // Prepare the data for the user object. + $data['email'] = JStringPunycode::emailToPunycode($data['email1']); + $data['password'] = $data['password1']; + $useractivation = $params->get('useractivation'); + $sendpassword = $params->get('sendpassword', 1); + + // Check if the user needs to activate their account. + if (($useractivation == 1) || ($useractivation == 2)) + { + $data['activation'] = JApplicationHelper::getHash(JUserHelper::genRandomPassword()); + $data['block'] = 1; + } + + // Bind the data. + if (!$user->bind($data)) + { + $this->setError(JText::sprintf('COM_USERS_REGISTRATION_BIND_FAILED', $user->getError())); + + return false; + } + + // Load the users plugin group. + JPluginHelper::importPlugin('user'); + + // Store the data. + if (!$user->save()) + { + $this->setError(JText::sprintf('COM_USERS_REGISTRATION_SAVE_FAILED', $user->getError())); + + return false; + } + + $config = JFactory::getConfig(); + $db = $this->getDbo(); + $query = $db->getQuery(true); + + // Compile the notification mail values. + $data = $user->getProperties(); + $data['fromname'] = $config->get('fromname'); + $data['mailfrom'] = $config->get('mailfrom'); + $data['sitename'] = $config->get('sitename'); + $data['siteurl'] = JUri::root(); + + // Handle account activation/confirmation emails. + if ($useractivation == 2) + { + // Set the link to confirm the user email. + $linkMode = $config->get('force_ssl', 0) == 2 ? Route::TLS_FORCE : Route::TLS_IGNORE; + + $data['activate'] = JRoute::link( + 'site', + 'index.php?option=com_users&task=registration.activate&token=' . $data['activation'], + false, + $linkMode, + true + ); + + $emailSubject = JText::sprintf( + 'COM_USERS_EMAIL_ACCOUNT_DETAILS', + $data['name'], + $data['sitename'] + ); + + if ($sendpassword) + { + $emailBody = JText::sprintf( + 'COM_USERS_EMAIL_REGISTERED_WITH_ADMIN_ACTIVATION_BODY', + $data['name'], + $data['sitename'], + $data['activate'], + $data['siteurl'], + $data['username'], + $data['password_clear'] + ); + } + else + { + $emailBody = JText::sprintf( + 'COM_USERS_EMAIL_REGISTERED_WITH_ADMIN_ACTIVATION_BODY_NOPW', + $data['name'], + $data['sitename'], + $data['activate'], + $data['siteurl'], + $data['username'] + ); + } + } + elseif ($useractivation == 1) + { + // Set the link to activate the user account. + $linkMode = $config->get('force_ssl', 0) == 2 ? Route::TLS_FORCE : Route::TLS_IGNORE; + + $data['activate'] = JRoute::link( + 'site', + 'index.php?option=com_users&task=registration.activate&token=' . $data['activation'], + false, + $linkMode, + true + ); + + $emailSubject = JText::sprintf( + 'COM_USERS_EMAIL_ACCOUNT_DETAILS', + $data['name'], + $data['sitename'] + ); + + if ($sendpassword) + { + $emailBody = JText::sprintf( + 'COM_USERS_EMAIL_REGISTERED_WITH_ACTIVATION_BODY', + $data['name'], + $data['sitename'], + $data['activate'], + $data['siteurl'], + $data['username'], + $data['password_clear'] + ); + } + else + { + $emailBody = JText::sprintf( + 'COM_USERS_EMAIL_REGISTERED_WITH_ACTIVATION_BODY_NOPW', + $data['name'], + $data['sitename'], + $data['activate'], + $data['siteurl'], + $data['username'] + ); + } + } + else + { + $emailSubject = JText::sprintf( + 'COM_USERS_EMAIL_ACCOUNT_DETAILS', + $data['name'], + $data['sitename'] + ); + + if ($sendpassword) + { + $emailBody = JText::sprintf( + 'COM_USERS_EMAIL_REGISTERED_BODY', + $data['name'], + $data['sitename'], + $data['siteurl'], + $data['username'], + $data['password_clear'] + ); + } + else + { + $emailBody = JText::sprintf( + 'COM_USERS_EMAIL_REGISTERED_BODY_NOPW', + $data['name'], + $data['sitename'], + $data['siteurl'] + ); + } + } + + // Send the registration email. + $return = JFactory::getMailer()->sendMail($data['mailfrom'], $data['fromname'], $data['email'], $emailSubject, $emailBody); + + // Send Notification mail to administrators + if (($params->get('useractivation') < 2) && ($params->get('mail_to_admin') == 1)) + { + $emailSubject = JText::sprintf( + 'COM_USERS_EMAIL_ACCOUNT_DETAILS', + $data['name'], + $data['sitename'] + ); + + $emailBodyAdmin = JText::sprintf( + 'COM_USERS_EMAIL_REGISTERED_NOTIFICATION_TO_ADMIN_BODY', + $data['name'], + $data['username'], + $data['siteurl'] + ); + + // Get all admin users + $query->clear() + ->select($db->quoteName(array('name', 'email', 'sendEmail'))) + ->from($db->quoteName('#__users')) + ->where($db->quoteName('sendEmail') . ' = 1') + ->where($db->quoteName('block') . ' = 0'); + + $db->setQuery($query); + + try + { + $rows = $db->loadObjectList(); + } + catch (RuntimeException $e) + { + $this->setError(JText::sprintf('COM_USERS_DATABASE_ERROR', $e->getMessage()), 500); + + return false; + } + + // Send mail to all superadministrators id + foreach ($rows as $row) + { + $return = JFactory::getMailer()->sendMail($data['mailfrom'], $data['fromname'], $row->email, $emailSubject, $emailBodyAdmin); + + // Check for an error. + if ($return !== true) + { + $this->setError(JText::_('COM_USERS_REGISTRATION_ACTIVATION_NOTIFY_SEND_MAIL_FAILED')); + + return false; + } + } + } + + // Check for an error. + if ($return !== true) + { + $this->setError(JText::_('COM_USERS_REGISTRATION_SEND_MAIL_FAILED')); + + // Send a system message to administrators receiving system mails + $db = $this->getDbo(); + $query->clear() + ->select($db->quoteName('id')) + ->from($db->quoteName('#__users')) + ->where($db->quoteName('block') . ' = ' . (int) 0) + ->where($db->quoteName('sendEmail') . ' = ' . (int) 1); + $db->setQuery($query); + + try + { + $userids = $db->loadColumn(); + } + catch (RuntimeException $e) + { + $this->setError(JText::sprintf('COM_USERS_DATABASE_ERROR', $e->getMessage()), 500); + + return false; + } + + if (count($userids) > 0) + { + $jdate = new JDate; + + // Build the query to add the messages + foreach ($userids as $userid) + { + $values = array( + $db->quote($userid), + $db->quote($userid), + $db->quote($jdate->toSql()), + $db->quote(JText::_('COM_USERS_MAIL_SEND_FAILURE_SUBJECT')), + $db->quote(JText::sprintf('COM_USERS_MAIL_SEND_FAILURE_BODY', $return, $data['username'])) + ); + $query->clear() + ->insert($db->quoteName('#__messages')) + ->columns($db->quoteName(array('user_id_from', 'user_id_to', 'date_time', 'subject', 'message'))) + ->values(implode(',', $values)); + $db->setQuery($query); + + try + { + $db->execute(); + } + catch (RuntimeException $e) + { + $this->setError(JText::sprintf('COM_USERS_DATABASE_ERROR', $e->getMessage()), 500); + + return false; + } + } + } + + return false; + } + + if ($useractivation == 1) + { + return 'useractivate'; + } + elseif ($useractivation == 2) + { + return 'adminactivate'; + } + else + { + return $user->id; + } + } +} diff --git a/Sites/pages/components/com_users/models/remind.php b/Sites/pages/components/com_users/models/remind.php new file mode 100644 index 00000000..2fcf1578 --- /dev/null +++ b/Sites/pages/components/com_users/models/remind.php @@ -0,0 +1,201 @@ +loadForm('com_users.remind', 'remind', array('control' => 'jform', 'load_data' => $loadData)); + + if (empty($form)) + { + return false; + } + + return $form; + } + + /** + * Override preprocessForm to load the user plugin group instead of content. + * + * @param JForm $form A JForm object. + * @param mixed $data The data expected for the form. + * @param string $group The name of the plugin group to import (defaults to "content"). + * + * @return void + * + * @throws Exception if there is an error in the form event. + * + * @since 1.6 + */ + protected function preprocessForm(JForm $form, $data, $group = 'user') + { + parent::preprocessForm($form, $data, 'user'); + } + + /** + * Method to auto-populate the model state. + * + * Note. Calling getState in this method will result in recursion. + * + * @return void + * + * @since 1.6 + */ + protected function populateState() + { + // Get the application object. + $app = JFactory::getApplication(); + $params = $app->getParams('com_users'); + + // Load the parameters. + $this->setState('params', $params); + } + + /** + * Send the remind username email + * + * @param array $data Array with the data received from the form + * + * @return boolean + * + * @since 1.6 + */ + public function processRemindRequest($data) + { + // Get the form. + $form = $this->getForm(); + $data['email'] = JStringPunycode::emailToPunycode($data['email']); + + // Check for an error. + if (empty($form)) + { + return false; + } + + // Validate the data. + $data = $this->validate($form, $data); + + // Check for an error. + if ($data instanceof Exception) + { + return false; + } + + // Check the validation results. + if ($data === false) + { + // Get the validation messages from the form. + foreach ($form->getErrors() as $formError) + { + $this->setError($formError->getMessage()); + } + + return false; + } + + // Find the user id for the given email address. + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select('*') + ->from($db->quoteName('#__users')) + ->where('LOWER(' . $db->quoteName('email') . ') = LOWER(' . $db->quote($data['email']) . ')'); + + // Get the user id. + $db->setQuery($query); + + try + { + $user = $db->loadObject(); + } + catch (RuntimeException $e) + { + $this->setError(JText::sprintf('COM_USERS_DATABASE_ERROR', $e->getMessage()), 500); + + return false; + } + + // Check for a user. + if (empty($user)) + { + $this->setError(JText::_('COM_USERS_USER_NOT_FOUND')); + + return false; + } + + // Make sure the user isn't blocked. + if ($user->block) + { + $this->setError(JText::_('COM_USERS_USER_BLOCKED')); + + return false; + } + + $config = JFactory::getConfig(); + + // Assemble the login link. + $link = 'index.php?option=com_users&view=login'; + $mode = $config->get('force_ssl', 0) == 2 ? 1 : (-1); + + // Put together the email template data. + $data = ArrayHelper::fromObject($user); + $data['fromname'] = $config->get('fromname'); + $data['mailfrom'] = $config->get('mailfrom'); + $data['sitename'] = $config->get('sitename'); + $data['link_text'] = JRoute::_($link, false, $mode); + $data['link_html'] = JRoute::_($link, true, $mode); + + $subject = JText::sprintf( + 'COM_USERS_EMAIL_USERNAME_REMINDER_SUBJECT', + $data['sitename'] + ); + $body = JText::sprintf( + 'COM_USERS_EMAIL_USERNAME_REMINDER_BODY', + $data['sitename'], + $data['username'], + $data['link_text'] + ); + + // Send the password reset request email. + $return = JFactory::getMailer()->sendMail($data['mailfrom'], $data['fromname'], $user->email, $subject, $body); + + // Check for an error. + if ($return !== true) + { + $this->setError(JText::_('COM_USERS_MAIL_FAILED'), 500); + + return false; + } + + $dispatcher = \JEventDispatcher::getInstance(); + $dispatcher->trigger('onUserAfterRemind', array($user)); + + return true; + } +} diff --git a/Sites/pages/components/com_users/models/reset.php b/Sites/pages/components/com_users/models/reset.php new file mode 100644 index 00000000..2e7a6d53 --- /dev/null +++ b/Sites/pages/components/com_users/models/reset.php @@ -0,0 +1,526 @@ +loadForm('com_users.reset_request', 'reset_request', array('control' => 'jform', 'load_data' => $loadData)); + + if (empty($form)) + { + return false; + } + + return $form; + } + + /** + * Method to get the password reset complete form. + * + * @param array $data Data for the form. + * @param boolean $loadData True if the form is to load its own data (default case), false if not. + * + * @return JForm A JForm object on success, false on failure + * + * @since 1.6 + */ + public function getResetCompleteForm($data = array(), $loadData = true) + { + // Get the form. + $form = $this->loadForm('com_users.reset_complete', 'reset_complete', $options = array('control' => 'jform')); + + if (empty($form)) + { + return false; + } + + return $form; + } + + /** + * Method to get the password reset confirm form. + * + * @param array $data Data for the form. + * @param boolean $loadData True if the form is to load its own data (default case), false if not. + * + * @return JForm A JForm object on success, false on failure + * + * @since 1.6 + */ + public function getResetConfirmForm($data = array(), $loadData = true) + { + // Get the form. + $form = $this->loadForm('com_users.reset_confirm', 'reset_confirm', $options = array('control' => 'jform')); + + if (empty($form)) + { + return false; + } + else + { + $form->setValue('token', '', JFactory::getApplication()->input->get('token')); + } + + return $form; + } + + /** + * Override preprocessForm to load the user plugin group instead of content. + * + * @param JForm $form A JForm object. + * @param mixed $data The data expected for the form. + * @param string $group The name of the plugin group to import (defaults to "content"). + * + * @return void + * + * @throws Exception if there is an error in the form event. + * + * @since 1.6 + */ + protected function preprocessForm(JForm $form, $data, $group = 'user') + { + parent::preprocessForm($form, $data, $group); + } + + /** + * Method to auto-populate the model state. + * + * Note. Calling getState in this method will result in recursion. + * + * @return void + * + * @since 1.6 + */ + protected function populateState() + { + // Get the application object. + $params = JFactory::getApplication()->getParams('com_users'); + + // Load the parameters. + $this->setState('params', $params); + } + + /** + * Save the new password after reset is done + * + * @param array $data The data expected for the form. + * + * @return mixed Exception | JException | boolean + * + * @since 1.6 + */ + public function processResetComplete($data) + { + // Get the form. + $form = $this->getResetCompleteForm(); + + // Check for an error. + if ($form instanceof Exception) + { + return $form; + } + + // Filter and validate the form data. + $data = $form->filter($data); + $return = $form->validate($data); + + // Check for an error. + if ($return instanceof Exception) + { + return $return; + } + + // Check the validation results. + if ($return === false) + { + // Get the validation messages from the form. + foreach ($form->getErrors() as $formError) + { + $this->setError($formError->getMessage()); + } + + return false; + } + + // Get the token and user id from the confirmation process. + $app = JFactory::getApplication(); + $token = $app->getUserState('com_users.reset.token', null); + $userId = $app->getUserState('com_users.reset.user', null); + + // Check the token and user id. + if (empty($token) || empty($userId)) + { + return new JException(JText::_('COM_USERS_RESET_COMPLETE_TOKENS_MISSING'), 403); + } + + // Get the user object. + $user = JUser::getInstance($userId); + + // Check for a user and that the tokens match. + if (empty($user) || $user->activation !== $token) + { + $this->setError(JText::_('COM_USERS_USER_NOT_FOUND')); + + return false; + } + + // Make sure the user isn't blocked. + if ($user->block) + { + $this->setError(JText::_('COM_USERS_USER_BLOCKED')); + + return false; + } + + // Check if the user is reusing the current password if required to reset their password + if ($user->requireReset == 1 && JUserHelper::verifyPassword($data['password1'], $user->password)) + { + $this->setError(JText::_('JLIB_USER_ERROR_CANNOT_REUSE_PASSWORD')); + + return false; + } + + // Prepare user data. + $data['password'] = $data['password1']; + $data['activation'] = ''; + + // Update the user object. + if (!$user->bind($data)) + { + return new \Exception($user->getError(), 500); + } + + // Save the user to the database. + if (!$user->save(true)) + { + return new JException(JText::sprintf('COM_USERS_USER_SAVE_FAILED', $user->getError()), 500); + } + + // Flush the user data from the session. + $app->setUserState('com_users.reset.token', null); + $app->setUserState('com_users.reset.user', null); + + return true; + } + + /** + * Receive the reset password request + * + * @param array $data The data expected for the form. + * + * @return mixed Exception | JException | boolean + * + * @since 1.6 + */ + public function processResetConfirm($data) + { + // Get the form. + $form = $this->getResetConfirmForm(); + + // Check for an error. + if ($form instanceof Exception) + { + return $form; + } + + // Filter and validate the form data. + $data = $form->filter($data); + $return = $form->validate($data); + + // Check for an error. + if ($return instanceof Exception) + { + return $return; + } + + // Check the validation results. + if ($return === false) + { + // Get the validation messages from the form. + foreach ($form->getErrors() as $formError) + { + $this->setError($formError->getMessage()); + } + + return false; + } + + // Find the user id for the given token. + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select('activation') + ->select('id') + ->select('block') + ->from($db->quoteName('#__users')) + ->where($db->quoteName('username') . ' = ' . $db->quote($data['username'])); + + // Get the user id. + $db->setQuery($query); + + try + { + $user = $db->loadObject(); + } + catch (RuntimeException $e) + { + return new JException(JText::sprintf('COM_USERS_DATABASE_ERROR', $e->getMessage()), 500); + } + + // Check for a user. + if (empty($user)) + { + $this->setError(JText::_('COM_USERS_USER_NOT_FOUND')); + + return false; + } + + if (!$user->activation) + { + $this->setError(JText::_('COM_USERS_USER_NOT_FOUND')); + + return false; + } + + // Verify the token + if (!JUserHelper::verifyPassword($data['token'], $user->activation)) + { + $this->setError(JText::_('COM_USERS_USER_NOT_FOUND')); + + return false; + } + + // Make sure the user isn't blocked. + if ($user->block) + { + $this->setError(JText::_('COM_USERS_USER_BLOCKED')); + + return false; + } + + // Push the user data into the session. + $app = JFactory::getApplication(); + $app->setUserState('com_users.reset.token', $user->activation); + $app->setUserState('com_users.reset.user', $user->id); + + return true; + } + + /** + * Method to start the password reset process. + * + * @param array $data The data expected for the form. + * + * @return mixed Exception | JException | boolean + * + * @since 1.6 + */ + public function processResetRequest($data) + { + $config = JFactory::getConfig(); + + // Get the form. + $form = $this->getForm(); + + $data['email'] = JStringPunycode::emailToPunycode($data['email']); + + // Check for an error. + if ($form instanceof Exception) + { + return $form; + } + + // Filter and validate the form data. + $data = $form->filter($data); + $return = $form->validate($data); + + // Check for an error. + if ($return instanceof Exception) + { + return $return; + } + + // Check the validation results. + if ($return === false) + { + // Get the validation messages from the form. + foreach ($form->getErrors() as $formError) + { + $this->setError($formError->getMessage()); + } + + return false; + } + + // Find the user id for the given email address. + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select('id') + ->from($db->quoteName('#__users')) + ->where('LOWER(' . $db->quoteName('email') . ') = LOWER(' . $db->quote($data['email']) . ')'); + + // Get the user object. + $db->setQuery($query); + + try + { + $userId = $db->loadResult(); + } + catch (RuntimeException $e) + { + $this->setError(JText::sprintf('COM_USERS_DATABASE_ERROR', $e->getMessage()), 500); + + return false; + } + + // Check for a user. + if (empty($userId)) + { + $this->setError(JText::_('COM_USERS_INVALID_EMAIL')); + + return false; + } + + // Get the user object. + $user = JUser::getInstance($userId); + + // Make sure the user isn't blocked. + if ($user->block) + { + $this->setError(JText::_('COM_USERS_USER_BLOCKED')); + + return false; + } + + // Make sure the user isn't a Super Admin. + if ($user->authorise('core.admin')) + { + $this->setError(JText::_('COM_USERS_REMIND_SUPERADMIN_ERROR')); + + return false; + } + + // Make sure the user has not exceeded the reset limit + if (!$this->checkResetLimit($user)) + { + $resetLimit = (int) JFactory::getApplication()->getParams()->get('reset_time'); + $this->setError(JText::plural('COM_USERS_REMIND_LIMIT_ERROR_N_HOURS', $resetLimit)); + + return false; + } + + // Set the confirmation token. + $token = JApplicationHelper::getHash(JUserHelper::genRandomPassword()); + $hashedToken = JUserHelper::hashPassword($token); + + $user->activation = $hashedToken; + + // Save the user to the database. + if (!$user->save(true)) + { + return new JException(JText::sprintf('COM_USERS_USER_SAVE_FAILED', $user->getError()), 500); + } + + // Assemble the password reset confirmation link. + $mode = $config->get('force_ssl', 0) == 2 ? 1 : (-1); + $link = 'index.php?option=com_users&view=reset&layout=confirm&token=' . $token; + + // Put together the email template data. + $data = $user->getProperties(); + $data['fromname'] = $config->get('fromname'); + $data['mailfrom'] = $config->get('mailfrom'); + $data['sitename'] = $config->get('sitename'); + $data['link_text'] = JRoute::_($link, false, $mode); + $data['link_html'] = JRoute::_($link, true, $mode); + $data['token'] = $token; + + $subject = JText::sprintf( + 'COM_USERS_EMAIL_PASSWORD_RESET_SUBJECT', + $data['sitename'] + ); + + $body = JText::sprintf( + 'COM_USERS_EMAIL_PASSWORD_RESET_BODY', + $data['sitename'], + $data['token'], + $data['link_text'] + ); + + // Send the password reset request email. + $return = JFactory::getMailer()->sendMail($data['mailfrom'], $data['fromname'], $user->email, $subject, $body); + + // Check for an error. + if ($return !== true) + { + return new JException(JText::_('COM_USERS_MAIL_FAILED'), 500); + } + + return true; + } + + /** + * Method to check if user reset limit has been exceeded within the allowed time period. + * + * @param JUser $user User doing the password reset + * + * @return boolean true if user can do the reset, false if limit exceeded + * + * @since 2.5 + */ + public function checkResetLimit($user) + { + $params = JFactory::getApplication()->getParams(); + $maxCount = (int) $params->get('reset_count'); + $resetHours = (int) $params->get('reset_time'); + $result = true; + + $lastResetTime = strtotime($user->lastResetTime) ?: 0; + $hoursSinceLastReset = (strtotime(JFactory::getDate()->toSql()) - $lastResetTime) / 3600; + + if ($hoursSinceLastReset > $resetHours) + { + // If it's been long enough, start a new reset count + $user->lastResetTime = JFactory::getDate()->toSql(); + $user->resetCount = 1; + } + elseif ($user->resetCount < $maxCount) + { + // If we are under the max count, just increment the counter + ++$user->resetCount; + } + else + { + // At this point, we know we have exceeded the maximum resets for the time period + $result = false; + } + + return $result; + } +} diff --git a/Sites/pages/components/com_users/models/rules/loginuniquefield.php b/Sites/pages/components/com_users/models/rules/loginuniquefield.php new file mode 100644 index 00000000..02b4e9f4 --- /dev/null +++ b/Sites/pages/components/com_users/models/rules/loginuniquefield.php @@ -0,0 +1,56 @@ +` tag for the form field object. + * @param mixed $value The form field value to validate. + * @param string $group The field name group control value. This acts as an array container for the field. + * For example if the field has name="foo" and the group value is set to "bar" then the + * full field name would end up being "bar[foo]". + * @param Registry $input An optional Registry object with the entire data set to validate against the entire form. + * @param JForm $form The form object for which the field is being tested. + * + * @return boolean True if the value is valid, false otherwise. + * + * @since 3.6 + */ + public function test(SimpleXMLElement $element, $value, $group = null, Registry $input = null, JForm $form = null) + { + $loginRedirectUrl = $input['params']->login_redirect_url; + $loginRedirectMenuitem = $input['params']->login_redirect_menuitem; + + if ($form === null) + { + throw new InvalidArgumentException(sprintf('The value for $form must not be null in %s', get_class($this))); + } + + if ($input === null) + { + throw new InvalidArgumentException(sprintf('The value for $input must not be null in %s', get_class($this))); + } + + return true; + } +} diff --git a/Sites/pages/components/com_users/models/rules/logoutuniquefield.php b/Sites/pages/components/com_users/models/rules/logoutuniquefield.php new file mode 100644 index 00000000..7d663a29 --- /dev/null +++ b/Sites/pages/components/com_users/models/rules/logoutuniquefield.php @@ -0,0 +1,56 @@ +` tag for the form field object. + * @param mixed $value The form field value to validate. + * @param string $group The field name group control value. This acts as an array container for the field. + * For example if the field has name="foo" and the group value is set to "bar" then the + * full field name would end up being "bar[foo]". + * @param Registry $input An optional Registry object with the entire data set to validate against the entire form. + * @param JForm $form The form object for which the field is being tested. + * + * @return boolean True if the value is valid, false otherwise. + * + * @since 3.6 + */ + public function test(SimpleXMLElement $element, $value, $group = null, Registry $input = null, JForm $form = null) + { + $logoutRedirectUrl = $input['params']->logout_redirect_url; + $logoutRedirectMenuitem = $input['params']->logout_redirect_menuitem; + + if ($form === null) + { + throw new InvalidArgumentException(sprintf('The value for $form must not be null in %s', get_class($this))); + } + + if ($input === null) + { + throw new InvalidArgumentException(sprintf('The value for $input must not be null in %s', get_class($this))); + } + + return true; + } +} diff --git a/Sites/pages/components/com_users/router.php b/Sites/pages/components/com_users/router.php new file mode 100644 index 00000000..eb40cc3a --- /dev/null +++ b/Sites/pages/components/com_users/router.php @@ -0,0 +1,89 @@ +registerView(new JComponentRouterViewconfiguration('login')); + $profile = new JComponentRouterViewconfiguration('profile'); + $profile->addLayout('edit'); + $this->registerView($profile); + $this->registerView(new JComponentRouterViewconfiguration('registration')); + $this->registerView(new JComponentRouterViewconfiguration('remind')); + $this->registerView(new JComponentRouterViewconfiguration('reset')); + + parent::__construct($app, $menu); + + $this->attachRule(new JComponentRouterRulesMenu($this)); + + $params = JComponentHelper::getParams('com_users'); + + if ($params->get('sef_advanced', 0)) + { + $this->attachRule(new JComponentRouterRulesStandard($this)); + $this->attachRule(new JComponentRouterRulesNomenu($this)); + } + else + { + JLoader::register('UsersRouterRulesLegacy', __DIR__ . '/helpers/legacyrouter.php'); + $this->attachRule(new UsersRouterRulesLegacy($this)); + } + } +} + +/** + * Users router functions + * + * These functions are proxys for the new router interface + * for old SEF extensions. + * + * @param array &$query REQUEST query + * + * @return array Segments of the SEF url + * + * @deprecated 4.0 Use Class based routers instead + */ +function usersBuildRoute(&$query) +{ + $app = JFactory::getApplication(); + $router = new UsersRouter($app, $app->getMenu()); + + return $router->build($query); +} + +/** + * Convert SEF URL segments into query variables + * + * @param array $segments Segments in the current URL + * + * @return array Query variables + * + * @deprecated 4.0 Use Class based routers instead + */ +function usersParseRoute($segments) +{ + $app = JFactory::getApplication(); + $router = new UsersRouter($app, $app->getMenu()); + + return $router->parse($segments); +} diff --git a/Sites/pages/components/com_users/users.php b/Sites/pages/components/com_users/users.php new file mode 100644 index 00000000..1bdd441e --- /dev/null +++ b/Sites/pages/components/com_users/users.php @@ -0,0 +1,16 @@ +execute(JFactory::getApplication()->input->get('task', 'display')); +$controller->redirect(); diff --git a/Sites/pages/components/com_users/views/login/tmpl/default.php b/Sites/pages/components/com_users/views/login/tmpl/default.php new file mode 100644 index 00000000..24ba5147 --- /dev/null +++ b/Sites/pages/components/com_users/views/login/tmpl/default.php @@ -0,0 +1,23 @@ +user->get('cookieLogin'); + +if (!empty($cookieLogin) || $this->user->get('guest')) +{ + // The user is not logged in or needs to provide a password. + echo $this->loadTemplate('login'); +} +else +{ + // The user is already logged in. + echo $this->loadTemplate('logout'); +} diff --git a/Sites/pages/components/com_users/views/login/tmpl/default.xml b/Sites/pages/components/com_users/views/login/tmpl/default.xml new file mode 100644 index 00000000..5797631a --- /dev/null +++ b/Sites/pages/components/com_users/views/login/tmpl/default.xml @@ -0,0 +1,166 @@ + + + + + + + + + + + + + +
        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        +
        +
        diff --git a/Sites/pages/components/com_users/views/login/tmpl/default_login.php b/Sites/pages/components/com_users/views/login/tmpl/default_login.php new file mode 100644 index 00000000..f5781cda --- /dev/null +++ b/Sites/pages/components/com_users/views/login/tmpl/default_login.php @@ -0,0 +1,88 @@ + +
        + params->get('show_page_heading')) : ?> + + + params->get('logindescription_show') == 1 && str_replace(' ', '', $this->params->get('login_description')) != '') || $this->params->get('login_image') != '') : ?> + + +
        +
        + form->renderFieldset('credentials'); ?> + tfa) : ?> + form->renderField('secretkey'); ?> + + +
        +
        + +
        +
        + +
        +
        + +
        +
        + +
        +
        + form->getValue('return', '', $this->params->get('login_redirect_url', $this->params->get('login_redirect_menuitem'))); ?> + + +
        +
        +
        +
        + +
        diff --git a/Sites/pages/components/com_users/views/login/tmpl/default_logout.php b/Sites/pages/components/com_users/views/login/tmpl/default_logout.php new file mode 100644 index 00000000..44cd77d5 --- /dev/null +++ b/Sites/pages/components/com_users/views/login/tmpl/default_logout.php @@ -0,0 +1,49 @@ + +
        + params->get('show_page_heading')) : ?> + + + params->get('logoutdescription_show') == 1 && str_replace(' ', '', $this->params->get('logout_description')) != '')|| $this->params->get('logout_image') != '') : ?> +
        + + params->get('logoutdescription_show') == 1) : ?> + params->get('logout_description'); ?> + + params->get('logout_image') != '') : ?> + <?php echo JText::_('COM_USER_LOGOUT_IMAGE_ALT'); ?> + + params->get('logoutdescription_show') == 1 && str_replace(' ', '', $this->params->get('logout_description')) != '')|| $this->params->get('logout_image') != '') : ?> +
        + +
        +
        +
        + +
        +
        + params->get('logout_redirect_url')) : ?> + + + + + +
        +
        diff --git a/Sites/pages/components/com_users/views/login/tmpl/logout.xml b/Sites/pages/components/com_users/views/login/tmpl/logout.xml new file mode 100644 index 00000000..8dab8b30 --- /dev/null +++ b/Sites/pages/components/com_users/views/login/tmpl/logout.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + +
        + +
        +
        + + + +
        + + + +
        +
        +
        diff --git a/Sites/pages/components/com_users/views/login/view.html.php b/Sites/pages/components/com_users/views/login/view.html.php new file mode 100644 index 00000000..dd8995a7 --- /dev/null +++ b/Sites/pages/components/com_users/views/login/view.html.php @@ -0,0 +1,131 @@ +user = JFactory::getUser(); + $this->form = $this->get('Form'); + $this->state = $this->get('State'); + $this->params = $this->state->get('params'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + JError::raiseError(500, implode('
        ', $errors)); + + return false; + } + + // Check for layout override + $active = JFactory::getApplication()->getMenu()->getActive(); + + if (isset($active->query['layout'])) + { + $this->setLayout($active->query['layout']); + } + + $tfa = JAuthenticationHelper::getTwoFactorMethods(); + $this->tfa = is_array($tfa) && count($tfa) > 1; + + // Escape strings for HTML output + $this->pageclass_sfx = htmlspecialchars($this->params->get('pageclass_sfx'), ENT_COMPAT, 'UTF-8'); + + $this->prepareDocument(); + + parent::display($tpl); + } + + /** + * Prepares the document + * + * @return void + * + * @since 1.6 + */ + protected function prepareDocument() + { + $app = JFactory::getApplication(); + $menus = $app->getMenu(); + $user = JFactory::getUser(); + $login = $user->get('guest') ? true : false; + $title = null; + + // Because the application sets a default page title, + // we need to get it from the menu item itself + $menu = $menus->getActive(); + + if ($menu) + { + $this->params->def('page_heading', $this->params->get('page_title', $menu->title)); + } + else + { + $this->params->def('page_heading', $login ? JText::_('JLOGIN') : JText::_('JLOGOUT')); + } + + $title = $this->params->get('page_title', ''); + + if (empty($title)) + { + $title = $app->get('sitename'); + } + elseif ($app->get('sitename_pagetitles', 0) == 1) + { + $title = JText::sprintf('JPAGETITLE', $app->get('sitename'), $title); + } + elseif ($app->get('sitename_pagetitles', 0) == 2) + { + $title = JText::sprintf('JPAGETITLE', $title, $app->get('sitename')); + } + + $this->document->setTitle($title); + + if ($this->params->get('menu-meta_description')) + { + $this->document->setDescription($this->params->get('menu-meta_description')); + } + + if ($this->params->get('menu-meta_keywords')) + { + $this->document->setMetadata('keywords', $this->params->get('menu-meta_keywords')); + } + + if ($this->params->get('robots')) + { + $this->document->setMetadata('robots', $this->params->get('robots')); + } + } +} diff --git a/Sites/pages/components/com_users/views/profile/tmpl/default.php b/Sites/pages/components/com_users/views/profile/tmpl/default.php new file mode 100644 index 00000000..191de0e6 --- /dev/null +++ b/Sites/pages/components/com_users/views/profile/tmpl/default.php @@ -0,0 +1,34 @@ + +
        + params->get('show_page_heading')) : ?> + + + id == $this->data->id) : ?> + + + loadTemplate('core'); ?> + loadTemplate('params'); ?> + loadTemplate('custom'); ?> +
        diff --git a/Sites/pages/components/com_users/views/profile/tmpl/default.xml b/Sites/pages/components/com_users/views/profile/tmpl/default.xml new file mode 100644 index 00000000..c9140969 --- /dev/null +++ b/Sites/pages/components/com_users/views/profile/tmpl/default.xml @@ -0,0 +1,11 @@ + + + + + + + + + diff --git a/Sites/pages/components/com_users/views/profile/tmpl/default_core.php b/Sites/pages/components/com_users/views/profile/tmpl/default_core.php new file mode 100644 index 00000000..7d190370 --- /dev/null +++ b/Sites/pages/components/com_users/views/profile/tmpl/default_core.php @@ -0,0 +1,49 @@ + +
        + + + +
        +
        + +
        +
        + escape($this->data->name); ?> +
        +
        + +
        +
        + escape($this->data->username); ?> +
        +
        + +
        +
        + data->registerDate, JText::_('DATE_FORMAT_LC1')); ?> +
        +
        + +
        + data->lastvisitDate != $this->db->getNullDate()) : ?> +
        + data->lastvisitDate, JText::_('DATE_FORMAT_LC1')); ?> +
        + +
        + +
        + +
        +
        diff --git a/Sites/pages/components/com_users/views/profile/tmpl/default_custom.php b/Sites/pages/components/com_users/views/profile/tmpl/default_custom.php new file mode 100644 index 00000000..2096596c --- /dev/null +++ b/Sites/pages/components/com_users/views/profile/tmpl/default_custom.php @@ -0,0 +1,70 @@ +form->getFieldsets(); + +if (isset($fieldsets['core'])) +{ + unset($fieldsets['core']); +} + +if (isset($fieldsets['params'])) +{ + unset($fieldsets['params']); +} + +$tmp = isset($this->data->jcfields) ? $this->data->jcfields : array(); +$customFields = array(); + +foreach ($tmp as $customField) +{ + $customFields[$customField->name] = $customField; +} + +?> + $fieldset) : ?> + form->getFieldset($group); ?> + +
        + label) && ($legend = trim(JText::_($fieldset->label))) !== '') : ?> + + + description) && trim($fieldset->description)) : ?> +

        escape(JText::_($fieldset->description)); ?>

        + +
        + + hidden && $field->type !== 'Spacer') : ?> +
        + title; ?> +
        +
        + fieldname, $customFields)) : ?> + fieldname]->value) ? $customFields[$field->fieldname]->value : JText::_('COM_USERS_PROFILE_VALUE_NOT_FOUND'); ?> + id)) : ?> + id, $field->value); ?> + fieldname)) : ?> + fieldname, $field->value); ?> + type)) : ?> + type, $field->value); ?> + + value); ?> + +
        + + +
        +
        + + diff --git a/Sites/pages/components/com_users/views/profile/tmpl/default_params.php b/Sites/pages/components/com_users/views/profile/tmpl/default_params.php new file mode 100644 index 00000000..e303d51b --- /dev/null +++ b/Sites/pages/components/com_users/views/profile/tmpl/default_params.php @@ -0,0 +1,40 @@ + +form->getFieldset('params'); ?> + +
        + +
        + + hidden) : ?> +
        + title; ?> +
        +
        + id)) : ?> + id, $field->value); ?> + fieldname)) : ?> + fieldname, $field->value); ?> + type)) : ?> + type, $field->value); ?> + + value); ?> + +
        + + +
        +
        + diff --git a/Sites/pages/components/com_users/views/profile/tmpl/edit.php b/Sites/pages/components/com_users/views/profile/tmpl/edit.php new file mode 100644 index 00000000..792fc3a4 --- /dev/null +++ b/Sites/pages/components/com_users/views/profile/tmpl/edit.php @@ -0,0 +1,152 @@ +load('plg_user_profile', JPATH_ADMINISTRATOR); + +?> +
        + params->get('show_page_heading')) : ?> + + + +
        + + form->getFieldsets() as $group => $fieldset) : ?> + form->getFieldset($group); ?> + +
        + + label)) : ?> + + label); ?> + + + description) && trim($fieldset->description)) : ?> +

        + escape(JText::_($fieldset->description)); ?> +

        + + + + + hidden) : ?> + input; ?> + +
        +
        + label; ?> + required && $field->type !== 'Spacer') : ?> + + + + +
        +
        + fieldname === 'password1') : ?> + + + + input; ?> +
        +
        + + +
        + + + twofactormethods) > 1) : ?> +
        + +
        +
        + +
        +
        + twofactormethods, 'jform[twofactor][method]', array('onchange' => 'Joomla.twoFactorMethodChange()'), 'value', 'text', $this->otpConfig->method, 'jform_twofactor_method', false); ?> +
        +
        +
        + twofactorform as $form) : ?> + otpConfig->method ? 'display: block' : 'display: none'; ?> +
        + +
        + +
        +
        +
        + + + +
        + +
        + otpConfig->otep)) : ?> +
        + +
        + + otpConfig->otep as $otep) : ?> + + --- + + +
        + +
        + +
        +
        + + + + + + +
        +
        + +
        +
        diff --git a/Sites/pages/components/com_users/views/profile/tmpl/edit.xml b/Sites/pages/components/com_users/views/profile/tmpl/edit.xml new file mode 100644 index 00000000..7c8f3346 --- /dev/null +++ b/Sites/pages/components/com_users/views/profile/tmpl/edit.xml @@ -0,0 +1,11 @@ + + + + + + + + + diff --git a/Sites/pages/components/com_users/views/profile/view.html.php b/Sites/pages/components/com_users/views/profile/view.html.php new file mode 100644 index 00000000..452fe14d --- /dev/null +++ b/Sites/pages/components/com_users/views/profile/view.html.php @@ -0,0 +1,168 @@ +data = $this->get('Data'); + $this->form = $this->getModel()->getForm(new JObject(array('id' => $user->id))); + $this->state = $this->get('State'); + $this->params = $this->state->get('params'); + $this->twofactorform = $this->get('Twofactorform'); + $this->twofactormethods = UsersHelper::getTwoFactorMethods(); + $this->otpConfig = $this->get('OtpConfig'); + $this->db = JFactory::getDbo(); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + JError::raiseError(500, implode('
        ', $errors)); + + return false; + } + + // View also takes responsibility for checking if the user logged in with remember me. + $cookieLogin = $user->get('cookieLogin'); + + if (!empty($cookieLogin)) + { + // If so, the user must login to edit the password and other data. + // What should happen here? Should we force a logout which destroys the cookies? + $app = JFactory::getApplication(); + $app->enqueueMessage(JText::_('JGLOBAL_REMEMBER_MUST_LOGIN'), 'message'); + $app->redirect(JRoute::_('index.php?option=com_users&view=login', false)); + + return false; + } + + // Check if a user was found. + if (!$this->data->id) + { + JError::raiseError(404, JText::_('JERROR_USERS_PROFILE_NOT_FOUND')); + + return false; + } + + JPluginHelper::importPlugin('content'); + $this->data->text = ''; + JEventDispatcher::getInstance()->trigger('onContentPrepare', array ('com_users.user', &$this->data, &$this->data->params, 0)); + unset($this->data->text); + + // Check for layout override + $active = JFactory::getApplication()->getMenu()->getActive(); + + if (isset($active->query['layout'])) + { + $this->setLayout($active->query['layout']); + } + + // Escape strings for HTML output + $this->pageclass_sfx = htmlspecialchars($this->params->get('pageclass_sfx')); + + $this->prepareDocument(); + + return parent::display($tpl); + } + + /** + * Prepares the document + * + * @return void + * + * @since 1.6 + */ + protected function prepareDocument() + { + $app = JFactory::getApplication(); + $menus = $app->getMenu(); + $user = JFactory::getUser(); + $title = null; + + // Because the application sets a default page title, + // we need to get it from the menu item itself + $menu = $menus->getActive(); + + if ($menu) + { + $this->params->def('page_heading', $this->params->get('page_title', $user->name)); + } + else + { + $this->params->def('page_heading', JText::_('COM_USERS_PROFILE')); + } + + $title = $this->params->get('page_title', ''); + + if (empty($title)) + { + $title = $app->get('sitename'); + } + elseif ($app->get('sitename_pagetitles', 0) == 1) + { + $title = JText::sprintf('JPAGETITLE', $app->get('sitename'), $title); + } + elseif ($app->get('sitename_pagetitles', 0) == 2) + { + $title = JText::sprintf('JPAGETITLE', $title, $app->get('sitename')); + } + + $this->document->setTitle($title); + + if ($this->params->get('menu-meta_description')) + { + $this->document->setDescription($this->params->get('menu-meta_description')); + } + + if ($this->params->get('menu-meta_keywords')) + { + $this->document->setMetadata('keywords', $this->params->get('menu-meta_keywords')); + } + + if ($this->params->get('robots')) + { + $this->document->setMetadata('robots', $this->params->get('robots')); + } + } +} diff --git a/Sites/pages/components/com_users/views/registration/tmpl/complete.php b/Sites/pages/components/com_users/views/registration/tmpl/complete.php new file mode 100644 index 00000000..79c537d5 --- /dev/null +++ b/Sites/pages/components/com_users/views/registration/tmpl/complete.php @@ -0,0 +1,19 @@ + +
        + params->get('show_page_heading')) : ?> +

        + escape($this->params->get('page_heading')); ?> +

        + +
        diff --git a/Sites/pages/components/com_users/views/registration/tmpl/default.php b/Sites/pages/components/com_users/views/registration/tmpl/default.php new file mode 100644 index 00000000..f142f829 --- /dev/null +++ b/Sites/pages/components/com_users/views/registration/tmpl/default.php @@ -0,0 +1,50 @@ + +
        + params->get('show_page_heading')) : ?> + + +
        + + form->getFieldsets() as $fieldset) : ?> + form->getFieldset($fieldset->name); ?> + +
        + + label)) : ?> + label); ?> + + form->renderFieldset($fieldset->name); ?> +
        + + +
        +
        + + + + + + +
        +
        + +
        +
        diff --git a/Sites/pages/components/com_users/views/registration/tmpl/default.xml b/Sites/pages/components/com_users/views/registration/tmpl/default.xml new file mode 100644 index 00000000..35e0551e --- /dev/null +++ b/Sites/pages/components/com_users/views/registration/tmpl/default.xml @@ -0,0 +1,11 @@ + + + + + + + + + diff --git a/Sites/pages/components/com_users/views/registration/view.html.php b/Sites/pages/components/com_users/views/registration/view.html.php new file mode 100644 index 00000000..138b8833 --- /dev/null +++ b/Sites/pages/components/com_users/views/registration/view.html.php @@ -0,0 +1,128 @@ +form = $this->get('Form'); + $this->data = $this->get('Data'); + $this->state = $this->get('State'); + $this->params = $this->state->get('params'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + JError::raiseError(500, implode('
        ', $errors)); + + return false; + } + + // Check for layout override + $active = JFactory::getApplication()->getMenu()->getActive(); + + if (isset($active->query['layout'])) + { + $this->setLayout($active->query['layout']); + } + + // Escape strings for HTML output + $this->pageclass_sfx = htmlspecialchars($this->params->get('pageclass_sfx'), ENT_COMPAT, 'UTF-8'); + + $this->prepareDocument(); + + return parent::display($tpl); + } + + /** + * Prepares the document. + * + * @return void + * + * @since 1.6 + */ + protected function prepareDocument() + { + $app = JFactory::getApplication(); + $menus = $app->getMenu(); + $title = null; + + // Because the application sets a default page title, + // we need to get it from the menu item itself + $menu = $menus->getActive(); + + if ($menu) + { + $this->params->def('page_heading', $this->params->get('page_title', $menu->title)); + } + else + { + $this->params->def('page_heading', JText::_('COM_USERS_REGISTRATION')); + } + + $title = $this->params->get('page_title', ''); + + if (empty($title)) + { + $title = $app->get('sitename'); + } + elseif ($app->get('sitename_pagetitles', 0) == 1) + { + $title = JText::sprintf('JPAGETITLE', $app->get('sitename'), $title); + } + elseif ($app->get('sitename_pagetitles', 0) == 2) + { + $title = JText::sprintf('JPAGETITLE', $title, $app->get('sitename')); + } + + $this->document->setTitle($title); + + if ($this->params->get('menu-meta_description')) + { + $this->document->setDescription($this->params->get('menu-meta_description')); + } + + if ($this->params->get('menu-meta_keywords')) + { + $this->document->setMetadata('keywords', $this->params->get('menu-meta_keywords')); + } + + if ($this->params->get('robots')) + { + $this->document->setMetadata('robots', $this->params->get('robots')); + } + } +} diff --git a/Sites/pages/components/com_users/views/remind/tmpl/default.php b/Sites/pages/components/com_users/views/remind/tmpl/default.php new file mode 100644 index 00000000..4a554b98 --- /dev/null +++ b/Sites/pages/components/com_users/views/remind/tmpl/default.php @@ -0,0 +1,42 @@ + +
        + params->get('show_page_heading')) : ?> + + +
        + form->getFieldsets() as $fieldset) : ?> +
        + label)) : ?> +

        label); ?>

        + + form->renderFieldset($fieldset->name); ?> +
        + +
        +
        + +
        +
        + +
        +
        diff --git a/Sites/pages/components/com_users/views/remind/tmpl/default.xml b/Sites/pages/components/com_users/views/remind/tmpl/default.xml new file mode 100644 index 00000000..65832a03 --- /dev/null +++ b/Sites/pages/components/com_users/views/remind/tmpl/default.xml @@ -0,0 +1,11 @@ + + + + + + + + + diff --git a/Sites/pages/components/com_users/views/remind/view.html.php b/Sites/pages/components/com_users/views/remind/view.html.php new file mode 100644 index 00000000..178dc644 --- /dev/null +++ b/Sites/pages/components/com_users/views/remind/view.html.php @@ -0,0 +1,123 @@ +form = $this->get('Form'); + $this->state = $this->get('State'); + $this->params = $this->state->params; + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + JError::raiseError(500, implode('
        ', $errors)); + + return false; + } + + // Check for layout override + $active = JFactory::getApplication()->getMenu()->getActive(); + + if (isset($active->query['layout'])) + { + $this->setLayout($active->query['layout']); + } + + // Escape strings for HTML output + $this->pageclass_sfx = htmlspecialchars($this->params->get('pageclass_sfx'), ENT_COMPAT, 'UTF-8'); + + $this->prepareDocument(); + + parent::display($tpl); + } + + /** + * Prepares the document. + * + * @return void + * + * @since 1.6 + */ + protected function prepareDocument() + { + $app = JFactory::getApplication(); + $menus = $app->getMenu(); + $title = null; + + // Because the application sets a default page title, + // we need to get it from the menu item itself + $menu = $menus->getActive(); + + if ($menu) + { + $this->params->def('page_heading', $this->params->get('page_title', $menu->title)); + } + else + { + $this->params->def('page_heading', JText::_('COM_USERS_REMIND')); + } + + $title = $this->params->get('page_title', ''); + + if (empty($title)) + { + $title = $app->get('sitename'); + } + elseif ($app->get('sitename_pagetitles', 0) == 1) + { + $title = JText::sprintf('JPAGETITLE', $app->get('sitename'), $title); + } + elseif ($app->get('sitename_pagetitles', 0) == 2) + { + $title = JText::sprintf('JPAGETITLE', $title, $app->get('sitename')); + } + + $this->document->setTitle($title); + + if ($this->params->get('menu-meta_description')) + { + $this->document->setDescription($this->params->get('menu-meta_description')); + } + + if ($this->params->get('menu-meta_keywords')) + { + $this->document->setMetadata('keywords', $this->params->get('menu-meta_keywords')); + } + + if ($this->params->get('robots')) + { + $this->document->setMetadata('robots', $this->params->get('robots')); + } + } +} diff --git a/Sites/pages/components/com_users/views/reset/tmpl/complete.php b/Sites/pages/components/com_users/views/reset/tmpl/complete.php new file mode 100644 index 00000000..55aa591a --- /dev/null +++ b/Sites/pages/components/com_users/views/reset/tmpl/complete.php @@ -0,0 +1,42 @@ + +
        + params->get('show_page_heading')) : ?> + + +
        + form->getFieldsets() as $fieldset) : ?> +
        + label)) : ?> +

        label); ?>

        + + form->renderFieldset($fieldset->name); ?> +
        + +
        +
        + +
        +
        + +
        +
        diff --git a/Sites/pages/components/com_users/views/reset/tmpl/confirm.php b/Sites/pages/components/com_users/views/reset/tmpl/confirm.php new file mode 100644 index 00000000..fb4adf6d --- /dev/null +++ b/Sites/pages/components/com_users/views/reset/tmpl/confirm.php @@ -0,0 +1,42 @@ + +
        + params->get('show_page_heading')) : ?> + + +
        + form->getFieldsets() as $fieldset) : ?> +
        + label)) : ?> +

        label); ?>

        + + form->renderFieldset($fieldset->name); ?> +
        + +
        +
        + +
        +
        + +
        +
        diff --git a/Sites/pages/components/com_users/views/reset/tmpl/default.php b/Sites/pages/components/com_users/views/reset/tmpl/default.php new file mode 100644 index 00000000..bda6e1a7 --- /dev/null +++ b/Sites/pages/components/com_users/views/reset/tmpl/default.php @@ -0,0 +1,42 @@ + +
        + params->get('show_page_heading')) : ?> + + +
        + form->getFieldsets() as $fieldset) : ?> +
        + label)) : ?> +

        label); ?>

        + + form->renderFieldset($fieldset->name); ?> +
        + +
        +
        + +
        +
        + +
        +
        diff --git a/Sites/pages/components/com_users/views/reset/tmpl/default.xml b/Sites/pages/components/com_users/views/reset/tmpl/default.xml new file mode 100644 index 00000000..e1f8b31c --- /dev/null +++ b/Sites/pages/components/com_users/views/reset/tmpl/default.xml @@ -0,0 +1,11 @@ + + + + + + + + + diff --git a/Sites/pages/components/com_users/views/reset/view.html.php b/Sites/pages/components/com_users/views/reset/view.html.php new file mode 100644 index 00000000..106b9019 --- /dev/null +++ b/Sites/pages/components/com_users/views/reset/view.html.php @@ -0,0 +1,133 @@ +getLayout(); + + // Check that the name is valid - has an associated model. + if (!in_array($name, array('confirm', 'complete'))) + { + $name = 'default'; + } + + if ('default' === $name) + { + $formname = 'Form'; + } + else + { + $formname = ucfirst($this->_name) . ucfirst($name) . 'Form'; + } + + // Get the view data. + $this->form = $this->get($formname); + $this->state = $this->get('State'); + $this->params = $this->state->params; + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + JError::raiseError(500, implode('
        ', $errors)); + + return false; + } + + // Escape strings for HTML output + $this->pageclass_sfx = htmlspecialchars($this->params->get('pageclass_sfx'), ENT_COMPAT, 'UTF-8'); + + $this->prepareDocument(); + + parent::display($tpl); + } + + /** + * Prepares the document. + * + * @return void + * + * @since 1.6 + */ + protected function prepareDocument() + { + $app = JFactory::getApplication(); + $menus = $app->getMenu(); + $title = null; + + // Because the application sets a default page title, + // we need to get it from the menu item itself + $menu = $menus->getActive(); + + if ($menu) + { + $this->params->def('page_heading', $this->params->get('page_title', $menu->title)); + } + else + { + $this->params->def('page_heading', JText::_('COM_USERS_RESET')); + } + + $title = $this->params->get('page_title', ''); + + if (empty($title)) + { + $title = $app->get('sitename'); + } + elseif ($app->get('sitename_pagetitles', 0) == 1) + { + $title = JText::sprintf('JPAGETITLE', $app->get('sitename'), $title); + } + elseif ($app->get('sitename_pagetitles', 0) == 2) + { + $title = JText::sprintf('JPAGETITLE', $title, $app->get('sitename')); + } + + $this->document->setTitle($title); + + if ($this->params->get('menu-meta_description')) + { + $this->document->setDescription($this->params->get('menu-meta_description')); + } + + if ($this->params->get('menu-meta_keywords')) + { + $this->document->setMetadata('keywords', $this->params->get('menu-meta_keywords')); + } + + if ($this->params->get('robots')) + { + $this->document->setMetadata('robots', $this->params->get('robots')); + } + } +} diff --git a/Sites/pages/components/com_wrapper/controller.php b/Sites/pages/components/com_wrapper/controller.php new file mode 100644 index 00000000..5f18ff6b --- /dev/null +++ b/Sites/pages/components/com_wrapper/controller.php @@ -0,0 +1,39 @@ +input->get('view', 'wrapper'); + $this->input->set('view', $vName); + + return parent::display($cachable, array('Itemid' => 'INT')); + } +} diff --git a/Sites/pages/components/com_wrapper/router.php b/Sites/pages/components/com_wrapper/router.php new file mode 100644 index 00000000..cdbff114 --- /dev/null +++ b/Sites/pages/components/com_wrapper/router.php @@ -0,0 +1,89 @@ + 'wrapper'); + } +} + +/** + * Wrapper router functions + * + * These functions are proxys for the new router interface + * for old SEF extensions. + * + * @param array &$query An array of URL arguments + * + * @return array The URL arguments to use to assemble the subsequent URL. + * + * @deprecated 4.0 Use Class based routers instead + */ +function wrapperBuildRoute(&$query) +{ + $router = new WrapperRouter; + + return $router->build($query); +} + +/** + * Wrapper router functions + * + * These functions are proxys for the new router interface + * for old SEF extensions. + * + * @param array $segments The segments of the URL to parse. + * + * @return array The URL attributes to be used by the application. + * + * @deprecated 4.0 Use Class based routers instead + */ +function wrapperParseRoute($segments) +{ + $router = new WrapperRouter; + + return $router->parse($segments); +} diff --git a/Sites/pages/components/com_wrapper/views/wrapper/tmpl/default.php b/Sites/pages/components/com_wrapper/views/wrapper/tmpl/default.php new file mode 100644 index 00000000..9d8dfda2 --- /dev/null +++ b/Sites/pages/components/com_wrapper/views/wrapper/tmpl/default.php @@ -0,0 +1,43 @@ + 'auto', 'relative' => true)); + +?> +
        + params->get('show_page_heading')) : ?> + + + +
        diff --git a/Sites/pages/components/com_wrapper/views/wrapper/tmpl/default.xml b/Sites/pages/components/com_wrapper/views/wrapper/tmpl/default.xml new file mode 100644 index 00000000..f0c1e350 --- /dev/null +++ b/Sites/pages/components/com_wrapper/views/wrapper/tmpl/default.xml @@ -0,0 +1,104 @@ + + + + + + + + + + + +
        + + +
        + + + + +
        + + + + + + + + + + + +
        + + +
        + + + + + + + + + + + + + + + + +
        +
        +
        diff --git a/Sites/pages/components/com_wrapper/views/wrapper/view.html.php b/Sites/pages/components/com_wrapper/views/wrapper/view.html.php new file mode 100644 index 00000000..a1a1276e --- /dev/null +++ b/Sites/pages/components/com_wrapper/views/wrapper/view.html.php @@ -0,0 +1,117 @@ +getParams(); + + // Because the application sets a default page title, we need to get it + // right from the menu item itself + $title = $params->get('page_title', ''); + + if (empty($title)) + { + $title = $app->get('sitename'); + } + elseif ($app->get('sitename_pagetitles', 0) == 1) + { + $title = JText::sprintf('JPAGETITLE', $app->get('sitename'), $title); + } + elseif ($app->get('sitename_pagetitles', 0) == 2) + { + $title = JText::sprintf('JPAGETITLE', $title, $app->get('sitename')); + } + + $this->document->setTitle($title); + + if ($params->get('menu-meta_description')) + { + $this->document->setDescription($params->get('menu-meta_description')); + } + + if ($params->get('menu-meta_keywords')) + { + $this->document->setMetadata('keywords', $params->get('menu-meta_keywords')); + } + + if ($params->get('robots')) + { + $this->document->setMetadata('robots', $params->get('robots')); + } + + $wrapper = new stdClass; + + // Auto height control + if ($params->def('height_auto')) + { + $wrapper->load = 'onload="iFrameHeight(this)"'; + } + else + { + $wrapper->load = ''; + } + + $url = $params->def('url', ''); + + if ($params->def('add_scheme', 1)) + { + // Adds 'http://' or 'https://' if none is set + if (strpos($url, '//') === 0) + { + // URL without scheme in component. Prepend current scheme. + $wrapper->url = JUri::getInstance()->toString(array('scheme')) . substr($url, 2); + } + elseif (strpos($url, '/') === 0) + { + // Relative URL in component. Use scheme + host + port. + $wrapper->url = JUri::getInstance()->toString(array('scheme', 'host', 'port')) . $url; + } + elseif (strpos($url, 'http://') !== 0 && strpos($url, 'https://') !== 0) + { + // URL doesn't start with either 'http://' or 'https://'. Add current scheme. + $wrapper->url = JUri::getInstance()->toString(array('scheme')) . $url; + } + else + { + // URL starts with either 'http://' or 'https://'. Do not change it. + $wrapper->url = $url; + } + } + else + { + $wrapper->url = $url; + } + + // Escape strings for HTML output + $this->pageclass_sfx = htmlspecialchars($params->get('pageclass_sfx')); + $this->params = &$params; + $this->wrapper = &$wrapper; + + parent::display($tpl); + } +} diff --git a/Sites/pages/components/com_wrapper/wrapper.php b/Sites/pages/components/com_wrapper/wrapper.php new file mode 100644 index 00000000..df873e19 --- /dev/null +++ b/Sites/pages/components/com_wrapper/wrapper.php @@ -0,0 +1,14 @@ +execute(JFactory::getApplication()->input->get('task')); +$controller->redirect(); diff --git a/Sites/pages/components/com_wrapper/wrapper.xml b/Sites/pages/components/com_wrapper/wrapper.xml new file mode 100644 index 00000000..bcdf964f --- /dev/null +++ b/Sites/pages/components/com_wrapper/wrapper.xml @@ -0,0 +1,33 @@ + + + com_wrapper + Joomla! Project + April 2006 + (C) 2005 - 2020 Open Source Matters. All rights reserved. + + GNU General Public License version 2 or later; see LICENSE.txt + admin@joomla.org + www.joomla.org + 3.0.0 + COM_WRAPPER_XML_DESCRIPTION + + controller.php + index.html + metadata.xml + router.php + wrapper.php + views + + + language/en-GB.com_wrapper.ini + + + + index.html + + + language/en-GB.com_wrapper.ini + language/en-GB.com_wrapper.sys.ini + + + diff --git a/Sites/pages/components/index.html b/Sites/pages/components/index.html new file mode 100644 index 00000000..2efb97f3 --- /dev/null +++ b/Sites/pages/components/index.html @@ -0,0 +1 @@ + diff --git a/Sites/pages/composer.json b/Sites/pages/composer.json new file mode 100644 index 00000000..0d31ce5f --- /dev/null +++ b/Sites/pages/composer.json @@ -0,0 +1,5 @@ +{ + "require": { + "joomlatools/pages": "^0.19.8" + } +} diff --git a/Sites/pages/composer.lock b/Sites/pages/composer.lock new file mode 100644 index 00000000..b2a72a0e --- /dev/null +++ b/Sites/pages/composer.lock @@ -0,0 +1,434 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "f34ccd659f3264820934a5d019340a5e", + "packages": [ + { + "name": "joomlatools/composer", + "version": "v1.2.0", + "source": { + "type": "git", + "url": "https://github.com/joomlatools/joomlatools-composer.git", + "reference": "8ce2421baeae2e57671b019d10d6447d81e5b0c4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/joomlatools/joomlatools-composer/zipball/8ce2421baeae2e57671b019d10d6447d81e5b0c4", + "reference": "8ce2421baeae2e57671b019d10d6447d81e5b0c4", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0" + }, + "type": "composer-plugin", + "extra": { + "class": "Joomlatools\\Composer\\Plugin" + }, + "autoload": { + "psr-0": { + "Joomlatools\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-3.0-only" + ], + "authors": [ + { + "name": "Joomlatools", + "email": "info@joomlatools.com", + "homepage": "https://www.joomlatools.com" + } + ], + "description": "A Composer plugin to install Joomla extensions into your installation.", + "homepage": "https://github.com/joomlatools/joomlatools-composer", + "keywords": [ + "composer", + "extension", + "installer", + "joomla" + ], + "time": "2020-12-21T13:45:10+00:00" + }, + { + "name": "joomlatools/framework", + "version": "v3.4.13", + "source": { + "type": "git", + "url": "git@github.com:joomlatools/joomlatools-framework.git", + "reference": "28305af6fb7b61768d1a92d829f362142ef6b109" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/joomlatools/joomlatools-framework/zipball/28305af6fb7b61768d1a92d829f362142ef6b109", + "reference": "28305af6fb7b61768d1a92d829f362142ef6b109", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "joomlatools/composer": "*", + "php": ">=5.4", + "symfony/yaml": "^2.8|^3.0|^4.0" + }, + "suggest": { + "erusev/parsedown-extra": "Allows using Markddown in templates", + "mustache/mustache": "Allows building logic less templates using the Mustache syntax", + "twig/twig": "Allows building templates using the Twig template engine" + }, + "type": "joomlatools-extension", + "extra": { + "manifest": "code/plugins/system/joomlatools/joomlatools.xml" + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-3.0-only" + ], + "authors": [ + { + "name": "Johan Janssens", + "email": "johan@janssens.me", + "homepage": "http://about.me/johanjanssens" + }, + { + "name": "Timble", + "email": "info@timble.net", + "homepage": "http://www.timble.net" + } + ], + "description": "Joomlatools Framework is an open-source extension framework for Joomla", + "homepage": "https://github.com/joomlatools/joomlatools-framework", + "keywords": [ + "extension", + "framework", + "joomla", + "koowa" + ], + "time": "2021-03-19T23:33:07+00:00" + }, + { + "name": "joomlatools/pages", + "version": "v0.19.8", + "source": { + "type": "git", + "url": "https://github.com/joomlatools/joomlatools-pages.git", + "reference": "633bf72eeed5c7ddfb89479bbe4ee4d2789b18b3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/joomlatools/joomlatools-pages/zipball/633bf72eeed5c7ddfb89479bbe4ee4d2789b18b3", + "reference": "633bf72eeed5c7ddfb89479bbe4ee4d2789b18b3", + "shasum": "" + }, + "require": { + "joomlatools/composer": "*", + "joomlatools/framework": "~3.4.13", + "michelf/php-markdown": "1.8.*", + "php": ">=7.0.0", + "scrivo/highlight.php": "9.*" + }, + "type": "joomlatools-installer", + "extra": { + "manifest": "code/administrator/components/com_pages/pages.xml" + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-3.0-only" + ], + "authors": [ + { + "name": "Johan Janssens", + "email": "johan@janssens.me", + "homepage": "http://about.me/johanjanssens" + }, + { + "name": "Timble", + "email": "info@timble.net", + "homepage": "http://www.timble.net" + } + ], + "description": "A component for including html and markdown into Joomla. Inspired by Jekyll and Grav", + "homepage": "https://github.com/joomlatools/joomlatools-pages", + "keywords": [ + "component", + "joomla", + "markdown", + "pages" + ], + "time": "2021-03-20T15:28:41+00:00" + }, + { + "name": "michelf/php-markdown", + "version": "1.8.0", + "source": { + "type": "git", + "url": "https://github.com/michelf/php-markdown.git", + "reference": "01ab082b355bf188d907b9929cd99b2923053495" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/michelf/php-markdown/zipball/01ab082b355bf188d907b9929cd99b2923053495", + "reference": "01ab082b355bf188d907b9929cd99b2923053495", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Michelf\\": "Michelf/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Michel Fortin", + "email": "michel.fortin@michelf.ca", + "homepage": "https://michelf.ca/", + "role": "Developer" + }, + { + "name": "John Gruber", + "homepage": "https://daringfireball.net/" + } + ], + "description": "PHP Markdown", + "homepage": "https://michelf.ca/projects/php-markdown/", + "keywords": [ + "markdown" + ], + "time": "2018-01-15T00:49:33+00:00" + }, + { + "name": "scrivo/highlight.php", + "version": "v9.18.1.6", + "source": { + "type": "git", + "url": "https://github.com/scrivo/highlight.php.git", + "reference": "44a3d4136edb5ad8551590bf90f437db80b2d466" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/scrivo/highlight.php/zipball/44a3d4136edb5ad8551590bf90f437db80b2d466", + "reference": "44a3d4136edb5ad8551590bf90f437db80b2d466", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-mbstring": "*", + "php": ">=5.4" + }, + "require-dev": { + "phpunit/phpunit": "^4.8|^5.7", + "sabberworm/php-css-parser": "^8.3", + "symfony/finder": "^2.8|^3.4", + "symfony/var-dumper": "^2.8|^3.4" + }, + "type": "library", + "autoload": { + "psr-0": { + "Highlight\\": "", + "HighlightUtilities\\": "" + }, + "files": [ + "HighlightUtilities/functions.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Geert Bergman", + "homepage": "http://www.scrivo.org/", + "role": "Project Author" + }, + { + "name": "Vladimir Jimenez", + "homepage": "https://allejo.io", + "role": "Maintainer" + }, + { + "name": "Martin Folkers", + "homepage": "https://twobrain.io", + "role": "Contributor" + } + ], + "description": "Server side syntax highlighter that supports 185 languages. It's a PHP port of highlight.js", + "keywords": [ + "code", + "highlight", + "highlight.js", + "highlight.php", + "syntax" + ], + "funding": [ + { + "url": "https://github.com/allejo", + "type": "github" + } + ], + "time": "2020-12-22T19:20:29+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.22.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "c6c942b1ac76c82448322025e084cadc56048b4e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/c6c942b1ac76c82448322025e084cadc56048b4e", + "reference": "c6c942b1ac76c82448322025e084cadc56048b4e", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.22-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-01-07T16:49:33+00:00" + }, + { + "name": "symfony/yaml", + "version": "v4.4.20", + "source": { + "type": "git", + "url": "https://github.com/symfony/yaml.git", + "reference": "29e61305e1c79d25f71060903982ead8f533e267" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/yaml/zipball/29e61305e1c79d25f71060903982ead8f533e267", + "reference": "29e61305e1c79d25f71060903982ead8f533e267", + "shasum": "" + }, + "require": { + "php": ">=7.1.3", + "symfony/polyfill-ctype": "~1.8" + }, + "conflict": { + "symfony/console": "<3.4" + }, + "require-dev": { + "symfony/console": "^3.4|^4.0|^5.0" + }, + "suggest": { + "symfony/console": "For validating YAML files using the lint command" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Yaml\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Loads and dumps YAML files", + "homepage": "https://symfony.com", + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-02-22T15:36:50+00:00" + } + ], + "packages-dev": [], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": [], + "platform-dev": [], + "plugin-api-version": "1.1.0" +} diff --git a/Sites/pages/configuration-pages.php b/Sites/pages/configuration-pages.php new file mode 100644 index 00000000..0e337470 --- /dev/null +++ b/Sites/pages/configuration-pages.php @@ -0,0 +1,7 @@ + [ + '[*]' => '/Projects/joomlatools-pages', + ], +); \ No newline at end of file diff --git a/Sites/pages/configuration.php b/Sites/pages/configuration.php new file mode 100644 index 00000000..5027ecc5 --- /dev/null +++ b/Sites/pages/configuration.php @@ -0,0 +1,99 @@ +Please check back again soon.'; + public $display_offline_message = '1'; + public $offline_image = ''; + public $sitename = 'pages'; + public $editor = 'tinymce'; + public $captcha = '0'; + public $list_limit = '20'; + public $access = '1'; + public $debug = '0'; + public $debug_lang = '0'; + public $debug_lang_const = '1'; + public $dbtype = 'mysqli'; + public $host = 'db'; + public $user = 'root'; + public $password = 'root'; + public $db = 'sites_pages'; + public $dbprefix = 'j_'; + public $live_site = ''; + public $secret = 'R1Wv3PfwqCJk9Jmu'; + public $gzip = '0'; + public $error_reporting = 'default'; + public $helpurl = 'https://help.joomla.org/proxy?keyref=Help{major}{minor}:{keyref}&lang={langcode}'; + public $ftp_host = ''; + public $ftp_port = ''; + public $ftp_user = ''; + public $ftp_pass = ''; + public $ftp_root = ''; + public $ftp_enable = '0'; + public $offset = 'UTC'; + public $mailonline = '1'; + public $mailer = 'mail'; + public $mailfrom = 'admin@pages.com'; + public $fromname = 'pages'; + public $sendmail = '/usr/sbin/sendmail'; + public $smtpauth = '0'; + public $smtpuser = ''; + public $smtppass = ''; + public $smtphost = 'localhost'; + public $smtpsecure = 'none'; + public $smtpport = '25'; + public $caching = '0'; + public $cache_handler = 'file'; + public $cachetime = '15'; + public $cache_platformprefix = '0'; + public $MetaDesc = 'a demo of how pages works'; + public $MetaKeys = ''; + public $MetaTitle = '1'; + public $MetaAuthor = '1'; + public $MetaVersion = '0'; + public $robots = ''; + public $sef = '1'; + public $sef_rewrite = '1'; + public $sef_suffix = '0'; + public $unicodeslugs = '0'; + public $feed_limit = '10'; + public $feed_email = 'none'; + public $log_path = '/Sites/pages/administrator/logs'; + public $tmp_path = '/Sites/pages/tmp'; + public $lifetime = '15'; + public $session_handler = 'database'; + public $shared_session = '0'; + public $memcache_persist = '1'; + public $memcache_compress = '0'; + public $memcache_server_host = 'localhost'; + public $memcache_server_port = '11211'; + public $memcached_persist = '1'; + public $memcached_compress = '0'; + public $memcached_server_host = 'localhost'; + public $memcached_server_port = '11211'; + public $redis_persist = '1'; + public $redis_server_host = 'localhost'; + public $redis_server_port = '6379'; + public $redis_server_db = '0'; + public $proxy_enable = '0'; + public $proxy_host = ''; + public $proxy_port = ''; + public $proxy_user = ''; + public $massmailoff = '0'; + public $replyto = ''; + public $replytoname = ''; + public $MetaRights = ''; + public $sitename_pagetitles = '0'; + public $force_ssl = '0'; + public $session_memcache_server_host = 'localhost'; + public $session_memcache_server_port = '11211'; + public $session_memcached_server_host = 'localhost'; + public $session_memcached_server_port = '11211'; + public $session_redis_persist = '1'; + public $session_redis_server_host = 'localhost'; + public $session_redis_server_port = '6379'; + public $session_redis_server_db = '0'; + public $frontediting = '1'; + public $cookie_domain = ''; + public $cookie_path = ''; + public $asset_id = '1'; +} \ No newline at end of file diff --git a/Sites/pages/htaccess.txt b/Sites/pages/htaccess.txt new file mode 100644 index 00000000..25b89f65 --- /dev/null +++ b/Sites/pages/htaccess.txt @@ -0,0 +1,92 @@ +## +# @package Joomla +# @copyright Copyright (C) 2005 - 2020 Open Source Matters. All rights reserved. +# @license GNU General Public License version 2 or later; see LICENSE.txt +## + +## +# READ THIS COMPLETELY IF YOU CHOOSE TO USE THIS FILE! +# +# The line 'Options +FollowSymLinks' may cause problems with some server configurations. +# It is required for the use of Apache mod_rewrite, but it may have already been set by +# your server administrator in a way that disallows changing it in this .htaccess file. +# If using it causes your site to produce an error, comment it out (add # to the +# beginning of the line), reload your site in your browser and test your sef urls. If +# they work, then it has been set by your server administrator and you do not need to +# set it here. +## + +## No directory listings + + IndexIgnore * + + +## Suppress mime type detection in browsers for unknown types + +Header always set X-Content-Type-Options "nosniff" + + +## Can be commented out if causes errors, see notes above. +Options +FollowSymlinks +Options -Indexes + +## Disable inline JavaScript when directly opening SVG files or embedding them with the object-tag + + + Header always set Content-Security-Policy "script-src 'none'" + + + +## Mod_rewrite in use. + +RewriteEngine On + +## Begin - Rewrite rules to block out some common exploits. +# If you experience problems on your site then comment out the operations listed +# below by adding a # to the beginning of the line. +# This attempts to block the most common type of exploit `attempts` on Joomla! +# +# Block any script trying to base64_encode data within the URL. +RewriteCond %{QUERY_STRING} base64_encode[^(]*\([^)]*\) [OR] +# Block any script that includes a "; + + return '' . JText::_('JLIB_HTML_CLOAKING') . '' . $inlineScript; + } + + /** + * Convert encoded text + * + * @param string $text Text to convert + * + * @return string The converted text. + * + * @since 1.5 + */ + protected static function convertEncoding($text) + { + $text = html_entity_decode($text); + + // Replace vowels with character encoding + $text = str_replace('a', 'a', $text); + $text = str_replace('e', 'e', $text); + $text = str_replace('i', 'i', $text); + $text = str_replace('o', 'o', $text); + $text = str_replace('u', 'u', $text); + $text = htmlentities($text, ENT_QUOTES, 'UTF-8', false); + + return $text; + } +} diff --git a/Sites/pages/libraries/cms/html/form.php b/Sites/pages/libraries/cms/html/form.php new file mode 100644 index 00000000..08696114 --- /dev/null +++ b/Sites/pages/libraries/cms/html/form.php @@ -0,0 +1,82 @@ +'; + } + + /** + * Add CSRF form token to Joomla script options that developers can get it by Javascript. + * + * @param string $name The script option key name. + * + * @return void + * + * @since 3.8.0 + */ + public static function csrf($name = 'csrf.token') + { + if (isset(static::$loaded[__METHOD__][$name])) + { + return; + } + + /** @var JDocumentHtml $doc */ + $doc = JFactory::getDocument(); + + if (!$doc instanceof JDocumentHtml || $doc->getType() !== 'html') + { + return; + } + + $doc->addScriptOptions($name, JSession::getFormToken()); + + static::$loaded[__METHOD__][$name] = true; + } +} diff --git a/Sites/pages/libraries/cms/html/formbehavior.php b/Sites/pages/libraries/cms/html/formbehavior.php new file mode 100644 index 00000000..3faebbe7 --- /dev/null +++ b/Sites/pages/libraries/cms/html/formbehavior.php @@ -0,0 +1,151 @@ + value [optional] + * + * @return void + * + * @since 3.0 + */ + public static function chosen($selector = '.advancedSelect', $debug = null, $options = array()) + { + if (isset(static::$loaded[__METHOD__][$selector])) + { + return; + } + + // If no debugging value is set, use the configuration setting + if ($debug === null) + { + $debug = JDEBUG; + } + + // Default settings + if (!isset($options['disable_search_threshold'])) + { + $options['disable_search_threshold'] = 10; + } + + // Allow searching contains space in query + if (!isset($options['search_contains'])) + { + $options['search_contains'] = true; + } + + if (!isset($options['allow_single_deselect'])) + { + $options['allow_single_deselect'] = true; + } + + if (!isset($options['placeholder_text_multiple'])) + { + $options['placeholder_text_multiple'] = JText::_('JGLOBAL_TYPE_OR_SELECT_SOME_OPTIONS'); + } + + if (!isset($options['placeholder_text_single'])) + { + $options['placeholder_text_single'] = JText::_('JGLOBAL_SELECT_AN_OPTION'); + } + + if (!isset($options['no_results_text'])) + { + $options['no_results_text'] = JText::_('JGLOBAL_SELECT_NO_RESULTS_MATCH'); + } + + $displayData = array( + 'debug' => $debug, + 'options' => $options, + 'selector' => $selector, + ); + + JLayoutHelper::render('joomla.html.formbehavior.chosen', $displayData); + + static::$loaded[__METHOD__][$selector] = true; + + return; + } + + /** + * Method to load the AJAX Chosen library + * + * If debugging mode is on an uncompressed version of AJAX Chosen is included for easier debugging. + * + * @param Registry $options Options in a Registry object + * @param mixed $debug Is debugging mode on? [optional] + * + * @return void + * + * @since 3.0 + */ + public static function ajaxchosen(Registry $options, $debug = null) + { + // Retrieve options/defaults + $selector = $options->get('selector', '.tagfield'); + $type = $options->get('type', 'GET'); + $url = $options->get('url', null); + $dataType = $options->get('dataType', 'json'); + $jsonTermKey = $options->get('jsonTermKey', 'term'); + $afterTypeDelay = $options->get('afterTypeDelay', '500'); + $minTermLength = $options->get('minTermLength', '3'); + + // Ajax URL is mandatory + if (!empty($url)) + { + if (isset(static::$loaded[__METHOD__][$selector])) + { + return; + } + + // Requires chosen to work + static::chosen($selector, $debug); + + $displayData = array( + 'url' => $url, + 'debug' => $debug, + 'options' => $options, + 'selector' => $selector, + 'type' => $type, + 'dataType' => $dataType, + 'jsonTermKey' => $jsonTermKey, + 'afterTypeDelay' => $afterTypeDelay, + 'minTermLength' => $minTermLength, + ); + + JLayoutHelper::render('joomla.html.formbehavior.ajaxchosen', $displayData); + + static::$loaded[__METHOD__][$selector] = true; + } + + return; + } +} diff --git a/Sites/pages/libraries/cms/html/grid.php b/Sites/pages/libraries/cms/html/grid.php new file mode 100644 index 00000000..05fcd933 --- /dev/null +++ b/Sites/pages/libraries/cms/html/grid.php @@ -0,0 +1,368 @@ + tag. + $bool = $value ? 'true' : 'false'; + $task = $value ? $taskOff : $taskOn; + $toggle = (!$task) ? false : true; + + if ($toggle) + { + return ''; + } + else + { + return ''; + } + } + + /** + * Method to sort a column in a grid + * + * @param string $title The link title + * @param string $order The order field for the column + * @param string $direction The current direction + * @param string $selected The selected ordering + * @param string $task An optional task override + * @param string $newDirection An optional direction for the new column + * @param string $tip An optional text shown as tooltip title instead of $title + * @param string $form An optional form selector + * + * @return string + * + * @since 1.5 + */ + public static function sort($title, $order, $direction = 'asc', $selected = '', $task = null, $newDirection = 'asc', $tip = '', $form = null) + { + JHtml::_('behavior.core'); + JHtml::_('bootstrap.popover'); + + $direction = strtolower($direction); + $icon = array('arrow-up-3', 'arrow-down-3'); + $index = (int) ($direction === 'desc'); + + if ($order != $selected) + { + $direction = $newDirection; + } + else + { + $direction = $direction === 'desc' ? 'asc' : 'desc'; + } + + if ($form) + { + $form = ', document.getElementById(\'' . $form . '\')'; + } + + $html = ''; + + if (isset($title['0']) && $title['0'] === '<') + { + $html .= $title; + } + else + { + $html .= JText::_($title); + } + + if ($order == $selected) + { + $html .= ''; + } + + $html .= ''; + + return $html; + } + + /** + * Method to check all checkboxes in a grid + * + * @param string $name The name of the form element + * @param string $tip The text shown as tooltip title instead of $tip + * @param string $action The action to perform on clicking the checkbox + * + * @return string + * + * @since 3.1.2 + */ + public static function checkall($name = 'checkall-toggle', $tip = 'JGLOBAL_CHECK_ALL', $action = 'Joomla.checkAll(this)') + { + JHtml::_('behavior.core'); + JHtml::_('bootstrap.tooltip'); + + return ''; + } + + /** + * Method to create a checkbox for a grid row. + * + * @param integer $rowNum The row index + * @param integer $recId The record id + * @param boolean $checkedOut True if item is checked out + * @param string $name The name of the form element + * @param string $stub The name of stub identifier + * + * @return mixed String of html with a checkbox if item is not checked out, null if checked out. + * + * @since 1.5 + */ + public static function id($rowNum, $recId, $checkedOut = false, $name = 'cid', $stub = 'cb') + { + return $checkedOut ? '' : ''; + } + + /** + * Displays a checked out icon. + * + * @param object &$row A data object (must contain checkedout as a property). + * @param integer $i The index of the row. + * @param string $identifier The property name of the primary key or index of the row. + * + * @return string + * + * @since 1.5 + */ + public static function checkedOut(&$row, $i, $identifier = 'id') + { + $user = JFactory::getUser(); + $userid = $user->get('id'); + + if ($row instanceof JTable) + { + $result = $row->isCheckedOut($userid); + } + else + { + $result = false; + } + + if ($result) + { + return static::_checkedOut($row); + } + else + { + if ($identifier === 'id') + { + return JHtml::_('grid.id', $i, $row->$identifier); + } + else + { + return JHtml::_('grid.id', $i, $row->$identifier, $result, $identifier); + } + } + } + + /** + * Method to create a clickable icon to change the state of an item + * + * @param mixed $value Either the scalar value or an object (for backward compatibility, deprecated) + * @param integer $i The index + * @param string $img1 Image for a positive or on value + * @param string $img0 Image for the empty or off value + * @param string $prefix An optional prefix for the task + * + * @return string + * + * @since 1.5 + */ + public static function published($value, $i, $img1 = 'tick.png', $img0 = 'publish_x.png', $prefix = '') + { + if (is_object($value)) + { + $value = $value->published; + } + + $img = $value ? $img1 : $img0; + $task = $value ? 'unpublish' : 'publish'; + $alt = $value ? JText::_('JPUBLISHED') : JText::_('JUNPUBLISHED'); + $action = $value ? JText::_('JLIB_HTML_UNPUBLISH_ITEM') : JText::_('JLIB_HTML_PUBLISH_ITEM'); + + return '' + . JHtml::_('image', 'admin/' . $img, $alt, null, true) . ''; + } + + /** + * Method to create a select list of states for filtering + * By default the filter shows only published and unpublished items + * + * @param string $filterState The initial filter state + * @param string $published The JText string for published + * @param string $unpublished The JText string for Unpublished + * @param string $archived The JText string for Archived + * @param string $trashed The JText string for Trashed + * + * @return string + * + * @since 1.5 + */ + public static function state($filterState = '*', $published = 'JPUBLISHED', $unpublished = 'JUNPUBLISHED', $archived = null, $trashed = null) + { + $state = array('' => '- ' . JText::_('JLIB_HTML_SELECT_STATE') . ' -', 'P' => JText::_($published), 'U' => JText::_($unpublished)); + + if ($archived) + { + $state['A'] = JText::_($archived); + } + + if ($trashed) + { + $state['T'] = JText::_($trashed); + } + + return JHtml::_( + 'select.genericlist', + $state, + 'filter_state', + array( + 'list.attr' => 'class="inputbox" size="1" onchange="Joomla.submitform();"', + 'list.select' => $filterState, + 'option.key' => null, + ) + ); + } + + /** + * Method to create an icon for saving a new ordering in a grid + * + * @param array $rows The array of rows of rows + * @param string $image The image [UNUSED] + * @param string $task The task to use, defaults to save order + * + * @return string + * + * @since 1.5 + */ + public static function order($rows, $image = 'filesave.png', $task = 'saveorder') + { + return ''; + } + + /** + * Method to create a checked out icon with optional overlib in a grid. + * + * @param object &$row The row object + * @param boolean $overlib True if an overlib with checkout information should be created. + * + * @return string HTMl for the icon and overlib + * + * @since 1.5 + */ + protected static function _checkedOut(&$row, $overlib = true) + { + $hover = ''; + + if ($overlib) + { + JHtml::_('bootstrap.tooltip'); + + $date = JHtml::_('date', $row->checked_out_time, JText::_('DATE_FORMAT_LC1')); + $time = JHtml::_('date', $row->checked_out_time, 'H:i'); + + $hover = ''; + } + + return $hover . JHtml::_('image', 'admin/checked_out.png', null, null, true) . ''; + } + + /** + * Method to build the behavior script and add it to the document head. + * + * @return void + * + * @since 1.6 + * + * @deprecated 4.0 This is only used in hathor and will be removed without replacement + */ + public static function behavior() + { + static $loaded; + + if (!$loaded) + { + // Include jQuery + JHtml::_('jquery.framework'); + + // Build the behavior script. + $js = ' + jQuery(function($){ + $actions = $(\'a.move_up, a.move_down, a.grid_true, a.grid_false, a.grid_trash\'); + $actions.each(function(){ + $(this).on(\'click\', function(){ + args = JSON.decode(this.rel); + listItemTask(args.id, args.task); + }); + }); + $(\'input.check-all-toggle\').each(function(){ + $(this).on(\'click\', function(){ + if (this.checked) { + $(this).closest(\'form\').find(\'input[type="checkbox"]\').each(function(){ + this.checked = true; + }) + } + else { + $(this).closest(\'form\').find(\'input[type="checkbox"]\').each(function(){ + this.checked = false; + }) + } + }); + }); + });'; + + // Add the behavior to the document head. + $document = JFactory::getDocument(); + $document->addScriptDeclaration($js); + + $loaded = true; + } + } +} diff --git a/Sites/pages/libraries/cms/html/icons.php b/Sites/pages/libraries/cms/html/icons.php new file mode 100644 index 00000000..b26ab88e --- /dev/null +++ b/Sites/pages/libraries/cms/html/icons.php @@ -0,0 +1,81 @@ +authorise($button['access'][$i], $button['access'][$i + 1])) + { + return ''; + } + } + } + } + + // Instantiate a new JLayoutFile instance and render the layout + $layout = new JLayoutFile('joomla.quickicons.icon'); + + return $layout->render($button); + } +} diff --git a/Sites/pages/libraries/cms/html/jgrid.php b/Sites/pages/libraries/cms/html/jgrid.php new file mode 100644 index 00000000..b0f351b5 --- /dev/null +++ b/Sites/pages/libraries/cms/html/jgrid.php @@ -0,0 +1,406 @@ +'; + $html[] = ''; + $html[] = ''; + } + else + { + $html[] = ''; + } + + $html[] = ''; + } + + return implode($html); + } + + /** + * Returns a state on a grid + * + * @param array $states array of value/state. Each state is an array of the form + * (task, text, active title, inactive title, tip (boolean), HTML active class, HTML inactive class) + * or ('task'=>task, 'text'=>text, 'active_title'=>active title, + * 'inactive_title'=>inactive title, 'tip'=>boolean, 'active_class'=>html active class, + * 'inactive_class'=>html inactive class) + * @param integer $value The state value. + * @param integer $i The row index + * @param string|array $prefix An optional task prefix or an array of options + * @param boolean $enabled An optional setting for access control on the action. + * @param boolean $translate An optional setting for translation. + * @param string $checkbox An optional prefix for checkboxes. + * + * @return string The HTML markup + * + * @since 1.6 + */ + public static function state($states, $value, $i, $prefix = '', $enabled = true, $translate = true, $checkbox = 'cb') + { + if (is_array($prefix)) + { + $options = $prefix; + $enabled = array_key_exists('enabled', $options) ? $options['enabled'] : $enabled; + $translate = array_key_exists('translate', $options) ? $options['translate'] : $translate; + $checkbox = array_key_exists('checkbox', $options) ? $options['checkbox'] : $checkbox; + $prefix = array_key_exists('prefix', $options) ? $options['prefix'] : ''; + } + + $state = ArrayHelper::getValue($states, (int) $value, $states[0]); + $task = array_key_exists('task', $state) ? $state['task'] : $state[0]; + $text = array_key_exists('text', $state) ? $state['text'] : (array_key_exists(1, $state) ? $state[1] : ''); + $activeTitle = array_key_exists('active_title', $state) ? $state['active_title'] : (array_key_exists(2, $state) ? $state[2] : ''); + $inactiveTitle = array_key_exists('inactive_title', $state) ? $state['inactive_title'] : (array_key_exists(3, $state) ? $state[3] : ''); + $tip = array_key_exists('tip', $state) ? $state['tip'] : (array_key_exists(4, $state) ? $state[4] : false); + $activeClass = array_key_exists('active_class', $state) ? $state['active_class'] : (array_key_exists(5, $state) ? $state[5] : ''); + $inactiveClass = array_key_exists('inactive_class', $state) ? $state['inactive_class'] : (array_key_exists(6, $state) ? $state[6] : ''); + + return static::action( + $i, $task, $prefix, $text, $activeTitle, $inactiveTitle, $tip, + $activeClass, $inactiveClass, $enabled, $translate, $checkbox + ); + } + + /** + * Returns a published state on a grid + * + * @param integer $value The state value. + * @param integer $i The row index + * @param string|array $prefix An optional task prefix or an array of options + * @param boolean $enabled An optional setting for access control on the action. + * @param string $checkbox An optional prefix for checkboxes. + * @param string $publishUp An optional start publishing date. + * @param string $publishDown An optional finish publishing date. + * + * @return string The HTML markup + * + * @see JHtmlJGrid::state() + * @since 1.6 + */ + public static function published($value, $i, $prefix = '', $enabled = true, $checkbox = 'cb', $publishUp = null, $publishDown = null) + { + if (is_array($prefix)) + { + $options = $prefix; + $enabled = array_key_exists('enabled', $options) ? $options['enabled'] : $enabled; + $checkbox = array_key_exists('checkbox', $options) ? $options['checkbox'] : $checkbox; + $prefix = array_key_exists('prefix', $options) ? $options['prefix'] : ''; + } + + $states = array( + 1 => array('unpublish', 'JPUBLISHED', 'JLIB_HTML_UNPUBLISH_ITEM', 'JPUBLISHED', true, 'publish', 'publish'), + 0 => array('publish', 'JUNPUBLISHED', 'JLIB_HTML_PUBLISH_ITEM', 'JUNPUBLISHED', true, 'unpublish', 'unpublish'), + 2 => array('unpublish', 'JARCHIVED', 'JLIB_HTML_UNPUBLISH_ITEM', 'JARCHIVED', true, 'archive', 'archive'), + -2 => array('publish', 'JTRASHED', 'JLIB_HTML_PUBLISH_ITEM', 'JTRASHED', true, 'trash', 'trash'), + ); + + // Special state for dates + if ($publishUp || $publishDown) + { + $nullDate = JFactory::getDbo()->getNullDate(); + $nowDate = JFactory::getDate()->toUnix(); + + $tz = JFactory::getUser()->getTimezone(); + + $publishUp = ($publishUp != $nullDate) ? JFactory::getDate($publishUp, 'UTC')->setTimeZone($tz) : false; + $publishDown = ($publishDown != $nullDate) ? JFactory::getDate($publishDown, 'UTC')->setTimeZone($tz) : false; + + // Create tip text, only we have publish up or down settings + $tips = array(); + + if ($publishUp) + { + $tips[] = JText::sprintf('JLIB_HTML_PUBLISHED_START', JHtml::_('date', $publishUp, JText::_('DATE_FORMAT_LC5'), 'UTC')); + } + + if ($publishDown) + { + $tips[] = JText::sprintf('JLIB_HTML_PUBLISHED_FINISHED', JHtml::_('date', $publishDown, JText::_('DATE_FORMAT_LC5'), 'UTC')); + } + + $tip = empty($tips) ? false : implode('
        ', $tips); + + // Add tips and special titles + foreach ($states as $key => $state) + { + // Create special titles for published items + if ($key == 1) + { + $states[$key][2] = $states[$key][3] = 'JLIB_HTML_PUBLISHED_ITEM'; + + if ($publishUp > $nullDate && $nowDate < $publishUp->toUnix()) + { + $states[$key][2] = $states[$key][3] = 'JLIB_HTML_PUBLISHED_PENDING_ITEM'; + $states[$key][5] = $states[$key][6] = 'pending'; + } + + if ($publishDown > $nullDate && $nowDate > $publishDown->toUnix()) + { + $states[$key][2] = $states[$key][3] = 'JLIB_HTML_PUBLISHED_EXPIRED_ITEM'; + $states[$key][5] = $states[$key][6] = 'expired'; + } + } + + // Add tips to titles + if ($tip) + { + $states[$key][1] = JText::_($states[$key][1]); + $states[$key][2] = JText::_($states[$key][2]) . '
        ' . $tip; + $states[$key][3] = JText::_($states[$key][3]) . '
        ' . $tip; + $states[$key][4] = true; + } + } + + return static::state($states, $value, $i, array('prefix' => $prefix, 'translate' => !$tip), $enabled, true, $checkbox); + } + + return static::state($states, $value, $i, $prefix, $enabled, true, $checkbox); + } + + /** + * Returns an isDefault state on a grid + * + * @param integer $value The state value. + * @param integer $i The row index + * @param string|array $prefix An optional task prefix or an array of options + * @param boolean $enabled An optional setting for access control on the action. + * @param string $checkbox An optional prefix for checkboxes. + * + * @return string The HTML markup + * + * @see JHtmlJGrid::state() + * @since 1.6 + */ + public static function isdefault($value, $i, $prefix = '', $enabled = true, $checkbox = 'cb') + { + if (is_array($prefix)) + { + $options = $prefix; + $enabled = array_key_exists('enabled', $options) ? $options['enabled'] : $enabled; + $checkbox = array_key_exists('checkbox', $options) ? $options['checkbox'] : $checkbox; + $prefix = array_key_exists('prefix', $options) ? $options['prefix'] : ''; + } + + $states = array( + 0 => array('setDefault', '', 'JLIB_HTML_SETDEFAULT_ITEM', '', 1, 'unfeatured', 'unfeatured'), + 1 => array('unsetDefault', 'JDEFAULT', 'JLIB_HTML_UNSETDEFAULT_ITEM', 'JDEFAULT', 1, 'featured', 'featured'), + ); + + return static::state($states, $value, $i, $prefix, $enabled, true, $checkbox); + } + + /** + * Returns an array of standard published state filter options. + * + * @param array $config An array of configuration options. + * This array can contain a list of key/value pairs where values are boolean + * and keys can be taken from 'published', 'unpublished', 'archived', 'trash', 'all'. + * These pairs determine which values are displayed. + * + * @return string The HTML markup + * + * @since 1.6 + */ + public static function publishedOptions($config = array()) + { + // Build the active state filter options. + $options = array(); + + if (!array_key_exists('published', $config) || $config['published']) + { + $options[] = JHtml::_('select.option', '1', 'JPUBLISHED'); + } + + if (!array_key_exists('unpublished', $config) || $config['unpublished']) + { + $options[] = JHtml::_('select.option', '0', 'JUNPUBLISHED'); + } + + if (!array_key_exists('archived', $config) || $config['archived']) + { + $options[] = JHtml::_('select.option', '2', 'JARCHIVED'); + } + + if (!array_key_exists('trash', $config) || $config['trash']) + { + $options[] = JHtml::_('select.option', '-2', 'JTRASHED'); + } + + if (!array_key_exists('all', $config) || $config['all']) + { + $options[] = JHtml::_('select.option', '*', 'JALL'); + } + + return $options; + } + + /** + * Returns a checked-out icon + * + * @param integer $i The row index. + * @param string $editorName The name of the editor. + * @param string $time The time that the object was checked out. + * @param string|array $prefix An optional task prefix or an array of options + * @param boolean $enabled True to enable the action. + * @param string $checkbox An optional prefix for checkboxes. + * + * @return string The HTML markup + * + * @since 1.6 + */ + public static function checkedout($i, $editorName, $time, $prefix = '', $enabled = false, $checkbox = 'cb') + { + JHtml::_('bootstrap.tooltip'); + + if (is_array($prefix)) + { + $options = $prefix; + $enabled = array_key_exists('enabled', $options) ? $options['enabled'] : $enabled; + $checkbox = array_key_exists('checkbox', $options) ? $options['checkbox'] : $checkbox; + $prefix = array_key_exists('prefix', $options) ? $options['prefix'] : ''; + } + + $text = $editorName . '
        ' . JHtml::_('date', $time, JText::_('DATE_FORMAT_LC')) . '
        ' . JHtml::_('date', $time, 'H:i'); + $activeTitle = JHtml::_('tooltipText', JText::_('JLIB_HTML_CHECKIN'), $text, 0); + $inactiveTitle = JHtml::_('tooltipText', JText::_('JLIB_HTML_CHECKED_OUT'), $text, 0); + + return static::action( + $i, 'checkin', $prefix, JText::_('JLIB_HTML_CHECKED_OUT'), html_entity_decode($activeTitle, ENT_QUOTES, 'UTF-8'), + html_entity_decode($inactiveTitle, ENT_QUOTES, 'UTF-8'), true, 'checkedout', 'checkedout', $enabled, false, $checkbox + ); + } + + /** + * Creates an order-up action icon. + * + * @param integer $i The row index. + * @param string $task An optional task to fire. + * @param string|array $prefix An optional task prefix or an array of options + * @param string $text An optional text to display + * @param boolean $enabled An optional setting for access control on the action. + * @param string $checkbox An optional prefix for checkboxes. + * + * @return string The HTML markup + * + * @since 1.6 + */ + public static function orderUp($i, $task = 'orderup', $prefix = '', $text = 'JLIB_HTML_MOVE_UP', $enabled = true, $checkbox = 'cb') + { + if (is_array($prefix)) + { + $options = $prefix; + $text = array_key_exists('text', $options) ? $options['text'] : $text; + $enabled = array_key_exists('enabled', $options) ? $options['enabled'] : $enabled; + $checkbox = array_key_exists('checkbox', $options) ? $options['checkbox'] : $checkbox; + $prefix = array_key_exists('prefix', $options) ? $options['prefix'] : ''; + } + + return static::action($i, $task, $prefix, $text, $text, $text, false, 'uparrow', 'uparrow_disabled', $enabled, true, $checkbox); + } + + /** + * Creates an order-down action icon. + * + * @param integer $i The row index. + * @param string $task An optional task to fire. + * @param string|array $prefix An optional task prefix or an array of options + * @param string $text An optional text to display + * @param boolean $enabled An optional setting for access control on the action. + * @param string $checkbox An optional prefix for checkboxes. + * + * @return string The HTML markup + * + * @since 1.6 + */ + public static function orderDown($i, $task = 'orderdown', $prefix = '', $text = 'JLIB_HTML_MOVE_DOWN', $enabled = true, $checkbox = 'cb') + { + if (is_array($prefix)) + { + $options = $prefix; + $text = array_key_exists('text', $options) ? $options['text'] : $text; + $enabled = array_key_exists('enabled', $options) ? $options['enabled'] : $enabled; + $checkbox = array_key_exists('checkbox', $options) ? $options['checkbox'] : $checkbox; + $prefix = array_key_exists('prefix', $options) ? $options['prefix'] : ''; + } + + return static::action($i, $task, $prefix, $text, $text, $text, false, 'downarrow', 'downarrow_disabled', $enabled, true, $checkbox); + } +} diff --git a/Sites/pages/libraries/cms/html/jquery.php b/Sites/pages/libraries/cms/html/jquery.php new file mode 100644 index 00000000..8945dc2b --- /dev/null +++ b/Sites/pages/libraries/cms/html/jquery.php @@ -0,0 +1,149 @@ +get('debug'); + } + + JHtml::_('script', 'jui/jquery.min.js', array('version' => 'auto', 'relative' => true, 'detectDebug' => $debug)); + + // Check if we are loading in noConflict + if ($noConflict) + { + JHtml::_('script', 'jui/jquery-noconflict.js', array('version' => 'auto', 'relative' => true)); + } + + // Check if we are loading Migrate + if ($migrate) + { + JHtml::_('script', 'jui/jquery-migrate.min.js', array('version' => 'auto', 'relative' => true, 'detectDebug' => $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) + { + $debug = JDEBUG; + } + + // 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', array('version' => 'auto', 'relative' => true, 'detectDebug' => $debug)); + static::$loaded[__METHOD__][$component] = true; + } + } + + return; + } + + /** + * Auto set CSRF token to ajaxSetup so all jQuery ajax call will contains CSRF token. + * + * @param string $name The CSRF meta tag name. + * + * @return void + * + * @throws \InvalidArgumentException + * + * @since 3.8.0 + */ + public static function token($name = 'csrf.token') + { + // Only load once + if (!empty(static::$loaded[__METHOD__][$name])) + { + return; + } + + static::framework(); + JHtml::_('form.csrf', $name); + + $doc = JFactory::getDocument(); + + $doc->addScriptDeclaration( +<< 0) + { + $layout = new JLayoutFile('joomla.links.groupsopen'); + $html[] = $layout->render(''); + + foreach ($groupsOfLinks as $title => $links) + { + if (isset($links[0]['separategroup'])) + { + $layout = new JLayoutFile('joomla.links.groupseparator'); + $html[] = $layout->render($title); + } + + $layout = new JLayoutFile('joomla.links.groupopen'); + $htmlHeader = $layout->render($title); + + $htmlLinks = JHtml::_('links.links', $links); + + if ($htmlLinks != '') + { + $html[] = $htmlHeader; + $html[] = $htmlLinks; + + $layout = new JLayoutFile('joomla.links.groupclose'); + $html[] = $layout->render(''); + } + } + + $layout = new JLayoutFile('joomla.links.groupsclose'); + $html[] = $layout->render(''); + } + + return implode($html); + } + + /** + * Method to generate html code for a list of links + * + * @param array $links Array of links + * + * @return string + * + * @since 3.2 + */ + public static function links($links) + { + $html = array(); + + foreach ($links as $link) + { + $html[] = JHtml::_('links.link', $link); + } + + return implode($html); + } + + /** + * Method to generate html code for a single link + * + * @param array $link link properties + * + * @return string + * + * @since 3.2 + */ + public static function link($link) + { + if (isset($link['access'])) + { + if (is_bool($link['access'])) + { + if ($link['access'] == false) + { + return ''; + } + } + else + { + // Get the user object to verify permissions + $user = JFactory::getUser(); + + // Take each pair of permission, context values. + for ($i = 0, $n = count($link['access']); $i < $n; $i += 2) + { + if (!$user->authorise($link['access'][$i], $link['access'][$i + 1])) + { + return ''; + } + } + } + } + + // Instantiate a new JLayoutFile instance and render the layout + $layout = new JLayoutFile('joomla.links.link'); + + return $layout->render($link); + } +} diff --git a/Sites/pages/libraries/cms/html/list.php b/Sites/pages/libraries/cms/html/list.php new file mode 100644 index 00000000..505564e9 --- /dev/null +++ b/Sites/pages/libraries/cms/html/list.php @@ -0,0 +1,270 @@ +getFilename(); + + if (!$file->isFile()) + { + continue; + } + + if (preg_match('#(' . $extensions . ')$#', $fileName)) + { + $images[] = JHtml::_('select.option', $fileName); + } + } + + $images = JHtml::_( + 'select.genericlist', + $images, + $name, + array( + 'list.attr' => 'class="inputbox" size="1" ' . $javascript, + 'list.select' => $active, + ) + ); + + return $images; + } + + /** + * Returns an array of options + * + * @param string $query SQL with 'ordering' AS value and 'name field' AS text + * @param integer $chop The length of the truncated headline + * + * @return array An array of objects formatted for JHtml list processing + * + * @since 1.5 + */ + public static function genericordering($query, $chop = 30) + { + $db = JFactory::getDbo(); + $options = array(); + $db->setQuery($query); + + $items = $db->loadObjectList(); + + if (empty($items)) + { + $options[] = JHtml::_('select.option', 1, JText::_('JOPTION_ORDER_FIRST')); + + return $options; + } + + $options[] = JHtml::_('select.option', 0, '0 ' . JText::_('JOPTION_ORDER_FIRST')); + + for ($i = 0, $n = count($items); $i < $n; $i++) + { + $items[$i]->text = JText::_($items[$i]->text); + + if (StringHelper::strlen($items[$i]->text) > $chop) + { + $text = StringHelper::substr($items[$i]->text, 0, $chop) . '...'; + } + else + { + $text = $items[$i]->text; + } + + $options[] = JHtml::_('select.option', $items[$i]->value, $items[$i]->value . '. ' . $text); + } + + $options[] = JHtml::_('select.option', $items[$i - 1]->value + 1, ($items[$i - 1]->value + 1) . ' ' . JText::_('JOPTION_ORDER_LAST')); + + return $options; + } + + /** + * Build the select list for Ordering derived from a query + * + * @param integer $name The scalar value + * @param string $query The query + * @param string $attribs HTML tag attributes + * @param string $selected The selected item + * @param integer $neworder 1 if new and first, -1 if new and last, 0 or null if existing item + * + * @return string HTML markup for the select list + * + * @since 1.6 + */ + public static function ordering($name, $query, $attribs = null, $selected = null, $neworder = null) + { + if (empty($attribs)) + { + $attribs = 'class="inputbox" size="1"'; + } + + if (empty($neworder)) + { + $orders = JHtml::_('list.genericordering', $query); + $html = JHtml::_('select.genericlist', $orders, $name, array('list.attr' => $attribs, 'list.select' => (int) $selected)); + } + else + { + if ($neworder > 0) + { + $text = JText::_('JGLOBAL_NEWITEMSLAST_DESC'); + } + elseif ($neworder <= 0) + { + $text = JText::_('JGLOBAL_NEWITEMSFIRST_DESC'); + } + + $html = '' . $text . ''; + } + + return $html; + } + + /** + * Select list of active users + * + * @param string $name The name of the field + * @param string $active The active user + * @param integer $nouser If set include an option to select no user + * @param string $javascript Custom javascript + * @param string $order Specify a field to order by + * + * @return string The HTML for a list of users list of users + * + * @since 1.5 + */ + public static function users($name, $active, $nouser = 0, $javascript = null, $order = 'name') + { + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->select('u.id AS value, u.name AS text') + ->from('#__users AS u') + ->join('LEFT', '#__user_usergroup_map AS m ON m.user_id = u.id') + ->where('u.block = 0') + ->order($order) + ->group('u.id'); + $db->setQuery($query); + + if ($nouser) + { + $users[] = JHtml::_('select.option', '0', JText::_('JOPTION_NO_USER')); + $users = array_merge($users, $db->loadObjectList()); + } + else + { + $users = $db->loadObjectList(); + } + + $users = JHtml::_( + 'select.genericlist', + $users, + $name, + array( + 'list.attr' => 'class="inputbox" size="1" ' . $javascript, + 'list.select' => $active, + ) + ); + + return $users; + } + + /** + * Select list of positions - generally used for location of images + * + * @param string $name Name of the field + * @param string $active The active value + * @param string $javascript Alternative javascript + * @param boolean $none Null if not assigned + * @param boolean $center Null if not assigned + * @param boolean $left Null if not assigned + * @param boolean $right Null if not assigned + * @param boolean $id Null if not assigned + * + * @return array The positions + * + * @since 1.5 + */ + public static function positions($name, $active = null, $javascript = null, $none = true, $center = true, $left = true, $right = true, + $id = false) + { + $pos = array(); + + if ($none) + { + $pos[''] = JText::_('JNONE'); + } + + if ($center) + { + $pos['center'] = JText::_('JGLOBAL_CENTER'); + } + + if ($left) + { + $pos['left'] = JText::_('JGLOBAL_LEFT'); + } + + if ($right) + { + $pos['right'] = JText::_('JGLOBAL_RIGHT'); + } + + $positions = JHtml::_( + 'select.genericlist', $pos, $name, + array( + 'id' => $id, + 'list.attr' => 'class="inputbox" size="1"' . $javascript, + 'list.select' => $active, + 'option.key' => null, + ) + ); + + return $positions; + } +} diff --git a/Sites/pages/libraries/cms/html/menu.php b/Sites/pages/libraries/cms/html/menu.php new file mode 100644 index 00000000..d1ac5644 --- /dev/null +++ b/Sites/pages/libraries/cms/html/menu.php @@ -0,0 +1,403 @@ +getQuery(true) + ->select($db->qn(array('id', 'menutype', 'title', 'client_id'), array('id', 'value', 'text', 'client_id'))) + ->from($db->quoteName('#__menu_types')) + ->order('client_id, title'); + + if (isset($clientId)) + { + $query->where('client_id = ' . (int) $clientId); + } + + static::$menus[$key] = $db->setQuery($query)->loadObjectList(); + } + + return static::$menus[$key]; + } + + /** + * Returns an array of menu items grouped by menu. + * + * @param array $config An array of configuration options [published, checkacl, clientid]. + * + * @return array + * + * @since 1.6 + */ + public static function menuItems($config = array()) + { + $key = serialize($config); + + if (empty(static::$items[$key])) + { + // B/C - not passed = 0, null can be passed for both clients + $clientId = array_key_exists('clientid', $config) ? $config['clientid'] : 0; + $menus = static::menus($clientId); + + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->select('a.id AS value, a.title AS text, a.level, a.menutype, a.client_id') + ->from('#__menu AS a') + ->where('a.parent_id > 0'); + + // Filter on the client id + if (isset($clientId)) + { + $query->where('a.client_id = ' . (int) $clientId); + } + + // Filter on the published state + if (isset($config['published'])) + { + if (is_numeric($config['published'])) + { + $query->where('a.published = ' . (int) $config['published']); + } + elseif ($config['published'] === '') + { + $query->where('a.published IN (0,1)'); + } + } + + $query->order('a.lft'); + + $db->setQuery($query); + $items = $db->loadObjectList(); + + // Collate menu items based on menutype + $lookup = array(); + + foreach ($items as &$item) + { + if (!isset($lookup[$item->menutype])) + { + $lookup[$item->menutype] = array(); + } + + $lookup[$item->menutype][] = &$item; + + // Translate the menu item title when client is administrator + if ($clientId === 1) + { + $item->text = JText::_($item->text); + } + + $item->text = str_repeat('- ', $item->level) . $item->text; + } + + static::$items[$key] = array(); + + $user = JFactory::getUser(); + + $aclcheck = !empty($config['checkacl']) ? (int) $config['checkacl'] : 0; + + foreach ($menus as &$menu) + { + if ($aclcheck) + { + $action = $aclcheck == $menu->id ? 'edit' : 'create'; + + if (!$user->authorise('core.' . $action, 'com_menus.menu.' . $menu->id)) + { + continue; + } + } + + // Start group: + static::$items[$key][] = JHtml::_('select.optgroup', $menu->text); + + // Special "Add to this Menu" option: + static::$items[$key][] = JHtml::_('select.option', $menu->value . '.1', JText::_('JLIB_HTML_ADD_TO_THIS_MENU')); + + // Menu items: + if (isset($lookup[$menu->value])) + { + foreach ($lookup[$menu->value] as &$item) + { + static::$items[$key][] = JHtml::_('select.option', $menu->value . '.' . $item->value, $item->text); + } + } + + // Finish group: + static::$items[$key][] = JHtml::_('select.optgroup', $menu->text); + } + } + + return static::$items[$key]; + } + + /** + * Displays an HTML select list of menu items. + * + * @param string $name The name of the control. + * @param string $selected The value of the selected option. + * @param string $attribs Attributes for the control. + * @param array $config An array of options for the control [id, published, checkacl, clientid]. + * + * @return string + * + * @since 1.6 + */ + public static function menuItemList($name, $selected = null, $attribs = null, $config = array()) + { + static $count; + + $options = static::menuItems($config); + + return JHtml::_( + 'select.genericlist', $options, $name, + array( + 'id' => isset($config['id']) ? $config['id'] : 'assetgroups_' . (++$count), + 'list.attr' => $attribs === null ? 'class="inputbox" size="1"' : $attribs, + 'list.select' => (int) $selected, + 'list.translate' => false, + ) + ); + } + + /** + * Build the select list for Menu Ordering + * + * @param object &$row The row object + * @param integer $id The id for the row. Must exist to enable menu ordering + * + * @return string + * + * @since 1.5 + */ + public static function ordering(&$row, $id) + { + if ($id) + { + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->select('ordering AS value, title AS text') + ->from($db->quoteName('#__menu')) + ->where($db->quoteName('menutype') . ' = ' . $db->quote($row->menutype)) + ->where($db->quoteName('parent_id') . ' = ' . (int) $row->parent_id) + ->where($db->quoteName('published') . ' != -2') + ->order('ordering'); + $order = JHtml::_('list.genericordering', $query); + $ordering = JHtml::_( + 'select.genericlist', $order, 'ordering', + array('list.attr' => 'class="inputbox" size="1"', 'list.select' => (int) $row->ordering) + ); + } + else + { + $ordering = '' . JText::_('JGLOBAL_NEWITEMSLAST_DESC'); + } + + return $ordering; + } + + /** + * Build the multiple select list for Menu Links/Pages + * + * @param boolean $all True if all can be selected + * @param boolean $unassigned True if unassigned can be selected + * @param int $clientId The client id + * + * @return string + * + * @since 1.5 + */ + public static function linkOptions($all = false, $unassigned = false, $clientId = 0) + { + $db = JFactory::getDbo(); + + // Get a list of the menu items + $query = $db->getQuery(true) + ->select('m.id, m.parent_id, m.title, m.menutype, m.client_id') + ->from($db->quoteName('#__menu') . ' AS m') + ->where($db->quoteName('m.published') . ' = 1') + ->order('m.client_id, m.menutype, m.parent_id'); + + if (isset($clientId)) + { + $query->where('m.client_id = ' . (int) $clientId); + } + + $db->setQuery($query); + + $mitems = $db->loadObjectList(); + + if (!$mitems) + { + $mitems = array(); + } + + // Establish the hierarchy of the menu + $children = array(); + + // First pass - collect children + foreach ($mitems as $v) + { + $pt = $v->parent_id; + $list = @$children[$pt] ? $children[$pt] : array(); + $list[] = $v; + $children[$pt] = $list; + } + + // Second pass - get an indent list of the items + $list = static::treerecurse((int) $mitems[0]->parent_id, '', array(), $children, 9999, 0, 0); + + // Code that adds menu name to Display of Page(s) + $mitems = array(); + + if ($all | $unassigned) + { + $mitems[] = JHtml::_('select.option', '', JText::_('JOPTION_MENUS')); + + if ($all) + { + $mitems[] = JHtml::_('select.option', 0, JText::_('JALL')); + } + + if ($unassigned) + { + $mitems[] = JHtml::_('select.option', -1, JText::_('JOPTION_UNASSIGNED')); + } + + $mitems[] = JHtml::_('select.option', ''); + } + + $lastMenuType = null; + $tmpMenuType = null; + + foreach ($list as $list_a) + { + if ($list_a->menutype != $lastMenuType) + { + if ($tmpMenuType) + { + $mitems[] = JHtml::_('select.option', ''); + } + + $mitems[] = JHtml::_('select.option', '', $list_a->menutype); + $lastMenuType = $list_a->menutype; + $tmpMenuType = $list_a->menutype; + } + + $mitems[] = JHtml::_('select.option', $list_a->id, $list_a->title); + } + + if ($lastMenuType !== null) + { + $mitems[] = JHtml::_('select.option', ''); + } + + return $mitems; + } + + /** + * Build the list representing the menu tree + * + * @param integer $id Id of the menu item + * @param string $indent The indentation string + * @param array $list The list to process + * @param array &$children The children of the current item + * @param integer $maxlevel The maximum number of levels in the tree + * @param integer $level The starting level + * @param int $type Set the type of spacer to use. Use 1 for |_ or 0 for - + * + * @return array + * + * @since 1.5 + */ + public static function treerecurse($id, $indent, $list, &$children, $maxlevel = 9999, $level = 0, $type = 1) + { + if ($level <= $maxlevel && isset($children[$id]) && is_array($children[$id])) + { + if ($type) + { + $pre = '|_ '; + $spacer = '.      '; + } + else + { + $pre = '- '; + $spacer = '  '; + } + + foreach ($children[$id] as $v) + { + $id = $v->id; + + if ($v->parent_id == 0) + { + $txt = $v->title; + } + else + { + $txt = $pre . $v->title; + } + + $list[$id] = $v; + $list[$id]->treename = $indent . $txt; + + if (isset($children[$id]) && is_array($children[$id])) + { + $list[$id]->children = count($children[$id]); + $list = static::treerecurse($id, $indent . $spacer, $list, $children, $maxlevel, $level + 1, $type); + } + else + { + $list[$id]->children = 0; + } + } + } + + return $list; + } +} diff --git a/Sites/pages/libraries/cms/html/number.php b/Sites/pages/libraries/cms/html/number.php new file mode 100644 index 00000000..3a3d9fa6 --- /dev/null +++ b/Sites/pages/libraries/cms/html/number.php @@ -0,0 +1,112 @@ +'; + $html[] = JHtml::_('tabs.start', 'acl-rules-' . $assetId, array('useCookie' => 1)); + $html[] = JHtml::_('tabs.panel', JText::_('JLIB_HTML_ACCESS_SUMMARY'), 'summary'); + $html[] = '

        ' . JText::_('JLIB_HTML_ACCESS_SUMMARY_DESC') . '

        '; + $html[] = ' '; + $html[] = ' '; + $html[] = ' '; + $html[] = ' '; + + foreach ($actions as $i => $action) + { + $html[] = ' '; + } + + $html[] = ' '; + + foreach ($groups as $i => $group) + { + $html[] = ' '; + $html[] = ' '; + + foreach ($actions as $j => $action) + { + $html[] = ' '; + } + + $html[] = ' '; + } + + $html[] = '
        ' . JText::_('JLIB_HTML_ACCESS_SUMMARY_DESC_CAPTION') . '
        ' . JText::_('JLIB_RULES_GROUPS') . '' . JText::_($action->title) . '
        ' . $group->text . '' + . ($assetId ? ($inherited->allow($action->name, $group->identities) ? $images['allow'] : $images['deny']) + : ($inheriting->allow($action->name, $group->identities) ? $images['allow'] : $images['deny'])) . '
        '; + + foreach ($actions as $action) + { + $actionTitle = JText::_($action->title); + $actionDesc = JText::_($action->description); + $html[] = JHtml::_('tabs.panel', $actionTitle, $action->name); + $html[] = '

        ' . $actionDesc . '

        '; + $html[] = ' '; + $html[] = ' '; + $html[] = ' '; + $html[] = ' '; + $html[] = ' '; + $html[] = ' '; + $html[] = ' '; + $html[] = ' '; + + foreach ($groups as $i => $group) + { + $selected = $rules->allow($action->name, $group->value); + + $html[] = ' '; + $html[] = ' '; + $html[] = ' '; + $html[] = ' '; + $html[] = ' '; + $html[] = ' '; + } + + $html[] = '
        ' . JText::_('JLIB_HTML_ACCESS_MODIFY_DESC_CAPTION_ACL') . ' ' . $actionTitle . ' ' + . JText::_('JLIB_HTML_ACCESS_MODIFY_DESC_CAPTION_TABLE') . '
        ' . JText::_('JLIB_RULES_GROUP') . '' . JText::_('JLIB_RULES_INHERIT') . '' . JText::_('JMODIFY') . '' . JText::_('JCURRENT') . '
        ' . $group->text . '' + . ($inheriting->allow($action->name, $group->identities) ? $images['allow-i'] : $images['deny-i']) . ''; + $html[] = ' '; + $html[] = ' ' + . ($assetId ? ($inherited->allow($action->name, $group->identities) ? $images['allow'] : $images['deny']) + : ($inheriting->allow($action->name, $group->identities) ? $images['allow'] : $images['deny'])) . '
        '; + } + + $html[] = JHtml::_('tabs.end'); + + // Build the footer with legend and special purpose buttons. + $html[] = '
        '; + $html[] = '
          '; + $html[] = '
        • ' . JText::_('JLIB_RULES_ALLOWED') . '
        • '; + $html[] = '
        • ' . JText::_('JLIB_RULES_DENIED') . '
        • '; + $html[] = '
        '; + $html[] = '
      '; + + return implode("\n", $html); + } + + /** + * Get the id of the parent asset + * + * @param integer $assetId The asset for which the parentid will be returned + * + * @return integer The id of the parent asset + * + * @since 1.6 + * @deprecated 4.0 + */ + protected static function _getParentAssetId($assetId) + { + // Get a database object. + $db = JFactory::getDbo(); + $query = $db->getQuery(true); + + // Get the user groups from the database. + $query->select($db->quoteName('parent_id')) + ->from($db->quoteName('#__assets')) + ->where($db->quoteName('id') . ' = ' . (int) $assetId); + $db->setQuery($query); + + return (int) $db->loadResult(); + } + + /** + * Get the user groups + * + * @return array Array of user groups + * + * @since 1.6 + * @deprecated 4.0 + */ + protected static function _getUserGroups() + { + // Get a database object. + $db = JFactory::getDbo(); + + // Get the user groups from the database. + $db->setQuery( + 'SELECT a.id AS value, a.title AS text, b.id as parent' + . ' FROM #__usergroups AS a LEFT JOIN #__usergroups AS b ON a.lft >= b.lft AND a.rgt <= b.rgt' + . ' ORDER BY a.lft ASC, b.lft ASC' + ); + $result = $db->loadObjectList(); + $options = array(); + + // Pre-compute additional values. + foreach ($result as $option) + { + $end = end($options); + + if ($end === false || $end->value != $option->value) + { + $end = $option; + $end->level = 0; + $options[] = $end; + } + else + { + $end->level++; + } + + $end->identities[] = $option->parent; + } + + return $options; + } + + /** + * Get the array of images associate with specific permissions + * + * @return array An associative array of permissions and images + * + * @since 1.6 + * @deprecated 4.0 + */ + protected static function _getImagesArray() + { + $images['allow-l'] = ''; + $images['deny-l'] = ''; + $images['allow'] = ' '; + $images['deny'] = ' '; + $images['allow-i'] = ' '; + $images['deny-i'] = ' '; + + return $images; + } +} diff --git a/Sites/pages/libraries/cms/html/searchtools.php b/Sites/pages/libraries/cms/html/searchtools.php new file mode 100644 index 00000000..1bc809ea --- /dev/null +++ b/Sites/pages/libraries/cms/html/searchtools.php @@ -0,0 +1,167 @@ + 'auto', 'relative' => true)); + JHtml::_('stylesheet', 'jui/jquery.searchtools.css', array('version' => 'auto', 'relative' => true)); + + static::$loaded[__METHOD__] = true; + } + + return; + } + + /** + * Load searchtools for a specific form + * + * @param mixed $selector Is debugging mode on? [optional] + * @param array $options Optional array of parameters for search tools + * + * @return void + * + * @since 3.2 + */ + public static function form($selector = '.js-stools-form', $options = array()) + { + $sig = md5(serialize(array($selector, $options))); + + // Only load once + if (!isset(static::$loaded[__METHOD__][$sig])) + { + // Include Bootstrap framework + static::main(); + + // Add the form selector to the search tools options + $options['formSelector'] = $selector; + + // Generate options with default values + $options = static::optionsToRegistry($options); + + $doc = JFactory::getDocument(); + $script = " + (function($){ + $(document).ready(function() { + $('" . $selector . "').searchtools( + " . $options->toString() . " + ); + }); + })(jQuery); + "; + $doc->addScriptDeclaration($script); + + static::$loaded[__METHOD__][$sig] = true; + } + + return; + } + + /** + * Function to receive & pre-process javascript options + * + * @param mixed $options Associative array/Registry object with options + * + * @return Registry Options converted to Registry object + */ + private static function optionsToRegistry($options) + { + // Support options array + if (is_array($options)) + { + $options = new Registry($options); + } + + if (!($options instanceof Registry)) + { + $options = new Registry; + } + + return $options; + } + + /** + * Method to sort a column in a grid + * + * @param string $title The link title + * @param string $order The order field for the column + * @param string $direction The current direction + * @param mixed $selected The selected ordering + * @param string $task An optional task override + * @param string $newDirection An optional direction for the new column + * @param string $tip An optional text shown as tooltip title instead of $title + * @param string $icon Icon to show + * @param string $formName Name of the form to submit + * + * @return string + */ + public static function sort($title, $order, $direction = 'asc', $selected = 0, $task = null, $newDirection = 'asc', $tip = '', $icon = null, + $formName = 'adminForm') + { + $direction = strtolower($direction); + $orderIcons = array('icon-arrow-up-3', 'icon-arrow-down-3'); + $index = (int) ($direction === 'desc'); + + if ($order !== $selected) + { + $direction = $newDirection; + } + else + { + $direction = $direction === 'desc' ? 'asc' : 'desc'; + } + + // Create an object to pass it to the layouts + $data = new stdClass; + $data->order = $order; + $data->direction = $direction; + $data->selected = $selected; + $data->task = $task; + $data->tip = $tip; + $data->title = $title; + $data->orderIcon = $orderIcons[$index]; + $data->icon = $icon; + $data->formName = $formName; + + return JLayoutHelper::render('joomla.searchtools.grid.sort', $data); + } +} diff --git a/Sites/pages/libraries/cms/html/select.php b/Sites/pages/libraries/cms/html/select.php new file mode 100644 index 00000000..7143b204 --- /dev/null +++ b/Sites/pages/libraries/cms/html/select.php @@ -0,0 +1,820 @@ + array( + 'option.attr' => null, + 'option.disable' => 'disable', + 'option.id' => null, + 'option.key' => 'value', + 'option.key.toHtml' => true, + 'option.label' => null, + 'option.label.toHtml' => true, + 'option.text' => 'text', + 'option.text.toHtml' => true, + 'option.class' => 'class', + 'option.onclick' => 'onclick', + ), + ); + + /** + * Generates a yes/no radio list. + * + * @param string $name The value of the HTML name attribute + * @param array $attribs Additional HTML attributes for the `` tag. This + * can be an array of attributes, or an array of options. Treated as options + * if it is the last argument passed. Valid options are: + * Format options, see {@see JHtml::$formatOptions}. + * Selection options, see {@see JHtmlSelect::options()}. + * list.attr, string|array: Additional attributes for the select + * element. + * id, string: Value to use as the select element id attribute. + * Defaults to the same as the name. + * list.select, string|array: Identifies one or more option elements + * to be selected, based on the option key values. + * @param string $optKey The name of the object variable for the option value. If + * set to null, the index of the value array is used. + * @param string $optText The name of the object variable for the option text. + * @param mixed $selected The key that is selected (accepts an array or a string). + * @param mixed $idtag Value of the field id or null by default + * @param boolean $translate True to translate + * + * @return string HTML for the select list. + * + * @since 1.5 + */ + public static function genericlist($data, $name, $attribs = null, $optKey = 'value', $optText = 'text', $selected = null, $idtag = false, + $translate = false) + { + // Set default options + $options = array_merge(JHtml::$formatOptions, array('format.depth' => 0, 'id' => false)); + + if (is_array($attribs) && func_num_args() === 3) + { + // Assume we have an options array + $options = array_merge($options, $attribs); + } + else + { + // Get options from the parameters + $options['id'] = $idtag; + $options['list.attr'] = $attribs; + $options['list.translate'] = $translate; + $options['option.key'] = $optKey; + $options['option.text'] = $optText; + $options['list.select'] = $selected; + } + + $attribs = ''; + + if (isset($options['list.attr'])) + { + if (is_array($options['list.attr'])) + { + $attribs = ArrayHelper::toString($options['list.attr']); + } + else + { + $attribs = $options['list.attr']; + } + + if ($attribs !== '') + { + $attribs = ' ' . $attribs; + } + } + + $id = $options['id'] !== false ? $options['id'] : $name; + $id = str_replace(array('[', ']', ' '), '', $id); + + $baseIndent = str_repeat($options['format.indent'], $options['format.depth']++); + $html = $baseIndent . '' . $options['format.eol'] + . static::options($data, $options) . $baseIndent . '' . $options['format.eol']; + + return $html; + } + + /** + * Method to build a list with suggestions + * + * @param array $data An array of objects, arrays, or values. + * @param string $optKey The name of the object variable for the option value. If + * set to null, the index of the value array is used. + * @param string $optText The name of the object variable for the option text. + * @param mixed $idtag Value of the field id or null by default + * @param boolean $translate True to translate + * + * @return string HTML for the select list + * + * @since 3.2 + * @deprecated 4.0 Just create the `` directly instead + */ + public static function suggestionlist($data, $optKey = 'value', $optText = 'text', $idtag = null, $translate = false) + { + // Log deprecated message + JLog::add( + sprintf( + '%s() is deprecated. Create the tag directly instead.', + __METHOD__ + ), + JLog::WARNING, + 'deprecated' + ); + + // Note: $idtag is required but has to be an optional argument in the funtion call due to argument order + if (!$idtag) + { + throw new InvalidArgumentException('$idtag is a required argument in deprecated JHtmlSelect::suggestionlist'); + } + + // Set default options + $options = array_merge(JHtml::$formatOptions, array('format.depth' => 0, 'id' => false)); + + // Get options from the parameters + $options['id'] = $idtag; + $options['list.attr'] = null; + $options['list.translate'] = $translate; + $options['option.key'] = $optKey; + $options['option.text'] = $optText; + $options['list.select'] = null; + + $id = ' id="' . $idtag . '"'; + + $baseIndent = str_repeat($options['format.indent'], $options['format.depth']++); + $html = $baseIndent . '' . $options['format.eol'] + . static::options($data, $options) . $baseIndent . '' . $options['format.eol']; + + return $html; + } + + /** + * Generates a grouped HTML selection list from nested arrays. + * + * @param array $data An array of groups, each of which is an array of options. + * @param string $name The value of the HTML name attribute + * @param array $options Options, an array of key/value pairs. Valid options are: + * Format options, {@see JHtml::$formatOptions}. + * Selection options. See {@see JHtmlSelect::options()}. + * group.id: The property in each group to use as the group id + * attribute. Defaults to none. + * group.label: The property in each group to use as the group + * label. Defaults to "text". If set to null, the data array index key is + * used. + * group.items: The property in each group to use as the array of + * items in the group. Defaults to "items". If set to null, group.id and + * group. label are forced to null and the data element is assumed to be a + * list of selections. + * id: Value to use as the select element id attribute. Defaults to + * the same as the name. + * list.attr: Attributes for the select element. Can be a string or + * an array of key/value pairs. Defaults to none. + * list.select: either the value of one selected option or an array + * of selected options. Default: none. + * list.translate: Boolean. If set, text and labels are translated via + * JText::_(). + * + * @return string HTML for the select list + * + * @since 1.5 + * @throws RuntimeException If a group has contents that cannot be processed. + */ + public static function groupedlist($data, $name, $options = array()) + { + // Set default options and overwrite with anything passed in + $options = array_merge( + JHtml::$formatOptions, + array('format.depth' => 0, 'group.items' => 'items', 'group.label' => 'text', 'group.label.toHtml' => true, 'id' => false), + $options + ); + + // Apply option rules + if ($options['group.items'] === null) + { + $options['group.label'] = null; + } + + $attribs = ''; + + if (isset($options['list.attr'])) + { + if (is_array($options['list.attr'])) + { + $attribs = ArrayHelper::toString($options['list.attr']); + } + else + { + $attribs = $options['list.attr']; + } + + if ($attribs !== '') + { + $attribs = ' ' . $attribs; + } + } + + $id = $options['id'] !== false ? $options['id'] : $name; + $id = str_replace(array('[', ']', ' '), '', $id); + + // Disable groups in the options. + $options['groups'] = false; + + $baseIndent = str_repeat($options['format.indent'], $options['format.depth']++); + $html = $baseIndent . '' . $options['format.eol']; + $groupIndent = str_repeat($options['format.indent'], $options['format.depth']++); + + foreach ($data as $dataKey => $group) + { + $label = $dataKey; + $id = ''; + $noGroup = is_int($dataKey); + + if ($options['group.items'] == null) + { + // Sub-list is an associative array + $subList = $group; + } + elseif (is_array($group)) + { + // Sub-list is in an element of an array. + $subList = $group[$options['group.items']]; + + if (isset($group[$options['group.label']])) + { + $label = $group[$options['group.label']]; + $noGroup = false; + } + + if (isset($options['group.id']) && isset($group[$options['group.id']])) + { + $id = $group[$options['group.id']]; + $noGroup = false; + } + } + elseif (is_object($group)) + { + // Sub-list is in a property of an object + $subList = $group->{$options['group.items']}; + + if (isset($group->{$options['group.label']})) + { + $label = $group->{$options['group.label']}; + $noGroup = false; + } + + if (isset($options['group.id']) && isset($group->{$options['group.id']})) + { + $id = $group->{$options['group.id']}; + $noGroup = false; + } + } + else + { + throw new RuntimeException('Invalid group contents.', 1); + } + + if ($noGroup) + { + $html .= static::options($subList, $options); + } + else + { + $html .= $groupIndent . '' . $options['format.eol'] + . static::options($subList, $options) . $groupIndent . '' . $options['format.eol']; + } + } + + $html .= $baseIndent . '' . $options['format.eol']; + + return $html; + } + + /** + * Generates a selection list of integers. + * + * @param integer $start The start integer + * @param integer $end The end integer + * @param integer $inc The increment + * @param string $name The value of the HTML name attribute + * @param mixed $attribs Additional HTML attributes for the `` tag + * @param mixed $optKey The key that is selected + * @param string $optText The name of the object variable for the option value + * @param string $selected The name of the object variable for the option text + * @param boolean $idtag Value of the field id or null by default + * @param boolean $translate True if options will be translated + * + * @return string HTML for the select list + * + * @since 1.5 + */ + public static function radiolist($data, $name, $attribs = null, $optKey = 'value', $optText = 'text', $selected = null, $idtag = false, + $translate = false) + { + + if (is_array($attribs)) + { + $attribs = ArrayHelper::toString($attribs); + } + + $id_text = $idtag ?: $name; + + $html = '
      '; + + foreach ($data as $obj) + { + $k = $obj->$optKey; + $t = $translate ? JText::_($obj->$optText) : $obj->$optText; + $id = (isset($obj->id) ? $obj->id : null); + + $extra = ''; + $id = $id ? $obj->id : $id_text . $k; + + if (is_array($selected)) + { + foreach ($selected as $val) + { + $k2 = is_object($val) ? $val->$optKey : $val; + + if ($k == $k2) + { + $extra .= ' selected="selected" '; + break; + } + } + } + else + { + $extra .= ((string) $k === (string) $selected ? ' checked="checked" ' : ''); + } + + $html .= "\n\t" . ''; + } + + $html .= "\n"; + $html .= '
      '; + $html .= "\n"; + + return $html; + } +} diff --git a/Sites/pages/libraries/cms/html/sidebar.php b/Sites/pages/libraries/cms/html/sidebar.php new file mode 100644 index 00000000..43457402 --- /dev/null +++ b/Sites/pages/libraries/cms/html/sidebar.php @@ -0,0 +1,149 @@ +list = static::getEntries(); + $data->filters = static::getFilters(); + $data->action = static::getAction(); + $data->displayMenu = count($data->list); + $data->displayFilters = count($data->filters); + $data->hide = JFactory::getApplication()->input->getBool('hidemainmenu'); + + // Create a layout object and ask it to render the sidebar + $layout = new JLayoutFile('joomla.sidebars.submenu'); + + return $layout->render($data); + } + + /** + * Method to add a menu item to submenu. + * + * @param string $name Name of the menu item. + * @param string $link URL of the menu item. + * @param bool $active True if the item is active, false otherwise. + * + * @return void + * + * @since 3.0 + */ + public static function addEntry($name, $link = '', $active = false) + { + static::$entries[] = array($name, $link, $active); + } + + /** + * Returns an array of all submenu entries + * + * @return array + * + * @since 3.0 + */ + public static function getEntries() + { + return static::$entries; + } + + /** + * Method to add a filter to the submenu + * + * @param string $label Label for the menu item. + * @param string $name Name for the filter. Also used as id. + * @param string $options Options for the select field. + * @param bool $noDefault Don't show the label as the empty option + * + * @return void + * + * @since 3.0 + */ + public static function addFilter($label, $name, $options, $noDefault = false) + { + static::$filters[] = array('label' => $label, 'name' => $name, 'options' => $options, 'noDefault' => $noDefault); + } + + /** + * Returns an array of all filters + * + * @return array + * + * @since 3.0 + */ + public static function getFilters() + { + return static::$filters; + } + + /** + * Set value for the action attribute of the filter form + * + * @param string $action Value for the action attribute of the form + * + * @return void + * + * @since 3.0 + */ + public static function setAction($action) + { + static::$action = $action; + } + + /** + * Get value for the action attribute of the filter form + * + * @return string + * + * @since 3.0 + */ + public static function getAction() + { + return static::$action; + } +} diff --git a/Sites/pages/libraries/cms/html/sliders.php b/Sites/pages/libraries/cms/html/sliders.php new file mode 100644 index 00000000..45276594 --- /dev/null +++ b/Sites/pages/libraries/cms/html/sliders.php @@ -0,0 +1,123 @@ +
      '; + } + + /** + * Close the current pane. + * + * @return string hTML to close the pane + * + * @since 1.6 + * @deprecated 3.7.0 These helpers are dependent on the deprecated MooTools support + */ + public static function end() + { + return '
      '; + } + + /** + * Begins the display of a new panel. + * + * @param string $text Text to display. + * @param string $id Identifier of the panel. + * + * @return string HTML to start a panel + * + * @since 1.6 + * @deprecated 3.7.0 These helpers are dependent on the deprecated MooTools support + */ + public static function panel($text, $id) + { + return '

      ' . $text + . '

      '; + } + + /** + * Load the JavaScript behavior. + * + * @param string $group The pane identifier. + * @param array $params Array of options. + * + * @return void + * + * @since 1.6 + * @deprecated 3.7.0 These helpers are dependent on the deprecated MooTools support + */ + protected static function loadBehavior($group, $params = array()) + { + static $loaded = array(); + + if (!array_key_exists($group, $loaded)) + { + // Get the JInput object + $input = JFactory::getApplication()->input; + + $loaded[$group] = true; + + // Include mootools framework. + JHtml::_('behavior.framework', true); + + $document = JFactory::getDocument(); + + $display = (isset($params['startOffset']) && isset($params['startTransition']) && $params['startTransition']) + ? (int) $params['startOffset'] : null; + $show = (isset($params['startOffset']) && !(isset($params['startTransition']) && $params['startTransition'])) + ? (int) $params['startOffset'] : null; + + $opt['onActive'] = "\\function(toggler, i) {toggler.addClass('pane-toggler-down');" . + "toggler.removeClass('pane-toggler');i.addClass('pane-down');i.removeClass('pane-hide');Cookie.write('jpanesliders_" + . $group . "',$$('div#" . $group . ".pane-sliders > .panel > h3').indexOf(toggler));}"; + $opt['onBackground'] = "\\function(toggler, i) {toggler.addClass('pane-toggler');" . + "toggler.removeClass('pane-toggler-down');i.addClass('pane-hide');i.removeClass('pane-down');if($$('div#" + . $group . ".pane-sliders > .panel > h3').length==$$('div#" . $group + . ".pane-sliders > .panel > h3.pane-toggler').length) Cookie.write('jpanesliders_" . $group . "',-1);}"; + $opt['duration'] = isset($params['duration']) ? (int) $params['duration'] : 300; + $opt['display'] = (isset($params['useCookie']) && $params['useCookie']) ? $input->cookie->get('jpanesliders_' . $group, $display, 'integer') + : $display; + $opt['show'] = (isset($params['useCookie']) && $params['useCookie']) ? $input->cookie->get('jpanesliders_' . $group, $show, 'integer') : $show; + $opt['opacity'] = (isset($params['opacityTransition']) && $params['opacityTransition']) ? 'true' : 'false'; + $opt['alwaysHide'] = (isset($params['allowAllClose']) && (!$params['allowAllClose'])) ? 'false' : 'true'; + + $options = JHtml::getJSObject($opt); + + $js = "window.addEvent('domready', function(){ new Fx.Accordion($$('div#" . $group + . ".pane-sliders > .panel > h3.pane-toggler'), $$('div#" . $group . ".pane-sliders > .panel > div.pane-slider'), " . $options + . "); });"; + + $document->addScriptDeclaration($js); + } + } +} diff --git a/Sites/pages/libraries/cms/html/sortablelist.php b/Sites/pages/libraries/cms/html/sortablelist.php new file mode 100644 index 00000000..9a12e795 --- /dev/null +++ b/Sites/pages/libraries/cms/html/sortablelist.php @@ -0,0 +1,107 @@ + $tableId, + 'formId' => $formId, + 'sortDir' => $sortDir, + 'saveOrderingUrl' => $saveOrderingUrl, + 'nestedList' => $nestedList, + 'proceedSaveOrderButton' => $proceedSaveOrderButton, + ); + + JLayoutHelper::render('joomla.html.sortablelist', $displayData); + + // Set static array + static::$loaded[__METHOD__] = true; + + return; + } + + /** + * Method to inject script for enabled and disable Save order button + * when changing value of ordering input boxes + * + * @return void + * + * @since 3.0 + * + * @deprecated 4.0 The logic is merged in the JLayout file + */ + public static function _proceedSaveOrderButton() + { + JFactory::getDocument()->addScriptDeclaration( + "(function ($){ + $(document).ready(function (){ + var saveOrderButton = $('.saveorder'); + saveOrderButton.css({'opacity':'0.2', 'cursor':'default'}).attr('onclick','return false;'); + var oldOrderingValue = ''; + $('.text-area-order').focus(function () + { + oldOrderingValue = $(this).attr('value'); + }) + .keyup(function (){ + var newOrderingValue = $(this).attr('value'); + if (oldOrderingValue != newOrderingValue) + { + saveOrderButton.css({'opacity':'1', 'cursor':'pointer'}).removeAttr('onclick') + } + }); + }); + })(jQuery);" + ); + + return; + } +} diff --git a/Sites/pages/libraries/cms/html/string.php b/Sites/pages/libraries/cms/html/string.php new file mode 100644 index 00000000..3e802cc9 --- /dev/null +++ b/Sites/pages/libraries/cms/html/string.php @@ -0,0 +1,301 @@ +', '> ', $text); + $text = str_replace(array(' ', ' '), ' ', $text); + $text = StringHelper::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 = StringHelper::trim(preg_replace('#\s+#mui', ' ', $text)); + } + + // Whether or not allowing HTML, truncate the item text if it is too long. + if ($length > 0 && StringHelper::strlen($text) > $length) + { + $tmp = trim(StringHelper::substr($text, 0, $length)); + + if ($tmp[0] === '<' && 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 = StringHelper::strrpos($tmp, ' '); + $tmp = StringHelper::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 (StringHelper::strlen($tmp) > $length - 3) + { + $tmp = trim(StringHelper::substr($tmp, 0, StringHelper::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("#]*?)>#iU", $tmp, $result); + $closedTags = $result[1]; + + $numOpened = count($openedTags); + + // Not all tags are closed so trim the text and finish. + if (count($closedTags) !== $numOpened) + { + // 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 .= ''; + } + else + { + unset($closedTags[array_search($openedTags[$i], $closedTags)]); + } + } + } + + // Check if we are within a tag + if (StringHelper::strrpos($tmp, '<') > StringHelper::strrpos($tmp, '>')) + { + $offset = StringHelper::strrpos($tmp, '<'); + $tmp = StringHelper::trim(StringHelper::substr($tmp, 0, $offset)); + } + } + + if ($tmp === false || strlen($text) > strlen($tmp)) + { + $text = trim($tmp) . '...'; + } + } + + // Clean up any internal spaces created by the processing. + $text = str_replace(' $maxLength) + { + return '...'; + } + + // Deal with maximum length of 1 where the string starts with a tag. + if ($maxLength === 1 && $html[0] === '<') + { + $endTagPos = strlen(strstr($html, '>', true)); + $tag = substr($html, 1, $endTagPos); + + $l = $endTagPos + 1; + + if ($noSplit) + { + return substr($html, 0, $l) . ' $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 (StringHelper::strlen($text) > $length) + { + // Determine the remaining text length. + $remainder = $length - ($intro + 3); + + // Extract the beginning and ending text sections. + $beg = StringHelper::substr($text, 0, $intro); + $end = StringHelper::substr($text, StringHelper::strlen($text) - $remainder); + + // Build the resulting string. + $text = $beg . '...' . $end; + } + + return $text; + } +} diff --git a/Sites/pages/libraries/cms/html/tabs.php b/Sites/pages/libraries/cms/html/tabs.php new file mode 100644 index 00000000..2908d57d --- /dev/null +++ b/Sites/pages/libraries/cms/html/tabs.php @@ -0,0 +1,111 @@ +
      '; + } + + /** + * Close the current pane + * + * @return string HTML to close the pane + * + * @since 1.6 + * @deprecated 3.7.0 These helpers are dependent on the deprecated MooTools support + */ + public static function end() + { + return '
      '; + } + + /** + * Begins the display of a new panel. + * + * @param string $text Text to display. + * @param string $id Identifier of the panel. + * + * @return string HTML to start a new panel + * + * @since 1.6 + * @deprecated 3.7.0 These helpers are dependent on the deprecated MooTools support + */ + public static function panel($text, $id) + { + return '

      ' . $text . '

      '; + } + + /** + * Load the JavaScript behavior. + * + * @param string $group The pane identifier. + * @param array $params Array of options. + * + * @return void + * + * @since 1.6 + * @deprecated 3.7.0 These helpers are dependent on the deprecated MooTools support + */ + protected static function loadBehavior($group, $params = array()) + { + static $loaded = array(); + + if (!array_key_exists((string) $group, $loaded)) + { + // Include MooTools framework + JHtml::_('behavior.framework', true); + + $opt['onActive'] = isset($params['onActive']) ? '\\' . $params['onActive'] : null; + $opt['onBackground'] = isset($params['onBackground']) ? '\\' . $params['onBackground'] : null; + $opt['display'] = isset($params['startOffset']) ? (int) $params['startOffset'] : null; + $opt['titleSelector'] = 'dt.tabs'; + $opt['descriptionSelector'] = 'dd.tabs'; + + // When use storage is set and value is false - By default we allow to use storage + $opt['useStorage'] = !(isset($params['useCookie']) && !$params['useCookie']); + + $options = JHtml::getJSObject($opt); + + $js = ' window.addEvent(\'domready\', function(){ + $$(\'dl#' . $group . '.tabs\').each(function(tabs){ + new JTabs(tabs, ' . $options . '); + }); + });'; + + $document = JFactory::getDocument(); + $document->addScriptDeclaration($js); + JHtml::_('script', 'system/tabs.js', array('version' => 'auto', 'relative' => true)); + + $loaded[(string) $group] = true; + } + } +} diff --git a/Sites/pages/libraries/cms/html/tag.php b/Sites/pages/libraries/cms/html/tag.php new file mode 100644 index 00000000..6454ab46 --- /dev/null +++ b/Sites/pages/libraries/cms/html/tag.php @@ -0,0 +1,180 @@ + array(0, 1))) + { + $hash = md5(serialize($config)); + + if (!isset(static::$items[$hash])) + { + $config = (array) $config; + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->select('a.id, a.title, a.level') + ->from('#__tags AS a') + ->where('a.parent_id > 0'); + + // Filter on the published state + if (isset($config['filter.published'])) + { + if (is_numeric($config['filter.published'])) + { + $query->where('a.published = ' . (int) $config['filter.published']); + } + elseif (is_array($config['filter.published'])) + { + $config['filter.published'] = ArrayHelper::toInteger($config['filter.published']); + $query->where('a.published IN (' . implode(',', $config['filter.published']) . ')'); + } + } + + // Filter on the language + if (isset($config['filter.language'])) + { + if (is_string($config['filter.language'])) + { + $query->where('a.language = ' . $db->quote($config['filter.language'])); + } + elseif (is_array($config['filter.language'])) + { + foreach ($config['filter.language'] as &$language) + { + $language = $db->quote($language); + } + + $query->where('a.language IN (' . implode(',', $config['filter.language']) . ')'); + } + } + + $query->order('a.lft'); + + $db->setQuery($query); + $items = $db->loadObjectList(); + + // Assemble the list options. + static::$items[$hash] = array(); + + foreach ($items as &$item) + { + $repeat = ($item->level - 1 >= 0) ? $item->level - 1 : 0; + $item->title = str_repeat('- ', $repeat) . $item->title; + static::$items[$hash][] = JHtml::_('select.option', $item->id, $item->title); + } + } + + return static::$items[$hash]; + } + + /** + * Returns an array of tags. + * + * @param array $config An array of configuration options. By default, only published and unpublished tags are returned. + * + * @return array Tag data + * + * @since 3.1 + */ + public static function tags($config = array('filter.published' => array(0, 1))) + { + $hash = md5(serialize($config)); + $config = (array) $config; + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->select('a.id, a.title, a.level, a.parent_id') + ->from('#__tags AS a') + ->where('a.parent_id > 0'); + + // Filter on the published state + if (isset($config['filter.published'])) + { + if (is_numeric($config['filter.published'])) + { + $query->where('a.published = ' . (int) $config['filter.published']); + } + elseif (is_array($config['filter.published'])) + { + $config['filter.published'] = ArrayHelper::toInteger($config['filter.published']); + $query->where('a.published IN (' . implode(',', $config['filter.published']) . ')'); + } + } + + $query->order('a.lft'); + + $db->setQuery($query); + $items = $db->loadObjectList(); + + // Assemble the list options. + static::$items[$hash] = array(); + + foreach ($items as &$item) + { + $repeat = ($item->level - 1 >= 0) ? $item->level - 1 : 0; + $item->title = str_repeat('- ', $repeat) . $item->title; + static::$items[$hash][] = JHtml::_('select.option', $item->id, $item->title); + } + + return static::$items[$hash]; + } + + /** + * This is just a proxy for the formbehavior.ajaxchosen method + * + * @param string $selector DOM id of the tag field + * @param boolean $allowCustom Flag to allow custom values + * + * @return void + * + * @since 3.1 + */ + public static function ajaxfield($selector = '#jform_tags', $allowCustom = true) + { + // Get the component parameters + $params = JComponentHelper::getParams('com_tags'); + $minTermLength = (int) $params->get('min_term_length', 3); + + $displayData = array( + 'minTermLength' => $minTermLength, + 'selector' => $selector, + 'allowCustom' => JFactory::getUser()->authorise('core.create', 'com_tags') ? $allowCustom : false, + ); + + JLayoutHelper::render('joomla.html.tag', $displayData); + + return; + } +} diff --git a/Sites/pages/libraries/cms/html/tel.php b/Sites/pages/libraries/cms/html/tel.php new file mode 100644 index 00000000..ace320a0 --- /dev/null +++ b/Sites/pages/libraries/cms/html/tel.php @@ -0,0 +1,75 @@ +getAll()); + + for ($i = 0, $n = count($options); $i < $n; $i++) + { + $options[$i]->value = $options[$i]->id; + $options[$i]->text = str_repeat('- ', $options[$i]->level) . $options[$i]->title; + $groups[] = JHtml::_('select.option', $options[$i]->value, $options[$i]->text); + } + + // Exclude super admin groups if requested + if (!$includeSuperAdmin) + { + $filteredGroups = array(); + + foreach ($groups as $group) + { + if (!JAccess::checkGroup($group->value, 'core.admin')) + { + $filteredGroups[] = $group; + } + } + + $groups = $filteredGroups; + } + + return $groups; + } + + /** + * Get a list of users. + * + * @return string + * + * @since 2.5 + */ + public static function userlist() + { + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->select('a.id AS value, a.name AS text') + ->from('#__users AS a') + ->where('a.block = 0') + ->order('a.name'); + $db->setQuery($query); + + return $db->loadObjectList(); + } +} diff --git a/Sites/pages/libraries/cms/less/formatter/joomla.php b/Sites/pages/libraries/cms/less/formatter/joomla.php new file mode 100644 index 00000000..97a20e53 --- /dev/null +++ b/Sites/pages/libraries/cms/less/formatter/joomla.php @@ -0,0 +1,31 @@ +setFormatter($formatter); + } + + /** + * Override compile to reset $this->allParsedFiles array to allow + * parsing multiple files/strings using same imports. + * PR: https://github.com/leafo/lessphp/pull/607 + * + * For documentation on this please see /vendor/leafo/lessc.inc.php + * + * @param string $string LESS string to parse. + * @param string $name The sourceName used for error messages. + * + * @return string $out The compiled css output. + */ + public function compile($string, $name = null) + { + $this->allParsedFiles = array(); + + return parent::compile($string, $name); + } +} diff --git a/Sites/pages/libraries/fof/LICENSE.txt b/Sites/pages/libraries/fof/LICENSE.txt new file mode 100644 index 00000000..56e598d4 --- /dev/null +++ b/Sites/pages/libraries/fof/LICENSE.txt @@ -0,0 +1,345 @@ +================================================================================ +Historical note +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +On February 21st, 2013 FOF changed its license to GPLv2 or later. +================================================================================ + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. \ No newline at end of file diff --git a/Sites/pages/libraries/fof/autoloader/component.php b/Sites/pages/libraries/fof/autoloader/component.php new file mode 100644 index 00000000..9b016587 --- /dev/null +++ b/Sites/pages/libraries/fof/autoloader/component.php @@ -0,0 +1,781 @@ +getComponentBaseDirs($component); + $fofComponents[$component] = file_exists($componentPaths['admin'] . '/fof.xml'); + } + + return $fofComponents[$component]; + } + + /** + * Creates class aliases. On systems where eval() is enabled it creates a + * real class. On other systems it merely creates an alias. The eval() + * method is preferred as class_aliases result in the name of the class + * being instantiated not being available, making it impossible to create + * a class instance without passing a $config array :( + * + * @param string $original The name of the original (existing) class + * @param string $alias The name of the new (aliased) class + * @param boolean $autoload Should I try to autoload the $original class? + * + * @return void + */ + private function class_alias($original, $alias, $autoload = true) + { + static $hasEval = null; + + if (is_null($hasEval)) + { + $hasEval = false; + + if (function_exists('ini_get')) + { + $disabled_functions = ini_get('disabled_functions'); + + if (!is_string($disabled_functions)) + { + $hasEval = true; + } + else + { + $disabled_functions = explode(',', $disabled_functions); + $hasEval = !in_array('eval', $disabled_functions); + } + } + } + + if (!class_exists($original, $autoload)) + { + return; + } + + if ($hasEval) + { + $phpCode = "class $alias extends $original {}"; + eval($phpCode); + } + else + { + class_alias($original, $alias, $autoload); + } + } + + /** + * Autoload Controllers + * + * @param string $class_name The name of the class to load + * + * @return void + */ + public function autoload_fof_controller($class_name) + { + FOFPlatform::getInstance()->logDebug(__METHOD__ . "() autoloading $class_name"); + + static $isCli = null, $isAdmin = null; + + if (is_null($isCli) && is_null($isAdmin)) + { + list($isCli, $isAdmin) = FOFDispatcher::isCliAdmin(); + } + + if (strpos($class_name, 'Controller') === false) + { + return; + } + + // Change from camel cased into a lowercase array + $class_modified = preg_replace('/(\s)+/', '_', $class_name); + $class_modified = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $class_modified)); + $parts = explode('_', $class_modified); + + // We need three parts in the name + if (count($parts) != 3) + { + return; + } + + // We need the second part to be "controller" + if ($parts[1] != 'controller') + { + return; + } + + // Get the information about this class + $component_raw = $parts[0]; + $component = 'com_' . $parts[0]; + $view = $parts[2]; + + // Is this an FOF 2.1 or later component? + if (!$this->isFOFComponent($component)) + { + return; + } + + // Get the alternate view and class name (opposite singular/plural name) + $alt_view = FOFInflector::isSingular($view) ? FOFInflector::pluralize($view) : FOFInflector::singularize($view); + $alt_class = FOFInflector::camelize($component_raw . '_controller_' . $alt_view); + + // Get the component's paths + $componentPaths = FOFPlatform::getInstance()->getComponentBaseDirs($component); + + // Get the proper and alternate paths and file names + $file = "/controllers/$view.php"; + $altFile = "/controllers/$alt_view.php"; + $path = $componentPaths['main']; + $altPath = $componentPaths['alt']; + + // Try to find the proper class in the proper path + if (file_exists($path . $file)) + { + @include_once $path . $file; + } + + // Try to find the proper class in the alternate path + if (!class_exists($class_name) && file_exists($altPath . $file)) + { + @include_once $altPath . $file; + } + + // Try to find the alternate class in the proper path + if (!class_exists($alt_class) && file_exists($path . $altFile)) + { + @include_once $path . $altFile; + } + + // Try to find the alternate class in the alternate path + if (!class_exists($alt_class) && file_exists($altPath . $altFile)) + { + @include_once $altPath . $altFile; + } + + // If the alternate class exists just map the class to the alternate + if (!class_exists($class_name) && class_exists($alt_class)) + { + $this->class_alias($alt_class, $class_name); + } + + // No class found? Map to FOFController + elseif (!class_exists($class_name)) + { + if ($view != 'default') + { + $defaultClass = FOFInflector::camelize($component_raw . '_controller_default'); + $this->class_alias($defaultClass, $class_name); + } + else + { + $this->class_alias('FOFController', $class_name); + } + } + } + + /** + * Autoload Models + * + * @param string $class_name The name of the class to load + * + * @return void + */ + public function autoload_fof_model($class_name) + { + FOFPlatform::getInstance()->logDebug(__METHOD__ . "() autoloading $class_name"); + + static $isCli = null, $isAdmin = null; + + if (is_null($isCli) && is_null($isAdmin)) + { + list($isCli, $isAdmin) = FOFDispatcher::isCliAdmin(); + } + + if (strpos($class_name, 'Model') === false) + { + return; + } + + // Change from camel cased into a lowercase array + $class_modified = preg_replace('/(\s)+/', '_', $class_name); + $class_modified = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $class_modified)); + $parts = explode('_', $class_modified); + + // We need three parts in the name + if (count($parts) != 3) + { + return; + } + + // We need the second part to be "model" + if ($parts[1] != 'model') + { + return; + } + + // Get the information about this class + $component_raw = $parts[0]; + $component = 'com_' . $parts[0]; + $view = $parts[2]; + + // Is this an FOF 2.1 or later component? + if (!$this->isFOFComponent($component)) + { + return; + } + + // Get the alternate view and class name (opposite singular/plural name) + $alt_view = FOFInflector::isSingular($view) ? FOFInflector::pluralize($view) : FOFInflector::singularize($view); + $alt_class = FOFInflector::camelize($component_raw . '_model_' . $alt_view); + + // Get the proper and alternate paths and file names + $componentPaths = FOFPlatform::getInstance()->getComponentBaseDirs($component); + + $file = "/models/$view.php"; + $altFile = "/models/$alt_view.php"; + $path = $componentPaths['main']; + $altPath = $componentPaths['alt']; + + // Try to find the proper class in the proper path + if (file_exists($path . $file)) + { + @include_once $path . $file; + } + + // Try to find the proper class in the alternate path + if (!class_exists($class_name) && file_exists($altPath . $file)) + { + @include_once $altPath . $file; + } + + // Try to find the alternate class in the proper path + if (!class_exists($alt_class) && file_exists($path . $altFile)) + { + @include_once $path . $altFile; + } + + // Try to find the alternate class in the alternate path + if (!class_exists($alt_class) && file_exists($altPath . $altFile)) + { + @include_once $altPath . $altFile; + } + + // If the alternate class exists just map the class to the alternate + if (!class_exists($class_name) && class_exists($alt_class)) + { + $this->class_alias($alt_class, $class_name); + } + + // No class found? Map to FOFModel + elseif (!class_exists($class_name)) + { + if ($view != 'default') + { + $defaultClass = FOFInflector::camelize($component_raw . '_model_default'); + $this->class_alias($defaultClass, $class_name); + } + else + { + $this->class_alias('FOFModel', $class_name, true); + } + } + } + + /** + * Autoload Views + * + * @param string $class_name The name of the class to load + * + * @return void + */ + public function autoload_fof_view($class_name) + { + FOFPlatform::getInstance()->logDebug(__METHOD__ . "() autoloading $class_name"); + + static $isCli = null, $isAdmin = null; + + if (is_null($isCli) && is_null($isAdmin)) + { + list($isCli, $isAdmin) = FOFDispatcher::isCliAdmin(); + } + + if (strpos($class_name, 'View') === false) + { + return; + } + + // Change from camel cased into a lowercase array + $class_modified = preg_replace('/(\s)+/', '_', $class_name); + $class_modified = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $class_modified)); + $parts = explode('_', $class_modified); + + // We need at least three parts in the name + + if (count($parts) < 3) + { + return; + } + + // We need the second part to be "view" + + if ($parts[1] != 'view') + { + return; + } + + // Get the information about this class + $component_raw = $parts[0]; + $component = 'com_' . $parts[0]; + $view = $parts[2]; + + if (count($parts) > 3) + { + $format = $parts[3]; + } + else + { + $input = new FOFInput; + $format = $input->getCmd('format', 'html', 'cmd'); + } + + // Is this an FOF 2.1 or later component? + if (!$this->isFOFComponent($component)) + { + return; + } + + // Get the alternate view and class name (opposite singular/plural name) + $alt_view = FOFInflector::isSingular($view) ? FOFInflector::pluralize($view) : FOFInflector::singularize($view); + $alt_class = FOFInflector::camelize($component_raw . '_view_' . $alt_view); + + // Get the proper and alternate paths and file names + $componentPaths = FOFPlatform::getInstance()->getComponentBaseDirs($component); + + $protoFile = "/models/$view"; + $protoAltFile = "/models/$alt_view"; + $path = $componentPaths['main']; + $altPath = $componentPaths['alt']; + + $formats = array($format); + + if ($format != 'html') + { + $formats[] = 'raw'; + } + + foreach ($formats as $currentFormat) + { + $file = $protoFile . '.' . $currentFormat . '.php'; + $altFile = $protoAltFile . '.' . $currentFormat . '.php'; + + // Try to find the proper class in the proper path + if (!class_exists($class_name) && file_exists($path . $file)) + { + @include_once $path . $file; + } + + // Try to find the proper class in the alternate path + if (!class_exists($class_name) && file_exists($altPath . $file)) + { + @include_once $altPath . $file; + } + + // Try to find the alternate class in the proper path + if (!class_exists($alt_class) && file_exists($path . $altFile)) + { + @include_once $path . $altFile; + } + + // Try to find the alternate class in the alternate path + if (!class_exists($alt_class) && file_exists($altPath . $altFile)) + { + @include_once $altPath . $altFile; + } + } + + // If the alternate class exists just map the class to the alternate + if (!class_exists($class_name) && class_exists($alt_class)) + { + $this->class_alias($alt_class, $class_name); + } + + // No class found? Map to FOFModel + elseif (!class_exists($class_name)) + { + if ($view != 'default') + { + $defaultClass = FOFInflector::camelize($component_raw . '_view_default'); + $this->class_alias($defaultClass, $class_name); + } + else + { + if (!file_exists(self::$fofPath . '/view/' . $format . '.php')) + { + $default_class = 'FOFView'; + } + else + { + $default_class = 'FOFView' . ucfirst($format); + } + + $this->class_alias($default_class, $class_name, true); + } + } + } + + /** + * Autoload Tables + * + * @param string $class_name The name of the class to load + * + * @return void + */ + public function autoload_fof_table($class_name) + { + FOFPlatform::getInstance()->logDebug(__METHOD__ . "() autoloading $class_name"); + + static $isCli = null, $isAdmin = null; + + if (is_null($isCli) && is_null($isAdmin)) + { + list($isCli, $isAdmin) = FOFDispatcher::isCliAdmin(); + } + + if (strpos($class_name, 'Table') === false) + { + return; + } + + // Change from camel cased into a lowercase array + $class_modified = preg_replace('/(\s)+/', '_', $class_name); + $class_modified = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $class_modified)); + $parts = explode('_', $class_modified); + + // We need three parts in the name + + if (count($parts) != 3) + { + return; + } + + // We need the second part to be "model" + if ($parts[1] != 'table') + { + return; + } + + // Get the information about this class + $component_raw = $parts[0]; + $component = 'com_' . $parts[0]; + $view = $parts[2]; + + // Is this an FOF 2.1 or later component? + if (!$this->isFOFComponent($component)) + { + return; + } + + // Get the alternate view and class name (opposite singular/plural name) + $alt_view = FOFInflector::isSingular($view) ? FOFInflector::pluralize($view) : FOFInflector::singularize($view); + $alt_class = FOFInflector::camelize($component_raw . '_table_' . $alt_view); + + // Get the proper and alternate paths and file names + $componentPaths = FOFPlatform::getInstance()->getComponentBaseDirs($component); + + $file = "/tables/$view.php"; + $altFile = "/tables/$alt_view.php"; + $path = $componentPaths['admin']; + + // Try to find the proper class in the proper path + if (file_exists($path . $file)) + { + @include_once $path . $file; + } + + // Try to find the alternate class in the proper path + if (!class_exists($alt_class) && file_exists($path . $altFile)) + { + @include_once $path . $altFile; + } + + // If the alternate class exists just map the class to the alternate + if (!class_exists($class_name) && class_exists($alt_class)) + { + $this->class_alias($alt_class, $class_name); + } + + // No class found? Map to FOFModel + elseif (!class_exists($class_name)) + { + if ($view != 'default') + { + $defaultClass = FOFInflector::camelize($component_raw . '_table_default'); + $this->class_alias($defaultClass, $class_name); + } + else + { + $this->class_alias('FOFTable', $class_name, true); + } + } + } + + /** + * Autoload Helpers + * + * @param string $class_name The name of the class to load + * + * @return void + */ + public function autoload_fof_helper($class_name) + { + FOFPlatform::getInstance()->logDebug(__METHOD__ . "() autoloading $class_name"); + + static $isCli = null, $isAdmin = null; + + if (is_null($isCli) && is_null($isAdmin)) + { + list($isCli, $isAdmin) = FOFDispatcher::isCliAdmin(); + } + + if (strpos($class_name, 'Helper') === false) + { + return; + } + + // Change from camel cased into a lowercase array + $class_modified = preg_replace('/(\s)+/', '_', $class_name); + $class_modified = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $class_modified)); + $parts = explode('_', $class_modified); + + // We need three parts in the name + if (count($parts) != 3) + { + return; + } + + // We need the second part to be "model" + if ($parts[1] != 'helper') + { + return; + } + + // Get the information about this class + $component_raw = $parts[0]; + $component = 'com_' . $parts[0]; + $view = $parts[2]; + + // Is this an FOF 2.1 or later component? + if (!$this->isFOFComponent($component)) + { + return; + } + + // Get the alternate view and class name (opposite singular/plural name) + $alt_view = FOFInflector::isSingular($view) ? FOFInflector::pluralize($view) : FOFInflector::singularize($view); + $alt_class = FOFInflector::camelize($component_raw . '_helper_' . $alt_view); + + // Get the proper and alternate paths and file names + $componentPaths = FOFPlatform::getInstance()->getComponentBaseDirs($component); + + $file = "/helpers/$view.php"; + $altFile = "/helpers/$alt_view.php"; + $path = $componentPaths['main']; + $altPath = $componentPaths['alt']; + + // Try to find the proper class in the proper path + if (file_exists($path . $file)) + { + @include_once $path . $file; + } + + // Try to find the proper class in the alternate path + if (!class_exists($class_name) && file_exists($altPath . $file)) + { + @include_once $altPath . $file; + } + + // Try to find the alternate class in the proper path + if (!class_exists($alt_class) && file_exists($path . $altFile)) + { + @include_once $path . $altFile; + } + + // Try to find the alternate class in the alternate path + if (!class_exists($alt_class) && file_exists($altPath . $altFile)) + { + @include_once $altPath . $altFile; + } + + // If the alternate class exists just map the class to the alternate + if (!class_exists($class_name) && class_exists($alt_class)) + { + $this->class_alias($alt_class, $class_name); + } + } + + /** + * Autoload Toolbars + * + * @param string $class_name The name of the class to load + * + * @return void + */ + public function autoload_fof_toolbar($class_name) + { + FOFPlatform::getInstance()->logDebug(__METHOD__ . "() autoloading $class_name"); + + static $isCli = null, $isAdmin = null; + + if (is_null($isCli) && is_null($isAdmin)) + { + list($isCli, $isAdmin) = FOFDispatcher::isCliAdmin(); + } + + if (strpos($class_name, 'Toolbar') === false) + { + return; + } + + // Change from camel cased into a lowercase array + $class_modified = preg_replace('/(\s)+/', '_', $class_name); + $class_modified = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $class_modified)); + $parts = explode('_', $class_modified); + + // We need two parts in the name + if (count($parts) != 2) + { + return; + } + + // We need the second part to be "model" + if ($parts[1] != 'toolbar') + { + return; + } + + // Get the information about this class + $component_raw = $parts[0]; + $component = 'com_' . $parts[0]; + + $platformDirs = FOFPlatform::getInstance()->getPlatformBaseDirs(); + + // Get the proper and alternate paths and file names + $file = "/components/$component/toolbar.php"; + $path = ($isAdmin || $isCli) ? $platformDirs['admin'] : $platformDirs['public']; + $altPath = ($isAdmin || $isCli) ? $platformDirs['public'] : $platformDirs['admin']; + + // Try to find the proper class in the proper path + + if (file_exists($path . $file)) + { + @include_once $path . $file; + } + + // Try to find the proper class in the alternate path + if (!class_exists($class_name) && file_exists($altPath . $file)) + { + @include_once $altPath . $file; + } + + // No class found? Map to FOFToolbar + if (!class_exists($class_name)) + { + $this->class_alias('FOFToolbar', $class_name, true); + } + } + + /** + * Autoload Fields + * + * @param string $class_name The name of the class to load + * + * @return void + */ + public function autoload_fof_field($class_name) + { + FOFPlatform::getInstance()->logDebug(__METHOD__ . "() autoloading $class_name"); + + // @todo + } +} diff --git a/Sites/pages/libraries/fof/autoloader/fof.php b/Sites/pages/libraries/fof/autoloader/fof.php new file mode 100644 index 00000000..602c9192 --- /dev/null +++ b/Sites/pages/libraries/fof/autoloader/fof.php @@ -0,0 +1,116 @@ +dispatcher; + + // Sanity check + + if (empty($dispatcherData)) + { + return; + } + + $options = $xml->xpath('dispatcher/option'); + + if (!empty($options)) + { + foreach ($options as $option) + { + $key = (string) $option['name']; + $ret['dispatcher'][$key] = (string) $option; + } + } + } + + /** + * Return a configuration variable + * + * @param string &$configuration Configuration variables (hashed array) + * @param string $var The variable we want to fetch + * @param mixed $default Default value + * + * @return mixed The variable's value + */ + public function get(&$configuration, $var, $default) + { + if (isset($configuration['dispatcher'][$var])) + { + return $configuration['dispatcher'][$var]; + } + else + { + return $default; + } + } +} diff --git a/Sites/pages/libraries/fof/config/domain/interface.php b/Sites/pages/libraries/fof/config/domain/interface.php new file mode 100644 index 00000000..44a6101f --- /dev/null +++ b/Sites/pages/libraries/fof/config/domain/interface.php @@ -0,0 +1,42 @@ +xpath('table'); + + // Sanity check + if (empty($tableData)) + { + return; + } + + foreach ($tableData as $aTable) + { + $key = (string) $aTable['name']; + + $ret['tables'][$key]['behaviors'] = (string) $aTable->behaviors; + $ret['tables'][$key]['tablealias'] = $aTable->xpath('tablealias'); + $ret['tables'][$key]['fields'] = array(); + $ret['tables'][$key]['relations'] = array(); + + $fieldData = $aTable->xpath('field'); + + if (!empty($fieldData)) + { + foreach ($fieldData as $field) + { + $k = (string) $field['name']; + $ret['tables'][$key]['fields'][$k] = (string) $field; + } + } + + $relationsData = $aTable->xpath('relation'); + + if (!empty($relationsData)) + { + foreach ($relationsData as $relationData) + { + $type = (string)$relationData['type']; + $itemName = (string)$relationData['name']; + + if (empty($type) || empty($itemName)) + { + continue; + } + + $tableClass = (string)$relationData['tableClass']; + $localKey = (string)$relationData['localKey']; + $remoteKey = (string)$relationData['remoteKey']; + $ourPivotKey = (string)$relationData['ourPivotKey']; + $theirPivotKey = (string)$relationData['theirPivotKey']; + $pivotTable = (string)$relationData['pivotTable']; + $default = (string)$relationData['default']; + + $default = !in_array($default, array('no', 'false', 0)); + + $relation = array( + 'type' => $type, + 'itemName' => $itemName, + 'tableClass' => empty($tableClass) ? null : $tableClass, + 'localKey' => empty($localKey) ? null : $localKey, + 'remoteKey' => empty($remoteKey) ? null : $remoteKey, + 'default' => $default, + ); + + if (!empty($ourPivotKey) || !empty($theirPivotKey) || !empty($pivotTable)) + { + $relation['ourPivotKey'] = empty($ourPivotKey) ? null : $ourPivotKey; + $relation['theirPivotKey'] = empty($theirPivotKey) ? null : $theirPivotKey; + $relation['pivotTable'] = empty($pivotTable) ? null : $pivotTable; + } + + $ret['tables'][$key]['relations'][] = $relation; + } + } + } + } + + /** + * Return a configuration variable + * + * @param string &$configuration Configuration variables (hashed array) + * @param string $var The variable we want to fetch + * @param mixed $default Default value + * + * @return mixed The variable's value + */ + public function get(&$configuration, $var, $default) + { + $parts = explode('.', $var); + + $view = $parts[0]; + $method = 'get' . ucfirst($parts[1]); + + if (!method_exists($this, $method)) + { + return $default; + } + + array_shift($parts); + array_shift($parts); + + $ret = $this->$method($view, $configuration, $parts, $default); + + return $ret; + } + + /** + * Internal method to return the magic field mapping + * + * @param string $table The table for which we will be fetching a field map + * @param array &$configuration The configuration parameters hash array + * @param array $params Extra options; key 0 defines the table we want to fetch + * @param string $default Default magic field mapping; empty if not defined + * + * @return array Field map + */ + protected function getField($table, &$configuration, $params, $default = '') + { + $fieldmap = array(); + + if (isset($configuration['tables']['*']) && isset($configuration['tables']['*']['fields'])) + { + $fieldmap = $configuration['tables']['*']['fields']; + } + + if (isset($configuration['tables'][$table]) && isset($configuration['tables'][$table]['fields'])) + { + $fieldmap = array_merge($fieldmap, $configuration['tables'][$table]['fields']); + } + + $map = $default; + + if (empty($params[0])) + { + $map = $fieldmap; + } + elseif (isset($fieldmap[$params[0]])) + { + $map = $fieldmap[$params[0]]; + } + + return $map; + } + + /** + * Internal method to get table alias + * + * @param string $table The table for which we will be fetching table alias + * @param array &$configuration The configuration parameters hash array + * @param array $params Extra options; key 0 defines the table we want to fetch + * @param string $default Default table alias + * + * @return string Table alias + */ + protected function getTablealias($table, &$configuration, $params, $default = '') + { + $tablealias = $default; + + if (isset($configuration['tables']['*']) + && isset($configuration['tables']['*']['tablealias']) + && isset($configuration['tables']['*']['tablealias'][0])) + { + $tablealias = (string) $configuration['tables']['*']['tablealias'][0]; + } + + if (isset($configuration['tables'][$table]) + && isset($configuration['tables'][$table]['tablealias']) + && isset($configuration['tables'][$table]['tablealias'][0])) + { + $tablealias = (string) $configuration['tables'][$table]['tablealias'][0]; + } + + return $tablealias; + } + + /** + * Internal method to get table behaviours + * + * @param string $table The table for which we will be fetching table alias + * @param array &$configuration The configuration parameters hash array + * @param array $params Extra options; key 0 defines the table we want to fetch + * @param string $default Default table alias + * + * @return string Table behaviours + */ + protected function getBehaviors($table, &$configuration, $params, $default = '') + { + $behaviors = $default; + + if (isset($configuration['tables']['*']) + && isset($configuration['tables']['*']['behaviors'])) + { + $behaviors = (string) $configuration['tables']['*']['behaviors']; + } + + if (isset($configuration['tables'][$table]) + && isset($configuration['tables'][$table]['behaviors'])) + { + $behaviors = (string) $configuration['tables'][$table]['behaviors']; + } + + return $behaviors; + } + + /** + * Internal method to get table relations + * + * @param string $table The table for which we will be fetching table alias + * @param array &$configuration The configuration parameters hash array + * @param array $params Extra options; key 0 defines the table we want to fetch + * @param string $default Default table alias + * + * @return array Table relations + */ + protected function getRelations($table, &$configuration, $params, $default = '') + { + $relations = $default; + + if (isset($configuration['tables']['*']) + && isset($configuration['tables']['*']['relations'])) + { + $relations = $configuration['tables']['*']['relations']; + } + + if (isset($configuration['tables'][$table]) + && isset($configuration['tables'][$table]['relations'])) + { + $relations = $configuration['tables'][$table]['relations']; + } + + return $relations; + } +} diff --git a/Sites/pages/libraries/fof/config/domain/views.php b/Sites/pages/libraries/fof/config/domain/views.php new file mode 100644 index 00000000..1c18b62e --- /dev/null +++ b/Sites/pages/libraries/fof/config/domain/views.php @@ -0,0 +1,302 @@ +xpath('view'); + + // Sanity check + + if (empty($viewData)) + { + return; + } + + foreach ($viewData as $aView) + { + $key = (string) $aView['name']; + + // Parse ACL options + $ret['views'][$key]['acl'] = array(); + $aclData = $aView->xpath('acl/task'); + + if (!empty($aclData)) + { + foreach ($aclData as $acl) + { + $k = (string) $acl['name']; + $ret['views'][$key]['acl'][$k] = (string) $acl; + } + } + + // Parse taskmap + $ret['views'][$key]['taskmap'] = array(); + $taskmapData = $aView->xpath('taskmap/task'); + + if (!empty($taskmapData)) + { + foreach ($taskmapData as $map) + { + $k = (string) $map['name']; + $ret['views'][$key]['taskmap'][$k] = (string) $map; + } + } + + // Parse controller configuration + $ret['views'][$key]['config'] = array(); + $optionData = $aView->xpath('config/option'); + + if (!empty($optionData)) + { + foreach ($optionData as $option) + { + $k = (string) $option['name']; + $ret['views'][$key]['config'][$k] = (string) $option; + } + } + + // Parse the toolbar + $ret['views'][$key]['toolbar'] = array(); + $toolBars = $aView->xpath('toolbar'); + + if (!empty($toolBars)) + { + foreach ($toolBars as $toolBar) + { + $taskName = isset($toolBar['task']) ? (string) $toolBar['task'] : '*'; + + // If a toolbar title is specified, create a title element. + if (isset($toolBar['title'])) + { + $ret['views'][$key]['toolbar'][$taskName]['title'] = array( + 'value' => (string) $toolBar['title'] + ); + } + + // Parse the toolbar buttons data + $toolbarData = $toolBar->xpath('button'); + + if (!empty($toolbarData)) + { + foreach ($toolbarData as $button) + { + $k = (string) $button['type']; + $ret['views'][$key]['toolbar'][$taskName][$k] = current($button->attributes()); + $ret['views'][$key]['toolbar'][$taskName][$k]['value'] = (string) $button; + } + } + } + } + } + } + + /** + * Return a configuration variable + * + * @param string &$configuration Configuration variables (hashed array) + * @param string $var The variable we want to fetch + * @param mixed $default Default value + * + * @return mixed The variable's value + */ + public function get(&$configuration, $var, $default) + { + $parts = explode('.', $var); + + $view = $parts[0]; + $method = 'get' . ucfirst($parts[1]); + + if (!method_exists($this, $method)) + { + return $default; + } + + array_shift($parts); + array_shift($parts); + + $ret = $this->$method($view, $configuration, $parts, $default); + + return $ret; + } + + /** + * Internal function to return the task map for a view + * + * @param string $view The view for which we will be fetching a task map + * @param array &$configuration The configuration parameters hash array + * @param array $params Extra options (not used) + * @param array $default ßDefault task map; empty array if not provided + * + * @return array The task map as a hash array in the format task => method + */ + protected function getTaskmap($view, &$configuration, $params, $default = array()) + { + $taskmap = array(); + + if (isset($configuration['views']['*']) && isset($configuration['views']['*']['taskmap'])) + { + $taskmap = $configuration['views']['*']['taskmap']; + } + + if (isset($configuration['views'][$view]) && isset($configuration['views'][$view]['taskmap'])) + { + $taskmap = array_merge($taskmap, $configuration['views'][$view]['taskmap']); + } + + if (empty($taskmap)) + { + return $default; + } + + return $taskmap; + } + + /** + * Internal method to return the ACL mapping (privilege required to access + * a specific task) for the given view's tasks + * + * @param string $view The view for which we will be fetching a task map + * @param array &$configuration The configuration parameters hash array + * @param array $params Extra options; key 0 defines the task we want to fetch + * @param string $default Default ACL option; empty (no ACL check) if not defined + * + * @return string The privilege required to access this view + */ + protected function getAcl($view, &$configuration, $params, $default = '') + { + $aclmap = array(); + + if (isset($configuration['views']['*']) && isset($configuration['views']['*']['acl'])) + { + $aclmap = $configuration['views']['*']['acl']; + } + + if (isset($configuration['views'][$view]) && isset($configuration['views'][$view]['acl'])) + { + $aclmap = array_merge($aclmap, $configuration['views'][$view]['acl']); + } + + $acl = $default; + + if (isset($aclmap['*'])) + { + $acl = $aclmap['*']; + } + + if (isset($aclmap[$params[0]])) + { + $acl = $aclmap[$params[0]]; + } + + return $acl; + } + + /** + * Internal method to return the a configuration option for the view. These + * are equivalent to $config array options passed to the Controller + * + * @param string $view The view for which we will be fetching a task map + * @param array &$configuration The configuration parameters hash array + * @param array $params Extra options; key 0 defines the option variable we want to fetch + * @param mixed $default Default option; null if not defined + * + * @return string The setting for the requested option + */ + protected function getConfig($view, &$configuration, $params, $default = null) + { + $ret = $default; + + if (isset($configuration['views']['*']) + && isset($configuration['views']['*']['config']) + && isset($configuration['views']['*']['config'][$params[0]])) + { + $ret = $configuration['views']['*']['config'][$params[0]]; + } + + if (isset($configuration['views'][$view]) + && isset($configuration['views'][$view]['config']) + && isset($configuration['views'][$view]['config'][$params[0]])) + { + $ret = $configuration['views'][$view]['config'][$params[0]]; + } + + return $ret; + } + + /** + * Internal method to return the toolbar infos. + * + * @param string $view The view for which we will be fetching buttons + * @param array &$configuration The configuration parameters hash array + * @param array $params Extra options + * @param string $default Default option + * + * @return string The toolbar data for this view + */ + protected function getToolbar($view, &$configuration, $params, $default = '') + { + $toolbar = array(); + + if (isset($configuration['views']['*']) + && isset($configuration['views']['*']['toolbar']) + && isset($configuration['views']['*']['toolbar']['*'])) + { + $toolbar = $configuration['views']['*']['toolbar']['*']; + } + + if (isset($configuration['views']['*']) + && isset($configuration['views']['*']['toolbar']) + && isset($configuration['views']['*']['toolbar'][$params[0]])) + { + $toolbar = array_merge($toolbar, $configuration['views']['*']['toolbar'][$params[0]]); + } + + if (isset($configuration['views'][$view]) + && isset($configuration['views'][$view]['toolbar']) + && isset($configuration['views'][$view]['toolbar']['*'])) + { + $toolbar = array_merge($toolbar, $configuration['views'][$view]['toolbar']['*']); + } + + if (isset($configuration['views'][$view]) + && isset($configuration['views'][$view]['toolbar']) + && isset($configuration['views'][$view]['toolbar'][$params[0]])) + { + $toolbar = array_merge($toolbar, $configuration['views'][$view]['toolbar'][$params[0]]); + } + + if (empty($toolbar)) + { + return $default; + } + + return $toolbar; + } +} diff --git a/Sites/pages/libraries/fof/config/provider.php b/Sites/pages/libraries/fof/config/provider.php new file mode 100644 index 00000000..c0609f5f --- /dev/null +++ b/Sites/pages/libraries/fof/config/provider.php @@ -0,0 +1,213 @@ +isCli()) + { + $order = array('cli', 'backend'); + } + elseif (FOFPlatform::getInstance()->isBackend()) + { + $order = array('backend'); + } + else + { + $order = array('frontend'); + } + + $order[] = 'common'; + + $order = array_reverse($order); + self::$configurations[$component] = array(); + + foreach ($order as $area) + { + $config = $this->parseComponentArea($component, $area); + self::$configurations[$component] = array_merge_recursive(self::$configurations[$component], $config); + } + } + + /** + * Returns the value of a variable. Variables use a dot notation, e.g. + * view.config.whatever where the first part is the domain, the rest of the + * parts specify the path to the variable. + * + * @param string $variable The variable name + * @param mixed $default The default value, or null if not specified + * + * @return mixed The value of the variable + */ + public function get($variable, $default = null) + { + static $domains = null; + + if (is_null($domains)) + { + $domains = $this->getDomains(); + } + + list($component, $domain, $var) = explode('.', $variable, 3); + + if (!isset(self::$configurations[$component])) + { + $this->parseComponent($component); + } + + if (!in_array($domain, $domains)) + { + return $default; + } + + $class = 'FOFConfigDomain' . ucfirst($domain); + $o = new $class; + + return $o->get(self::$configurations[$component], $var, $default); + } + + /** + * Parses the configuration options of a specific component area + * + * @param string $component Which component's configuration to parse + * @param string $area Which area to parse (frontend, backend, cli) + * + * @return array A hash array with the configuration data + */ + protected function parseComponentArea($component, $area) + { + // Initialise the return array + $ret = array(); + + // Get the folders of the component + $componentPaths = FOFPlatform::getInstance()->getComponentBaseDirs($component); + $filesystem = FOFPlatform::getInstance()->getIntegrationObject('filesystem'); + + // Check that the path exists + $path = $componentPaths['admin']; + $path = $filesystem->pathCheck($path); + + if (!$filesystem->folderExists($path)) + { + return $ret; + } + + // Read the filename if it exists + $filename = $path . '/fof.xml'; + + if (!$filesystem->fileExists($filename)) + { + return $ret; + } + + $data = file_get_contents($filename); + + // Load the XML data in a SimpleXMLElement object + $xml = simplexml_load_string($data); + + if (!($xml instanceof SimpleXMLElement)) + { + return $ret; + } + + // Get this area's data + $areaData = $xml->xpath('//' . $area); + + if (empty($areaData)) + { + return $ret; + } + + $xml = array_shift($areaData); + + // Parse individual configuration domains + $domains = $this->getDomains(); + + foreach ($domains as $dom) + { + $class = 'FOFConfigDomain' . ucfirst($dom); + + if (class_exists($class, true)) + { + $o = new $class; + $o->parseDomain($xml, $ret); + } + } + + // Finally, return the result + return $ret; + } + + /** + * Gets a list of the available configuration domain adapters + * + * @return array A list of the available domains + */ + protected function getDomains() + { + static $domains = array(); + + if (empty($domains)) + { + $filesystem = FOFPlatform::getInstance()->getIntegrationObject('filesystem'); + + $files = $filesystem->folderFiles(__DIR__ . '/domain', '.php'); + + if (!empty($files)) + { + foreach ($files as $file) + { + $domain = basename($file, '.php'); + + if ($domain == 'interface') + { + continue; + } + + $domain = preg_replace('/[^A-Za-z0-9]/', '', $domain); + $domains[] = $domain; + } + + $domains = array_unique($domains); + } + } + + return $domains; + } +} diff --git a/Sites/pages/libraries/fof/controller/controller.php b/Sites/pages/libraries/fof/controller/controller.php new file mode 100644 index 00000000..76b34169 --- /dev/null +++ b/Sites/pages/libraries/fof/controller/controller.php @@ -0,0 +1,3414 @@ +getCmd('option', 'com_foobar'); + $config['view'] = !is_null($view) ? $view : $input->getCmd('view', 'cpanel'); + + // Get the class base name, e.g. FoobarController + $classBaseName = ucfirst(str_replace('com_', '', $config['option'])) . 'Controller'; + + // Get the class name suffixes, in the order to be searched for: plural, singular, 'default' + $classSuffixes = array( + FOFInflector::pluralize($config['view']), + FOFInflector::singularize($config['view']), + 'default' + ); + + // Get the path names for the component + $componentPaths = FOFPlatform::getInstance()->getComponentBaseDirs($config['option']); + $filesystem = FOFPlatform::getInstance()->getIntegrationObject('filesystem'); + + // Look for the best classname match + foreach ($classSuffixes as $suffix) + { + $className = $classBaseName . ucfirst($suffix); + + if (class_exists($className)) + { + // The class is already loaded. We have a match! + break; + } + + // The class is not already loaded. Try to find and load it. + $searchPaths = array( + $componentPaths['main'] . '/controllers', + $componentPaths['admin'] . '/controllers' + ); + + // If we have a searchpath in the configuration please search it first + + if (array_key_exists('searchpath', $config)) + { + array_unshift($searchPaths, $config['searchpath']); + } + else + { + $configProvider = new FOFConfigProvider; + $searchPath = $configProvider->get($config['option'] . '.views.' . FOFInflector::singularize($config['view']) . '.config.searchpath', null); + + if ($searchPath) + { + array_unshift($searchPaths, $componentPaths['admin'] . '/' . $searchPath); + array_unshift($searchPaths, $componentPaths['main'] . '/' . $searchPath); + } + } + + /** + * Try to find the path to this file. First try to find the + * format-specific controller file, e.g. foobar.json.php for + * format=json, then the regular one-size-fits-all controller + */ + + $format = $input->getCmd('format', 'html'); + $path = null; + + if (!empty($format)) + { + $path = $filesystem->pathFind( + $searchPaths, strtolower($suffix) . '.' . strtolower($format) . '.php' + ); + } + + if (!$path) + { + $path = $filesystem->pathFind( + $searchPaths, strtolower($suffix) . '.php' + ); + } + + // The path is found. Load the file and make sure the expected class name exists. + + if ($path) + { + require_once $path; + + if (class_exists($className)) + { + // The class was loaded successfully. We have a match! + break; + } + } + } + + if (!class_exists($className)) + { + // If no specialised class is found, instantiate the generic FOFController + $className = 'FOFController'; + } + + $instance = new $className($config); + + return $instance; + } + + /** + * Public constructor of the Controller class + * + * @param array $config Optional configuration parameters + */ + public function __construct($config = array()) + { + // Make sure $config is an array + if (is_object($config)) + { + $config = (array) $config; + } + elseif (!is_array($config)) + { + $config = array(); + } + + $this->methods = array(); + $this->message = null; + $this->messageType = 'message'; + $this->paths = array(); + $this->redirect = null; + $this->taskMap = array(); + + // Cache the config + $this->config = $config; + + // Get the input for this MVC triad + + if (array_key_exists('input', $config)) + { + $input = $config['input']; + } + else + { + $input = null; + } + + if (array_key_exists('input_options', $config)) + { + $input_options = $config['input_options']; + } + else + { + $input_options = array(); + } + + if ($input instanceof FOFInput) + { + $this->input = $input; + } + else + { + $this->input = new FOFInput($input, $input_options); + } + + // Load the configuration provider + $this->configProvider = new FOFConfigProvider; + + // Determine the methods to exclude from the base class. + $xMethods = get_class_methods('FOFController'); + + // Some methods must always be considered valid tasks + $iMethods = array('accesspublic', 'accessregistered', 'accessspecial', + 'add', 'apply', 'browse', 'cancel', 'copy', 'edit', 'orderdown', + 'orderup', 'publish', 'read', 'remove', 'save', 'savenew', + 'saveorder', 'unpublish', 'display', 'archive', 'trash', 'loadhistory'); + + // Get the public methods in this class using reflection. + $r = new ReflectionClass($this); + $rMethods = $r->getMethods(ReflectionMethod::IS_PUBLIC); + + foreach ($rMethods as $rMethod) + { + $mName = $rMethod->getName(); + + // If the developer screwed up and declared one of the helper method public do NOT make them available as + // tasks. + if ((substr($mName, 0, 8) == 'onBefore') || (substr($mName, 0, 7) == 'onAfter') || substr($mName, 0, 1) == '_') + { + continue; + } + + // Add default display method if not explicitly declared. + if (!in_array($mName, $xMethods) || in_array($mName, $iMethods)) + { + $this->methods[] = strtolower($mName); + + // Auto register the methods as tasks. + $this->taskMap[strtolower($mName)] = $mName; + } + } + + // Get the default values for the component and view names + $classNameParts = FOFInflector::explode(get_class($this)); + + if (count($classNameParts) == 3) + { + $defComponent = "com_" . $classNameParts[0]; + $defView = $classNameParts[2]; + } + else + { + $defComponent = 'com_foobar'; + $defView = 'cpanel'; + } + + $this->component = $this->input->get('option', $defComponent, 'cmd'); + $this->view = $this->input->get('view', $defView, 'cmd'); + $this->layout = $this->input->get('layout', null, 'cmd'); + + // Overrides from the config + if (array_key_exists('option', $config)) + { + $this->component = $config['option']; + } + + if (array_key_exists('view', $config)) + { + $this->view = $config['view']; + } + + if (array_key_exists('layout', $config)) + { + $this->layout = $config['layout']; + } + + $this->layout = $this->configProvider->get($this->component . '.views.' . FOFInflector::singularize($this->view) . '.config.layout', $this->layout); + + $this->input->set('option', $this->component); + + // Set the bareComponent variable + $this->bareComponent = str_replace('com_', '', strtolower($this->component)); + + // Set the $name variable + $this->name = $this->bareComponent; + + // Set the basePath variable + $componentPaths = FOFPlatform::getInstance()->getComponentBaseDirs($this->component); + $basePath = $componentPaths['main']; + + if (array_key_exists('base_path', $config)) + { + $basePath = $config['base_path']; + } + + $altBasePath = $this->configProvider->get( + $this->component . '.views.' . + FOFInflector::singularize($this->view) . '.config.base_path', null + ); + + if (!is_null($altBasePath)) + { + $platformDirs = FOFPlatform::getInstance()->getPlatformBaseDirs(); + $basePath = $platformDirs['public'] . '/' . $altBasePath; + } + + $this->basePath = $basePath; + + // If the default task is set, register it as such + $defaultTask = $this->configProvider->get( + $this->component . '.views.' . + FOFInflector::singularize($this->view) . '.config.default_task', 'display' + ); + + if (array_key_exists('default_task', $config)) + { + $this->registerDefaultTask($config['default_task']); + } + else + { + $this->registerDefaultTask($defaultTask); + } + + // Set the models prefix + + if (empty($this->model_prefix)) + { + if (array_key_exists('model_prefix', $config)) + { + // User-defined prefix + $this->model_prefix = $config['model_prefix']; + } + else + { + $this->model_prefix = $this->name . 'Model'; + $this->model_prefix = $this->configProvider->get( + $this->component . '.views.' . + FOFInflector::singularize($this->view) . '.config.model_prefix', $this->model_prefix + ); + } + } + + // Set the default model search path + + if (array_key_exists('model_path', $config)) + { + // User-defined dirs + $this->addModelPath($config['model_path'], $this->model_prefix); + } + else + { + $modelPath = $this->basePath . '/models'; + $altModelPath = $this->configProvider->get( + $this->component . '.views.' . + FOFInflector::singularize($this->view) . '.config.model_path', null + ); + + if (!is_null($altModelPath)) + { + $modelPath = $this->basePath . '/' . $altModelPath; + } + + $this->addModelPath($modelPath, $this->model_prefix); + } + + // Set the default view search path + if (array_key_exists('view_path', $config)) + { + // User-defined dirs + $this->setPath('view', $config['view_path']); + } + else + { + $viewPath = $this->basePath . '/views'; + $altViewPath = $this->configProvider->get( + $this->component . '.views.' . + FOFInflector::singularize($this->view) . '.config.view_path', null + ); + + if (!is_null($altViewPath)) + { + $viewPath = $this->basePath . '/' . $altViewPath; + } + + $this->setPath('view', $viewPath); + } + + // Set the default view. + + if (array_key_exists('default_view', $config)) + { + $this->default_view = $config['default_view']; + } + else + { + if (empty($this->default_view)) + { + $this->default_view = $this->getName(); + } + + $this->default_view = $this->configProvider->get( + $this->component . '.views.' . + FOFInflector::singularize($this->view) . '.config.default_view', $this->default_view + ); + } + + // Set the CSRF protection + if (array_key_exists('csrf_protection', $config)) + { + $this->csrfProtection = $config['csrf_protection']; + } + + $this->csrfProtection = $this->configProvider->get( + $this->component . '.views.' . + FOFInflector::singularize($this->view) . '.config.csrf_protection', $this->csrfProtection + ); + + // Set any model/view name overrides + if (array_key_exists('viewName', $config)) + { + $this->setThisViewName($config['viewName']); + } + else + { + $overrideViewName = $this->configProvider->get( + $this->component . '.views.' . + FOFInflector::singularize($this->view) . '.config.viewName', null + ); + + if ($overrideViewName) + { + $this->setThisViewName($overrideViewName); + } + } + + if (array_key_exists('modelName', $config)) + { + $this->setThisModelName($config['modelName']); + } + else + { + $overrideModelName = $this->configProvider->get( + $this->component . '.views.' . + FOFInflector::singularize($this->view) . '.config.modelName', null + ); + + if ($overrideModelName) + { + $this->setThisModelName($overrideModelName); + } + } + + // Caching + if (array_key_exists('cacheableTasks', $config)) + { + if (is_array($config['cacheableTasks'])) + { + $this->cacheableTasks = $config['cacheableTasks']; + } + } + else + { + $cacheableTasks = $this->configProvider->get( + $this->component . '.views.' . + FOFInflector::singularize($this->view) . '.config.cacheableTasks', null + ); + + if ($cacheableTasks) + { + $cacheableTasks = explode(',', $cacheableTasks); + + if (count($cacheableTasks)) + { + $temp = array(); + + foreach ($cacheableTasks as $t) + { + $temp[] = trim($t); + } + + $temp = array_unique($temp); + $this->cacheableTasks = $temp; + } + } + } + + // Bit mask for auto routing on setRedirect + $this->autoRouting = $this->configProvider->get( + $this->component . '.views.' . + FOFInflector::singularize($this->view) . '.config.autoRouting', $this->autoRouting + ); + + if (array_key_exists('autoRouting', $config)) + { + $this->autoRouting = $config['autoRouting']; + } + + // Apply task map + $taskmap = $this->configProvider->get( + $this->component . '.views.' . + FOFInflector::singularize($this->view) . '.taskmap' + ); + + if (is_array($taskmap) && !empty($taskmap)) + { + foreach ($taskmap as $aliasedtask => $realmethod) + { + $this->registerTask($aliasedtask, $realmethod); + } + } + } + + /** + * Adds to the stack of model paths in LIFO order. + * + * @param mixed $path The directory (string) , or list of directories (array) to add. + * @param string $prefix A prefix for models + * + * @return void + */ + public static function addModelPath($path, $prefix = '') + { + FOFModel::addIncludePath($path, $prefix); + } + + /** + * Adds to the search path for templates and resources. + * + * @param string $type The path type (e.g. 'model', 'view'). + * @param mixed $path The directory string or stream array to search. + * + * @return FOFController A FOFController object to support chaining. + */ + protected function addPath($type, $path) + { + // Just force path to array + settype($path, 'array'); + + $filesystem = FOFPlatform::getInstance()->getIntegrationObject('filesystem'); + + if (!isset($this->paths[$type])) + { + $this->paths[$type] = array(); + } + + // Loop through the path directories + foreach ($path as $dir) + { + // No surrounding spaces allowed! + $dir = rtrim($filesystem->pathCheck($dir, '/'), '/') . '/'; + + // Add to the top of the search dirs + array_unshift($this->paths[$type], $dir); + } + + return $this; + } + + /** + * Add one or more view paths to the controller's stack, in LIFO order. + * + * @param mixed $path The directory (string) or list of directories (array) to add. + * + * @return FOFController This object to support chaining. + */ + public function addViewPath($path) + { + $this->addPath('view', $path); + + return $this; + } + + /** + * Authorisation check + * + * @param string $task The ACO Section Value to check access on. + * + * @return boolean True if authorised + * + * @deprecated 2.0 Use JAccess instead. + */ + public function authorise($task) + { + FOFPlatform::getInstance()->logDeprecated(__CLASS__ . '::' .__METHOD__ . ' is deprecated. Use checkACL() instead.'); + + return true; + } + + /** + * 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. Optional. + * + * @return string The filename. + */ + protected static function createFileName($type, $parts = array()) + { + $filename = ''; + + switch ($type) + { + case 'controller': + if (!empty($parts['format'])) + { + if ($parts['format'] == 'html') + { + $parts['format'] = ''; + } + else + { + $parts['format'] = '.' . $parts['format']; + } + } + else + { + $parts['format'] = ''; + } + + $filename = strtolower($parts['name'] . $parts['format'] . '.php'); + break; + + case 'view': + if (!empty($parts['type'])) + { + $parts['type'] = '.' . $parts['type']; + } + else + { + $parts['type'] = ''; + } + + $filename = strtolower($parts['name'] . '/view' . $parts['type'] . '.php'); + break; + } + + return $filename; + } + + /** + * Executes a given controller task. The onBefore and onAfter + * methods are called automatically if they exist. + * + * @param string $task The task to execute, e.g. "browse" + * + * @throws Exception Exception thrown if the onBefore returns false + * + * @return null|bool False on execution failure + */ + public function execute($task) + { + $this->task = $task; + + $method_name = 'onBefore' . ucfirst($task); + + if (!method_exists($this, $method_name)) + { + $result = $this->onBeforeGenericTask($task); + } + elseif (method_exists($this, $method_name)) + { + $result = $this->$method_name(); + } + else + { + $result = true; + } + + if ($result) + { + $plugin_event = FOFInflector::camelize('on before ' . $this->bareComponent . ' controller ' . $this->view . ' ' . $task); + $plugin_result = FOFPlatform::getInstance()->runPlugins($plugin_event, array(&$this, &$this->input)); + + if (in_array(false, $plugin_result, true)) + { + $result = false; + } + } + + if (!$result) + { + throw new Exception(JText::_('JLIB_APPLICATION_ERROR_ACCESS_FORBIDDEN'), 403); + } + + // Do not allow the display task to be directly called + $task = strtolower($task); + + if (isset($this->taskMap[$task])) + { + $doTask = $this->taskMap[$task]; + } + elseif (isset($this->taskMap['__default'])) + { + $doTask = $this->taskMap['__default']; + } + else + { + $doTask = null; + } + + if ($doTask == 'display') + { + FOFPlatform::getInstance()->setHeader('Status', '400 Bad Request', true); + + throw new Exception('Bad Request', 400); + } + + $this->doTask = $doTask; + + $ret = $this->$doTask(); + + $method_name = 'onAfter' . ucfirst($task); + + if (method_exists($this, $method_name)) + { + $result = $this->$method_name(); + } + else + { + $result = true; + } + + if ($result) + { + $plugin_event = FOFInflector::camelize('on after ' . $this->bareComponent . ' controller ' . $this->view . ' ' . $task); + $plugin_result = FOFPlatform::getInstance()->runPlugins($plugin_event, array(&$this, &$this->input, &$ret)); + + if (in_array(false, $plugin_result, true)) + { + $result = false; + } + } + + if (!$result) + { + throw new Exception(JText::_('JLIB_APPLICATION_ERROR_ACCESS_FORBIDDEN'), 403); + } + + return $ret; + } + + /** + * Default task. Assigns a model to the view and asks the view to render + * itself. + * + * YOU MUST NOT USETHIS TASK DIRECTLY IN A URL. It is supposed to be + * used ONLY inside your code. In the URL, use task=browse instead. + * + * @param bool $cachable Is this view cacheable? + * @param bool $urlparams Add your safe URL parameters (see further down in the code) + * @param string $tpl The name of the template file to parse + * + * @return bool + */ + public function display($cachable = false, $urlparams = false, $tpl = null) + { + $document = FOFPlatform::getInstance()->getDocument(); + + if ($document instanceof JDocument) + { + $viewType = $document->getType(); + } + else + { + $viewType = $this->input->getCmd('format', 'html'); + } + + $view = $this->getThisView(); + + // Get/Create the model + + if ($model = $this->getThisModel()) + { + // Push the model into the view (as default) + $view->setModel($model, true); + } + + // Set the layout + $view->setLayout(is_null($this->layout) ? 'default' : $this->layout); + + // Display the view + $conf = FOFPlatform::getInstance()->getConfig(); + + if (FOFPlatform::getInstance()->isFrontend() && $cachable && ($viewType != 'feed') && $conf->get('caching') >= 1) + { + // Get a JCache object + $option = $this->input->get('option', 'com_foobar', 'cmd'); + $cache = JFactory::getCache($option, 'view'); + + // Set up a cache ID based on component, view, task and user group assignment + $user = FOFPlatform::getInstance()->getUser(); + + if ($user->guest) + { + $groups = array(); + } + else + { + $groups = $user->groups; + } + + $importantParameters = array(); + + // Set up safe URL parameters + if (!is_array($urlparams)) + { + $urlparams = array( + 'option' => 'CMD', + 'view' => 'CMD', + 'task' => 'CMD', + 'format' => 'CMD', + 'layout' => 'CMD', + 'id' => 'INT', + ); + } + + if (is_array($urlparams)) + { + $app = JFactory::getApplication(); + + $registeredurlparams = null; + + if (version_compare(JVERSION, '3.0', 'ge')) + { + if (property_exists($app, 'registeredurlparams')) + { + $registeredurlparams = $app->registeredurlparams; + } + } + else + { + $registeredurlparams = $app->get('registeredurlparams'); + } + + if (empty($registeredurlparams)) + { + $registeredurlparams = new stdClass; + } + + foreach ($urlparams AS $key => $value) + { + // Add your safe url parameters with variable type as value {@see JFilterInput::clean()}. + $registeredurlparams->$key = $value; + + // Add the URL-important parameters into the array + $importantParameters[$key] = $this->input->get($key, null, $value); + } + + if (version_compare(JVERSION, '3.0', 'ge')) + { + $app->registeredurlparams = $registeredurlparams; + } + else + { + $app->set('registeredurlparams', $registeredurlparams); + } + } + + // Create the cache ID after setting the registered URL params, as they are used to generate the ID + $cacheId = md5(serialize(array(JCache::makeId(), $view->getName(), $this->doTask, $groups, $importantParameters))); + + // Get the cached view or cache the current view + $cache->get($view, 'display', $cacheId); + } + else + { + // Display without caching + $view->display($tpl); + } + + return true; + } + + /** + * Implements a default browse task, i.e. read a bunch of records and send + * them to the browser. + * + * @return boolean + */ + public function browse() + { + if ($this->input->get('savestate', -999, 'int') == -999) + { + $this->input->set('savestate', true); + } + + // Do I have a form? + $model = $this->getThisModel(); + + if (empty($this->layout)) + { + $formname = 'form.default'; + } + else + { + $formname = 'form.' . $this->layout; + } + + $model->setState('form_name', $formname); + + $form = $model->getForm(); + + if ($form !== false) + { + $this->hasForm = true; + } + + $this->display(in_array('browse', $this->cacheableTasks)); + + return true; + } + + /** + * Single record read. The id set in the request is passed to the model and + * then the item layout is used to render the result. + * + * @return bool + */ + public function read() + { + // Load the model + $model = $this->getThisModel(); + + if (!$model->getId()) + { + $model->setIDsFromRequest(); + } + + // Set the layout to item, if it's not set in the URL + if (is_null($this->layout)) + { + $this->layout = 'item'; + } + + // Do I have a form? + $model->setState('form_name', 'form.' . $this->layout); + + $item = $model->getItem(); + + if (!($item instanceof FOFTable)) + { + return false; + } + + $itemKey = $item->getKeyName(); + + if ($item->$itemKey != $model->getId()) + { + return false; + } + + $formData = is_object($item) ? $item->getData() : array(); + $form = $model->getForm($formData); + + if ($form !== false) + { + $this->hasForm = true; + } + + // Display + $this->display(in_array('read', $this->cacheableTasks)); + + return true; + } + + /** + * Single record add. The form layout is used to present a blank page. + * + * @return false|void + */ + public function add() + { + // Load and reset the model + $model = $this->getThisModel(); + $model->reset(); + + // Set the layout to form, if it's not set in the URL + + if (!$this->layout) + { + $this->layout = 'form'; + } + + // Do I have a form? + $model->setState('form_name', 'form.' . $this->layout); + + $item = $model->getItem(); + + if (!($item instanceof FOFTable)) + { + return false; + } + + $formData = is_object($item) ? $item->getData() : array(); + $form = $model->getForm($formData); + + if ($form !== false) + { + $this->hasForm = true; + } + + // Display + $this->display(in_array('add', $this->cacheableTasks)); + } + + /** + * Single record edit. The ID set in the request is passed to the model, + * then the form layout is used to edit the result. + * + * @return bool + */ + public function edit() + { + // Load the model + $model = $this->getThisModel(); + + if (!$model->getId()) + { + $model->setIDsFromRequest(); + } + + $status = $model->checkout(); + + if (!$status) + { + // Redirect on error + + if ($customURL = $this->input->get('returnurl', '', 'string')) + { + $customURL = base64_decode($customURL); + } + + $url = !empty($customURL) ? $customURL : 'index.php?option=' . $this->component . '&view=' . FOFInflector::pluralize($this->view) . $this->getItemidURLSuffix(); + $this->setRedirect($url, $model->getError(), 'error'); + + return false; + } + + // Set the layout to form, if it's not set in the URL + + if (is_null($this->layout)) + { + $this->layout = 'form'; + } + + // Do I have a form? + $model->setState('form_name', 'form.' . $this->layout); + + $item = $model->getItem(); + + if (!($item instanceof FOFTable)) + { + return false; + } + + $itemKey = $item->getKeyName(); + + if ($item->$itemKey != $model->getId()) + { + return false; + } + + $formData = is_object($item) ? $item->getData() : array(); + $form = $model->getForm($formData); + + if ($form !== false) + { + $this->hasForm = true; + } + + // Display + $this->display(in_array('edit', $this->cacheableTasks)); + + return true; + } + + /** + * Save the incoming data and then return to the Edit task + * + * @return bool + */ + public function apply() + { + // CSRF prevention + if ($this->csrfProtection) + { + $this->_csrfProtection(); + } + + $model = $this->getThisModel(); + $result = $this->applySave(); + + // Redirect to the edit task + if ($result) + { + $id = $this->input->get('id', 0, 'int'); + $textkey = strtoupper($this->component) . '_LBL_' . strtoupper($this->view) . '_SAVED'; + + if ($customURL = $this->input->get('returnurl', '', 'string')) + { + $customURL = base64_decode($customURL); + } + + $url = !empty($customURL) ? $customURL : 'index.php?option=' . $this->component . '&view=' . $this->view . '&task=edit&id=' . $id . $this->getItemidURLSuffix(); + $this->setRedirect($url, JText::_($textkey)); + } + + return $result; + } + + /** + * Duplicates selected items + * + * @return bool + */ + public function copy() + { + // CSRF prevention + if ($this->csrfProtection) + { + $this->_csrfProtection(); + } + + $model = $this->getThisModel(); + + if (!$model->getId()) + { + $model->setIDsFromRequest(); + } + + $status = $model->copy(); + + // Redirect + if ($customURL = $this->input->get('returnurl', '', 'string')) + { + $customURL = base64_decode($customURL); + } + + $url = !empty($customURL) ? $customURL : 'index.php?option=' . $this->component . '&view=' . FOFInflector::pluralize($this->view) . $this->getItemidURLSuffix(); + + if (!$status) + { + $this->setRedirect($url, $model->getError(), 'error'); + + return false; + } + else + { + if(!FOFPlatform::getInstance()->isCli()) + { + FOFPlatform::getInstance()->setHeader('Status', '201 Created', true); + } + + $this->setRedirect($url); + + return true; + } + } + + /** + * Save the incoming data and then return to the Browse task + * + * @return bool + */ + public function save() + { + // CSRF prevention + if ($this->csrfProtection) + { + $this->_csrfProtection(); + } + + $result = $this->applySave(); + + // Redirect to the display task + if ($result) + { + $textkey = strtoupper($this->component) . '_LBL_' . strtoupper($this->view) . '_SAVED'; + + if ($customURL = $this->input->get('returnurl', '', 'string')) + { + $customURL = base64_decode($customURL); + } + + $url = !empty($customURL) ? $customURL : 'index.php?option=' . $this->component . '&view=' . FOFInflector::pluralize($this->view) . $this->getItemidURLSuffix(); + $this->setRedirect($url, JText::_($textkey)); + } + + return $result; + } + + /** + * Save the incoming data and then return to the Add task + * + * @return bool + */ + public function savenew() + { + // CSRF prevention + if ($this->csrfProtection) + { + $this->_csrfProtection(); + } + + $result = $this->applySave(); + + // Redirect to the display task + + if ($result) + { + $textkey = strtoupper($this->component) . '_LBL_' . strtoupper($this->view) . '_SAVED'; + + if ($customURL = $this->input->get('returnurl', '', 'string')) + { + $customURL = base64_decode($customURL); + } + + $url = !empty($customURL) ? $customURL : 'index.php?option=' . $this->component . '&view=' . $this->view . '&task=add' . $this->getItemidURLSuffix(); + $this->setRedirect($url, JText::_($textkey)); + } + + return $result; + } + + /** + * Cancel the edit, check in the record and return to the Browse task + * + * @return bool + */ + public function cancel() + { + $model = $this->getThisModel(); + + if (!$model->getId()) + { + $model->setIDsFromRequest(); + } + + $model->checkin(); + + // Remove any saved data + JFactory::getSession()->set($model->getHash() . 'savedata', null); + + // Redirect to the display task + + if ($customURL = $this->input->get('returnurl', '', 'string')) + { + $customURL = base64_decode($customURL); + } + + $url = !empty($customURL) ? $customURL : 'index.php?option=' . $this->component . '&view=' . FOFInflector::pluralize($this->view) . $this->getItemidURLSuffix(); + $this->setRedirect($url); + + return true; + } + + /** + * Method to load a row from version history + * + * @return boolean True if the content history is reverted, false otherwise + * + * @since 2.2 + */ + public function loadhistory() + { + $app = JFactory::getApplication(); + $lang = JFactory::getLanguage(); + $model = $this->getThisModel(); + $table = $model->getTable(); + $historyId = $app->input->get('version_id', null, 'integer'); + $status = $model->checkout(); + $alias = $this->component . '.' . $this->view; + + if (!$model->loadhistory($historyId, $table, $alias)) + { + $this->setMessage($model->getError(), 'error'); + + $url = !empty($customURL) ? $customURL : 'index.php?option=' . $this->component . '&view=' . FOFInflector::pluralize($this->view) . $this->getItemidURLSuffix(); + $this->setRedirect($url); + + return false; + } + + // Determine the name of the primary key for the data. + if (empty($key)) + { + $key = $table->getKeyName(); + } + + $recordId = $table->$key; + + // To avoid data collisions the urlVar may be different from the primary key. + $urlVar = empty($this->urlVar) ? $key : $this->urlVar; + + // Access check. + $privilege = $this->configProvider->get( + $this->component . '.views.' . + FOFInflector::singularize($this->view) . '.acl.edit', 'core.edit' + ); + + if (!$this->checkACL($privilege)) + { + $this->setError(JText::_('JLIB_APPLICATION_ERROR_EDIT_NOT_PERMITTED')); + $this->setMessage($this->getError(), 'error'); + + $url = !empty($customURL) ? $customURL : 'index.php?option=' . $this->component . '&view=' . FOFInflector::pluralize($this->view) . $this->getItemidURLSuffix(); + $this->setRedirect($url); + $table->checkin(); + + return false; + } + + $table->store(); + $url = !empty($customURL) ? $customURL : 'index.php?option=' . $this->component . '&view=' . FOFInflector::pluralize($this->view) . $this->getItemidURLSuffix(); + $this->setRedirect($url); + + $this->setMessage(JText::sprintf('JLIB_APPLICATION_SUCCESS_LOAD_HISTORY', $model->getState('save_date'), $model->getState('version_note'))); + + return true; + } + + /** + * Sets the access to public. Joomla! 1.5 compatibility. + * + * @return bool + * + * @deprecated since 2.0 + */ + public function accesspublic() + { + // CSRF prevention + + if ($this->csrfProtection) + { + $this->_csrfProtection(); + } + + return $this->setaccess(0); + } + + /** + * Sets the access to registered. Joomla! 1.5 compatibility. + * + * @return bool + * + * @deprecated since 2.0 + */ + public function accessregistered() + { + // CSRF prevention + + if ($this->csrfProtection) + { + $this->_csrfProtection(); + } + + return $this->setaccess(1); + } + + /** + * Sets the access to special. Joomla! 1.5 compatibility. + * + * @return bool + * + * @deprecated since 2.0 + */ + public function accessspecial() + { + // CSRF prevention + + if ($this->csrfProtection) + { + $this->_csrfProtection(); + } + + return $this->setaccess(2); + } + + /** + * Publish (set enabled = 1) an item. + * + * @return bool + */ + public function publish() + { + // CSRF prevention + if ($this->csrfProtection) + { + $this->_csrfProtection(); + } + + return $this->setstate(1); + } + + /** + * Unpublish (set enabled = 0) an item. + * + * @return bool + */ + public function unpublish() + { + // CSRF prevention + if ($this->csrfProtection) + { + $this->_csrfProtection(); + } + + return $this->setstate(0); + } + + /** + * Archive (set enabled = 2) an item. + * + * @return bool + */ + public function archive() + { + // CSRF prevention + if ($this->csrfProtection) + { + $this->_csrfProtection(); + } + + return $this->setstate(2); + } + + /** + * Trash (set enabled = -2) an item. + * + * @return bool + */ + public function trash() + { + // CSRF prevention + if ($this->csrfProtection) + { + $this->_csrfProtection(); + } + + return $this->setstate(-2); + } + + /** + * Saves the order of the items + * + * @return bool + */ + public function saveorder() + { + // CSRF prevention + if ($this->csrfProtection) + { + $this->_csrfProtection(); + } + + $model = $this->getThisModel(); + + if (!$model->getId()) + { + $model->setIDsFromRequest(); + } + + $ordering = $model->getTable()->getColumnAlias('ordering'); + $ids = $model->getIds(); + $orders = $this->input->get('order', array(), 'array'); + + if ($n = count($ids)) + { + for ($i = 0; $i < $n; $i++) + { + $model->setId($ids[$i]); + $neworder = (int) $orders[$i]; + + $item = $model->getItem(); + + if (!($item instanceof FOFTable)) + { + return false; + } + + $key = $item->getKeyName(); + + if ($item->$key == $ids[$i]) + { + $item->$ordering = $neworder; + $model->save($item); + } + } + } + + $status = $model->reorder(); + + // Redirect + if ($customURL = $this->input->get('returnurl', '', 'string')) + { + $customURL = base64_decode($customURL); + } + + $url = !empty($customURL) ? $customURL : 'index.php?option=' . $this->component . '&view=' . FOFInflector::pluralize($this->view) . $this->getItemidURLSuffix(); + $this->setRedirect($url); + + return $status; + } + + /** + * Moves selected items one position down the ordering list + * + * @return bool + */ + public function orderdown() + { + // CSRF prevention + if ($this->csrfProtection) + { + $this->_csrfProtection(); + } + + $model = $this->getThisModel(); + + if (!$model->getId()) + { + $model->setIDsFromRequest(); + } + + $status = $model->move(1); + + // Redirect + if ($customURL = $this->input->get('returnurl', '', 'string')) + { + $customURL = base64_decode($customURL); + } + + $url = !empty($customURL) ? $customURL : 'index.php?option=' . $this->component . '&view=' . FOFInflector::pluralize($this->view) . $this->getItemidURLSuffix(); + + if (!$status) + { + $this->setRedirect($url, $model->getError(), 'error'); + } + else + { + $this->setRedirect($url); + } + + return $status; + } + + /** + * Moves selected items one position up the ordering list + * + * @return bool + */ + public function orderup() + { + // CSRF prevention + if ($this->csrfProtection) + { + $this->_csrfProtection(); + } + + $model = $this->getThisModel(); + + if (!$model->getId()) + { + $model->setIDsFromRequest(); + } + + $status = $model->move(-1); + + // Redirect + if ($customURL = $this->input->get('returnurl', '', 'string')) + { + $customURL = base64_decode($customURL); + } + + $url = !empty($customURL) ? $customURL : 'index.php?option=' . $this->component . '&view=' . FOFInflector::pluralize($this->view) . $this->getItemidURLSuffix(); + + if (!$status) + { + $this->setRedirect($url, $model->getError(), 'error'); + } + else + { + $this->setRedirect($url); + } + + return $status; + } + + /** + * Delete selected item(s) + * + * @return bool + */ + public function remove() + { + // CSRF prevention + if ($this->csrfProtection) + { + $this->_csrfProtection(); + } + + $model = $this->getThisModel(); + + if (!$model->getId()) + { + $model->setIDsFromRequest(); + } + + $status = $model->delete(); + + // Redirect + if ($customURL = $this->input->get('returnurl', '', 'string')) + { + $customURL = base64_decode($customURL); + } + + $url = !empty($customURL) ? $customURL : 'index.php?option=' . $this->component . '&view=' . FOFInflector::pluralize($this->view) . $this->getItemidURLSuffix(); + + if (!$status) + { + $this->setRedirect($url, $model->getError(), 'error'); + } + else + { + $this->setRedirect($url); + } + + return $status; + } + + /** + * Redirects the browser or returns false if no redirect is set. + * + * @return boolean False if no redirect exists. + */ + public function redirect() + { + if ($this->redirect) + { + $app = JFactory::getApplication(); + $app->enqueueMessage($this->message, $this->messageType); + $app->redirect($this->redirect); + + return true; + } + + return false; + } + + /** + * Returns true if there is a redirect set in the controller + * + * @return boolean + */ + public function hasRedirect() + { + return !empty($this->redirect); + } + + /** + * Register the default task to perform if a mapping is not found. + * + * @param string $method The name of the method in the derived class to perform if a named task is not found. + * + * @return FOFController A FOFController object to support chaining. + */ + public function registerDefaultTask($method) + { + $this->registerTask('__default', $method); + + return $this; + } + + /** + * Register (map) a task to a method in the class. + * + * @param string $task The task. + * @param string $method The name of the method in the derived class to perform for this task. + * + * @return FOFController A FOFController object to support chaining. + */ + public function registerTask($task, $method) + { + if (in_array(strtolower($method), $this->methods)) + { + $this->taskMap[strtolower($task)] = $method; + } + + return $this; + } + + /** + * Unregister (unmap) a task in the class. + * + * @param string $task The task. + * + * @return FOFController This object to support chaining. + */ + public function unregisterTask($task) + { + unset($this->taskMap[strtolower($task)]); + + return $this; + } + + /** + * Sets the internal message that is passed with a redirect + * + * @param string $text Message to display on redirect. + * @param string $type Message type. Optional, defaults to 'message'. + * + * @return string Previous message + */ + public function setMessage($text, $type = 'message') + { + $previous = $this->message; + $this->message = $text; + $this->messageType = $type; + + return $previous; + } + + /** + * Sets an entire array of search paths for resources. + * + * @param string $type The type of path to set, typically 'view' or 'model'. + * @param string $path The new set of search paths. If null or false, resets to the current directory only. + * + * @return void + */ + protected function setPath($type, $path) + { + // Clear out the prior search dirs + $this->paths[$type] = array(); + + // Actually add the user-specified directories + $this->addPath($type, $path); + } + + /** + * Registers a redirection with an optional message. The redirection is + * carried out when you use the redirect method. + * + * @param string $url The URL to redirect to + * @param string $msg The message to be pushed to the application + * @param string $type The message type to be pushed to the application, e.g. 'error' + * + * @return FOFController This object to support chaining + */ + public function setRedirect($url, $msg = null, $type = null) + { + // Do the logic only if we're parsing a raw url (index.php?foo=bar&etc=etc) + if (strpos($url, 'index.php') === 0) + { + $isAdmin = FOFPlatform::getInstance()->isBackend(); + $auto = false; + + if (($this->autoRouting == 2 || $this->autoRouting == 3) && $isAdmin) + { + $auto = true; + } + elseif (($this->autoRouting == 1 || $this->autoRouting == 3) && !$isAdmin) + { + $auto = true; + } + + if ($auto) + { + $url = JRoute::_($url, false); + } + } + + $this->redirect = $url; + + if ($msg !== null) + { + // Controller may have set this directly + $this->message = $msg; + } + + // Ensure the type is not overwritten by a previous call to setMessage. + if (empty($type)) + { + if (empty($this->messageType)) + { + $this->messageType = 'message'; + } + } + // If the type is explicitly set, set it. + else + { + $this->messageType = $type; + } + + return $this; + } + + /** + * Sets the published state (the enabled field) of the selected item(s) + * + * @param integer $state The desired state. 0 is unpublished, 1 is published. + * + * @return bool + */ + protected function setstate($state = 0) + { + $model = $this->getThisModel(); + + if (!$model->getId()) + { + $model->setIDsFromRequest(); + } + + $status = $model->publish($state); + + // Redirect + if ($customURL = $this->input->get('returnurl', '', 'string')) + { + $customURL = base64_decode($customURL); + } + + $url = !empty($customURL) ? $customURL : 'index.php?option=' . $this->component . '&view=' . FOFInflector::pluralize($this->view) . $this->getItemidURLSuffix(); + + if (!$status) + { + $this->setRedirect($url, $model->getError(), 'error'); + } + else + { + $this->setRedirect($url); + } + + return $status; + } + + /** + * Sets the access level of the selected item(s). + * + * @param integer $level The desired viewing access level ID + * + * @return bool + */ + protected function setaccess($level = 0) + { + $model = $this->getThisModel(); + + if (!$model->getId()) + { + $model->setIDsFromRequest(); + } + + $id = $model->getId(); + $item = $model->getItem(); + + if (!($item instanceof FOFTable)) + { + return false; + } + + $accessField = $item->getColumnAlias('access'); + $key = $item->getKeyName(); + $loadedid = $item->$key; + + if ($id == $loadedid) + { + $item->$accessField = $level; + $status = $model->save($item); + } + else + { + $status = false; + } + + // Redirect + if ($customURL = $this->input->get('returnurl', '', 'string')) + { + $customURL = base64_decode($customURL); + } + + $url = !empty($customURL) ? $customURL : 'index.php?option=' . $this->component . '&view=' . FOFInflector::pluralize($this->view) . $this->getItemidURLSuffix(); + + if (!$status) + { + $this->setRedirect($url, $model->getError(), 'error'); + } + else + { + $this->setRedirect($url); + } + + return $status; + } + + /** + * Common method to handle apply and save tasks + * + * @return boolean Returns true on success + */ + private function applySave() + { + // Load the model + $model = $this->getThisModel(); + + if (!$model->getId()) + { + $model->setIDsFromRequest(); + } + + $id = $model->getId(); + + $data = $this->input->getData(); + + if (!$this->onBeforeApplySave($data)) + { + return false; + } + + // Set the layout to form, if it's not set in the URL + + if (is_null($this->layout)) + { + $this->layout = 'form'; + } + + // Do I have a form? + $model->setState('form_name', 'form.' . $this->layout); + + $status = $model->save($data); + + if ($status && ($id != 0)) + { + FOFPlatform::getInstance()->setHeader('Status', '201 Created', true); + + // Try to check-in the record if it's not a new one + $status = $model->checkin(); + } + + if ($status) + { + $status = $this->onAfterApplySave(); + } + + $this->input->set('id', $model->getId()); + + if (!$status) + { + // Redirect on error + $id = $model->getId(); + + if ($customURL = $this->input->get('returnurl', '', 'string')) + { + $customURL = base64_decode($customURL); + } + + if (!empty($customURL)) + { + $url = $customURL; + } + elseif ($id != 0) + { + $url = 'index.php?option=' . $this->component . '&view=' . $this->view . '&task=edit&id=' . $id . $this->getItemidURLSuffix(); + } + else + { + $url = 'index.php?option=' . $this->component . '&view=' . $this->view . '&task=add' . $this->getItemidURLSuffix(); + } + + $this->setRedirect($url, '
    • ' . implode('
    • ', $model->getErrors()) . '
    • ', 'error'); + + return false; + } + else + { + $session = JFactory::getSession(); + $session->set($model->getHash() . 'savedata', null); + + return true; + } + } + + /** + * Returns the default model associated with the current view + * + * @param array $config Configuration variables for the model + * + * @return FOFModel The global instance of the model (singleton) + */ + final public function getThisModel($config = array()) + { + if (!is_object($this->_modelObject)) + { + // Make sure $config is an array + if (is_object($config)) + { + $config = (array) $config; + } + elseif (!is_array($config)) + { + $config = array(); + } + + if (!empty($this->modelName)) + { + $parts = FOFInflector::explode($this->modelName); + $modelName = ucfirst(array_pop($parts)); + $prefix = FOFInflector::implode($parts); + } + else + { + $prefix = ucfirst($this->bareComponent) . 'Model'; + $modelName = ucfirst(FOFInflector::pluralize($this->view)); + } + + if (!array_key_exists('input', $config) || !($config['input'] instanceof FOFInput)) + { + $config['input'] = $this->input; + } + + $this->_modelObject = $this->getModel($modelName, $prefix, $config); + } + + return $this->_modelObject; + } + + /** + * Method to get a model object, loading it if required. + * + * @param string $name The model name. Optional. + * @param string $prefix The class prefix. Optional. + * @param array $config Configuration array for model. Optional. + * + * @return object The model. + */ + public function getModel($name = '', $prefix = '', $config = array()) + { + // Make sure $config is an array + if (is_object($config)) + { + $config = (array) $config; + } + elseif (!is_array($config) || empty($config)) + { + // array_merge is required to create a copy instead of assigning by reference + $config = array_merge($this->config); + } + + if (empty($name)) + { + $name = $this->getName(); + } + + if (empty($prefix)) + { + $prefix = $this->model_prefix; + } + + if ($model = $this->createModel($name, $prefix, $config)) + { + // Task is a reserved state + $model->setState('task', $this->task); + + // Let's get the application object and set menu information if it's available + if (!FOFPlatform::getInstance()->isCli()) + { + $app = JFactory::getApplication(); + $menu = $app->getMenu(); + + if (is_object($menu)) + { + if ($item = $menu->getActive()) + { + $params = $menu->getParams($item->id); + + // Set default state data + $model->setState('parameters.menu', $params); + } + } + } + } + + return $model; + } + + /** + * Returns current view object + * + * @param array $config Configuration variables for the model + * + * @return FOFView The global instance of the view object (singleton) + */ + final public function getThisView($config = array()) + { + if (!is_object($this->_viewObject)) + { + // Make sure $config is an array + if (is_object($config)) + { + $config = (array) $config; + } + elseif (!is_array($config) || empty($config)) + { + // array_merge is required to create a copy instead of assigning by reference + $config = array_merge($this->config); + } + + $prefix = null; + $viewName = null; + $viewType = null; + + if (!empty($this->viewName)) + { + $parts = FOFInflector::explode($this->viewName); + $viewName = ucfirst(array_pop($parts)); + $prefix = FOFInflector::implode($parts); + } + else + { + $prefix = ucfirst($this->bareComponent) . 'View'; + $viewName = ucfirst($this->view); + } + + $document = FOFPlatform::getInstance()->getDocument(); + + if ($document instanceof JDocument) + { + $viewType = $document->getType(); + } + else + { + $viewType = $this->input->getCmd('format', 'html'); + } + + if (($viewType == 'html') && $this->hasForm) + { + $viewType = 'form'; + } + + if (!array_key_exists('input', $config) || !($config['input'] instanceof FOFInput)) + { + $config['input'] = $this->input; + } + + $config['input']->set('base_path', $this->basePath); + + $this->_viewObject = $this->getView($viewName, $viewType, $prefix, $config); + } + + return $this->_viewObject; + } + + /** + * Method to get the controller name + * + * The dispatcher name is set by default parsed using the classname, or it can be set + * by passing a $config['name'] in the class constructor + * + * @throws Exception + * + * @return string The name of the dispatcher + */ + public function getName() + { + if (empty($this->name)) + { + if (empty($this->bareComponent)) + { + $r = null; + + if (!preg_match('/(.*)Controller/i', get_class($this), $r)) + { + throw new Exception(JText::_('JLIB_APPLICATION_ERROR_CONTROLLER_GET_NAME'), 500); + } + + $this->name = strtolower($r[1]); + } + else + { + $this->name = $this->bareComponent; + } + } + + return $this->name; + } + + /** + * Get the last task that is being performed or was most recently performed. + * + * @return string The task that is being performed or was most recently performed. + */ + public function getTask() + { + return $this->task; + } + + /** + * Gets the available tasks in the controller. + * + * @return array Array[i] of task names. + */ + public function getTasks() + { + return $this->methods; + } + + /** + * Method to get a reference to the current view and load it if necessary. + * + * @param string $name The view name. Optional, defaults to the controller name. + * @param string $type The view type. Optional. + * @param string $prefix The class prefix. Optional. + * @param array $config Configuration array for view. Optional. + * + * @throws Exception + * + * @return FOFView Reference to the view or an error. + */ + public function getView($name = '', $type = '', $prefix = '', $config = array()) + { + // Make sure $config is an array + if (is_object($config)) + { + $config = (array) $config; + } + elseif (!is_array($config)) + { + $config = array(); + } + + if (empty($name)) + { + $name = $this->getName(); + } + + if (empty($prefix)) + { + $prefix = $this->getName() . 'View'; + } + + $signature = md5($name . $type . $prefix . serialize($config)); + + if (empty($this->viewsCache[$signature])) + { + if ($view = $this->createView($name, $prefix, $type, $config)) + { + $this->viewsCache[$signature] = & $view; + } + else + { + throw new Exception(JText::sprintf('JLIB_APPLICATION_ERROR_VIEW_NOT_FOUND', $name, $type, $prefix), 500); + } + } + + return $this->viewsCache[$signature]; + } + + /** + * Creates a new model object + * + * @param string $name The name of the model class, e.g. Items + * @param string $prefix The prefix of the model class, e.g. FoobarModel + * @param array $config The configuration parameters for the model class + * + * @return FOFModel The model object + */ + protected function createModel($name, $prefix = '', $config = array()) + { + // Make sure $config is an array + + if (is_object($config)) + { + $config = (array) $config; + } + elseif (!is_array($config)) + { + $config = array(); + } + + $result = null; + + // Clean the model name + $modelName = preg_replace('/[^A-Z0-9_]/i', '', $name); + $classPrefix = preg_replace('/[^A-Z0-9_]/i', '', $prefix); + + $result = FOFModel::getAnInstance($modelName, $classPrefix, $config); + + return $result; + } + + /** + * Method to load and return a model object. + * + * @param string $name The name of the model. + * @param string $prefix Optional model prefix. + * @param array $config Configuration array for the model. Optional. + * + * @return mixed Model object on success; otherwise null + */ + protected function &_createModel($name, $prefix = '', $config = array()) + { + FOFPlatform::getInstance()->logDeprecated(__CLASS__ . '::' .__METHOD__ . ' is deprecated. Use createModel() instead.'); + + return $this->createModel($name, $prefix, $config); + } + + /** + * Creates a View object instance and returns it + * + * @param string $name The name of the view, e.g. Items + * @param string $prefix The prefix of the view, e.g. FoobarView + * @param string $type The type of the view, usually one of Html, Raw, Json or Csv + * @param array $config The configuration variables to use for creating the view + * + * @return FOFView + */ + protected function createView($name, $prefix = '', $type = '', $config = array()) + { + // Make sure $config is an array + + if (is_object($config)) + { + $config = (array) $config; + } + elseif (!is_array($config)) + { + $config = array(); + } + + $result = null; + + // Clean the view name + $viewName = preg_replace('/[^A-Z0-9_]/i', '', $name); + $classPrefix = preg_replace('/[^A-Z0-9_]/i', '', $prefix); + $viewType = preg_replace('/[^A-Z0-9_]/i', '', $type); + + if (!isset($config['input'])) + { + $config['input'] = $this->input; + } + + if (($config['input'] instanceof FOFInput)) + { + $tmpInput = $config['input']; + } + else + { + $tmpInput = new FOFInput($config['input']); + } + + // Guess the component name and view + + if (!empty($prefix)) + { + preg_match('/(.*)View$/', $prefix, $m); + $component = 'com_' . strtolower($m[1]); + } + else + { + $component = ''; + } + + if (empty($component) && array_key_exists('input', $config)) + { + $component = $tmpInput->get('option', $component, 'cmd'); + } + + if (array_key_exists('option', $config)) + { + if ($config['option']) + { + $component = $config['option']; + } + } + + $config['option'] = $component; + + $view = strtolower($viewName); + + if (empty($view) && array_key_exists('input', $config)) + { + $view = $tmpInput->get('view', $view, 'cmd'); + } + + if (array_key_exists('view', $config)) + { + if ($config['view']) + { + $view = $config['view']; + } + } + + $config['view'] = $view; + + if (array_key_exists('input', $config)) + { + $tmpInput->set('option', $config['option']); + $tmpInput->set('view', $config['view']); + $config['input'] = $tmpInput; + } + + // Get the component directories + $componentPaths = FOFPlatform::getInstance()->getComponentBaseDirs($config['option']); + + // Get the base paths where the view class files are expected to live + $basePaths = array( + $componentPaths['main'], + $componentPaths['alt'] + ); + $basePaths = array_merge($this->paths['view']); + + // Get the alternate (singular/plural) view name + $altViewName = FOFInflector::isPlural($viewName) ? FOFInflector::singularize($viewName) : FOFInflector::pluralize($viewName); + + $suffixes = array( + $viewName, + $altViewName, + 'default' + ); + + $filesystem = FOFPlatform::getInstance()->getIntegrationObject('filesystem'); + + foreach ($suffixes as $suffix) + { + // Build the view class name + $viewClass = $classPrefix . ucfirst($suffix); + + if (class_exists($viewClass)) + { + // The class is already loaded + break; + } + + // The class is not loaded. Let's load it! + $viewPath = $this->createFileName('view', array('name' => $suffix, 'type' => $viewType)); + $path = $filesystem->pathFind($basePaths, $viewPath); + + if ($path) + { + require_once $path; + } + + if (class_exists($viewClass)) + { + // The class was loaded successfully + break; + } + } + + if (!class_exists($viewClass)) + { + $viewClass = 'FOFView' . ucfirst($type); + } + + $templateOverridePath = FOFPlatform::getInstance()->getTemplateOverridePath($config['option']); + + // Setup View configuration options + + if (!array_key_exists('template_path', $config)) + { + $config['template_path'][] = $componentPaths['main'] . '/views/' . FOFInflector::pluralize($config['view']) . '/tmpl'; + + if ($templateOverridePath) + { + $config['template_path'][] = $templateOverridePath . '/' . FOFInflector::pluralize($config['view']); + } + + $config['template_path'][] = $componentPaths['main'] . '/views/' . FOFInflector::singularize($config['view']) . '/tmpl'; + + if ($templateOverridePath) + { + $config['template_path'][] = $templateOverridePath . '/' . FOFInflector::singularize($config['view']); + } + + $config['template_path'][] = $componentPaths['main'] . '/views/' . $config['view'] . '/tmpl'; + + if ($templateOverridePath) + { + $config['template_path'][] = $templateOverridePath . '/' . $config['view']; + } + } + + $extraTemplatePath = $this->configProvider->get($config['option'] . '.views.' . $config['view'] . '.config.template_path', null); + + if ($extraTemplatePath) + { + array_unshift($config['template_path'], $componentPaths['main'] . '/' . $extraTemplatePath); + } + + if (!array_key_exists('helper_path', $config)) + { + $config['helper_path'] = array( + $componentPaths['main'] . '/helpers', + $componentPaths['admin'] . '/helpers' + ); + } + + $extraHelperPath = $this->configProvider->get($config['option'] . '.views.' . $config['view'] . '.config.helper_path', null); + + if ($extraHelperPath) + { + $config['helper_path'][] = $componentPaths['main'] . '/' . $extraHelperPath; + } + + // Set up the page title + $setFrontendPageTitle = $this->configProvider->get($config['option'] . '.views.' . $config['view'] . '.config.setFrontendPageTitle', null); + + if ($setFrontendPageTitle) + { + $setFrontendPageTitle = strtolower($setFrontendPageTitle); + $config['setFrontendPageTitle'][] = in_array($setFrontendPageTitle, array('1', 'yes', 'true', 'on')); + } + + $defaultPageTitle = $this->configProvider->get($config['option'] . '.views.' . $config['view'] . '.config.defaultPageTitle', null); + + if ($defaultPageTitle) + { + $config['defaultPageTitle'][] = in_array($defaultPageTitle, array('1', 'yes', 'true', 'on')); + } + + // Set the use_hypermedia flag in $config if it's not already set + if (!isset($config['use_hypermedia'])) + { + $config['use_hypermedia'] = $this->configProvider->get($config['option'] . '.views.' . $config['view'] . '.config.use_hypermedia', false); + } + + // Set also the linkbar_style + if (!isset($config['linkbar_style'])) + { + $style = $this->configProvider->get($config['option'] . '.views.' . $config['view'] . '.config.linkbar_style', false); + + if ($style) { + $config['linkbar_style'] = $style; + } + } + + /** + * Some administrative templates force format=utf (yeah, I know, what the heck, right?) when a format + * URL parameter does not exist in the URL. Of course there is no such thing as FOFViewUtf (why the heck would + * it be, there is no such thing as a format=utf in Joomla! for crying out loud) which causes a Fatal Error. So + * we have to detect that and force $type='html'... + */ + if (!class_exists($viewClass) && ($type != 'html')) + { + $type = 'html'; + $result = $this->createView($name, $prefix, $type, $config); + } + else + { + $result = new $viewClass($config); + } + + return $result; + } + + /** + * Deprecated function to create a View object instance + * + * @param string $name The name of the view, e.g. 'Items' + * @param string $prefix The prefix of the view, e.g. 'FoobarView' + * @param string $type The view type, e.g. 'html' + * @param array $config The configuration array for the view + * + * @return FOFView + * + * @see FOFController::createView + * + * @deprecated since version 2.0 + */ + protected function &_createView($name, $prefix = '', $type = '', $config = array()) + { + FOFPlatform::getInstance()->logDeprecated(__CLASS__ . '::' . __METHOD__ . ' is deprecated. Use createView() instead.'); + + return $this->createView($name, $prefix, $type, $config); + } + + /** + * Set the name of the view to be used by this Controller + * + * @param string $viewName The name of the view + * + * @return void + */ + public function setThisViewName($viewName) + { + $this->viewName = $viewName; + } + + /** + * Set the name of the model to be used by this Controller + * + * @param string $modelName The name of the model + * + * @return void + */ + public function setThisModelName($modelName) + { + $this->modelName = $modelName; + } + + /** + * Checks if the current user has enough privileges for the requested ACL + * area. + * + * @param string $area The ACL area, e.g. core.manage. + * + * @return boolean True if the user has the ACL privilege specified + */ + protected function checkACL($area) + { + if (in_array(strtolower($area), array('false','0','no','403'))) + { + return false; + } + + if (in_array(strtolower($area), array('true','1','yes'))) + { + return true; + } + elseif (empty($area)) + { + return true; + } + else + { + // Check if we're dealing with ids + $ids = null; + + // First, check if there is an asset for this record + $table = $this->getThisModel()->getTable(); + + if ($table && $table->isAssetsTracked()) + { + $ids = $this->getThisModel()->getId() ? $this->getThisModel()->getId() : null; + } + + // Generic or Asset tracking + + if (empty($ids)) + { + return FOFPlatform::getInstance()->authorise($area, $this->component); + } + else + { + if (!is_array($ids)) + { + $ids = array($ids); + } + + $resource = FOFInflector::singularize($this->view); + $isEditState = ($area == 'core.edit.state'); + + foreach ($ids as $id) + { + $asset = $this->component . '.' . $resource . '.' . $id; + + // Dedicated permission found, check it! + + if (FOFPlatform::getInstance()->authorise($area, $asset) ) + { + return true; + } + + // Fallback on edit.own, if not edit.state. First test if the permission is available. + + if ((!$isEditState) && (FOFPlatform::getInstance()->authorise('core.edit.own', $asset))) + { + $table = $this->getThisModel()->getTable(); + $table->load($id); + + $created_by = $table->getColumnAlias('created_by'); + + if ($table && isset($table->$created_by)) + { + // Now test the owner is the user. + $owner_id = (int) $table->$created_by; + + // If the owner matches 'me' then do the test. + if ($owner_id == FOFPlatform::getInstance()->getUser()->id) + { + return true; + } + else + { + return false; + } + } + else + { + return false; + } + } + } + } + } + + return false; + } + + /** + * A catch-all method for all tasks without a corresponding onBefore + * method. Applies the ACL preferences defined in fof.xml. + * + * @param string $task The task being executed + * + * @return boolean True to allow execution of the task + */ + protected function onBeforeGenericTask($task) + { + $privilege = $this->configProvider->get( + $this->component . '.views.' . + FOFInflector::singularize($this->view) . '.acl.' . $task, '' + ); + + return $this->checkACL($privilege); + } + + /** + * Execute something before applySave is called. Return false to prevent + * applySave from executing. + * + * @param array &$data The data upon which applySave will act + * + * @return boolean True to allow applySave to run + */ + protected function onBeforeApplySave(&$data) + { + return true; + } + + /** + * Execute something after applySave has run. + * + * @return boolean True to allow normal return, false to cause a 403 error + */ + protected function onAfterApplySave() + { + return true; + } + + /** + * ACL check before changing the access level; override to customise + * + * @return boolean True to allow accesspublic() to run + */ + protected function onBeforeAccesspublic() + { + $privilege = $this->configProvider->get( + $this->component . '.views.' . + FOFInflector::singularize($this->view) . '.acl.accesspublic', 'core.edit.state'); + + return $this->checkACL($privilege); + } + + /** + * ACL check before changing the access level; override to customise + * + * @return boolean True to allow the method to run + */ + protected function onBeforeAccessregistered() + { + $privilege = $this->configProvider->get( + $this->component . '.views.' . + FOFInflector::singularize($this->view) . '.acl.accessregistered', 'core.edit.state' + ); + + return $this->checkACL($privilege); + } + + /** + * ACL check before changing the access level; override to customise + * + * @return boolean True to allow the method to run + */ + protected function onBeforeAccessspecial() + { + $privilege = $this->configProvider->get( + $this->component . '.views.' . + FOFInflector::singularize($this->view) . '.acl.accessspecial', 'core.edit.state' + ); + + return $this->checkACL($privilege); + } + + /** + * ACL check before adding a new record; override to customise + * + * @return boolean True to allow the method to run + */ + protected function onBeforeAdd() + { + $privilege = $this->configProvider->get( + $this->component . '.views.' . + FOFInflector::singularize($this->view) . '.acl.add', 'core.create' + ); + + return $this->checkACL($privilege); + } + + /** + * ACL check before saving a new/modified record; override to customise + * + * @return boolean True to allow the method to run + */ + protected function onBeforeApply() + { + $model = $this->getThisModel(); + + if (!$model->getId()) + { + $model->setIDsFromRequest(); + } + + $id = $model->getId(); + + if(!$id) + { + $defaultPrivilege = 'core.create'; + } + else + { + $defaultPrivilege = 'core.edit'; + } + + $privilege = $this->configProvider->get( + $this->component . '.views.' . + FOFInflector::singularize($this->view) . '.acl.apply', $defaultPrivilege + ); + + return $this->checkACL($privilege); + } + + /** + * ACL check before allowing someone to browse + * + * @return boolean True to allow the method to run + */ + protected function onBeforeBrowse() + { + $defaultPrivilege = ''; + + $privilege = $this->configProvider->get( + $this->component . '.views.' . + FOFInflector::singularize($this->view) . '.acl.browse', $defaultPrivilege + ); + + return $this->checkACL($privilege); + } + + /** + * ACL check before cancelling an edit + * + * @return boolean True to allow the method to run + */ + protected function onBeforeCancel() + { + $model = $this->getThisModel(); + + if (!$model->getId()) + { + $model->setIDsFromRequest(); + } + + $id = $model->getId(); + + if(!$id) + { + $defaultPrivilege = 'core.create'; + } + else + { + $defaultPrivilege = 'core.edit'; + } + + $privilege = $this->configProvider->get( + $this->component . '.views.' . + FOFInflector::singularize($this->view) . '.acl.cancel', $defaultPrivilege + ); + + return $this->checkACL($privilege); + } + + /** + * ACL check before editing a record; override to customise + * + * @return boolean True to allow the method to run + */ + protected function onBeforeEdit() + { + $privilege = $this->configProvider->get( + $this->component . '.views.' . + FOFInflector::singularize($this->view) . '.acl.edit', 'core.edit' + ); + + return $this->checkACL($privilege); + } + + /** + * ACL check before changing the ordering of a record; override to customise + * + * @return boolean True to allow the method to run + */ + protected function onBeforeOrderdown() + { + $privilege = $this->configProvider->get( + $this->component . '.views.' . + FOFInflector::singularize($this->view) . '.acl.orderdown', 'core.edit.state' + ); + + return $this->checkACL($privilege); + } + + /** + * ACL check before changing the ordering of a record; override to customise + * + * @return boolean True to allow the method to run + */ + protected function onBeforeOrderup() + { + $privilege = $this->configProvider->get( + $this->component . '.views.' . + FOFInflector::singularize($this->view) . '.acl.orderup', 'core.edit.state' + ); + + return $this->checkACL($privilege); + } + + /** + * ACL check before changing the publish status of a record; override to customise + * + * @return boolean True to allow the method to run + */ + protected function onBeforePublish() + { + $privilege = $this->configProvider->get( + $this->component . '.views.' . + FOFInflector::singularize($this->view) . '.acl.publish', 'core.edit.state' + ); + + return $this->checkACL($privilege); + } + + /** + * ACL check before removing a record; override to customise + * + * @return boolean True to allow the method to run + */ + protected function onBeforeRemove() + { + $privilege = $this->configProvider->get( + $this->component . '.views.' . + FOFInflector::singularize($this->view) . '.acl.remove', 'core.delete' + ); + + return $this->checkACL($privilege); + } + + /** + * ACL check before saving a new/modified record; override to customise + * + * @return boolean True to allow the method to run + */ + protected function onBeforeSave() + { + $model = $this->getThisModel(); + + if (!$model->getId()) + { + $model->setIDsFromRequest(); + } + + $id = $model->getId(); + + if(!$id) + { + $defaultPrivilege = 'core.create'; + } + else + { + $defaultPrivilege = 'core.edit'; + } + + $privilege = $this->configProvider->get( + $this->component . '.views.' . + FOFInflector::singularize($this->view) . '.acl.save', $defaultPrivilege + ); + + return $this->checkACL($privilege); + } + + /** + * ACL check before saving a new/modified record; override to customise + * + * @return boolean True to allow the method to run + */ + protected function onBeforeSavenew() + { + $privilege = $this->configProvider->get( + $this->component . '.views.' . + FOFInflector::singularize($this->view) . '.acl.savenew', 'core.create' + ); + + return $this->checkACL($privilege); + } + + /** + * ACL check before changing the ordering of a record; override to customise + * + * @return boolean True to allow the method to run + */ + protected function onBeforeSaveorder() + { + $privilege = $this->configProvider->get( + $this->component . '.views.' . + FOFInflector::singularize($this->view) . '.acl.saveorder', 'core.edit.state' + ); + + return $this->checkACL($privilege); + } + + /** + * ACL check before changing the publish status of a record; override to customise + * + * @return boolean True to allow the method to run + */ + protected function onBeforeUnpublish() + { + $privilege = $this->configProvider->get( + $this->component . '.views.' . + FOFInflector::singularize($this->view) . '.acl.unpublish', 'core.edit.state' + ); + + return $this->checkACL($privilege); + } + + /** + * Gets a URL suffix with the Itemid parameter. If it's not the front-end of the site, or if + * there is no Itemid set it returns an empty string. + * + * @return string The &Itemid=123 URL suffix, or an empty string if Itemid is not applicable + */ + public function getItemidURLSuffix() + { + if (FOFPlatform::getInstance()->isFrontend() && ($this->input->getCmd('Itemid', 0) != 0)) + { + return '&Itemid=' . $this->input->getInt('Itemid', 0); + } + else + { + return ''; + } + } + + /** + * Applies CSRF protection by means of a standard Joomla! token (nonce) check. + * Raises a 403 Access Forbidden error through the platform if the check fails. + * + * TODO Move this check inside the platform + * + * @return boolean True if the CSRF check is successful + * + * @throws Exception + */ + protected function _csrfProtection() + { + static $isCli = null, $isAdmin = null; + + if (is_null($isCli)) + { + $isCli = FOFPlatform::getInstance()->isCli(); + $isAdmin = FOFPlatform::getInstance()->isBackend(); + } + + switch ($this->csrfProtection) + { + // Never + case 0: + return true; + break; + + // Always + case 1: + break; + + // Only back-end and HTML format + case 2: + if ($isCli) + { + return true; + } + elseif (!$isAdmin && ($this->input->get('format', 'html', 'cmd') != 'html')) + { + return true; + } + break; + + // Only back-end + case 3: + if (!$isAdmin) + { + return true; + } + break; + } + + $hasToken = false; + $session = JFactory::getSession(); + + // Joomla! 1.5/1.6/1.7/2.5 (classic Joomla! API) method + if (method_exists('JUtility', 'getToken')) + { + $token = JUtility::getToken(); + $hasToken = $this->input->get($token, false, 'none') == 1; + + if (!$hasToken) + { + $hasToken = $this->input->get('_token', null, 'none') == $token; + } + } + + // Joomla! 2.5+ (Platform 12.1+) method + if (!$hasToken) + { + if (method_exists($session, 'getToken')) + { + $token = $session->getToken(); + $hasToken = $this->input->get($token, false, 'none') == 1; + + if (!$hasToken) + { + $hasToken = $this->input->get('_token', null, 'none') == $token; + } + } + } + + // Joomla! 2.5+ formToken method + if (!$hasToken) + { + if (method_exists($session, 'getFormToken')) + { + $token = $session->getFormToken(); + $hasToken = $this->input->get($token, false, 'none') == 1; + + if (!$hasToken) + { + $hasToken = $this->input->get('_token', null, 'none') == $token; + } + } + } + + if (!$hasToken) + { + FOFPlatform::getInstance()->raiseError(403, JText::_('JLIB_APPLICATION_ERROR_ACCESS_FORBIDDEN')); + + return false; + } + } +} diff --git a/Sites/pages/libraries/fof/database/database.php b/Sites/pages/libraries/fof/database/database.php new file mode 100644 index 00000000..dc5a7188 --- /dev/null +++ b/Sites/pages/libraries/fof/database/database.php @@ -0,0 +1,199 @@ +execute(); + } + + /** + * Get a list of available database connectors. The list will only be populated with connectors that both + * the class exists and the static test method returns true. This gives us the ability to have a multitude + * of connector classes that are self-aware as to whether or not they are able to be used on a given system. + * + * @return array An array of available database connectors. + * + * @since 11.1 + * @deprecated 13.1 (Platform) & 4.0 (CMS) + */ + public static function getConnectors() + { + if (class_exists('JLog')) + { + JLog::add('FOFDatabase::getConnectors() is deprecated, use FOFDatabaseDriver::getConnectors() instead.', JLog::WARNING, 'deprecated'); + } + + return FOFDatabaseDriver::getConnectors(); + } + + /** + * Gets the error message from the database connection. + * + * @param boolean $escaped True to escape the message string for use in JavaScript. + * + * @return string The error message for the most recent query. + * + * @deprecated 13.3 (Platform) & 4.0 (CMS) + * @since 11.1 + */ + public function getErrorMsg($escaped = false) + { + if (class_exists('JLog')) + { + JLog::add('FOFDatabase::getErrorMsg() is deprecated, use exception handling instead.', JLog::WARNING, 'deprecated'); + } + + if ($escaped) + { + return addslashes($this->errorMsg); + } + else + { + return $this->errorMsg; + } + } + + /** + * Gets the error number from the database connection. + * + * @return integer The error number for the most recent query. + * + * @since 11.1 + * @deprecated 13.3 (Platform) & 4.0 (CMS) + */ + public function getErrorNum() + { + if (class_exists('JLog')) + { + JLog::add('FOFDatabase::getErrorNum() is deprecated, use exception handling instead.', JLog::WARNING, 'deprecated'); + } + + return $this->errorNum; + } + + /** + * Method to return a FOFDatabaseDriver instance based on the given options. There are three global options and then + * the rest are specific to the database driver. The 'driver' option defines which FOFDatabaseDriver class is + * used for the connection -- the default is 'mysqli'. The 'database' option determines which database is to + * be used for the connection. The 'select' option determines whether the connector should automatically select + * the chosen database. + * + * Instances are unique to the given options and new objects are only created when a unique options array is + * passed into the method. This ensures that we don't end up with unnecessary database connection resources. + * + * @param array $options Parameters to be passed to the database driver. + * + * @return FOFDatabaseDriver A database object. + * + * @since 11.1 + * @deprecated 13.1 (Platform) & 4.0 (CMS) + */ + public static function getInstance($options = array()) + { + if (class_exists('JLog')) + { + JLog::add('FOFDatabase::getInstance() is deprecated, use FOFDatabaseDriver::getInstance() instead.', JLog::WARNING, 'deprecated'); + } + + return FOFDatabaseDriver::getInstance($options); + } + + /** + * Splits a string of multiple queries into an array of individual queries. + * + * @param string $query Input SQL string with which to split into individual queries. + * + * @return array The queries from the input string separated into an array. + * + * @since 11.1 + * @deprecated 13.1 (Platform) & 4.0 (CMS) + */ + public static function splitSql($query) + { + if (class_exists('JLog')) + { + JLog::add('FOFDatabase::splitSql() is deprecated, use FOFDatabaseDriver::splitSql() instead.', JLog::WARNING, 'deprecated'); + } + + return FOFDatabaseDriver::splitSql($query); + } + + /** + * Return the most recent error message for the database connector. + * + * @param boolean $showSQL True to display the SQL statement sent to the database as well as the error. + * + * @return string The error message for the most recent query. + * + * @since 11.1 + * @deprecated 13.3 (Platform) & 4.0 (CMS) + */ + public function stderr($showSQL = false) + { + if (class_exists('JLog')) + { + JLog::add('FOFDatabase::stderr() is deprecated.', JLog::WARNING, 'deprecated'); + } + + if ($this->errorNum != 0) + { + return JText::sprintf('JLIB_DATABASE_ERROR_FUNCTION_FAILED', $this->errorNum, $this->errorMsg) + . ($showSQL ? "
      SQL =
      $this->sql
      " : ''); + } + else + { + return JText::_('JLIB_DATABASE_FUNCTION_NOERROR'); + } + } + + /** + * Test to see if the connector is available. + * + * @return boolean True on success, false otherwise. + * + * @since 11.1 + * @deprecated 12.3 (Platform) & 4.0 (CMS) - Use FOFDatabaseDriver::isSupported() instead. + */ + public static function test() + { + if (class_exists('JLog')) + { + JLog::add('FOFDatabase::test() is deprecated. Use FOFDatabaseDriver::isSupported() instead.', JLog::WARNING, 'deprecated'); + } + + return static::isSupported(); + } +} diff --git a/Sites/pages/libraries/fof/database/driver.php b/Sites/pages/libraries/fof/database/driver.php new file mode 100644 index 00000000..daec1f15 --- /dev/null +++ b/Sites/pages/libraries/fof/database/driver.php @@ -0,0 +1,2256 @@ +getFilename(); + + // Only load for php files. + if (!$file->isFile() || $file->getExtension() != 'php') + { + continue; + } + + // Block the ext/mysql driver for PHP 7 + if ($fileName === 'mysql.php' && PHP_MAJOR_VERSION >= 7) + { + continue; + } + + // Derive the class name from the type. + $class = str_ireplace('.php', '', 'FOFDatabaseDriver' . ucfirst(trim($fileName))); + + // If the class doesn't exist we have nothing left to do but look at the next type. We did our best. + if (!class_exists($class)) + { + continue; + } + + // Sweet! Our class exists, so now we just need to know if it passes its test method. + if ($class::isSupported()) + { + // Connector names should not have file extensions. + $connectors[] = str_ireplace('.php', '', $fileName); + } + } + + return $connectors; + } + + /** + * Method to return a FOFDatabaseDriver instance based on the given options. There are three global options and then + * the rest are specific to the database driver. The 'driver' option defines which FOFDatabaseDriver class is + * used for the connection -- the default is 'mysqli'. The 'database' option determines which database is to + * be used for the connection. The 'select' option determines whether the connector should automatically select + * the chosen database. + * + * Instances are unique to the given options and new objects are only created when a unique options array is + * passed into the method. This ensures that we don't end up with unnecessary database connection resources. + * + * @param array $options Parameters to be passed to the database driver. + * + * @return FOFDatabaseDriver A database object. + * + * @since 11.1 + * @throws RuntimeException + */ + public static function getInstance($options = array()) + { + // Sanitize the database connector options. + $options['driver'] = (isset($options['driver'])) ? preg_replace('/[^A-Z0-9_\.-]/i', '', $options['driver']) : 'mysqli'; + $options['database'] = (isset($options['database'])) ? $options['database'] : null; + $options['select'] = (isset($options['select'])) ? $options['select'] : true; + + // If the selected driver is `mysql` and we are on PHP 7 or greater, switch to the `mysqli` driver. + if ($options['driver'] === 'mysql' && PHP_MAJOR_VERSION >= 7) + { + // Check if we have support for the other MySQL drivers + $mysqliSupported = FOFDatabaseDriverMysqli::isSupported(); + $pdoMysqlSupported = FOFDatabaseDriverPdomysql::isSupported(); + + // If neither is supported, then the user cannot use MySQL; throw an exception + if (!$mysqliSupported && !$pdoMysqlSupported) + { + throw new RuntimeException( + 'The PHP `ext/mysql` extension is removed in PHP 7, cannot use the `mysql` driver.' + . ' Also, this system does not support MySQLi or PDO MySQL. Cannot instantiate database driver.' + ); + } + + // Prefer MySQLi as it is a closer replacement for the removed MySQL driver, otherwise use the PDO driver + if ($mysqliSupported) + { + if (class_exists('JLog')) + { + JLog::add( + 'The PHP `ext/mysql` extension is removed in PHP 7, cannot use the `mysql` driver. Trying `mysqli` instead.', + JLog::WARNING, + 'deprecated' + ); + } + + $options['driver'] = 'mysqli'; + } + else + { + if (class_exists('JLog')) + { + JLog::add( + 'The PHP `ext/mysql` extension is removed in PHP 7, cannot use the `mysql` driver. Trying `pdomysql` instead.', + JLog::WARNING, + 'deprecated' + ); + } + + $options['driver'] = 'pdomysql'; + } + } + + // Get the options signature for the database connector. + $signature = md5(serialize($options)); + + // If we already have a database connector instance for these options then just use that. + if (empty(self::$instances[$signature])) + { + // Derive the class name from the driver. + $class = 'FOFDatabaseDriver' . ucfirst(strtolower($options['driver'])); + + // If the class still doesn't exist we have nothing left to do but throw an exception. We did our best. + if (!class_exists($class)) + { + throw new RuntimeException(sprintf('Unable to load Database Driver: %s', $options['driver'])); + } + + // Create our new FOFDatabaseDriver connector based on the options given. + try + { + $instance = new $class($options); + } + catch (RuntimeException $e) + { + throw new RuntimeException(sprintf('Unable to connect to the Database: %s', $e->getMessage()), $e->getCode(), $e); + } + + // Set the new connector to the global instances based on signature. + self::$instances[$signature] = $instance; + } + + return self::$instances[$signature]; + } + + /** + * Splits a string of multiple queries into an array of individual queries. + * + * @param string $sql Input SQL string with which to split into individual queries. + * + * @return array The queries from the input string separated into an array. + * + * @since 11.1 + */ + public static function splitSql($sql) + { + $start = 0; + $open = false; + $char = ''; + $end = strlen($sql); + $queries = array(); + + for ($i = 0; $i < $end; $i++) + { + $current = substr($sql, $i, 1); + + if (($current == '"' || $current == '\'')) + { + $n = 2; + + while (substr($sql, $i - $n + 1, 1) == '\\' && $n < $i) + { + $n++; + } + + if ($n % 2 == 0) + { + if ($open) + { + if ($current == $char) + { + $open = false; + $char = ''; + } + } + else + { + $open = true; + $char = $current; + } + } + } + + if (($current == ';' && !$open) || $i == $end - 1) + { + $queries[] = substr($sql, $start, ($i - $start + 1)); + $start = $i + 1; + } + } + + return $queries; + } + + /** + * Magic method to provide method alias support for quote() and quoteName(). + * + * @param string $method The called method. + * @param array $args The array of arguments passed to the method. + * + * @return mixed The aliased method's return value or null. + * + * @since 11.1 + */ + public function __call($method, $args) + { + if (empty($args)) + { + return; + } + + switch ($method) + { + case 'q': + return $this->quote($args[0], isset($args[1]) ? $args[1] : true); + break; + case 'qn': + return $this->quoteName($args[0], isset($args[1]) ? $args[1] : null); + break; + } + } + + /** + * Constructor. + * + * @param array $options List of options used to configure the connection + * + * @since 11.1 + */ + public function __construct($options) + { + // Initialise object variables. + $this->_database = (isset($options['database'])) ? $options['database'] : ''; + $this->tablePrefix = (isset($options['prefix'])) ? $options['prefix'] : 'jos_'; + $this->connection = array_key_exists('connection', $options) ? $options['connection'] : null; + + $this->count = 0; + $this->errorNum = 0; + $this->log = array(); + + // Set class options. + $this->options = $options; + } + + /** + * Alter database's character set, obtaining query string from protected member. + * + * @param string $dbName The database name that will be altered + * + * @return string The query that alter the database query string + * + * @since 12.2 + * @throws RuntimeException + */ + public function alterDbCharacterSet($dbName) + { + if (is_null($dbName)) + { + throw new RuntimeException('Database name must not be null.'); + } + + $this->setQuery($this->getAlterDbCharacterSet($dbName)); + + return $this->execute(); + } + + /** + * Alter a table's character set, obtaining an array of queries to do so from a protected method. The conversion is + * wrapped in a transaction, if supported by the database driver. Otherwise the table will be locked before the + * conversion. This prevents data corruption. + * + * @param string $tableName The name of the table to alter + * @param boolean $rethrow True to rethrow database exceptions. Default: false (exceptions are suppressed) + * + * @return boolean True if successful + * + * @since CMS 3.5.0 + * @throws RuntimeException If the table name is empty + * @throws Exception Relayed from the database layer if a database error occurs and $rethrow == true + */ + public function alterTableCharacterSet($tableName, $rethrow = false) + { + if (is_null($tableName)) + { + throw new RuntimeException('Table name must not be null.'); + } + + $queries = $this->getAlterTableCharacterSet($tableName); + + if (empty($queries)) + { + return false; + } + + $hasTransaction = true; + + try + { + $this->transactionStart(); + } + catch (Exception $e) + { + $hasTransaction = false; + $this->lockTable($tableName); + } + + foreach ($queries as $query) + { + try + { + $this->setQuery($query)->execute(); + } + catch (Exception $e) + { + if ($hasTransaction) + { + $this->transactionRollback(); + } + else + { + $this->unlockTables(); + } + + if ($rethrow) + { + throw $e; + } + + return false; + } + } + + if ($hasTransaction) + { + try + { + $this->transactionCommit(); + } + catch (Exception $e) + { + $this->transactionRollback(); + + if ($rethrow) + { + throw $e; + } + + return false; + } + } + else + { + $this->unlockTables(); + } + + return true; + } + + /** + * Connects to the database if needed. + * + * @return void Returns void if the database connected successfully. + * + * @since 12.1 + * @throws RuntimeException + */ + abstract public function connect(); + + /** + * Determines if the connection to the server is active. + * + * @return boolean True if connected to the database engine. + * + * @since 11.1 + */ + abstract public function connected(); + + /** + * Create a new database using information from $options object, obtaining query string + * from protected member. + * + * @param stdClass $options Object used to pass user and database name to database driver. + * This object must have "db_name" and "db_user" set. + * @param boolean $utf True if the database supports the UTF-8 character set. + * + * @return string The query that creates database + * + * @since 12.2 + * @throws RuntimeException + */ + public function createDatabase($options, $utf = true) + { + if (is_null($options)) + { + throw new RuntimeException('$options object must not be null.'); + } + elseif (empty($options->db_name)) + { + throw new RuntimeException('$options object must have db_name set.'); + } + elseif (empty($options->db_user)) + { + throw new RuntimeException('$options object must have db_user set.'); + } + + $this->setQuery($this->getCreateDatabaseQuery($options, $utf)); + + return $this->execute(); + } + + /** + * Disconnects the database. + * + * @return void + * + * @since 12.1 + */ + abstract public function disconnect(); + + /** + * Adds a function callable just before disconnecting the database. Parameter of the callable is $this FOFDatabaseDriver + * + * @param callable $callable Function to call in disconnect() method just before disconnecting from database + * + * @return void + * + * @since CMS 3.1.2 + */ + public function addDisconnectHandler($callable) + { + $this->disconnectHandlers[] = $callable; + } + + /** + * Drops a table from the database. + * + * @param string $table The name of the database table to drop. + * @param boolean $ifExists Optionally specify that the table must exist before it is dropped. + * + * @return FOFDatabaseDriver Returns this object to support chaining. + * + * @since 11.4 + * @throws RuntimeException + */ + public abstract function dropTable($table, $ifExists = true); + + /** + * Escapes a string for usage in an SQL statement. + * + * @param string $text The string to be escaped. + * @param boolean $extra Optional parameter to provide extra escaping. + * + * @return string The escaped string. + * + * @since 11.1 + */ + abstract public function escape($text, $extra = false); + + /** + * Method to fetch a row from the result set cursor as an array. + * + * @param mixed $cursor The optional result set cursor from which to fetch the row. + * + * @return mixed Either the next row from the result set or false if there are no more rows. + * + * @since 11.1 + */ + abstract protected function fetchArray($cursor = null); + + /** + * Method to fetch a row from the result set cursor as an associative array. + * + * @param mixed $cursor The optional result set cursor from which to fetch the row. + * + * @return mixed Either the next row from the result set or false if there are no more rows. + * + * @since 11.1 + */ + abstract protected function fetchAssoc($cursor = null); + + /** + * Method to fetch a row from the result set cursor as an object. + * + * @param mixed $cursor The optional result set cursor from which to fetch the row. + * @param string $class The class name to use for the returned row object. + * + * @return mixed Either the next row from the result set or false if there are no more rows. + * + * @since 11.1 + */ + abstract protected function fetchObject($cursor = null, $class = 'stdClass'); + + /** + * Method to free up the memory used for the result set. + * + * @param mixed $cursor The optional result set cursor from which to fetch the row. + * + * @return void + * + * @since 11.1 + */ + abstract protected function freeResult($cursor = null); + + /** + * Get the number of affected rows for the previous executed SQL statement. + * + * @return integer The number of affected rows. + * + * @since 11.1 + */ + abstract public function getAffectedRows(); + + /** + * Return the query string to alter the database character set. + * + * @param string $dbName The database name + * + * @return string The query that alter the database query string + * + * @since 12.2 + */ + public function getAlterDbCharacterSet($dbName) + { + $charset = $this->utf8mb4 ? 'utf8mb4' : 'utf8'; + + return 'ALTER DATABASE ' . $this->quoteName($dbName) . ' CHARACTER SET `' . $charset . '`'; + } + + /** + * Get the query strings to alter the character set and collation of a table. + * + * @param string $tableName The name of the table + * + * @return string[] The queries required to alter the table's character set and collation + * + * @since CMS 3.5.0 + */ + public function getAlterTableCharacterSet($tableName) + { + $charset = $this->utf8mb4 ? 'utf8mb4' : 'utf8'; + $collation = $charset . '_general_ci'; + + $quotedTableName = $this->quoteName($tableName); + + $queries = array(); + $queries[] = "ALTER TABLE $quotedTableName CONVERT TO CHARACTER SET $charset COLLATE $collation"; + + /** + * We also need to convert each text column, modifying their character set and collation. This allows us to + * change, for example, a utf8_bin collated column to a utf8mb4_bin collated column. + */ + $sql = "SHOW FULL COLUMNS FROM $quotedTableName"; + $this->setQuery($sql); + $columns = $this->loadAssocList(); + $columnMods = array(); + + if (is_array($columns)) + { + foreach ($columns as $column) + { + // Make sure we are redefining only columns which do support a collation + $col = (object) $column; + + if (empty($col->Collation)) + { + continue; + } + + // Default new collation: utf8_general_ci or utf8mb4_general_ci + $newCollation = $charset . '_general_ci'; + $collationParts = explode('_', $col->Collation); + + /** + * If the collation is in the form charset_collationType_ci or charset_collationType we have to change + * the charset but leave the collationType intact (e.g. utf8_bin must become utf8mb4_bin, NOT + * utf8mb4_general_ci). + */ + if (count($collationParts) >= 2) + { + $ci = array_pop($collationParts); + $collationType = array_pop($collationParts); + $newCollation = $charset . '_' . $collationType . '_' . $ci; + + /** + * When the last part of the old collation is not _ci we have a charset_collationType format, + * something like utf8_bin. Therefore the new collation only has *two* parts. + */ + if ($ci != 'ci') + { + $newCollation = $charset . '_' . $ci; + } + } + + // If the old and new collation is the same we don't have to change the collation type + if (strtolower($newCollation) == strtolower($col->Collation)) + { + continue; + } + + $null = $col->Null == 'YES' ? 'NULL' : 'NOT NULL'; + $default = is_null($col->Default) ? '' : "DEFAULT '" . $this->q($col->Default) . "'"; + $columnMods[] = "MODIFY COLUMN `{$col->Field}` {$col->Type} CHARACTER SET $charset COLLATE $newCollation $null $default"; + } + } + + if (count($columnMods)) + { + $queries[] = "ALTER TABLE $quotedTableName " . + implode(',', $columnMods) . + " CHARACTER SET $charset COLLATE $collation"; + } + + return $queries; + } + + /** + * Automatically downgrade a CREATE TABLE or ALTER TABLE query from utf8mb4 (UTF-8 Multibyte) to plain utf8. Used + * when the server doesn't support UTF-8 Multibyte. + * + * @param string $query The query to convert + * + * @return string The converted query + */ + public function convertUtf8mb4QueryToUtf8($query) + { + if ($this->hasUTF8mb4Support()) + { + return $query; + } + + // If it's not an ALTER TABLE or CREATE TABLE command there's nothing to convert + $beginningOfQuery = substr($query, 0, 12); + $beginningOfQuery = strtoupper($beginningOfQuery); + + if (!in_array($beginningOfQuery, array('ALTER TABLE ', 'CREATE TABLE'))) + { + return $query; + } + + // Replace utf8mb4 with utf8 + return str_replace('utf8mb4', 'utf8', $query); + } + + /** + * Return the query string to create new Database. + * Each database driver, other than MySQL, need to override this member to return correct string. + * + * @param stdClass $options Object used to pass user and database name to database driver. + * This object must have "db_name" and "db_user" set. + * @param boolean $utf True if the database supports the UTF-8 character set. + * + * @return string The query that creates database + * + * @since 12.2 + */ + protected function getCreateDatabaseQuery($options, $utf) + { + if ($utf) + { + $charset = $this->utf8mb4 ? 'utf8mb4' : 'utf8'; + + return 'CREATE DATABASE ' . $this->quoteName($options->db_name) . ' CHARACTER SET `' . $charset . '`'; + } + + return 'CREATE DATABASE ' . $this->quoteName($options->db_name); + } + + /** + * Method to get the database collation in use by sampling a text field of a table in the database. + * + * @return mixed The collation in use by the database or boolean false if not supported. + * + * @since 11.1 + */ + abstract public function getCollation(); + + /** + * Method to get the database connection collation, as reported by the driver. If the connector doesn't support + * reporting this value please return an empty string. + * + * @return string + */ + public function getConnectionCollation() + { + return ''; + } + + /** + * Method that provides access to the underlying database connection. Useful for when you need to call a + * proprietary method such as postgresql's lo_* methods. + * + * @return resource The underlying database connection resource. + * + * @since 11.1 + */ + public function getConnection() + { + return $this->connection; + } + + /** + * Get the total number of SQL statements executed by the database driver. + * + * @return integer + * + * @since 11.1 + */ + public function getCount() + { + return $this->count; + } + + /** + * Gets the name of the database used by this connection. + * + * @return string + * + * @since 11.4 + */ + protected function getDatabase() + { + return $this->_database; + } + + /** + * Returns a PHP date() function compliant date format for the database driver. + * + * @return string The format string. + * + * @since 11.1 + */ + public function getDateFormat() + { + return 'Y-m-d H:i:s'; + } + + /** + * Get the database driver SQL statement log. + * + * @return array SQL statements executed by the database driver. + * + * @since 11.1 + */ + public function getLog() + { + return $this->log; + } + + /** + * Get the database driver SQL statement log. + * + * @return array SQL statements executed by the database driver. + * + * @since CMS 3.1.2 + */ + public function getTimings() + { + return $this->timings; + } + + /** + * Get the database driver SQL statement log. + * + * @return array SQL statements executed by the database driver. + * + * @since CMS 3.1.2 + */ + public function getCallStacks() + { + return $this->callStacks; + } + + /** + * Get the minimum supported database version. + * + * @return string The minimum version number for the database driver. + * + * @since 12.1 + */ + public function getMinimum() + { + return static::$dbMinimum; + } + + /** + * Get the null or zero representation of a timestamp for the database driver. + * + * @return string Null or zero representation of a timestamp. + * + * @since 11.1 + */ + public function getNullDate() + { + return $this->nullDate; + } + + /** + * Get the number of returned rows for the previous executed SQL statement. + * + * @param resource $cursor An optional database cursor resource to extract the row count from. + * + * @return integer The number of returned rows. + * + * @since 11.1 + */ + abstract public function getNumRows($cursor = null); + + /** + * Get the common table prefix for the database driver. + * + * @return string The common database table prefix. + * + * @since 11.1 + */ + public function getPrefix() + { + return $this->tablePrefix; + } + + /** + * Gets an exporter class object. + * + * @return FOFDatabaseExporter An exporter object. + * + * @since 12.1 + * @throws RuntimeException + */ + public function getExporter() + { + // Derive the class name from the driver. + $class = 'FOFDatabaseExporter' . ucfirst($this->name); + + // Make sure we have an exporter class for this driver. + if (!class_exists($class)) + { + // If it doesn't exist we are at an impasse so throw an exception. + throw new RuntimeException('Database Exporter not found.'); + } + + $o = new $class; + $o->setDbo($this); + + return $o; + } + + /** + * Gets an importer class object. + * + * @return FOFDatabaseImporter An importer object. + * + * @since 12.1 + * @throws RuntimeException + */ + public function getImporter() + { + // Derive the class name from the driver. + $class = 'FOFDatabaseImporter' . ucfirst($this->name); + + // Make sure we have an importer class for this driver. + if (!class_exists($class)) + { + // If it doesn't exist we are at an impasse so throw an exception. + throw new RuntimeException('Database Importer not found'); + } + + $o = new $class; + $o->setDbo($this); + + return $o; + } + + /** + * Get the name of the database driver. If $this->name is not set it will try guessing the driver name from the + * class name. + * + * @return string + * + * @since CMS 3.5.0 + */ + public function getName() + { + if (empty($this->name)) + { + $className = get_class($this); + $className = str_replace('FOFDatabaseDriver', '', $className); + $this->name = strtolower($className); + } + + return $this->name; + } + + /** + * Get the server family type, e.g. mysql, postgresql, oracle, sqlite, mssql. If $this->serverType is not set it + * will attempt guessing the server family type from the driver name. If this is not possible the driver name will + * be returned instead. + * + * @return string + * + * @since CMS 3.5.0 + */ + public function getServerType() + { + if (empty($this->serverType)) + { + $name = $this->getName(); + + if (stristr($name, 'mysql') !== false) + { + $this->serverType = 'mysql'; + } + elseif (stristr($name, 'postgre') !== false) + { + $this->serverType = 'postgresql'; + } + elseif (stristr($name, 'oracle') !== false) + { + $this->serverType = 'oracle'; + } + elseif (stristr($name, 'sqlite') !== false) + { + $this->serverType = 'sqlite'; + } + elseif (stristr($name, 'sqlsrv') !== false) + { + $this->serverType = 'mssql'; + } + elseif (stristr($name, 'mssql') !== false) + { + $this->serverType = 'mssql'; + } + else + { + $this->serverType = $name; + } + } + + return $this->serverType; + } + + /** + * Get the current query object or a new FOFDatabaseQuery object. + * + * @param boolean $new False to return the current query object, True to return a new FOFDatabaseQuery object. + * + * @return FOFDatabaseQuery The current query object or a new object extending the FOFDatabaseQuery class. + * + * @since 11.1 + * @throws RuntimeException + */ + public function getQuery($new = false) + { + if ($new) + { + // Derive the class name from the driver. + $class = 'FOFDatabaseQuery' . ucfirst($this->name); + + // Make sure we have a query class for this driver. + if (!class_exists($class)) + { + // If it doesn't exist we are at an impasse so throw an exception. + throw new RuntimeException('Database Query Class not found.'); + } + + return new $class($this); + } + else + { + return $this->sql; + } + } + + /** + * Get a new iterator on the current query. + * + * @param string $column An option column to use as the iterator key. + * @param string $class The class of object that is returned. + * + * @return FOFDatabaseIterator A new database iterator. + * + * @since 12.1 + * @throws RuntimeException + */ + public function getIterator($column = null, $class = 'stdClass') + { + // Derive the class name from the driver. + $iteratorClass = 'FOFDatabaseIterator' . ucfirst($this->name); + + // Make sure we have an iterator class for this driver. + if (!class_exists($iteratorClass)) + { + // If it doesn't exist we are at an impasse so throw an exception. + throw new RuntimeException(sprintf('class *%s* is not defined', $iteratorClass)); + } + + // Return a new iterator + return new $iteratorClass($this->execute(), $column, $class); + } + + /** + * Retrieves field information about the given tables. + * + * @param string $table The name of the database table. + * @param boolean $typeOnly True (default) to only return field types. + * + * @return array An array of fields by table. + * + * @since 11.1 + * @throws RuntimeException + */ + abstract public function getTableColumns($table, $typeOnly = true); + + /** + * Shows the table CREATE statement that creates the given tables. + * + * @param mixed $tables A table name or a list of table names. + * + * @return array A list of the create SQL for the tables. + * + * @since 11.1 + * @throws RuntimeException + */ + abstract public function getTableCreate($tables); + + /** + * Retrieves field information about the given tables. + * + * @param mixed $tables A table name or a list of table names. + * + * @return array An array of keys for the table(s). + * + * @since 11.1 + * @throws RuntimeException + */ + abstract public function getTableKeys($tables); + + /** + * Method to get an array of all tables in the database. + * + * @return array An array of all the tables in the database. + * + * @since 11.1 + * @throws RuntimeException + */ + abstract public function getTableList(); + + /** + * Determine whether or not the database engine supports UTF-8 character encoding. + * + * @return boolean True if the database engine supports UTF-8 character encoding. + * + * @since 11.1 + * @deprecated 12.3 (Platform) & 4.0 (CMS) - Use hasUTFSupport() instead + */ + public function getUTFSupport() + { + if (class_exists('JLog')) + { + JLog::add('FOFDatabaseDriver::getUTFSupport() is deprecated. Use FOFDatabaseDriver::hasUTFSupport() instead.', JLog::WARNING, 'deprecated'); + } + + return $this->hasUTFSupport(); + } + + /** + * Determine whether or not the database engine supports UTF-8 character encoding. + * + * @return boolean True if the database engine supports UTF-8 character encoding. + * + * @since 12.1 + */ + public function hasUTFSupport() + { + return $this->utf; + } + + /** + * Determine whether the database engine support the UTF-8 Multibyte (utf8mb4) character encoding. This applies to + * MySQL databases. + * + * @return boolean True if the database engine supports UTF-8 Multibyte. + * + * @since CMS 3.5.0 + */ + public function hasUTF8mb4Support() + { + return $this->utf8mb4; + } + + /** + * Get the version of the database connector + * + * @return string The database connector version. + * + * @since 11.1 + */ + abstract public function getVersion(); + + /** + * Method to get the auto-incremented value from the last INSERT statement. + * + * @return mixed The value of the auto-increment field from the last inserted row. + * + * @since 11.1 + */ + abstract public function insertid(); + + /** + * Inserts a row into a table based on an object's properties. + * + * @param string $table The name of the database table to insert into. + * @param object &$object A reference to an object whose public properties match the table fields. + * @param string $key The name of the primary key. If provided the object property is updated. + * + * @return boolean True on success. + * + * @since 11.1 + * @throws RuntimeException + */ + public function insertObject($table, &$object, $key = null) + { + $fields = array(); + $values = array(); + + // Iterate over the object variables to build the query fields and values. + foreach (get_object_vars($object) as $k => $v) + { + // Only process non-null scalars. + if (is_array($v) or is_object($v) or $v === null) + { + continue; + } + + // Ignore any internal fields. + if ($k[0] == '_') + { + continue; + } + + // Prepare and sanitize the fields and values for the database query. + $fields[] = $this->quoteName($k); + $values[] = $this->quote($v); + } + + // Create the base insert statement. + $query = $this->getQuery(true) + ->insert($this->quoteName($table)) + ->columns($fields) + ->values(implode(',', $values)); + + // Set the query and execute the insert. + $this->setQuery($query); + + if (!$this->execute()) + { + return false; + } + + // Update the primary key if it exists. + $id = $this->insertid(); + + if ($key && $id && is_string($key)) + { + $object->$key = $id; + } + + return true; + } + + /** + * Method to check whether the installed database version is supported by the database driver + * + * @return boolean True if the database version is supported + * + * @since 12.1 + */ + public function isMinimumVersion() + { + return version_compare($this->getVersion(), static::$dbMinimum) >= 0; + } + + /** + * Method to get the first row of the result set from the database query as an associative array + * of ['field_name' => 'row_value']. + * + * @return mixed The return value or null if the query failed. + * + * @since 11.1 + * @throws RuntimeException + */ + public function loadAssoc() + { + $this->connect(); + + $ret = null; + + // Execute the query and get the result set cursor. + if (!($cursor = $this->execute())) + { + return null; + } + + // Get the first row from the result set as an associative array. + if ($array = $this->fetchAssoc($cursor)) + { + $ret = $array; + } + + // Free up system resources and return. + $this->freeResult($cursor); + + return $ret; + } + + /** + * Method to get an array of the result set rows from the database query where each row is an associative array + * of ['field_name' => 'row_value']. The array of rows can optionally be keyed by a field name, but defaults to + * a sequential numeric array. + * + * NOTE: Choosing to key the result array by a non-unique field name can result in unwanted + * behavior and should be avoided. + * + * @param string $key The name of a field on which to key the result array. + * @param string $column An optional column name. Instead of the whole row, only this column value will be in + * the result array. + * + * @return mixed The return value or null if the query failed. + * + * @since 11.1 + * @throws RuntimeException + */ + public function loadAssocList($key = null, $column = null) + { + $this->connect(); + + $array = array(); + + // Execute the query and get the result set cursor. + if (!($cursor = $this->execute())) + { + return null; + } + + // Get all of the rows from the result set. + while ($row = $this->fetchAssoc($cursor)) + { + $value = ($column) ? (isset($row[$column]) ? $row[$column] : $row) : $row; + + if ($key) + { + $array[$row[$key]] = $value; + } + else + { + $array[] = $value; + } + } + + // Free up system resources and return. + $this->freeResult($cursor); + + return $array; + } + + /** + * Method to get an array of values from the $offset field in each row of the result set from + * the database query. + * + * @param integer $offset The row offset to use to build the result array. + * + * @return mixed The return value or null if the query failed. + * + * @since 11.1 + * @throws RuntimeException + */ + public function loadColumn($offset = 0) + { + $this->connect(); + + $array = array(); + + // Execute the query and get the result set cursor. + if (!($cursor = $this->execute())) + { + return null; + } + + // Get all of the rows from the result set as arrays. + while ($row = $this->fetchArray($cursor)) + { + $array[] = $row[$offset]; + } + + // Free up system resources and return. + $this->freeResult($cursor); + + return $array; + } + + /** + * Method to get the next row in the result set from the database query as an object. + * + * @param string $class The class name to use for the returned row object. + * + * @return mixed The result of the query as an array, false if there are no more rows. + * + * @since 11.1 + * @throws RuntimeException + * @deprecated 12.3 (Platform) & 4.0 (CMS) - Use getIterator() instead + */ + public function loadNextObject($class = 'stdClass') + { + if (class_exists('JLog')) + { + JLog::add(__METHOD__ . '() is deprecated. Use FOFDatabaseDriver::getIterator() instead.', JLog::WARNING, 'deprecated'); + } + + $this->connect(); + + static $cursor = null; + + // Execute the query and get the result set cursor. + if ( is_null($cursor) ) + { + if (!($cursor = $this->execute())) + { + return $this->errorNum ? null : false; + } + } + + // Get the next row from the result set as an object of type $class. + if ($row = $this->fetchObject($cursor, $class)) + { + return $row; + } + + // Free up system resources and return. + $this->freeResult($cursor); + $cursor = null; + + return false; + } + + /** + * Method to get the next row in the result set from the database query as an array. + * + * @return mixed The result of the query as an array, false if there are no more rows. + * + * @since 11.1 + * @throws RuntimeException + * @deprecated 4.0 (CMS) Use FOFDatabaseDriver::getIterator() instead + */ + public function loadNextRow() + { + if (class_exists('JLog')) + { + JLog::add(__METHOD__ . '() is deprecated. Use FOFDatabaseDriver::getIterator() instead.', JLog::WARNING, 'deprecated'); + } + + $this->connect(); + + static $cursor = null; + + // Execute the query and get the result set cursor. + if ( is_null($cursor) ) + { + if (!($cursor = $this->execute())) + { + return $this->errorNum ? null : false; + } + } + + // Get the next row from the result set as an object of type $class. + if ($row = $this->fetchArray($cursor)) + { + return $row; + } + + // Free up system resources and return. + $this->freeResult($cursor); + $cursor = null; + + return false; + } + + /** + * Method to get the first row of the result set from the database query as an object. + * + * @param string $class The class name to use for the returned row object. + * + * @return mixed The return value or null if the query failed. + * + * @since 11.1 + * @throws RuntimeException + */ + public function loadObject($class = 'stdClass') + { + $this->connect(); + + $ret = null; + + // Execute the query and get the result set cursor. + if (!($cursor = $this->execute())) + { + return null; + } + + // Get the first row from the result set as an object of type $class. + if ($object = $this->fetchObject($cursor, $class)) + { + $ret = $object; + } + + // Free up system resources and return. + $this->freeResult($cursor); + + return $ret; + } + + /** + * Method to get an array of the result set rows from the database query where each row is an object. The array + * of objects can optionally be keyed by a field name, but defaults to a sequential numeric array. + * + * NOTE: Choosing to key the result array by a non-unique field name can result in unwanted + * behavior and should be avoided. + * + * @param string $key The name of a field on which to key the result array. + * @param string $class The class name to use for the returned row objects. + * + * @return mixed The return value or null if the query failed. + * + * @since 11.1 + * @throws RuntimeException + */ + public function loadObjectList($key = '', $class = 'stdClass') + { + $this->connect(); + + $array = array(); + + // Execute the query and get the result set cursor. + if (!($cursor = $this->execute())) + { + return null; + } + + // Get all of the rows from the result set as objects of type $class. + while ($row = $this->fetchObject($cursor, $class)) + { + if ($key) + { + $array[$row->$key] = $row; + } + else + { + $array[] = $row; + } + } + + // Free up system resources and return. + $this->freeResult($cursor); + + return $array; + } + + /** + * Method to get the first field of the first row of the result set from the database query. + * + * @return mixed The return value or null if the query failed. + * + * @since 11.1 + * @throws RuntimeException + */ + public function loadResult() + { + $this->connect(); + + $ret = null; + + // Execute the query and get the result set cursor. + if (!($cursor = $this->execute())) + { + return null; + } + + // Get the first row from the result set as an array. + if ($row = $this->fetchArray($cursor)) + { + $ret = $row[0]; + } + + // Free up system resources and return. + $this->freeResult($cursor); + + return $ret; + } + + /** + * Method to get the first row of the result set from the database query as an array. Columns are indexed + * numerically so the first column in the result set would be accessible via $row[0], etc. + * + * @return mixed The return value or null if the query failed. + * + * @since 11.1 + * @throws RuntimeException + */ + public function loadRow() + { + $this->connect(); + + $ret = null; + + // Execute the query and get the result set cursor. + if (!($cursor = $this->execute())) + { + return null; + } + + // Get the first row from the result set as an array. + if ($row = $this->fetchArray($cursor)) + { + $ret = $row; + } + + // Free up system resources and return. + $this->freeResult($cursor); + + return $ret; + } + + /** + * Method to get an array of the result set rows from the database query where each row is an array. The array + * of objects can optionally be keyed by a field offset, but defaults to a sequential numeric array. + * + * NOTE: Choosing to key the result array by a non-unique field can result in unwanted + * behavior and should be avoided. + * + * @param string $key The name of a field on which to key the result array. + * + * @return mixed The return value or null if the query failed. + * + * @since 11.1 + * @throws RuntimeException + */ + public function loadRowList($key = null) + { + $this->connect(); + + $array = array(); + + // Execute the query and get the result set cursor. + if (!($cursor = $this->execute())) + { + return null; + } + + // Get all of the rows from the result set as arrays. + while ($row = $this->fetchArray($cursor)) + { + if ($key !== null) + { + $array[$row[$key]] = $row; + } + else + { + $array[] = $row; + } + } + + // Free up system resources and return. + $this->freeResult($cursor); + + return $array; + } + + /** + * Locks a table in the database. + * + * @param string $tableName The name of the table to unlock. + * + * @return FOFDatabaseDriver Returns this object to support chaining. + * + * @since 11.4 + * @throws RuntimeException + */ + public abstract function lockTable($tableName); + + /** + * Quotes and optionally escapes a string to database requirements for use in database queries. + * + * @param mixed $text A string or an array of strings to quote. + * @param boolean $escape True (default) to escape the string, false to leave it unchanged. + * + * @return string The quoted input string. + * + * @note Accepting an array of strings was added in 12.3. + * @since 11.1 + */ + public function quote($text, $escape = true) + { + if (is_array($text)) + { + foreach ($text as $k => $v) + { + $text[$k] = $this->quote($v, $escape); + } + + return $text; + } + else + { + return '\'' . ($escape ? $this->escape($text) : $text) . '\''; + } + } + + /** + * Wrap an SQL statement identifier name such as column, table or database names in quotes to prevent injection + * risks and reserved word conflicts. + * + * @param mixed $name The identifier name to wrap in quotes, or an array of identifier names to wrap in quotes. + * Each type supports dot-notation name. + * @param mixed $as The AS query part associated to $name. It can be string or array, in latter case it has to be + * same length of $name; if is null there will not be any AS part for string or array element. + * + * @return mixed The quote wrapped name, same type of $name. + * + * @since 11.1 + */ + public function quoteName($name, $as = null) + { + if (is_string($name)) + { + $quotedName = $this->quoteNameStr(explode('.', $name)); + + $quotedAs = ''; + + if (!is_null($as)) + { + settype($as, 'array'); + $quotedAs .= ' AS ' . $this->quoteNameStr($as); + } + + return $quotedName . $quotedAs; + } + else + { + $fin = array(); + + if (is_null($as)) + { + foreach ($name as $str) + { + $fin[] = $this->quoteName($str); + } + } + elseif (is_array($name) && (count($name) == count($as))) + { + $count = count($name); + + for ($i = 0; $i < $count; $i++) + { + $fin[] = $this->quoteName($name[$i], $as[$i]); + } + } + + return $fin; + } + } + + /** + * Quote strings coming from quoteName call. + * + * @param array $strArr Array of strings coming from quoteName dot-explosion. + * + * @return string Dot-imploded string of quoted parts. + * + * @since 11.3 + */ + protected function quoteNameStr($strArr) + { + $parts = array(); + $q = $this->nameQuote; + + foreach ($strArr as $part) + { + if (is_null($part)) + { + continue; + } + + if (strlen($q) == 1) + { + $parts[] = $q . $part . $q; + } + else + { + $parts[] = $q[0] . $part . $q[1]; + } + } + + return implode('.', $parts); + } + + /** + * This function replaces a string identifier $prefix with the string held is the + * tablePrefix class variable. + * + * @param string $sql The SQL statement to prepare. + * @param string $prefix The common table prefix. + * + * @return string The processed SQL statement. + * + * @since 11.1 + */ + public function replacePrefix($sql, $prefix = '#__') + { + $startPos = 0; + $literal = ''; + + $sql = trim($sql); + $n = strlen($sql); + + while ($startPos < $n) + { + $ip = strpos($sql, $prefix, $startPos); + + if ($ip === false) + { + break; + } + + $j = strpos($sql, "'", $startPos); + $k = strpos($sql, '"', $startPos); + + if (($k !== false) && (($k < $j) || ($j === false))) + { + $quoteChar = '"'; + $j = $k; + } + else + { + $quoteChar = "'"; + } + + if ($j === false) + { + $j = $n; + } + + $literal .= str_replace($prefix, $this->tablePrefix, substr($sql, $startPos, $j - $startPos)); + $startPos = $j; + + $j = $startPos + 1; + + if ($j >= $n) + { + break; + } + + // Quote comes first, find end of quote + while (true) + { + $k = strpos($sql, $quoteChar, $j); + $escaped = false; + + if ($k === false) + { + break; + } + + $l = $k - 1; + + while ($l >= 0 && $sql[$l] == '\\') + { + $l--; + $escaped = !$escaped; + } + + if ($escaped) + { + $j = $k + 1; + continue; + } + + break; + } + + if ($k === false) + { + // Error in the query - no end quote; ignore it + break; + } + + $literal .= substr($sql, $startPos, $k - $startPos + 1); + $startPos = $k + 1; + } + + if ($startPos < $n) + { + $literal .= substr($sql, $startPos, $n - $startPos); + } + + return $literal; + } + + /** + * Renames a table in the database. + * + * @param string $oldTable The name of the table to be renamed + * @param string $newTable The new name for the table. + * @param string $backup Table prefix + * @param string $prefix For the table - used to rename constraints in non-mysql databases + * + * @return FOFDatabaseDriver Returns this object to support chaining. + * + * @since 11.4 + * @throws RuntimeException + */ + public abstract function renameTable($oldTable, $newTable, $backup = null, $prefix = null); + + /** + * Select a database for use. + * + * @param string $database The name of the database to select for use. + * + * @return boolean True if the database was successfully selected. + * + * @since 11.1 + * @throws RuntimeException + */ + abstract public function select($database); + + /** + * Sets the database debugging state for the driver. + * + * @param boolean $level True to enable debugging. + * + * @return boolean The old debugging level. + * + * @since 11.1 + */ + public function setDebug($level) + { + $previous = $this->debug; + $this->debug = (bool) $level; + + return $previous; + } + + /** + * Sets the SQL statement string for later execution. + * + * @param mixed $query The SQL statement to set either as a FOFDatabaseQuery object or a string. + * @param integer $offset The affected row offset to set. + * @param integer $limit The maximum affected rows to set. + * + * @return FOFDatabaseDriver This object to support method chaining. + * + * @since 11.1 + */ + public function setQuery($query, $offset = 0, $limit = 0) + { + $this->sql = $query; + + if ($query instanceof FOFDatabaseQueryLimitable) + { + if (!$limit && $query->limit) + { + $limit = $query->limit; + } + + if (!$offset && $query->offset) + { + $offset = $query->offset; + } + + $query->setLimit($limit, $offset); + } + else + { + $this->limit = (int) max(0, $limit); + $this->offset = (int) max(0, $offset); + } + + return $this; + } + + /** + * Set the connection to use UTF-8 character encoding. + * + * @return boolean True on success. + * + * @since 11.1 + */ + abstract public function setUtf(); + + /** + * Method to commit a transaction. + * + * @param boolean $toSavepoint If true, commit to the last savepoint. + * + * @return void + * + * @since 11.1 + * @throws RuntimeException + */ + abstract public function transactionCommit($toSavepoint = false); + + /** + * Method to roll back a transaction. + * + * @param boolean $toSavepoint If true, rollback to the last savepoint. + * + * @return void + * + * @since 11.1 + * @throws RuntimeException + */ + abstract public function transactionRollback($toSavepoint = false); + + /** + * Method to initialize a transaction. + * + * @param boolean $asSavepoint If true and a transaction is already active, a savepoint will be created. + * + * @return void + * + * @since 11.1 + * @throws RuntimeException + */ + abstract public function transactionStart($asSavepoint = false); + + /** + * Method to truncate a table. + * + * @param string $table The table to truncate + * + * @return void + * + * @since 11.3 + * @throws RuntimeException + */ + public function truncateTable($table) + { + $this->setQuery('TRUNCATE TABLE ' . $this->quoteName($table)); + $this->execute(); + } + + /** + * Updates a row in a table based on an object's properties. + * + * @param string $table The name of the database table to update. + * @param object &$object A reference to an object whose public properties match the table fields. + * @param array $key The name of the primary key. + * @param boolean $nulls True to update null fields or false to ignore them. + * + * @return boolean True on success. + * + * @since 11.1 + * @throws RuntimeException + */ + public function updateObject($table, &$object, $key, $nulls = false) + { + $fields = array(); + $where = array(); + + if (is_string($key)) + { + $key = array($key); + } + + if (is_object($key)) + { + $key = (array) $key; + } + + // Create the base update statement. + $statement = 'UPDATE ' . $this->quoteName($table) . ' SET %s WHERE %s'; + + // Iterate over the object variables to build the query fields/value pairs. + foreach (get_object_vars($object) as $k => $v) + { + // Only process scalars that are not internal fields. + if (is_array($v) or is_object($v) or $k[0] == '_') + { + continue; + } + + // Set the primary key to the WHERE clause instead of a field to update. + if (in_array($k, $key)) + { + $where[] = $this->quoteName($k) . '=' . $this->quote($v); + continue; + } + + // Prepare and sanitize the fields and values for the database query. + if ($v === null) + { + // If the value is null and we want to update nulls then set it. + if ($nulls) + { + $val = 'NULL'; + } + // If the value is null and we do not want to update nulls then ignore this field. + else + { + continue; + } + } + // The field is not null so we prep it for update. + else + { + $val = $this->quote($v); + } + + // Add the field to be updated. + $fields[] = $this->quoteName($k) . '=' . $val; + } + + // We don't have any fields to update. + if (empty($fields)) + { + return true; + } + + // Set the query and execute the update. + $this->setQuery(sprintf($statement, implode(",", $fields), implode(' AND ', $where))); + + return $this->execute(); + } + + /** + * Execute the SQL statement. + * + * @return mixed A database cursor resource on success, boolean false on failure. + * + * @since 12.1 + * @throws RuntimeException + */ + abstract public function execute(); + + /** + * Unlocks tables in the database. + * + * @return FOFDatabaseDriver Returns this object to support chaining. + * + * @since 11.4 + * @throws RuntimeException + */ + public abstract function unlockTables(); +} diff --git a/Sites/pages/libraries/fof/database/driver/joomla.php b/Sites/pages/libraries/fof/database/driver/joomla.php new file mode 100644 index 00000000..cfffe64f --- /dev/null +++ b/Sites/pages/libraries/fof/database/driver/joomla.php @@ -0,0 +1,779 @@ +dbo = JFactory::getDbo(); + + $reflection = new ReflectionClass($this->dbo); + + try + { + $refProp = $reflection->getProperty('nameQuote'); + $refProp->setAccessible(true); + $this->nameQuote = $refProp->getValue($this->dbo); + } + catch (Exception $e) + { + $this->nameQuote = '`'; + } + } + + public function close() + { + if (method_exists($this->dbo, 'close')) + { + $this->dbo->close(); + } + elseif (method_exists($this->dbo, 'disconnect')) + { + $this->dbo->disconnect(); + } + } + + public function disconnect() + { + $this->close(); + } + + public function open() + { + if (method_exists($this->dbo, 'open')) + { + $this->dbo->open(); + } + elseif (method_exists($this->dbo, 'connect')) + { + $this->dbo->connect(); + } + } + + public function connect() + { + $this->open(); + } + + public function connected() + { + if (method_exists($this->dbo, 'connected')) + { + return $this->dbo->connected(); + } + + return true; + } + + public function escape($text, $extra = false) + { + return $this->dbo->escape($text, $extra); + } + + public function execute() + { + if (method_exists($this->dbo, 'execute')) + { + return $this->dbo->execute(); + } + + return $this->dbo->query(); + } + + public function getAffectedRows() + { + if (method_exists($this->dbo, 'getAffectedRows')) + { + return $this->dbo->getAffectedRows(); + } + + return 0; + } + + public function getCollation() + { + if (method_exists($this->dbo, 'getCollation')) + { + return $this->dbo->getCollation(); + } + + return 'utf8_general_ci'; + } + + public function getConnection() + { + if (method_exists($this->dbo, 'getConnection')) + { + return $this->dbo->getConnection(); + } + + return null; + } + + public function getCount() + { + if (method_exists($this->dbo, 'getCount')) + { + return $this->dbo->getCount(); + } + + return 0; + } + + public function getDateFormat() + { + if (method_exists($this->dbo, 'getDateFormat')) + { + return $this->dbo->getDateFormat(); + } + + return 'Y-m-d H:i:s';; + } + + public function getMinimum() + { + if (method_exists($this->dbo, 'getMinimum')) + { + return $this->dbo->getMinimum(); + } + + return '5.0.40'; + } + + public function getNullDate() + { + if (method_exists($this->dbo, 'getNullDate')) + { + return $this->dbo->getNullDate(); + } + + return '0000-00-00 00:00:00'; + } + + public function getNumRows($cursor = null) + { + if (method_exists($this->dbo, 'getNumRows')) + { + return $this->dbo->getNumRows($cursor); + } + + return 0; + } + + public function getQuery($new = false) + { + if (method_exists($this->dbo, 'getQuery')) + { + return $this->dbo->getQuery($new); + } + + return null; + } + + public function getTableColumns($table, $typeOnly = true) + { + if (method_exists($this->dbo, 'getTableColumns')) + { + return $this->dbo->getTableColumns($table, $typeOnly); + } + + $result = $this->dbo->getTableFields(array($table), $typeOnly); + + return $result[$table]; + } + + public function getTableKeys($tables) + { + if (method_exists($this->dbo, 'getTableKeys')) + { + return $this->dbo->getTableKeys($tables); + } + + return array(); + } + + public function getTableList() + { + if (method_exists($this->dbo, 'getTableList')) + { + return $this->dbo->getTableList(); + } + + return array(); + } + + public function getVersion() + { + if (method_exists($this->dbo, 'getVersion')) + { + return $this->dbo->getVersion(); + } + + return '5.0.40'; + } + + public function insertid() + { + if (method_exists($this->dbo, 'insertid')) + { + return $this->dbo->insertid(); + } + + return null; + } + + public function insertObject($table, &$object, $key = null) + { + if (method_exists($this->dbo, 'insertObject')) + { + return $this->dbo->insertObject($table, $object, $key); + } + + return null; + } + + public function loadAssoc() + { + if (method_exists($this->dbo, 'loadAssoc')) + { + return $this->dbo->loadAssoc(); + } + + return null; + } + + public function loadAssocList($key = null, $column = null) + { + if (method_exists($this->dbo, 'loadAssocList')) + { + return $this->dbo->loadAssocList($key, $column); + } + + return null; + } + + public function loadObject($class = 'stdClass') + { + if (method_exists($this->dbo, 'loadObject')) + { + return $this->dbo->loadObject($class); + } + + return null; + } + + public function loadObjectList($key = '', $class = 'stdClass') + { + if (method_exists($this->dbo, 'loadObjectList')) + { + return $this->dbo->loadObjectList($key, $class); + } + + return null; + } + + public function loadResult() + { + if (method_exists($this->dbo, 'loadResult')) + { + return $this->dbo->loadResult(); + } + + return null; + } + + public function loadRow() + { + if (method_exists($this->dbo, 'loadRow')) + { + return $this->dbo->loadRow(); + } + + return null; + } + + public function loadRowList($key = null) + { + if (method_exists($this->dbo, 'loadRowList')) + { + return $this->dbo->loadRowList($key); + } + + return null; + } + + public function lockTable($tableName) + { + if (method_exists($this->dbo, 'lockTable')) + { + return $this->dbo->lockTable($this); + } + + return $this; + } + + public function quote($text, $escape = true) + { + if (method_exists($this->dbo, 'quote')) + { + return $this->dbo->quote($text, $escape); + } + + return $text; + } + + public function select($database) + { + if (method_exists($this->dbo, 'select')) + { + return $this->dbo->select($database); + } + + return false; + } + + public function setQuery($query, $offset = 0, $limit = 0) + { + if (method_exists($this->dbo, 'setQuery')) + { + return $this->dbo->setQuery($query, $offset, $limit); + } + + return false; + } + + public function transactionCommit($toSavepoint = false) + { + if (method_exists($this->dbo, 'transactionCommit')) + { + $this->dbo->transactionCommit($toSavepoint); + } + } + + public function transactionRollback($toSavepoint = false) + { + if (method_exists($this->dbo, 'transactionRollback')) + { + $this->dbo->transactionRollback($toSavepoint); + } + } + + public function transactionStart($asSavepoint = false) + { + if (method_exists($this->dbo, 'transactionStart')) + { + $this->dbo->transactionStart($asSavepoint); + } + } + + public function unlockTables() + { + if (method_exists($this->dbo, 'unlockTables')) + { + return $this->dbo->unlockTables(); + } + + return $this; + } + + public function updateObject($table, &$object, $key, $nulls = false) + { + if (method_exists($this->dbo, 'updateObject')) + { + return $this->dbo->updateObject($table, $object, $key, $nulls); + } + + return false; + } + + public function getLog() + { + if (method_exists($this->dbo, 'getLog')) + { + return $this->dbo->getLog(); + } + + return array(); + } + + public function dropTable($table, $ifExists = true) + { + if (method_exists($this->dbo, 'dropTable')) + { + return $this->dbo->dropTable($table, $ifExists); + } + + return $this; + } + + public function getTableCreate($tables) + { + if (method_exists($this->dbo, 'getTableCreate')) + { + return $this->dbo->getTableCreate($tables); + } + + return array(); + } + + public function renameTable($oldTable, $newTable, $backup = null, $prefix = null) + { + if (method_exists($this->dbo, 'renameTable')) + { + return $this->dbo->renameTable($oldTable, $newTable, $backup, $prefix); + } + + return $this; + } + + public function setUtf() + { + if (method_exists($this->dbo, 'setUtf')) + { + return $this->dbo->setUtf(); + } + + return false; + } + + + protected function freeResult($cursor = null) + { + return false; + } + + /** + * Method to get an array of values from the $offset field in each row of the result set from + * the database query. + * + * @param integer $offset The row offset to use to build the result array. + * + * @return mixed The return value or null if the query failed. + * + * @since 11.1 + * @throws RuntimeException + */ + public function loadColumn($offset = 0) + { + if (method_exists($this->dbo, 'loadColumn')) + { + return $this->dbo->loadColumn($offset); + } + + return $this->dbo->loadResultArray($offset); + } + + /** + * Wrap an SQL statement identifier name such as column, table or database names in quotes to prevent injection + * risks and reserved word conflicts. + * + * @param mixed $name The identifier name to wrap in quotes, or an array of identifier names to wrap in quotes. + * Each type supports dot-notation name. + * @param mixed $as The AS query part associated to $name. It can be string or array, in latter case it has to be + * same length of $name; if is null there will not be any AS part for string or array element. + * + * @return mixed The quote wrapped name, same type of $name. + * + * @since 11.1 + */ + public function quoteName($name, $as = null) + { + if (is_string($name)) + { + $quotedName = $this->quoteNameStr(explode('.', $name)); + + $quotedAs = ''; + + if (!is_null($as)) + { + settype($as, 'array'); + $quotedAs .= ' AS ' . $this->quoteNameStr($as); + } + + return $quotedName . $quotedAs; + } + else + { + $fin = array(); + + if (is_null($as)) + { + foreach ($name as $str) + { + $fin[] = $this->quoteName($str); + } + } + elseif (is_array($name) && (count($name) == count($as))) + { + $count = count($name); + + for ($i = 0; $i < $count; $i++) + { + $fin[] = $this->quoteName($name[$i], $as[$i]); + } + } + + return $fin; + } + } + + /** + * Quote strings coming from quoteName call. + * + * @param array $strArr Array of strings coming from quoteName dot-explosion. + * + * @return string Dot-imploded string of quoted parts. + * + * @since 11.3 + */ + protected function quoteNameStr($strArr) + { + $parts = array(); + $q = $this->nameQuote; + + foreach ($strArr as $part) + { + if (is_null($part)) + { + continue; + } + + if (strlen($q) == 1) + { + $parts[] = $q . $part . $q; + } + else + { + $parts[] = $q[0] . $part . $q[1]; + } + } + + return implode('.', $parts); + } + + /** + * Gets the error message from the database connection. + * + * @param boolean $escaped True to escape the message string for use in JavaScript. + * + * @return string The error message for the most recent query. + * + * @since 11.1 + */ + public function getErrorMsg($escaped = false) + { + if (method_exists($this->dbo, 'getErrorMsg')) + { + $errorMessage = $this->dbo->getErrorMsg(); + } + else + { + $errorMessage = $this->errorMsg; + } + + if ($escaped) + { + return addslashes($errorMessage); + } + + return $errorMessage; + } + + /** + * Gets the error number from the database connection. + * + * @return integer The error number for the most recent query. + * + * @since 11.1 + * @deprecated 13.3 (Platform) & 4.0 (CMS) + */ + public function getErrorNum() + { + if (method_exists($this->dbo, 'getErrorNum')) + { + $errorNum = $this->dbo->getErrorNum(); + } + else + { + $errorNum = $this->getErrorNum; + } + + return $errorNum; + } + + /** + * Return the most recent error message for the database connector. + * + * @param boolean $showSQL True to display the SQL statement sent to the database as well as the error. + * + * @return string The error message for the most recent query. + */ + public function stderr($showSQL = false) + { + if (method_exists($this->dbo, 'stderr')) + { + return $this->dbo->stderr($showSQL); + } + + return parent::stderr($showSQL); + } + + /** + * Magic method to proxy all calls to the loaded database driver object + */ + public function __call($name, array $arguments) + { + if (is_null($this->dbo)) + { + throw new Exception('FOF database driver is not loaded'); + } + + if (method_exists($this->dbo, $name) || in_array($name, array('q', 'nq', 'qn', 'query'))) + { + switch ($name) + { + case 'execute': + $name = 'query'; + break; + + case 'q': + $name = 'quote'; + break; + + case 'qn': + case 'nq': + switch (count($arguments)) + { + case 0 : + $result = $this->quoteName(); + break; + case 1 : + $result = $this->quoteName($arguments[0]); + break; + case 2: + default: + $result = $this->quoteName($arguments[0], $arguments[1]); + break; + } + return $result; + + break; + } + + switch (count($arguments)) + { + case 0 : + $result = $this->dbo->$name(); + break; + case 1 : + $result = $this->dbo->$name($arguments[0]); + break; + case 2: + $result = $this->dbo->$name($arguments[0], $arguments[1]); + break; + case 3: + $result = $this->dbo->$name($arguments[0], $arguments[1], $arguments[2]); + break; + case 4: + $result = $this->dbo->$name($arguments[0], $arguments[1], $arguments[2], $arguments[3]); + break; + case 5: + $result = $this->dbo->$name($arguments[0], $arguments[1], $arguments[2], $arguments[3], $arguments[4]); + break; + default: + // Resort to using call_user_func_array for many segments + $result = call_user_func_array(array($this->dbo, $name), $arguments); + } + + if (class_exists('JDatabase') && is_object($result) && ($result instanceof JDatabase)) + { + return $this; + } + + return $result; + } + else + { + throw new \Exception('Method ' . $name . ' not found in FOFDatabase'); + } + } + + public function __get($name) + { + if (isset($this->dbo->$name) || property_exists($this->dbo, $name)) + { + return $this->dbo->$name; + } + else + { + $this->dbo->$name = null; + user_error('Database driver does not support property ' . $name); + } + } + + public function __set($name, $value) + { + if (isset($this->dbo->name) || property_exists($this->dbo, $name)) + { + $this->dbo->$name = $value; + } + else + { + $this->dbo->$name = null; + user_error('Database driver not support property ' . $name); + } + } +} diff --git a/Sites/pages/libraries/fof/database/driver/mysql.php b/Sites/pages/libraries/fof/database/driver/mysql.php new file mode 100644 index 00000000..5e35879f --- /dev/null +++ b/Sites/pages/libraries/fof/database/driver/mysql.php @@ -0,0 +1,577 @@ += 7) + { + throw new RuntimeException( + 'This driver is unsupported in PHP 7, please use the MySQLi or PDO MySQL driver instead.' + ); + } + + // Get some basic values from the options. + $options['host'] = (isset($options['host'])) ? $options['host'] : 'localhost'; + $options['user'] = (isset($options['user'])) ? $options['user'] : 'root'; + $options['password'] = (isset($options['password'])) ? $options['password'] : ''; + $options['database'] = (isset($options['database'])) ? $options['database'] : ''; + $options['select'] = (isset($options['select'])) ? (bool) $options['select'] : true; + + // Finalize initialisation. + parent::__construct($options); + } + + /** + * Destructor. + * + * @since 12.1 + */ + public function __destruct() + { + $this->disconnect(); + } + + /** + * Connects to the database if needed. + * + * @return void Returns void if the database connected successfully. + * + * @since 12.1 + * @throws RuntimeException + */ + public function connect() + { + if ($this->connection) + { + return; + } + + // Make sure the MySQL extension for PHP is installed and enabled. + if (!self::isSupported()) + { + throw new RuntimeException('Could not connect to MySQL.'); + } + + // Attempt to connect to the server. + if (!($this->connection = @ mysql_connect($this->options['host'], $this->options['user'], $this->options['password'], true))) + { + throw new RuntimeException('Could not connect to MySQL.'); + } + + // Set sql_mode to non_strict mode + mysql_query("SET @@SESSION.sql_mode = '';", $this->connection); + + // If auto-select is enabled select the given database. + if ($this->options['select'] && !empty($this->options['database'])) + { + $this->select($this->options['database']); + } + + // Pre-populate the UTF-8 Multibyte compatibility flag based on server version + $this->utf8mb4 = $this->serverClaimsUtf8mb4Support(); + + // Set the character set (needed for MySQL 4.1.2+). + $this->utf = $this->setUtf(); + + // Turn MySQL profiling ON in debug mode: + if ($this->debug && $this->hasProfiling()) + { + mysql_query("SET profiling = 1;", $this->connection); + } + } + + /** + * Disconnects the database. + * + * @return void + * + * @since 12.1 + */ + public function disconnect() + { + // Close the connection. + if (is_resource($this->connection)) + { + foreach ($this->disconnectHandlers as $h) + { + call_user_func_array($h, array( &$this)); + } + + mysql_close($this->connection); + } + + $this->connection = null; + } + + /** + * Method to escape a string for usage in an SQL statement. + * + * @param string $text The string to be escaped. + * @param boolean $extra Optional parameter to provide extra escaping. + * + * @return string The escaped string. + * + * @since 12.1 + */ + public function escape($text, $extra = false) + { + $this->connect(); + + $result = mysql_real_escape_string($text, $this->getConnection()); + + if ($extra) + { + $result = addcslashes($result, '%_'); + } + + return $result; + } + + /** + * Test to see if the MySQL connector is available. + * + * @return boolean True on success, false otherwise. + * + * @since 12.1 + */ + public static function isSupported() + { + return (function_exists('mysql_connect')); + } + + /** + * Determines if the connection to the server is active. + * + * @return boolean True if connected to the database engine. + * + * @since 12.1 + */ + public function connected() + { + if (is_resource($this->connection)) + { + return @mysql_ping($this->connection); + } + + return false; + } + + /** + * Get the number of affected rows by the last INSERT, UPDATE, REPLACE or DELETE for the previous executed SQL statement. + * + * @return integer The number of affected rows. + * + * @since 12.1 + */ + public function getAffectedRows() + { + $this->connect(); + + return mysql_affected_rows($this->connection); + } + + /** + * Get the number of returned rows for the previous executed SQL statement. + * This command is only valid for statements like SELECT or SHOW that return an actual result set. + * To retrieve the number of rows affected by a INSERT, UPDATE, REPLACE or DELETE query, use getAffectedRows(). + * + * @param resource $cursor An optional database cursor resource to extract the row count from. + * + * @return integer The number of returned rows. + * + * @since 12.1 + */ + public function getNumRows($cursor = null) + { + $this->connect(); + + return mysql_num_rows($cursor ? $cursor : $this->cursor); + } + + /** + * Get the version of the database connector. + * + * @return string The database connector version. + * + * @since 12.1 + */ + public function getVersion() + { + $this->connect(); + + return mysql_get_server_info($this->connection); + } + + /** + * Method to get the auto-incremented value from the last INSERT statement. + * + * @return integer The value of the auto-increment field from the last inserted row. + * + * @since 12.1 + */ + public function insertid() + { + $this->connect(); + + return mysql_insert_id($this->connection); + } + + /** + * Execute the SQL statement. + * + * @return mixed A database cursor resource on success, boolean false on failure. + * + * @since 12.1 + * @throws RuntimeException + */ + public function execute() + { + $this->connect(); + + if (!is_resource($this->connection)) + { + if (class_exists('JLog')) + { + JLog::add(JText::sprintf('JLIB_DATABASE_QUERY_FAILED', $this->errorNum, $this->errorMsg), JLog::ERROR, 'database'); + } + throw new RuntimeException($this->errorMsg, $this->errorNum); + } + + // Take a local copy so that we don't modify the original query and cause issues later + $query = $this->replacePrefix((string) $this->sql); + + if (!($this->sql instanceof FOFDatabaseQuery) && ($this->limit > 0 || $this->offset > 0)) + { + $query .= ' LIMIT ' . $this->offset . ', ' . $this->limit; + } + + // Increment the query counter. + $this->count++; + + // Reset the error values. + $this->errorNum = 0; + $this->errorMsg = ''; + + // If debugging is enabled then let's log the query. + if ($this->debug) + { + // Add the query to the object queue. + $this->log[] = $query; + + if (class_exists('JLog')) + { + JLog::add($query, JLog::DEBUG, 'databasequery'); + } + + $this->timings[] = microtime(true); + } + + // Execute the query. Error suppression is used here to prevent warnings/notices that the connection has been lost. + $this->cursor = @mysql_query($query, $this->connection); + + if ($this->debug) + { + $this->timings[] = microtime(true); + + if (defined('DEBUG_BACKTRACE_IGNORE_ARGS')) + { + $this->callStacks[] = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); + } + else + { + $this->callStacks[] = debug_backtrace(); + } + } + + // If an error occurred handle it. + if (!$this->cursor) + { + // Get the error number and message before we execute any more queries. + $this->errorNum = $this->getErrorNumber(); + $this->errorMsg = $this->getErrorMessage($query); + + // Check if the server was disconnected. + if (!$this->connected()) + { + try + { + // Attempt to reconnect. + $this->connection = null; + $this->connect(); + } + // If connect fails, ignore that exception and throw the normal exception. + catch (RuntimeException $e) + { + // Get the error number and message. + $this->errorNum = $this->getErrorNumber(); + $this->errorMsg = $this->getErrorMessage($query); + + // Throw the normal query exception. + if (class_exists('JLog')) + { + JLog::add(JText::sprintf('JLIB_DATABASE_QUERY_FAILED', $this->errorNum, $this->errorMsg), JLog::ERROR, 'database-error'); + } + + throw new RuntimeException($this->errorMsg, $this->errorNum, $e); + } + + // Since we were able to reconnect, run the query again. + return $this->execute(); + } + // The server was not disconnected. + else + { + // Throw the normal query exception. + if (class_exists('JLog')) + { + JLog::add(JText::sprintf('JLIB_DATABASE_QUERY_FAILED', $this->errorNum, $this->errorMsg), JLog::ERROR, 'database-error'); + } + + throw new RuntimeException($this->errorMsg, $this->errorNum); + } + } + + return $this->cursor; + } + + /** + * Select a database for use. + * + * @param string $database The name of the database to select for use. + * + * @return boolean True if the database was successfully selected. + * + * @since 12.1 + * @throws RuntimeException + */ + public function select($database) + { + $this->connect(); + + if (!$database) + { + return false; + } + + if (!mysql_select_db($database, $this->connection)) + { + throw new RuntimeException('Could not connect to database'); + } + + return true; + } + + /** + * Set the connection to use UTF-8 character encoding. + * + * @return boolean True on success. + * + * @since 12.1 + */ + public function setUtf() + { + // If UTF is not supported return false immediately + if (!$this->utf) + { + return false; + } + + // Make sure we're connected to the server + $this->connect(); + + // Which charset should I use, plain utf8 or multibyte utf8mb4? + $charset = $this->utf8mb4 ? 'utf8mb4' : 'utf8'; + + $result = @mysql_set_charset($charset, $this->connection); + + /** + * If I could not set the utf8mb4 charset then the server doesn't support utf8mb4 despite claiming otherwise. + * This happens on old MySQL server versions (less than 5.5.3) using the mysqlnd PHP driver. Since mysqlnd + * masks the server version and reports only its own we can not be sure if the server actually does support + * UTF-8 Multibyte (i.e. it's MySQL 5.5.3 or later). Since the utf8mb4 charset is undefined in this case we + * catch the error and determine that utf8mb4 is not supported! + */ + if (!$result && $this->utf8mb4) + { + $this->utf8mb4 = false; + $result = @mysql_set_charset('utf8', $this->connection); + } + + return $result; + } + + /** + * Method to fetch a row from the result set cursor as an array. + * + * @param mixed $cursor The optional result set cursor from which to fetch the row. + * + * @return mixed Either the next row from the result set or false if there are no more rows. + * + * @since 12.1 + */ + protected function fetchArray($cursor = null) + { + return mysql_fetch_row($cursor ? $cursor : $this->cursor); + } + + /** + * Method to fetch a row from the result set cursor as an associative array. + * + * @param mixed $cursor The optional result set cursor from which to fetch the row. + * + * @return mixed Either the next row from the result set or false if there are no more rows. + * + * @since 12.1 + */ + protected function fetchAssoc($cursor = null) + { + return mysql_fetch_assoc($cursor ? $cursor : $this->cursor); + } + + /** + * Method to fetch a row from the result set cursor as an object. + * + * @param mixed $cursor The optional result set cursor from which to fetch the row. + * @param string $class The class name to use for the returned row object. + * + * @return mixed Either the next row from the result set or false if there are no more rows. + * + * @since 12.1 + */ + protected function fetchObject($cursor = null, $class = 'stdClass') + { + return mysql_fetch_object($cursor ? $cursor : $this->cursor, $class); + } + + /** + * Method to free up the memory used for the result set. + * + * @param mixed $cursor The optional result set cursor from which to fetch the row. + * + * @return void + * + * @since 12.1 + */ + protected function freeResult($cursor = null) + { + mysql_free_result($cursor ? $cursor : $this->cursor); + } + + /** + * Internal function to check if profiling is available + * + * @return boolean + * + * @since 3.1.3 + */ + private function hasProfiling() + { + try + { + $res = mysql_query("SHOW VARIABLES LIKE 'have_profiling'", $this->connection); + $row = mysql_fetch_assoc($res); + + return isset($row); + } + catch (Exception $e) + { + return false; + } + } + + /** + * Does the database server claim to have support for UTF-8 Multibyte (utf8mb4) collation? + * + * libmysql supports utf8mb4 since 5.5.3 (same version as the MySQL server). mysqlnd supports utf8mb4 since 5.0.9. + * + * @return boolean + * + * @since CMS 3.5.0 + */ + private function serverClaimsUtf8mb4Support() + { + $client_version = mysql_get_client_info(); + + if (strpos($client_version, 'mysqlnd') !== false) + { + $client_version = preg_replace('/^\D+([\d.]+).*/', '$1', $client_version); + + return version_compare($client_version, '5.0.9', '>='); + } + else + { + return version_compare($client_version, '5.5.3', '>='); + } + } + + /** + * Return the actual SQL Error number + * + * @return integer The SQL Error number + * + * @since 3.4.6 + */ + protected function getErrorNumber() + { + return (int) mysql_errno($this->connection); + } + + /** + * Return the actual SQL Error message + * + * @param string $query The SQL Query that fails + * + * @return string The SQL Error message + * + * @since 3.4.6 + */ + protected function getErrorMessage($query) + { + $errorMessage = (string) mysql_error($this->connection); + + // Replace the Databaseprefix with `#__` if we are not in Debug + if (!$this->debug) + { + $errorMessage = str_replace($this->tablePrefix, '#__', $errorMessage); + $query = str_replace($this->tablePrefix, '#__', $query); + } + + return $errorMessage . ' SQL=' . $query; + } +} diff --git a/Sites/pages/libraries/fof/database/driver/mysqli.php b/Sites/pages/libraries/fof/database/driver/mysqli.php new file mode 100644 index 00000000..bc271f1c --- /dev/null +++ b/Sites/pages/libraries/fof/database/driver/mysqli.php @@ -0,0 +1,1019 @@ +disconnect(); + } + + /** + * Connects to the database if needed. + * + * @return void Returns void if the database connected successfully. + * + * @since 12.1 + * @throws RuntimeException + */ + public function connect() + { + if ($this->connection) + { + return; + } + + /* + * Unlike mysql_connect(), mysqli_connect() takes the port and socket as separate arguments. Therefore, we + * have to extract them from the host string. + */ + $port = isset($this->options['port']) ? $this->options['port'] : 3306; + $regex = '/^(?P((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))(:(?P.+))?$/'; + + if (preg_match($regex, $this->options['host'], $matches)) + { + // It's an IPv4 address with ot without port + $this->options['host'] = $matches['host']; + + if (!empty($matches['port'])) + { + $port = $matches['port']; + } + } + elseif (preg_match('/^(?P\[.*\])(:(?P.+))?$/', $this->options['host'], $matches)) + { + // We assume square-bracketed IPv6 address with or without port, e.g. [fe80:102::2%eth1]:3306 + $this->options['host'] = $matches['host']; + + if (!empty($matches['port'])) + { + $port = $matches['port']; + } + } + elseif (preg_match('/^(?P(\w+:\/{2,3})?[a-z0-9\.\-]+)(:(?P[^:]+))?$/i', $this->options['host'], $matches)) + { + // Named host (e.g domain.com or localhost) with ot without port + $this->options['host'] = $matches['host']; + + if (!empty($matches['port'])) + { + $port = $matches['port']; + } + } + elseif (preg_match('/^:(?P[^:]+)$/', $this->options['host'], $matches)) + { + // Empty host, just port, e.g. ':3306' + $this->options['host'] = 'localhost'; + $port = $matches['port']; + } + // ... else we assume normal (naked) IPv6 address, so host and port stay as they are or default + + // Get the port number or socket name + if (is_numeric($port)) + { + $this->options['port'] = (int) $port; + } + else + { + $this->options['socket'] = $port; + } + + // Make sure the MySQLi extension for PHP is installed and enabled. + if (!function_exists('mysqli_connect')) + { + throw new RuntimeException('The MySQL adapter mysqli is not available'); + } + + $this->connection = @mysqli_connect( + $this->options['host'], $this->options['user'], $this->options['password'], null, $this->options['port'], $this->options['socket'] + ); + + // Attempt to connect to the server. + if (!$this->connection) + { + throw new RuntimeException('Could not connect to MySQL.'); + } + + // Set sql_mode to non_strict mode + mysqli_query($this->connection, "SET @@SESSION.sql_mode = '';"); + + // If auto-select is enabled select the given database. + if ($this->options['select'] && !empty($this->options['database'])) + { + $this->select($this->options['database']); + } + + // Pre-populate the UTF-8 Multibyte compatibility flag based on server version + $this->utf8mb4 = $this->serverClaimsUtf8mb4Support(); + + // Set the character set (needed for MySQL 4.1.2+). + $this->utf = $this->setUtf(); + + // Turn MySQL profiling ON in debug mode: + if ($this->debug && $this->hasProfiling()) + { + mysqli_query($this->connection, "SET profiling_history_size = 100;"); + mysqli_query($this->connection, "SET profiling = 1;"); + } + } + + /** + * Disconnects the database. + * + * @return void + * + * @since 12.1 + */ + public function disconnect() + { + // Close the connection. + if ($this->connection) + { + foreach ($this->disconnectHandlers as $h) + { + call_user_func_array($h, array( &$this)); + } + + mysqli_close($this->connection); + } + + $this->connection = null; + } + + /** + * Method to escape a string for usage in an SQL statement. + * + * @param string $text The string to be escaped. + * @param boolean $extra Optional parameter to provide extra escaping. + * + * @return string The escaped string. + * + * @since 12.1 + */ + public function escape($text, $extra = false) + { + $this->connect(); + + $result = mysqli_real_escape_string($this->getConnection(), $text); + + if ($extra) + { + $result = addcslashes($result, '%_'); + } + + return $result; + } + + /** + * Test to see if the MySQL connector is available. + * + * @return boolean True on success, false otherwise. + * + * @since 12.1 + */ + public static function isSupported() + { + return (function_exists('mysqli_connect')); + } + + /** + * Determines if the connection to the server is active. + * + * @return boolean True if connected to the database engine. + * + * @since 12.1 + */ + public function connected() + { + if (is_object($this->connection)) + { + return mysqli_ping($this->connection); + } + + return false; + } + + /** + * Drops a table from the database. + * + * @param string $tableName The name of the database table to drop. + * @param boolean $ifExists Optionally specify that the table must exist before it is dropped. + * + * @return FOFDatabaseDriverMysqli Returns this object to support chaining. + * + * @since 12.2 + * @throws RuntimeException + */ + public function dropTable($tableName, $ifExists = true) + { + $this->connect(); + + $query = $this->getQuery(true); + + $this->setQuery('DROP TABLE ' . ($ifExists ? 'IF EXISTS ' : '') . $query->quoteName($tableName)); + + $this->execute(); + + return $this; + } + + /** + * Get the number of affected rows by the last INSERT, UPDATE, REPLACE or DELETE for the previous executed SQL statement. + * + * @return integer The number of affected rows. + * + * @since 12.1 + */ + public function getAffectedRows() + { + $this->connect(); + + return mysqli_affected_rows($this->connection); + } + + /** + * Method to get the database collation. + * + * @return mixed The collation in use by the database (string) or boolean false if not supported. + * + * @since 12.2 + * @throws RuntimeException + */ + public function getCollation() + { + $this->connect(); + + // Attempt to get the database collation by accessing the server system variable. + $this->setQuery('SHOW VARIABLES LIKE "collation_database"'); + $result = $this->loadObject(); + + if (property_exists($result, 'Value')) + { + return $result->Value; + } + else + { + return false; + } + } + + /** + * Method to get the database connection collation, as reported by the driver. If the connector doesn't support + * reporting this value please return an empty string. + * + * @return string + */ + public function getConnectionCollation() + { + $this->connect(); + + // Attempt to get the database collation by accessing the server system variable. + $this->setQuery('SHOW VARIABLES LIKE "collation_connection"'); + $result = $this->loadObject(); + + if (property_exists($result, 'Value')) + { + return $result->Value; + } + else + { + return false; + } + } + + /** + * Get the number of returned rows for the previous executed SQL statement. + * This command is only valid for statements like SELECT or SHOW that return an actual result set. + * To retrieve the number of rows affected by a INSERT, UPDATE, REPLACE or DELETE query, use getAffectedRows(). + * + * @param resource $cursor An optional database cursor resource to extract the row count from. + * + * @return integer The number of returned rows. + * + * @since 12.1 + */ + public function getNumRows($cursor = null) + { + return mysqli_num_rows($cursor ? $cursor : $this->cursor); + } + + /** + * Shows the table CREATE statement that creates the given tables. + * + * @param mixed $tables A table name or a list of table names. + * + * @return array A list of the create SQL for the tables. + * + * @since 12.1 + * @throws RuntimeException + */ + public function getTableCreate($tables) + { + $this->connect(); + + $result = array(); + + // Sanitize input to an array and iterate over the list. + settype($tables, 'array'); + + foreach ($tables as $table) + { + // Set the query to get the table CREATE statement. + $this->setQuery('SHOW CREATE table ' . $this->quoteName($this->escape($table))); + $row = $this->loadRow(); + + // Populate the result array based on the create statements. + $result[$table] = $row[1]; + } + + return $result; + } + + /** + * Retrieves field information about a given table. + * + * @param string $table The name of the database table. + * @param boolean $typeOnly True to only return field types. + * + * @return array An array of fields for the database table. + * + * @since 12.2 + * @throws RuntimeException + */ + public function getTableColumns($table, $typeOnly = true) + { + $this->connect(); + + $result = array(); + + // Set the query to get the table fields statement. + $this->setQuery('SHOW FULL COLUMNS FROM ' . $this->quoteName($this->escape($table))); + $fields = $this->loadObjectList(); + + // If we only want the type as the value add just that to the list. + if ($typeOnly) + { + foreach ($fields as $field) + { + $result[$field->Field] = preg_replace("/[(0-9)]/", '', $field->Type); + } + } + // If we want the whole field data object add that to the list. + else + { + foreach ($fields as $field) + { + $result[$field->Field] = $field; + } + } + + return $result; + } + + /** + * Get the details list of keys for a table. + * + * @param string $table The name of the table. + * + * @return array An array of the column specification for the table. + * + * @since 12.2 + * @throws RuntimeException + */ + public function getTableKeys($table) + { + $this->connect(); + + // Get the details columns information. + $this->setQuery('SHOW KEYS FROM ' . $this->quoteName($table)); + $keys = $this->loadObjectList(); + + return $keys; + } + + /** + * Method to get an array of all tables in the database. + * + * @return array An array of all the tables in the database. + * + * @since 12.2 + * @throws RuntimeException + */ + public function getTableList() + { + $this->connect(); + + // Set the query to get the tables statement. + $this->setQuery('SHOW TABLES'); + $tables = $this->loadColumn(); + + return $tables; + } + + /** + * Get the version of the database connector. + * + * @return string The database connector version. + * + * @since 12.1 + */ + public function getVersion() + { + $this->connect(); + + return mysqli_get_server_info($this->connection); + } + + /** + * Method to get the auto-incremented value from the last INSERT statement. + * + * @return mixed The value of the auto-increment field from the last inserted row. + * If the value is greater than maximal int value, it will return a string. + * + * @since 12.1 + */ + public function insertid() + { + $this->connect(); + + return mysqli_insert_id($this->connection); + } + + /** + * Locks a table in the database. + * + * @param string $table The name of the table to unlock. + * + * @return FOFDatabaseDriverMysqli Returns this object to support chaining. + * + * @since 12.2 + * @throws RuntimeException + */ + public function lockTable($table) + { + $this->setQuery('LOCK TABLES ' . $this->quoteName($table) . ' WRITE')->execute(); + + return $this; + } + + /** + * Execute the SQL statement. + * + * @return mixed A database cursor resource on success, boolean false on failure. + * + * @since 12.1 + * @throws RuntimeException + */ + public function execute() + { + $this->connect(); + + if (!is_object($this->connection)) + { + if (class_exists('JLog')) + { + JLog::add(JText::sprintf('JLIB_DATABASE_QUERY_FAILED', $this->errorNum, $this->errorMsg), JLog::ERROR, 'database'); + } + throw new RuntimeException($this->errorMsg, $this->errorNum); + } + + // Take a local copy so that we don't modify the original query and cause issues later + $query = $this->replacePrefix((string) $this->sql); + + if (!($this->sql instanceof FOFDatabaseQuery) && ($this->limit > 0 || $this->offset > 0)) + { + $query .= ' LIMIT ' . $this->offset . ', ' . $this->limit; + } + + // Increment the query counter. + $this->count++; + + // Reset the error values. + $this->errorNum = 0; + $this->errorMsg = ''; + $memoryBefore = null; + + // If debugging is enabled then let's log the query. + if ($this->debug) + { + // Add the query to the object queue. + $this->log[] = $query; + + if (class_exists('JLog')) + { + JLog::add($query, JLog::DEBUG, 'databasequery'); + } + + $this->timings[] = microtime(true); + + if (is_object($this->cursor)) + { + // Avoid warning if result already freed by third-party library + @$this->freeResult(); + } + + $memoryBefore = memory_get_usage(); + } + + // Execute the query. Error suppression is used here to prevent warnings/notices that the connection has been lost. + $this->cursor = @mysqli_query($this->connection, $query); + + if ($this->debug) + { + $this->timings[] = microtime(true); + + if (defined('DEBUG_BACKTRACE_IGNORE_ARGS')) + { + $this->callStacks[] = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); + } + else + { + $this->callStacks[] = debug_backtrace(); + } + + $this->callStacks[count($this->callStacks) - 1][0]['memory'] = array( + $memoryBefore, + memory_get_usage(), + is_object($this->cursor) ? $this->getNumRows() : null + ); + } + + // If an error occurred handle it. + if (!$this->cursor) + { + // Get the error number and message before we execute any more queries. + $this->errorNum = $this->getErrorNumber(); + $this->errorMsg = $this->getErrorMessage($query); + + // Check if the server was disconnected. + if (!$this->connected()) + { + try + { + // Attempt to reconnect. + $this->connection = null; + $this->connect(); + } + // If connect fails, ignore that exception and throw the normal exception. + catch (RuntimeException $e) + { + // Get the error number and message. + $this->errorNum = $this->getErrorNumber(); + $this->errorMsg = $this->getErrorMessage($query); + + if (class_exists('JLog')) + { + JLog::add(JText::sprintf('JLIB_DATABASE_QUERY_FAILED', $this->errorNum, $this->errorMsg), JLog::ERROR, 'database-error'); + } + + throw new RuntimeException($this->errorMsg, $this->errorNum, $e); + } + + // Since we were able to reconnect, run the query again. + return $this->execute(); + } + // The server was not disconnected. + else + { + if (class_exists('JLog')) + { + JLog::add(JText::sprintf('JLIB_DATABASE_QUERY_FAILED', $this->errorNum, $this->errorMsg), JLog::ERROR, 'database-error'); + } + + throw new RuntimeException($this->errorMsg, $this->errorNum); + } + } + + return $this->cursor; + } + + /** + * Renames a table in the database. + * + * @param string $oldTable The name of the table to be renamed + * @param string $newTable The new name for the table. + * @param string $backup Not used by MySQL. + * @param string $prefix Not used by MySQL. + * + * @return FOFDatabaseDriverMysqli Returns this object to support chaining. + * + * @since 12.2 + * @throws RuntimeException + */ + public function renameTable($oldTable, $newTable, $backup = null, $prefix = null) + { + $this->setQuery('RENAME TABLE ' . $oldTable . ' TO ' . $newTable)->execute(); + + return $this; + } + + /** + * Select a database for use. + * + * @param string $database The name of the database to select for use. + * + * @return boolean True if the database was successfully selected. + * + * @since 12.1 + * @throws RuntimeException + */ + public function select($database) + { + $this->connect(); + + if (!$database) + { + return false; + } + + if (!mysqli_select_db($this->connection, $database)) + { + throw new RuntimeException('Could not connect to database.'); + } + + return true; + } + + /** + * Set the connection to use UTF-8 character encoding. + * + * @return boolean True on success. + * + * @since 12.1 + */ + public function setUtf() + { + // If UTF is not supported return false immediately + if (!$this->utf) + { + return false; + } + + // Make sure we're connected to the server + $this->connect(); + + // Which charset should I use, plain utf8 or multibyte utf8mb4? + $charset = $this->utf8mb4 ? 'utf8mb4' : 'utf8'; + + $result = @$this->connection->set_charset($charset); + + /** + * If I could not set the utf8mb4 charset then the server doesn't support utf8mb4 despite claiming otherwise. + * This happens on old MySQL server versions (less than 5.5.3) using the mysqlnd PHP driver. Since mysqlnd + * masks the server version and reports only its own we can not be sure if the server actually does support + * UTF-8 Multibyte (i.e. it's MySQL 5.5.3 or later). Since the utf8mb4 charset is undefined in this case we + * catch the error and determine that utf8mb4 is not supported! + */ + if (!$result && $this->utf8mb4) + { + $this->utf8mb4 = false; + $result = @$this->connection->set_charset('utf8'); + } + + return $result; + } + + /** + * Method to commit a transaction. + * + * @param boolean $toSavepoint If true, commit to the last savepoint. + * + * @return void + * + * @since 12.2 + * @throws RuntimeException + */ + public function transactionCommit($toSavepoint = false) + { + $this->connect(); + + if (!$toSavepoint || $this->transactionDepth <= 1) + { + if ($this->setQuery('COMMIT')->execute()) + { + $this->transactionDepth = 0; + } + + return; + } + + $this->transactionDepth--; + } + + /** + * Method to roll back a transaction. + * + * @param boolean $toSavepoint If true, rollback to the last savepoint. + * + * @return void + * + * @since 12.2 + * @throws RuntimeException + */ + public function transactionRollback($toSavepoint = false) + { + $this->connect(); + + if (!$toSavepoint || $this->transactionDepth <= 1) + { + if ($this->setQuery('ROLLBACK')->execute()) + { + $this->transactionDepth = 0; + } + + return; + } + + $savepoint = 'SP_' . ($this->transactionDepth - 1); + $this->setQuery('ROLLBACK TO SAVEPOINT ' . $this->quoteName($savepoint)); + + if ($this->execute()) + { + $this->transactionDepth--; + } + } + + /** + * Method to initialize a transaction. + * + * @param boolean $asSavepoint If true and a transaction is already active, a savepoint will be created. + * + * @return void + * + * @since 12.2 + * @throws RuntimeException + */ + public function transactionStart($asSavepoint = false) + { + $this->connect(); + + if (!$asSavepoint || !$this->transactionDepth) + { + if ($this->setQuery('START TRANSACTION')->execute()) + { + $this->transactionDepth = 1; + } + + return; + } + + $savepoint = 'SP_' . $this->transactionDepth; + $this->setQuery('SAVEPOINT ' . $this->quoteName($savepoint)); + + if ($this->execute()) + { + $this->transactionDepth++; + } + } + + /** + * Method to fetch a row from the result set cursor as an array. + * + * @param mixed $cursor The optional result set cursor from which to fetch the row. + * + * @return mixed Either the next row from the result set or false if there are no more rows. + * + * @since 12.1 + */ + protected function fetchArray($cursor = null) + { + return mysqli_fetch_row($cursor ? $cursor : $this->cursor); + } + + /** + * Method to fetch a row from the result set cursor as an associative array. + * + * @param mixed $cursor The optional result set cursor from which to fetch the row. + * + * @return mixed Either the next row from the result set or false if there are no more rows. + * + * @since 12.1 + */ + protected function fetchAssoc($cursor = null) + { + return mysqli_fetch_assoc($cursor ? $cursor : $this->cursor); + } + + /** + * Method to fetch a row from the result set cursor as an object. + * + * @param mixed $cursor The optional result set cursor from which to fetch the row. + * @param string $class The class name to use for the returned row object. + * + * @return mixed Either the next row from the result set or false if there are no more rows. + * + * @since 12.1 + */ + protected function fetchObject($cursor = null, $class = 'stdClass') + { + return mysqli_fetch_object($cursor ? $cursor : $this->cursor, $class); + } + + /** + * Method to free up the memory used for the result set. + * + * @param mixed $cursor The optional result set cursor from which to fetch the row. + * + * @return void + * + * @since 12.1 + */ + protected function freeResult($cursor = null) + { + mysqli_free_result($cursor ? $cursor : $this->cursor); + + if ((! $cursor) || ($cursor === $this->cursor)) + { + $this->cursor = null; + } + } + + /** + * Unlocks tables in the database. + * + * @return FOFDatabaseDriverMysqli Returns this object to support chaining. + * + * @since 12.1 + * @throws RuntimeException + */ + public function unlockTables() + { + $this->setQuery('UNLOCK TABLES')->execute(); + + return $this; + } + + /** + * Internal function to check if profiling is available + * + * @return boolean + * + * @since 3.1.3 + */ + private function hasProfiling() + { + try + { + $res = mysqli_query($this->connection, "SHOW VARIABLES LIKE 'have_profiling'"); + $row = mysqli_fetch_assoc($res); + + return isset($row); + } + catch (Exception $e) + { + return false; + } + } + + /** + * Does the database server claim to have support for UTF-8 Multibyte (utf8mb4) collation? + * + * libmysql supports utf8mb4 since 5.5.3 (same version as the MySQL server). mysqlnd supports utf8mb4 since 5.0.9. + * + * @return boolean + * + * @since CMS 3.5.0 + */ + private function serverClaimsUtf8mb4Support() + { + $client_version = mysqli_get_client_info(); + + if (strpos($client_version, 'mysqlnd') !== false) + { + $client_version = preg_replace('/^\D+([\d.]+).*/', '$1', $client_version); + + return version_compare($client_version, '5.0.9', '>='); + } + else + { + return version_compare($client_version, '5.5.3', '>='); + } + } + + /** + * Return the actual SQL Error number + * + * @return integer The SQL Error number + * + * @since 3.4.6 + */ + protected function getErrorNumber() + { + return (int) mysqli_errno($this->connection); + } + + /** + * Return the actual SQL Error message + * + * @param string $query The SQL Query that fails + * + * @return string The SQL Error message + * + * @since 3.4.6 + */ + protected function getErrorMessage($query) + { + $errorMessage = (string) mysqli_error($this->connection); + + // Replace the Databaseprefix with `#__` if we are not in Debug + if (!$this->debug) + { + $errorMessage = str_replace($this->tablePrefix, '#__', $errorMessage); + $query = str_replace($this->tablePrefix, '#__', $query); + } + + return $errorMessage . ' SQL=' . $query; + } +} diff --git a/Sites/pages/libraries/fof/database/driver/oracle.php b/Sites/pages/libraries/fof/database/driver/oracle.php new file mode 100644 index 00000000..b760522c --- /dev/null +++ b/Sites/pages/libraries/fof/database/driver/oracle.php @@ -0,0 +1,713 @@ +charset = $options['charset']; + $this->dateformat = $options['dateformat']; + + // Finalize initialisation + parent::__construct($options); + } + + /** + * Destructor. + * + * @since 12.1 + */ + public function __destruct() + { + $this->freeResult(); + unset($this->connection); + } + + /** + * Connects to the database if needed. + * + * @return void Returns void if the database connected successfully. + * + * @since 12.1 + * @throws RuntimeException + */ + public function connect() + { + if ($this->connection) + { + return; + } + + parent::connect(); + + if (isset($this->options['schema'])) + { + $this->setQuery('ALTER SESSION SET CURRENT_SCHEMA = ' . $this->quoteName($this->options['schema']))->execute(); + } + + $this->setDateFormat($this->dateformat); + } + + /** + * Disconnects the database. + * + * @return void + * + * @since 12.1 + */ + public function disconnect() + { + // Close the connection. + $this->freeResult(); + unset($this->connection); + } + + /** + * Drops a table from the database. + * + * Note: The IF EXISTS flag is unused in the Oracle driver. + * + * @param string $tableName The name of the database table to drop. + * @param boolean $ifExists Optionally specify that the table must exist before it is dropped. + * + * @return FOFDatabaseDriverOracle Returns this object to support chaining. + * + * @since 12.1 + */ + public function dropTable($tableName, $ifExists = true) + { + $this->connect(); + + $query = $this->getQuery(true) + ->setQuery('DROP TABLE :tableName'); + $query->bind(':tableName', $tableName); + + $this->setQuery($query); + + $this->execute(); + + return $this; + } + + /** + * Method to get the database collation in use by sampling a text field of a table in the database. + * + * @return mixed The collation in use by the database or boolean false if not supported. + * + * @since 12.1 + */ + public function getCollation() + { + return $this->charset; + } + + /** + * Method to get the database connection collation, as reported by the driver. If the connector doesn't support + * reporting this value please return an empty string. + * + * @return string + */ + public function getConnectionCollation() + { + return $this->charset; + } + + /** + * Get a query to run and verify the database is operational. + * + * @return string The query to check the health of the DB. + * + * @since 12.2 + */ + public function getConnectedQuery() + { + return 'SELECT 1 FROM dual'; + } + + /** + * Returns the current date format + * This method should be useful in the case that + * somebody actually wants to use a different + * date format and needs to check what the current + * one is to see if it needs to be changed. + * + * @return string The current date format + * + * @since 12.1 + */ + public function getDateFormat() + { + return $this->dateformat; + } + + /** + * Shows the table CREATE statement that creates the given tables. + * + * Note: You must have the correct privileges before this method + * will return usable results! + * + * @param mixed $tables A table name or a list of table names. + * + * @return array A list of the create SQL for the tables. + * + * @since 12.1 + * @throws RuntimeException + */ + public function getTableCreate($tables) + { + $this->connect(); + + $result = array(); + $query = $this->getQuery(true) + ->select('dbms_metadata.get_ddl(:type, :tableName)') + ->from('dual') + ->bind(':type', 'TABLE'); + + // Sanitize input to an array and iterate over the list. + settype($tables, 'array'); + + foreach ($tables as $table) + { + $query->bind(':tableName', $table); + $this->setQuery($query); + $statement = (string) $this->loadResult(); + $result[$table] = $statement; + } + + return $result; + } + + /** + * Retrieves field information about a given table. + * + * @param string $table The name of the database table. + * @param boolean $typeOnly True to only return field types. + * + * @return array An array of fields for the database table. + * + * @since 12.1 + * @throws RuntimeException + */ + public function getTableColumns($table, $typeOnly = true) + { + $this->connect(); + + $columns = array(); + $query = $this->getQuery(true); + + $fieldCasing = $this->getOption(PDO::ATTR_CASE); + + $this->setOption(PDO::ATTR_CASE, PDO::CASE_UPPER); + + $table = strtoupper($table); + + $query->select('*'); + $query->from('ALL_TAB_COLUMNS'); + $query->where('table_name = :tableName'); + + $prefixedTable = str_replace('#__', strtoupper($this->tablePrefix), $table); + $query->bind(':tableName', $prefixedTable); + $this->setQuery($query); + $fields = $this->loadObjectList(); + + if ($typeOnly) + { + foreach ($fields as $field) + { + $columns[$field->COLUMN_NAME] = $field->DATA_TYPE; + } + } + else + { + foreach ($fields as $field) + { + $columns[$field->COLUMN_NAME] = $field; + $columns[$field->COLUMN_NAME]->Default = null; + } + } + + $this->setOption(PDO::ATTR_CASE, $fieldCasing); + + return $columns; + } + + /** + * Get the details list of keys for a table. + * + * @param string $table The name of the table. + * + * @return array An array of the column specification for the table. + * + * @since 12.1 + * @throws RuntimeException + */ + public function getTableKeys($table) + { + $this->connect(); + + $query = $this->getQuery(true); + + $fieldCasing = $this->getOption(PDO::ATTR_CASE); + + $this->setOption(PDO::ATTR_CASE, PDO::CASE_UPPER); + + $table = strtoupper($table); + $query->select('*') + ->from('ALL_CONSTRAINTS') + ->where('table_name = :tableName') + ->bind(':tableName', $table); + + $this->setQuery($query); + $keys = $this->loadObjectList(); + + $this->setOption(PDO::ATTR_CASE, $fieldCasing); + + return $keys; + } + + /** + * Method to get an array of all tables in the database (schema). + * + * @param string $databaseName The database (schema) name + * @param boolean $includeDatabaseName Whether to include the schema name in the results + * + * @return array An array of all the tables in the database. + * + * @since 12.1 + * @throws RuntimeException + */ + public function getTableList($databaseName = null, $includeDatabaseName = false) + { + $this->connect(); + + $query = $this->getQuery(true); + + if ($includeDatabaseName) + { + $query->select('owner, table_name'); + } + else + { + $query->select('table_name'); + } + + $query->from('all_tables'); + + if ($databaseName) + { + $query->where('owner = :database') + ->bind(':database', $databaseName); + } + + $query->order('table_name'); + + $this->setQuery($query); + + if ($includeDatabaseName) + { + $tables = $this->loadAssocList(); + } + else + { + $tables = $this->loadColumn(); + } + + return $tables; + } + + /** + * Get the version of the database connector. + * + * @return string The database connector version. + * + * @since 12.1 + */ + public function getVersion() + { + $this->connect(); + + $this->setQuery("select value from nls_database_parameters where parameter = 'NLS_RDBMS_VERSION'"); + + return $this->loadResult(); + } + + /** + * Select a database for use. + * + * @param string $database The name of the database to select for use. + * + * @return boolean True if the database was successfully selected. + * + * @since 12.1 + * @throws RuntimeException + */ + public function select($database) + { + $this->connect(); + + return true; + } + + /** + * Sets the Oracle Date Format for the session + * Default date format for Oracle is = DD-MON-RR + * The default date format for this driver is: + * 'RRRR-MM-DD HH24:MI:SS' since it is the format + * that matches the MySQL one used within most Joomla + * tables. + * + * @param string $dateFormat Oracle Date Format String + * + * @return boolean + * + * @since 12.1 + */ + public function setDateFormat($dateFormat = 'DD-MON-RR') + { + $this->connect(); + + $this->setQuery("ALTER SESSION SET NLS_DATE_FORMAT = '$dateFormat'"); + + if (!$this->execute()) + { + return false; + } + + $this->setQuery("ALTER SESSION SET NLS_TIMESTAMP_FORMAT = '$dateFormat'"); + + if (!$this->execute()) + { + return false; + } + + $this->dateformat = $dateFormat; + + return true; + } + + /** + * Set the connection to use UTF-8 character encoding. + * + * Returns false automatically for the Oracle driver since + * you can only set the character set when the connection + * is created. + * + * @return boolean True on success. + * + * @since 12.1 + */ + public function setUtf() + { + return false; + } + + /** + * Locks a table in the database. + * + * @param string $table The name of the table to unlock. + * + * @return FOFDatabaseDriverOracle Returns this object to support chaining. + * + * @since 12.1 + * @throws RuntimeException + */ + public function lockTable($table) + { + $this->setQuery('LOCK TABLE ' . $this->quoteName($table) . ' IN EXCLUSIVE MODE')->execute(); + + return $this; + } + + /** + * Renames a table in the database. + * + * @param string $oldTable The name of the table to be renamed + * @param string $newTable The new name for the table. + * @param string $backup Not used by Oracle. + * @param string $prefix Not used by Oracle. + * + * @return FOFDatabaseDriverOracle Returns this object to support chaining. + * + * @since 12.1 + * @throws RuntimeException + */ + public function renameTable($oldTable, $newTable, $backup = null, $prefix = null) + { + $this->setQuery('RENAME ' . $oldTable . ' TO ' . $newTable)->execute(); + + return $this; + } + + /** + * Unlocks tables in the database. + * + * @return FOFDatabaseDriverOracle Returns this object to support chaining. + * + * @since 12.1 + * @throws RuntimeException + */ + public function unlockTables() + { + $this->setQuery('COMMIT')->execute(); + + return $this; + } + + /** + * Test to see if the PDO ODBC connector is available. + * + * @return boolean True on success, false otherwise. + * + * @since 12.1 + */ + public static function isSupported() + { + return class_exists('PDO') && in_array('oci', PDO::getAvailableDrivers()); + } + + /** + * This function replaces a string identifier $prefix with the string held is the + * tablePrefix class variable. + * + * @param string $query The SQL statement to prepare. + * @param string $prefix The common table prefix. + * + * @return string The processed SQL statement. + * + * @since 11.1 + */ + public function replacePrefix($query, $prefix = '#__') + { + $startPos = 0; + $quoteChar = "'"; + $literal = ''; + + $query = trim($query); + $n = strlen($query); + + while ($startPos < $n) + { + $ip = strpos($query, $prefix, $startPos); + + if ($ip === false) + { + break; + } + + $j = strpos($query, "'", $startPos); + + if ($j === false) + { + $j = $n; + } + + $literal .= str_replace($prefix, $this->tablePrefix, substr($query, $startPos, $j - $startPos)); + $startPos = $j; + + $j = $startPos + 1; + + if ($j >= $n) + { + break; + } + + // Quote comes first, find end of quote + while (true) + { + $k = strpos($query, $quoteChar, $j); + $escaped = false; + + if ($k === false) + { + break; + } + + $l = $k - 1; + + while ($l >= 0 && $query[$l] == '\\') + { + $l--; + $escaped = !$escaped; + } + + if ($escaped) + { + $j = $k + 1; + continue; + } + + break; + } + + if ($k === false) + { + // Error in the query - no end quote; ignore it + break; + } + + $literal .= substr($query, $startPos, $k - $startPos + 1); + $startPos = $k + 1; + } + + if ($startPos < $n) + { + $literal .= substr($query, $startPos, $n - $startPos); + } + + return $literal; + } + + /** + * Method to commit a transaction. + * + * @param boolean $toSavepoint If true, commit to the last savepoint. + * + * @return void + * + * @since 12.3 + * @throws RuntimeException + */ + public function transactionCommit($toSavepoint = false) + { + $this->connect(); + + if (!$toSavepoint || $this->transactionDepth <= 1) + { + parent::transactionCommit($toSavepoint); + } + else + { + $this->transactionDepth--; + } + } + + /** + * Method to roll back a transaction. + * + * @param boolean $toSavepoint If true, rollback to the last savepoint. + * + * @return void + * + * @since 12.3 + * @throws RuntimeException + */ + public function transactionRollback($toSavepoint = false) + { + $this->connect(); + + if (!$toSavepoint || $this->transactionDepth <= 1) + { + parent::transactionRollback($toSavepoint); + } + else + { + $savepoint = 'SP_' . ($this->transactionDepth - 1); + $this->setQuery('ROLLBACK TO SAVEPOINT ' . $this->quoteName($savepoint)); + + if ($this->execute()) + { + $this->transactionDepth--; + } + } + } + + /** + * Method to initialize a transaction. + * + * @param boolean $asSavepoint If true and a transaction is already active, a savepoint will be created. + * + * @return void + * + * @since 12.3 + * @throws RuntimeException + */ + public function transactionStart($asSavepoint = false) + { + $this->connect(); + + if (!$asSavepoint || !$this->transactionDepth) + { + return parent::transactionStart($asSavepoint); + } + + $savepoint = 'SP_' . $this->transactionDepth; + $this->setQuery('SAVEPOINT ' . $this->quoteName($savepoint)); + + if ($this->execute()) + { + $this->transactionDepth++; + } + } +} diff --git a/Sites/pages/libraries/fof/database/driver/pdo.php b/Sites/pages/libraries/fof/database/driver/pdo.php new file mode 100644 index 00000000..ebc59eff --- /dev/null +++ b/Sites/pages/libraries/fof/database/driver/pdo.php @@ -0,0 +1,1106 @@ +disconnect(); + } + + /** + * Connects to the database if needed. + * + * @return void Returns void if the database connected successfully. + * + * @since 12.1 + * @throws RuntimeException + */ + public function connect() + { + if ($this->connection) + { + return; + } + + // Make sure the PDO extension for PHP is installed and enabled. + if (!self::isSupported()) + { + throw new RuntimeException('PDO Extension is not available.', 1); + } + + $replace = array(); + $with = array(); + + // Find the correct PDO DSN Format to use: + switch ($this->options['driver']) + { + case 'cubrid': + $this->options['port'] = (isset($this->options['port'])) ? $this->options['port'] : 33000; + + $format = 'cubrid:host=#HOST#;port=#PORT#;dbname=#DBNAME#'; + + $replace = array('#HOST#', '#PORT#', '#DBNAME#'); + $with = array($this->options['host'], $this->options['port'], $this->options['database']); + + break; + + case 'dblib': + $this->options['port'] = (isset($this->options['port'])) ? $this->options['port'] : 1433; + + $format = 'dblib:host=#HOST#;port=#PORT#;dbname=#DBNAME#'; + + $replace = array('#HOST#', '#PORT#', '#DBNAME#'); + $with = array($this->options['host'], $this->options['port'], $this->options['database']); + + break; + + case 'firebird': + $this->options['port'] = (isset($this->options['port'])) ? $this->options['port'] : 3050; + + $format = 'firebird:dbname=#DBNAME#'; + + $replace = array('#DBNAME#'); + $with = array($this->options['database']); + + break; + + case 'ibm': + $this->options['port'] = (isset($this->options['port'])) ? $this->options['port'] : 56789; + + if (!empty($this->options['dsn'])) + { + $format = 'ibm:DSN=#DSN#'; + + $replace = array('#DSN#'); + $with = array($this->options['dsn']); + } + else + { + $format = 'ibm:hostname=#HOST#;port=#PORT#;database=#DBNAME#'; + + $replace = array('#HOST#', '#PORT#', '#DBNAME#'); + $with = array($this->options['host'], $this->options['port'], $this->options['database']); + } + + break; + + case 'informix': + $this->options['port'] = (isset($this->options['port'])) ? $this->options['port'] : 1526; + $this->options['protocol'] = (isset($this->options['protocol'])) ? $this->options['protocol'] : 'onsoctcp'; + + if (!empty($this->options['dsn'])) + { + $format = 'informix:DSN=#DSN#'; + + $replace = array('#DSN#'); + $with = array($this->options['dsn']); + } + else + { + $format = 'informix:host=#HOST#;service=#PORT#;database=#DBNAME#;server=#SERVER#;protocol=#PROTOCOL#'; + + $replace = array('#HOST#', '#PORT#', '#DBNAME#', '#SERVER#', '#PROTOCOL#'); + $with = array($this->options['host'], $this->options['port'], $this->options['database'], $this->options['server'], $this->options['protocol']); + } + + break; + + case 'mssql': + $this->options['port'] = (isset($this->options['port'])) ? $this->options['port'] : 1433; + + $format = 'mssql:host=#HOST#;port=#PORT#;dbname=#DBNAME#'; + + $replace = array('#HOST#', '#PORT#', '#DBNAME#'); + $with = array($this->options['host'], $this->options['port'], $this->options['database']); + + break; + + // The pdomysql case is a special case within the CMS environment + case 'pdomysql': + case 'mysql': + $this->options['port'] = (isset($this->options['port'])) ? $this->options['port'] : 3306; + + $format = 'mysql:host=#HOST#;port=#PORT#;dbname=#DBNAME#;charset=#CHARSET#'; + + $replace = array('#HOST#', '#PORT#', '#DBNAME#', '#CHARSET#'); + $with = array($this->options['host'], $this->options['port'], $this->options['database'], $this->options['charset']); + + break; + + case 'oci': + $this->options['port'] = (isset($this->options['port'])) ? $this->options['port'] : 1521; + $this->options['charset'] = (isset($this->options['charset'])) ? $this->options['charset'] : 'AL32UTF8'; + + if (!empty($this->options['dsn'])) + { + $format = 'oci:dbname=#DSN#'; + + $replace = array('#DSN#'); + $with = array($this->options['dsn']); + } + else + { + $format = 'oci:dbname=//#HOST#:#PORT#/#DBNAME#'; + + $replace = array('#HOST#', '#PORT#', '#DBNAME#'); + $with = array($this->options['host'], $this->options['port'], $this->options['database']); + } + + $format .= ';charset=' . $this->options['charset']; + + break; + + case 'odbc': + $format = 'odbc:DSN=#DSN#;UID:#USER#;PWD=#PASSWORD#'; + + $replace = array('#DSN#', '#USER#', '#PASSWORD#'); + $with = array($this->options['dsn'], $this->options['user'], $this->options['password']); + + break; + + case 'pgsql': + $this->options['port'] = (isset($this->options['port'])) ? $this->options['port'] : 5432; + + $format = 'pgsql:host=#HOST#;port=#PORT#;dbname=#DBNAME#'; + + $replace = array('#HOST#', '#PORT#', '#DBNAME#'); + $with = array($this->options['host'], $this->options['port'], $this->options['database']); + + break; + + case 'sqlite': + if (isset($this->options['version']) && $this->options['version'] == 2) + { + $format = 'sqlite2:#DBNAME#'; + } + else + { + $format = 'sqlite:#DBNAME#'; + } + + $replace = array('#DBNAME#'); + $with = array($this->options['database']); + + break; + + case 'sybase': + $this->options['port'] = (isset($this->options['port'])) ? $this->options['port'] : 1433; + + $format = 'mssql:host=#HOST#;port=#PORT#;dbname=#DBNAME#'; + + $replace = array('#HOST#', '#PORT#', '#DBNAME#'); + $with = array($this->options['host'], $this->options['port'], $this->options['database']); + + break; + } + + // Create the connection string: + $connectionString = str_replace($replace, $with, $format); + + try + { + $this->connection = new PDO( + $connectionString, + $this->options['user'], + $this->options['password'], + $this->options['driverOptions'] + ); + } + catch (PDOException $e) + { + throw new RuntimeException('Could not connect to PDO: ' . $e->getMessage(), 2, $e); + } + } + + /** + * Disconnects the database. + * + * @return void + * + * @since 12.1 + */ + public function disconnect() + { + foreach ($this->disconnectHandlers as $h) + { + call_user_func_array($h, array( &$this)); + } + + $this->freeResult(); + unset($this->connection); + } + + /** + * Method to escape a string for usage in an SQL statement. + * + * Oracle escaping reference: + * http://www.orafaq.com/wiki/SQL_FAQ#How_does_one_escape_special_characters_when_writing_SQL_queries.3F + * + * SQLite escaping notes: + * http://www.sqlite.org/faq.html#q14 + * + * Method body is as implemented by the Zend Framework + * + * Note: Using query objects with bound variables is + * preferable to the below. + * + * @param string $text The string to be escaped. + * @param boolean $extra Unused optional parameter to provide extra escaping. + * + * @return string The escaped string. + * + * @since 12.1 + */ + public function escape($text, $extra = false) + { + if (is_int($text) || is_float($text)) + { + return $text; + } + + $text = str_replace("'", "''", $text); + + return addcslashes($text, "\000\n\r\\\032"); + } + + /** + * Execute the SQL statement. + * + * @return mixed A database cursor resource on success, boolean false on failure. + * + * @since 12.1 + * @throws RuntimeException + * @throws Exception + */ + public function execute() + { + $this->connect(); + + if (!is_object($this->connection)) + { + if (class_exists('JLog')) + { + JLog::add(JText::sprintf('JLIB_DATABASE_QUERY_FAILED', $this->errorNum, $this->errorMsg), JLog::ERROR, 'database'); + } + throw new RuntimeException($this->errorMsg, $this->errorNum); + } + + // Take a local copy so that we don't modify the original query and cause issues later + $query = $this->replacePrefix((string) $this->sql); + + if (!($this->sql instanceof FOFDatabaseQuery) && ($this->limit > 0 || $this->offset > 0)) + { + // @TODO + $query .= ' LIMIT ' . $this->offset . ', ' . $this->limit; + } + + // Increment the query counter. + $this->count++; + + // Reset the error values. + $this->errorNum = 0; + $this->errorMsg = ''; + + // If debugging is enabled then let's log the query. + if ($this->debug) + { + // Add the query to the object queue. + $this->log[] = $query; + + if (class_exists('JLog')) + { + JLog::add($query, JLog::DEBUG, 'databasequery'); + } + + $this->timings[] = microtime(true); + } + + // Execute the query. + $this->executed = false; + + if ($this->prepared instanceof PDOStatement) + { + // Bind the variables: + if ($this->sql instanceof FOFDatabaseQueryPreparable) + { + $bounded = $this->sql->getBounded(); + + foreach ($bounded as $key => $obj) + { + $this->prepared->bindParam($key, $obj->value, $obj->dataType, $obj->length, $obj->driverOptions); + } + } + + $this->executed = $this->prepared->execute(); + } + + if ($this->debug) + { + $this->timings[] = microtime(true); + + if (defined('DEBUG_BACKTRACE_IGNORE_ARGS')) + { + $this->callStacks[] = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); + } + else + { + $this->callStacks[] = debug_backtrace(); + } + } + + // If an error occurred handle it. + if (!$this->executed) + { + // Get the error number and message before we execute any more queries. + $errorNum = $this->getErrorNumber(); + $errorMsg = $this->getErrorMessage($query); + + // Check if the server was disconnected. + if (!$this->connected()) + { + try + { + // Attempt to reconnect. + $this->connection = null; + $this->connect(); + } + // If connect fails, ignore that exception and throw the normal exception. + catch (RuntimeException $e) + { + // Get the error number and message. + $this->errorNum = $this->getErrorNumber(); + $this->errorMsg = $this->getErrorMessage($query); + + // Throw the normal query exception. + if (class_exists('JLog')) + { + JLog::add(JText::sprintf('JLIB_DATABASE_QUERY_FAILED', $this->errorNum, $this->errorMsg), JLog::ERROR, 'database-error'); + } + + throw new RuntimeException($this->errorMsg, $this->errorNum, $e); + } + + // Since we were able to reconnect, run the query again. + return $this->execute(); + } + // The server was not disconnected. + else + { + // Get the error number and message from before we tried to reconnect. + $this->errorNum = $errorNum; + $this->errorMsg = $errorMsg; + + // Throw the normal query exception. + if (class_exists('JLog')) + { + JLog::add(JText::sprintf('JLIB_DATABASE_QUERY_FAILED', $this->errorNum, $this->errorMsg), JLog::ERROR, 'database-error'); + } + + throw new RuntimeException($this->errorMsg, $this->errorNum); + } + } + + return $this->prepared; + } + + /** + * Retrieve a PDO database connection attribute + * http://www.php.net/manual/en/pdo.getattribute.php + * + * Usage: $db->getOption(PDO::ATTR_CASE); + * + * @param mixed $key One of the PDO::ATTR_* Constants + * + * @return mixed + * + * @since 12.1 + */ + public function getOption($key) + { + $this->connect(); + + return $this->connection->getAttribute($key); + } + + /** + * Get a query to run and verify the database is operational. + * + * @return string The query to check the health of the DB. + * + * @since 12.2 + */ + public function getConnectedQuery() + { + return 'SELECT 1'; + } + + /** + * Sets an attribute on the PDO database handle. + * http://www.php.net/manual/en/pdo.setattribute.php + * + * Usage: $db->setOption(PDO::ATTR_CASE, PDO::CASE_UPPER); + * + * @param integer $key One of the PDO::ATTR_* Constants + * @param mixed $value One of the associated PDO Constants + * related to the particular attribute + * key. + * + * @return boolean + * + * @since 12.1 + */ + public function setOption($key, $value) + { + $this->connect(); + + return $this->connection->setAttribute($key, $value); + } + + /** + * Test to see if the PDO extension is available. + * Override as needed to check for specific PDO Drivers. + * + * @return boolean True on success, false otherwise. + * + * @since 12.1 + */ + public static function isSupported() + { + return defined('PDO::ATTR_DRIVER_NAME'); + } + + /** + * Determines if the connection to the server is active. + * + * @return boolean True if connected to the database engine. + * + * @since 12.1 + */ + public function connected() + { + // Flag to prevent recursion into this function. + static $checkingConnected = false; + + if ($checkingConnected) + { + // Reset this flag and throw an exception. + $checkingConnected = true; + die('Recursion trying to check if connected.'); + } + + // Backup the query state. + $query = $this->sql; + $limit = $this->limit; + $offset = $this->offset; + $prepared = $this->prepared; + + try + { + // Set the checking connection flag. + $checkingConnected = true; + + // Run a simple query to check the connection. + $this->setQuery($this->getConnectedQuery()); + $status = (bool) $this->loadResult(); + } + // If we catch an exception here, we must not be connected. + catch (Exception $e) + { + $status = false; + } + + // Restore the query state. + $this->sql = $query; + $this->limit = $limit; + $this->offset = $offset; + $this->prepared = $prepared; + $checkingConnected = false; + + return $status; + } + + /** + * Get the number of affected rows for the previous executed SQL statement. + * Only applicable for DELETE, INSERT, or UPDATE statements. + * + * @return integer The number of affected rows. + * + * @since 12.1 + */ + public function getAffectedRows() + { + $this->connect(); + + if ($this->prepared instanceof PDOStatement) + { + return $this->prepared->rowCount(); + } + else + { + return 0; + } + } + + /** + * Get the number of returned rows for the previous executed SQL statement. + * Only applicable for DELETE, INSERT, or UPDATE statements. + * + * @param resource $cursor An optional database cursor resource to extract the row count from. + * + * @return integer The number of returned rows. + * + * @since 12.1 + */ + public function getNumRows($cursor = null) + { + $this->connect(); + + if ($cursor instanceof PDOStatement) + { + return $cursor->rowCount(); + } + elseif ($this->prepared instanceof PDOStatement) + { + return $this->prepared->rowCount(); + } + else + { + return 0; + } + } + + /** + * Method to get the auto-incremented value from the last INSERT statement. + * + * @return string The value of the auto-increment field from the last inserted row. + * + * @since 12.1 + */ + public function insertid() + { + $this->connect(); + + // Error suppress this to prevent PDO warning us that the driver doesn't support this operation. + return @$this->connection->lastInsertId(); + } + + /** + * Select a database for use. + * + * @param string $database The name of the database to select for use. + * + * @return boolean True if the database was successfully selected. + * + * @since 12.1 + * @throws RuntimeException + */ + public function select($database) + { + $this->connect(); + + return true; + } + + /** + * Sets the SQL statement string for later execution. + * + * @param mixed $query The SQL statement to set either as a FOFDatabaseQuery object or a string. + * @param integer $offset The affected row offset to set. + * @param integer $limit The maximum affected rows to set. + * @param array $driverOptions The optional PDO driver options. + * + * @return FOFDatabaseDriver This object to support method chaining. + * + * @since 12.1 + */ + public function setQuery($query, $offset = null, $limit = null, $driverOptions = array()) + { + $this->connect(); + + $this->freeResult(); + + if (is_string($query)) + { + // Allows taking advantage of bound variables in a direct query: + $query = $this->getQuery(true)->setQuery($query); + } + + if ($query instanceof FOFDatabaseQueryLimitable && !is_null($offset) && !is_null($limit)) + { + $query = $query->processLimit($query, $limit, $offset); + } + + // Create a stringified version of the query (with prefixes replaced): + $sql = $this->replacePrefix((string) $query); + + // Use the stringified version in the prepare call: + $this->prepared = $this->connection->prepare($sql, $driverOptions); + + // Store reference to the original FOFDatabaseQuery instance within the class. + // This is important since binding variables depends on it within execute(): + parent::setQuery($query, $offset, $limit); + + return $this; + } + + /** + * Set the connection to use UTF-8 character encoding. + * + * @return boolean True on success. + * + * @since 12.1 + */ + public function setUtf() + { + return false; + } + + /** + * Method to commit a transaction. + * + * @param boolean $toSavepoint If true, commit to the last savepoint. + * + * @return void + * + * @since 12.1 + * @throws RuntimeException + */ + public function transactionCommit($toSavepoint = false) + { + $this->connect(); + + if (!$toSavepoint || $this->transactionDepth == 1) + { + $this->connection->commit(); + } + + $this->transactionDepth--; + } + + /** + * Method to roll back a transaction. + * + * @param boolean $toSavepoint If true, rollback to the last savepoint. + * + * @return void + * + * @since 12.1 + * @throws RuntimeException + */ + public function transactionRollback($toSavepoint = false) + { + $this->connect(); + + if (!$toSavepoint || $this->transactionDepth == 1) + { + $this->connection->rollBack(); + } + + $this->transactionDepth--; + } + + /** + * Method to initialize a transaction. + * + * @param boolean $asSavepoint If true and a transaction is already active, a savepoint will be created. + * + * @return void + * + * @since 12.1 + * @throws RuntimeException + */ + public function transactionStart($asSavepoint = false) + { + $this->connect(); + + if (!$asSavepoint || !$this->transactionDepth) + { + $this->connection->beginTransaction(); + } + + $this->transactionDepth++; + } + + /** + * Method to fetch a row from the result set cursor as an array. + * + * @param mixed $cursor The optional result set cursor from which to fetch the row. + * + * @return mixed Either the next row from the result set or false if there are no more rows. + * + * @since 12.1 + */ + protected function fetchArray($cursor = null) + { + if (!empty($cursor) && $cursor instanceof PDOStatement) + { + return $cursor->fetch(PDO::FETCH_NUM); + } + + if ($this->prepared instanceof PDOStatement) + { + return $this->prepared->fetch(PDO::FETCH_NUM); + } + } + + /** + * Method to fetch a row from the result set cursor as an associative array. + * + * @param mixed $cursor The optional result set cursor from which to fetch the row. + * + * @return mixed Either the next row from the result set or false if there are no more rows. + * + * @since 12.1 + */ + protected function fetchAssoc($cursor = null) + { + if (!empty($cursor) && $cursor instanceof PDOStatement) + { + return $cursor->fetch(PDO::FETCH_ASSOC); + } + + if ($this->prepared instanceof PDOStatement) + { + return $this->prepared->fetch(PDO::FETCH_ASSOC); + } + } + + /** + * Method to fetch a row from the result set cursor as an object. + * + * @param mixed $cursor The optional result set cursor from which to fetch the row. + * @param string $class Unused, only necessary so method signature will be the same as parent. + * + * @return mixed Either the next row from the result set or false if there are no more rows. + * + * @since 12.1 + */ + protected function fetchObject($cursor = null, $class = 'stdClass') + { + if (!empty($cursor) && $cursor instanceof PDOStatement) + { + return $cursor->fetchObject($class); + } + + if ($this->prepared instanceof PDOStatement) + { + return $this->prepared->fetchObject($class); + } + } + + /** + * Method to free up the memory used for the result set. + * + * @param mixed $cursor The optional result set cursor from which to fetch the row. + * + * @return void + * + * @since 12.1 + */ + protected function freeResult($cursor = null) + { + $this->executed = false; + + if ($cursor instanceof PDOStatement) + { + $cursor->closeCursor(); + $cursor = null; + } + + if ($this->prepared instanceof PDOStatement) + { + $this->prepared->closeCursor(); + $this->prepared = null; + } + } + + /** + * Method to get the next row in the result set from the database query as an object. + * + * @param string $class The class name to use for the returned row object. + * + * @return mixed The result of the query as an array, false if there are no more rows. + * + * @since 12.1 + * @throws RuntimeException + * @deprecated 4.0 (CMS) Use getIterator() instead + */ + public function loadNextObject($class = 'stdClass') + { + if (class_exists('JLog')) + { + JLog::add(__METHOD__ . '() is deprecated. Use FOFDatabaseDriver::getIterator() instead.', JLog::WARNING, 'deprecated'); + } + $this->connect(); + + // Execute the query and get the result set cursor. + if (!$this->executed) + { + if (!($this->execute())) + { + return $this->errorNum ? null : false; + } + } + + // Get the next row from the result set as an object of type $class. + if ($row = $this->fetchObject(null, $class)) + { + return $row; + } + + // Free up system resources and return. + $this->freeResult(); + + return false; + } + + /** + * Method to get the next row in the result set from the database query as an array. + * + * @return mixed The result of the query as an array, false if there are no more rows. + * + * @since 12.1 + * @throws RuntimeException + */ + public function loadNextAssoc() + { + $this->connect(); + + // Execute the query and get the result set cursor. + if (!$this->executed) + { + if (!($this->execute())) + { + return $this->errorNum ? null : false; + } + } + + // Get the next row from the result set as an object of type $class. + if ($row = $this->fetchAssoc()) + { + return $row; + } + + // Free up system resources and return. + $this->freeResult(); + + return false; + } + + /** + * Method to get the next row in the result set from the database query as an array. + * + * @return mixed The result of the query as an array, false if there are no more rows. + * + * @since 12.1 + * @throws RuntimeException + * @deprecated 4.0 (CMS) Use getIterator() instead + */ + public function loadNextRow() + { + if (class_exists('JLog')) + { + JLog::add(__METHOD__ . '() is deprecated. Use FOFDatabaseDriver::getIterator() instead.', JLog::WARNING, 'deprecated'); + } + $this->connect(); + + // Execute the query and get the result set cursor. + if (!$this->executed) + { + if (!($this->execute())) + { + return $this->errorNum ? null : false; + } + } + + // Get the next row from the result set as an object of type $class. + if ($row = $this->fetchArray()) + { + return $row; + } + + // Free up system resources and return. + $this->freeResult(); + + return false; + } + + /** + * PDO does not support serialize + * + * @return array + * + * @since 12.3 + */ + public function __sleep() + { + $serializedProperties = array(); + + $reflect = new ReflectionClass($this); + + // Get properties of the current class + $properties = $reflect->getProperties(); + + foreach ($properties as $property) + { + // Do not serialize properties that are PDO + if ($property->isStatic() == false && !($this->{$property->name} instanceof PDO)) + { + array_push($serializedProperties, $property->name); + } + } + + return $serializedProperties; + } + + /** + * Wake up after serialization + * + * @return array + * + * @since 12.3 + */ + public function __wakeup() + { + // Get connection back + $this->__construct($this->options); + } + + /** + * Return the actual SQL Error number + * + * @return integer The SQL Error number + * + * @since 3.4.6 + */ + protected function getErrorNumber() + { + return (int) $this->connection->errorCode(); + } + + /** + * Return the actual SQL Error message + * + * @param string $query The SQL Query that fails + * + * @return string The SQL Error message + * + * @since 3.4.6 + */ + protected function getErrorMessage($query) + { + // Note we ignoring $query here as it not used in the original code. + + // The SQL Error Information + $errorInfo = implode(", ", $this->connection->errorInfo()); + + // Replace the Databaseprefix with `#__` if we are not in Debug + if (!$this->debug) + { + $errorInfo = str_replace($this->tablePrefix, '#__', $errorInfo); + } + + return 'SQL: ' . $errorInfo; + } +} diff --git a/Sites/pages/libraries/fof/database/driver/pdomysql.php b/Sites/pages/libraries/fof/database/driver/pdomysql.php new file mode 100644 index 00000000..c0aa9fa0 --- /dev/null +++ b/Sites/pages/libraries/fof/database/driver/pdomysql.php @@ -0,0 +1,560 @@ +utf8mb4 = true; + + // Get some basic values from the options. + $options['driver'] = 'mysql'; + $options['charset'] = (isset($options['charset'])) ? $options['charset'] : 'utf8'; + + if ($this->utf8mb4 && ($options['charset'] == 'utf8')) + { + $options['charset'] = 'utf8mb4'; + } + + $this->charset = $options['charset']; + + // Finalize initialisation. + parent::__construct($options); + } + + /** + * Connects to the database if needed. + * + * @return void Returns void if the database connected successfully. + * + * @since 3.4 + * @throws RuntimeException + */ + public function connect() + { + try + { + // Try to connect to MySQL + parent::connect(); + } + catch (\RuntimeException $e) + { + // If the connection failed but not because of the wrong character set bubble up the exception + if (!$this->utf8mb4 || ($this->options['charset'] != 'utf8mb4')) + { + throw $e; + } + + /** + * If the connection failed and I was trying to use the utf8mb4 charset then it is likely that the server + * doesn't support utf8mb4 despite claiming otherwise. + * + * This happens on old MySQL server versions (less than 5.5.3) using the mysqlnd PHP driver. Since mysqlnd + * masks the server version and reports only its own we can not be sure if the server actually does support + * UTF-8 Multibyte (i.e. it's MySQL 5.5.3 or later). Since the utf8mb4 charset is undefined in this case we + * catch the error and determine that utf8mb4 is not supported! + */ + $this->utf8mb4 = false; + $this->options['charset'] = 'utf8'; + + parent::connect(); + } + + $this->connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + $this->connection->setAttribute(PDO::ATTR_EMULATE_PREPARES, true); + } + + /** + * Test to see if the MySQL connector is available. + * + * @return boolean True on success, false otherwise. + * + * @since 3.4 + */ + public static function isSupported() + { + return class_exists('PDO') && in_array('mysql', PDO::getAvailableDrivers()); + } + + /** + * Drops a table from the database. + * + * @param string $tableName The name of the database table to drop. + * @param boolean $ifExists Optionally specify that the table must exist before it is dropped. + * + * @return FOFDatabaseDriverPdomysql Returns this object to support chaining. + * + * @since 3.4 + * @throws RuntimeException + */ + public function dropTable($tableName, $ifExists = true) + { + $this->connect(); + + $query = $this->getQuery(true); + + $query->setQuery('DROP TABLE ' . ($ifExists ? 'IF EXISTS ' : '') . $this->quoteName($tableName)); + + $this->setQuery($query); + + $this->execute(); + + return $this; + } + + /** + * Select a database for use. + * + * @param string $database The name of the database to select for use. + * + * @return boolean True if the database was successfully selected. + * + * @since 3.4 + * @throws RuntimeException + */ + public function select($database) + { + $this->connect(); + + $this->setQuery('USE ' . $this->quoteName($database)); + + $this->execute(); + + return $this; + } + + /** + * Method to get the database collation in use by sampling a text field of a table in the database. + * + * @return mixed The collation in use by the database (string) or boolean false if not supported. + * + * @since 3.4 + * @throws RuntimeException + */ + public function getCollation() + { + $this->connect(); + + // Attempt to get the database collation by accessing the server system variable. + $this->setQuery('SHOW VARIABLES LIKE "collation_database"'); + $result = $this->loadObject(); + + if (property_exists($result, 'Value')) + { + return $result->Value; + } + else + { + return false; + } + } + + /** + * Method to get the database connection collation, as reported by the driver. If the connector doesn't support + * reporting this value please return an empty string. + * + * @return string + */ + public function getConnectionCollation() + { + $this->connect(); + + // Attempt to get the database collation by accessing the server system variable. + $this->setQuery('SHOW VARIABLES LIKE "collation_connection"'); + $result = $this->loadObject(); + + if (property_exists($result, 'Value')) + { + return $result->Value; + } + else + { + return false; + } + } + + /** + * Shows the table CREATE statement that creates the given tables. + * + * @param mixed $tables A table name or a list of table names. + * + * @return array A list of the create SQL for the tables. + * + * @since 3.4 + * @throws RuntimeException + */ + public function getTableCreate($tables) + { + $this->connect(); + + // Initialise variables. + $result = array(); + + // Sanitize input to an array and iterate over the list. + settype($tables, 'array'); + + foreach ($tables as $table) + { + $this->setQuery('SHOW CREATE TABLE ' . $this->quoteName($table)); + + $row = $this->loadRow(); + + // Populate the result array based on the create statements. + $result[$table] = $row[1]; + } + + return $result; + } + + /** + * Retrieves field information about a given table. + * + * @param string $table The name of the database table. + * @param boolean $typeOnly True to only return field types. + * + * @return array An array of fields for the database table. + * + * @since 3.4 + * @throws RuntimeException + */ + public function getTableColumns($table, $typeOnly = true) + { + $this->connect(); + + $result = array(); + + // Set the query to get the table fields statement. + $this->setQuery('SHOW FULL COLUMNS FROM ' . $this->quoteName($table)); + + $fields = $this->loadObjectList(); + + // If we only want the type as the value add just that to the list. + if ($typeOnly) + { + foreach ($fields as $field) + { + $result[$field->Field] = preg_replace("/[(0-9)]/", '', $field->Type); + } + } + // If we want the whole field data object add that to the list. + else + { + foreach ($fields as $field) + { + $result[$field->Field] = $field; + } + } + + return $result; + } + + /** + * Get the details list of keys for a table. + * + * @param string $table The name of the table. + * + * @return array An array of the column specification for the table. + * + * @since 3.4 + * @throws RuntimeException + */ + public function getTableKeys($table) + { + $this->connect(); + + // Get the details columns information. + $this->setQuery('SHOW KEYS FROM ' . $this->quoteName($table)); + + $keys = $this->loadObjectList(); + + return $keys; + } + + /** + * Method to get an array of all tables in the database. + * + * @return array An array of all the tables in the database. + * + * @since 3.4 + * @throws RuntimeException + */ + public function getTableList() + { + $this->connect(); + + // Set the query to get the tables statement. + $this->setQuery('SHOW TABLES'); + $tables = $this->loadColumn(); + + return $tables; + } + + /** + * Get the version of the database connector. + * + * @return string The database connector version. + * + * @since 3.4 + */ + public function getVersion() + { + $this->connect(); + + return $this->getOption(PDO::ATTR_SERVER_VERSION); + } + + /** + * Locks a table in the database. + * + * @param string $table The name of the table to unlock. + * + * @return FOFDatabaseDriverPdomysql Returns this object to support chaining. + * + * @since 3.4 + * @throws RuntimeException + */ + public function lockTable($table) + { + $this->setQuery('LOCK TABLES ' . $this->quoteName($table) . ' WRITE')->execute(); + + return $this; + } + + /** + * Renames a table in the database. + * + * @param string $oldTable The name of the table to be renamed + * @param string $newTable The new name for the table. + * @param string $backup Not used by MySQL. + * @param string $prefix Not used by MySQL. + * + * @return FOFDatabaseDriverPdomysql Returns this object to support chaining. + * + * @since 3.4 + * @throws RuntimeException + */ + public function renameTable($oldTable, $newTable, $backup = null, $prefix = null) + { + $this->setQuery('RENAME TABLE ' . $this->quoteName($oldTable) . ' TO ' . $this->quoteName($newTable)); + + $this->execute(); + + return $this; + } + + /** + * Method to escape a string for usage in an SQL statement. + * + * Oracle escaping reference: + * http://www.orafaq.com/wiki/SQL_FAQ#How_does_one_escape_special_characters_when_writing_SQL_queries.3F + * + * SQLite escaping notes: + * http://www.sqlite.org/faq.html#q14 + * + * Method body is as implemented by the Zend Framework + * + * Note: Using query objects with bound variables is + * preferable to the below. + * + * @param string $text The string to be escaped. + * @param boolean $extra Unused optional parameter to provide extra escaping. + * + * @return string The escaped string. + * + * @since 3.4 + */ + public function escape($text, $extra = false) + { + $this->connect(); + + if (is_int($text) || is_float($text)) + { + return $text; + } + + $result = substr($this->connection->quote($text), 1, -1); + + if ($extra) + { + $result = addcslashes($result, '%_'); + } + + return $result; + } + + /** + * Unlocks tables in the database. + * + * @return FOFDatabaseDriverPdomysql Returns this object to support chaining. + * + * @since 3.4 + * @throws RuntimeException + */ + public function unlockTables() + { + $this->setQuery('UNLOCK TABLES')->execute(); + + return $this; + } + + /** + * Method to commit a transaction. + * + * @param boolean $toSavepoint If true, commit to the last savepoint. + * + * @return void + * + * @since 3.4 + * @throws RuntimeException + */ + public function transactionCommit($toSavepoint = false) + { + $this->connect(); + + if (!$toSavepoint || $this->transactionDepth <= 1) + { + parent::transactionCommit($toSavepoint); + } + else + { + $this->transactionDepth--; + } + } + + /** + * Method to roll back a transaction. + * + * @param boolean $toSavepoint If true, rollback to the last savepoint. + * + * @return void + * + * @since 3.4 + * @throws RuntimeException + */ + public function transactionRollback($toSavepoint = false) + { + $this->connect(); + + if (!$toSavepoint || $this->transactionDepth <= 1) + { + parent::transactionRollback($toSavepoint); + } + else + { + $savepoint = 'SP_' . ($this->transactionDepth - 1); + $this->setQuery('ROLLBACK TO SAVEPOINT ' . $this->quoteName($savepoint)); + + if ($this->execute()) + { + $this->transactionDepth--; + } + } + } + + /** + * Method to initialize a transaction. + * + * @param boolean $asSavepoint If true and a transaction is already active, a savepoint will be created. + * + * @return void + * + * @since 3.4 + * @throws RuntimeException + */ + public function transactionStart($asSavepoint = false) + { + $this->connect(); + + if (!$asSavepoint || !$this->transactionDepth) + { + parent::transactionStart($asSavepoint); + } + else + { + $savepoint = 'SP_' . $this->transactionDepth; + $this->setQuery('SAVEPOINT ' . $this->quoteName($savepoint)); + + if ($this->execute()) + { + $this->transactionDepth++; + } + } + } +} diff --git a/Sites/pages/libraries/fof/database/driver/postgresql.php b/Sites/pages/libraries/fof/database/driver/postgresql.php new file mode 100644 index 00000000..0869fe01 --- /dev/null +++ b/Sites/pages/libraries/fof/database/driver/postgresql.php @@ -0,0 +1,1530 @@ +disconnect(); + } + + /** + * Connects to the database if needed. + * + * @return void Returns void if the database connected successfully. + * + * @since 12.1 + * @throws RuntimeException + */ + public function connect() + { + if ($this->connection) + { + return; + } + + // Make sure the postgresql extension for PHP is installed and enabled. + if (!function_exists('pg_connect')) + { + throw new RuntimeException('PHP extension pg_connect is not available.'); + } + + // Build the DSN for the connection. + $dsn = ''; + + if (!empty($this->options['host'])) + { + $dsn .= "host={$this->options['host']} "; + } + + $dsn .= "dbname={$this->options['database']} user={$this->options['user']} password={$this->options['password']}"; + + // Attempt to connect to the server. + if (!($this->connection = @pg_connect($dsn))) + { + throw new RuntimeException('Error connecting to PGSQL database.'); + } + + pg_set_error_verbosity($this->connection, PGSQL_ERRORS_DEFAULT); + pg_query('SET standard_conforming_strings=off'); + pg_query('SET escape_string_warning=off'); + } + + /** + * Disconnects the database. + * + * @return void + * + * @since 12.1 + */ + public function disconnect() + { + // Close the connection. + if (is_resource($this->connection)) + { + foreach ($this->disconnectHandlers as $h) + { + call_user_func_array($h, array( &$this)); + } + + pg_close($this->connection); + } + + $this->connection = null; + } + + /** + * Method to escape a string for usage in an SQL statement. + * + * @param string $text The string to be escaped. + * @param boolean $extra Optional parameter to provide extra escaping. + * + * @return string The escaped string. + * + * @since 12.1 + */ + public function escape($text, $extra = false) + { + $this->connect(); + + $result = pg_escape_string($this->connection, $text); + + if ($extra) + { + $result = addcslashes($result, '%_'); + } + + return $result; + } + + /** + * Test to see if the PostgreSQL connector is available + * + * @return boolean True on success, false otherwise. + * + * @since 12.1 + */ + public static function test() + { + return (function_exists('pg_connect')); + } + + /** + * Determines if the connection to the server is active. + * + * @return boolean + * + * @since 12.1 + */ + public function connected() + { + $this->connect(); + + if (is_resource($this->connection)) + { + return pg_ping($this->connection); + } + + return false; + } + + /** + * Drops a table from the database. + * + * @param string $tableName The name of the database table to drop. + * @param boolean $ifExists Optionally specify that the table must exist before it is dropped. + * + * @return boolean + * + * @since 12.1 + * @throws RuntimeException + */ + public function dropTable($tableName, $ifExists = true) + { + $this->connect(); + + $this->setQuery('DROP TABLE ' . ($ifExists ? 'IF EXISTS ' : '') . $this->quoteName($tableName)); + $this->execute(); + + return true; + } + + /** + * Get the number of affected rows by the last INSERT, UPDATE, REPLACE or DELETE for the previous executed SQL statement. + * + * @return integer The number of affected rows in the previous operation + * + * @since 12.1 + */ + public function getAffectedRows() + { + $this->connect(); + + return pg_affected_rows($this->cursor); + } + + /** + * Method to get the database collation in use by sampling a text field of a table in the database. + * + * @return mixed The collation in use by the database or boolean false if not supported. + * + * @since 12.1 + * @throws RuntimeException + */ + public function getCollation() + { + $this->connect(); + + $this->setQuery('SHOW LC_COLLATE'); + $array = $this->loadAssocList(); + + return $array[0]['lc_collate']; + } + + /** + * Method to get the database connection collation, as reported by the driver. If the connector doesn't support + * reporting this value please return an empty string. + * + * @return string + */ + public function getConnectionCollation() + { + return pg_client_encoding($this->connection); + } + + /** + * Get the number of returned rows for the previous executed SQL statement. + * This command is only valid for statements like SELECT or SHOW that return an actual result set. + * To retrieve the number of rows affected by a INSERT, UPDATE, REPLACE or DELETE query, use getAffectedRows(). + * + * @param resource $cur An optional database cursor resource to extract the row count from. + * + * @return integer The number of returned rows. + * + * @since 12.1 + */ + public function getNumRows($cur = null) + { + $this->connect(); + + return pg_num_rows((int) $cur ? $cur : $this->cursor); + } + + /** + * Get the current or query, or new FOFDatabaseQuery object. + * + * @param boolean $new False to return the last query set, True to return a new FOFDatabaseQuery object. + * @param boolean $asObj False to return last query as string, true to get FOFDatabaseQueryPostgresql object. + * + * @return FOFDatabaseQuery The current query object or a new object extending the FOFDatabaseQuery class. + * + * @since 12.1 + * @throws RuntimeException + */ + public function getQuery($new = false, $asObj = false) + { + if ($new) + { + // Make sure we have a query class for this driver. + if (!class_exists('FOFDatabaseQueryPostgresql')) + { + throw new RuntimeException('FOFDatabaseQueryPostgresql Class not found.'); + } + + $this->queryObject = new FOFDatabaseQueryPostgresql($this); + + return $this->queryObject; + } + else + { + if ($asObj) + { + return $this->queryObject; + } + else + { + return $this->sql; + } + } + } + + /** + * Shows the table CREATE statement that creates the given tables. + * + * This is unsupported by PostgreSQL. + * + * @param mixed $tables A table name or a list of table names. + * + * @return string An empty char because this function is not supported by PostgreSQL. + * + * @since 12.1 + */ + public function getTableCreate($tables) + { + return ''; + } + + /** + * Retrieves field information about a given table. + * + * @param string $table The name of the database table. + * @param boolean $typeOnly True to only return field types. + * + * @return array An array of fields for the database table. + * + * @since 12.1 + * @throws RuntimeException + */ + public function getTableColumns($table, $typeOnly = true) + { + $this->connect(); + + $result = array(); + + $tableSub = $this->replacePrefix($table); + + $this->setQuery(' + SELECT a.attname AS "column_name", + pg_catalog.format_type(a.atttypid, a.atttypmod) as "type", + CASE WHEN a.attnotnull IS TRUE + THEN \'NO\' + ELSE \'YES\' + END AS "null", + CASE WHEN pg_catalog.pg_get_expr(adef.adbin, adef.adrelid, true) IS NOT NULL + THEN pg_catalog.pg_get_expr(adef.adbin, adef.adrelid, true) + END as "Default", + CASE WHEN pg_catalog.col_description(a.attrelid, a.attnum) IS NULL + THEN \'\' + ELSE pg_catalog.col_description(a.attrelid, a.attnum) + END AS "comments" + FROM pg_catalog.pg_attribute a + LEFT JOIN pg_catalog.pg_attrdef adef ON a.attrelid=adef.adrelid AND a.attnum=adef.adnum + LEFT JOIN pg_catalog.pg_type t ON a.atttypid=t.oid + WHERE a.attrelid = + (SELECT oid FROM pg_catalog.pg_class WHERE relname=' . $this->quote($tableSub) . ' + AND relnamespace = (SELECT oid FROM pg_catalog.pg_namespace WHERE + nspname = \'public\') + ) + AND a.attnum > 0 AND NOT a.attisdropped + ORDER BY a.attnum' + ); + + $fields = $this->loadObjectList(); + + if ($typeOnly) + { + foreach ($fields as $field) + { + $result[$field->column_name] = preg_replace("/[(0-9)]/", '', $field->type); + } + } + else + { + foreach ($fields as $field) + { + if (stristr(strtolower($field->type), "character varying")) + { + $field->Default = ""; + } + if (stristr(strtolower($field->type), "text")) + { + $field->Default = ""; + } + // Do some dirty translation to MySQL output. + // TODO: Come up with and implement a standard across databases. + $result[$field->column_name] = (object) array( + 'column_name' => $field->column_name, + 'type' => $field->type, + 'null' => $field->null, + 'Default' => $field->Default, + 'comments' => '', + 'Field' => $field->column_name, + 'Type' => $field->type, + 'Null' => $field->null, + // TODO: Improve query above to return primary key info as well + // 'Key' => ($field->PK == '1' ? 'PRI' : '') + ); + } + } + + /* Change Postgresql's NULL::* type with PHP's null one */ + foreach ($fields as $field) + { + if (preg_match("/^NULL::*/", $field->Default)) + { + $field->Default = null; + } + } + + return $result; + } + + /** + * Get the details list of keys for a table. + * + * @param string $table The name of the table. + * + * @return array An array of the column specification for the table. + * + * @since 12.1 + * @throws RuntimeException + */ + public function getTableKeys($table) + { + $this->connect(); + + // To check if table exists and prevent SQL injection + $tableList = $this->getTableList(); + + if (in_array($table, $tableList)) + { + // Get the details columns information. + $this->setQuery(' + SELECT indexname AS "idxName", indisprimary AS "isPrimary", indisunique AS "isUnique", + CASE WHEN indisprimary = true THEN + ( SELECT \'ALTER TABLE \' || tablename || \' ADD \' || pg_catalog.pg_get_constraintdef(const.oid, true) + FROM pg_constraint AS const WHERE const.conname= pgClassFirst.relname ) + ELSE pg_catalog.pg_get_indexdef(indexrelid, 0, true) + END AS "Query" + FROM pg_indexes + LEFT JOIN pg_class AS pgClassFirst ON indexname=pgClassFirst.relname + LEFT JOIN pg_index AS pgIndex ON pgClassFirst.oid=pgIndex.indexrelid + WHERE tablename=' . $this->quote($table) . ' ORDER BY indkey' + ); + + $keys = $this->loadObjectList(); + + return $keys; + } + + return false; + } + + /** + * Method to get an array of all tables in the database. + * + * @return array An array of all the tables in the database. + * + * @since 12.1 + * @throws RuntimeException + */ + public function getTableList() + { + $this->connect(); + + $query = $this->getQuery(true) + ->select('table_name') + ->from('information_schema.tables') + ->where('table_type=' . $this->quote('BASE TABLE')) + ->where('table_schema NOT IN (' . $this->quote('pg_catalog') . ', ' . $this->quote('information_schema') . ')') + ->order('table_name ASC'); + + $this->setQuery($query); + $tables = $this->loadColumn(); + + return $tables; + } + + /** + * Get the details list of sequences for a table. + * + * @param string $table The name of the table. + * + * @return array An array of sequences specification for the table. + * + * @since 12.1 + * @throws RuntimeException + */ + public function getTableSequences($table) + { + $this->connect(); + + // To check if table exists and prevent SQL injection + $tableList = $this->getTableList(); + + if (in_array($table, $tableList)) + { + $name = array( + 's.relname', 'n.nspname', 't.relname', 'a.attname', 'info.data_type', 'info.minimum_value', 'info.maximum_value', + 'info.increment', 'info.cycle_option' + ); + $as = array('sequence', 'schema', 'table', 'column', 'data_type', 'minimum_value', 'maximum_value', 'increment', 'cycle_option'); + + if (version_compare($this->getVersion(), '9.1.0') >= 0) + { + $name[] .= 'info.start_value'; + $as[] .= 'start_value'; + } + + // Get the details columns information. + $query = $this->getQuery(true) + ->select($this->quoteName($name, $as)) + ->from('pg_class AS s') + ->join('LEFT', "pg_depend d ON d.objid=s.oid AND d.classid='pg_class'::regclass AND d.refclassid='pg_class'::regclass") + ->join('LEFT', 'pg_class t ON t.oid=d.refobjid') + ->join('LEFT', 'pg_namespace n ON n.oid=t.relnamespace') + ->join('LEFT', 'pg_attribute a ON a.attrelid=t.oid AND a.attnum=d.refobjsubid') + ->join('LEFT', 'information_schema.sequences AS info ON info.sequence_name=s.relname') + ->where("s.relkind='S' AND d.deptype='a' AND t.relname=" . $this->quote($table)); + $this->setQuery($query); + $seq = $this->loadObjectList(); + + return $seq; + } + + return false; + } + + /** + * Get the version of the database connector. + * + * @return string The database connector version. + * + * @since 12.1 + */ + public function getVersion() + { + $this->connect(); + $version = pg_version($this->connection); + + return $version['server']; + } + + /** + * Method to get the auto-incremented value from the last INSERT statement. + * To be called after the INSERT statement, it's MANDATORY to have a sequence on + * every primary key table. + * + * To get the auto incremented value it's possible to call this function after + * INSERT INTO query, or use INSERT INTO with RETURNING clause. + * + * @example with insertid() call: + * $query = $this->getQuery(true) + * ->insert('jos_dbtest') + * ->columns('title,start_date,description') + * ->values("'testTitle2nd','1971-01-01','testDescription2nd'"); + * $this->setQuery($query); + * $this->execute(); + * $id = $this->insertid(); + * + * @example with RETURNING clause: + * $query = $this->getQuery(true) + * ->insert('jos_dbtest') + * ->columns('title,start_date,description') + * ->values("'testTitle2nd','1971-01-01','testDescription2nd'") + * ->returning('id'); + * $this->setQuery($query); + * $id = $this->loadResult(); + * + * @return integer The value of the auto-increment field from the last inserted row. + * + * @since 12.1 + */ + public function insertid() + { + $this->connect(); + $insertQuery = $this->getQuery(false, true); + $table = $insertQuery->__get('insert')->getElements(); + + /* find sequence column name */ + $colNameQuery = $this->getQuery(true); + $colNameQuery->select('column_default') + ->from('information_schema.columns') + ->where("table_name=" . $this->quote($this->replacePrefix(str_replace('"', '', $table[0]))), 'AND') + ->where("column_default LIKE '%nextval%'"); + + $this->setQuery($colNameQuery); + $colName = $this->loadRow(); + $changedColName = str_replace('nextval', 'currval', $colName); + + $insertidQuery = $this->getQuery(true); + $insertidQuery->select($changedColName); + $this->setQuery($insertidQuery); + $insertVal = $this->loadRow(); + + return $insertVal[0]; + } + + /** + * Locks a table in the database. + * + * @param string $tableName The name of the table to unlock. + * + * @return FOFDatabaseDriverPostgresql Returns this object to support chaining. + * + * @since 12.1 + * @throws RuntimeException + */ + public function lockTable($tableName) + { + $this->transactionStart(); + $this->setQuery('LOCK TABLE ' . $this->quoteName($tableName) . ' IN ACCESS EXCLUSIVE MODE')->execute(); + + return $this; + } + + /** + * Execute the SQL statement. + * + * @return mixed A database cursor resource on success, boolean false on failure. + * + * @since 12.1 + * @throws RuntimeException + */ + public function execute() + { + $this->connect(); + + if (!is_resource($this->connection)) + { + if (class_exists('JLog')) + { + JLog::add(JText::sprintf('JLIB_DATABASE_QUERY_FAILED', $this->errorNum, $this->errorMsg), JLog::ERROR, 'database'); + } + throw new RuntimeException($this->errorMsg, $this->errorNum); + } + + // Take a local copy so that we don't modify the original query and cause issues later + $query = $this->replacePrefix((string) $this->sql); + + if (!($this->sql instanceof FOFDatabaseQuery) && ($this->limit > 0 || $this->offset > 0)) + { + $query .= ' LIMIT ' . $this->limit . ' OFFSET ' . $this->offset; + } + + // Increment the query counter. + $this->count++; + + // Reset the error values. + $this->errorNum = 0; + $this->errorMsg = ''; + + // If debugging is enabled then let's log the query. + if ($this->debug) + { + // Add the query to the object queue. + $this->log[] = $query; + + if (class_exists('JLog')) + { + JLog::add($query, JLog::DEBUG, 'databasequery'); + } + + $this->timings[] = microtime(true); + } + + // Execute the query. Error suppression is used here to prevent warnings/notices that the connection has been lost. + $this->cursor = @pg_query($this->connection, $query); + + if ($this->debug) + { + $this->timings[] = microtime(true); + + if (defined('DEBUG_BACKTRACE_IGNORE_ARGS')) + { + $this->callStacks[] = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); + } + else + { + $this->callStacks[] = debug_backtrace(); + } + } + + // If an error occurred handle it. + if (!$this->cursor) + { + // Get the error number and message before we execute any more queries. + $errorNum = $this->getErrorNumber(); + $errorMsg = $this->getErrorMessage($query); + + // Check if the server was disconnected. + if (!$this->connected()) + { + try + { + // Attempt to reconnect. + $this->connection = null; + $this->connect(); + } + // If connect fails, ignore that exception and throw the normal exception. + catch (RuntimeException $e) + { + $this->errorNum = $this->getErrorNumber(); + $this->errorMsg = $this->getErrorMessage($query); + + // Throw the normal query exception. + if (class_exists('JLog')) + { + JLog::add(JText::sprintf('JLIB_DATABASE_QUERY_FAILED', $this->errorNum, $this->errorMsg), JLog::ERROR, 'database-error'); + } + + throw new RuntimeException($this->errorMsg, null, $e); + } + + // Since we were able to reconnect, run the query again. + return $this->execute(); + } + // The server was not disconnected. + else + { + // Get the error number and message from before we tried to reconnect. + $this->errorNum = $errorNum; + $this->errorMsg = $errorMsg; + + // Throw the normal query exception. + if (class_exists('JLog')) + { + JLog::add(JText::sprintf('JLIB_DATABASE_QUERY_FAILED', $this->errorNum, $this->errorMsg), JLog::ERROR, 'database-error'); + } + + throw new RuntimeException($this->errorMsg); + } + } + + return $this->cursor; + } + + /** + * Renames a table in the database. + * + * @param string $oldTable The name of the table to be renamed + * @param string $newTable The new name for the table. + * @param string $backup Not used by PostgreSQL. + * @param string $prefix Not used by PostgreSQL. + * + * @return FOFDatabaseDriverPostgresql Returns this object to support chaining. + * + * @since 12.1 + * @throws RuntimeException + */ + public function renameTable($oldTable, $newTable, $backup = null, $prefix = null) + { + $this->connect(); + + // To check if table exists and prevent SQL injection + $tableList = $this->getTableList(); + + // Origin Table does not exist + if (!in_array($oldTable, $tableList)) + { + // Origin Table not found + throw new RuntimeException('Table not found in Postgresql database.'); + } + else + { + /* Rename indexes */ + $this->setQuery( + 'SELECT relname + FROM pg_class + WHERE oid IN ( + SELECT indexrelid + FROM pg_index, pg_class + WHERE pg_class.relname=' . $this->quote($oldTable, true) . ' + AND pg_class.oid=pg_index.indrelid );' + ); + + $oldIndexes = $this->loadColumn(); + + foreach ($oldIndexes as $oldIndex) + { + $changedIdxName = str_replace($oldTable, $newTable, $oldIndex); + $this->setQuery('ALTER INDEX ' . $this->escape($oldIndex) . ' RENAME TO ' . $this->escape($changedIdxName)); + $this->execute(); + } + + /* Rename sequence */ + $this->setQuery( + 'SELECT relname + FROM pg_class + WHERE relkind = \'S\' + AND relnamespace IN ( + SELECT oid + FROM pg_namespace + WHERE nspname NOT LIKE \'pg_%\' + AND nspname != \'information_schema\' + ) + AND relname LIKE \'%' . $oldTable . '%\' ;' + ); + + $oldSequences = $this->loadColumn(); + + foreach ($oldSequences as $oldSequence) + { + $changedSequenceName = str_replace($oldTable, $newTable, $oldSequence); + $this->setQuery('ALTER SEQUENCE ' . $this->escape($oldSequence) . ' RENAME TO ' . $this->escape($changedSequenceName)); + $this->execute(); + } + + /* Rename table */ + $this->setQuery('ALTER TABLE ' . $this->escape($oldTable) . ' RENAME TO ' . $this->escape($newTable)); + $this->execute(); + } + + return true; + } + + /** + * Selects the database, but redundant for PostgreSQL + * + * @param string $database Database name to select. + * + * @return boolean Always true + * + * @since 12.1 + */ + public function select($database) + { + return true; + } + + /** + * Custom settings for UTF support + * + * @return integer Zero on success, -1 on failure + * + * @since 12.1 + */ + public function setUtf() + { + $this->connect(); + + return pg_set_client_encoding($this->connection, 'UTF8'); + } + + /** + * This function return a field value as a prepared string to be used in a SQL statement. + * + * @param array $columns Array of table's column returned by ::getTableColumns. + * @param string $field_name The table field's name. + * @param string $field_value The variable value to quote and return. + * + * @return string The quoted string. + * + * @since 12.1 + */ + public function sqlValue($columns, $field_name, $field_value) + { + switch ($columns[$field_name]) + { + case 'boolean': + $val = 'NULL'; + + if ($field_value == 't') + { + $val = 'TRUE'; + } + elseif ($field_value == 'f') + { + $val = 'FALSE'; + } + + break; + + case 'bigint': + case 'bigserial': + case 'integer': + case 'money': + case 'numeric': + case 'real': + case 'smallint': + case 'serial': + case 'numeric,': + $val = strlen($field_value) == 0 ? 'NULL' : $field_value; + break; + + case 'date': + case 'timestamp without time zone': + if (empty($field_value)) + { + $field_value = $this->getNullDate(); + } + + $val = $this->quote($field_value); + break; + + default: + $val = $this->quote($field_value); + break; + } + + return $val; + } + + /** + * Method to commit a transaction. + * + * @param boolean $toSavepoint If true, commit to the last savepoint. + * + * @return void + * + * @since 12.1 + * @throws RuntimeException + */ + public function transactionCommit($toSavepoint = false) + { + $this->connect(); + + if (!$toSavepoint || $this->transactionDepth <= 1) + { + if ($this->setQuery('COMMIT')->execute()) + { + $this->transactionDepth = 0; + } + + return; + } + + $this->transactionDepth--; + } + + /** + * Method to roll back a transaction. + * + * @param boolean $toSavepoint If true, rollback to the last savepoint. + * + * @return void + * + * @since 12.1 + * @throws RuntimeException + */ + public function transactionRollback($toSavepoint = false) + { + $this->connect(); + + if (!$toSavepoint || $this->transactionDepth <= 1) + { + if ($this->setQuery('ROLLBACK')->execute()) + { + $this->transactionDepth = 0; + } + + return; + } + + $savepoint = 'SP_' . ($this->transactionDepth - 1); + $this->setQuery('ROLLBACK TO SAVEPOINT ' . $this->quoteName($savepoint)); + + if ($this->execute()) + { + $this->transactionDepth--; + $this->setQuery('RELEASE SAVEPOINT ' . $this->quoteName($savepoint))->execute(); + } + } + + /** + * Method to initialize a transaction. + * + * @param boolean $asSavepoint If true and a transaction is already active, a savepoint will be created. + * + * @return void + * + * @since 12.1 + * @throws RuntimeException + */ + public function transactionStart($asSavepoint = false) + { + $this->connect(); + + if (!$asSavepoint || !$this->transactionDepth) + { + if ($this->setQuery('START TRANSACTION')->execute()) + { + $this->transactionDepth = 1; + } + + return; + } + + $savepoint = 'SP_' . $this->transactionDepth; + $this->setQuery('SAVEPOINT ' . $this->quoteName($savepoint)); + + if ($this->execute()) + { + $this->transactionDepth++; + } + } + + /** + * Method to fetch a row from the result set cursor as an array. + * + * @param mixed $cursor The optional result set cursor from which to fetch the row. + * + * @return mixed Either the next row from the result set or false if there are no more rows. + * + * @since 12.1 + */ + protected function fetchArray($cursor = null) + { + return pg_fetch_row($cursor ? $cursor : $this->cursor); + } + + /** + * Method to fetch a row from the result set cursor as an associative array. + * + * @param mixed $cursor The optional result set cursor from which to fetch the row. + * + * @return mixed Either the next row from the result set or false if there are no more rows. + * + * @since 12.1 + */ + protected function fetchAssoc($cursor = null) + { + return pg_fetch_assoc($cursor ? $cursor : $this->cursor); + } + + /** + * Method to fetch a row from the result set cursor as an object. + * + * @param mixed $cursor The optional result set cursor from which to fetch the row. + * @param string $class The class name to use for the returned row object. + * + * @return mixed Either the next row from the result set or false if there are no more rows. + * + * @since 12.1 + */ + protected function fetchObject($cursor = null, $class = 'stdClass') + { + return pg_fetch_object(is_null($cursor) ? $this->cursor : $cursor, null, $class); + } + + /** + * Method to free up the memory used for the result set. + * + * @param mixed $cursor The optional result set cursor from which to fetch the row. + * + * @return void + * + * @since 12.1 + */ + protected function freeResult($cursor = null) + { + pg_free_result($cursor ? $cursor : $this->cursor); + } + + /** + * Inserts a row into a table based on an object's properties. + * + * @param string $table The name of the database table to insert into. + * @param object &$object A reference to an object whose public properties match the table fields. + * @param string $key The name of the primary key. If provided the object property is updated. + * + * @return boolean True on success. + * + * @since 12.1 + * @throws RuntimeException + */ + public function insertObject($table, &$object, $key = null) + { + $columns = $this->getTableColumns($table); + + $fields = array(); + $values = array(); + + // Iterate over the object variables to build the query fields and values. + foreach (get_object_vars($object) as $k => $v) + { + // Only process non-null scalars. + if (is_array($v) or is_object($v) or $v === null) + { + continue; + } + + // Ignore any internal fields or primary keys with value 0. + if (($k[0] == "_") || ($k == $key && (($v === 0) || ($v === '0')))) + { + continue; + } + + // Prepare and sanitize the fields and values for the database query. + $fields[] = $this->quoteName($k); + $values[] = $this->sqlValue($columns, $k, $v); + } + + // Create the base insert statement. + $query = $this->getQuery(true) + ->insert($this->quoteName($table)) + ->columns($fields) + ->values(implode(',', $values)); + + $retVal = false; + + if ($key) + { + $query->returning($key); + + // Set the query and execute the insert. + $this->setQuery($query); + + $id = $this->loadResult(); + + if ($id) + { + $object->$key = $id; + $retVal = true; + } + } + else + { + // Set the query and execute the insert. + $this->setQuery($query); + + if ($this->execute()) + { + $retVal = true; + } + } + + return $retVal; + } + + /** + * Test to see if the PostgreSQL connector is available. + * + * @return boolean True on success, false otherwise. + * + * @since 12.1 + */ + public static function isSupported() + { + return (function_exists('pg_connect')); + } + + /** + * Returns an array containing database's table list. + * + * @return array The database's table list. + * + * @since 12.1 + */ + public function showTables() + { + $this->connect(); + + $query = $this->getQuery(true) + ->select('table_name') + ->from('information_schema.tables') + ->where('table_type = ' . $this->quote('BASE TABLE')) + ->where('table_schema NOT IN (' . $this->quote('pg_catalog') . ', ' . $this->quote('information_schema') . ' )'); + + $this->setQuery($query); + $tableList = $this->loadColumn(); + + return $tableList; + } + + /** + * Get the substring position inside a string + * + * @param string $substring The string being sought + * @param string $string The string/column being searched + * + * @return integer The position of $substring in $string + * + * @since 12.1 + */ + public function getStringPositionSql( $substring, $string ) + { + $this->connect(); + + $query = "SELECT POSITION( $substring IN $string )"; + $this->setQuery($query); + $position = $this->loadRow(); + + return $position['position']; + } + + /** + * Generate a random value + * + * @return float The random generated number + * + * @since 12.1 + */ + public function getRandom() + { + $this->connect(); + + $this->setQuery('SELECT RANDOM()'); + $random = $this->loadAssoc(); + + return $random['random']; + } + + /** + * Get the query string to alter the database character set. + * + * @param string $dbName The database name + * + * @return string The query that alter the database query string + * + * @since 12.1 + */ + public function getAlterDbCharacterSet( $dbName ) + { + $query = 'ALTER DATABASE ' . $this->quoteName($dbName) . ' SET CLIENT_ENCODING TO ' . $this->quote('UTF8'); + + return $query; + } + + /** + * Get the query string to create new Database in correct PostgreSQL syntax. + * + * @param object $options object coming from "initialise" function to pass user and database name to database driver. + * @param boolean $utf True if the database supports the UTF-8 character set, not used in PostgreSQL "CREATE DATABASE" query. + * + * @return string The query that creates database, owned by $options['user'] + * + * @since 12.1 + */ + public function getCreateDbQuery($options, $utf) + { + $query = 'CREATE DATABASE ' . $this->quoteName($options->db_name) . ' OWNER ' . $this->quoteName($options->db_user); + + if ($utf) + { + $query .= ' ENCODING ' . $this->quote('UTF-8'); + } + + return $query; + } + + /** + * This function replaces a string identifier $prefix with the string held is the + * tablePrefix class variable. + * + * @param string $query The SQL statement to prepare. + * @param string $prefix The common table prefix. + * + * @return string The processed SQL statement. + * + * @since 12.1 + */ + public function replacePrefix($query, $prefix = '#__') + { + $query = trim($query); + + if (strpos($query, '\'')) + { + // Sequence name quoted with ' ' but need to be replaced + if (strpos($query, 'currval')) + { + $query = explode('currval', $query); + + for ($nIndex = 1; $nIndex < count($query); $nIndex = $nIndex + 2) + { + $query[$nIndex] = str_replace($prefix, $this->tablePrefix, $query[$nIndex]); + } + + $query = implode('currval', $query); + } + + // Sequence name quoted with ' ' but need to be replaced + if (strpos($query, 'nextval')) + { + $query = explode('nextval', $query); + + for ($nIndex = 1; $nIndex < count($query); $nIndex = $nIndex + 2) + { + $query[$nIndex] = str_replace($prefix, $this->tablePrefix, $query[$nIndex]); + } + + $query = implode('nextval', $query); + } + + // Sequence name quoted with ' ' but need to be replaced + if (strpos($query, 'setval')) + { + $query = explode('setval', $query); + + for ($nIndex = 1; $nIndex < count($query); $nIndex = $nIndex + 2) + { + $query[$nIndex] = str_replace($prefix, $this->tablePrefix, $query[$nIndex]); + } + + $query = implode('setval', $query); + } + + $explodedQuery = explode('\'', $query); + + for ($nIndex = 0; $nIndex < count($explodedQuery); $nIndex = $nIndex + 2) + { + if (strpos($explodedQuery[$nIndex], $prefix)) + { + $explodedQuery[$nIndex] = str_replace($prefix, $this->tablePrefix, $explodedQuery[$nIndex]); + } + } + + $replacedQuery = implode('\'', $explodedQuery); + } + else + { + $replacedQuery = str_replace($prefix, $this->tablePrefix, $query); + } + + return $replacedQuery; + } + + /** + * Method to release a savepoint. + * + * @param string $savepointName Savepoint's name to release + * + * @return void + * + * @since 12.1 + */ + public function releaseTransactionSavepoint( $savepointName ) + { + $this->connect(); + $this->setQuery('RELEASE SAVEPOINT ' . $this->quoteName($this->escape($savepointName))); + $this->execute(); + } + + /** + * Method to create a savepoint. + * + * @param string $savepointName Savepoint's name to create + * + * @return void + * + * @since 12.1 + */ + public function transactionSavepoint( $savepointName ) + { + $this->connect(); + $this->setQuery('SAVEPOINT ' . $this->quoteName($this->escape($savepointName))); + $this->execute(); + } + + /** + * Unlocks tables in the database, this command does not exist in PostgreSQL, + * it is automatically done on commit or rollback. + * + * @return FOFDatabaseDriverPostgresql Returns this object to support chaining. + * + * @since 12.1 + * @throws RuntimeException + */ + public function unlockTables() + { + $this->transactionCommit(); + + return $this; + } + + /** + * Updates a row in a table based on an object's properties. + * + * @param string $table The name of the database table to update. + * @param object &$object A reference to an object whose public properties match the table fields. + * @param array $key The name of the primary key. + * @param boolean $nulls True to update null fields or false to ignore them. + * + * @return boolean True on success. + * + * @since 12.1 + * @throws RuntimeException + */ + public function updateObject($table, &$object, $key, $nulls = false) + { + $columns = $this->getTableColumns($table); + $fields = array(); + $where = array(); + + if (is_string($key)) + { + $key = array($key); + } + + if (is_object($key)) + { + $key = (array) $key; + } + + // Create the base update statement. + $statement = 'UPDATE ' . $this->quoteName($table) . ' SET %s WHERE %s'; + + // Iterate over the object variables to build the query fields/value pairs. + foreach (get_object_vars($object) as $k => $v) + { + // Only process scalars that are not internal fields. + if (is_array($v) or is_object($v) or $k[0] == '_') + { + continue; + } + + // Set the primary key to the WHERE clause instead of a field to update. + if (in_array($k, $key)) + { + $key_val = $this->sqlValue($columns, $k, $v); + $where[] = $this->quoteName($k) . '=' . $key_val; + continue; + } + + // Prepare and sanitize the fields and values for the database query. + if ($v === null) + { + // If the value is null and we want to update nulls then set it. + if ($nulls) + { + $val = 'NULL'; + } + // If the value is null and we do not want to update nulls then ignore this field. + else + { + continue; + } + } + // The field is not null so we prep it for update. + else + { + $val = $this->sqlValue($columns, $k, $v); + } + + // Add the field to be updated. + $fields[] = $this->quoteName($k) . '=' . $val; + } + + // We don't have any fields to update. + if (empty($fields)) + { + return true; + } + + // Set the query and execute the update. + $this->setQuery(sprintf($statement, implode(",", $fields), implode(' AND ', $where))); + + return $this->execute(); + } + + /** + * Return the actual SQL Error number + * + * @return integer The SQL Error number + * + * @since 3.4.6 + */ + protected function getErrorNumber() + { + return (int) pg_result_error_field($this->cursor, PGSQL_DIAG_SQLSTATE) . ' '; + } + + /** + * Return the actual SQL Error message + * + * @param string $query The SQL Query that fails + * + * @return string The SQL Error message + * + * @since 3.4.6 + */ + protected function getErrorMessage($query) + { + $errorMessage = (string) pg_last_error($this->connection); + + // Replace the Databaseprefix with `#__` if we are not in Debug + if (!$this->debug) + { + $errorMessage = str_replace($this->tablePrefix, '#__', $errorMessage); + $query = str_replace($this->tablePrefix, '#__', $query); + } + + return $errorMessage . "SQL=" . $query; + } +} diff --git a/Sites/pages/libraries/fof/database/driver/sqlazure.php b/Sites/pages/libraries/fof/database/driver/sqlazure.php new file mode 100644 index 00000000..90e0a4f8 --- /dev/null +++ b/Sites/pages/libraries/fof/database/driver/sqlazure.php @@ -0,0 +1,30 @@ +freeResult(); + unset($this->connection); + } + + /** + * Disconnects the database. + * + * @return void + * + * @since 12.1 + */ + public function disconnect() + { + $this->freeResult(); + unset($this->connection); + } + + /** + * Drops a table from the database. + * + * @param string $tableName The name of the database table to drop. + * @param boolean $ifExists Optionally specify that the table must exist before it is dropped. + * + * @return FOFDatabaseDriverSqlite Returns this object to support chaining. + * + * @since 12.1 + */ + public function dropTable($tableName, $ifExists = true) + { + $this->connect(); + + $query = $this->getQuery(true); + + $this->setQuery('DROP TABLE ' . ($ifExists ? 'IF EXISTS ' : '') . $query->quoteName($tableName)); + + $this->execute(); + + return $this; + } + + /** + * Method to escape a string for usage in an SQLite statement. + * + * Note: Using query objects with bound variables is + * preferable to the below. + * + * @param string $text The string to be escaped. + * @param boolean $extra Unused optional parameter to provide extra escaping. + * + * @return string The escaped string. + * + * @since 12.1 + */ + public function escape($text, $extra = false) + { + if (is_int($text) || is_float($text)) + { + return $text; + } + + return SQLite3::escapeString($text); + } + + /** + * Method to get the database collation in use by sampling a text field of a table in the database. + * + * @return mixed The collation in use by the database or boolean false if not supported. + * + * @since 12.1 + */ + public function getCollation() + { + return $this->charset; + } + + /** + * Method to get the database connection collation, as reported by the driver. If the connector doesn't support + * reporting this value please return an empty string. + * + * @return string + */ + public function getConnectionCollation() + { + return $this->charset; + } + + /** + * Shows the table CREATE statement that creates the given tables. + * + * Note: Doesn't appear to have support in SQLite + * + * @param mixed $tables A table name or a list of table names. + * + * @return array A list of the create SQL for the tables. + * + * @since 12.1 + * @throws RuntimeException + */ + public function getTableCreate($tables) + { + $this->connect(); + + // Sanitize input to an array and iterate over the list. + settype($tables, 'array'); + + return $tables; + } + + /** + * Retrieves field information about a given table. + * + * @param string $table The name of the database table. + * @param boolean $typeOnly True to only return field types. + * + * @return array An array of fields for the database table. + * + * @since 12.1 + * @throws RuntimeException + */ + public function getTableColumns($table, $typeOnly = true) + { + $this->connect(); + + $columns = array(); + $query = $this->getQuery(true); + + $fieldCasing = $this->getOption(PDO::ATTR_CASE); + + $this->setOption(PDO::ATTR_CASE, PDO::CASE_UPPER); + + $table = strtoupper($table); + + $query->setQuery('pragma table_info(' . $table . ')'); + + $this->setQuery($query); + $fields = $this->loadObjectList(); + + if ($typeOnly) + { + foreach ($fields as $field) + { + $columns[$field->NAME] = $field->TYPE; + } + } + else + { + foreach ($fields as $field) + { + // Do some dirty translation to MySQL output. + // TODO: Come up with and implement a standard across databases. + $columns[$field->NAME] = (object) array( + 'Field' => $field->NAME, + 'Type' => $field->TYPE, + 'Null' => ($field->NOTNULL == '1' ? 'NO' : 'YES'), + 'Default' => $field->DFLT_VALUE, + 'Key' => ($field->PK != '0' ? 'PRI' : '') + ); + } + } + + $this->setOption(PDO::ATTR_CASE, $fieldCasing); + + return $columns; + } + + /** + * Get the details list of keys for a table. + * + * @param string $table The name of the table. + * + * @return array An array of the column specification for the table. + * + * @since 12.1 + * @throws RuntimeException + */ + public function getTableKeys($table) + { + $this->connect(); + + $keys = array(); + $query = $this->getQuery(true); + + $fieldCasing = $this->getOption(PDO::ATTR_CASE); + + $this->setOption(PDO::ATTR_CASE, PDO::CASE_UPPER); + + $table = strtoupper($table); + $query->setQuery('pragma table_info( ' . $table . ')'); + + // $query->bind(':tableName', $table); + + $this->setQuery($query); + $rows = $this->loadObjectList(); + + foreach ($rows as $column) + { + if ($column->PK == 1) + { + $keys[$column->NAME] = $column; + } + } + + $this->setOption(PDO::ATTR_CASE, $fieldCasing); + + return $keys; + } + + /** + * Method to get an array of all tables in the database (schema). + * + * @return array An array of all the tables in the database. + * + * @since 12.1 + * @throws RuntimeException + */ + public function getTableList() + { + $this->connect(); + + $type = 'table'; + + $query = $this->getQuery(true) + ->select('name') + ->from('sqlite_master') + ->where('type = :type') + ->bind(':type', $type) + ->order('name'); + + $this->setQuery($query); + + $tables = $this->loadColumn(); + + return $tables; + } + + /** + * Get the version of the database connector. + * + * @return string The database connector version. + * + * @since 12.1 + */ + public function getVersion() + { + $this->connect(); + + $this->setQuery("SELECT sqlite_version()"); + + return $this->loadResult(); + } + + /** + * Select a database for use. + * + * @param string $database The name of the database to select for use. + * + * @return boolean True if the database was successfully selected. + * + * @since 12.1 + * @throws RuntimeException + */ + public function select($database) + { + $this->connect(); + + return true; + } + + /** + * Set the connection to use UTF-8 character encoding. + * + * Returns false automatically for the Oracle driver since + * you can only set the character set when the connection + * is created. + * + * @return boolean True on success. + * + * @since 12.1 + */ + public function setUtf() + { + $this->connect(); + + return false; + } + + /** + * Locks a table in the database. + * + * @param string $table The name of the table to unlock. + * + * @return FOFDatabaseDriverSqlite Returns this object to support chaining. + * + * @since 12.1 + * @throws RuntimeException + */ + public function lockTable($table) + { + return $this; + } + + /** + * Renames a table in the database. + * + * @param string $oldTable The name of the table to be renamed + * @param string $newTable The new name for the table. + * @param string $backup Not used by Sqlite. + * @param string $prefix Not used by Sqlite. + * + * @return FOFDatabaseDriverSqlite Returns this object to support chaining. + * + * @since 12.1 + * @throws RuntimeException + */ + public function renameTable($oldTable, $newTable, $backup = null, $prefix = null) + { + $this->setQuery('ALTER TABLE ' . $oldTable . ' RENAME TO ' . $newTable)->execute(); + + return $this; + } + + /** + * Unlocks tables in the database. + * + * @return FOFDatabaseDriverSqlite Returns this object to support chaining. + * + * @since 12.1 + * @throws RuntimeException + */ + public function unlockTables() + { + return $this; + } + + /** + * Test to see if the PDO ODBC connector is available. + * + * @return boolean True on success, false otherwise. + * + * @since 12.1 + */ + public static function isSupported() + { + return class_exists('PDO') && in_array('sqlite', PDO::getAvailableDrivers()); + } + + /** + * Method to commit a transaction. + * + * @param boolean $toSavepoint If true, commit to the last savepoint. + * + * @return void + * + * @since 12.3 + * @throws RuntimeException + */ + public function transactionCommit($toSavepoint = false) + { + $this->connect(); + + if (!$toSavepoint || $this->transactionDepth <= 1) + { + parent::transactionCommit($toSavepoint); + } + else + { + $this->transactionDepth--; + } + } + + /** + * Method to roll back a transaction. + * + * @param boolean $toSavepoint If true, rollback to the last savepoint. + * + * @return void + * + * @since 12.3 + * @throws RuntimeException + */ + public function transactionRollback($toSavepoint = false) + { + $this->connect(); + + if (!$toSavepoint || $this->transactionDepth <= 1) + { + parent::transactionRollback($toSavepoint); + } + else + { + $savepoint = 'SP_' . ($this->transactionDepth - 1); + $this->setQuery('ROLLBACK TO ' . $this->quoteName($savepoint)); + + if ($this->execute()) + { + $this->transactionDepth--; + } + } + } + + /** + * Method to initialize a transaction. + * + * @param boolean $asSavepoint If true and a transaction is already active, a savepoint will be created. + * + * @return void + * + * @since 12.3 + * @throws RuntimeException + */ + public function transactionStart($asSavepoint = false) + { + $this->connect(); + + if (!$asSavepoint || !$this->transactionDepth) + { + parent::transactionStart($asSavepoint); + } + + $savepoint = 'SP_' . $this->transactionDepth; + $this->setQuery('SAVEPOINT ' . $this->quoteName($savepoint)); + + if ($this->execute()) + { + $this->transactionDepth++; + } + } +} diff --git a/Sites/pages/libraries/fof/database/driver/sqlsrv.php b/Sites/pages/libraries/fof/database/driver/sqlsrv.php new file mode 100644 index 00000000..e637c240 --- /dev/null +++ b/Sites/pages/libraries/fof/database/driver/sqlsrv.php @@ -0,0 +1,1172 @@ +disconnect(); + } + + /** + * Connects to the database if needed. + * + * @return void Returns void if the database connected successfully. + * + * @since 12.1 + * @throws RuntimeException + */ + public function connect() + { + if ($this->connection) + { + return; + } + + // Build the connection configuration array. + $config = array( + 'Database' => $this->options['database'], + 'uid' => $this->options['user'], + 'pwd' => $this->options['password'], + 'CharacterSet' => 'UTF-8', + 'ReturnDatesAsStrings' => true); + + // Make sure the SQLSRV extension for PHP is installed and enabled. + if (!function_exists('sqlsrv_connect')) + { + throw new RuntimeException('PHP extension sqlsrv_connect is not available.'); + } + + // Attempt to connect to the server. + if (!($this->connection = @ sqlsrv_connect($this->options['host'], $config))) + { + throw new RuntimeException('Database sqlsrv_connect failed'); + } + + // Make sure that DB warnings are not returned as errors. + sqlsrv_configure('WarningsReturnAsErrors', 0); + + // If auto-select is enabled select the given database. + if ($this->options['select'] && !empty($this->options['database'])) + { + $this->select($this->options['database']); + } + + // Set charactersets. + $this->utf = $this->setUtf(); + } + + /** + * Disconnects the database. + * + * @return void + * + * @since 12.1 + */ + public function disconnect() + { + // Close the connection. + if (is_resource($this->connection)) + { + foreach ($this->disconnectHandlers as $h) + { + call_user_func_array($h, array( &$this)); + } + + sqlsrv_close($this->connection); + } + + $this->connection = null; + } + + /** + * Get table constraints + * + * @param string $tableName The name of the database table. + * + * @return array Any constraints available for the table. + * + * @since 12.1 + */ + protected function getTableConstraints($tableName) + { + $this->connect(); + + $query = $this->getQuery(true); + + $this->setQuery( + 'SELECT CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE TABLE_NAME = ' . $query->quote($tableName) + ); + + return $this->loadColumn(); + } + + /** + * Rename constraints. + * + * @param array $constraints Array(strings) of table constraints + * @param string $prefix A string + * @param string $backup A string + * + * @return void + * + * @since 12.1 + */ + protected function renameConstraints($constraints = array(), $prefix = null, $backup = null) + { + $this->connect(); + + foreach ($constraints as $constraint) + { + $this->setQuery('sp_rename ' . $constraint . ',' . str_replace($prefix, $backup, $constraint)); + $this->execute(); + } + } + + /** + * Method to escape a string for usage in an SQL statement. + * + * The escaping for MSSQL isn't handled in the driver though that would be nice. Because of this we need + * to handle the escaping ourselves. + * + * @param string $text The string to be escaped. + * @param boolean $extra Optional parameter to provide extra escaping. + * + * @return string The escaped string. + * + * @since 12.1 + */ + public function escape($text, $extra = false) + { + $result = addslashes($text); + $result = str_replace("\'", "''", $result); + $result = str_replace('\"', '"', $result); + $result = str_replace('\/', '/', $result); + + if ($extra) + { + // We need the below str_replace since the search in sql server doesn't recognize _ character. + $result = str_replace('_', '[_]', $result); + } + + return $result; + } + + /** + * Determines if the connection to the server is active. + * + * @return boolean True if connected to the database engine. + * + * @since 12.1 + */ + public function connected() + { + // TODO: Run a blank query here + return true; + } + + /** + * Drops a table from the database. + * + * @param string $tableName The name of the database table to drop. + * @param boolean $ifExists Optionally specify that the table must exist before it is dropped. + * + * @return FOFDatabaseDriverSqlsrv Returns this object to support chaining. + * + * @since 12.1 + */ + public function dropTable($tableName, $ifExists = true) + { + $this->connect(); + + $query = $this->getQuery(true); + + if ($ifExists) + { + $this->setQuery( + 'IF EXISTS(SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = ' . $query->quote($tableName) . ') DROP TABLE ' . $tableName + ); + } + else + { + $this->setQuery('DROP TABLE ' . $tableName); + } + + $this->execute(); + + return $this; + } + + /** + * Get the number of affected rows for the previous executed SQL statement. + * + * @return integer The number of affected rows. + * + * @since 12.1 + */ + public function getAffectedRows() + { + $this->connect(); + + return sqlsrv_rows_affected($this->cursor); + } + + /** + * Method to get the database collation in use by sampling a text field of a table in the database. + * + * @return mixed The collation in use by the database or boolean false if not supported. + * + * @since 12.1 + */ + public function getCollation() + { + // TODO: Not fake this + return 'MSSQL UTF-8 (UCS2)'; + } + + /** + * Method to get the database connection collation, as reported by the driver. If the connector doesn't support + * reporting this value please return an empty string. + * + * @return string + */ + public function getConnectionCollation() + { + // TODO: Not fake this + return 'MSSQL UTF-8 (UCS2)'; + } + + /** + * Get the number of returned rows for the previous executed SQL statement. + * + * @param resource $cursor An optional database cursor resource to extract the row count from. + * + * @return integer The number of returned rows. + * + * @since 12.1 + */ + public function getNumRows($cursor = null) + { + $this->connect(); + + return sqlsrv_num_rows($cursor ? $cursor : $this->cursor); + } + + /** + * Retrieves field information about the given tables. + * + * @param mixed $table A table name + * @param boolean $typeOnly True to only return field types. + * + * @return array An array of fields. + * + * @since 12.1 + * @throws RuntimeException + */ + public function getTableColumns($table, $typeOnly = true) + { + $result = array(); + + $table_temp = $this->replacePrefix((string) $table); + + // Set the query to get the table fields statement. + $this->setQuery( + 'SELECT column_name as Field, data_type as Type, is_nullable as \'Null\', column_default as \'Default\'' . + ' FROM information_schema.columns WHERE table_name = ' . $this->quote($table_temp) + ); + $fields = $this->loadObjectList(); + + // If we only want the type as the value add just that to the list. + if ($typeOnly) + { + foreach ($fields as $field) + { + $result[$field->Field] = preg_replace("/[(0-9)]/", '', $field->Type); + } + } + // If we want the whole field data object add that to the list. + else + { + foreach ($fields as $field) + { + if (stristr(strtolower($field->Type), "nvarchar")) + { + $field->Default = ""; + } + $result[$field->Field] = $field; + } + } + + return $result; + } + + /** + * Shows the table CREATE statement that creates the given tables. + * + * This is unsupported by MSSQL. + * + * @param mixed $tables A table name or a list of table names. + * + * @return array A list of the create SQL for the tables. + * + * @since 12.1 + * @throws RuntimeException + */ + public function getTableCreate($tables) + { + $this->connect(); + + return ''; + } + + /** + * Get the details list of keys for a table. + * + * @param string $table The name of the table. + * + * @return array An array of the column specification for the table. + * + * @since 12.1 + * @throws RuntimeException + */ + public function getTableKeys($table) + { + $this->connect(); + + // TODO To implement. + return array(); + } + + /** + * Method to get an array of all tables in the database. + * + * @return array An array of all the tables in the database. + * + * @since 12.1 + * @throws RuntimeException + */ + public function getTableList() + { + $this->connect(); + + // Set the query to get the tables statement. + $this->setQuery('SELECT name FROM ' . $this->getDatabase() . '.sys.Tables WHERE type = \'U\';'); + $tables = $this->loadColumn(); + + return $tables; + } + + /** + * Get the version of the database connector. + * + * @return string The database connector version. + * + * @since 12.1 + */ + public function getVersion() + { + $this->connect(); + + $version = sqlsrv_server_info($this->connection); + + return $version['SQLServerVersion']; + } + + /** + * Inserts a row into a table based on an object's properties. + * + * @param string $table The name of the database table to insert into. + * @param object &$object A reference to an object whose public properties match the table fields. + * @param string $key The name of the primary key. If provided the object property is updated. + * + * @return boolean True on success. + * + * @since 12.1 + * @throws RuntimeException + */ + public function insertObject($table, &$object, $key = null) + { + $fields = array(); + $values = array(); + $statement = 'INSERT INTO ' . $this->quoteName($table) . ' (%s) VALUES (%s)'; + + foreach (get_object_vars($object) as $k => $v) + { + // Only process non-null scalars. + if (is_array($v) or is_object($v) or $v === null) + { + continue; + } + + if (!$this->checkFieldExists($table, $k)) + { + continue; + } + + if ($k[0] == '_') + { + // Internal field + continue; + } + + if ($k == $key && $key == 0) + { + continue; + } + + $fields[] = $this->quoteName($k); + $values[] = $this->Quote($v); + } + // Set the query and execute the insert. + $this->setQuery(sprintf($statement, implode(',', $fields), implode(',', $values))); + + if (!$this->execute()) + { + return false; + } + + $id = $this->insertid(); + + if ($key && $id) + { + $object->$key = $id; + } + + return true; + } + + /** + * Method to get the auto-incremented value from the last INSERT statement. + * + * @return integer The value of the auto-increment field from the last inserted row. + * + * @since 12.1 + */ + public function insertid() + { + $this->connect(); + + // TODO: SELECT IDENTITY + $this->setQuery('SELECT @@IDENTITY'); + + return (int) $this->loadResult(); + } + + /** + * Method to get the first field of the first row of the result set from the database query. + * + * @return mixed The return value or null if the query failed. + * + * @since 12.1 + * @throws RuntimeException + */ + public function loadResult() + { + $ret = null; + + // Execute the query and get the result set cursor. + if (!($cursor = $this->execute())) + { + return null; + } + + // Get the first row from the result set as an array. + if ($row = sqlsrv_fetch_array($cursor, SQLSRV_FETCH_NUMERIC)) + { + $ret = $row[0]; + } + + // Free up system resources and return. + $this->freeResult($cursor); + + // For SQLServer - we need to strip slashes + $ret = stripslashes($ret); + + return $ret; + } + + /** + * Execute the SQL statement. + * + * @return mixed A database cursor resource on success, boolean false on failure. + * + * @since 12.1 + * @throws RuntimeException + * @throws Exception + */ + public function execute() + { + $this->connect(); + + if (!is_resource($this->connection)) + { + if (class_exists('JLog')) + { + JLog::add(JText::sprintf('JLIB_DATABASE_QUERY_FAILED', $this->errorNum, $this->errorMsg), JLog::ERROR, 'database'); + } + throw new RuntimeException($this->errorMsg, $this->errorNum); + } + + // Take a local copy so that we don't modify the original query and cause issues later + $query = $this->replacePrefix((string) $this->sql); + + if (!($this->sql instanceof FOFDatabaseQuery) && ($this->limit > 0 || $this->offset > 0)) + { + $query = $this->limit($query, $this->limit, $this->offset); + } + + // Increment the query counter. + $this->count++; + + // Reset the error values. + $this->errorNum = 0; + $this->errorMsg = ''; + + // If debugging is enabled then let's log the query. + if ($this->debug) + { + // Add the query to the object queue. + $this->log[] = $query; + + if (class_exists('JLog')) + { + JLog::add($query, JLog::DEBUG, 'databasequery'); + } + + $this->timings[] = microtime(true); + } + + // SQLSrv_num_rows requires a static or keyset cursor. + if (strncmp(ltrim(strtoupper($query)), 'SELECT', strlen('SELECT')) == 0) + { + $array = array('Scrollable' => SQLSRV_CURSOR_KEYSET); + } + else + { + $array = array(); + } + + // Execute the query. Error suppression is used here to prevent warnings/notices that the connection has been lost. + $this->cursor = @sqlsrv_query($this->connection, $query, array(), $array); + + if ($this->debug) + { + $this->timings[] = microtime(true); + + if (defined('DEBUG_BACKTRACE_IGNORE_ARGS')) + { + $this->callStacks[] = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); + } + else + { + $this->callStacks[] = debug_backtrace(); + } + } + + // If an error occurred handle it. + if (!$this->cursor) + { + // Get the error number and message before we execute any more queries. + $errorNum = $this->getErrorNumber(); + $errorMsg = $this->getErrorMessage($query); + + // Check if the server was disconnected. + if (!$this->connected()) + { + try + { + // Attempt to reconnect. + $this->connection = null; + $this->connect(); + } + // If connect fails, ignore that exception and throw the normal exception. + catch (RuntimeException $e) + { + // Get the error number and message. + $this->errorNum = $this->getErrorNumber(); + $this->errorMsg = $this->getErrorMessage($query); + + // Throw the normal query exception. + if (class_exists('JLog')) + { + JLog::add(JText::sprintf('JLIB_DATABASE_QUERY_FAILED', $this->errorNum, $this->errorMsg), JLog::ERROR, 'database-error'); + } + + throw new RuntimeException($this->errorMsg, $this->errorNum, $e); + } + + // Since we were able to reconnect, run the query again. + return $this->execute(); + } + // The server was not disconnected. + else + { + // Get the error number and message from before we tried to reconnect. + $this->errorNum = $errorNum; + $this->errorMsg = $errorMsg; + + // Throw the normal query exception. + if (class_exists('JLog')) + { + JLog::add(JText::sprintf('JLIB_DATABASE_QUERY_FAILED', $this->errorNum, $this->errorMsg), JLog::ERROR, 'database-error'); + } + + throw new RuntimeException($this->errorMsg, $this->errorNum); + } + } + + return $this->cursor; + } + + /** + * This function replaces a string identifier $prefix with the string held is the + * tablePrefix class variable. + * + * @param string $query The SQL statement to prepare. + * @param string $prefix The common table prefix. + * + * @return string The processed SQL statement. + * + * @since 12.1 + */ + public function replacePrefix($query, $prefix = '#__') + { + $startPos = 0; + $literal = ''; + + $query = trim($query); + $n = strlen($query); + + while ($startPos < $n) + { + $ip = strpos($query, $prefix, $startPos); + + if ($ip === false) + { + break; + } + + $j = strpos($query, "N'", $startPos); + $k = strpos($query, '"', $startPos); + + if (($k !== false) && (($k < $j) || ($j === false))) + { + $quoteChar = '"'; + $j = $k; + } + else + { + $quoteChar = "'"; + } + + if ($j === false) + { + $j = $n; + } + + $literal .= str_replace($prefix, $this->tablePrefix, substr($query, $startPos, $j - $startPos)); + $startPos = $j; + + $j = $startPos + 1; + + if ($j >= $n) + { + break; + } + + // Quote comes first, find end of quote + while (true) + { + $k = strpos($query, $quoteChar, $j); + $escaped = false; + + if ($k === false) + { + break; + } + + $l = $k - 1; + + while ($l >= 0 && $query[$l] == '\\') + { + $l--; + $escaped = !$escaped; + } + + if ($escaped) + { + $j = $k + 1; + continue; + } + + break; + } + + if ($k === false) + { + // Error in the query - no end quote; ignore it + break; + } + + $literal .= substr($query, $startPos, $k - $startPos + 1); + $startPos = $k + 1; + } + + if ($startPos < $n) + { + $literal .= substr($query, $startPos, $n - $startPos); + } + + return $literal; + } + + /** + * Select a database for use. + * + * @param string $database The name of the database to select for use. + * + * @return boolean True if the database was successfully selected. + * + * @since 12.1 + * @throws RuntimeException + */ + public function select($database) + { + $this->connect(); + + if (!$database) + { + return false; + } + + if (!sqlsrv_query($this->connection, 'USE ' . $database, null, array('scrollable' => SQLSRV_CURSOR_STATIC))) + { + throw new RuntimeException('Could not connect to database'); + } + + return true; + } + + /** + * Set the connection to use UTF-8 character encoding. + * + * @return boolean True on success. + * + * @since 12.1 + */ + public function setUtf() + { + return false; + } + + /** + * Method to commit a transaction. + * + * @param boolean $toSavepoint If true, commit to the last savepoint. + * + * @return void + * + * @since 12.1 + * @throws RuntimeException + */ + public function transactionCommit($toSavepoint = false) + { + $this->connect(); + + if (!$toSavepoint || $this->transactionDepth <= 1) + { + if ($this->setQuery('COMMIT TRANSACTION')->execute()) + { + $this->transactionDepth = 0; + } + + return; + } + + $this->transactionDepth--; + } + + /** + * Method to roll back a transaction. + * + * @param boolean $toSavepoint If true, rollback to the last savepoint. + * + * @return void + * + * @since 12.1 + * @throws RuntimeException + */ + public function transactionRollback($toSavepoint = false) + { + $this->connect(); + + if (!$toSavepoint || $this->transactionDepth <= 1) + { + if ($this->setQuery('ROLLBACK TRANSACTION')->execute()) + { + $this->transactionDepth = 0; + } + + return; + } + + $savepoint = 'SP_' . ($this->transactionDepth - 1); + $this->setQuery('ROLLBACK TRANSACTION ' . $this->quoteName($savepoint)); + + if ($this->execute()) + { + $this->transactionDepth--; + } + } + + /** + * Method to initialize a transaction. + * + * @param boolean $asSavepoint If true and a transaction is already active, a savepoint will be created. + * + * @return void + * + * @since 12.1 + * @throws RuntimeException + */ + public function transactionStart($asSavepoint = false) + { + $this->connect(); + + if (!$asSavepoint || !$this->transactionDepth) + { + if ($this->setQuery('BEGIN TRANSACTION')->execute()) + { + $this->transactionDepth = 1; + } + + return; + } + + $savepoint = 'SP_' . $this->transactionDepth; + $this->setQuery('BEGIN TRANSACTION ' . $this->quoteName($savepoint)); + + if ($this->execute()) + { + $this->transactionDepth++; + } + } + + /** + * Method to fetch a row from the result set cursor as an array. + * + * @param mixed $cursor The optional result set cursor from which to fetch the row. + * + * @return mixed Either the next row from the result set or false if there are no more rows. + * + * @since 12.1 + */ + protected function fetchArray($cursor = null) + { + return sqlsrv_fetch_array($cursor ? $cursor : $this->cursor, SQLSRV_FETCH_NUMERIC); + } + + /** + * Method to fetch a row from the result set cursor as an associative array. + * + * @param mixed $cursor The optional result set cursor from which to fetch the row. + * + * @return mixed Either the next row from the result set or false if there are no more rows. + * + * @since 12.1 + */ + protected function fetchAssoc($cursor = null) + { + return sqlsrv_fetch_array($cursor ? $cursor : $this->cursor, SQLSRV_FETCH_ASSOC); + } + + /** + * Method to fetch a row from the result set cursor as an object. + * + * @param mixed $cursor The optional result set cursor from which to fetch the row. + * @param string $class The class name to use for the returned row object. + * + * @return mixed Either the next row from the result set or false if there are no more rows. + * + * @since 12.1 + */ + protected function fetchObject($cursor = null, $class = 'stdClass') + { + return sqlsrv_fetch_object($cursor ? $cursor : $this->cursor, $class); + } + + /** + * Method to free up the memory used for the result set. + * + * @param mixed $cursor The optional result set cursor from which to fetch the row. + * + * @return void + * + * @since 12.1 + */ + protected function freeResult($cursor = null) + { + sqlsrv_free_stmt($cursor ? $cursor : $this->cursor); + } + + /** + * Method to check and see if a field exists in a table. + * + * @param string $table The table in which to verify the field. + * @param string $field The field to verify. + * + * @return boolean True if the field exists in the table. + * + * @since 12.1 + */ + protected function checkFieldExists($table, $field) + { + $this->connect(); + + $table = $this->replacePrefix((string) $table); + $query = "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '$table' AND COLUMN_NAME = '$field'" . + " ORDER BY ORDINAL_POSITION"; + $this->setQuery($query); + + if ($this->loadResult()) + { + return true; + } + else + { + return false; + } + } + + /** + * Method to wrap an SQL statement to provide a LIMIT and OFFSET behavior for scrolling through a result set. + * + * @param string $query The SQL statement to process. + * @param integer $limit The maximum affected rows to set. + * @param integer $offset The affected row offset to set. + * + * @return string The processed SQL statement. + * + * @since 12.1 + */ + protected function limit($query, $limit, $offset) + { + if ($limit == 0 && $offset == 0) + { + return $query; + } + + $start = $offset + 1; + $end = $offset + $limit; + + $orderBy = stristr($query, 'ORDER BY'); + + if (is_null($orderBy) || empty($orderBy)) + { + $orderBy = 'ORDER BY (select 0)'; + } + + $query = str_ireplace($orderBy, '', $query); + + $rowNumberText = ', ROW_NUMBER() OVER (' . $orderBy . ') AS RowNumber FROM '; + + $query = preg_replace('/\sFROM\s/i', $rowNumberText, $query, 1); + + return $query; + } + + /** + * Renames a table in the database. + * + * @param string $oldTable The name of the table to be renamed + * @param string $newTable The new name for the table. + * @param string $backup Table prefix + * @param string $prefix For the table - used to rename constraints in non-mysql databases + * + * @return FOFDatabaseDriverSqlsrv Returns this object to support chaining. + * + * @since 12.1 + * @throws RuntimeException + */ + public function renameTable($oldTable, $newTable, $backup = null, $prefix = null) + { + $constraints = array(); + + if (!is_null($prefix) && !is_null($backup)) + { + $constraints = $this->getTableConstraints($oldTable); + } + + if (!empty($constraints)) + { + $this->renameConstraints($constraints, $prefix, $backup); + } + + $this->setQuery("sp_rename '" . $oldTable . "', '" . $newTable . "'"); + + return $this->execute(); + } + + /** + * Locks a table in the database. + * + * @param string $tableName The name of the table to lock. + * + * @return FOFDatabaseDriverSqlsrv Returns this object to support chaining. + * + * @since 12.1 + * @throws RuntimeException + */ + public function lockTable($tableName) + { + return $this; + } + + /** + * Unlocks tables in the database. + * + * @return FOFDatabaseDriverSqlsrv Returns this object to support chaining. + * + * @since 12.1 + * @throws RuntimeException + */ + public function unlockTables() + { + return $this; + } + + /** + * Return the actual SQL Error number + * + * @return integer The SQL Error number + * + * @since 3.4.6 + */ + protected function getErrorNumber() + { + $errors = sqlsrv_errors(); + + return $errors[0]['SQLSTATE']; + } + + /** + * Return the actual SQL Error message + * + * @param string $query The SQL Query that fails + * + * @return string The SQL Error message + * + * @since 3.4.6 + */ + protected function getErrorMessage($query) + { + $errors = sqlsrv_errors(); + $errorMessage = (string) $errors[0]['message']; + + // Replace the Databaseprefix with `#__` if we are not in Debug + if (!$this->debug) + { + $errorMessage = str_replace($this->tablePrefix, '#__', $errorMessage); + $query = str_replace($this->tablePrefix, '#__', $query); + } + + return $errorMessage . ' SQL=' . $query; + } +} diff --git a/Sites/pages/libraries/fof/database/factory.php b/Sites/pages/libraries/fof/database/factory.php new file mode 100644 index 00000000..681247ad --- /dev/null +++ b/Sites/pages/libraries/fof/database/factory.php @@ -0,0 +1,127 @@ +getMessage()), $e->getCode(), $e); + } + + return $instance; + } + + /** + * Gets an instance of the factory object. + * + * @return FOFDatabaseFactory + * + * @since 12.1 + */ + public static function getInstance() + { + return self::$_instance ? self::$_instance : new FOFDatabaseFactory; + } + + /** + * Get the current query object or a new FOFDatabaseQuery object. + * + * @param string $name Name of the driver you want an query object for. + * @param FOFDatabaseDriver $db Optional FOFDatabaseDriver instance + * + * @return FOFDatabaseQuery The current query object or a new object extending the FOFDatabaseQuery class. + * + * @since 12.1 + * @throws RuntimeException + */ + public function getQuery($name, FOFDatabaseDriver $db = null) + { + // Derive the class name from the driver. + $class = 'FOFDatabaseQuery' . ucfirst(strtolower($name)); + + // Make sure we have a query class for this driver. + if (!class_exists($class)) + { + // If it doesn't exist we are at an impasse so throw an exception. + throw new RuntimeException('Database Query class not found'); + } + + return new $class($db); + } + + /** + * Gets an instance of a factory object to return on subsequent calls of getInstance. + * + * @param FOFDatabaseFactory $instance A FOFDatabaseFactory object. + * + * @return void + * + * @since 12.1 + */ + public static function setInstance(FOFDatabaseFactory $instance = null) + { + self::$_instance = $instance; + } +} diff --git a/Sites/pages/libraries/fof/database/installer.php b/Sites/pages/libraries/fof/database/installer.php new file mode 100644 index 00000000..c7aec16e --- /dev/null +++ b/Sites/pages/libraries/fof/database/installer.php @@ -0,0 +1,1020 @@ +input = $config['input']; + } + else + { + $this->input = new FOFInput($config['input']); + } + } + else + { + $this->input = new FOFInput; + } + + // Set the database object + if (array_key_exists('dbo', $config)) + { + $this->db = $config['dbo']; + } + else + { + $this->db = FOFPlatform::getInstance()->getDbo(); + } + + // Set the $name/$_name variable + $component = $this->input->getCmd('option', 'com_foobar'); + + if (array_key_exists('option', $config)) + { + $component = $config['option']; + } + + // Figure out where the XML schema files are stored + if (array_key_exists('dbinstaller_directory', $config)) + { + $this->xmlDirectory = $config['dbinstaller_directory']; + } + else + { + // Nothing is defined, assume the files are stored in the sql/xml directory inside the component's administrator section + $directories = FOFPlatform::getInstance()->getComponentBaseDirs($component); + $this->setXmlDirectory($directories['admin'] . '/sql/xml'); + } + + // Do we have a set of XML files to look for? + if (array_key_exists('dbinstaller_files', $config)) + { + $files = $config['dbinstaller_files']; + + if (!is_array($files)) + { + $files = explode(',', $files); + } + + $this->xmlFiles = $files; + } + + } + + /** + * Sets the directory where XML schema files are stored + * + * @param string $xmlDirectory + */ + public function setXmlDirectory($xmlDirectory) + { + $this->xmlDirectory = $xmlDirectory; + } + + /** + * Returns the directory where XML schema files are stored + * + * @return string + */ + public function getXmlDirectory() + { + return $this->xmlDirectory; + } + + /** + * Creates or updates the database schema + * + * @return void + * + * @throws Exception When a database query fails and it doesn't have the canfail flag + */ + public function updateSchema() + { + // Get the schema XML file + $xml = $this->findSchemaXml(); + + if (empty($xml)) + { + return; + } + + // Make sure there are SQL commands in this file + if (!$xml->sql) + { + return; + } + + // Walk the sql > action tags to find all tables + /** @var SimpleXMLElement $actions */ + $actions = $xml->sql->children(); + + /** + * The meta/autocollation node defines if I should automatically apply the correct collation (utf8 or utf8mb4) + * to the database tables managed by the schema updater. When enabled (default) the queries are automatically + * converted to the correct collation (utf8mb4_unicode_ci or utf8_general_ci) depending on whether your Joomla! + * and MySQL server support Multibyte UTF-8 (UTF8MB4). Moreover, if UTF8MB4 is supported, all CREATE TABLE + * queries are analyzed and the tables referenced in them are auto-converted to the proper utf8mb4 collation. + */ + $autoCollationConversion = true; + + if ($xml->meta->autocollation) + { + $value = (string) $xml->meta->autocollation; + $value = trim($value); + $value = strtolower($value); + + $autoCollationConversion = in_array($value, array('true', '1', 'on', 'yes')); + } + + try + { + $hasUtf8mb4Support = $this->db->hasUTF8mb4Support(); + } + catch (\Exception $e) + { + $hasUtf8mb4Support = false; + } + + $tablesToConvert = array(); + + /** @var SimpleXMLElement $action */ + foreach ($actions as $action) + { + // Get the attributes + $attributes = $action->attributes(); + + // Get the table / view name + $table = $attributes->table ? (string)$attributes->table : ''; + + if (empty($table)) + { + continue; + } + + // Am I allowed to let this action fail? + $canFailAction = $attributes->canfail ? $attributes->canfail : 0; + + // Evaluate conditions + $shouldExecute = true; + + /** @var SimpleXMLElement $node */ + foreach ($action->children() as $node) + { + if ($node->getName() == 'condition') + { + // Get the operator + $operator = $node->attributes()->operator ? (string)$node->attributes()->operator : 'and'; + $operator = empty($operator) ? 'and' : $operator; + + $condition = $this->conditionMet($table, $node); + + switch ($operator) + { + case 'not': + $shouldExecute = $shouldExecute && !$condition; + break; + + case 'or': + $shouldExecute = $shouldExecute || $condition; + break; + + case 'nor': + $shouldExecute = !$shouldExecute && !$condition; + break; + + case 'xor': + $shouldExecute = ($shouldExecute xor $condition); + break; + + case 'maybe': + $shouldExecute = $condition ? true : $shouldExecute; + break; + + default: + $shouldExecute = $shouldExecute && $condition; + break; + } + } + + // DO NOT USE BOOLEAN SHORT CIRCUIT EVALUATION! + // if (!$shouldExecute) break; + } + + // Do I have to only collect the tables from CREATE TABLE queries? + $onlyCollectTables = !$shouldExecute && $autoCollationConversion && $hasUtf8mb4Support; + + // Make sure all conditions are met OR I have to collect tables from CREATE TABLE queries. + if (!$shouldExecute && !$onlyCollectTables) + { + continue; + } + + // Execute queries + foreach ($action->children() as $node) + { + if ($node->getName() == 'query') + { + $query = (string) $node; + + if ($autoCollationConversion && $hasUtf8mb4Support) + { + $this->extractTablesToConvert($query, $tablesToConvert); + } + + // If we're only collecting tables do not run the queries + if ($onlyCollectTables) + { + continue; + } + + $canFail = $node->attributes->canfail ? (string)$node->attributes->canfail : $canFailAction; + + if (is_string($canFail)) + { + $canFail = strtoupper($canFail); + } + + $canFail = (in_array($canFail, array(true, 1, 'YES', 'TRUE'))); + + // Do I need to automatically convert the collation of all CREATE / ALTER queries? + if ($autoCollationConversion) + { + if ($hasUtf8mb4Support) + { + // We have UTF8MB4 support. Convert all queries to UTF8MB4. + $query = $this->convertUtf8QueryToUtf8mb4($query); + } + else + { + // We do not have UTF8MB4 support. Convert all queries to plain old UTF8. + $query = $this->convertUtf8mb4QueryToUtf8($query); + } + } + + $this->db->setQuery($query); + + try + { + $this->db->execute(); + } + catch (Exception $e) + { + // If we are not allowed to fail, throw back the exception we caught + if (!$canFail) + { + throw $e; + } + } + } + } + } + + // Auto-convert the collation of tables if we are told to do so, have utf8mb4 support and a list of tables. + if ($autoCollationConversion && $hasUtf8mb4Support && !empty($tablesToConvert)) + { + $this->convertTablesToUtf8mb4($tablesToConvert); + } + } + + /** + * Uninstalls the database schema + * + * @return void + */ + public function removeSchema() + { + // Get the schema XML file + $xml = $this->findSchemaXml(); + + if (empty($xml)) + { + return; + } + + // Make sure there are SQL commands in this file + if (!$xml->sql) + { + return; + } + + // Walk the sql > action tags to find all tables + $tables = array(); + /** @var SimpleXMLElement $actions */ + $actions = $xml->sql->children(); + + /** @var SimpleXMLElement $action */ + foreach ($actions as $action) + { + $attributes = $action->attributes(); + $tables[] = (string)$attributes->table; + } + + // Simplify the tables list + $tables = array_unique($tables); + + // Start dropping tables + foreach ($tables as $table) + { + try + { + $this->db->dropTable($table); + } + catch (Exception $e) + { + // Do not fail if I can't drop the table + } + } + } + + /** + * Find an suitable schema XML file for this database type and return the SimpleXMLElement holding its information + * + * @return null|SimpleXMLElement Null if no suitable schema XML file is found + */ + protected function findSchemaXml() + { + $driverType = $this->db->name; + $xml = null; + + // And now look for the file + foreach ($this->xmlFiles as $baseName) + { + // Remove any accidental whitespace + $baseName = trim($baseName); + + // Get the full path to the file + $fileName = $this->xmlDirectory . '/' . $baseName . '.xml'; + + // Make sure the file exists + if (!@file_exists($fileName)) + { + continue; + } + + // Make sure the file is a valid XML document + try + { + $xml = new SimpleXMLElement($fileName, LIBXML_NONET, true); + } + catch (Exception $e) + { + $xml = null; + continue; + } + + // Make sure the file is an XML schema file + if ($xml->getName() != 'schema') + { + $xml = null; + continue; + } + + if (!$xml->meta) + { + $xml = null; + continue; + } + + if (!$xml->meta->drivers) + { + $xml = null; + continue; + } + + /** @var SimpleXMLElement $drivers */ + $drivers = $xml->meta->drivers; + + // Strict driver name match + foreach ($drivers->children() as $driverTypeTag) + { + $thisDriverType = (string)$driverTypeTag; + + if ($thisDriverType == $driverType) + { + return $xml; + } + } + + // Some custom database drivers use a non-standard $name variable. Let try a relaxed match. + foreach ($drivers->children() as $driverTypeTag) + { + $thisDriverType = (string)$driverTypeTag; + + if ( + // e.g. $driverType = 'mysqlistupid', $thisDriverType = 'mysqli' => driver matched + strpos($driverType, $thisDriverType) === 0 + // e.g. $driverType = 'stupidmysqli', $thisDriverType = 'mysqli' => driver matched + || (substr($driverType, -strlen($thisDriverType)) == $thisDriverType) + ) + { + return $xml; + } + } + + $xml = null; + } + + return $xml; + } + + /** + * Checks if a condition is met + * + * @param string $table The table we're operating on + * @param SimpleXMLElement $node The condition definition node + * + * @return bool + */ + protected function conditionMet($table, SimpleXMLElement $node) + { + if (empty(static::$allTables)) + { + static::$allTables = $this->db->getTableList(); + } + + // Does the table exist? + $tableNormal = $this->db->replacePrefix($table); + $tableExists = in_array($tableNormal, static::$allTables); + + // Initialise + $condition = false; + + // Get the condition's attributes + $attributes = $node->attributes(); + $type = $attributes->type ? $attributes->type : null; + $value = $attributes->value ? (string) $attributes->value : null; + + switch ($type) + { + // Check if a table or column is missing + case 'missing': + $fieldName = (string)$value; + + if (empty($fieldName)) + { + $condition = !$tableExists; + } + else + { + try + { + $tableColumns = $this->db->getTableColumns($tableNormal, true); + } + catch (\Exception $e) + { + $tableColumns = array(); + } + + $condition = !array_key_exists($fieldName, $tableColumns); + } + + break; + + // Check if a column type matches the "coltype" attribute + case 'type': + try + { + $tableColumns = $this->db->getTableColumns($tableNormal, false); + } + catch (\Exception $e) + { + $tableColumns = array(); + } + + $condition = false; + + if (array_key_exists($value, $tableColumns)) + { + $coltype = $attributes->coltype ? $attributes->coltype : null; + + if (!empty($coltype)) + { + $coltype = strtolower($coltype); + $currentType = strtolower($tableColumns[$value]->Type); + + $condition = ($coltype == $currentType); + } + } + + break; + + // Check if a (named) index exists on the table. Currently only supported on MySQL. + case 'index': + $indexName = (string) $value; + $condition = true; + + if (!empty($indexName)) + { + $indexName = str_replace('#__', $this->db->getPrefix(), $indexName); + $condition = $this->hasIndex($tableNormal, $indexName); + } + + break; + + // Check if a table or column needs to be upgraded to utf8mb4 + case 'utf8mb4upgrade': + $condition = false; + + // Check if the driver and the database connection have UTF8MB4 support + try + { + $hasUtf8mb4Support = $this->db->hasUTF8mb4Support(); + } + catch (\Exception $e) + { + $hasUtf8mb4Support = false; + } + + if ($hasUtf8mb4Support) + { + $fieldName = (string)$value; + + if (empty($fieldName)) + { + $collation = $this->getTableCollation($tableNormal); + } + else + { + $collation = $this->getColumnCollation($tableNormal, $fieldName); + } + + $parts = explode('_', $collation, 3); + $encoding = empty($parts[0]) ? '' : strtolower($parts[0]); + + $condition = $encoding != 'utf8mb4'; + } + + break; + + // Check if the result of a query matches our expectation + case 'equals': + $query = (string)$node; + $this->db->setQuery($query); + + try + { + $result = $this->db->loadResult(); + $condition = ($result == $value); + } + catch (Exception $e) + { + return false; + } + + break; + + // Always returns true + case 'true': + return true; + break; + + default: + return false; + break; + } + + return $condition; + } + + /** + * Get the collation of a table. Uses an internal cache for efficiency. + * + * @param string $tableName The name of the table + * + * @return string The collation, e.g. "utf8_general_ci" + */ + private function getTableCollation($tableName) + { + static $cache = array(); + + $tableName = $this->db->replacePrefix($tableName); + + if (!isset($cache[$tableName])) + { + $cache[$tableName] = $this->realGetTableCollation($tableName); + } + + return $cache[$tableName]; + } + + /** + * Get the collation of a table. This is the internal method used by getTableCollation. + * + * @param string $tableName The name of the table + * + * @return string The collation, e.g. "utf8_general_ci" + */ + private function realGetTableCollation($tableName) + { + try + { + $utf8Support = $this->db->hasUTFSupport(); + } + catch (\Exception $e) + { + $utf8Support = false; + } + + try + { + $utf8mb4Support = $utf8Support && $this->db->hasUTF8mb4Support(); + } + catch (\Exception $e) + { + $utf8mb4Support = false; + } + + $collation = $utf8mb4Support ? 'utf8mb4_unicode_ci' : ($utf8Support ? 'utf_general_ci' : 'latin1_swedish_ci'); + + $query = 'SHOW TABLE STATUS LIKE ' . $this->db->q($tableName); + + try + { + $row = $this->db->setQuery($query)->loadAssoc(); + } + catch (\Exception $e) + { + return $collation; + } + + if (empty($row)) + { + return $collation; + } + + if (!isset($row['Collation'])) + { + return $collation; + } + + if (empty($row['Collation'])) + { + return $collation; + } + + return $row['Collation']; + } + + /** + * Get the collation of a column. Uses an internal cache for efficiency. + * + * @param string $tableName The name of the table + * @param string $columnName The name of the column + * + * @return string The collation, e.g. "utf8_general_ci" + */ + private function getColumnCollation($tableName, $columnName) + { + static $cache = array(); + + $tableName = $this->db->replacePrefix($tableName); + $columnName = $this->db->replacePrefix($columnName); + + if (!isset($cache[$tableName])) + { + $cache[$tableName] = array(); + } + + if (!isset($cache[$tableName][$columnName])) + { + $cache[$tableName][$columnName] = $this->realGetColumnCollation($tableName, $columnName); + } + + return $cache[$tableName][$columnName]; + } + + /** + * Get the collation of a column. This is the internal method used by getColumnCollation. + * + * @param string $tableName The name of the table + * @param string $columnName The name of the column + * + * @return string The collation, e.g. "utf8_general_ci" + */ + private function realGetColumnCollation($tableName, $columnName) + { + $collation = $this->getTableCollation($tableName); + + $query = 'SHOW FULL COLUMNS FROM ' . $this->db->qn($tableName) . ' LIKE ' . $this->db->q($columnName); + + try + { + $row = $this->db->setQuery($query)->loadAssoc(); + } + catch (\Exception $e) + { + return $collation; + } + + if (empty($row)) + { + return $collation; + } + + if (!isset($row['Collation'])) + { + return $collation; + } + + if (empty($row['Collation'])) + { + return $collation; + } + + return $row['Collation']; + } + + /** + * Automatically downgrade a CREATE TABLE or ALTER TABLE query from utf8mb4 (UTF-8 Multibyte) to plain utf8. + * + * We use our own method so we can be site it works even on Joomla! 3.4 or earlier, where UTF8MB4 support is not + * implemented. + * + * @param string $query The query to convert + * + * @return string The converted query + */ + private function convertUtf8mb4QueryToUtf8($query) + { + // If it's not an ALTER TABLE or CREATE TABLE command there's nothing to convert + $beginningOfQuery = substr($query, 0, 12); + $beginningOfQuery = strtoupper($beginningOfQuery); + + if (!in_array($beginningOfQuery, array('ALTER TABLE ', 'CREATE TABLE'))) + { + return $query; + } + + // Replace utf8mb4 with utf8 + $from = array( + 'utf8mb4_unicode_ci', + 'utf8mb4_', + 'utf8mb4', + ); + + $to = array( + 'utf8_general_ci', // Yeah, we convert utf8mb4_unicode_ci to utf8_general_ci per Joomla!'s conventions + 'utf8_', + 'utf8', + ); + + return str_replace($from, $to, $query); + } + + /** + * Automatically upgrade a CREATE TABLE or ALTER TABLE query from plain utf8 to utf8mb4 (UTF-8 Multibyte). + * + * @param string $query The query to convert + * + * @return string The converted query + */ + private function convertUtf8QueryToUtf8mb4($query) + { + // If it's not an ALTER TABLE or CREATE TABLE command there's nothing to convert + $beginningOfQuery = substr($query, 0, 12); + $beginningOfQuery = strtoupper($beginningOfQuery); + + if (!in_array($beginningOfQuery, array('ALTER TABLE ', 'CREATE TABLE'))) + { + return $query; + } + + // Replace utf8 with utf8mb4 + $from = array( + 'utf8_general_ci', + 'utf8_', + 'utf8', + ); + + $to = array( + 'utf8mb4_unicode_ci', // Yeah, we convert utf8_general_ci to utf8mb4_unicode_ci per Joomla!'s conventions + 'utf8mb4_', + 'utf8mb4', + ); + + return str_replace($from, $to, $query); + } + + /** + * Analyzes a query. If it's a CREATE TABLE query the table is added to the $tables array. + * + * @param string $query The query to analyze + * @param string $tables The array where the name of the detected table is added + * + * @return void + */ + private function extractTablesToConvert($query, &$tables) + { + // Normalize the whitespace of the query + $query = trim($query); + $query = str_replace(array("\r\n", "\r", "\n"), ' ', $query); + + while (strstr($query, ' ') !== false) + { + $query = str_replace(' ', ' ', $query); + } + + // Is it a create table query? + $queryStart = substr($query, 0, 12); + $queryStart = strtoupper($queryStart); + + if ($queryStart != 'CREATE TABLE') + { + return; + } + + // Remove the CREATE TABLE keyword. Also, If there's an IF NOT EXISTS clause remove it. + $query = substr($query, 12); + $query = str_ireplace('IF NOT EXISTS', '', $query); + $query = trim($query); + + // Make sure there is a space between the table name and its definition, denoted by an open parenthesis + $query = str_replace('(', ' (', $query); + + // Now we should have the name of the table, a space and the rest of the query. Extract the table name. + $parts = explode(' ', $query, 2); + $tableName = $parts[0]; + + /** + * The table name may be quoted. Since UTF8MB4 is only supported in MySQL, the table name can only be + * quoted with surrounding backticks. Therefore we can trim backquotes from the table name to unquote it! + **/ + $tableName = trim($tableName, '`'); + + // Finally, add the table name to $tables if it doesn't already exist. + if (!in_array($tableName, $tables)) + { + $tables[] = $tableName; + } + } + + /** + * Converts the collation of tables listed in $tablesToConvert to utf8mb4_unicode_ci + * + * @param array $tablesToConvert The list of tables to convert + * + * @return void + */ + private function convertTablesToUtf8mb4($tablesToConvert) + { + try + { + $utf8mb4Support = $this->db->hasUTF8mb4Support(); + } + catch (\Exception $e) + { + $utf8mb4Support = false; + } + + // Make sure the database driver REALLY has support for converting character sets + if (!$utf8mb4Support) + { + return; + } + + asort($tablesToConvert); + + foreach ($tablesToConvert as $tableName) + { + $collation = $this->getTableCollation($tableName); + + $parts = explode('_', $collation, 3); + $encoding = empty($parts[0]) ? '' : strtolower($parts[0]); + + if ($encoding != 'utf8mb4') + { + $queries = $this->db->getAlterTableCharacterSet($tableName); + + try + { + foreach ($queries as $query) + { + $this->db->setQuery($query)->execute(); + } + } + catch (\Exception $e) + { + // We ignore failed conversions. Remember, you MUST change your indices MANUALLY. + } + } + } + } + + /** + * Returns true if table $tableName has an index named $indexName or if it's impossible to retrieve index names for + * the table (not enough privileges, not a MySQL database, ...) + * + * @param string $tableName The name of the table + * @param string $indexName The name of the index + * + * @return bool + */ + private function hasIndex($tableName, $indexName) + { + static $isMySQL = null; + static $cache = array(); + + if (is_null($isMySQL)) + { + $driverType = $this->db->name; + $driverType = strtolower($driverType); + $isMySQL = true; + + if ( + !strpos($driverType, 'mysql') === 0 + && !(substr($driverType, -5) == 'mysql') + && !(substr($driverType, -6) == 'mysqli') + ) + { + $isMySQL = false; + } + } + + // Not MySQL? Lie and return true. + if (!$isMySQL) + { + return true; + } + + if (!isset($cache[$tableName])) + { + $cache[$tableName] = array(); + } + + if (!isset($cache[$tableName][$indexName])) + { + $cache[$tableName][$indexName] = true; + + try + { + $indices = array(); + $query = 'SHOW INDEXES FROM ' . $this->db->qn($tableName); + $indexDefinitions = $this->db->setQuery($query)->loadAssocList(); + + if (!empty($indexDefinitions) && is_array($indexDefinitions)) + { + foreach ($indexDefinitions as $def) + { + $indices[] = $def['Key_name']; + } + + $indices = array_unique($indices); + } + + $cache[$tableName][$indexName] = in_array($indexName, $indices); + } + catch (\Exception $e) + { + // Ignore errors + } + } + + return $cache[$tableName][$indexName]; + } +} diff --git a/Sites/pages/libraries/fof/database/interface.php b/Sites/pages/libraries/fof/database/interface.php new file mode 100644 index 00000000..21be6112 --- /dev/null +++ b/Sites/pages/libraries/fof/database/interface.php @@ -0,0 +1,37 @@ +_tableObject = FOFTable::getInstance($parts[2], ucfirst($parts[0]) . ucfirst($parts[1]))->getClone(); + + $this->cursor = $cursor; + $this->class = 'stdClass'; + $this->_column = $column; + $this->_fetched = 0; + + $this->next(); + } + + /** + * Database iterator destructor. + */ + public function __destruct() + { + if ($this->cursor) + { + $this->freeResult($this->cursor); + } + } + + /** + * The current element in the iterator. + * + * @return object + * + * @see Iterator::current() + */ + public function current() + { + return $this->_currentTable; + } + + /** + * The key of the current element in the iterator. + * + * @return scalar + * + * @see Iterator::key() + */ + public function key() + { + return $this->_key; + } + + /** + * Moves forward to the next result from the SQL query. + * + * @return void + * + * @see Iterator::next() + */ + public function next() + { + // Set the default key as being the number of fetched object + $this->_key = $this->_fetched; + + // Try to get an object + $this->_current = $this->fetchObject(); + + // If an object has been found + if ($this->_current) + { + $this->_currentTable = $this->getTable(); + + // Set the key as being the indexed column (if it exists) + if (isset($this->_current->{$this->_column})) + { + $this->_key = $this->_current->{$this->_column}; + } + + // Update the number of fetched object + $this->_fetched++; + } + } + + /** + * Rewinds the iterator. + * + * This iterator cannot be rewound. + * + * @return void + * + * @see Iterator::rewind() + */ + public function rewind() + { + } + + /** + * Checks if the current position of the iterator is valid. + * + * @return boolean + * + * @see Iterator::valid() + */ + public function valid() + { + return (boolean) $this->_current; + } + + /** + * Method to fetch a row from the result set cursor as an object. + * + * @return mixed Either the next row from the result set or false if there are no more rows. + */ + abstract protected function fetchObject(); + + /** + * Method to free up the memory used for the result set. + * + * @return void + */ + abstract protected function freeResult(); + + /** + * Returns the data in $this->_current as a FOFTable instance + * + * @return FOFTable + * + * @throws OutOfBoundsException + */ + protected function getTable() + { + if (!$this->valid()) + { + throw new OutOfBoundsException('Cannot get item past iterator\'s bounds', 500); + } + + $this->_tableObject->bind($this->_current); + + return $this->_tableObject; + } +} diff --git a/Sites/pages/libraries/fof/database/iterator/azure.php b/Sites/pages/libraries/fof/database/iterator/azure.php new file mode 100644 index 00000000..384e1050 --- /dev/null +++ b/Sites/pages/libraries/fof/database/iterator/azure.php @@ -0,0 +1,20 @@ +cursor); + } + + /** + * Method to fetch a row from the result set cursor as an object. + * + * @return mixed Either the next row from the result set or false if there are no more rows. + */ + protected function fetchObject() + { + return @mysql_fetch_object($this->cursor, $this->class); + } + + /** + * Method to free up the memory used for the result set. + * + * @return void + */ + protected function freeResult() + { + @mysql_free_result($this->cursor); + } +} diff --git a/Sites/pages/libraries/fof/database/iterator/mysqli.php b/Sites/pages/libraries/fof/database/iterator/mysqli.php new file mode 100644 index 00000000..91de4c32 --- /dev/null +++ b/Sites/pages/libraries/fof/database/iterator/mysqli.php @@ -0,0 +1,51 @@ +cursor); + } + + /** + * Method to fetch a row from the result set cursor as an object. + * + * @return mixed Either the next row from the result set or false if there are no more rows. + */ + protected function fetchObject() + { + return @mysqli_fetch_object($this->cursor, $this->class); + } + + /** + * Method to free up the memory used for the result set. + * + * @return void + */ + protected function freeResult() + { + @mysqli_free_result($this->cursor); + } +} diff --git a/Sites/pages/libraries/fof/database/iterator/oracle.php b/Sites/pages/libraries/fof/database/iterator/oracle.php new file mode 100644 index 00000000..fc63e9e5 --- /dev/null +++ b/Sites/pages/libraries/fof/database/iterator/oracle.php @@ -0,0 +1,20 @@ +cursor) && $this->cursor instanceof PDOStatement) + { + return @$this->cursor->rowCount(); + } + else + { + return 0; + } + } + + /** + * Method to fetch a row from the result set cursor as an object. + * + * @return mixed Either the next row from the result set or false if there are no more rows. + */ + protected function fetchObject() + { + if (!empty($this->cursor) && $this->cursor instanceof PDOStatement) + { + return @$this->cursor->fetchObject($this->class); + } + else + { + return false; + } + } + + /** + * Method to free up the memory used for the result set. + * + * @return void + */ + protected function freeResult() + { + if (!empty($this->cursor) && $this->cursor instanceof PDOStatement) + { + @$this->cursor->closeCursor(); + } + } +} diff --git a/Sites/pages/libraries/fof/database/iterator/pdomysql.php b/Sites/pages/libraries/fof/database/iterator/pdomysql.php new file mode 100644 index 00000000..558455a3 --- /dev/null +++ b/Sites/pages/libraries/fof/database/iterator/pdomysql.php @@ -0,0 +1,20 @@ +cursor); + } + + /** + * Method to fetch a row from the result set cursor as an object. + * + * @return mixed Either the next row from the result set or false if there are no more rows. + */ + protected function fetchObject() + { + return @pg_fetch_object($this->cursor, null, $this->class); + } + + /** + * Method to free up the memory used for the result set. + * + * @return void + */ + protected function freeResult() + { + @pg_free_result($this->cursor); + } +} diff --git a/Sites/pages/libraries/fof/database/iterator/sqlite.php b/Sites/pages/libraries/fof/database/iterator/sqlite.php new file mode 100644 index 00000000..02cffb82 --- /dev/null +++ b/Sites/pages/libraries/fof/database/iterator/sqlite.php @@ -0,0 +1,20 @@ +cursor); + } + + /** + * Method to fetch a row from the result set cursor as an object. + * + * @return mixed Either the next row from the result set or false if there are no more rows. + */ + protected function fetchObject() + { + return @sqlsrv_fetch_object($this->cursor, $this->class); + } + + /** + * Method to free up the memory used for the result set. + * + * @return void + */ + protected function freeResult() + { + @sqlsrv_free_stmt($this->cursor); + } +} diff --git a/Sites/pages/libraries/fof/database/query.php b/Sites/pages/libraries/fof/database/query.php new file mode 100644 index 00000000..d8760920 --- /dev/null +++ b/Sites/pages/libraries/fof/database/query.php @@ -0,0 +1,1733 @@ +quote($args[0], isset($args[1]) ? $args[1] : true); + break; + + case 'qn': + return $this->quoteName($args[0], isset($args[1]) ? $args[1] : null); + break; + + case 'e': + return $this->escape($args[0], isset($args[1]) ? $args[1] : false); + break; + } + } + + /** + * Class constructor. + * + * @param FOFDatabaseDriver $db The database driver. + * + * @since 11.1 + */ + public function __construct(FOFDatabaseDriver $db = null) + { + $this->db = $db; + } + + /** + * Magic function to convert the query to a string. + * + * @return string The completed query. + * + * @since 11.1 + */ + public function __toString() + { + $query = ''; + + if ($this->sql) + { + return $this->sql; + } + + switch ($this->type) + { + case 'element': + $query .= (string) $this->element; + break; + + case 'select': + $query .= (string) $this->select; + $query .= (string) $this->from; + + if ($this->join) + { + // Special case for joins + foreach ($this->join as $join) + { + $query .= (string) $join; + } + } + + if ($this->where) + { + $query .= (string) $this->where; + } + + if ($this->group) + { + $query .= (string) $this->group; + } + + if ($this->having) + { + $query .= (string) $this->having; + } + + if ($this->order) + { + $query .= (string) $this->order; + } + + if ($this->union) + { + $query .= (string) $this->union; + } + + break; + + case 'delete': + $query .= (string) $this->delete; + $query .= (string) $this->from; + + if ($this->join) + { + // Special case for joins + foreach ($this->join as $join) + { + $query .= (string) $join; + } + } + + if ($this->where) + { + $query .= (string) $this->where; + } + + if ($this->order) + { + $query .= (string) $this->order; + } + + break; + + case 'update': + $query .= (string) $this->update; + + if ($this->join) + { + // Special case for joins + foreach ($this->join as $join) + { + $query .= (string) $join; + } + } + + $query .= (string) $this->set; + + if ($this->where) + { + $query .= (string) $this->where; + } + + if ($this->order) + { + $query .= (string) $this->order; + } + + break; + + case 'insert': + $query .= (string) $this->insert; + + // Set method + if ($this->set) + { + $query .= (string) $this->set; + } + // Columns-Values method + elseif ($this->values) + { + if ($this->columns) + { + $query .= (string) $this->columns; + } + + $elements = $this->values->getElements(); + + if (!($elements[0] instanceof $this)) + { + $query .= ' VALUES '; + } + + $query .= (string) $this->values; + } + + break; + + case 'call': + $query .= (string) $this->call; + break; + + case 'exec': + $query .= (string) $this->exec; + break; + } + + if ($this instanceof FOFDatabaseQueryLimitable) + { + $query = $this->processLimit($query, $this->limit, $this->offset); + } + + return $query; + } + + /** + * Magic function to get protected variable value + * + * @param string $name The name of the variable. + * + * @return mixed + * + * @since 11.1 + */ + public function __get($name) + { + return isset($this->$name) ? $this->$name : null; + } + + /** + * Add a single column, or array of columns to the CALL clause of the query. + * + * Note that you must not mix insert, update, delete and select method calls when building a query. + * The call method can, however, be called multiple times in the same query. + * + * Usage: + * $query->call('a.*')->call('b.id'); + * $query->call(array('a.*', 'b.id')); + * + * @param mixed $columns A string or an array of field names. + * + * @return FOFDatabaseQuery Returns this object to allow chaining. + * + * @since 12.1 + */ + public function call($columns) + { + $this->type = 'call'; + + if (is_null($this->call)) + { + $this->call = new FOFDatabaseQueryElement('CALL', $columns); + } + else + { + $this->call->append($columns); + } + + return $this; + } + + /** + * Casts a value to a char. + * + * Ensure that the value is properly quoted before passing to the method. + * + * Usage: + * $query->select($query->castAsChar('a')); + * + * @param string $value The value to cast as a char. + * + * @return string Returns the cast value. + * + * @since 11.1 + */ + public function castAsChar($value) + { + return $value; + } + + /** + * Gets the number of characters in a string. + * + * Note, use 'length' to find the number of bytes in a string. + * + * Usage: + * $query->select($query->charLength('a')); + * + * @param string $field A value. + * @param string $operator Comparison operator between charLength integer value and $condition + * @param string $condition Integer value to compare charLength with. + * + * @return string The required char length call. + * + * @since 11.1 + */ + public function charLength($field, $operator = null, $condition = null) + { + return 'CHAR_LENGTH(' . $field . ')' . (isset($operator) && isset($condition) ? ' ' . $operator . ' ' . $condition : ''); + } + + /** + * Clear data from the query or a specific clause of the query. + * + * @param string $clause Optionally, the name of the clause to clear, or nothing to clear the whole query. + * + * @return FOFDatabaseQuery Returns this object to allow chaining. + * + * @since 11.1 + */ + public function clear($clause = null) + { + $this->sql = null; + + switch ($clause) + { + case 'select': + $this->select = null; + $this->type = null; + break; + + case 'delete': + $this->delete = null; + $this->type = null; + break; + + case 'update': + $this->update = null; + $this->type = null; + break; + + case 'insert': + $this->insert = null; + $this->type = null; + $this->autoIncrementField = null; + break; + + case 'from': + $this->from = null; + break; + + case 'join': + $this->join = null; + break; + + case 'set': + $this->set = null; + break; + + case 'where': + $this->where = null; + break; + + case 'group': + $this->group = null; + break; + + case 'having': + $this->having = null; + break; + + case 'order': + $this->order = null; + break; + + case 'columns': + $this->columns = null; + break; + + case 'values': + $this->values = null; + break; + + case 'exec': + $this->exec = null; + $this->type = null; + break; + + case 'call': + $this->call = null; + $this->type = null; + break; + + case 'limit': + $this->offset = 0; + $this->limit = 0; + break; + + case 'offset': + $this->offset = 0; + break; + + case 'union': + $this->union = null; + break; + + case 'unionAll': + $this->unionAll = null; + break; + + default: + $this->type = null; + $this->select = null; + $this->delete = null; + $this->update = null; + $this->insert = null; + $this->from = null; + $this->join = null; + $this->set = null; + $this->where = null; + $this->group = null; + $this->having = null; + $this->order = null; + $this->columns = null; + $this->values = null; + $this->autoIncrementField = null; + $this->exec = null; + $this->call = null; + $this->union = null; + $this->unionAll = null; + $this->offset = 0; + $this->limit = 0; + break; + } + + return $this; + } + + /** + * Adds a column, or array of column names that would be used for an INSERT INTO statement. + * + * @param mixed $columns A column name, or array of column names. + * + * @return FOFDatabaseQuery Returns this object to allow chaining. + * + * @since 11.1 + */ + public function columns($columns) + { + if (is_null($this->columns)) + { + $this->columns = new FOFDatabaseQueryElement('()', $columns); + } + else + { + $this->columns->append($columns); + } + + return $this; + } + + /** + * Concatenates an array of column names or values. + * + * Usage: + * $query->select($query->concatenate(array('a', 'b'))); + * + * @param array $values An array of values to concatenate. + * @param string $separator As separator to place between each value. + * + * @return string The concatenated values. + * + * @since 11.1 + */ + public function concatenate($values, $separator = null) + { + if ($separator) + { + return 'CONCATENATE(' . implode(' || ' . $this->quote($separator) . ' || ', $values) . ')'; + } + else + { + return 'CONCATENATE(' . implode(' || ', $values) . ')'; + } + } + + /** + * Gets the current date and time. + * + * Usage: + * $query->where('published_up < '.$query->currentTimestamp()); + * + * @return string + * + * @since 11.1 + */ + public function currentTimestamp() + { + return 'CURRENT_TIMESTAMP()'; + } + + /** + * Returns a PHP date() function compliant date format for the database driver. + * + * This method is provided for use where the query object is passed to a function for modification. + * If you have direct access to the database object, it is recommended you use the getDateFormat method directly. + * + * @return string The format string. + * + * @since 11.1 + */ + public function dateFormat() + { + if (!($this->db instanceof FOFDatabaseDriver)) + { + throw new RuntimeException('JLIB_DATABASE_ERROR_INVALID_DB_OBJECT'); + } + + return $this->db->getDateFormat(); + } + + /** + * Creates a formatted dump of the query for debugging purposes. + * + * Usage: + * echo $query->dump(); + * + * @return string + * + * @since 11.3 + */ + public function dump() + { + return '
      ' . str_replace('#__', $this->db->getPrefix(), $this) . '
      '; + } + + /** + * Add a table name to the DELETE clause of the query. + * + * Note that you must not mix insert, update, delete and select method calls when building a query. + * + * Usage: + * $query->delete('#__a')->where('id = 1'); + * + * @param string $table The name of the table to delete from. + * + * @return FOFDatabaseQuery Returns this object to allow chaining. + * + * @since 11.1 + */ + public function delete($table = null) + { + $this->type = 'delete'; + $this->delete = new FOFDatabaseQueryElement('DELETE', null); + + if (!empty($table)) + { + $this->from($table); + } + + return $this; + } + + /** + * Method to escape a string for usage in an SQL statement. + * + * This method is provided for use where the query object is passed to a function for modification. + * If you have direct access to the database object, it is recommended you use the escape method directly. + * + * Note that 'e' is an alias for this method as it is in FOFDatabaseDriver. + * + * @param string $text The string to be escaped. + * @param boolean $extra Optional parameter to provide extra escaping. + * + * @return string The escaped string. + * + * @since 11.1 + * @throws RuntimeException if the internal db property is not a valid object. + */ + public function escape($text, $extra = false) + { + if (!($this->db instanceof FOFDatabaseDriver)) + { + throw new RuntimeException('JLIB_DATABASE_ERROR_INVALID_DB_OBJECT'); + } + + return $this->db->escape($text, $extra); + } + + /** + * Add a single column, or array of columns to the EXEC clause of the query. + * + * Note that you must not mix insert, update, delete and select method calls when building a query. + * The exec method can, however, be called multiple times in the same query. + * + * Usage: + * $query->exec('a.*')->exec('b.id'); + * $query->exec(array('a.*', 'b.id')); + * + * @param mixed $columns A string or an array of field names. + * + * @return FOFDatabaseQuery Returns this object to allow chaining. + * + * @since 12.1 + */ + public function exec($columns) + { + $this->type = 'exec'; + + if (is_null($this->exec)) + { + $this->exec = new FOFDatabaseQueryElement('EXEC', $columns); + } + else + { + $this->exec->append($columns); + } + + return $this; + } + + /** + * Add a table to the FROM clause of the query. + * + * Note that while an array of tables can be provided, it is recommended you use explicit joins. + * + * Usage: + * $query->select('*')->from('#__a'); + * + * @param mixed $tables A string or array of table names. + * This can be a FOFDatabaseQuery object (or a child of it) when used + * as a subquery in FROM clause along with a value for $subQueryAlias. + * @param string $subQueryAlias Alias used when $tables is a FOFDatabaseQuery. + * + * @return FOFDatabaseQuery Returns this object to allow chaining. + * + * @throws RuntimeException + * + * @since 11.1 + */ + public function from($tables, $subQueryAlias = null) + { + if (is_null($this->from)) + { + if ($tables instanceof $this) + { + if (is_null($subQueryAlias)) + { + throw new RuntimeException('JLIB_DATABASE_ERROR_NULL_SUBQUERY_ALIAS'); + } + + $tables = '( ' . (string) $tables . ' ) AS ' . $this->quoteName($subQueryAlias); + } + + $this->from = new FOFDatabaseQueryElement('FROM', $tables); + } + else + { + $this->from->append($tables); + } + + return $this; + } + + /** + * Used to get a string to extract year from date column. + * + * Usage: + * $query->select($query->year($query->quoteName('dateColumn'))); + * + * @param string $date Date column containing year to be extracted. + * + * @return string Returns string to extract year from a date. + * + * @since 12.1 + */ + public function year($date) + { + return 'YEAR(' . $date . ')'; + } + + /** + * Used to get a string to extract month from date column. + * + * Usage: + * $query->select($query->month($query->quoteName('dateColumn'))); + * + * @param string $date Date column containing month to be extracted. + * + * @return string Returns string to extract month from a date. + * + * @since 12.1 + */ + public function month($date) + { + return 'MONTH(' . $date . ')'; + } + + /** + * Used to get a string to extract day from date column. + * + * Usage: + * $query->select($query->day($query->quoteName('dateColumn'))); + * + * @param string $date Date column containing day to be extracted. + * + * @return string Returns string to extract day from a date. + * + * @since 12.1 + */ + public function day($date) + { + return 'DAY(' . $date . ')'; + } + + /** + * Used to get a string to extract hour from date column. + * + * Usage: + * $query->select($query->hour($query->quoteName('dateColumn'))); + * + * @param string $date Date column containing hour to be extracted. + * + * @return string Returns string to extract hour from a date. + * + * @since 12.1 + */ + public function hour($date) + { + return 'HOUR(' . $date . ')'; + } + + /** + * Used to get a string to extract minute from date column. + * + * Usage: + * $query->select($query->minute($query->quoteName('dateColumn'))); + * + * @param string $date Date column containing minute to be extracted. + * + * @return string Returns string to extract minute from a date. + * + * @since 12.1 + */ + public function minute($date) + { + return 'MINUTE(' . $date . ')'; + } + + /** + * Used to get a string to extract seconds from date column. + * + * Usage: + * $query->select($query->second($query->quoteName('dateColumn'))); + * + * @param string $date Date column containing second to be extracted. + * + * @return string Returns string to extract second from a date. + * + * @since 12.1 + */ + public function second($date) + { + return 'SECOND(' . $date . ')'; + } + + /** + * Add a grouping column to the GROUP clause of the query. + * + * Usage: + * $query->group('id'); + * + * @param mixed $columns A string or array of ordering columns. + * + * @return FOFDatabaseQuery Returns this object to allow chaining. + * + * @since 11.1 + */ + public function group($columns) + { + if (is_null($this->group)) + { + $this->group = new FOFDatabaseQueryElement('GROUP BY', $columns); + } + else + { + $this->group->append($columns); + } + + return $this; + } + + /** + * A conditions to the HAVING clause of the query. + * + * Usage: + * $query->group('id')->having('COUNT(id) > 5'); + * + * @param mixed $conditions A string or array of columns. + * @param string $glue The glue by which to join the conditions. Defaults to AND. + * + * @return FOFDatabaseQuery Returns this object to allow chaining. + * + * @since 11.1 + */ + public function having($conditions, $glue = 'AND') + { + if (is_null($this->having)) + { + $glue = strtoupper($glue); + $this->having = new FOFDatabaseQueryElement('HAVING', $conditions, " $glue "); + } + else + { + $this->having->append($conditions); + } + + return $this; + } + + /** + * Add an INNER JOIN clause to the query. + * + * Usage: + * $query->innerJoin('b ON b.id = a.id')->innerJoin('c ON c.id = b.id'); + * + * @param string $condition The join condition. + * + * @return FOFDatabaseQuery Returns this object to allow chaining. + * + * @since 11.1 + */ + public function innerJoin($condition) + { + $this->join('INNER', $condition); + + return $this; + } + + /** + * Add a table name to the INSERT clause of the query. + * + * Note that you must not mix insert, update, delete and select method calls when building a query. + * + * Usage: + * $query->insert('#__a')->set('id = 1'); + * $query->insert('#__a')->columns('id, title')->values('1,2')->values('3,4'); + * $query->insert('#__a')->columns('id, title')->values(array('1,2', '3,4')); + * + * @param mixed $table The name of the table to insert data into. + * @param boolean $incrementField The name of the field to auto increment. + * + * @return FOFDatabaseQuery Returns this object to allow chaining. + * + * @since 11.1 + */ + public function insert($table, $incrementField=false) + { + $this->type = 'insert'; + $this->insert = new FOFDatabaseQueryElement('INSERT INTO', $table); + $this->autoIncrementField = $incrementField; + + return $this; + } + + /** + * Add a JOIN clause to the query. + * + * Usage: + * $query->join('INNER', 'b ON b.id = a.id); + * + * @param string $type The type of join. This string is prepended to the JOIN keyword. + * @param string $conditions A string or array of conditions. + * + * @return FOFDatabaseQuery Returns this object to allow chaining. + * + * @since 11.1 + */ + public function join($type, $conditions) + { + if (is_null($this->join)) + { + $this->join = array(); + } + + $this->join[] = new FOFDatabaseQueryElement(strtoupper($type) . ' JOIN', $conditions); + + return $this; + } + + /** + * Add a LEFT JOIN clause to the query. + * + * Usage: + * $query->leftJoin('b ON b.id = a.id')->leftJoin('c ON c.id = b.id'); + * + * @param string $condition The join condition. + * + * @return FOFDatabaseQuery Returns this object to allow chaining. + * + * @since 11.1 + */ + public function leftJoin($condition) + { + $this->join('LEFT', $condition); + + return $this; + } + + /** + * Get the length of a string in bytes. + * + * Note, use 'charLength' to find the number of characters in a string. + * + * Usage: + * query->where($query->length('a').' > 3'); + * + * @param string $value The string to measure. + * + * @return int + * + * @since 11.1 + */ + public function length($value) + { + return 'LENGTH(' . $value . ')'; + } + + /** + * Get the null or zero representation of a timestamp for the database driver. + * + * This method is provided for use where the query object is passed to a function for modification. + * If you have direct access to the database object, it is recommended you use the nullDate method directly. + * + * Usage: + * $query->where('modified_date <> '.$query->nullDate()); + * + * @param boolean $quoted Optionally wraps the null date in database quotes (true by default). + * + * @return string Null or zero representation of a timestamp. + * + * @since 11.1 + */ + public function nullDate($quoted = true) + { + if (!($this->db instanceof FOFDatabaseDriver)) + { + throw new RuntimeException('JLIB_DATABASE_ERROR_INVALID_DB_OBJECT'); + } + + $result = $this->db->getNullDate($quoted); + + if ($quoted) + { + return $this->db->quote($result); + } + + return $result; + } + + /** + * Add a ordering column to the ORDER clause of the query. + * + * Usage: + * $query->order('foo')->order('bar'); + * $query->order(array('foo','bar')); + * + * @param mixed $columns A string or array of ordering columns. + * + * @return FOFDatabaseQuery Returns this object to allow chaining. + * + * @since 11.1 + */ + public function order($columns) + { + if (is_null($this->order)) + { + $this->order = new FOFDatabaseQueryElement('ORDER BY', $columns); + } + else + { + $this->order->append($columns); + } + + return $this; + } + + /** + * Add an OUTER JOIN clause to the query. + * + * Usage: + * $query->outerJoin('b ON b.id = a.id')->outerJoin('c ON c.id = b.id'); + * + * @param string $condition The join condition. + * + * @return FOFDatabaseQuery Returns this object to allow chaining. + * + * @since 11.1 + */ + public function outerJoin($condition) + { + $this->join('OUTER', $condition); + + return $this; + } + + /** + * Method to quote and optionally escape a string to database requirements for insertion into the database. + * + * This method is provided for use where the query object is passed to a function for modification. + * If you have direct access to the database object, it is recommended you use the quote method directly. + * + * Note that 'q' is an alias for this method as it is in FOFDatabaseDriver. + * + * Usage: + * $query->quote('fulltext'); + * $query->q('fulltext'); + * $query->q(array('option', 'fulltext')); + * + * @param mixed $text A string or an array of strings to quote. + * @param boolean $escape True to escape the string, false to leave it unchanged. + * + * @return string The quoted input string. + * + * @since 11.1 + * @throws RuntimeException if the internal db property is not a valid object. + */ + public function quote($text, $escape = true) + { + if (!($this->db instanceof FOFDatabaseDriver)) + { + throw new RuntimeException('JLIB_DATABASE_ERROR_INVALID_DB_OBJECT'); + } + + return $this->db->quote($text, $escape); + } + + /** + * Wrap an SQL statement identifier name such as column, table or database names in quotes to prevent injection + * risks and reserved word conflicts. + * + * This method is provided for use where the query object is passed to a function for modification. + * If you have direct access to the database object, it is recommended you use the quoteName method directly. + * + * Note that 'qn' is an alias for this method as it is in FOFDatabaseDriver. + * + * Usage: + * $query->quoteName('#__a'); + * $query->qn('#__a'); + * + * @param mixed $name The identifier name to wrap in quotes, or an array of identifier names to wrap in quotes. + * Each type supports dot-notation name. + * @param mixed $as The AS query part associated to $name. It can be string or array, in latter case it has to be + * same length of $name; if is null there will not be any AS part for string or array element. + * + * @return mixed The quote wrapped name, same type of $name. + * + * @since 11.1 + * @throws RuntimeException if the internal db property is not a valid object. + */ + public function quoteName($name, $as = null) + { + if (!($this->db instanceof FOFDatabaseDriver)) + { + throw new RuntimeException('JLIB_DATABASE_ERROR_INVALID_DB_OBJECT'); + } + + return $this->db->quoteName($name, $as); + } + + /** + * Add a RIGHT JOIN clause to the query. + * + * Usage: + * $query->rightJoin('b ON b.id = a.id')->rightJoin('c ON c.id = b.id'); + * + * @param string $condition The join condition. + * + * @return FOFDatabaseQuery Returns this object to allow chaining. + * + * @since 11.1 + */ + public function rightJoin($condition) + { + $this->join('RIGHT', $condition); + + return $this; + } + + /** + * Add a single column, or array of columns to the SELECT clause of the query. + * + * Note that you must not mix insert, update, delete and select method calls when building a query. + * The select method can, however, be called multiple times in the same query. + * + * Usage: + * $query->select('a.*')->select('b.id'); + * $query->select(array('a.*', 'b.id')); + * + * @param mixed $columns A string or an array of field names. + * + * @return FOFDatabaseQuery Returns this object to allow chaining. + * + * @since 11.1 + */ + public function select($columns) + { + $this->type = 'select'; + + if (is_null($this->select)) + { + $this->select = new FOFDatabaseQueryElement('SELECT', $columns); + } + else + { + $this->select->append($columns); + } + + return $this; + } + + /** + * Add a single condition string, or an array of strings to the SET clause of the query. + * + * Usage: + * $query->set('a = 1')->set('b = 2'); + * $query->set(array('a = 1', 'b = 2'); + * + * @param mixed $conditions A string or array of string conditions. + * @param string $glue The glue by which to join the condition strings. Defaults to ,. + * Note that the glue is set on first use and cannot be changed. + * + * @return FOFDatabaseQuery Returns this object to allow chaining. + * + * @since 11.1 + */ + public function set($conditions, $glue = ',') + { + if (is_null($this->set)) + { + $glue = strtoupper($glue); + $this->set = new FOFDatabaseQueryElement('SET', $conditions, "\n\t$glue "); + } + else + { + $this->set->append($conditions); + } + + return $this; + } + + /** + * Allows a direct query to be provided to the database + * driver's setQuery() method, but still allow queries + * to have bounded variables. + * + * Usage: + * $query->setQuery('select * from #__users'); + * + * @param mixed $sql An SQL Query + * + * @return FOFDatabaseQuery Returns this object to allow chaining. + * + * @since 12.1 + */ + public function setQuery($sql) + { + $this->sql = $sql; + + return $this; + } + + /** + * Add a table name to the UPDATE clause of the query. + * + * Note that you must not mix insert, update, delete and select method calls when building a query. + * + * Usage: + * $query->update('#__foo')->set(...); + * + * @param string $table A table to update. + * + * @return FOFDatabaseQuery Returns this object to allow chaining. + * + * @since 11.1 + */ + public function update($table) + { + $this->type = 'update'; + $this->update = new FOFDatabaseQueryElement('UPDATE', $table); + + return $this; + } + + /** + * Adds a tuple, or array of tuples that would be used as values for an INSERT INTO statement. + * + * Usage: + * $query->values('1,2,3')->values('4,5,6'); + * $query->values(array('1,2,3', '4,5,6')); + * + * @param string $values A single tuple, or array of tuples. + * + * @return FOFDatabaseQuery Returns this object to allow chaining. + * + * @since 11.1 + */ + public function values($values) + { + if (is_null($this->values)) + { + $this->values = new FOFDatabaseQueryElement('()', $values, '),('); + } + else + { + $this->values->append($values); + } + + return $this; + } + + /** + * Add a single condition, or an array of conditions to the WHERE clause of the query. + * + * Usage: + * $query->where('a = 1')->where('b = 2'); + * $query->where(array('a = 1', 'b = 2')); + * + * @param mixed $conditions A string or array of where conditions. + * @param string $glue The glue by which to join the conditions. Defaults to AND. + * Note that the glue is set on first use and cannot be changed. + * + * @return FOFDatabaseQuery Returns this object to allow chaining. + * + * @since 11.1 + */ + public function where($conditions, $glue = 'AND') + { + if (is_null($this->where)) + { + $glue = strtoupper($glue); + $this->where = new FOFDatabaseQueryElement('WHERE', $conditions, " $glue "); + } + else + { + $this->where->append($conditions); + } + + return $this; + } + + /** + * Method to provide deep copy support to nested objects and + * arrays when cloning. + * + * @return void + * + * @since 11.3 + */ + public function __clone() + { + foreach ($this as $k => $v) + { + if ($k === 'db') + { + continue; + } + + if (is_object($v) || is_array($v)) + { + $this->{$k} = unserialize(serialize($v)); + } + } + } + + /** + * Add a query to UNION with the current query. + * Multiple unions each require separate statements and create an array of unions. + * + * Usage (the $query base query MUST be a select query): + * $query->union('SELECT name FROM #__foo') + * $query->union('SELECT name FROM #__foo', true) + * $query->union(array('SELECT name FROM #__foo','SELECT name FROM #__bar')) + * $query->union($query2)->union($query3) + * $query->union(array($query2, $query3)) + * + * @param mixed $query The FOFDatabaseQuery object or string to union. + * @param boolean $distinct True to only return distinct rows from the union. + * @param string $glue The glue by which to join the conditions. + * + * @return mixed The FOFDatabaseQuery object on success or boolean false on failure. + * + * @see http://dev.mysql.com/doc/refman/5.0/en/union.html + * + * @since 12.1 + */ + public function union($query, $distinct = false, $glue = '') + { + // Set up the DISTINCT flag, the name with parentheses, and the glue. + if ($distinct) + { + $name = 'UNION DISTINCT ()'; + $glue = ')' . PHP_EOL . 'UNION DISTINCT ('; + } + else + { + $glue = ')' . PHP_EOL . 'UNION ('; + $name = 'UNION ()'; + } + + // Get the FOFDatabaseQueryElement if it does not exist + if (is_null($this->union)) + { + $this->union = new FOFDatabaseQueryElement($name, $query, "$glue"); + } + // Otherwise append the second UNION. + else + { + $this->union->append($query); + } + + return $this; + } + + /** + * Add a query to UNION DISTINCT with the current query. Simply a proxy to union with the DISTINCT keyword. + * + * Usage: + * $query->unionDistinct('SELECT name FROM #__foo') + * + * @param mixed $query The FOFDatabaseQuery object or string to union. + * @param string $glue The glue by which to join the conditions. + * + * @return mixed The FOFDatabaseQuery object on success or boolean false on failure. + * + * @see union + * + * @since 12.1 + */ + public function unionDistinct($query, $glue = '') + { + $distinct = true; + + // Apply the distinct flag to the union. + return $this->union($query, $distinct, $glue); + } + + /** + * Find and replace sprintf-like tokens in a format string. + * Each token takes one of the following forms: + * %% - A literal percent character. + * %[t] - Where [t] is a type specifier. + * %[n]$[x] - Where [n] is an argument specifier and [t] is a type specifier. + * + * Types: + * a - Numeric: Replacement text is coerced to a numeric type but not quoted or escaped. + * e - Escape: Replacement text is passed to $this->escape(). + * E - Escape (extra): Replacement text is passed to $this->escape() with true as the second argument. + * n - Name Quote: Replacement text is passed to $this->quoteName(). + * q - Quote: Replacement text is passed to $this->quote(). + * Q - Quote (no escape): Replacement text is passed to $this->quote() with false as the second argument. + * r - Raw: Replacement text is used as-is. (Be careful) + * + * Date Types: + * - Replacement text automatically quoted (use uppercase for Name Quote). + * - Replacement text should be a string in date format or name of a date column. + * y/Y - Year + * m/M - Month + * d/D - Day + * h/H - Hour + * i/I - Minute + * s/S - Second + * + * Invariable Types: + * - Takes no argument. + * - Argument index not incremented. + * t - Replacement text is the result of $this->currentTimestamp(). + * z - Replacement text is the result of $this->nullDate(false). + * Z - Replacement text is the result of $this->nullDate(true). + * + * Usage: + * $query->format('SELECT %1$n FROM %2$n WHERE %3$n = %4$a', 'foo', '#__foo', 'bar', 1); + * Returns: SELECT `foo` FROM `#__foo` WHERE `bar` = 1 + * + * Notes: + * The argument specifier is optional but recommended for clarity. + * The argument index used for unspecified tokens is incremented only when used. + * + * @param string $format The formatting string. + * + * @return string Returns a string produced according to the formatting string. + * + * @since 12.3 + */ + public function format($format) + { + $query = $this; + $args = array_slice(func_get_args(), 1); + array_unshift($args, null); + + $i = 1; + $func = function ($match) use ($query, $args, &$i) + { + if (isset($match[6]) && $match[6] == '%') + { + return '%'; + } + + // No argument required, do not increment the argument index. + switch ($match[5]) + { + case 't': + return $query->currentTimestamp(); + break; + + case 'z': + return $query->nullDate(false); + break; + + case 'Z': + return $query->nullDate(true); + break; + } + + // Increment the argument index only if argument specifier not provided. + $index = is_numeric($match[4]) ? (int) $match[4] : $i++; + + if (!$index || !isset($args[$index])) + { + // TODO - What to do? sprintf() throws a Warning in these cases. + $replacement = ''; + } + else + { + $replacement = $args[$index]; + } + + switch ($match[5]) + { + case 'a': + return 0 + $replacement; + break; + + case 'e': + return $query->escape($replacement); + break; + + case 'E': + return $query->escape($replacement, true); + break; + + case 'n': + return $query->quoteName($replacement); + break; + + case 'q': + return $query->quote($replacement); + break; + + case 'Q': + return $query->quote($replacement, false); + break; + + case 'r': + return $replacement; + break; + + // Dates + case 'y': + return $query->year($query->quote($replacement)); + break; + + case 'Y': + return $query->year($query->quoteName($replacement)); + break; + + case 'm': + return $query->month($query->quote($replacement)); + break; + + case 'M': + return $query->month($query->quoteName($replacement)); + break; + + case 'd': + return $query->day($query->quote($replacement)); + break; + + case 'D': + return $query->day($query->quoteName($replacement)); + break; + + case 'h': + return $query->hour($query->quote($replacement)); + break; + + case 'H': + return $query->hour($query->quoteName($replacement)); + break; + + case 'i': + return $query->minute($query->quote($replacement)); + break; + + case 'I': + return $query->minute($query->quoteName($replacement)); + break; + + case 's': + return $query->second($query->quote($replacement)); + break; + + case 'S': + return $query->second($query->quoteName($replacement)); + break; + } + + return ''; + }; + + /** + * Regexp to find an replace all tokens. + * Matched fields: + * 0: Full token + * 1: Everything following '%' + * 2: Everything following '%' unless '%' + * 3: Argument specifier and '$' + * 4: Argument specifier + * 5: Type specifier + * 6: '%' if full token is '%%' + */ + return preg_replace_callback('#%(((([\d]+)\$)?([aeEnqQryYmMdDhHiIsStzZ]))|(%))#', $func, $format); + } + + /** + * Add to the current date and time. + * Usage: + * $query->select($query->dateAdd()); + * Prefixing the interval with a - (negative sign) will cause subtraction to be used. + * Note: Not all drivers support all units. + * + * @param datetime $date The date to add to. May be date or datetime + * @param string $interval The string representation of the appropriate number of units + * @param string $datePart The part of the date to perform the addition on + * + * @return string The string with the appropriate sql for addition of dates + * + * @link http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html#function_date-add + * @since 13.1 + */ + public function dateAdd($date, $interval, $datePart) + { + return trim("DATE_ADD('" . $date . "', INTERVAL " . $interval . ' ' . $datePart . ')'); + } + + /** + * Add a query to UNION ALL with the current query. + * Multiple unions each require separate statements and create an array of unions. + * + * Usage: + * $query->union('SELECT name FROM #__foo') + * $query->union(array('SELECT name FROM #__foo','SELECT name FROM #__bar')) + * + * @param mixed $query The FOFDatabaseQuery object or string to union. + * @param boolean $distinct Not used - ignored. + * @param string $glue Not used - ignored. + * + * @return mixed The FOFDatabaseQuery object on success or boolean false on failure. + * + * @see union + * + * @since 13.1 + */ + public function unionAll($query, $distinct = false, $glue = '') + { + $glue = ')' . PHP_EOL . 'UNION ALL ('; + $name = 'UNION ALL ()'; + + // Get the FOFDatabaseQueryElement if it does not exist + if (is_null($this->unionAll)) + { + $this->unionAll = new FOFDatabaseQueryElement($name, $query, "$glue"); + } + + // Otherwise append the second UNION. + else + { + $this->unionAll->append($query); + } + + return $this; + } +} diff --git a/Sites/pages/libraries/fof/database/query/element.php b/Sites/pages/libraries/fof/database/query/element.php new file mode 100644 index 00000000..f3a5bae8 --- /dev/null +++ b/Sites/pages/libraries/fof/database/query/element.php @@ -0,0 +1,132 @@ +elements = array(); + $this->name = $name; + $this->glue = $glue; + + $this->append($elements); + } + + /** + * Magic function to convert the query element to a string. + * + * @return string + * + * @since 11.1 + */ + public function __toString() + { + if (substr($this->name, -2) == '()') + { + return PHP_EOL . substr($this->name, 0, -2) . '(' . implode($this->glue, $this->elements) . ')'; + } + else + { + return PHP_EOL . $this->name . ' ' . implode($this->glue, $this->elements); + } + } + + /** + * Appends element parts to the internal list. + * + * @param mixed $elements String or array. + * + * @return void + * + * @since 11.1 + */ + public function append($elements) + { + if (is_array($elements)) + { + $this->elements = array_merge($this->elements, $elements); + } + else + { + $this->elements = array_merge($this->elements, array($elements)); + } + } + + /** + * Gets the elements of this element. + * + * @return array + * + * @since 11.1 + */ + public function getElements() + { + return $this->elements; + } + + /** + * Method to provide deep copy support to nested objects and arrays + * when cloning. + * + * @return void + * + * @since 11.3 + */ + public function __clone() + { + foreach ($this as $k => $v) + { + if (is_object($v) || is_array($v)) + { + $this->{$k} = unserialize(serialize($v)); + } + } + } +} diff --git a/Sites/pages/libraries/fof/database/query/limitable.php b/Sites/pages/libraries/fof/database/query/limitable.php new file mode 100644 index 00000000..5d450e5b --- /dev/null +++ b/Sites/pages/libraries/fof/database/query/limitable.php @@ -0,0 +1,72 @@ +setLimit(100, 0); (retrieve 100 rows, starting at first record) + * $query->setLimit(50, 50); (retrieve 50 rows, starting at 50th record) + * + * @param integer $limit The limit for the result set + * @param integer $offset The offset for the result set + * + * @return FOFDatabaseQuery Returns this object to allow chaining. + * + * @since 12.1 + */ + public function setLimit($limit = 0, $offset = 0); + } +} + +/** + * Joomla Database Query Limitable Interface. + * Adds bind/unbind methods as well as a getBounded() method + * to retrieve the stored bounded variables on demand prior to + * query execution. + * + * @since 12.1 + */ +interface FOFDatabaseQueryLimitable extends JDatabaseQueryLimitable +{ +} diff --git a/Sites/pages/libraries/fof/database/query/mysql.php b/Sites/pages/libraries/fof/database/query/mysql.php new file mode 100644 index 00000000..73db5b31 --- /dev/null +++ b/Sites/pages/libraries/fof/database/query/mysql.php @@ -0,0 +1,23 @@ + 0 || $offset > 0) + { + $query .= ' LIMIT ' . $offset . ', ' . $limit; + } + + return $query; + } + + /** + * Concatenates an array of column names or values. + * + * @param array $values An array of values to concatenate. + * @param string $separator As separator to place between each value. + * + * @return string The concatenated values. + * + * @since 11.1 + */ + public function concatenate($values, $separator = null) + { + if ($separator) + { + $concat_string = 'CONCAT_WS(' . $this->quote($separator); + + foreach ($values as $value) + { + $concat_string .= ', ' . $value; + } + + return $concat_string . ')'; + } + else + { + return 'CONCAT(' . implode(',', $values) . ')'; + } + } + + /** + * Sets the offset and limit for the result set, if the database driver supports it. + * + * Usage: + * $query->setLimit(100, 0); (retrieve 100 rows, starting at first record) + * $query->setLimit(50, 50); (retrieve 50 rows, starting at 50th record) + * + * @param integer $limit The limit for the result set + * @param integer $offset The offset for the result set + * + * @return FOFDatabaseQuery Returns this object to allow chaining. + * + * @since 12.1 + */ + public function setLimit($limit = 0, $offset = 0) + { + $this->limit = (int) $limit; + $this->offset = (int) $offset; + + return $this; + } + + /** + * Return correct regexp operator for mysqli. + * + * Ensure that the regexp operator is mysqli compatible. + * + * Usage: + * $query->where('field ' . $query->regexp($search)); + * + * @param string $value The regex pattern. + * + * @return string Returns the regex operator. + * + * @since 11.3 + */ + public function regexp($value) + { + return ' REGEXP ' . $value; + } + + /** + * Return correct rand() function for Mysql. + * + * Ensure that the rand() function is Mysql compatible. + * + * Usage: + * $query->Rand(); + * + * @return string The correct rand function. + * + * @since 3.5 + */ + public function Rand() + { + return ' RAND() '; + } +} diff --git a/Sites/pages/libraries/fof/database/query/oracle.php b/Sites/pages/libraries/fof/database/query/oracle.php new file mode 100644 index 00000000..62206908 --- /dev/null +++ b/Sites/pages/libraries/fof/database/query/oracle.php @@ -0,0 +1,205 @@ +bounded = array(); + + return $this; + } + + // Case 2: Key Provided, null value (unset key from $bounded array) + if (is_null($value)) + { + if (isset($this->bounded[$key])) + { + unset($this->bounded[$key]); + } + + return $this; + } + + $obj = new stdClass; + + $obj->value = &$value; + $obj->dataType = $dataType; + $obj->length = $length; + $obj->driverOptions = $driverOptions; + + // Case 3: Simply add the Key/Value into the bounded array + $this->bounded[$key] = $obj; + + return $this; + } + + /** + * Retrieves the bound parameters array when key is null and returns it by reference. If a key is provided then that item is + * returned. + * + * @param mixed $key The bounded variable key to retrieve. + * + * @return mixed + * + * @since 12.1 + */ + public function &getBounded($key = null) + { + if (empty($key)) + { + return $this->bounded; + } + else + { + if (isset($this->bounded[$key])) + { + return $this->bounded[$key]; + } + } + } + + /** + * Clear data from the query or a specific clause of the query. + * + * @param string $clause Optionally, the name of the clause to clear, or nothing to clear the whole query. + * + * @return FOFDatabaseQueryOracle Returns this object to allow chaining. + * + * @since 12.1 + */ + public function clear($clause = null) + { + switch ($clause) + { + case null: + $this->bounded = array(); + break; + } + + parent::clear($clause); + + return $this; + } + + /** + * Method to modify a query already in string format with the needed + * additions to make the query limited to a particular number of + * results, or start at a particular offset. This method is used + * automatically by the __toString() method if it detects that the + * query implements the FOFDatabaseQueryLimitable interface. + * + * @param string $query The query in string format + * @param integer $limit The limit for the result set + * @param integer $offset The offset for the result set + * + * @return string + * + * @since 12.1 + */ + public function processLimit($query, $limit, $offset = 0) + { + // Check if we need to mangle the query. + if ($limit || $offset) + { + $query = "SELECT joomla2.* + FROM ( + SELECT joomla1.*, ROWNUM AS joomla_db_rownum + FROM ( + " . $query . " + ) joomla1 + ) joomla2"; + + // Check if the limit value is greater than zero. + if ($limit > 0) + { + $query .= ' WHERE joomla2.joomla_db_rownum BETWEEN ' . ($offset + 1) . ' AND ' . ($offset + $limit); + } + else + { + // Check if there is an offset and then use this. + if ($offset) + { + $query .= ' WHERE joomla2.joomla_db_rownum > ' . ($offset + 1); + } + } + } + + return $query; + } + + /** + * Sets the offset and limit for the result set, if the database driver supports it. + * + * Usage: + * $query->setLimit(100, 0); (retrieve 100 rows, starting at first record) + * $query->setLimit(50, 50); (retrieve 50 rows, starting at 50th record) + * + * @param integer $limit The limit for the result set + * @param integer $offset The offset for the result set + * + * @return FOFDatabaseQueryOracle Returns this object to allow chaining. + * + * @since 12.1 + */ + public function setLimit($limit = 0, $offset = 0) + { + $this->limit = (int) $limit; + $this->offset = (int) $offset; + + return $this; + } +} diff --git a/Sites/pages/libraries/fof/database/query/pdo.php b/Sites/pages/libraries/fof/database/query/pdo.php new file mode 100644 index 00000000..13d36198 --- /dev/null +++ b/Sites/pages/libraries/fof/database/query/pdo.php @@ -0,0 +1,22 @@ +type) + { + case 'select': + $query .= (string) $this->select; + $query .= (string) $this->from; + + if ($this->join) + { + // Special case for joins + foreach ($this->join as $join) + { + $query .= (string) $join; + } + } + + if ($this->where) + { + $query .= (string) $this->where; + } + + if ($this->group) + { + $query .= (string) $this->group; + } + + if ($this->having) + { + $query .= (string) $this->having; + } + + if ($this->order) + { + $query .= (string) $this->order; + } + + if ($this->forUpdate) + { + $query .= (string) $this->forUpdate; + } + else + { + if ($this->forShare) + { + $query .= (string) $this->forShare; + } + } + + if ($this->noWait) + { + $query .= (string) $this->noWait; + } + + break; + + case 'update': + $query .= (string) $this->update; + $query .= (string) $this->set; + + if ($this->join) + { + $onWord = ' ON '; + + // Workaround for special case of JOIN with UPDATE + foreach ($this->join as $join) + { + $joinElem = $join->getElements(); + + $joinArray = explode($onWord, $joinElem[0]); + + $this->from($joinArray[0]); + $this->where($joinArray[1]); + } + + $query .= (string) $this->from; + } + + if ($this->where) + { + $query .= (string) $this->where; + } + + break; + + case 'insert': + $query .= (string) $this->insert; + + if ($this->values) + { + if ($this->columns) + { + $query .= (string) $this->columns; + } + + $elements = $this->values->getElements(); + + if (!($elements[0] instanceof $this)) + { + $query .= ' VALUES '; + } + + $query .= (string) $this->values; + + if ($this->returning) + { + $query .= (string) $this->returning; + } + } + + break; + + default: + $query = parent::__toString(); + break; + } + + if ($this instanceof FOFDatabaseQueryLimitable) + { + $query = $this->processLimit($query, $this->limit, $this->offset); + } + + return $query; + } + + /** + * Clear data from the query or a specific clause of the query. + * + * @param string $clause Optionally, the name of the clause to clear, or nothing to clear the whole query. + * + * @return FOFDatabaseQueryPostgresql Returns this object to allow chaining. + * + * @since 11.3 + */ + public function clear($clause = null) + { + switch ($clause) + { + case 'limit': + $this->limit = null; + break; + + case 'offset': + $this->offset = null; + break; + + case 'forUpdate': + $this->forUpdate = null; + break; + + case 'forShare': + $this->forShare = null; + break; + + case 'noWait': + $this->noWait = null; + break; + + case 'returning': + $this->returning = null; + break; + + case 'select': + case 'update': + case 'delete': + case 'insert': + case 'from': + case 'join': + case 'set': + case 'where': + case 'group': + case 'having': + case 'order': + case 'columns': + case 'values': + parent::clear($clause); + break; + + default: + $this->type = null; + $this->limit = null; + $this->offset = null; + $this->forUpdate = null; + $this->forShare = null; + $this->noWait = null; + $this->returning = null; + parent::clear($clause); + break; + } + + return $this; + } + + /** + * Casts a value to a char. + * + * Ensure that the value is properly quoted before passing to the method. + * + * Usage: + * $query->select($query->castAsChar('a')); + * + * @param string $value The value to cast as a char. + * + * @return string Returns the cast value. + * + * @since 11.3 + */ + public function castAsChar($value) + { + return $value . '::text'; + } + + /** + * Concatenates an array of column names or values. + * + * Usage: + * $query->select($query->concatenate(array('a', 'b'))); + * + * @param array $values An array of values to concatenate. + * @param string $separator As separator to place between each value. + * + * @return string The concatenated values. + * + * @since 11.3 + */ + public function concatenate($values, $separator = null) + { + if ($separator) + { + return implode(' || ' . $this->quote($separator) . ' || ', $values); + } + else + { + return implode(' || ', $values); + } + } + + /** + * Gets the current date and time. + * + * @return string Return string used in query to obtain + * + * @since 11.3 + */ + public function currentTimestamp() + { + return 'NOW()'; + } + + /** + * Sets the FOR UPDATE lock on select's output row + * + * @param string $table_name The table to lock + * @param string $glue The glue by which to join the conditions. Defaults to ',' . + * + * @return FOFDatabaseQueryPostgresql FOR UPDATE query element + * + * @since 11.3 + */ + public function forUpdate($table_name, $glue = ',') + { + $this->type = 'forUpdate'; + + if (is_null($this->forUpdate)) + { + $glue = strtoupper($glue); + $this->forUpdate = new FOFDatabaseQueryElement('FOR UPDATE', 'OF ' . $table_name, "$glue "); + } + else + { + $this->forUpdate->append($table_name); + } + + return $this; + } + + /** + * Sets the FOR SHARE lock on select's output row + * + * @param string $table_name The table to lock + * @param string $glue The glue by which to join the conditions. Defaults to ',' . + * + * @return FOFDatabaseQueryPostgresql FOR SHARE query element + * + * @since 11.3 + */ + public function forShare($table_name, $glue = ',') + { + $this->type = 'forShare'; + + if (is_null($this->forShare)) + { + $glue = strtoupper($glue); + $this->forShare = new FOFDatabaseQueryElement('FOR SHARE', 'OF ' . $table_name, "$glue "); + } + else + { + $this->forShare->append($table_name); + } + + return $this; + } + + /** + * Used to get a string to extract year from date column. + * + * Usage: + * $query->select($query->year($query->quoteName('dateColumn'))); + * + * @param string $date Date column containing year to be extracted. + * + * @return string Returns string to extract year from a date. + * + * @since 12.1 + */ + public function year($date) + { + return 'EXTRACT (YEAR FROM ' . $date . ')'; + } + + /** + * Used to get a string to extract month from date column. + * + * Usage: + * $query->select($query->month($query->quoteName('dateColumn'))); + * + * @param string $date Date column containing month to be extracted. + * + * @return string Returns string to extract month from a date. + * + * @since 12.1 + */ + public function month($date) + { + return 'EXTRACT (MONTH FROM ' . $date . ')'; + } + + /** + * Used to get a string to extract day from date column. + * + * Usage: + * $query->select($query->day($query->quoteName('dateColumn'))); + * + * @param string $date Date column containing day to be extracted. + * + * @return string Returns string to extract day from a date. + * + * @since 12.1 + */ + public function day($date) + { + return 'EXTRACT (DAY FROM ' . $date . ')'; + } + + /** + * Used to get a string to extract hour from date column. + * + * Usage: + * $query->select($query->hour($query->quoteName('dateColumn'))); + * + * @param string $date Date column containing hour to be extracted. + * + * @return string Returns string to extract hour from a date. + * + * @since 12.1 + */ + public function hour($date) + { + return 'EXTRACT (HOUR FROM ' . $date . ')'; + } + + /** + * Used to get a string to extract minute from date column. + * + * Usage: + * $query->select($query->minute($query->quoteName('dateColumn'))); + * + * @param string $date Date column containing minute to be extracted. + * + * @return string Returns string to extract minute from a date. + * + * @since 12.1 + */ + public function minute($date) + { + return 'EXTRACT (MINUTE FROM ' . $date . ')'; + } + + /** + * Used to get a string to extract seconds from date column. + * + * Usage: + * $query->select($query->second($query->quoteName('dateColumn'))); + * + * @param string $date Date column containing second to be extracted. + * + * @return string Returns string to extract second from a date. + * + * @since 12.1 + */ + public function second($date) + { + return 'EXTRACT (SECOND FROM ' . $date . ')'; + } + + /** + * Sets the NOWAIT lock on select's output row + * + * @return FOFDatabaseQueryPostgresql NO WAIT query element + * + * @since 11.3 + */ + public function noWait () + { + $this->type = 'noWait'; + + if (is_null($this->noWait)) + { + $this->noWait = new FOFDatabaseQueryElement('NOWAIT', null); + } + + return $this; + } + + /** + * Set the LIMIT clause to the query + * + * @param integer $limit An int of how many row will be returned + * + * @return FOFDatabaseQueryPostgresql Returns this object to allow chaining. + * + * @since 11.3 + */ + public function limit($limit = 0) + { + if (is_null($this->limit)) + { + $this->limit = new FOFDatabaseQueryElement('LIMIT', (int) $limit); + } + + return $this; + } + + /** + * Set the OFFSET clause to the query + * + * @param integer $offset An int for skipping row + * + * @return FOFDatabaseQueryPostgresql Returns this object to allow chaining. + * + * @since 11.3 + */ + public function offset($offset = 0) + { + if (is_null($this->offset)) + { + $this->offset = new FOFDatabaseQueryElement('OFFSET', (int) $offset); + } + + return $this; + } + + /** + * Add the RETURNING element to INSERT INTO statement. + * + * @param mixed $pkCol The name of the primary key column. + * + * @return FOFDatabaseQueryPostgresql Returns this object to allow chaining. + * + * @since 11.3 + */ + public function returning($pkCol) + { + if (is_null($this->returning)) + { + $this->returning = new FOFDatabaseQueryElement('RETURNING', $pkCol); + } + + return $this; + } + + /** + * Sets the offset and limit for the result set, if the database driver supports it. + * + * Usage: + * $query->setLimit(100, 0); (retrieve 100 rows, starting at first record) + * $query->setLimit(50, 50); (retrieve 50 rows, starting at 50th record) + * + * @param integer $limit The limit for the result set + * @param integer $offset The offset for the result set + * + * @return FOFDatabaseQueryPostgresql Returns this object to allow chaining. + * + * @since 12.1 + */ + public function setLimit($limit = 0, $offset = 0) + { + $this->limit = (int) $limit; + $this->offset = (int) $offset; + + return $this; + } + + /** + * Method to modify a query already in string format with the needed + * additions to make the query limited to a particular number of + * results, or start at a particular offset. + * + * @param string $query The query in string format + * @param integer $limit The limit for the result set + * @param integer $offset The offset for the result set + * + * @return string + * + * @since 12.1 + */ + public function processLimit($query, $limit, $offset = 0) + { + if ($limit > 0) + { + $query .= ' LIMIT ' . $limit; + } + + if ($offset > 0) + { + $query .= ' OFFSET ' . $offset; + } + + return $query; + } + + /** + * Add to the current date and time in Postgresql. + * Usage: + * $query->select($query->dateAdd()); + * Prefixing the interval with a - (negative sign) will cause subtraction to be used. + * + * @param datetime $date The date to add to + * @param string $interval The string representation of the appropriate number of units + * @param string $datePart The part of the date to perform the addition on + * + * @return string The string with the appropriate sql for addition of dates + * + * @since 13.1 + * @note Not all drivers support all units. Check appropriate references + * @link http://www.postgresql.org/docs/9.0/static/functions-datetime.html. + */ + public function dateAdd($date, $interval, $datePart) + { + if (substr($interval, 0, 1) != '-') + { + return "timestamp '" . $date . "' + interval '" . $interval . " " . $datePart . "'"; + } + else + { + return "timestamp '" . $date . "' - interval '" . ltrim($interval, '-') . " " . $datePart . "'"; + } + } + + /** + * Return correct regexp operator for Postgresql. + * + * Ensure that the regexp operator is Postgresql compatible. + * + * Usage: + * $query->where('field ' . $query->regexp($search)); + * + * @param string $value The regex pattern. + * + * @return string Returns the regex operator. + * + * @since 11.3 + */ + public function regexp($value) + { + return ' ~* ' . $value; + } + + /** + * Return correct rand() function for Postgresql. + * + * Ensure that the rand() function is Postgresql compatible. + * + * Usage: + * $query->Rand(); + * + * @return string The correct rand function. + * + * @since 3.5 + */ + public function Rand() + { + return ' RANDOM() '; + } +} diff --git a/Sites/pages/libraries/fof/database/query/preparable.php b/Sites/pages/libraries/fof/database/query/preparable.php new file mode 100644 index 00000000..8f58bfa8 --- /dev/null +++ b/Sites/pages/libraries/fof/database/query/preparable.php @@ -0,0 +1,62 @@ +bounded = array(); + + return $this; + } + + // Case 2: Key Provided, null value (unset key from $bounded array) + if (is_null($value)) + { + if (isset($this->bounded[$key])) + { + unset($this->bounded[$key]); + } + + return $this; + } + + $obj = new stdClass; + + $obj->value = &$value; + $obj->dataType = $dataType; + $obj->length = $length; + $obj->driverOptions = $driverOptions; + + // Case 3: Simply add the Key/Value into the bounded array + $this->bounded[$key] = $obj; + + return $this; + } + + /** + * Retrieves the bound parameters array when key is null and returns it by reference. If a key is provided then that item is + * returned. + * + * @param mixed $key The bounded variable key to retrieve. + * + * @return mixed + * + * @since 12.1 + */ + public function &getBounded($key = null) + { + if (empty($key)) + { + return $this->bounded; + } + else + { + if (isset($this->bounded[$key])) + { + return $this->bounded[$key]; + } + } + } + + /** + * Gets the number of characters in a string. + * + * Note, use 'length' to find the number of bytes in a string. + * + * Usage: + * $query->select($query->charLength('a')); + * + * @param string $field A value. + * @param string $operator Comparison operator between charLength integer value and $condition + * @param string $condition Integer value to compare charLength with. + * + * @return string The required char length call. + * + * @since 13.1 + */ + public function charLength($field, $operator = null, $condition = null) + { + return 'length(' . $field . ')' . (isset($operator) && isset($condition) ? ' ' . $operator . ' ' . $condition : ''); + } + + /** + * Clear data from the query or a specific clause of the query. + * + * @param string $clause Optionally, the name of the clause to clear, or nothing to clear the whole query. + * + * @return FOFDatabaseQuerySqlite Returns this object to allow chaining. + * + * @since 12.1 + */ + public function clear($clause = null) + { + switch ($clause) + { + case null: + $this->bounded = array(); + break; + } + + parent::clear($clause); + + return $this; + } + + /** + * Concatenates an array of column names or values. + * + * Usage: + * $query->select($query->concatenate(array('a', 'b'))); + * + * @param array $values An array of values to concatenate. + * @param string $separator As separator to place between each value. + * + * @return string The concatenated values. + * + * @since 11.1 + */ + public function concatenate($values, $separator = null) + { + if ($separator) + { + return implode(' || ' . $this->quote($separator) . ' || ', $values); + } + else + { + return implode(' || ', $values); + } + } + + /** + * Method to modify a query already in string format with the needed + * additions to make the query limited to a particular number of + * results, or start at a particular offset. This method is used + * automatically by the __toString() method if it detects that the + * query implements the FOFDatabaseQueryLimitable interface. + * + * @param string $query The query in string format + * @param integer $limit The limit for the result set + * @param integer $offset The offset for the result set + * + * @return string + * + * @since 12.1 + */ + public function processLimit($query, $limit, $offset = 0) + { + if ($limit > 0 || $offset > 0) + { + $query .= ' LIMIT ' . $offset . ', ' . $limit; + } + + return $query; + } + + /** + * Sets the offset and limit for the result set, if the database driver supports it. + * + * Usage: + * $query->setLimit(100, 0); (retrieve 100 rows, starting at first record) + * $query->setLimit(50, 50); (retrieve 50 rows, starting at 50th record) + * + * @param integer $limit The limit for the result set + * @param integer $offset The offset for the result set + * + * @return FOFDatabaseQuerySqlite Returns this object to allow chaining. + * + * @since 12.1 + */ + public function setLimit($limit = 0, $offset = 0) + { + $this->limit = (int) $limit; + $this->offset = (int) $offset; + + return $this; + } + + /** + * Add to the current date and time. + * Usage: + * $query->select($query->dateAdd()); + * Prefixing the interval with a - (negative sign) will cause subtraction to be used. + * + * @param datetime $date The date or datetime to add to + * @param string $interval The string representation of the appropriate number of units + * @param string $datePart The part of the date to perform the addition on + * + * @return string The string with the appropriate sql for addition of dates + * + * @since 13.1 + * @link http://www.sqlite.org/lang_datefunc.html + */ + public function dateAdd($date, $interval, $datePart) + { + // SQLite does not support microseconds as a separate unit. Convert the interval to seconds + if (strcasecmp($datePart, 'microseconds') == 0) + { + $interval = .001 * $interval; + $datePart = 'seconds'; + } + + if (substr($interval, 0, 1) != '-') + { + return "datetime('" . $date . "', '+" . $interval . " " . $datePart . "')"; + } + else + { + return "datetime('" . $date . "', '" . $interval . " " . $datePart . "')"; + } + } + + /** + * Gets the current date and time. + * + * Usage: + * $query->where('published_up < '.$query->currentTimestamp()); + * + * @return string + * + * @since 3.4 + */ + public function currentTimestamp() + { + return 'CURRENT_TIMESTAMP'; + } +} diff --git a/Sites/pages/libraries/fof/database/query/sqlsrv.php b/Sites/pages/libraries/fof/database/query/sqlsrv.php new file mode 100644 index 00000000..bee0f807 --- /dev/null +++ b/Sites/pages/libraries/fof/database/query/sqlsrv.php @@ -0,0 +1,380 @@ +type) + { + case 'select': + $query .= (string) $this->select; + $query .= (string) $this->from; + + if ($this->join) + { + // Special case for joins + foreach ($this->join as $join) + { + $query .= (string) $join; + } + } + + if ($this->where) + { + $query .= (string) $this->where; + } + + if ($this->group) + { + $query .= (string) $this->group; + } + + if ($this->order) + { + $query .= (string) $this->order; + } + + if ($this->having) + { + $query .= (string) $this->having; + } + + if ($this instanceof FOFDatabaseQueryLimitable && ($this->limit > 0 || $this->offset > 0)) + { + $query = $this->processLimit($query, $this->limit, $this->offset); + } + + break; + + case 'insert': + $query .= (string) $this->insert; + + // Set method + if ($this->set) + { + $query .= (string) $this->set; + } + // Columns-Values method + elseif ($this->values) + { + if ($this->columns) + { + $query .= (string) $this->columns; + } + + $elements = $this->insert->getElements(); + $tableName = array_shift($elements); + + $query .= 'VALUES '; + $query .= (string) $this->values; + + if ($this->autoIncrementField) + { + $query = 'SET IDENTITY_INSERT ' . $tableName . ' ON;' . $query . 'SET IDENTITY_INSERT ' . $tableName . ' OFF;'; + } + + if ($this->where) + { + $query .= (string) $this->where; + } + } + + break; + + case 'delete': + $query .= (string) $this->delete; + $query .= (string) $this->from; + + if ($this->join) + { + // Special case for joins + foreach ($this->join as $join) + { + $query .= (string) $join; + } + } + + if ($this->where) + { + $query .= (string) $this->where; + } + + if ($this->order) + { + $query .= (string) $this->order; + } + + break; + + case 'update': + $query .= (string) $this->update; + + if ($this->join) + { + // Special case for joins + foreach ($this->join as $join) + { + $query .= (string) $join; + } + } + + $query .= (string) $this->set; + + if ($this->where) + { + $query .= (string) $this->where; + } + + if ($this->order) + { + $query .= (string) $this->order; + } + + break; + + default: + $query = parent::__toString(); + break; + } + + return $query; + } + + /** + * Casts a value to a char. + * + * Ensure that the value is properly quoted before passing to the method. + * + * @param string $value The value to cast as a char. + * + * @return string Returns the cast value. + * + * @since 11.1 + */ + public function castAsChar($value) + { + return 'CAST(' . $value . ' as NVARCHAR(10))'; + } + + /** + * Gets the function to determine the length of a character string. + * + * @param string $field A value. + * @param string $operator Comparison operator between charLength integer value and $condition + * @param string $condition Integer value to compare charLength with. + * + * @return string The required char length call. + * + * @since 11.1 + */ + public function charLength($field, $operator = null, $condition = null) + { + return 'DATALENGTH(' . $field . ')' . (isset($operator) && isset($condition) ? ' ' . $operator . ' ' . $condition : ''); + } + + /** + * Concatenates an array of column names or values. + * + * @param array $values An array of values to concatenate. + * @param string $separator As separator to place between each value. + * + * @return string The concatenated values. + * + * @since 11.1 + */ + public function concatenate($values, $separator = null) + { + if ($separator) + { + return '(' . implode('+' . $this->quote($separator) . '+', $values) . ')'; + } + else + { + return '(' . implode('+', $values) . ')'; + } + } + + /** + * Gets the current date and time. + * + * @return string + * + * @since 11.1 + */ + public function currentTimestamp() + { + return 'GETDATE()'; + } + + /** + * Get the length of a string in bytes. + * + * @param string $value The string to measure. + * + * @return integer + * + * @since 11.1 + */ + public function length($value) + { + return 'LEN(' . $value . ')'; + } + + /** + * Add to the current date and time. + * Usage: + * $query->select($query->dateAdd()); + * Prefixing the interval with a - (negative sign) will cause subtraction to be used. + * + * @param datetime $date The date to add to; type may be time or datetime. + * @param string $interval The string representation of the appropriate number of units + * @param string $datePart The part of the date to perform the addition on + * + * @return string The string with the appropriate sql for addition of dates + * + * @since 13.1 + * @note Not all drivers support all units. + * @link http://msdn.microsoft.com/en-us/library/ms186819.aspx for more information + */ + public function dateAdd($date, $interval, $datePart) + { + return "DATEADD('" . $datePart . "', '" . $interval . "', '" . $date . "'" . ')'; + } + + /** + * Method to modify a query already in string format with the needed + * additions to make the query limited to a particular number of + * results, or start at a particular offset. + * + * @param string $query The query in string format + * @param integer $limit The limit for the result set + * @param integer $offset The offset for the result set + * + * @return string + * + * @since 12.1 + */ + public function processLimit($query, $limit, $offset = 0) + { + if ($limit == 0 && $offset == 0) + { + return $query; + } + + $start = $offset + 1; + $end = $offset + $limit; + + $orderBy = stristr($query, 'ORDER BY'); + + if (is_null($orderBy) || empty($orderBy)) + { + $orderBy = 'ORDER BY (select 0)'; + } + + $query = str_ireplace($orderBy, '', $query); + + $rowNumberText = ', ROW_NUMBER() OVER (' . $orderBy . ') AS RowNumber FROM '; + + $query = preg_replace('/\sFROM\s/i', $rowNumberText, $query, 1); + $query = 'SELECT * FROM (' . $query . ') A WHERE A.RowNumber BETWEEN ' . $start . ' AND ' . $end; + + return $query; + } + + /** + * Sets the offset and limit for the result set, if the database driver supports it. + * + * Usage: + * $query->setLimit(100, 0); (retrieve 100 rows, starting at first record) + * $query->setLimit(50, 50); (retrieve 50 rows, starting at 50th record) + * + * @param integer $limit The limit for the result set + * @param integer $offset The offset for the result set + * + * @return FOFDatabaseQuery Returns this object to allow chaining. + * + * @since 12.1 + */ + public function setLimit($limit = 0, $offset = 0) + { + $this->limit = (int) $limit; + $this->offset = (int) $offset; + + return $this; + } + + /** + * Return correct rand() function for MSSQL. + * + * Ensure that the rand() function is MSSQL compatible. + * + * Usage: + * $query->Rand(); + * + * @return string The correct rand function. + * + * @since 3.5 + */ + public function Rand() + { + return ' NEWID() '; + } +} diff --git a/Sites/pages/libraries/fof/dispatcher/dispatcher.php b/Sites/pages/libraries/fof/dispatcher/dispatcher.php new file mode 100644 index 00000000..de9a9f46 --- /dev/null +++ b/Sites/pages/libraries/fof/dispatcher/dispatcher.php @@ -0,0 +1,720 @@ +getCmd('option', 'com_foobar'); + $config['view'] = !is_null($view) ? $view : $input->getCmd('view', ''); + + $input->set('option', $config['option']); + $input->set('view', $config['view']); + + $config['input'] = $input; + + $className = ucfirst(str_replace('com_', '', $config['option'])) . 'Dispatcher'; + + if (!class_exists($className)) + { + $componentPaths = FOFPlatform::getInstance()->getComponentBaseDirs($config['option']); + + $searchPaths = array( + $componentPaths['main'], + $componentPaths['main'] . '/dispatchers', + $componentPaths['admin'], + $componentPaths['admin'] . '/dispatchers' + ); + + if (array_key_exists('searchpath', $config)) + { + array_unshift($searchPaths, $config['searchpath']); + } + + $filesystem = FOFPlatform::getInstance()->getIntegrationObject('filesystem'); + + $path = $filesystem->pathFind( + $searchPaths, 'dispatcher.php' + ); + + if ($path) + { + require_once $path; + } + } + + if (!class_exists($className)) + { + $className = 'FOFDispatcher'; + } + + $instance = new $className($config); + + return $instance; + } + + /** + * Public constructor + * + * @param array $config The configuration variables + */ + public function __construct($config = array()) + { + // Cache the config + $this->config = $config; + + // Get the input for this MVC triad + if (array_key_exists('input', $config)) + { + $this->input = $config['input']; + } + else + { + $this->input = new FOFInput; + } + + // Get the default values for the component name + $this->component = $this->input->getCmd('option', 'com_foobar'); + + // Load the component's fof.xml configuration file + $configProvider = new FOFConfigProvider; + $this->defaultView = $configProvider->get($this->component . '.dispatcher.default_view', $this->defaultView); + + // Get the default values for the view name + $this->view = $this->input->getCmd('view', null); + + if (empty($this->view)) + { + // Do we have a task formatted as controller.task? + $task = $this->input->getCmd('task', ''); + + if (!empty($task) && (strstr($task, '.') !== false)) + { + list($this->view, $task) = explode('.', $task, 2); + $this->input->set('task', $task); + } + } + + if (empty($this->view)) + { + $this->view = $this->defaultView; + } + + $this->layout = $this->input->getCmd('layout', null); + + // Overrides from the config + if (array_key_exists('option', $config)) + { + $this->component = $config['option']; + } + + if (array_key_exists('view', $config)) + { + $this->view = empty($config['view']) ? $this->view : $config['view']; + } + + if (array_key_exists('layout', $config)) + { + $this->layout = $config['layout']; + } + + $this->input->set('option', $this->component); + $this->input->set('view', $this->view); + $this->input->set('layout', $this->layout); + + if (array_key_exists('authTimeStep', $config)) + { + $this->fofAuth_timeStep = empty($config['authTimeStep']) ? 6 : $config['authTimeStep']; + } + } + + /** + * The main code of the Dispatcher. It spawns the necessary controller and + * runs it. + * + * @throws Exception + * + * @return void|Exception + */ + public function dispatch() + { + $platform = FOFPlatform::getInstance(); + + if (!$platform->authorizeAdmin($this->input->getCmd('option', 'com_foobar'))) + { + return $platform->raiseError(403, JText::_('JLIB_APPLICATION_ERROR_ACCESS_FORBIDDEN')); + } + + $this->transparentAuthentication(); + + // Merge English and local translations + $platform->loadTranslations($this->component); + + $canDispatch = true; + + if ($platform->isCli()) + { + $canDispatch = $canDispatch && $this->onBeforeDispatchCLI(); + } + + $canDispatch = $canDispatch && $this->onBeforeDispatch(); + + if (!$canDispatch) + { + // We can set header only if we're not in CLI + if(!$platform->isCli()) + { + $platform->setHeader('Status', '403 Forbidden', true); + } + + return $platform->raiseError(403, JText::_('JLIB_APPLICATION_ERROR_ACCESS_FORBIDDEN')); + } + + // Get and execute the controller + $option = $this->input->getCmd('option', 'com_foobar'); + $view = $this->input->getCmd('view', $this->defaultView); + $task = $this->input->getCmd('task', null); + + if (empty($task)) + { + $task = $this->getTask($view); + } + + // Pluralise/sungularise the view name for typical tasks + if (in_array($task, array('edit', 'add', 'read'))) + { + $view = FOFInflector::singularize($view); + } + elseif (in_array($task, array('browse'))) + { + $view = FOFInflector::pluralize($view); + } + + $this->input->set('view', $view); + $this->input->set('task', $task); + + $config = $this->config; + $config['input'] = $this->input; + + $controller = FOFController::getTmpInstance($option, $view, $config); + $status = $controller->execute($task); + + if (!$this->onAfterDispatch()) + { + // We can set header only if we're not in CLI + if(!$platform->isCli()) + { + $platform->setHeader('Status', '403 Forbidden', true); + } + + return $platform->raiseError(403, JText::_('JLIB_APPLICATION_ERROR_ACCESS_FORBIDDEN')); + } + + $format = $this->input->get('format', 'html', 'cmd'); + $format = empty($format) ? 'html' : $format; + + if ($controller->hasRedirect()) + { + $controller->redirect(); + } + } + + /** + * Tries to guess the controller task to execute based on the view name and + * the HTTP request method. + * + * @param string $view The name of the view + * + * @return string The best guess of the task to execute + */ + protected function getTask($view) + { + // Get a default task based on plural/singular view + $request_task = $this->input->getCmd('task', null); + $task = FOFInflector::isPlural($view) ? 'browse' : 'edit'; + + // Get a potential ID, we might need it later + $id = $this->input->get('id', null, 'int'); + + if ($id == 0) + { + $ids = $this->input->get('ids', array(), 'array'); + + if (!empty($ids)) + { + $id = array_shift($ids); + } + } + + // Check the request method + + if (!isset($_SERVER['REQUEST_METHOD'])) + { + $_SERVER['REQUEST_METHOD'] = 'GET'; + } + + $requestMethod = strtoupper($_SERVER['REQUEST_METHOD']); + + switch ($requestMethod) + { + case 'POST': + case 'PUT': + if (!is_null($id)) + { + $task = 'save'; + } + break; + + case 'DELETE': + if ($id != 0) + { + $task = 'delete'; + } + break; + + case 'GET': + default: + // If it's an edit without an ID or ID=0, it's really an add + if (($task == 'edit') && ($id == 0)) + { + $task = 'add'; + } + + // If it's an edit in the frontend, it's really a read + elseif (($task == 'edit') && FOFPlatform::getInstance()->isFrontend()) + { + $task = 'read'; + } + break; + } + + return $task; + } + + /** + * Executes right before the dispatcher tries to instantiate and run the + * controller. + * + * @return boolean Return false to abort + */ + public function onBeforeDispatch() + { + return true; + } + + /** + * Sets up some environment variables, so we can work as usually on CLI, too. + * + * @return boolean Return false to abort + */ + public function onBeforeDispatchCLI() + { + JLoader::import('joomla.environment.uri'); + JLoader::import('joomla.application.component.helper'); + + // Trick to create a valid url used by JURI + $this->_originalPhpScript = ''; + + // We have no Application Helper (there is no Application!), so I have to define these constants manually + $option = $this->input->get('option', '', 'cmd'); + + if ($option) + { + $componentPaths = FOFPlatform::getInstance()->getComponentBaseDirs($option); + + if (!defined('JPATH_COMPONENT')) + { + define('JPATH_COMPONENT', $componentPaths['main']); + } + + if (!defined('JPATH_COMPONENT_SITE')) + { + define('JPATH_COMPONENT_SITE', $componentPaths['site']); + } + + if (!defined('JPATH_COMPONENT_ADMINISTRATOR')) + { + define('JPATH_COMPONENT_ADMINISTRATOR', $componentPaths['admin']); + } + } + + return true; + } + + /** + * Executes right after the dispatcher runs the controller. + * + * @return boolean Return false to abort + */ + public function onAfterDispatch() + { + // If we have to log out the user, please do so now + if ($this->fofAuth_LogoutOnReturn && $this->_fofAuth_isLoggedIn) + { + FOFPlatform::getInstance()->logoutUser(); + } + + return true; + } + + /** + * Transparently authenticates a user + * + * @return void + */ + public function transparentAuthentication() + { + // Only run when there is no logged in user + if (!FOFPlatform::getInstance()->getUser()->guest) + { + return; + } + + // @todo Check the format + $format = $this->input->getCmd('format', 'html'); + + if (!in_array($format, $this->fofAuth_Formats)) + { + return; + } + + foreach ($this->fofAuth_AuthMethods as $method) + { + // If we're already logged in, don't bother + if ($this->_fofAuth_isLoggedIn) + { + continue; + } + + // This will hold our authentication data array (username, password) + $authInfo = null; + + switch ($method) + { + case 'HTTPBasicAuth_TOTP': + + if (empty($this->fofAuth_Key)) + { + continue 2; + } + + if (!isset($_SERVER['PHP_AUTH_USER'])) + { + continue 2; + } + + if (!isset($_SERVER['PHP_AUTH_PW'])) + { + continue 2; + } + + if ($_SERVER['PHP_AUTH_USER'] != '_fof_auth') + { + continue 2; + } + + $encryptedData = $_SERVER['PHP_AUTH_PW']; + + $authInfo = $this->_decryptWithTOTP($encryptedData); + break; + + case 'QueryString_TOTP': + $encryptedData = $this->input->get('_fofauthentication', '', 'raw'); + + if (empty($encryptedData)) + { + continue 2; + } + + $authInfo = $this->_decryptWithTOTP($encryptedData); + break; + + case 'HTTPBasicAuth_Plaintext': + if (!isset($_SERVER['PHP_AUTH_USER'])) + { + continue 2; + } + + if (!isset($_SERVER['PHP_AUTH_PW'])) + { + continue 2; + } + + $authInfo = array( + 'username' => $_SERVER['PHP_AUTH_USER'], + 'password' => $_SERVER['PHP_AUTH_PW'] + ); + break; + + case 'QueryString_Plaintext': + $jsonencoded = $this->input->get('_fofauthentication', '', 'raw'); + + if (empty($jsonencoded)) + { + continue 2; + } + + $authInfo = json_decode($jsonencoded, true); + + if (!is_array($authInfo)) + { + $authInfo = null; + } + elseif (!array_key_exists('username', $authInfo) || !array_key_exists('password', $authInfo)) + { + $authInfo = null; + } + break; + + case 'SplitQueryString_Plaintext': + $authInfo = array( + 'username' => $this->input->get('_fofauthentication_username', '', 'raw'), + 'password' => $this->input->get('_fofauthentication_password', '', 'raw'), + ); + + if (empty($authInfo['username'])) + { + $authInfo = null; + } + + break; + + default: + continue 2; + + break; + } + + // No point trying unless we have a username and password + if (!is_array($authInfo)) + { + continue; + } + + $this->_fofAuth_isLoggedIn = FOFPlatform::getInstance()->loginUser($authInfo); + } + } + + /** + * Decrypts a transparent authentication message using a TOTP + * + * @param string $encryptedData The encrypted data + * + * @codeCoverageIgnore + * @return array The decrypted data + */ + private function _decryptWithTOTP($encryptedData) + { + if (empty($this->fofAuth_Key)) + { + $this->_fofAuth_CryptoKey = null; + + return null; + } + + $totp = new FOFEncryptTotp($this->fofAuth_timeStep); + $period = $totp->getPeriod(); + $period--; + + for ($i = 0; $i <= 2; $i++) + { + $time = ($period + $i) * $this->fofAuth_timeStep; + $otp = $totp->getCode($this->fofAuth_Key, $time); + $this->_fofAuth_CryptoKey = hash('sha256', $this->fofAuth_Key . $otp); + + $aes = new FOFEncryptAes($this->_fofAuth_CryptoKey); + $ret = $aes->decryptString($encryptedData); + $ret = rtrim($ret, "\000"); + + $ret = json_decode($ret, true); + + if (!is_array($ret)) + { + continue; + } + + if (!array_key_exists('username', $ret)) + { + continue; + } + + if (!array_key_exists('password', $ret)) + { + continue; + } + + // Successful decryption! + return $ret; + } + + // Obviously if we're here we could not decrypt anything. Bail out. + $this->_fofAuth_CryptoKey = null; + + return null; + } + + /** + * Creates a decryption key for use with the TOTP decryption method + * + * @param integer $time The timestamp used for TOTP calculation, leave empty to use current timestamp + * + * @codeCoverageIgnore + * @return string THe encryption key + */ + private function _createDecryptionKey($time = null) + { + $totp = new FOFEncryptTotp($this->fofAuth_timeStep); + $otp = $totp->getCode($this->fofAuth_Key, $time); + + $key = hash('sha256', $this->fofAuth_Key . $otp); + + return $key; + } + + /** + * Main function to detect if we're running in a CLI environment and we're admin + * + * @return array isCLI and isAdmin. It's not an associative array, so we can use list. + */ + public static function isCliAdmin() + { + static $isCLI = null; + static $isAdmin = null; + + if (is_null($isCLI) && is_null($isAdmin)) + { + $isCLI = FOFPlatform::getInstance()->isCli(); + $isAdmin = FOFPlatform::getInstance()->isBackend(); + } + + return array($isCLI, $isAdmin); + } +} diff --git a/Sites/pages/libraries/fof/download/adapter/abstract.php b/Sites/pages/libraries/fof/download/adapter/abstract.php new file mode 100644 index 00000000..19f46f2f --- /dev/null +++ b/Sites/pages/libraries/fof/download/adapter/abstract.php @@ -0,0 +1,113 @@ +supportsChunkDownload; + } + + /** + * Does this download adapter support reading the size of a remote file? + * + * @return boolean True if remote file size determination is supported + */ + public function supportsFileSize() + { + return $this->supportsFileSize; + } + + /** + * Is this download class supported in the current server environment? + * + * @return boolean True if this server environment supports this download class + */ + public function isSupported() + { + return $this->isSupported; + } + + /** + * Get the priority of this adapter. If multiple download adapters are + * supported on a site, the one with the highest priority will be + * used. + * + * @return boolean + */ + public function getPriority() + { + return $this->priority; + } + + /** + * Returns the name of this download adapter in use + * + * @return string + */ + public function getName() + { + return $this->name; + } + + /** + * Download a part (or the whole) of a remote URL and return the downloaded + * data. You are supposed to check the size of the returned data. If it's + * smaller than what you expected you've reached end of file. If it's empty + * you have tried reading past EOF. If it's larger than what you expected + * the server doesn't support chunk downloads. + * + * If this class' supportsChunkDownload returns false you should assume + * that the $from and $to parameters will be ignored. + * + * @param string $url The remote file's URL + * @param integer $from Byte range to start downloading from. Use null for start of file. + * @param integer $to Byte range to stop downloading. Use null to download the entire file ($from is ignored) + * @param array $params Additional params that will be added before performing the download + * + * @return string The raw file data retrieved from the remote URL. + * + * @throws Exception A generic exception is thrown on error + */ + public function downloadAndReturn($url, $from = null, $to = null, array $params = array()) + { + return ''; + } + + /** + * Get the size of a remote file in bytes + * + * @param string $url The remote file's URL + * + * @return integer The file size, or -1 if the remote server doesn't support this feature + */ + public function getFileSize($url) + { + return -1; + } +} \ No newline at end of file diff --git a/Sites/pages/libraries/fof/download/adapter/cacert.pem b/Sites/pages/libraries/fof/download/adapter/cacert.pem new file mode 100644 index 00000000..f9126f8f --- /dev/null +++ b/Sites/pages/libraries/fof/download/adapter/cacert.pem @@ -0,0 +1,5104 @@ +## +## Bundle of CA Root Certificates +## +## Certificate data from CentOS as of Oct 3 2015 +## +## This is a bundle of X.509 certificates of public Certificate Authorities +## (CA). These were automatically extracted from CentOS /etc/pki/tls/certs/ca-bundle.crt +## +## It contains the certificates in PEM format and therefore +## can be directly used with curl / libcurl / php_curl, or with +## an Apache+mod_ssl webserver for SSL client authentication. +## Just configure this file as the SSLCACertificateFile. +## + +-----BEGIN CERTIFICATE----- +MIICWjCCAcMCAgGlMA0GCSqGSIb3DQEBBAUAMHUxCzAJBgNVBAYTAlVTMRgwFgYD +VQQKEw9HVEUgQ29ycG9yYXRpb24xJzAlBgNVBAsTHkdURSBDeWJlclRydXN0IFNv +bHV0aW9ucywgSW5jLjEjMCEGA1UEAxMaR1RFIEN5YmVyVHJ1c3QgR2xvYmFsIFJv +b3QwHhcNOTgwODEzMDAyOTAwWhcNMTgwODEzMjM1OTAwWjB1MQswCQYDVQQGEwJV +UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMScwJQYDVQQLEx5HVEUgQ3liZXJU +cnVzdCBTb2x1dGlvbnMsIEluYy4xIzAhBgNVBAMTGkdURSBDeWJlclRydXN0IEds +b2JhbCBSb290MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCVD6C28FCc6HrH +iM3dFw4usJTQGz0O9pTAipTHBsiQl8i4ZBp6fmw8U+E3KHNgf7KXUwefU/ltWJTS +r41tiGeA5u2ylc9yMcqlHHK6XALnZELn+aks1joNrI1CqiQBOeacPwGFVw1Yh0X4 +04Wqk2kmhXBIgD8SFcd5tB8FLztimQIDAQABMA0GCSqGSIb3DQEBBAUAA4GBAG3r +GwnpXtlR22ciYaQqPEh346B8pt5zohQDhT37qw4wxYMWM4ETCJ57NE7fQMh017l9 +3PR2VX2bY1QY6fDq81yx2YtCHrnAlU66+tXifPVoYb+O7AWXX1uw16OFNMQkpw0P +lZPvy5TYnh+dXIVtx6quTx8itc2VrbqnzPmrC3p/ +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIDEzCCAnygAwIBAgIBATANBgkqhkiG9w0BAQQFADCBxDELMAkGA1UEBhMCWkEx +FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYD +VQQKExRUaGF3dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlv +biBTZXJ2aWNlcyBEaXZpc2lvbjEZMBcGA1UEAxMQVGhhd3RlIFNlcnZlciBDQTEm +MCQGCSqGSIb3DQEJARYXc2VydmVyLWNlcnRzQHRoYXd0ZS5jb20wHhcNOTYwODAx +MDAwMDAwWhcNMjAxMjMxMjM1OTU5WjCBxDELMAkGA1UEBhMCWkExFTATBgNVBAgT +DFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYDVQQKExRUaGF3 +dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNl +cyBEaXZpc2lvbjEZMBcGA1UEAxMQVGhhd3RlIFNlcnZlciBDQTEmMCQGCSqGSIb3 +DQEJARYXc2VydmVyLWNlcnRzQHRoYXd0ZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQAD +gY0AMIGJAoGBANOkUG7I/1Zr5s9dtuoMaHVHoqrC2oQl/Kj0R1HahbUgdJSGHg91 +yekIYfUGbTBuFRkC6VLAYttNmZ7iagxEOM3+vuNkCXDF/rFrKbYvScg71CcEJRCX +L+eQbcAoQpnXTEPew/UhbVSfXcNY4cDk2VuwuNy0e982OsK1ZiIS1ocNAgMBAAGj +EzARMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAB/pMaVz7lcxG +7oWDTSEwjsrZqG9JGubaUeNgcGyEYRGhGshIPllDfU+VPaGLtwtimHp1it2ITk6e +QNuozDJ0uW8NxuOzRAvZim+aKZuZGCg70eNAKJpaPNW15yAbi8qkq43pUdniTCxZ +qdq5snUb9kLy78fyGPmJvKP/iiMucEc= +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIDJzCCApCgAwIBAgIBATANBgkqhkiG9w0BAQQFADCBzjELMAkGA1UEBhMCWkEx +FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYD +VQQKExRUaGF3dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlv +biBTZXJ2aWNlcyBEaXZpc2lvbjEhMB8GA1UEAxMYVGhhd3RlIFByZW1pdW0gU2Vy +dmVyIENBMSgwJgYJKoZIhvcNAQkBFhlwcmVtaXVtLXNlcnZlckB0aGF3dGUuY29t +MB4XDTk2MDgwMTAwMDAwMFoXDTIwMTIzMTIzNTk1OVowgc4xCzAJBgNVBAYTAlpB +MRUwEwYDVQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEdMBsG +A1UEChMUVGhhd3RlIENvbnN1bHRpbmcgY2MxKDAmBgNVBAsTH0NlcnRpZmljYXRp +b24gU2VydmljZXMgRGl2aXNpb24xITAfBgNVBAMTGFRoYXd0ZSBQcmVtaXVtIFNl +cnZlciBDQTEoMCYGCSqGSIb3DQEJARYZcHJlbWl1bS1zZXJ2ZXJAdGhhd3RlLmNv +bTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA0jY2aovXwlue2oFBYo847kkE +VdbQ7xwblRZH7xhINTpS9CtqBo87L+pW46+GjZ4X9560ZXUCTe/LCaIhUdib0GfQ +ug2SBhRz1JPLlyoAnFxODLz6FVL88kRu2hFKbgifLy3j+ao6hnO2RlNYyIkFvYMR +uHM/qgeN9EJN50CdHDcCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG +9w0BAQQFAAOBgQAmSCwWwlj66BZ0DKqqX1Q/8tfJeGBeXm43YyJ3Nn6yF8Q0ufUI +hfzJATj/Tb7yFkJD57taRvvBxhEf8UqwKEbJw8RCfbz6q1lu1bdRiBHjpIUZa4JM +pAwSremkrj/xw0llmozFyD4lt5SZu5IycQfwhl7tUCemDaYj+bvLpgcUQg== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIDIDCCAomgAwIBAgIENd70zzANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJV +UzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2Vy +dGlmaWNhdGUgQXV0aG9yaXR5MB4XDTk4MDgyMjE2NDE1MVoXDTE4MDgyMjE2NDE1 +MVowTjELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VxdWlmYXgxLTArBgNVBAsTJEVx +dWlmYXggU2VjdXJlIENlcnRpZmljYXRlIEF1dGhvcml0eTCBnzANBgkqhkiG9w0B +AQEFAAOBjQAwgYkCgYEAwV2xWGcIYu6gmi0fCG2RFGiYCh7+2gRvE4RiIcPRfM6f +BeC4AfBONOziipUEZKzxa1NfBbPLZ4C/QgKO/t0BCezhABRP/PvwDN1Dulsr4R+A +cJkVV5MW8Q+XarfCaCMczE1ZMKxRHjuvK9buY0V7xdlfUNLjUA86iOe/FP3gx7kC +AwEAAaOCAQkwggEFMHAGA1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEQ +MA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2VydGlm +aWNhdGUgQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMBoGA1UdEAQTMBGBDzIwMTgw +ODIyMTY0MTUxWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUSOZo+SvSspXXR9gj +IBBPM5iQn9QwHQYDVR0OBBYEFEjmaPkr0rKV10fYIyAQTzOYkJ/UMAwGA1UdEwQF +MAMBAf8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUA +A4GBAFjOKer89961zgK5F7WF0bnj4JXMJTENAKaSbn+2kmOeUJXRmm/kEd5jhW6Y +7qj/WsjTVbJmcVfewCHrPSqnI0kBBIZCe/zuf6IWUrVnZ9NA2zsmWLIodz2uFHdh +1voqZiegDfqnc1zqcPGUIWVEX/r87yloqaKHee9570+sB3c4 +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIDKTCCApKgAwIBAgIENnAVljANBgkqhkiG9w0BAQUFADBGMQswCQYDVQQGEwJV +UzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMREwDwYDVQQL +EwhEU1RDQSBFMTAeFw05ODEyMTAxODEwMjNaFw0xODEyMTAxODQwMjNaMEYxCzAJ +BgNVBAYTAlVTMSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4x +ETAPBgNVBAsTCERTVENBIEUxMIGdMA0GCSqGSIb3DQEBAQUAA4GLADCBhwKBgQCg +bIGpzzQeJN3+hijM3oMv+V7UQtLodGBmE5gGHKlREmlvMVW5SXIACH7TpWJENySZ +j9mDSI+ZbZUTu0M7LklOiDfBu1h//uG9+LthzfNHwJmm8fOR6Hh8AMthyUQncWlV +Sn5JTe2io74CTADKAqjuAQIxZA9SLRN0dja1erQtcQIBA6OCASQwggEgMBEGCWCG +SAGG+EIBAQQEAwIABzBoBgNVHR8EYTBfMF2gW6BZpFcwVTELMAkGA1UEBhMCVVMx +JDAiBgNVBAoTG0RpZ2l0YWwgU2lnbmF0dXJlIFRydXN0IENvLjERMA8GA1UECxMI +RFNUQ0EgRTExDTALBgNVBAMTBENSTDEwKwYDVR0QBCQwIoAPMTk5ODEyMTAxODEw +MjNagQ8yMDE4MTIxMDE4MTAyM1owCwYDVR0PBAQDAgEGMB8GA1UdIwQYMBaAFGp5 +fpFpRhgTCgJ3pVlbYJglDqL4MB0GA1UdDgQWBBRqeX6RaUYYEwoCd6VZW2CYJQ6i ++DAMBgNVHRMEBTADAQH/MBkGCSqGSIb2fQdBAAQMMAobBFY0LjADAgSQMA0GCSqG +SIb3DQEBBQUAA4GBACIS2Hod3IEGtgllsofIH160L+nEHvI8wbsEkBFKg05+k7lN +QseSJqBcNJo4cvj9axY+IO6CizEqkzaFI4iKPANo08kJD038bKTaKHKTDomAsH3+ +gG9lbRgzl4vCa4nuYD3Im+9/KzJic5PLPON74nZ4RbyhkwS7hp86W0N6w4pl +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIDKTCCApKgAwIBAgIENm7TzjANBgkqhkiG9w0BAQUFADBGMQswCQYDVQQGEwJV +UzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMREwDwYDVQQL +EwhEU1RDQSBFMjAeFw05ODEyMDkxOTE3MjZaFw0xODEyMDkxOTQ3MjZaMEYxCzAJ +BgNVBAYTAlVTMSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4x +ETAPBgNVBAsTCERTVENBIEUyMIGdMA0GCSqGSIb3DQEBAQUAA4GLADCBhwKBgQC/ +k48Xku8zExjrEH9OFr//Bo8qhbxe+SSmJIi2A7fBw18DW9Fvrn5C6mYjuGODVvso +LeE4i7TuqAHhzhy2iCoiRoX7n6dwqUcUP87eZfCocfdPJmyMvMa1795JJ/9IKn3o +TQPMx7JSxhcxEzu1TdvIxPbDDyQq2gyd55FbgM2UnQIBA6OCASQwggEgMBEGCWCG +SAGG+EIBAQQEAwIABzBoBgNVHR8EYTBfMF2gW6BZpFcwVTELMAkGA1UEBhMCVVMx +JDAiBgNVBAoTG0RpZ2l0YWwgU2lnbmF0dXJlIFRydXN0IENvLjERMA8GA1UECxMI +RFNUQ0EgRTIxDTALBgNVBAMTBENSTDEwKwYDVR0QBCQwIoAPMTk5ODEyMDkxOTE3 +MjZagQ8yMDE4MTIwOTE5MTcyNlowCwYDVR0PBAQDAgEGMB8GA1UdIwQYMBaAFB6C +TShlgDzJQW6sNS5ay97u+DlbMB0GA1UdDgQWBBQegk0oZYA8yUFurDUuWsve7vg5 +WzAMBgNVHRMEBTADAQH/MBkGCSqGSIb2fQdBAAQMMAobBFY0LjADAgSQMA0GCSqG +SIb3DQEBBQUAA4GBAEeNg61i8tuwnkUiBbmi1gMOOHLnnvx75pO2mqWilMg0HZHR +xdf0CiUPPXiBng+xZ8SQTGPdXqfiup/1902lMXucKS1M/mQ+7LZT/uqb7YLbdHVL +B3luHtgZg3Pe9T7Qtd7nS2h9Qy4qIOF+oHhEngj1mPnHfxsb1gYgAlihw6ID +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIICPDCCAaUCEHC65B0Q2Sk0tjjKewPMur8wDQYJKoZIhvcNAQECBQAwXzELMAkG +A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFz +cyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2 +MDEyOTAwMDAwMFoXDTI4MDgwMTIzNTk1OVowXzELMAkGA1UEBhMCVVMxFzAVBgNV +BAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmlt +YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUAA4GN +ADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhE +BarsAx94f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/is +I19wKTakyYbnsZogy1Olhec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0G +CSqGSIb3DQEBAgUAA4GBALtMEivPLCYATxQT3ab7/AoRhIzzKBxnki98tsX63/Do +lbwdj2wsqFHMc9ikwFPwTtYmwHYBV4GSXiHx0bH/59AhWM1pF+NEHJwZRDmJXNyc +AA9WjQKZ7aKQRUzkuxCkPfAyAw7xzvjoyVGM5mKf5p/AfbdynMk2OmufTqj/ZA1k +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIDAjCCAmsCEEzH6qqYPnHTkxD4PTqJkZIwDQYJKoZIhvcNAQEFBQAwgcExCzAJ +BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xh +c3MgMSBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcy +MTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3Jp +emVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMB4X +DTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVowgcExCzAJBgNVBAYTAlVTMRcw +FQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMSBQdWJsaWMg +UHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEo +YykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5 +MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEB +AQUAA4GNADCBiQKBgQCq0Lq+Fi24g9TK0g+8djHKlNgdk4xWArzZbxpvUjZudVYK +VdPfQ4chEWWKfo+9Id5rMj8bhDSVBZ1BNeuS65bdqlk/AVNtmU/t5eIqWpDBucSm +Fc/IReumXY6cPvBkJHalzasab7bYe1FhbqZ/h8jit+U03EGI6glAvnOSPWvndQID +AQABMA0GCSqGSIb3DQEBBQUAA4GBAKlPww3HZ74sy9mozS11534Vnjty637rXC0J +h9ZrbWB85a7FkCMMXErQr7Fd88e2CtvgFZMN3QO8x3aKtd1Pw5sTdbgBwObJW2ul +uIncrKTdcu1OofdPvAbT6shkdHvClUGcZXNY8ZCaPGqxmMnEh7zPRW1F4m4iP/68 +DzFc6PLZ +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIDAzCCAmwCEQC5L2DMiJ+hekYJuFtwbIqvMA0GCSqGSIb3DQEBBQUAMIHBMQsw +CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xPDA6BgNVBAsTM0Ns +YXNzIDIgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBH +MjE6MDgGA1UECxMxKGMpIDE5OTggVmVyaVNpZ24sIEluYy4gLSBGb3IgYXV0aG9y +aXplZCB1c2Ugb25seTEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1c3QgTmV0d29yazAe +Fw05ODA1MTgwMDAwMDBaFw0yODA4MDEyMzU5NTlaMIHBMQswCQYDVQQGEwJVUzEX +MBUGA1UEChMOVmVyaVNpZ24sIEluYy4xPDA6BgNVBAsTM0NsYXNzIDIgUHVibGlj +IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMjE6MDgGA1UECxMx +KGMpIDE5OTggVmVyaVNpZ24sIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25s +eTEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1c3QgTmV0d29yazCBnzANBgkqhkiG9w0B +AQEFAAOBjQAwgYkCgYEAp4gBIXQs5xoD8JjhlzwPIQjxnNuX6Zr8wgQGE75fUsjM +HiwSViy4AWkszJkfrbCWrnkE8hM5wXuYuggs6MKEEyyqaekJ9MepAqRCwiNPStjw +DqL7MWzJ5m+ZJwf15vRMeJ5t60aG+rmGyVTyssSv1EYcWskVMP8NbPUtDm3Of3cC +AwEAATANBgkqhkiG9w0BAQUFAAOBgQByLvl/0fFx+8Se9sVeUYpAmLho+Jscg9ji +nb3/7aHmZuovCfTK1+qlK5X2JGCGTUQug6XELaDTrnhpb3LabK4I8GOSN+a7xDAX +rXfMSTWqz9iP0b63GJZHc2pUIjRkLbYWm1lbtFFZOrMLFPQS32eg9K0yZF6xRnIn +jBJ7xUS0rg== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIDAjCCAmsCEH3Z/gfPqB63EHln+6eJNMYwDQYJKoZIhvcNAQEFBQAwgcExCzAJ +BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xh +c3MgMyBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcy +MTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3Jp +emVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMB4X +DTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVowgcExCzAJBgNVBAYTAlVTMRcw +FQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMyBQdWJsaWMg +UHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEo +YykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5 +MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEB +AQUAA4GNADCBiQKBgQDMXtERXVxp0KvTuWpMmR9ZmDCOFoUgRm1HP9SFIIThbbP4 +pO0M8RcPO/mn+SXXwc+EY/J8Y8+iR/LGWzOOZEAEaMGAuWQcRXfH2G71lSk8UOg0 +13gfqLptQ5GVj0VXXn7F+8qkBOvqlzdUMG+7AUcyM83cV5tkaWH4mx0ciU9cZwID +AQABMA0GCSqGSIb3DQEBBQUAA4GBAFFNzb5cy5gZnBWyATl4Lk0PZ3BwmcYQWpSk +U01UbSuvDV1Ai2TT1+7eVmGSX6bEHRBhNtMsJzzoKQm5EWR0zLVznxxIqbxhAe7i +F6YM40AIOw7n60RzKprxaZLvcRTDOaxxp5EJb+RxBrO6WVcmeQD2+A2iMzAo1KpY +oJ2daZH9 +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG +A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv +b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw +MDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i +YWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxT +aWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaDuaZ +jc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavp +xy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp +1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdG +snUOhugZitVtbNV4FpWi6cgKOOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJ +U26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N8 +9iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E +BTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0B +AQUFAAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOz +yj1hTdNGCbM+w6DjY1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE +38NflNUVyRRBnMRddWQVDf9VMOyGj/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymP +AbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhHhm4qxFYxldBniYUr+WymXUad +DKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveCX4XSQRjbgbME +HMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0 +IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAz +BgNVBAsTLFZhbGlDZXJ0IENsYXNzIDEgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9y +aXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG +9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNTIyMjM0OFoXDTE5MDYy +NTIyMjM0OFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0d29y +azEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs +YXNzIDEgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRw +Oi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNl +cnQuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDYWYJ6ibiWuqYvaG9Y +LqdUHAZu9OqNSLwxlBfw8068srg1knaw0KWlAdcAAxIiGQj4/xEjm84H9b9pGib+ +TunRf50sQB1ZaG6m+FiwnRqP0z/x3BkGgagO4DrdyFNFCQbmD3DD+kCmDuJWBQ8Y +TfwggtFzVXSNdnKgHZ0dwN0/cQIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAFBoPUn0 +LBwGlN+VYH+Wexf+T3GtZMjdd9LvWVXoP+iOBSoh8gfStadS/pyxtuJbdxdA6nLW +I8sogTLDAHkY7FkXicnGah5xyf23dKUlRWnFSKsZ4UWKJWsZ7uW7EvV/96aNUcPw +nXS3qT6gpf+2SQMT2iLM7XGCK5nPOrf1LXLI +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0 +IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAz +BgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9y +aXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG +9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAwMTk1NFoXDTE5MDYy +NjAwMTk1NFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0d29y +azEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs +YXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRw +Oi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNl +cnQuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDOOnHK5avIWZJV16vY +dA757tn2VUdZZUcOBVXc65g2PFxTXdMwzzjsvUGJ7SVCCSRrCl6zfN1SLUzm1NZ9 +WlmpZdRJEy0kTRxQb7XBhVQ7/nHk01xC+YDgkRoKWzk2Z/M/VXwbP7RfZHM047QS +v4dk+NoS/zcnwbNDu+97bi5p9wIDAQABMA0GCSqGSIb3DQEBBQUAA4GBADt/UG9v +UJSZSWI4OB9L+KXIPqeCgfYrx+jFzug6EILLGACOTb2oWH+heQC1u+mNr0HZDzTu +IYEZoDJJKPTEjlbVUjP9UNV+mWwD5MlM/Mtsq2azSiGM5bUMMj4QssxsodyamEwC +W/POuZ6lcg5Ktz885hZo+L7tdEy8W9ViH0Pd +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0 +IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAz +BgNVBAsTLFZhbGlDZXJ0IENsYXNzIDMgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9y +aXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG +9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAwMjIzM1oXDTE5MDYy +NjAwMjIzM1owgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0d29y +azEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs +YXNzIDMgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRw +Oi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNl +cnQuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDjmFGWHOjVsQaBalfD +cnWTq8+epvzzFlLWLU2fNUSoLgRNB0mKOCn1dzfnt6td3zZxFJmP3MKS8edgkpfs +2Ejcv8ECIMYkpChMMFp2bbFc893enhBxoYjHW5tBbcqwuI4V7q0zK89HBFx1cQqY +JJgpp0lZpd34t0NiYfPT4tBVPwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAFa7AliE +Zwgs3x/be0kz9dNnnfS0ChCzycUs4pJqcXgn8nCDQtM+z6lU9PHYkhaM0QTLS6vJ +n0WuPIqpsHEzXcjFV9+vqDWzf4mH6eglkrh/hXqu1rweN1gqZ8mRzyqBPu3GOd/A +PhmcGcwTTYJBtYze4D1gCCAPRX5ron+jjBXu +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIEGjCCAwICEQCLW3VWhFSFCwDPrzhIzrGkMA0GCSqGSIb3DQEBBQUAMIHKMQsw +CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl +cmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWdu +LCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlT +aWduIENsYXNzIDEgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp +dHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQswCQYD +VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT +aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJ +bmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWdu +IENsYXNzIDEgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg +LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAN2E1Lm0+afY8wR4 +nN493GwTFtl63SRRZsDHJlkNrAYIwpTRMx/wgzUfbhvI3qpuFU5UJ+/EbRrsC+MO +8ESlV8dAWB6jRx9x7GD2bZTIGDnt/kIYVt/kTEkQeE4BdjVjEjbdZrwBBDajVWjV +ojYJrKshJlQGrT/KFOCsyq0GHZXi+J3x4GD/wn91K0zM2v6HmSHquv4+VNfSWXjb +PG7PoBMAGrgnoeS+Z5bKoMWznN3JdZ7rMJpfo83ZrngZPyPpXNspva1VyBtUjGP2 +6KbqxzcSXKMpHgLZ2x87tNcPVkeBFQRKr4Mn0cVYiMHd9qqnoxjaaKptEVHhv2Vr +n5Z20T0CAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAq2aN17O6x5q25lXQBfGfMY1a +qtmqRiYPce2lrVNWYgFHKkTp/j90CxObufRNG7LRX7K20ohcs5/Ny9Sn2WCVhDr4 +wTcdYcrnsMXlkdpUpqwxga6X3s0IrLjAl4B/bnKk52kTlWUfxJM8/XmPBNQ+T+r3 +ns7NZ3xPZQL/kYVUc8f/NveGLezQXk//EZ9yBta4GvFMDSZl4kSAHsef493oCtrs +pSCAaWihT37ha88HQfqDjrw43bAuEbFrskLMmrz5SCJ5ShkPshw+IHTZasO+8ih4 +E1Z5T21Q6huwtVexN2ZYI/PcD98Kh8TvhgXVOBRgmaNL3gaWcSzy27YfpO8/7g== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIEGTCCAwECEGFwy0mMX5hFKeewptlQW3owDQYJKoZIhvcNAQEFBQAwgcoxCzAJ +BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjEfMB0GA1UECxMWVmVy +aVNpZ24gVHJ1c3QgTmV0d29yazE6MDgGA1UECxMxKGMpIDE5OTkgVmVyaVNpZ24s +IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTFFMEMGA1UEAxM8VmVyaVNp +Z24gQ2xhc3MgMiBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0 +eSAtIEczMB4XDTk5MTAwMTAwMDAwMFoXDTM2MDcxNjIzNTk1OVowgcoxCzAJBgNV +BAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjEfMB0GA1UECxMWVmVyaVNp +Z24gVHJ1c3QgTmV0d29yazE6MDgGA1UECxMxKGMpIDE5OTkgVmVyaVNpZ24sIElu +Yy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTFFMEMGA1UEAxM8VmVyaVNpZ24g +Q2xhc3MgMiBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAt +IEczMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArwoNwtUs22e5LeWU +J92lvuCwTY+zYVY81nzD9M0+hsuiiOLh2KRpxbXiv8GmR1BeRjmL1Za6tW8UvxDO +JxOeBUebMXoT2B/Z0wI3i60sR/COgQanDTAM6/c8DyAd3HJG7qUCyFvDyVZpTMUY +wZF7C9UTAJu878NIPkZgIIUq1ZC2zYugzDLdt/1AVbJQHFauzI13TccgTacxdu9o +koqQHgiBVrKtaaNS0MscxCM9H5n+TOgWY47GCI72MfbS+uV23bUckqNJzc0BzWjN +qWm6o+sdDZykIKbBoMXRRkwXbdKsZj+WjOCE1Db/IlnF+RFgqF8EffIa9iVCYQ/E +Srg+iQIDAQABMA0GCSqGSIb3DQEBBQUAA4IBAQA0JhU8wI1NQ0kdvekhktdmnLfe +xbjQ5F1fdiLAJvmEOjr5jLX77GDx6M4EsMjdpwOPMPOY36TmpDHf0xwLRtxyID+u +7gU8pDM/CzmscHhzS5kr3zDCVLCoO1Wh/hYozUK9dG6A2ydEp85EXdQbkJgNHkKU +sQAsBNB0owIFImNjzYO1+8FtYmtpdf1dcEG59b98377BMnMiIYtYgXsVkXq642RI +sH/7NiXaldDxJBQX3RiAa0YjOVT1jmIJBB2UkKab5iXiQkWquJCtvgiPqQtCGJTP +cjnhsUPgKM+351psE2tJs//jGHyJizNdrDPXp/naOlXJWBD5qu9ats9LS98q +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIEGjCCAwICEQCbfgZJoz5iudXukEhxKe9XMA0GCSqGSIb3DQEBBQUAMIHKMQsw +CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl +cmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWdu +LCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlT +aWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp +dHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQswCQYD +VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT +aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJ +bmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWdu +IENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg +LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMu6nFL8eB8aHm8b +N3O9+MlrlBIwT/A2R/XQkQr1F8ilYcEWQE37imGQ5XYgwREGfassbqb1EUGO+i2t +KmFZpGcmTNDovFJbcCAEWNF6yaRpvIMXZK0Fi7zQWM6NjPXr8EJJC52XJ2cybuGu +kxUccLwgTS8Y3pKI6GyFVxEa6X7jJhFUokWWVYPKMIno3Nij7SqAP395ZVc+FSBm +CC+Vk7+qRy+oRpfwEuL+wgorUeZ25rdGt+INpsyow0xZVYnm6FNcHOqd8GIWC6fJ +Xwzw3sJ2zq/3avL6QaaiMxTJ5Xpj055iN9WFZZ4O5lMkdBteHRJTW8cs54NJOxWu +imi5V5cCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAERSWwauSCPc/L8my/uRan2Te +2yFPhpk0djZX3dAVL8WtfxUfN2JzPtTnX84XA9s1+ivbrmAJXx5fj267Cz3qWhMe +DGBvtcC1IyIuBwvLqXTLR7sdwdela8wv0kL9Sd2nic9TutoAWii/gt/4uhMdUIaC +/Y4wjylGsB49Ndo4YhYYSq3mtlFs3q9i6wHQHiT+eo8SGhJouPtmmRQURVyu565p +F4ErWjfJXir0xuKhXFSbplQAz/DxwceYMBo7Nhbbo27q/a2ywtrvAkcTisDxszGt +TxzhT5yvDwyd93gN2PQ1VoDat20Xj50egWTh/sVFuq1ruQp6Tk9LhO5L8X3dEQ== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIEGjCCAwICEQDsoKeLbnVqAc/EfMwvlF7XMA0GCSqGSIb3DQEBBQUAMIHKMQsw +CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl +cmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWdu +LCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlT +aWduIENsYXNzIDQgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp +dHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQswCQYD +VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT +aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJ +bmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWdu +IENsYXNzIDQgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg +LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK3LpRFpxlmr8Y+1 +GQ9Wzsy1HyDkniYlS+BzZYlZ3tCD5PUPtbut8XzoIfzk6AzufEUiGXaStBO3IFsJ ++mGuqPKljYXCKtbeZjbSmwL0qJJgfJxptI8kHtCGUvYynEFYHiK9zUVilQhu0Gbd +U6LM8BDcVHOLBKFGMzNcF0C5nk3T875Vg+ixiY5afJqWIpA7iCXy0lOIAgwLePLm +NxdLMEYH5IBtptiWLugs+BGzOA1mppvqySNb247i8xOOGlktqgLw7KSHZtzBP/XY +ufTsgsbSPZUd5cBPhMnZo0QoBmrXRazwa2rvTl/4EYIeOGM0ZlDUPpNz+jDDZq3/ +ky2X7wMCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAj/ola09b5KROJ1WrIhVZPMq1 +CtRK26vdoV9TxaBXOcLORyu+OshWv8LZJxA6sQU8wHcxuzrTBXttmhwwjIDLk5Mq +g6sFUYICABFna/OIYUdfA5PVWw3g8dShMjWFsjrbsIKr0csKvE+MW8VLADsfKoKm +fjaF3H48ZwC15DtS4KjrXRX5xm3wrR0OhbepmnMUWluPQSjA1egtTaRezarZ7c7c +2NU8Qh0XwRJdRTjDOPP8hS6DRkiy1yBfkjaP53kPmF6Z6PDQpLv1U70qzlmwr25/ +bLvSHgCwIe34QWKCudiyxLtGUPMxxY8BqHTr9Xgn2uf3ZkPznoM+IKrDNWCRzg== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIE2DCCBEGgAwIBAgIEN0rSQzANBgkqhkiG9w0BAQUFADCBwzELMAkGA1UEBhMC +VVMxFDASBgNVBAoTC0VudHJ1c3QubmV0MTswOQYDVQQLEzJ3d3cuZW50cnVzdC5u +ZXQvQ1BTIGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMc +KGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDE6MDgGA1UEAxMxRW50cnVzdC5u +ZXQgU2VjdXJlIFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw05OTA1 +MjUxNjA5NDBaFw0xOTA1MjUxNjM5NDBaMIHDMQswCQYDVQQGEwJVUzEUMBIGA1UE +ChMLRW50cnVzdC5uZXQxOzA5BgNVBAsTMnd3dy5lbnRydXN0Lm5ldC9DUFMgaW5j +b3JwLiBieSByZWYuIChsaW1pdHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBF +bnRydXN0Lm5ldCBMaW1pdGVkMTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUg +U2VydmVyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGdMA0GCSqGSIb3DQEBAQUA +A4GLADCBhwKBgQDNKIM0VBuJ8w+vN5Ex/68xYMmo6LIQaO2f55M28Qpku0f1BBc/ +I0dNxScZgSYMVHINiC3ZH5oSn7yzcdOAGT9HZnuMNSjSuQrfJNqc1lB5gXpa0zf3 +wkrYKZImZNHkmGw6AIr1NJtl+O3jEP/9uElY3KDegjlrgbEWGWG5VLbmQwIBA6OC +AdcwggHTMBEGCWCGSAGG+EIBAQQEAwIABzCCARkGA1UdHwSCARAwggEMMIHeoIHb +oIHYpIHVMIHSMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLRW50cnVzdC5uZXQxOzA5 +BgNVBAsTMnd3dy5lbnRydXN0Lm5ldC9DUFMgaW5jb3JwLiBieSByZWYuIChsaW1p +dHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBFbnRydXN0Lm5ldCBMaW1pdGVk +MTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUgU2VydmVyIENlcnRpZmljYXRp +b24gQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMCmgJ6AlhiNodHRwOi8vd3d3LmVu +dHJ1c3QubmV0L0NSTC9uZXQxLmNybDArBgNVHRAEJDAigA8xOTk5MDUyNTE2MDk0 +MFqBDzIwMTkwNTI1MTYwOTQwWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAU8Bdi +E1U9s/8KAGv7UISX8+1i0BowHQYDVR0OBBYEFPAXYhNVPbP/CgBr+1CEl/PtYtAa +MAwGA1UdEwQFMAMBAf8wGQYJKoZIhvZ9B0EABAwwChsEVjQuMAMCBJAwDQYJKoZI +hvcNAQEFBQADgYEAkNwwAvpkdMKnCqV8IY00F6j7Rw7/JXyNEwr75Ji174z4xRAN +95K+8cPV1ZVqBLssziY2ZcgxxufuP+NXdYR6Ee9GTxj005i7qIcyunL2POI9n9cd +2cNgQ4xYDiKWL2KjLB+6rQXvqzJ4h6BUcxm1XAX5Uj5tLUUL9wqT6u0G+bI= +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ +RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD +VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX +DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y +ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy +VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr +mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr +IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK +mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu +XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy +dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye +jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1 +BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3 +DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92 +9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx +jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0 +Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz +ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS +R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIICkDCCAfmgAwIBAgIBATANBgkqhkiG9w0BAQQFADBaMQswCQYDVQQGEwJVUzEc +MBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5jLjEtMCsGA1UEAxMkRXF1aWZheCBT +ZWN1cmUgR2xvYmFsIGVCdXNpbmVzcyBDQS0xMB4XDTk5MDYyMTA0MDAwMFoXDTIw +MDYyMTA0MDAwMFowWjELMAkGA1UEBhMCVVMxHDAaBgNVBAoTE0VxdWlmYXggU2Vj +dXJlIEluYy4xLTArBgNVBAMTJEVxdWlmYXggU2VjdXJlIEdsb2JhbCBlQnVzaW5l +c3MgQ0EtMTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAuucXkAJlsTRVPEnC +UdXfp9E3j9HngXNBUmCbnaEXJnitx7HoJpQytd4zjTov2/KaelpzmKNc6fuKcxtc +58O/gGzNqfTWK8D3+ZmqY6KxRwIP1ORROhI8bIpaVIRw28HFkM9yRcuoWcDNM50/ +o5brhTMhHD4ePmBudpxnhcXIw2ECAwEAAaNmMGQwEQYJYIZIAYb4QgEBBAQDAgAH +MA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUvqigdHJQa0S3ySPY+6j/s1dr +aGwwHQYDVR0OBBYEFL6ooHRyUGtEt8kj2Puo/7NXa2hsMA0GCSqGSIb3DQEBBAUA +A4GBADDiAVGqx+pf2rnQZQ8w1j7aDRRJbpGTJxQx78T3LUX47Me/okENI7SS+RkA +Z70Br83gcfxaz2TE4JaY0KNA4gGK7ycH8WUBikQtBmV1UsCGECAhX2xrD2yuCRyv +8qIYNMR1pHMc8Y3c7635s3a0kr/clRAevsvIO1qEYBlWlKlV +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIICgjCCAeugAwIBAgIBBDANBgkqhkiG9w0BAQQFADBTMQswCQYDVQQGEwJVUzEc +MBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5jLjEmMCQGA1UEAxMdRXF1aWZheCBT +ZWN1cmUgZUJ1c2luZXNzIENBLTEwHhcNOTkwNjIxMDQwMDAwWhcNMjAwNjIxMDQw +MDAwWjBTMQswCQYDVQQGEwJVUzEcMBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5j +LjEmMCQGA1UEAxMdRXF1aWZheCBTZWN1cmUgZUJ1c2luZXNzIENBLTEwgZ8wDQYJ +KoZIhvcNAQEBBQADgY0AMIGJAoGBAM4vGbwXt3fek6lfWg0XTzQaDJj0ItlZ1MRo +RvC0NcWFAyDGr0WlIVFFQesWWDYyb+JQYmT5/VGcqiTZ9J2DKocKIdMSODRsjQBu +WqDZQu4aIZX5UkxVWsUPOE9G+m34LjXWHXzr4vCwdYDIqROsvojvOm6rXyo4YgKw +Env+j6YDAgMBAAGjZjBkMBEGCWCGSAGG+EIBAQQEAwIABzAPBgNVHRMBAf8EBTAD +AQH/MB8GA1UdIwQYMBaAFEp4MlIR21kWNl7fwRQ2QGpHfEyhMB0GA1UdDgQWBBRK +eDJSEdtZFjZe38EUNkBqR3xMoTANBgkqhkiG9w0BAQQFAAOBgQB1W6ibAxHm6VZM +zfmpTMANmvPMZWnmJXbMWbfWVMMdzZmsGd20hdXgPfxiIKeES1hl8eL5lSE/9dR+ +WB5Hh1Q+WKG1tfgq73HnvMP2sUlG4tega+VWeponmHxGYhTnyfxuAxJ5gDgdSIKN +/Bf+KpYrtWKmpj29f5JZzVoqgrI3eQ== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIEGDCCAwCgAwIBAgIBATANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQGEwJTRTEU +MBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3 +b3JrMSEwHwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3QwHhcNMDAwNTMw +MTAzODMxWhcNMjAwNTMwMTAzODMxWjBlMQswCQYDVQQGEwJTRTEUMBIGA1UEChML +QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSEwHwYD +VQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQCWltQhSWDia+hBBwzexODcEyPNwTXH+9ZOEQpnXvUGW2ul +CDtbKRY654eyNAbFvAWlA3yCyykQruGIgb3WntP+LVbBFc7jJp0VLhD7Bo8wBN6n +tGO0/7Gcrjyvd7ZWxbWroulpOj0OM3kyP3CCkplhbY0wCI9xP6ZIVxn4JdxLZlyl +dI+Yrsj5wAYi56xz36Uu+1LcsRVlIPo1Zmne3yzxbrww2ywkEtvrNTVokMsAsJch +PXQhI2U0K7t4WaPW4XY5mqRJjox0r26kmqPZm9I4XJuiGMx1I4S+6+JNM3GOGvDC ++Mcdoq0Dlyz4zyXG9rgkMbFjXZJ/Y/AlyVMuH79NAgMBAAGjgdIwgc8wHQYDVR0O +BBYEFJWxtPCUtr3H2tERCSG+wa9J/RB7MAsGA1UdDwQEAwIBBjAPBgNVHRMBAf8E +BTADAQH/MIGPBgNVHSMEgYcwgYSAFJWxtPCUtr3H2tERCSG+wa9J/RB7oWmkZzBl +MQswCQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFk +ZFRydXN0IFRUUCBOZXR3b3JrMSEwHwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENB +IFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBACxtZBsfzQ3duQH6lmM0MkhHma6X +7f1yFqZzR1r0693p9db7RcwpiURdv0Y5PejuvE1Uhh4dbOMXJ0PhiVYrqW9yTkkz +43J8KiOavD7/KCrto/8cI7pDVwlnTUtiBi34/2ydYB7YHEt9tTEv2dB8Xfjea4MY +eDdXL+gzB2ffHsdrKpV2ro9Xo/D0UrSpUwjP4E/TelOL/bscVjby/rK25Xa71SJl +pz/+0WatC7xrmYbvP33zGDLKe8bjq2RGlfgmadlVg3sslgf/WSxEo8bl6ancoWOA +WiFeIc9TVPC6b4nbqKqVz4vjccweGyBECMB6tkD9xOQ14R0WHNC8K47Wcdk= +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEU +MBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFs +IFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290 +MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFowbzELMAkGA1UEBhMCU0Ux +FDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRUcnVzdCBFeHRlcm5h +bCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0EgUm9v +dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvt +H7xsD821+iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9 +uMq/NzgtHj6RQa1wVsfwTz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzX +mk6vBbOmcZSccbNQYArHE504B4YCqOmoaSYYkKtMsE8jqzpPhNjfzp/haW+710LX +a0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy2xSoRcRdKn23tNbE7qzN +E0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv77+ldU9U0 +WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYD +VR0PBAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0 +Jvf6xCZU7wO94CTLVBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRU +cnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsx +IjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENBIFJvb3SCAQEwDQYJKoZIhvcN +AQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZlj7DYd7usQWxH +YINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5 +6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvC +Nr4TDea9Y355e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEX +c4g/VhsxOBi0cQ+azcgOno4uG+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5a +mnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ= +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIEFTCCAv2gAwIBAgIBATANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQGEwJTRTEU +MBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3 +b3JrMSAwHgYDVQQDExdBZGRUcnVzdCBQdWJsaWMgQ0EgUm9vdDAeFw0wMDA1MzAx +MDQxNTBaFw0yMDA1MzAxMDQxNTBaMGQxCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtB +ZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQIE5ldHdvcmsxIDAeBgNV +BAMTFOFkZFRydXN0IFB1YmxpYyBDQSBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEA6Rowj4OIFMEg2Dybjxt+A3S72mnTRqX4jsIMEZBRpS9mVEBV +6tsfSlbunyNu9DnLoblv8n75XYcmYZ4c+OLspoH4IcUkzBEMP9smcnrHAZcHF/nX +GCwwfQ56HmIexkvA/X1id9NEHif2P0tEs7c42TkfYNVRknMDtABp4/MUTu7R3AnP +dzRGULD4EfL+OHn3Bzn+UZKXC1sIXzSGAa2Il+tmzV7R/9x98oTaunet3IAIx6eH +1lWfl2royBFkuucZKT8Rs3iQhCBSWxHveNCD9tVIkNAwHM+A+WD+eeSI8t0A65RF +62WUaUC6wNW0uLp9BBGo6zEFlpROWCGOn9Bg/QIDAQABo4HRMIHOMB0GA1UdDgQW +BBSBPjfYkrAfd59ctKtzquf2NGAv+jALBgNVHQ8EBAMCAQYwDwYDVR0TAQH/BAUw +AwEB/zCBjgYDVR0jBIGGMIGDgBSBPjfYkrAfd59ctKtzquf2NGAv+qFopGYwZDEL +MAkGA1UEBhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQLExRBZGRU +cnVzdCBUVFAgTmV0d29yazEgMB4GA1UEAxMXQWRkVHJ1c3QgUHVibGljIENBIFJv +b3SCAQEwDQYJKoZIhvcNAQEFBQADggEBAAP3FUr4JNojVhaTdt02KLmuG7jD8WS6 +IBh4lSknVwW8fCr0uVFV2ocC3g8WFzH4qnkuCRO7r7IgGRLlk/lL+YPoRNWyQSW/ +iHVv/xD8SlTQX/D67zZzfRs2RcYhbbQVuE7PnFylPVoAjgbjPGsye/Kf8Lb93/Ao +GEjwxrzQvzSAlsJKsW2Ox5BF3i9nrEUEo3rcVZLJR2bYGozH7ZxOmuASu7VqTITh +4SINhwBk/ox9Yjllpu9CtoAlEmEBqCQTcAARJl/6NVDFSMwGR+gn2HCNX2TmoUQm +XiLsks3/QppEIW1cxeMiHV9HEufOX1362KqxMy3ZdvJOOjMMK7MtkAY= +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIEHjCCAwagAwIBAgIBATANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQGEwJTRTEU +MBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3 +b3JrMSMwIQYDVQQDExpBZGRUcnVzdCBRdWFsaWZpZWQgQ0EgUm9vdDAeFw0wMDA1 +MzAxMDQ0NTBaFw0yMDA1MzAxMDQ0NTBaMGcxCzAJBgNVBAYTAlNFMRQwEgYDVQQK +EwtBZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQIE5ldHdvcmsxIzAh +BgNVBAMTGkFkZFRydXN0IFF1YWxpZmllZCBDQSBSb290MIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEA5B6a/twJWoekn0e+EV+vhDTbYjx5eLfpMLXsDBwq +xBb/4Oxx64r1EW7tTw2R0hIYLUkVAcKkIhPHEWT/IhKauY5cLwjPcWqzZwFZ8V1G +87B4pfYOQnrjfxvM0PC3KP0q6p6zsLkEqv32x7SxuCqg+1jxGaBvcCV+PmlKfw8i +2O+tCBGaKZnhqkRFmhJePp1tUvznoD1oL/BLcHwTOK28FSXx1s6rosAx1i+f4P8U +WfyEk9mHfExUE+uf0S0R+Bg6Ot4l2ffTQO2kBhLEO+GRwVY18BTcZTYJbqukB8c1 +0cIDMzZbdSZtQvESa0NvS3GU+jQd7RNuyoB/mC9suWXY6QIDAQABo4HUMIHRMB0G +A1UdDgQWBBQ5lYtii1zJ1IC6WA+XPxUIQ8yYpzALBgNVHQ8EBAMCAQYwDwYDVR0T +AQH/BAUwAwEB/zCBkQYDVR0jBIGJMIGGgBQ5lYtii1zJ1IC6WA+XPxUIQ8yYp6Fr +pGkwZzELMAkGA1UEBhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQL +ExRBZGRUcnVzdCBUVFAgTmV0d29yazEjMCEGA1UEAxMaQWRkVHJ1c3QgUXVhbGlm +aWVkIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBABmrder4i2VhlRO6aQTv +hsoToMeqT2QbPxj2qC0sVY8FtzDqQmodwCVRLae/DLPt7wh/bDxGGuoYQ992zPlm +hpwsaPXpF/gxsxjE1kh9I0xowX67ARRvxdlu3rsEQmr49lx95dr6h+sNNVJn0J6X +dgWTP5XHAeZpVTh/EGGZyeNfpso+gmNIquIISD6q8rKFYqa0p9m9N5xotS1WfbC3 +P6CxB9bpT9zeRXEwMn8bLgn5v1Kh7sKAPgZcLlVAwRv1cEWw3F369nJad9Jjzc9Y +iQBCYz95OdBEsIJuQRno3eDBiFrRHnGTHyQwdOUeqN48Jzd/g66ed8/wMLH/S5no +xqE= +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIDYTCCAkmgAwIBAgIQCgEBAQAAAnwAAAAKAAAAAjANBgkqhkiG9w0BAQUFADA6 +MRkwFwYDVQQKExBSU0EgU2VjdXJpdHkgSW5jMR0wGwYDVQQLExRSU0EgU2VjdXJp +dHkgMjA0OCBWMzAeFw0wMTAyMjIyMDM5MjNaFw0yNjAyMjIyMDM5MjNaMDoxGTAX +BgNVBAoTEFJTQSBTZWN1cml0eSBJbmMxHTAbBgNVBAsTFFJTQSBTZWN1cml0eSAy +MDQ4IFYzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAt49VcdKA3Xtp +eafwGFAyPGJn9gqVB93mG/Oe2dJBVGutn3y+Gc37RqtBaB4Y6lXIL5F4iSj7Jylg +/9+PjDvJSZu1pJTOAeo+tWN7fyb9Gd3AIb2E0S1PRsNO3Ng3OTsor8udGuorryGl +wSMiuLgbWhOHV4PR8CDn6E8jQrAApX2J6elhc5SYcSa8LWrg903w8bYqODGBDSnh +AMFRD0xS+ARaqn1y07iHKrtjEAMqs6FPDVpeRrc9DvV07Jmf+T0kgYim3WBU6JU2 +PcYJk5qjEoAAVZkZR73QpXzDuvsf9/UP+Ky5tfQ3mBMY3oVbtwyCO4dvlTlYMNpu +AWgXIszACwIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +BjAfBgNVHSMEGDAWgBQHw1EwpKrpRa41JPr/JCwz0LGdjDAdBgNVHQ4EFgQUB8NR +MKSq6UWuNST6/yQsM9CxnYwwDQYJKoZIhvcNAQEFBQADggEBAF8+hnZuuDU8TjYc +HnmYv/3VEhF5Ug7uMYm83X/50cYVIeiKAVQNOvtUudZj1LGqlk2iQk3UUx+LEN5/ +Zb5gEydxiKRz44Rj0aRV4VCT5hsOedBnvEbIvz8XDZXmxpBp3ue0L96VfdASPz0+ +f00/FGj1EVDVwfSQpQgdMWD/YIwjVAqv/qFuxdF6Kmh4zx6CCiC0H63lhbJqaHVO +rSU3lIW+vaHU6rcMSzyd6BIA8F+sDeGscGNz9395nzIlQnQFgCi/vcEkllgVsRch +6YlL2weIZ/QVrXA+L02FO8K32/6YaCOJ4XQP3vTFhGMpG8zLB8kApKnXwiJPZ9d3 +7CAFYd4= +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT +MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i +YWwgQ0EwHhcNMDIwNTIxMDQwMDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQG +EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UEAxMSR2VvVHJ1c3Qg +R2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2swYYzD9 +9BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjoBbdq +fnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDv +iS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU +1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+ +bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5aszPeE4uwc2hGKceeoW +MPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTA +ephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVkDBF9qn1l +uMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKIn +Z57QzxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfS +tQWVYrmm3ok9Nns4d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcF +PseKUgzbFbS9bZvlxrFUaKnjaZC2mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Un +hw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6pXE0zX5IJL4hmXXeXxx12E6nV +5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvmMw== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIDojCCAoqgAwIBAgIQE4Y1TR0/BvLB+WUF1ZAcYjANBgkqhkiG9w0BAQUFADBr +MQswCQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRl +cm5hdGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNv +bW1lcmNlIFJvb3QwHhcNMDIwNjI2MDIxODM2WhcNMjIwNjI0MDAxNjEyWjBrMQsw +CQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRlcm5h +dGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNvbW1l +cmNlIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvV95WHm6h +2mCxlCfLF9sHP4CFT8icttD0b0/Pmdjh28JIXDqsOTPHH2qLJj0rNfVIsZHBAk4E +lpF7sDPwsRROEW+1QK8bRaVK7362rPKgH1g/EkZgPI2h4H3PVz4zHvtH8aoVlwdV +ZqW1LS7YgFmypw23RuwhY/81q6UCzyr0TP579ZRdhE2o8mCP2w4lPJ9zcc+U30rq +299yOIzzlr3xF7zSujtFWsan9sYXiwGd/BmoKoMWuDpI/k4+oKsGGelT84ATB+0t +vz8KPFUgOSwsAGl0lUq8ILKpeeUYiZGo3BxN77t+Nwtd/jmliFKMAGzsGHxBvfaL +dXe6YJ2E5/4tAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD +AgEGMB0GA1UdDgQWBBQVOIMPPyw/cDMezUb+B4wg4NfDtzANBgkqhkiG9w0BAQUF +AAOCAQEAX/FBfXxcCLkr4NWSR/pnXKUTwwMhmytMiUbPWU3J/qVAtmPN3XEolWcR +zCSs00Rsca4BIGsDoo8Ytyk6feUWYFN4PMCvFYP3j1IzJL1kk5fui/fbGKhtcbP3 +LBfQdCVp9/5rPJS+TUtBjE7ic9DjkCJzQ83z7+pzzkWKsKZJ/0x9nXGIxHYdkFsd +7v3M9+79YKWxehZx0RbQfBI8bGmX265fOZpwLwU8GUYEmSA20GBuYQa7FkKMcPcw +++DbZqMAAb3mLNqRX6BGi01qnD093QVG/na/oAo85ADmJ7f/hC3euiInlhBx6yLt +398znM/jra6O1I7mT1GvFpLgXPYHDw== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIDDDCCAfSgAwIBAgIDAQAgMA0GCSqGSIb3DQEBBQUAMD4xCzAJBgNVBAYTAlBM +MRswGQYDVQQKExJVbml6ZXRvIFNwLiB6IG8uby4xEjAQBgNVBAMTCUNlcnR1bSBD +QTAeFw0wMjA2MTExMDQ2MzlaFw0yNzA2MTExMDQ2MzlaMD4xCzAJBgNVBAYTAlBM +MRswGQYDVQQKExJVbml6ZXRvIFNwLiB6IG8uby4xEjAQBgNVBAMTCUNlcnR1bSBD +QTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM6xwS7TT3zNJc4YPk/E +jG+AanPIW1H4m9LcuwBcsaD8dQPugfCI7iNS6eYVM42sLQnFdvkrOYCJ5JdLkKWo +ePhzQ3ukYbDYWMzhbGZ+nPMJXlVjhNWo7/OxLjBos8Q82KxujZlakE403Daaj4GI +ULdtlkIJ89eVgw1BS7Bqa/j8D35in2fE7SZfECYPCE/wpFcozo+47UX2bu4lXapu +Ob7kky/ZR6By6/qmW6/KUz/iDsaWVhFu9+lmqSbYf5VT7QqFiLpPKaVCjF62/IUg +AKpoC6EahQGcxEZjgoi2IrHu/qpGWX7PNSzVttpd90gzFFS269lvzs2I1qsb2pY7 +HVkCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEA +uI3O7+cUus/usESSbLQ5PqKEbq24IXfS1HeCh+YgQYHu4vgRt2PRFze+GXYkHAQa +TOs9qmdvLdTN/mUxcMUbpgIKumB7bVjCmkn+YzILa+M6wKyrO7Do0wlRjBCDxjTg +xSvgGrZgFCdsMneMvLJymM/NzD+5yCRCFNZX/OYmQ6kd5YCQzgNUKD73P9P4Te1q +CjqTE5s7FCMTY5w/0YcneeVMUeMBrYVdGjux1XMQpNPyvG5k9VpWkKjHDkx0Dy5x +O/fIR/RpbxXyEV6DHpx8Uq79AtoSqFlnGNu8cN2bsWntgM6JQEhqDjXKKWYVIZQs +6GAqm4VKQPNriiTsBhYscw== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEb +MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow +GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmlj +YXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVowezEL +MAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE +BwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNVBAMM +GEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQua +BtDFcCLNSS1UY8y2bmhGC1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe +3M/vg4aijJRPn2jymJBGhCfHdr/jzDUsi14HZGWCwEiwqJH5YZ92IFCokcdmtet4 +YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszWY19zjNoFmag4qMsXeDZR +rOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjHYpy+g8cm +ez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQU +oBEKIz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF +MAMBAf8wewYDVR0fBHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20v +QUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29t +b2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2VzLmNybDANBgkqhkiG9w0BAQUF +AAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm7l3sAg9g1o1Q +GE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz +Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2 +G9w84FoVxp7Z8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsi +l2D4kF501KKaU73yqWjgom7C12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3 +smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIEPzCCAyegAwIBAgIBATANBgkqhkiG9w0BAQUFADB+MQswCQYDVQQGEwJHQjEb +MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow +GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEkMCIGA1UEAwwbU2VjdXJlIENlcnRp +ZmljYXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVow +fjELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G +A1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxJDAiBgNV +BAMMG1NlY3VyZSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBAMBxM4KK0HDrc4eCQNUd5MvJDkKQ+d40uaG6EfQlhfPM +cm3ye5drswfxdySRXyWP9nQ95IDC+DwN879A6vfIUtFyb+/Iq0G4bi4XKpVpDM3S +HpR7LZQdqnXXs5jLrLxkU0C8j6ysNstcrbvd4JQX7NFc0L/vpZXJkMWwrPsbQ996 +CF23uPJAGysnnlDOXmWCiIxe004MeuoIkbY2qitC++rCoznl2yY4rYsK7hljxxwk +3wN42ubqwUcaCwtGCd0C/N7Lh1/XMGNooa7cMqG6vv5Eq2i2pRcV/b3Vp6ea5EQz +6YiO/O1R65NxTq0B50SOqy3LqP4BSUjwwN3HaNiS/j0CAwEAAaOBxzCBxDAdBgNV +HQ4EFgQUPNiTiMLAggnMAZkGkyDpnnAJY08wDgYDVR0PAQH/BAQDAgEGMA8GA1Ud +EwEB/wQFMAMBAf8wgYEGA1UdHwR6MHgwO6A5oDeGNWh0dHA6Ly9jcmwuY29tb2Rv +Y2EuY29tL1NlY3VyZUNlcnRpZmljYXRlU2VydmljZXMuY3JsMDmgN6A1hjNodHRw +Oi8vY3JsLmNvbW9kby5uZXQvU2VjdXJlQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmww +DQYJKoZIhvcNAQEFBQADggEBAIcBbSMdflsXfcFhMs+P5/OKlFlm4J4oqF7Tt/Q0 +5qo5spcWxYJvMqTpjOev/e/C6LlLqqP05tqNZSH7uoDrJiiFGv45jN5bBAS0VPmj +Z55B+glSzAVIqMk/IQQezkhr/IXownuvf7fM+F86/TXGDe+X3EyrEeFryzHRbPtI +gKvcnDe4IRRLDXE97IMzbtFuMhbsmMcWi1mmNKsFVy2T96oTy9IT4rcuO81rUBcJ +aD61JlfutuC23bkpgHl9j6PwpCikFcSF9CfUa7/lXORlAnZUtOM3ZiTTGWHIUhDl +izeauan5Hb/qmZJhlv8BzaFfDbxxvA6sCx1HRR3B7Hzs/Sk= +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIEQzCCAyugAwIBAgIBATANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJHQjEb +MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow +GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDElMCMGA1UEAwwcVHJ1c3RlZCBDZXJ0 +aWZpY2F0ZSBTZXJ2aWNlczAeFw0wNDAxMDEwMDAwMDBaFw0yODEyMzEyMzU5NTla +MH8xCzAJBgNVBAYTAkdCMRswGQYDVQQIDBJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAO +BgNVBAcMB1NhbGZvcmQxGjAYBgNVBAoMEUNvbW9kbyBDQSBMaW1pdGVkMSUwIwYD +VQQDDBxUcnVzdGVkIENlcnRpZmljYXRlIFNlcnZpY2VzMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEA33FvNlhTWvI2VFeAxHQIIO0Yfyod5jWaHiWsnOWW +fnJSoBVC21ndZHoa0Lh73TkVvFVIxO06AOoxEbrycXQaZ7jPM8yoMa+j49d/vzMt +TGo87IvDktJTdyR0nAducPy9C1t2ul/y/9c3S0pgePfw+spwtOpZqqPOSC+pw7IL +fhdyFgymBwwbOM/JYrc/oJOlh0Hyt3BAd9i+FHzjqMB6juljatEPmsbS9Is6FARW +1O24zG71++IsWL1/T2sr92AkWCTOJu80kTrV44HQsvAEAtdbtz6SrGsSivnkBbA7 +kUlcsutT6vifR4buv5XAwAaf0lteERv0xwQ1KdJVXOTt6wIDAQABo4HJMIHGMB0G +A1UdDgQWBBTFe1i97doladL3WRaoszLAeydb9DAOBgNVHQ8BAf8EBAMCAQYwDwYD +VR0TAQH/BAUwAwEB/zCBgwYDVR0fBHwwejA8oDqgOIY2aHR0cDovL2NybC5jb21v +ZG9jYS5jb20vVHJ1c3RlZENlcnRpZmljYXRlU2VydmljZXMuY3JsMDqgOKA2hjRo +dHRwOi8vY3JsLmNvbW9kby5uZXQvVHJ1c3RlZENlcnRpZmljYXRlU2VydmljZXMu +Y3JsMA0GCSqGSIb3DQEBBQUAA4IBAQDIk4E7ibSvuIQSTI3S8NtwuleGFTQQuS9/ +HrCoiWChisJ3DFBKmwCL2Iv0QeLQg4pKHBQGsKNoBXAxMKdTmw7pSqBYaWcOrp32 +pSxBvzwGa+RZzG0Q8ZZvH9/0BAKkn0U+yNj6NkZEUD+Cl5EfKNsYEYwq5GWDVxIS +jBc/lDb+XbDABHcTuPQV1T84zJQ6VdCsmPW6AF/ghhmBeC8owH7TzEIK9a5QoNE+ +xqFx7D+gIIxmOom0jtTYsU0lR+4viMi14QVFwL4Ucd56/Y57fU0IlqUSc/Atyjcn +dBInTMu2l+nZrghtWjlA3QVHdWpaIbOjGM9O9y5Xt5hwXsjEeLBi +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIF0DCCBLigAwIBAgIEOrZQizANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJC +TTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDElMCMGA1UECxMcUm9vdCBDZXJ0 +aWZpY2F0aW9uIEF1dGhvcml0eTEuMCwGA1UEAxMlUXVvVmFkaXMgUm9vdCBDZXJ0 +aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wMTAzMTkxODMzMzNaFw0yMTAzMTcxODMz +MzNaMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMSUw +IwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYDVQQDEyVR +dW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv2G1lVO6V/z68mcLOhrfEYBklbTRvM16z/Yp +li4kVEAkOPcahdxYTMukJ0KX0J+DisPkBgNbAKVRHnAEdOLB1Dqr1607BxgFjv2D +rOpm2RgbaIr1VxqYuvXtdj182d6UajtLF8HVj71lODqV0D1VNk7feVcxKh7YWWVJ +WCCYfqtffp/p1k3sg3Spx2zY7ilKhSoGFPlU5tPaZQeLYzcS19Dsw3sgQUSj7cug +F+FxZc4dZjH3dgEZyH0DWLaVSR2mEiboxgx24ONmy+pdpibu5cxfvWenAScOospU +xbF6lR1xHkopigPcakXBpBlebzbNw6Kwt/5cOOJSvPhEQ+aQuwIDAQABo4ICUjCC +Ak4wPQYIKwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwczovL29jc3AucXVv +dmFkaXNvZmZzaG9yZS5jb20wDwYDVR0TAQH/BAUwAwEB/zCCARoGA1UdIASCAREw +ggENMIIBCQYJKwYBBAG+WAABMIH7MIHUBggrBgEFBQcCAjCBxxqBxFJlbGlhbmNl +IG9uIHRoZSBRdW9WYWRpcyBSb290IENlcnRpZmljYXRlIGJ5IGFueSBwYXJ0eSBh +c3N1bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJsZSBzdGFuZGFy +ZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGNlcnRpZmljYXRpb24gcHJh +Y3RpY2VzLCBhbmQgdGhlIFF1b1ZhZGlzIENlcnRpZmljYXRlIFBvbGljeS4wIgYI +KwYBBQUHAgEWFmh0dHA6Ly93d3cucXVvdmFkaXMuYm0wHQYDVR0OBBYEFItLbe3T +KbkGGew5Oanwl4Rqy+/fMIGuBgNVHSMEgaYwgaOAFItLbe3TKbkGGew5Oanwl4Rq +y+/foYGEpIGBMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1p +dGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYD +VQQDEyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggQ6tlCL +MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAitQUtf70mpKnGdSk +fnIYj9lofFIk3WdvOXrEql494liwTXCYhGHoG+NpGA7O+0dQoE7/8CQfvbLO9Sf8 +7C9TqnN7Az10buYWnuulLsS/VidQK2K6vkscPFVcQR0kvoIgR13VRH56FmjffU1R +cHhXHTMe/QKZnAzNCgVPx7uOpHX6Sm2xgI4JVrmcGmD+XcHXetwReNDWXcG31a0y +mQM6isxUJTkxgXsTIlG6Rmyhu576BGxJJnSP0nPrzDCi5upZIof4l/UO/erMkqQW +xFIY6iHOsfHmhIHluqmGKPJDWl0Snawe2ajlCmqnf6CHKc/yiU3U7MXi5nrQNiOK +SnQ2+Q== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIDWjCCAkKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBQMQswCQYDVQQGEwJKUDEY +MBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21t +dW5pY2F0aW9uIFJvb3RDQTEwHhcNMDMwOTMwMDQyMDQ5WhcNMjMwOTMwMDQyMDQ5 +WjBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYD +VQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQCzs/5/022x7xZ8V6UMbXaKL0u/ZPtM7orw8yl8 +9f/uKuDp6bpbZCKamm8sOiZpUQWZJtzVHGpxxpp9Hp3dfGzGjGdnSj74cbAZJ6kJ +DKaVv0uMDPpVmDvY6CKhS3E4eayXkmmziX7qIWgGmBSWh9JhNrxtJ1aeV+7AwFb9 +Ms+k2Y7CI9eNqPPYJayX5HA49LY6tJ07lyZDo6G8SVlyTCMwhwFY9k6+HGhWZq/N +QV3Is00qVUarH9oe4kA92819uZKAnDfdDJZkndwi92SL32HeFZRSFaB9UslLqCHJ +xrHty8OVYNEP8Ktw+N/LTX7s1vqr2b1/VPKl6Xn62dZ2JChzAgMBAAGjPzA9MB0G +A1UdDgQWBBSgc0mZaNyFW2XjmygvV5+9M7wHSDALBgNVHQ8EBAMCAQYwDwYDVR0T +AQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAaECpqLvkT115swW1F7NgE+vG +kl3g0dNq/vu+m22/xwVtWSDEHPC32oRYAmP6SBbvT6UL90qY8j+eG61Ha2POCEfr +Uj94nK9NrvjVT8+amCoQQTlSxN3Zmw7vkwGusi7KaEIkQmywszo+zenaSMQVy+n5 +Bw+SUEmK3TGXX8npN6o7WWWXlDLJs58+OmJYxUmtYg5xpTKqL8aJdkNAExNnPaJU +JRDL8Try2frbSVa7pv6nQTXD4IhhyYjH3zYQIphZ6rBK+1YWc26sTfcioU+tHXot +RSflMMFe8toTyyVCUZVHA4xsIcx0Qu1T/zOLjw9XARYvz6buyXAiFL39vmwLAw== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIDIDCCAgigAwIBAgIBJDANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGSTEP +MA0GA1UEChMGU29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MxIENBMB4XDTAx +MDQwNjEwNDkxM1oXDTIxMDQwNjEwNDkxM1owOTELMAkGA1UEBhMCRkkxDzANBgNV +BAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJhIENsYXNzMSBDQTCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBALWJHytPZwp5/8Ue+H887dF+2rDNbS82rDTG +29lkFwhjMDMiikzujrsPDUJVyZ0upe/3p4zDq7mXy47vPxVnqIJyY1MPQYx9EJUk +oVqlBvqSV536pQHydekfvFYmUk54GWVYVQNYwBSujHxVX3BbdyMGNpfzJLWaRpXk +3w0LBUXl0fIdgrvGE+D+qnr9aTCU89JFhfzyMlsy3uhsXR/LpCJ0sICOXZT3BgBL +qdReLjVQCfOAl/QMF6452F/NM8EcyonCIvdFEu1eEpOdY6uCLrnrQkFEy0oaAIIN +nvmLVz5MxxftLItyM19yejhW1ebZrgUaHXVFsculJRwSVzb9IjcCAwEAAaMzMDEw +DwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4ECgQIR+IMi/ZTiFIwCwYDVR0PBAQDAgEG +MA0GCSqGSIb3DQEBBQUAA4IBAQCLGrLJXWG04bkruVPRsoWdd44W7hE928Jj2VuX +ZfsSZ9gqXLar5V7DtxYvyOirHYr9qxp81V9jz9yw3Xe5qObSIjiHBxTZ/75Wtf0H +DjxVyhbMp6Z3N/vbXB9OWQaHowND9Rart4S9Tu+fMTfwRvFAttEMpWT4Y14h21VO +TzF2nBBhjrZTOqMRvq9tfB69ri3iDGnHhVNoomG6xT60eVR4ngrHAr5i0RGCS2Uv +kVrCqIexVmiUefkl98HVrhq4uz2PqYo4Ffdz0Fpg0YCw8NzVUM1O7pJIae2yIx4w +zMiUyLb1O4Z/P6Yun/Y+LLWSlj7fLJOK/4GMDw9ZIRlXvVWa +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIDIDCCAgigAwIBAgIBHTANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGSTEP +MA0GA1UEChMGU29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MyIENBMB4XDTAx +MDQwNjA3Mjk0MFoXDTIxMDQwNjA3Mjk0MFowOTELMAkGA1UEBhMCRkkxDzANBgNV +BAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJhIENsYXNzMiBDQTCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAJAXSjWdyvANlsdE+hY3/Ei9vX+ALTU74W+o +Z6m/AxxNjG8yR9VBaKQTBME1DJqEQ/xcHf+Js+gXGM2RX/uJ4+q/Tl18GybTdXnt +5oTjV+WtKcT0OijnpXuENmmz/V52vaMtmdOQTiMofRhj8VQ7Jp12W5dCsv+u8E7s +3TmVToMGf+dJQMjFAbJUWmYdPfz56TwKnoG4cPABi+QjVHzIrviQHgCWctRUz2Ej +vOr7nQKV0ba5cTppCD8PtOFCx4j1P5iop7oc4HFx71hXgVB6XGt0Rg6DA5jDjqhu +8nYybieDwnPz3BjotJPqdURrBGAgcVeHnfO+oJAjPYok4doh28MCAwEAAaMzMDEw +DwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4ECgQISqCqWITTXjwwCwYDVR0PBAQDAgEG +MA0GCSqGSIb3DQEBBQUAA4IBAQBazof5FnIVV0sd2ZvnoiYw7JNn39Yt0jSv9zil +zqsWuasvfDXLrNAPtEwr/IDva4yRXzZ299uzGxnq9LIR/WFxRL8oszodv7ND6J+/ +3DEIcbCdjdY0RzKQxmUk96BKfARzjzlvF4xytb1LyHr4e4PDKE6cCepnP7JnBBvD +FNr450kkkdAdavphOe9r5yF1BgfYErQhIHBCcYHaPJo2vqZbDWpsmh+Re/n570K6 +Tk6ezAyNlNzZRZxe7EJQY670XcSxEtzKO6gunRRaBXW37Ndj4ro1tgQIkejanZz2 +ZrUYrAqmVCY0M9IbwdR/GjqOC6oybtv8TyWf2TLHllpwrN9M +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIDujCCAqKgAwIBAgIEAJiWijANBgkqhkiG9w0BAQUFADBVMQswCQYDVQQGEwJO +TDEeMBwGA1UEChMVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSYwJAYDVQQDEx1TdGFh +dCBkZXIgTmVkZXJsYW5kZW4gUm9vdCBDQTAeFw0wMjEyMTcwOTIzNDlaFw0xNTEy +MTYwOTE1MzhaMFUxCzAJBgNVBAYTAk5MMR4wHAYDVQQKExVTdGFhdCBkZXIgTmVk +ZXJsYW5kZW4xJjAkBgNVBAMTHVN0YWF0IGRlciBOZWRlcmxhbmRlbiBSb290IENB +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmNK1URF6gaYUmHFtvszn +ExvWJw56s2oYHLZhWtVhCb/ekBPHZ+7d89rFDBKeNVU+LCeIQGv33N0iYfXCxw71 +9tV2U02PjLwYdjeFnejKScfST5gTCaI+Ioicf9byEGW07l8Y1Rfj+MX94p2i71MO +hXeiD+EwR+4A5zN9RGcaC1Hoi6CeUJhoNFIfLm0B8mBF8jHrqTFoKbt6QZ7GGX+U +tFE5A3+y3qcym7RHjm+0Sq7lr7HcsBthvJly3uSJt3omXdozSVtSnA71iq3DuD3o +BmrC1SoLbHuEvVYFy4ZlkuxEK7COudxwC0barbxjiDn622r+I/q85Ej0ZytqERAh +SQIDAQABo4GRMIGOMAwGA1UdEwQFMAMBAf8wTwYDVR0gBEgwRjBEBgRVHSAAMDww +OgYIKwYBBQUHAgEWLmh0dHA6Ly93d3cucGtpb3ZlcmhlaWQubmwvcG9saWNpZXMv +cm9vdC1wb2xpY3kwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSofeu8Y6R0E3QA +7Jbg0zTBLL9s+DANBgkqhkiG9w0BAQUFAAOCAQEABYSHVXQ2YcG70dTGFagTtJ+k +/rvuFbQvBgwp8qiSpGEN/KtcCFtREytNwiphyPgJWPwtArI5fZlmgb9uXJVFIGzm +eafR2Bwp/MIgJ1HI8XxdNGdphREwxgDS1/PTfLbwMVcoEoJz6TMvplW0C5GUR5z6 +u3pCMuiufi3IvKwUv9kP2Vv8wfl6leF9fpb8cbDCTMjfRTTJzg3ynGQI0DvDKcWy +7ZAEwbEpkcUwb8GpcjPM/l0WFywRaed+/sWDCN+83CI6LiBpIzlWYGeQiy52OfsR +iJf2fL1LuCAWZwWN4jvBcj+UlTfHXbme2JOhF4//DGYVwSR8MnwDHTuhWEUykw== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIEXjCCA0agAwIBAgIQRL4Mi1AAIbQR0ypoBqmtaTANBgkqhkiG9w0BAQUFADCB +kzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug +Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho +dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xGzAZBgNVBAMTElVUTiAtIERBVEFDb3Jw +IFNHQzAeFw05OTA2MjQxODU3MjFaFw0xOTA2MjQxOTA2MzBaMIGTMQswCQYDVQQG +EwJVUzELMAkGA1UECBMCVVQxFzAVBgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4wHAYD +VQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxITAfBgNVBAsTGGh0dHA6Ly93d3cu +dXNlcnRydXN0LmNvbTEbMBkGA1UEAxMSVVROIC0gREFUQUNvcnAgU0dDMIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3+5YEKIrblXEjr8uRgnn4AgPLit6 +E5Qbvfa2gI5lBZMAHryv4g+OGQ0SR+ysraP6LnD43m77VkIVni5c7yPeIbkFdicZ +D0/Ww5y0vpQZY/KmEQrrU0icvvIpOxboGqBMpsn0GFlowHDyUwDAXlCCpVZvNvlK +4ESGoE1O1kduSUrLZ9emxAW5jh70/P/N5zbgnAVssjMiFdC04MwXwLLA9P4yPykq +lXvY8qdOD1R8oQ2AswkDwf9c3V6aPryuvEeKaq5xyh+xKrhfQgUL7EYw0XILyulW +bfXv33i+Ybqypa4ETLyorGkVl73v67SMvzX41MPRKA5cOp9wGDMgd8SirwIDAQAB +o4GrMIGoMAsGA1UdDwQEAwIBxjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRT +MtGzz3/64PGgXYVOktKeRR20TzA9BgNVHR8ENjA0MDKgMKAuhixodHRwOi8vY3Js +LnVzZXJ0cnVzdC5jb20vVVROLURBVEFDb3JwU0dDLmNybDAqBgNVHSUEIzAhBggr +BgEFBQcDAQYKKwYBBAGCNwoDAwYJYIZIAYb4QgQBMA0GCSqGSIb3DQEBBQUAA4IB +AQAnNZcAiosovcYzMB4p/OL31ZjUQLtgyr+rFywJNn9Q+kHcrpY6CiM+iVnJowft +Gzet/Hy+UUla3joKVAgWRcKZsYfNjGjgaQPpxE6YsjuMFrMOoAyYUJuTqXAJyCyj +j98C5OBxOvG0I3KgqgHf35g+FFCgMSa9KOlaMCZ1+XtgHI3zzVAmbQQnmt/VDUVH +KWss5nbZqSl9Mt3JNjy9rjXxEZ4du5A/EkdOjtd+D2JzHVImOBwYSf0wdJrE5SIv +2MCN7ZF6TACPcn9d2t0bi0Vr591pl6jFVkwPDPafepE39peC4N1xaf92P2BNPM/3 +mfnGV/TJVTl4uix5yaaIK/QI +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIEojCCA4qgAwIBAgIQRL4Mi1AAJLQR0zYlJWfJiTANBgkqhkiG9w0BAQUFADCB +rjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug +Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho +dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xNjA0BgNVBAMTLVVUTi1VU0VSRmlyc3Qt +Q2xpZW50IEF1dGhlbnRpY2F0aW9uIGFuZCBFbWFpbDAeFw05OTA3MDkxNzI4NTBa +Fw0xOTA3MDkxNzM2NThaMIGuMQswCQYDVQQGEwJVUzELMAkGA1UECBMCVVQxFzAV +BgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5l +dHdvcmsxITAfBgNVBAsTGGh0dHA6Ly93d3cudXNlcnRydXN0LmNvbTE2MDQGA1UE +AxMtVVROLVVTRVJGaXJzdC1DbGllbnQgQXV0aGVudGljYXRpb24gYW5kIEVtYWls +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsjmFpPJ9q0E7YkY3rs3B +YHW8OWX5ShpHornMSMxqmNVNNRm5pELlzkniii8efNIxB8dOtINknS4p1aJkxIW9 +hVE1eaROaJB7HHqkkqgX8pgV8pPMyaQylbsMTzC9mKALi+VuG6JG+ni8om+rWV6l +L8/K2m2qL+usobNqqrcuZzWLeeEeaYji5kbNoKXqvgvOdjp6Dpvq/NonWz1zHyLm +SGHGTPNpsaguG7bUMSAsvIKKjqQOpdeJQ/wWWq8dcdcRWdq6hw2v+vPhwvCkxWeM +1tZUOt4KpLoDd7NlyP0e03RiqhjKaJMeoYV+9Udly/hNVyh00jT/MLbu9mIwFIws +6wIDAQABo4G5MIG2MAsGA1UdDwQEAwIBxjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud +DgQWBBSJgmd9xJ0mcABLtFBIfN49rgRufTBYBgNVHR8EUTBPME2gS6BJhkdodHRw +Oi8vY3JsLnVzZXJ0cnVzdC5jb20vVVROLVVTRVJGaXJzdC1DbGllbnRBdXRoZW50 +aWNhdGlvbmFuZEVtYWlsLmNybDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUH +AwQwDQYJKoZIhvcNAQEFBQADggEBALFtYV2mGn98q0rkMPxTbyUkxsrt4jFcKw7u +7mFVbwQ+zznexRtJlOTrIEy05p5QLnLZjfWqo7NK2lYcYJeA3IKirUq9iiv/Cwm0 +xtcgBEXkzYABurorbs6q15L+5K/r9CYdFip/bDCVNy8zEqx/3cfREYxRmLLQo5HQ +rfafnoOTHh1CuEava2bwm3/q4wMC5QJRwarVNZ1yQAOJujEdxRBoUp7fooXFXAim +eOZTT7Hot9MUnpOmw2TjrH5xzbyf6QMbzPvprDHBr3wVdAKZw7JHpsIyYdfHb0gk +USeh1YdV8nuPmD0Wnu51tvjQjvLzxq4oW6fw8zYX/MMF08oDSlQ= +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIEdDCCA1ygAwIBAgIQRL4Mi1AAJLQR0zYq/mUK/TANBgkqhkiG9w0BAQUFADCB +lzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug +Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho +dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3Qt +SGFyZHdhcmUwHhcNOTkwNzA5MTgxMDQyWhcNMTkwNzA5MTgxOTIyWjCBlzELMAkG +A1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEe +MBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8v +d3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3QtSGFyZHdh +cmUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCx98M4P7Sof885glFn +0G2f0v9Y8+efK+wNiVSZuTiZFvfgIXlIwrthdBKWHTxqctU8EGc6Oe0rE81m65UJ +M6Rsl7HoxuzBdXmcRl6Nq9Bq/bkqVRcQVLMZ8Jr28bFdtqdt++BxF2uiiPsA3/4a +MXcMmgF6sTLjKwEHOG7DpV4jvEWbe1DByTCP2+UretNb+zNAHqDVmBe8i4fDidNd +oI6yqqr2jmmIBsX6iSHzCJ1pLgkzmykNRg+MzEk0sGlRvfkGzWitZky8PqxhvQqI +DsjfPe58BEydCl5rkdbux+0ojatNh4lz0G6k0B4WixThdkQDf2Os5M1JnMWS9Ksy +oUhbAgMBAAGjgbkwgbYwCwYDVR0PBAQDAgHGMA8GA1UdEwEB/wQFMAMBAf8wHQYD +VR0OBBYEFKFyXyYbKJhDlV0HN9WFlp1L0sNFMEQGA1UdHwQ9MDswOaA3oDWGM2h0 +dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9VVE4tVVNFUkZpcnN0LUhhcmR3YXJlLmNy +bDAxBgNVHSUEKjAoBggrBgEFBQcDAQYIKwYBBQUHAwUGCCsGAQUFBwMGBggrBgEF +BQcDBzANBgkqhkiG9w0BAQUFAAOCAQEARxkP3nTGmZev/K0oXnWO6y1n7k57K9cM +//bey1WiCuFMVGWTYGufEpytXoMs61quwOQt9ABjHbjAbPLPSbtNk28Gpgoiskli +CE7/yMgUsogWXecB5BKV5UU0s4tpvc+0hY91UZ59Ojg6FEgSxvunOxqNDYJAB+gE +CJChicsZUN/KHAG8HQQZexB2lzvukJDKxA4fFm517zP4029bHpbj4HR3dHuKom4t +3XbWOTCC8KucUvIqx69JXn7HaOWCgchqJ/kniCrVWFCVH/A7HFe7fRQ5YiuayZSS +KqMiDP+JJn1fIytH1xUdqWqeUQ0qUZ6B+dQ7XnASfxAynB67nfhmqA== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIEZjCCA06gAwIBAgIQRL4Mi1AAJLQR0zYt4LNfGzANBgkqhkiG9w0BAQUFADCB +lTELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug +Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho +dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHTAbBgNVBAMTFFVUTi1VU0VSRmlyc3Qt +T2JqZWN0MB4XDTk5MDcwOTE4MzEyMFoXDTE5MDcwOTE4NDAzNlowgZUxCzAJBgNV +BAYTAlVTMQswCQYDVQQIEwJVVDEXMBUGA1UEBxMOU2FsdCBMYWtlIENpdHkxHjAc +BgNVBAoTFVRoZSBVU0VSVFJVU1QgTmV0d29yazEhMB8GA1UECxMYaHR0cDovL3d3 +dy51c2VydHJ1c3QuY29tMR0wGwYDVQQDExRVVE4tVVNFUkZpcnN0LU9iamVjdDCC +ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM6qgT+jo2F4qjEAVZURnicP +HxzfOpuCaDDASmEd8S8O+r5596Uj71VRloTN2+O5bj4x2AogZ8f02b+U60cEPgLO +KqJdhwQJ9jCdGIqXsqoc/EHSoTbL+z2RuufZcDX65OeQw5ujm9M89RKZd7G3CeBo +5hy485RjiGpq/gt2yb70IuRnuasaXnfBhQfdDWy/7gbHd2pBnqcP1/vulBe3/IW+ +pKvEHDHd17bR5PDv3xaPslKT16HUiaEHLr/hARJCHhrh2JU022R5KP+6LhHC5ehb +kkj7RwvCbNqtMoNB86XlQXD9ZZBt+vpRxPm9lisZBCzTbafc8H9vg2XiaquHhnUC +AwEAAaOBrzCBrDALBgNVHQ8EBAMCAcYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E +FgQU2u1kdBScFDyr3ZmpvVsoTYs8ydgwQgYDVR0fBDswOTA3oDWgM4YxaHR0cDov +L2NybC51c2VydHJ1c3QuY29tL1VUTi1VU0VSRmlyc3QtT2JqZWN0LmNybDApBgNV +HSUEIjAgBggrBgEFBQcDAwYIKwYBBQUHAwgGCisGAQQBgjcKAwQwDQYJKoZIhvcN +AQEFBQADggEBAAgfUrE3RHjb/c652pWWmKpVZIC1WkDdIaXFwfNfLEzIR1pp6ujw +NTX00CXzyKakh0q9G7FzCL3Uw8q2NbtZhncxzaeAFK4T7/yxSPlrJSUtUbYsbUXB +mMiKVl0+7kNOPmsnjtA6S4ULX9Ptaqd1y9Fahy85dRNacrACgZ++8A+EVCBibGnU +4U3GDZlDAQ0Slox4nb9QorFEqmrPF3rPbw/U+CRVX/A0FklmPlBGyWNxODFiuGK5 +81OtbLUrohKqGU8J2l7nk8aOFAj+8DCAGKCGhU3IfdeLA/5u1fedFqySLKAj5ZyR +Uh+U3xeUc8OzwcFxBSAAeL0TUh2oPs0AH8g= +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIEvTCCA6WgAwIBAgIBADANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJFVTEn +MCUGA1UEChMeQUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQL +ExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEiMCAGA1UEAxMZQ2hhbWJlcnMg +b2YgQ29tbWVyY2UgUm9vdDAeFw0wMzA5MzAxNjEzNDNaFw0zNzA5MzAxNjEzNDRa +MH8xCzAJBgNVBAYTAkVVMScwJQYDVQQKEx5BQyBDYW1lcmZpcm1hIFNBIENJRiBB +ODI3NDMyODcxIzAhBgNVBAsTGmh0dHA6Ly93d3cuY2hhbWJlcnNpZ24ub3JnMSIw +IAYDVQQDExlDaGFtYmVycyBvZiBDb21tZXJjZSBSb290MIIBIDANBgkqhkiG9w0B +AQEFAAOCAQ0AMIIBCAKCAQEAtzZV5aVdGDDg2olUkfzIx1L4L1DZ77F1c2VHfRtb +unXF/KGIJPov7coISjlUxFF6tdpg6jg8gbLL8bvZkSM/SAFwdakFKq0fcfPJVD0d +BmpAPrMMhe5cG3nCYsS4No41XQEMIwRHNaqbYE6gZj3LJgqcQKH0XZi/caulAGgq +7YN6D6IUtdQis4CwPAxaUWktWBiP7Zme8a7ileb2R6jWDA+wWFjbw2Y3npuRVDM3 +0pQcakjJyfKl2qUMI/cjDpwyVV5xnIQFUZot/eZOKjRa3spAN2cMVCFVd9oKDMyX +roDclDZK9D7ONhMeU+SsTjoF7Nuucpw4i9A5O4kKPnf+dQIBA6OCAUQwggFAMBIG +A1UdEwEB/wQIMAYBAf8CAQwwPAYDVR0fBDUwMzAxoC+gLYYraHR0cDovL2NybC5j +aGFtYmVyc2lnbi5vcmcvY2hhbWJlcnNyb290LmNybDAdBgNVHQ4EFgQU45T1sU3p +26EpW1eLTXYGduHRooowDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIA +BzAnBgNVHREEIDAegRxjaGFtYmVyc3Jvb3RAY2hhbWJlcnNpZ24ub3JnMCcGA1Ud +EgQgMB6BHGNoYW1iZXJzcm9vdEBjaGFtYmVyc2lnbi5vcmcwWAYDVR0gBFEwTzBN +BgsrBgEEAYGHLgoDATA+MDwGCCsGAQUFBwIBFjBodHRwOi8vY3BzLmNoYW1iZXJz +aWduLm9yZy9jcHMvY2hhbWJlcnNyb290Lmh0bWwwDQYJKoZIhvcNAQEFBQADggEB +AAxBl8IahsAifJ/7kPMa0QOx7xP5IV8EnNrJpY0nbJaHkb5BkAFyk+cefV/2icZd +p0AJPaxJRUXcLo0waLIJuvvDL8y6C98/d3tGfToSJI6WjzwFCm/SlCgdbQzALogi +1djPHRPH8EjX1wWnz8dHnjs8NMiAT9QUu/wNUPf6s+xCX6ndbcj0dc97wXImsQEc +XCz9ek60AcUFV7nnPKoF2YjpB0ZBzu9Bga5Y34OirsrXdx/nADydb47kMgkdTXg0 +eDQ8lJsm7U9xxhl6vSAiSFr+S30Dt+dYvsYyTnQeaN2oaFuzPu5ifdmA6Ap1erfu +tGWaIZDgqtCYvDi1czyL+Nw= +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIExTCCA62gAwIBAgIBADANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJFVTEn +MCUGA1UEChMeQUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQL +ExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEgMB4GA1UEAxMXR2xvYmFsIENo +YW1iZXJzaWduIFJvb3QwHhcNMDMwOTMwMTYxNDE4WhcNMzcwOTMwMTYxNDE4WjB9 +MQswCQYDVQQGEwJFVTEnMCUGA1UEChMeQUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgy +NzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEgMB4G +A1UEAxMXR2xvYmFsIENoYW1iZXJzaWduIFJvb3QwggEgMA0GCSqGSIb3DQEBAQUA +A4IBDQAwggEIAoIBAQCicKLQn0KuWxfH2H3PFIP8T8mhtxOviteePgQKkotgVvq0 +Mi+ITaFgCPS3CU6gSS9J1tPfnZdan5QEcOw/Wdm3zGaLmFIoCQLfxS+EjXqXd7/s +QJ0lcqu1PzKY+7e3/HKE5TWH+VX6ox8Oby4o3Wmg2UIQxvi1RMLQQ3/bvOSiPGpV +eAp3qdjqGTK3L/5cPxvusZjsyq16aUXjlg9V9ubtdepl6DJWk0aJqCWKZQbua795 +B9Dxt6/tLE2Su8CoX6dnfQTyFQhwrJLWfQTSM/tMtgsL+xrJxI0DqX5c8lCrEqWh +z0hQpe/SyBoT+rB/sYIcd2oPX9wLlY/vQ37mRQklAgEDo4IBUDCCAUwwEgYDVR0T +AQH/BAgwBgEB/wIBDDA/BgNVHR8EODA2MDSgMqAwhi5odHRwOi8vY3JsLmNoYW1i +ZXJzaWduLm9yZy9jaGFtYmVyc2lnbnJvb3QuY3JsMB0GA1UdDgQWBBRDnDafsJ4w +TcbOX60Qq+UDpfqpFDAOBgNVHQ8BAf8EBAMCAQYwEQYJYIZIAYb4QgEBBAQDAgAH +MCoGA1UdEQQjMCGBH2NoYW1iZXJzaWducm9vdEBjaGFtYmVyc2lnbi5vcmcwKgYD +VR0SBCMwIYEfY2hhbWJlcnNpZ25yb290QGNoYW1iZXJzaWduLm9yZzBbBgNVHSAE +VDBSMFAGCysGAQQBgYcuCgEBMEEwPwYIKwYBBQUHAgEWM2h0dHA6Ly9jcHMuY2hh +bWJlcnNpZ24ub3JnL2Nwcy9jaGFtYmVyc2lnbnJvb3QuaHRtbDANBgkqhkiG9w0B +AQUFAAOCAQEAPDtwkfkEVCeR4e3t/mh/YV3lQWVPMvEYBZRqHN4fcNs+ezICNLUM +bKGKfKX0j//U2K0X1S0E0T9YgOKBWYi+wONGkyT+kL0mojAt6JcmVzWJdJYY9hXi +ryQZVgICsroPFOrGimbBhkVVi76SvpykBMdJPJ7oKXqJ1/6v/2j1pReQvayZzKWG +VwlnRtvWFsJG8eSpUPWP0ZIV018+xgBJOm5YstHRJw0lyDL4IBHNfTIzSJRUTN3c +ecQwn+uOuFW114hcxWokPbLTBQNRxgfvzBRydD1ucs4YKIxKoHflCStFREest2d/ +AYoFWpO+ocH/+OcOZ6RHSXZddZAa9SaP8A== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIG0TCCBbmgAwIBAgIBezANBgkqhkiG9w0BAQUFADCByTELMAkGA1UEBhMCSFUx +ETAPBgNVBAcTCEJ1ZGFwZXN0MScwJQYDVQQKEx5OZXRMb2NrIEhhbG96YXRiaXp0 +b25zYWdpIEtmdC4xGjAYBgNVBAsTEVRhbnVzaXR2YW55a2lhZG9rMUIwQAYDVQQD +EzlOZXRMb2NrIE1pbm9zaXRldHQgS296amVneXpvaSAoQ2xhc3MgUUEpIFRhbnVz +aXR2YW55a2lhZG8xHjAcBgkqhkiG9w0BCQEWD2luZm9AbmV0bG9jay5odTAeFw0w +MzAzMzAwMTQ3MTFaFw0yMjEyMTUwMTQ3MTFaMIHJMQswCQYDVQQGEwJIVTERMA8G +A1UEBxMIQnVkYXBlc3QxJzAlBgNVBAoTHk5ldExvY2sgSGFsb3phdGJpenRvbnNh +Z2kgS2Z0LjEaMBgGA1UECxMRVGFudXNpdHZhbnlraWFkb2sxQjBABgNVBAMTOU5l +dExvY2sgTWlub3NpdGV0dCBLb3pqZWd5em9pIChDbGFzcyBRQSkgVGFudXNpdHZh +bnlraWFkbzEeMBwGCSqGSIb3DQEJARYPaW5mb0BuZXRsb2NrLmh1MIIBIjANBgkq +hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx1Ilstg91IRVCacbvWy5FPSKAtt2/Goq +eKvld/Bu4IwjZ9ulZJm53QE+b+8tmjwi8F3JV6BVQX/yQ15YglMxZc4e8ia6AFQe +r7C8HORSjKAyr7c3sVNnaHRnUPYtLmTeriZ539+Zhqurf4XsoPuAzPS4DB6TRWO5 +3Lhbm+1bOdRfYrCnjnxmOCyqsQhjF2d9zL2z8cM/z1A57dEZgxXbhxInlrfa6uWd +vLrqOU+L73Sa58XQ0uqGURzk/mQIKAR5BevKxXEOC++r6uwSEaEYBTJp0QwsGj0l +mT+1fMptsK6ZmfoIYOcZwvK9UdPM0wKswREMgM6r3JSda6M5UzrWhQIDAMV9o4IC +wDCCArwwEgYDVR0TAQH/BAgwBgEB/wIBBDAOBgNVHQ8BAf8EBAMCAQYwggJ1Bglg +hkgBhvhCAQ0EggJmFoICYkZJR1lFTEVNISBFemVuIHRhbnVzaXR2YW55IGEgTmV0 +TG9jayBLZnQuIE1pbm9zaXRldHQgU3pvbGdhbHRhdGFzaSBTemFiYWx5emF0YWJh +biBsZWlydCBlbGphcmFzb2sgYWxhcGphbiBrZXN6dWx0LiBBIG1pbm9zaXRldHQg +ZWxla3Ryb25pa3VzIGFsYWlyYXMgam9naGF0YXMgZXJ2ZW55ZXN1bGVzZW5laywg +dmFsYW1pbnQgZWxmb2dhZGFzYW5hayBmZWx0ZXRlbGUgYSBNaW5vc2l0ZXR0IFN6 +b2xnYWx0YXRhc2kgU3phYmFseXphdGJhbiwgYXogQWx0YWxhbm9zIFN6ZXJ6b2Rl +c2kgRmVsdGV0ZWxla2JlbiBlbG9pcnQgZWxsZW5vcnplc2kgZWxqYXJhcyBtZWd0 +ZXRlbGUuIEEgZG9rdW1lbnR1bW9rIG1lZ3RhbGFsaGF0b2sgYSBodHRwczovL3d3 +dy5uZXRsb2NrLmh1L2RvY3MvIGNpbWVuIHZhZ3kga2VyaGV0b2sgYXogaW5mb0Bu +ZXRsb2NrLm5ldCBlLW1haWwgY2ltZW4uIFdBUk5JTkchIFRoZSBpc3N1YW5jZSBh +bmQgdGhlIHVzZSBvZiB0aGlzIGNlcnRpZmljYXRlIGFyZSBzdWJqZWN0IHRvIHRo +ZSBOZXRMb2NrIFF1YWxpZmllZCBDUFMgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3 +Lm5ldGxvY2suaHUvZG9jcy8gb3IgYnkgZS1tYWlsIGF0IGluZm9AbmV0bG9jay5u +ZXQwHQYDVR0OBBYEFAlqYhaSsFq7VQ7LdTI6MuWyIckoMA0GCSqGSIb3DQEBBQUA +A4IBAQCRalCc23iBmz+LQuM7/KbD7kPgz/PigDVJRXYC4uMvBcXxKufAQTPGtpvQ +MznNwNuhrWw3AkxYQTvyl5LGSKjN5Yo5iWH5Upfpvfb5lHTocQ68d4bDBsxafEp+ +NFAwLvt/MpqNPfMgW/hqyobzMUwsWYACff44yTB1HLdV47yfuqhthCgFdbOLDcCR +VCHnpgu0mfVRQdzNo0ci2ccBgcTcR08m6h/t280NmPSjnLRzMkqWmf68f8glWPhY +83ZmiVSkpj7EUFy6iRiCdUgh0k8T6GB+B3bbELVR5qq5aKrN9p2QdRLqOBrKROi3 +macqaJVmlaut74nLYKkGEsaUR+ko +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIGfTCCBWWgAwIBAgICAQMwDQYJKoZIhvcNAQEEBQAwga8xCzAJBgNVBAYTAkhV +MRAwDgYDVQQIEwdIdW5nYXJ5MREwDwYDVQQHEwhCdWRhcGVzdDEnMCUGA1UEChMe +TmV0TG9jayBIYWxvemF0Yml6dG9uc2FnaSBLZnQuMRowGAYDVQQLExFUYW51c2l0 +dmFueWtpYWRvazE2MDQGA1UEAxMtTmV0TG9jayBLb3pqZWd5em9pIChDbGFzcyBB +KSBUYW51c2l0dmFueWtpYWRvMB4XDTk5MDIyNDIzMTQ0N1oXDTE5MDIxOTIzMTQ0 +N1owga8xCzAJBgNVBAYTAkhVMRAwDgYDVQQIEwdIdW5nYXJ5MREwDwYDVQQHEwhC +dWRhcGVzdDEnMCUGA1UEChMeTmV0TG9jayBIYWxvemF0Yml6dG9uc2FnaSBLZnQu +MRowGAYDVQQLExFUYW51c2l0dmFueWtpYWRvazE2MDQGA1UEAxMtTmV0TG9jayBL +b3pqZWd5em9pIChDbGFzcyBBKSBUYW51c2l0dmFueWtpYWRvMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvHSMD7tM9DceqQWC2ObhbHDqeLVu0ThEDaiD +zl3S1tWBxdRL51uUcCbbO51qTGL3cfNk1mE7PetzozfZz+qMkjvN9wfcZnSX9EUi +3fRc4L9t875lM+QVOr/bmJBVOMTtplVjC7B4BPTjbsE/jvxReB+SnoPC/tmwqcm8 +WgD/qaiYdPv2LD4VOQ22BFWoDpggQrOxJa1+mm9dU7GrDPzr4PN6s6iz/0b2Y6LY +Oph7tqyF/7AlT3Rj5xMHpQqPBffAZG9+pyeAlt7ULoZgx2srXnN7F+eRP2QM2Esi +NCubMvJIH5+hCoR64sKtlz2O1cH5VqNQ6ca0+pii7pXmKgOM3wIDAQABo4ICnzCC +ApswDgYDVR0PAQH/BAQDAgAGMBIGA1UdEwEB/wQIMAYBAf8CAQQwEQYJYIZIAYb4 +QgEBBAQDAgAHMIICYAYJYIZIAYb4QgENBIICURaCAk1GSUdZRUxFTSEgRXplbiB0 +YW51c2l0dmFueSBhIE5ldExvY2sgS2Z0LiBBbHRhbGFub3MgU3pvbGdhbHRhdGFz +aSBGZWx0ZXRlbGVpYmVuIGxlaXJ0IGVsamFyYXNvayBhbGFwamFuIGtlc3p1bHQu +IEEgaGl0ZWxlc2l0ZXMgZm9seWFtYXRhdCBhIE5ldExvY2sgS2Z0LiB0ZXJtZWtm +ZWxlbG9zc2VnLWJpenRvc2l0YXNhIHZlZGkuIEEgZGlnaXRhbGlzIGFsYWlyYXMg +ZWxmb2dhZGFzYW5hayBmZWx0ZXRlbGUgYXogZWxvaXJ0IGVsbGVub3J6ZXNpIGVs +amFyYXMgbWVndGV0ZWxlLiBBeiBlbGphcmFzIGxlaXJhc2EgbWVndGFsYWxoYXRv +IGEgTmV0TG9jayBLZnQuIEludGVybmV0IGhvbmxhcGphbiBhIGh0dHBzOi8vd3d3 +Lm5ldGxvY2submV0L2RvY3MgY2ltZW4gdmFneSBrZXJoZXRvIGF6IGVsbGVub3J6 +ZXNAbmV0bG9jay5uZXQgZS1tYWlsIGNpbWVuLiBJTVBPUlRBTlQhIFRoZSBpc3N1 +YW5jZSBhbmQgdGhlIHVzZSBvZiB0aGlzIGNlcnRpZmljYXRlIGlzIHN1YmplY3Qg +dG8gdGhlIE5ldExvY2sgQ1BTIGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5uZXRs +b2NrLm5ldC9kb2NzIG9yIGJ5IGUtbWFpbCBhdCBjcHNAbmV0bG9jay5uZXQuMA0G +CSqGSIb3DQEBBAUAA4IBAQBIJEb3ulZv+sgoA0BO5TE5ayZrU3/b39/zcT0mwBQO +xmd7I6gMc90Bu8bKbjc5VdXHjFYgDigKDtIqpLBJUsY4B/6+CgmM0ZjPytoUMaFP +0jn8DxEsQ8Pdq5PHVT5HfBgaANzze9jyf1JsIPQLX2lS9O74silg6+NJMSEN1rUQ +QeJBCWziGppWS3cC9qCbmieH6FUpccKQn0V4GuEVZD3QDtigdp+uxdAu6tYPVuxk +f1qbFFgBJ34TUMdrKuZoPL9coAob4Q566eKAw+np9v1sEZ7Q5SgnK1QyQhSCdeZK +8CtmdWOMovsEPoMOmzbwGOQmIMOM8CgHrTwXZoi1/baI +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIFSzCCBLSgAwIBAgIBaTANBgkqhkiG9w0BAQQFADCBmTELMAkGA1UEBhMCSFUx +ETAPBgNVBAcTCEJ1ZGFwZXN0MScwJQYDVQQKEx5OZXRMb2NrIEhhbG96YXRiaXp0 +b25zYWdpIEtmdC4xGjAYBgNVBAsTEVRhbnVzaXR2YW55a2lhZG9rMTIwMAYDVQQD +EylOZXRMb2NrIFV6bGV0aSAoQ2xhc3MgQikgVGFudXNpdHZhbnlraWFkbzAeFw05 +OTAyMjUxNDEwMjJaFw0xOTAyMjAxNDEwMjJaMIGZMQswCQYDVQQGEwJIVTERMA8G +A1UEBxMIQnVkYXBlc3QxJzAlBgNVBAoTHk5ldExvY2sgSGFsb3phdGJpenRvbnNh +Z2kgS2Z0LjEaMBgGA1UECxMRVGFudXNpdHZhbnlraWFkb2sxMjAwBgNVBAMTKU5l +dExvY2sgVXpsZXRpIChDbGFzcyBCKSBUYW51c2l0dmFueWtpYWRvMIGfMA0GCSqG +SIb3DQEBAQUAA4GNADCBiQKBgQCx6gTsIKAjwo84YM/HRrPVG/77uZmeBNwcf4xK +gZjupNTKihe5In+DCnVMm8Bp2GQ5o+2So/1bXHQawEfKOml2mrriRBf8TKPV/riX +iK+IA4kfpPIEPsgHC+b5sy96YhQJRhTKZPWLgLViqNhr1nGTLbO/CVRY7QbrqHvc +Q7GhaQIDAQABo4ICnzCCApswEgYDVR0TAQH/BAgwBgEB/wIBBDAOBgNVHQ8BAf8E +BAMCAAYwEQYJYIZIAYb4QgEBBAQDAgAHMIICYAYJYIZIAYb4QgENBIICURaCAk1G +SUdZRUxFTSEgRXplbiB0YW51c2l0dmFueSBhIE5ldExvY2sgS2Z0LiBBbHRhbGFu +b3MgU3pvbGdhbHRhdGFzaSBGZWx0ZXRlbGVpYmVuIGxlaXJ0IGVsamFyYXNvayBh +bGFwamFuIGtlc3p1bHQuIEEgaGl0ZWxlc2l0ZXMgZm9seWFtYXRhdCBhIE5ldExv +Y2sgS2Z0LiB0ZXJtZWtmZWxlbG9zc2VnLWJpenRvc2l0YXNhIHZlZGkuIEEgZGln +aXRhbGlzIGFsYWlyYXMgZWxmb2dhZGFzYW5hayBmZWx0ZXRlbGUgYXogZWxvaXJ0 +IGVsbGVub3J6ZXNpIGVsamFyYXMgbWVndGV0ZWxlLiBBeiBlbGphcmFzIGxlaXJh +c2EgbWVndGFsYWxoYXRvIGEgTmV0TG9jayBLZnQuIEludGVybmV0IGhvbmxhcGph +biBhIGh0dHBzOi8vd3d3Lm5ldGxvY2submV0L2RvY3MgY2ltZW4gdmFneSBrZXJo +ZXRvIGF6IGVsbGVub3J6ZXNAbmV0bG9jay5uZXQgZS1tYWlsIGNpbWVuLiBJTVBP +UlRBTlQhIFRoZSBpc3N1YW5jZSBhbmQgdGhlIHVzZSBvZiB0aGlzIGNlcnRpZmlj +YXRlIGlzIHN1YmplY3QgdG8gdGhlIE5ldExvY2sgQ1BTIGF2YWlsYWJsZSBhdCBo +dHRwczovL3d3dy5uZXRsb2NrLm5ldC9kb2NzIG9yIGJ5IGUtbWFpbCBhdCBjcHNA +bmV0bG9jay5uZXQuMA0GCSqGSIb3DQEBBAUAA4GBAATbrowXr/gOkDFOzT4JwG06 +sPgzTEdM43WIEJessDgVkcYplswhwG08pXTP2IKlOcNl40JwuyKQ433bNXbhoLXa +n3BukxowOR0w2y7jfLKRstE3Kfq51hdcR0/jHTjrn9V7lagonhVK0dHQKwCXoOKS +NitjrFgBazMpUIaD8QFI +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIFTzCCBLigAwIBAgIBaDANBgkqhkiG9w0BAQQFADCBmzELMAkGA1UEBhMCSFUx +ETAPBgNVBAcTCEJ1ZGFwZXN0MScwJQYDVQQKEx5OZXRMb2NrIEhhbG96YXRiaXp0 +b25zYWdpIEtmdC4xGjAYBgNVBAsTEVRhbnVzaXR2YW55a2lhZG9rMTQwMgYDVQQD +EytOZXRMb2NrIEV4cHJlc3N6IChDbGFzcyBDKSBUYW51c2l0dmFueWtpYWRvMB4X +DTk5MDIyNTE0MDgxMVoXDTE5MDIyMDE0MDgxMVowgZsxCzAJBgNVBAYTAkhVMREw +DwYDVQQHEwhCdWRhcGVzdDEnMCUGA1UEChMeTmV0TG9jayBIYWxvemF0Yml6dG9u +c2FnaSBLZnQuMRowGAYDVQQLExFUYW51c2l0dmFueWtpYWRvazE0MDIGA1UEAxMr +TmV0TG9jayBFeHByZXNzeiAoQ2xhc3MgQykgVGFudXNpdHZhbnlraWFkbzCBnzAN +BgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA6+ywbGGKIyWvYCDj2Z/8kwvbXY2wobNA +OoLO/XXgeDIDhlqGlZHtU/qdQPzm6N3ZW3oDvV3zOwzDUXmbrVWg6dADEK8KuhRC +2VImESLH0iDMgqSaqf64gXadarfSNnU+sYYJ9m5tfk63euyucYT2BDMIJTLrdKwW +RMbkQJMdf60CAwEAAaOCAp8wggKbMBIGA1UdEwEB/wQIMAYBAf8CAQQwDgYDVR0P +AQH/BAQDAgAGMBEGCWCGSAGG+EIBAQQEAwIABzCCAmAGCWCGSAGG+EIBDQSCAlEW +ggJNRklHWUVMRU0hIEV6ZW4gdGFudXNpdHZhbnkgYSBOZXRMb2NrIEtmdC4gQWx0 +YWxhbm9zIFN6b2xnYWx0YXRhc2kgRmVsdGV0ZWxlaWJlbiBsZWlydCBlbGphcmFz +b2sgYWxhcGphbiBrZXN6dWx0LiBBIGhpdGVsZXNpdGVzIGZvbHlhbWF0YXQgYSBO +ZXRMb2NrIEtmdC4gdGVybWVrZmVsZWxvc3NlZy1iaXp0b3NpdGFzYSB2ZWRpLiBB +IGRpZ2l0YWxpcyBhbGFpcmFzIGVsZm9nYWRhc2FuYWsgZmVsdGV0ZWxlIGF6IGVs +b2lydCBlbGxlbm9yemVzaSBlbGphcmFzIG1lZ3RldGVsZS4gQXogZWxqYXJhcyBs +ZWlyYXNhIG1lZ3RhbGFsaGF0byBhIE5ldExvY2sgS2Z0LiBJbnRlcm5ldCBob25s +YXBqYW4gYSBodHRwczovL3d3dy5uZXRsb2NrLm5ldC9kb2NzIGNpbWVuIHZhZ3kg +a2VyaGV0byBheiBlbGxlbm9yemVzQG5ldGxvY2submV0IGUtbWFpbCBjaW1lbi4g +SU1QT1JUQU5UISBUaGUgaXNzdWFuY2UgYW5kIHRoZSB1c2Ugb2YgdGhpcyBjZXJ0 +aWZpY2F0ZSBpcyBzdWJqZWN0IHRvIHRoZSBOZXRMb2NrIENQUyBhdmFpbGFibGUg +YXQgaHR0cHM6Ly93d3cubmV0bG9jay5uZXQvZG9jcyBvciBieSBlLW1haWwgYXQg +Y3BzQG5ldGxvY2submV0LjANBgkqhkiG9w0BAQQFAAOBgQAQrX/XDDKACtiG8XmY +ta3UzbM2xJZIwVzNmtkFLp++UOv0JhQQLdRmF/iewSf98e3ke0ugbLWrmldwpu2g +pO0u9f38vf5NNwgMvOOWgyL1SRt/Syu0VMGAfJlOHdCM7tCs5ZL6dVb+ZKATj7i4 +Fp1hBWeAyNDYpQcCNJgEjTME1A== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCB +gjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEk +MCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRY +UmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQxMTAxMTcx +NDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3 +dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2Vy +dmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB +dXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS6 +38eMpSe2OAtp87ZOqCwuIR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCP +KZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMxfoArtYzAQDsRhtDLooY2YKTVMIJt2W7Q +DxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FEzG+gSqmUsE3a56k0enI4 +qEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqsAxcZZPRa +JSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNVi +PvryxS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0P +BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASs +jVy16bYbMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0 +eS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQEwDQYJKoZIhvcNAQEFBQAD +ggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc/Kh4ZzXxHfAR +vbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt +qZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLa +IR9NmXmd4c8nnxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSy +i6mx5O+aGtA9aZnuqCij4Tyz8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQ +O+7ETPTsJ3xCwnR8gooJybQDJbw= +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh +MB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE +YWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3 +MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRo +ZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3Mg +MiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggEN +ADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCA +PVYYYwhv2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6w +wdhFJ2+qN1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXi +EqITLdiOr18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMY +avx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+ +YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0OBBYEFNLE +sNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h +/t2oatTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5 +IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmlj +YXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD +ggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wimPQoZ+YeAEW5p5JYXMP80kWNy +OO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKtI3lpjbi2Tc7P +TMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ +HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mER +dEr/VxqHD3VILs9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5Cuf +ReYNnyicsbkqWletNw+vHX/bvZ8= +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzEl +MCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMp +U3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQw +NjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBoMQswCQYDVQQGEwJVUzElMCMGA1UE +ChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZp +ZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqGSIb3 +DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf +8MOh2tTYbitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN ++lq2cwQlZut3f+dZxkqZJRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0 +X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVmepsZGD3/cVE8MC5fvj13c7JdBmzDI1aa +K4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSNF4Azbl5KXZnJHoe0nRrA +1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HFMIHCMB0G +A1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fR +zt0fhvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0 +YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBD +bGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8w +DQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGsafPzWdqbAYcaT1epoXkJKtv3 +L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLMPUxA2IGvd56D +eruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl +xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynp +VSJYACPq4xJDKVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEY +WQPJIrSPnNVeKtelttQKbfi3QBFGmh95DmK/D5fs4C8fF5Q= +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIHyTCCBbGgAwIBAgIBATANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJJTDEW +MBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwg +Q2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0NjM2WhcNMzYwOTE3MTk0NjM2WjB9 +MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMi +U2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3Rh +cnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUA +A4ICDwAwggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZk +pMyONvg45iPwbm2xPN1yo4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rf +OQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/C +Ji/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/deMotHweXMAEtcnn6RtYT +Kqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt2PZE4XNi +HzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMM +Av+Z6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w ++2OqqGwaVLRcJXrJosmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+ +Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3 +Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVcUjyJthkqcwEKDwOzEmDyei+B +26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT37uMdBNSSwID +AQABo4ICUjCCAk4wDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAa4wHQYDVR0OBBYE +FE4L7xqkQFulF2mHMMo0aEPQQa7yMGQGA1UdHwRdMFswLKAqoCiGJmh0dHA6Ly9j +ZXJ0LnN0YXJ0Y29tLm9yZy9zZnNjYS1jcmwuY3JsMCugKaAnhiVodHRwOi8vY3Js +LnN0YXJ0Y29tLm9yZy9zZnNjYS1jcmwuY3JsMIIBXQYDVR0gBIIBVDCCAVAwggFM +BgsrBgEEAYG1NwEBATCCATswLwYIKwYBBQUHAgEWI2h0dHA6Ly9jZXJ0LnN0YXJ0 +Y29tLm9yZy9wb2xpY3kucGRmMDUGCCsGAQUFBwIBFilodHRwOi8vY2VydC5zdGFy +dGNvbS5vcmcvaW50ZXJtZWRpYXRlLnBkZjCB0AYIKwYBBQUHAgIwgcMwJxYgU3Rh +cnQgQ29tbWVyY2lhbCAoU3RhcnRDb20pIEx0ZC4wAwIBARqBl0xpbWl0ZWQgTGlh +YmlsaXR5LCByZWFkIHRoZSBzZWN0aW9uICpMZWdhbCBMaW1pdGF0aW9ucyogb2Yg +dGhlIFN0YXJ0Q29tIENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFBvbGljeSBhdmFp +bGFibGUgYXQgaHR0cDovL2NlcnQuc3RhcnRjb20ub3JnL3BvbGljeS5wZGYwEQYJ +YIZIAYb4QgEBBAQDAgAHMDgGCWCGSAGG+EIBDQQrFilTdGFydENvbSBGcmVlIFNT +TCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTANBgkqhkiG9w0BAQUFAAOCAgEAFmyZ +9GYMNPXQhV59CuzaEE44HF7fpiUFS5Eyweg78T3dRAlbB0mKKctmArexmvclmAk8 +jhvh3TaHK0u7aNM5Zj2gJsfyOZEdUauCe37Vzlrk4gNXcGmXCPleWKYK34wGmkUW +FjgKXlf2Ysd6AgXmvB618p70qSmD+LIU424oh0TDkBreOKk8rENNZEXO3SipXPJz +ewT4F+irsfMuXGRuczE6Eri8sxHkfY+BUZo7jYn0TZNmezwD7dOaHZrzZVD1oNB1 +ny+v8OqCQ5j4aZyJecRDjkZy42Q2Eq/3JR44iZB3fsNrarnDy0RLrHiQi+fHLB5L +EUTINFInzQpdn4XBidUaePKVEFMy3YCEZnXZtWgo+2EuvoSoOMCZEoalHmdkrQYu +L6lwhceWD3yJZfWOQ1QOq92lgDmUYMA0yZZwLKMS9R9Ie70cfmu3nZD0Ijuu+Pwq +yvqCUqDvr0tVk+vBtfAii6w0TiYiBKGHLHVKt+V9E9e4DGTANtLJL4YSjCMJwRuC +O3NJo2pXh5Tl1njFmUNj403gdy3hZZlyaQQaRwnmDwFWJPsfvw55qVguucQJAX6V +um0ABj6y6koQOdjQK/W/7HW/lwLFCRsI3FU34oH7N4RDYiDK51ZLZer+bMEkkySh +NOsF/5oirpt9P/FlUQqmMGqz9IgcgA38corog14= +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCB +yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL +ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp +U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW +ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0 +aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCByjEL +MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW +ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2ln +biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp +U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y +aXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvJAgIKXo1 +nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKzj/i5Vbex +t0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIz +SdhDY2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQG +BO+QueQA5N06tRn/Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+ +rCpSx4/VBEnkjWNHiDxpg8v+R70rfk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/ +NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8E +BAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEwHzAH +BgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy +aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKv +MzEzMA0GCSqGSIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzE +p6B4Eq1iDkVwZMXnl2YtmAl+X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y +5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKEKQsTb47bDN0lAtukixlE0kF6BWlK +WE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiCKm0oHw0LxOXnGiYZ +4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vEZV8N +hnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBl +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv +b3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzExMTEwMDAwMDAwWjBlMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl +cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7c +JpSIqvTO9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYP +mDI2dsze3Tyoou9q+yHyUmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+ +wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4 +VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpyoeb6pNnVFzF1roV9Iq4/ +AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whfGHdPAgMB +AAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW +BBRF66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYun +pyGd823IDzANBgkqhkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRC +dWKuh+vy1dneVrOfzM4UKLkNl2BcEkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTf +fwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38FnSbNd67IJKusm7Xi+fT8r87cm +NW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i8b5QZ7dsvfPx +H2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe ++o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD +QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j +b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB +CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97 +nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt +43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P +T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4 +gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO +BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR +TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw +DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr +hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg +06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF +PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls +YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk +CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4= +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j +ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL +MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3 +LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug +RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm ++9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW +PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM +xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB +Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3 +hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg +EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF +MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA +FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec +nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z +eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF +hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2 +Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe +vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep ++OkuE6N36B9K +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIH0zCCBbugAwIBAgIIXsO3pkN/pOAwDQYJKoZIhvcNAQEFBQAwQjESMBAGA1UE +AwwJQUNDVlJBSVoxMRAwDgYDVQQLDAdQS0lBQ0NWMQ0wCwYDVQQKDARBQ0NWMQsw +CQYDVQQGEwJFUzAeFw0xMTA1MDUwOTM3MzdaFw0zMDEyMzEwOTM3MzdaMEIxEjAQ +BgNVBAMMCUFDQ1ZSQUlaMTEQMA4GA1UECwwHUEtJQUNDVjENMAsGA1UECgwEQUND +VjELMAkGA1UEBhMCRVMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCb +qau/YUqXry+XZpp0X9DZlv3P4uRm7x8fRzPCRKPfmt4ftVTdFXxpNRFvu8gMjmoY +HtiP2Ra8EEg2XPBjs5BaXCQ316PWywlxufEBcoSwfdtNgM3802/J+Nq2DoLSRYWo +G2ioPej0RGy9ocLLA76MPhMAhN9KSMDjIgro6TenGEyxCQ0jVn8ETdkXhBilyNpA +lHPrzg5XPAOBOp0KoVdDaaxXbXmQeOW1tDvYvEyNKKGno6e6Ak4l0Squ7a4DIrhr +IA8wKFSVf+DuzgpmndFALW4ir50awQUZ0m/A8p/4e7MCQvtQqR0tkw8jq8bBD5L/ +0KIV9VMJcRz/RROE5iZe+OCIHAr8Fraocwa48GOEAqDGWuzndN9wrqODJerWx5eH +k6fGioozl2A3ED6XPm4pFdahD9GILBKfb6qkxkLrQaLjlUPTAYVtjrs78yM2x/47 +4KElB0iryYl0/wiPgL/AlmXz7uxLaL2diMMxs0Dx6M/2OLuc5NF/1OVYm3z61PMO +m3WR5LpSLhl+0fXNWhn8ugb2+1KoS5kE3fj5tItQo05iifCHJPqDQsGH+tUtKSpa +cXpkatcnYGMN285J9Y0fkIkyF/hzQ7jSWpOGYdbhdQrqeWZ2iE9x6wQl1gpaepPl +uUsXQA+xtrn13k/c4LOsOxFwYIRKQ26ZIMApcQrAZQIDAQABo4ICyzCCAscwfQYI +KwYBBQUHAQEEcTBvMEwGCCsGAQUFBzAChkBodHRwOi8vd3d3LmFjY3YuZXMvZmls +ZWFkbWluL0FyY2hpdm9zL2NlcnRpZmljYWRvcy9yYWl6YWNjdjEuY3J0MB8GCCsG +AQUFBzABhhNodHRwOi8vb2NzcC5hY2N2LmVzMB0GA1UdDgQWBBTSh7Tj3zcnk1X2 +VuqB5TbMjB4/vTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNKHtOPfNyeT +VfZW6oHlNsyMHj+9MIIBcwYDVR0gBIIBajCCAWYwggFiBgRVHSAAMIIBWDCCASIG +CCsGAQUFBwICMIIBFB6CARAAQQB1AHQAbwByAGkAZABhAGQAIABkAGUAIABDAGUA +cgB0AGkAZgBpAGMAYQBjAGkA8wBuACAAUgBhAO0AegAgAGQAZQAgAGwAYQAgAEEA +QwBDAFYAIAAoAEEAZwBlAG4AYwBpAGEAIABkAGUAIABUAGUAYwBuAG8AbABvAGcA +7QBhACAAeQAgAEMAZQByAHQAaQBmAGkAYwBhAGMAaQDzAG4AIABFAGwAZQBjAHQA +cgDzAG4AaQBjAGEALAAgAEMASQBGACAAUQA0ADYAMAAxADEANQA2AEUAKQAuACAA +QwBQAFMAIABlAG4AIABoAHQAdABwADoALwAvAHcAdwB3AC4AYQBjAGMAdgAuAGUA +czAwBggrBgEFBQcCARYkaHR0cDovL3d3dy5hY2N2LmVzL2xlZ2lzbGFjaW9uX2Mu +aHRtMFUGA1UdHwROMEwwSqBIoEaGRGh0dHA6Ly93d3cuYWNjdi5lcy9maWxlYWRt +aW4vQXJjaGl2b3MvY2VydGlmaWNhZG9zL3JhaXphY2N2MV9kZXIuY3JsMA4GA1Ud +DwEB/wQEAwIBBjAXBgNVHREEEDAOgQxhY2N2QGFjY3YuZXMwDQYJKoZIhvcNAQEF +BQADggIBAJcxAp/n/UNnSEQU5CmH7UwoZtCPNdpNYbdKl02125DgBS4OxnnQ8pdp +D70ER9m+27Up2pvZrqmZ1dM8MJP1jaGo/AaNRPTKFpV8M9xii6g3+CfYCS0b78gU +JyCpZET/LtZ1qmxNYEAZSUNUY9rizLpm5U9EelvZaoErQNV/+QEnWCzI7UiRfD+m +AM/EKXMRNt6GGT6d7hmKG9Ww7Y49nCrADdg9ZuM8Db3VlFzi4qc1GwQA9j9ajepD +vV+JHanBsMyZ4k0ACtrJJ1vnE5Bc5PUzolVt3OAJTS+xJlsndQAJxGJ3KQhfnlms +tn6tn1QwIgPBHnFk/vk4CpYY3QIUrCPLBhwepH2NDd4nQeit2hW3sCPdK6jT2iWH +7ehVRE2I9DZ+hJp4rPcOVkkO1jMl1oRQQmwgEh0q1b688nCBpHBgvgW1m54ERL5h +I6zppSSMEYCUWqKiuUnSwdzRp+0xESyeGabu4VXhwOrPDYTkF7eifKXeVSUG7szA +h1xA2syVP1XgNce4hL60Xc16gwFy7ofmXx2utYXGJt/mwZrpHgJHnyqobalbz+xF +d3+YJ5oyXSrjhO7FmGYvliAd3djDJ9ew+f7Zfc3Qn48LFFhRny+Lwzgt3uiP1o2H +pPVWQxaZLPSkVrQ0uGE3ycJYgBugl6H8WY3pEfbRD0tVNEYqi4Y7 +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIFtTCCA52gAwIBAgIIYY3HhjsBggUwDQYJKoZIhvcNAQEFBQAwRDEWMBQGA1UE +AwwNQUNFRElDT00gUm9vdDEMMAoGA1UECwwDUEtJMQ8wDQYDVQQKDAZFRElDT00x +CzAJBgNVBAYTAkVTMB4XDTA4MDQxODE2MjQyMloXDTI4MDQxMzE2MjQyMlowRDEW +MBQGA1UEAwwNQUNFRElDT00gUm9vdDEMMAoGA1UECwwDUEtJMQ8wDQYDVQQKDAZF +RElDT00xCzAJBgNVBAYTAkVTMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKC +AgEA/5KV4WgGdrQsyFhIyv2AVClVYyT/kGWbEHV7w2rbYgIB8hiGtXxaOLHkWLn7 +09gtn70yN78sFW2+tfQh0hOR2QetAQXW8713zl9CgQr5auODAKgrLlUTY4HKRxx7 +XBZXehuDYAQ6PmXDzQHe3qTWDLqO3tkE7hdWIpuPY/1NFgu3e3eM+SW10W2ZEi5P +Grjm6gSSrj0RuVFCPYewMYWveVqc/udOXpJPQ/yrOq2lEiZmueIM15jO1FillUAK +t0SdE3QrwqXrIhWYENiLxQSfHY9g5QYbm8+5eaA9oiM/Qj9r+hwDezCNzmzAv+Yb +X79nuIQZ1RXve8uQNjFiybwCq0Zfm/4aaJQ0PZCOrfbkHQl/Sog4P75n/TSW9R28 +MHTLOO7VbKvU/PQAtwBbhTIWdjPp2KOZnQUAqhbm84F9b32qhm2tFXTTxKJxqvQU +fecyuB+81fFOvW8XAjnXDpVCOscAPukmYxHqC9FK/xidstd7LzrZlvvoHpKuE1XI +2Sf23EgbsCTBheN3nZqk8wwRHQ3ItBTutYJXCb8gWH8vIiPYcMt5bMlL8qkqyPyH +K9caUPgn6C9D4zq92Fdx/c6mUlv53U3t5fZvie27k5x2IXXwkkwp9y+cAS7+UEae +ZAwUswdbxcJzbPEHXEUkFDWug/FqTYl6+rPYLWbwNof1K1MCAwEAAaOBqjCBpzAP +BgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKaz4SsrSbbXc6GqlPUB53NlTKxQ +MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUprPhKytJttdzoaqU9QHnc2VMrFAw +RAYDVR0gBD0wOzA5BgRVHSAAMDEwLwYIKwYBBQUHAgEWI2h0dHA6Ly9hY2VkaWNv +bS5lZGljb21ncm91cC5jb20vZG9jMA0GCSqGSIb3DQEBBQUAA4ICAQDOLAtSUWIm +fQwng4/F9tqgaHtPkl7qpHMyEVNEskTLnewPeUKzEKbHDZ3Ltvo/Onzqv4hTGzz3 +gvoFNTPhNahXwOf9jU8/kzJPeGYDdwdY6ZXIfj7QeQCM8htRM5u8lOk6e25SLTKe +I6RF+7YuE7CLGLHdztUdp0J/Vb77W7tH1PwkzQSulgUV1qzOMPPKC8W64iLgpq0i +5ALudBF/TP94HTXa5gI06xgSYXcGCRZj6hitoocf8seACQl1ThCojz2GuHURwCRi +ipZ7SkXp7FnFvmuD5uHorLUwHv4FB4D54SMNUI8FmP8sX+g7tq3PgbUhh8oIKiMn +MCArz+2UW6yyetLHKKGKC5tNSixthT8Jcjxn4tncB7rrZXtaAWPWkFtPF2Y9fwsZ +o5NjEFIqnxQWWOLcpfShFosOkYuByptZ+thrkQdlVV9SH686+5DdaaVbnG0OLLb6 +zqylfDJKZ0DcMDQj3dcEI2bw/FWAp/tmGYI1Z2JwOV5vx+qQQEQIHriy1tvuWacN +GHk0vFQYXlPKNFHtRQrmjseCNj6nOGOpMCwXEGCSn1WHElkQwg9naRHMTh5+Spqt +r0CodaxWkHS4oJyleW/c6RrIaQXpuvoDs3zk4E7Czp3otkYNbn5XOmeUwssfnHdK +Z05phkOTOPu220+DkdRgfks+KzgHVZhepA== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIGZjCCBE6gAwIBAgIPB35Sk3vgFeNX8GmMy+wMMA0GCSqGSIb3DQEBBQUAMHsx +CzAJBgNVBAYTAkNPMUcwRQYDVQQKDD5Tb2NpZWRhZCBDYW1lcmFsIGRlIENlcnRp +ZmljYWNpw7NuIERpZ2l0YWwgLSBDZXJ0aWPDoW1hcmEgUy5BLjEjMCEGA1UEAwwa +QUMgUmHDrXogQ2VydGljw6FtYXJhIFMuQS4wHhcNMDYxMTI3MjA0NjI5WhcNMzAw +NDAyMjE0MjAyWjB7MQswCQYDVQQGEwJDTzFHMEUGA1UECgw+U29jaWVkYWQgQ2Ft +ZXJhbCBkZSBDZXJ0aWZpY2FjacOzbiBEaWdpdGFsIC0gQ2VydGljw6FtYXJhIFMu +QS4xIzAhBgNVBAMMGkFDIFJhw616IENlcnRpY8OhbWFyYSBTLkEuMIICIjANBgkq +hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAq2uJo1PMSCMI+8PPUZYILrgIem08kBeG +qentLhM0R7LQcNzJPNCNyu5LF6vQhbCnIwTLqKL85XXbQMpiiY9QngE9JlsYhBzL +fDe3fezTf3MZsGqy2IiKLUV0qPezuMDU2s0iiXRNWhU5cxh0T7XrmafBHoi0wpOQ +Y5fzp6cSsgkiBzPZkc0OnB8OIMfuuzONj8LSWKdf/WU34ojC2I+GdV75LaeHM/J4 +Ny+LvB2GNzmxlPLYvEqcgxhaBvzz1NS6jBUJJfD5to0EfhcSM2tXSExP2yYe68yQ +54v5aHxwD6Mq0Do43zeX4lvegGHTgNiRg0JaTASJaBE8rF9ogEHMYELODVoqDA+b +MMCm8Ibbq0nXl21Ii/kDwFJnmxL3wvIumGVC2daa49AZMQyth9VXAnow6IYm+48j +ilSH5L887uvDdUhfHjlvgWJsxS3EF1QZtzeNnDeRyPYL1epjb4OsOMLzP96a++Ej +YfDIJss2yKHzMI+ko6Kh3VOz3vCaMh+DkXkwwakfU5tTohVTP92dsxA7SH2JD/zt +A/X7JWR1DhcZDY8AFmd5ekD8LVkH2ZD6mq093ICK5lw1omdMEWux+IBkAC1vImHF +rEsm5VoQgpukg3s0956JkSCXjrdCx2bD0Omk1vUgjcTDlaxECp1bczwmPS9KvqfJ +pxAe+59QafMCAwEAAaOB5jCB4zAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQE +AwIBBjAdBgNVHQ4EFgQU0QnQ6dfOeXRU+Tows/RtLAMDG2gwgaAGA1UdIASBmDCB +lTCBkgYEVR0gADCBiTArBggrBgEFBQcCARYfaHR0cDovL3d3dy5jZXJ0aWNhbWFy +YS5jb20vZHBjLzBaBggrBgEFBQcCAjBOGkxMaW1pdGFjaW9uZXMgZGUgZ2FyYW50 +7WFzIGRlIGVzdGUgY2VydGlmaWNhZG8gc2UgcHVlZGVuIGVuY29udHJhciBlbiBs +YSBEUEMuMA0GCSqGSIb3DQEBBQUAA4ICAQBclLW4RZFNjmEfAygPU3zmpFmps4p6 +xbD/CHwso3EcIRNnoZUSQDWDg4902zNc8El2CoFS3UnUmjIz75uny3XlesuXEpBc +unvFm9+7OSPI/5jOCk0iAUgHforA1SBClETvv3eiiWdIG0ADBaGJ7M9i4z0ldma/ +Jre7Ir5v/zlXdLp6yQGVwZVR6Kss+LGGIOk/yzVb0hfpKv6DExdA7ohiZVvVO2Dp +ezy4ydV/NgIlqmjCMRW3MGXrfx1IebHPOeJCgBbT9ZMj/EyXyVo3bHwi2ErN0o42 +gzmRkBDI8ck1fj+404HGIGQatlDCIaR43NAvO2STdPCWkPHv+wlaNECW8DYSwaN0 +jJN+Qd53i+yG2dIPPy3RzECiiWZIHiCznCNZc6lEc7wkeZBWN7PGKX6jD/EpOe9+ +XCgycDWs2rjIdWb8m0w5R44bb5tNAlQiM+9hup4phO9OSzNHdpdqy35f/RWmnkJD +W2ZaiogN9xa5P1FlK2Zqi9E4UqLWRhH6/JocdJ6PlwsCT2TG9WjTSy3/pDceiz+/ +RL5hRqGEPQgnTIEgd4kI6mdAXmwIUV80WoyWaM3X94nCHNMyAK9Sy9NgWyo6R35r +MDOhYil/SrnhLecUIw4OGEfhefwVVdCx/CVxY3UzHCMrr1zZ7Ud3YA47Dx7SwNxk +BYn8eNZcLCZDqQ== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIFuzCCA6OgAwIBAgIIVwoRl0LE48wwDQYJKoZIhvcNAQELBQAwazELMAkGA1UE +BhMCSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8w +MzM1ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290 +IENBMB4XDTExMDkyMjExMjIwMloXDTMwMDkyMjExMjIwMlowazELMAkGA1UEBhMC +SVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8wMzM1 +ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290IENB +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAp8bEpSmkLO/lGMWwUKNv +UTufClrJwkg4CsIcoBh/kbWHuUA/3R1oHwiD1S0eiKD4j1aPbZkCkpAW1V8IbInX +4ay8IMKx4INRimlNAJZaby/ARH6jDuSRzVju3PvHHkVH3Se5CAGfpiEd9UEtL0z9 +KK3giq0itFZljoZUj5NDKd45RnijMCO6zfB9E1fAXdKDa0hMxKufgFpbOr3JpyI/ +gCczWw63igxdBzcIy2zSekciRDXFzMwujt0q7bd9Zg1fYVEiVRvjRuPjPdA1Yprb +rxTIW6HMiRvhMCb8oJsfgadHHwTrozmSBp+Z07/T6k9QnBn+locePGX2oxgkg4YQ +51Q+qDp2JE+BIcXjDwL4k5RHILv+1A7TaLndxHqEguNTVHnd25zS8gebLra8Pu2F +be8lEfKXGkJh90qX6IuxEAf6ZYGyojnP9zz/GPvG8VqLWeICrHuS0E4UT1lF9gxe +KF+w6D9Fz8+vm2/7hNN3WpVvrJSEnu68wEqPSpP4RCHiMUVhUE4Q2OM1fEwZtN4F +v6MGn8i1zeQf1xcGDXqVdFUNaBr8EBtiZJ1t4JWgw5QHVw0U5r0F+7if5t+L4sbn +fpb2U8WANFAoWPASUHEXMLrmeGO89LKtmyuy/uE5jF66CyCU3nuDuP/jVo23Eek7 +jPKxwV2dpAtMK9myGPW1n0sCAwEAAaNjMGEwHQYDVR0OBBYEFFLYiDrIn3hm7Ynz +ezhwlMkCAjbQMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUUtiIOsifeGbt +ifN7OHCUyQICNtAwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQAL +e3KHwGCmSUyIWOYdiPcUZEim2FgKDk8TNd81HdTtBjHIgT5q1d07GjLukD0R0i70 +jsNjLiNmsGe+b7bAEzlgqqI0JZN1Ut6nna0Oh4lScWoWPBkdg/iaKWW+9D+a2fDz +WochcYBNy+A4mz+7+uAwTc+G02UQGRjRlwKxK3JCaKygvU5a2hi/a5iB0P2avl4V +SM0RFbnAKVy06Ij3Pjaut2L9HmLecHgQHEhb2rykOLpn7VU+Xlff1ANATIGk0k9j +pwlCCRT8AKnCgHNPLsBA2RF7SOp6AsDT6ygBJlh0wcBzIm2Tlf05fbsq4/aC4yyX +X04fkZT6/iyj2HYauE2yOE+b+h1IYHkm4vP9qdCa6HCPSXrW5b0KDtst842/6+Ok +fcvHlXHo2qN8xcL4dJIEG4aspCJTQLas/kx2z/uUMsA1n3Y/buWQbqCmJqK4LL7R +K4X9p2jIugErsWx0Hbhzlefut8cl8ABMALJ+tguLHPPAUJ4lueAI3jZm/zel0btU +ZCzJJ7VLkn5l/9Mt4blOvH+kQSGQQXemOR/qnuOf0GZvBeyqdn6/axag67XH/JJU +LysRJyU3eExRarDzzFhdFPFqSBX/wge2sY0PjlxQRrM9vwGYT7JZVEc+NHt4bVaT +LnPqZih4zR0Uv6CPLy64Lo7yFIrM6bV8+2ydDKXhlg== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIDTDCCAjSgAwIBAgIId3cGJyapsXwwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UE +BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz +dCBDb21tZXJjaWFsMB4XDTEwMDEyOTE0MDYwNloXDTMwMTIzMTE0MDYwNlowRDEL +MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp +cm1UcnVzdCBDb21tZXJjaWFsMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEA9htPZwcroRX1BiLLHwGy43NFBkRJLLtJJRTWzsO3qyxPxkEylFf6EqdbDuKP +Hx6GGaeqtS25Xw2Kwq+FNXkyLbscYjfysVtKPcrNcV/pQr6U6Mje+SJIZMblq8Yr +ba0F8PrVC8+a5fBQpIs7R6UjW3p6+DM/uO+Zl+MgwdYoic+U+7lF7eNAFxHUdPAL +MeIrJmqbTFeurCA+ukV6BfO9m2kVrn1OIGPENXY6BwLJN/3HR+7o8XYdcxXyl6S1 +yHp52UKqK39c/s4mT6NmgTWvRLpUHhwwMmWd5jyTXlBOeuM61G7MGvv50jeuJCqr +VwMiKA1JdX+3KNp1v47j3A55MQIDAQABo0IwQDAdBgNVHQ4EFgQUnZPGU4teyq8/ +nx4P5ZmVvCT2lI8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ +KoZIhvcNAQELBQADggEBAFis9AQOzcAN/wr91LoWXym9e2iZWEnStB03TX8nfUYG +XUPGhi4+c7ImfU+TqbbEKpqrIZcUsd6M06uJFdhrJNTxFq7YpFzUf1GO7RgBsZNj +vbz4YYCanrHOQnDiqX0GJX0nof5v7LMeJNrjS1UaADs1tDvZ110w/YETifLCBivt +Z8SOyUOyXGsViQK8YvxO8rUzqrJv0wqiUOP2O+guRMLbZjipM1ZI8W0bM40NjD9g +N53Tym1+NH4Nn3J2ixufcv1SNUFFApYvHLKac0khsUlHRUe072o0EclNmsxZt9YC +nlpOZbWUrhvfKbAW8b8Angc6F2S1BLUjIZkKlTuXfO8= +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIDTDCCAjSgAwIBAgIIfE8EORzUmS0wDQYJKoZIhvcNAQEFBQAwRDELMAkGA1UE +BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz +dCBOZXR3b3JraW5nMB4XDTEwMDEyOTE0MDgyNFoXDTMwMTIzMTE0MDgyNFowRDEL +MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp +cm1UcnVzdCBOZXR3b3JraW5nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEAtITMMxcua5Rsa2FSoOujz3mUTOWUgJnLVWREZY9nZOIG41w3SfYvm4SEHi3y +YJ0wTsyEheIszx6e/jarM3c1RNg1lho9Nuh6DtjVR6FqaYvZ/Ls6rnla1fTWcbua +kCNrmreIdIcMHl+5ni36q1Mr3Lt2PpNMCAiMHqIjHNRqrSK6mQEubWXLviRmVSRL +QESxG9fhwoXA3hA/Pe24/PHxI1Pcv2WXb9n5QHGNfb2V1M6+oF4nI979ptAmDgAp +6zxG8D1gvz9Q0twmQVGeFDdCBKNwV6gbh+0t+nvujArjqWaJGctB+d1ENmHP4ndG +yH329JKBNv3bNPFyfvMMFr20FQIDAQABo0IwQDAdBgNVHQ4EFgQUBx/S55zawm6i +QLSwelAQUHTEyL0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ +KoZIhvcNAQEFBQADggEBAIlXshZ6qML91tmbmzTCnLQyFE2npN/svqe++EPbkTfO +tDIuUFUaNU52Q3Eg75N3ThVwLofDwR1t3Mu1J9QsVtFSUzpE0nPIxBsFZVpikpzu +QY0x2+c06lkh1QF612S4ZDnNye2v7UsDSKegmQGA3GWjNq5lWUhPgkvIZfFXHeVZ +Lgo/bNjR9eUJtGxUAArgFU2HdW23WJZa3W3SAKD0m0i+wzekujbgfIeFlxoVot4u +olu9rxj5kFDNcFn4J2dHy8egBzp90SxdbBk6ZrV9/ZFvgrG+CJPbFEfxojfHRZ48 +x3evZKiT3/Zpg4Jg8klCNO1aAFSFHBY2kgxc+qatv9s= +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIFRjCCAy6gAwIBAgIIbYwURrGmCu4wDQYJKoZIhvcNAQEMBQAwQTELMAkGA1UE +BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVz +dCBQcmVtaXVtMB4XDTEwMDEyOTE0MTAzNloXDTQwMTIzMTE0MTAzNlowQTELMAkG +A1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1U +cnVzdCBQcmVtaXVtMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxBLf +qV/+Qd3d9Z+K4/as4Tx4mrzY8H96oDMq3I0gW64tb+eT2TZwamjPjlGjhVtnBKAQ +JG9dKILBl1fYSCkTtuG+kU3fhQxTGJoeJKJPj/CihQvL9Cl/0qRY7iZNyaqoe5rZ ++jjeRFcV5fiMyNlI4g0WJx0eyIOFJbe6qlVBzAMiSy2RjYvmia9mx+n/K+k8rNrS +s8PhaJyJ+HoAVt70VZVs+7pk3WKL3wt3MutizCaam7uqYoNMtAZ6MMgpv+0GTZe5 +HMQxK9VfvFMSF5yZVylmd2EhMQcuJUmdGPLu8ytxjLW6OQdJd/zvLpKQBY0tL3d7 +70O/Nbua2Plzpyzy0FfuKE4mX4+QaAkvuPjcBukumj5Rp9EixAqnOEhss/n/fauG +V+O61oV4d7pD6kh/9ti+I20ev9E2bFhc8e6kGVQa9QPSdubhjL08s9NIS+LI+H+S +qHZGnEJlPqQewQcDWkYtuJfzt9WyVSHvutxMAJf7FJUnM7/oQ0dG0giZFmA7mn7S +5u046uwBHjxIVkkJx0w3AJ6IDsBz4W9m6XJHMD4Q5QsDyZpCAGzFlH5hxIrff4Ia +C1nEWTJ3s7xgaVY5/bQGeyzWZDbZvUjthB9+pSKPKrhC9IK31FOQeE4tGv2Bb0TX +OwF0lkLgAOIua+rF7nKsu7/+6qqo+Nz2snmKtmcCAwEAAaNCMEAwHQYDVR0OBBYE +FJ3AZ6YMItkm9UWrpmVSESfYRaxjMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/ +BAQDAgEGMA0GCSqGSIb3DQEBDAUAA4ICAQCzV00QYk465KzquByvMiPIs0laUZx2 +KI15qldGF9X1Uva3ROgIRL8YhNILgM3FEv0AVQVhh0HctSSePMTYyPtwni94loMg +Nt58D2kTiKV1NpgIpsbfrM7jWNa3Pt668+s0QNiigfV4Py/VpfzZotReBA4Xrf5B +8OWycvpEgjNC6C1Y91aMYj+6QrCcDFx+LmUmXFNPALJ4fqENmS2NuB2OosSw/WDQ +MKSOyARiqcTtNd56l+0OOF6SL5Nwpamcb6d9Ex1+xghIsV5n61EIJenmJWtSKZGc +0jlzCFfemQa0W50QBuHCAKi4HEoCChTQwUHK+4w1IX2COPKpVJEZNZOUbWo6xbLQ +u4mGk+ibyQ86p3q4ofB4Rvr8Ny/lioTz3/4E2aFooC8k4gmVBtWVyuEklut89pMF +u+1z6S3RdTnX5yTb2E5fQ4+e0BQ5v1VwSJlXMbSc7kqYA5YwH2AG7hsj/oFgIxpH +YoWlzBk0gG+zrBrjn/B7SK3VAdlntqlyk+otZrWyuOQ9PLLvTIzq6we/qzWaVYa8 +GKa1qF60g2xraUDTn9zxw2lrueFtCfTxqlB2Cnp9ehehVZZCmTEJ3WARjQUwfuaO +RtGdFNrHF+QFlozEJLUbzxQHskD4o55BhrwE0GuWyCqANP2/7waj3VjFhT0+j/6e +KeC2uAloGRwYQw== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIB/jCCAYWgAwIBAgIIdJclisc/elQwCgYIKoZIzj0EAwMwRTELMAkGA1UEBhMC +VVMxFDASBgNVBAoMC0FmZmlybVRydXN0MSAwHgYDVQQDDBdBZmZpcm1UcnVzdCBQ +cmVtaXVtIEVDQzAeFw0xMDAxMjkxNDIwMjRaFw00MDEyMzExNDIwMjRaMEUxCzAJ +BgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1UcnVzdDEgMB4GA1UEAwwXQWZmaXJt +VHJ1c3QgUHJlbWl1bSBFQ0MwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQNMF4bFZ0D +0KF5Nbc6PJJ6yhUczWLznCZcBz3lVPqj1swS6vQUX+iOGasvLkjmrBhDeKzQN8O9 +ss0s5kfiGuZjuD0uL3jET9v0D6RoTFVya5UdThhClXjMNzyR4ptlKymjQjBAMB0G +A1UdDgQWBBSaryl6wBE1NSZRMADDav5A1a7WPDAPBgNVHRMBAf8EBTADAQH/MA4G +A1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNnADBkAjAXCfOHiFBar8jAQr9HX/Vs +aobgxCd05DhT1wV/GzTjxi+zygk8N53X57hG8f2h4nECMEJZh0PUUd+60wkyWs6I +flc9nF9Ca/UHLbXwgpP5WW+uZPpY5Yse42O+tYHNbwKMeQ== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIDoDCCAoigAwIBAgIBMTANBgkqhkiG9w0BAQUFADBDMQswCQYDVQQGEwJKUDEc +MBoGA1UEChMTSmFwYW5lc2UgR292ZXJubWVudDEWMBQGA1UECxMNQXBwbGljYXRp +b25DQTAeFw0wNzEyMTIxNTAwMDBaFw0xNzEyMTIxNTAwMDBaMEMxCzAJBgNVBAYT +AkpQMRwwGgYDVQQKExNKYXBhbmVzZSBHb3Zlcm5tZW50MRYwFAYDVQQLEw1BcHBs +aWNhdGlvbkNBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAp23gdE6H +j6UG3mii24aZS2QNcfAKBZuOquHMLtJqO8F6tJdhjYq+xpqcBrSGUeQ3DnR4fl+K +f5Sk10cI/VBaVuRorChzoHvpfxiSQE8tnfWuREhzNgaeZCw7NCPbXCbkcXmP1G55 +IrmTwcrNwVbtiGrXoDkhBFcsovW8R0FPXjQilbUfKW1eSvNNcr5BViCH/OlQR9cw +FO5cjFW6WY2H/CPek9AEjP3vbb3QesmlOmpyM8ZKDQUXKi17safY1vC+9D/qDiht +QWEjdnjDuGWk81quzMKq2edY3rZ+nYVunyoKb58DKTCXKB28t89UKU5RMfkntigm +/qJj5kEW8DOYRwIDAQABo4GeMIGbMB0GA1UdDgQWBBRUWssmP3HMlEYNllPqa0jQ +k/5CdTAOBgNVHQ8BAf8EBAMCAQYwWQYDVR0RBFIwUKROMEwxCzAJBgNVBAYTAkpQ +MRgwFgYDVQQKDA/ml6XmnKzlm73mlL/lupwxIzAhBgNVBAsMGuOCouODl+ODquOC +seODvOOCt+ODp+ODs0NBMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD +ggEBADlqRHZ3ODrso2dGD/mLBqj7apAxzn7s2tGJfHrrLgy9mTLnsCTWw//1sogJ +hyzjVOGjprIIC8CFqMjSnHH2HZ9g/DgzE+Ge3Atf2hZQKXsvcJEPmbo0NI2VdMV+ +eKlmXb3KIXdCEKxmJj3ekav9FfBv7WxfEPjzFvYDio+nEhEMy/0/ecGc/WLuo89U +DNErXxc+4z6/wCs+CZv+iKZ+tJIX/COUgb1up8WMwusRRdv4QcmWdupwX3kSa+Sj +B1oF7ydJzyGfikwJcGapJsErEU4z0g781mzSDjJkaP+tBXhfAx2o45CsJOAPQKdL +rosot4LKGAfmt1t06SAZf7IbiVQ= +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIIXDPLYixfszIwDQYJKoZIhvcNAQELBQAwPDEeMBwGA1UE +AwwVQXRvcyBUcnVzdGVkUm9vdCAyMDExMQ0wCwYDVQQKDARBdG9zMQswCQYDVQQG +EwJERTAeFw0xMTA3MDcxNDU4MzBaFw0zMDEyMzEyMzU5NTlaMDwxHjAcBgNVBAMM +FUF0b3MgVHJ1c3RlZFJvb3QgMjAxMTENMAsGA1UECgwEQXRvczELMAkGA1UEBhMC +REUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCVhTuXbyo7LjvPpvMp +Nb7PGKw+qtn4TaA+Gke5vJrf8v7MPkfoepbCJI419KkM/IL9bcFyYie96mvr54rM +VD6QUM+A1JX76LWC1BTFtqlVJVfbsVD2sGBkWXppzwO3bw2+yj5vdHLqqjAqc2K+ +SZFhyBH+DgMq92og3AIVDV4VavzjgsG1xZ1kCWyjWZgHJ8cblithdHFsQ/H3NYkQ +4J7sVaE3IqKHBAUsR320HLliKWYoyrfhk/WklAOZuXCFteZI6o1Q/NnezG8HDt0L +cp2AMBYHlT8oDv3FdU9T1nSatCQujgKRz3bFmx5VdJx4IbHwLfELn8LVlhgf8FQi +eowHAgMBAAGjfTB7MB0GA1UdDgQWBBSnpQaxLKYJYO7Rl+lwrrw7GWzbITAPBgNV +HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKelBrEspglg7tGX6XCuvDsZbNshMBgG +A1UdIAQRMA8wDQYLKwYBBAGwLQMEAQEwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3 +DQEBCwUAA4IBAQAmdzTblEiGKkGdLD4GkGDEjKwLVLgfuXvTBznk+j57sj1O7Z8j +vZfza1zv7v1Apt+hk6EKhqzvINB5Ab149xnYJDE0BAGmuhWawyfc2E8PzBhj/5kP +DpFrdRbhIfzYJsdHt6bPWHJxfrrhTZVHO8mvbaG0weyJ9rQPOLXiZNwlz6bb65pc +maHFCN795trV1lpFDMS3wrUU77QR/w4VtfX128a961qn8FYiqTxlVMYVqL2Gns2D +lmh6cYGJ4Qvh6hEbaAjMaZ7snkGeRDImeuKHCnE96+RapNLbxc3G3mB/ufNPRJLv +KrcYPqcZ2Qt9sTdBQrC6YB3y/gkRsPCHe6ed +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIDzzCCAregAwIBAgIDAWweMA0GCSqGSIb3DQEBBQUAMIGNMQswCQYDVQQGEwJB +VDFIMEYGA1UECgw/QS1UcnVzdCBHZXMuIGYuIFNpY2hlcmhlaXRzc3lzdGVtZSBp +bSBlbGVrdHIuIERhdGVudmVya2VociBHbWJIMRkwFwYDVQQLDBBBLVRydXN0LW5R +dWFsLTAzMRkwFwYDVQQDDBBBLVRydXN0LW5RdWFsLTAzMB4XDTA1MDgxNzIyMDAw +MFoXDTE1MDgxNzIyMDAwMFowgY0xCzAJBgNVBAYTAkFUMUgwRgYDVQQKDD9BLVRy +dXN0IEdlcy4gZi4gU2ljaGVyaGVpdHNzeXN0ZW1lIGltIGVsZWt0ci4gRGF0ZW52 +ZXJrZWhyIEdtYkgxGTAXBgNVBAsMEEEtVHJ1c3QtblF1YWwtMDMxGTAXBgNVBAMM +EEEtVHJ1c3QtblF1YWwtMDMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB +AQCtPWFuA/OQO8BBC4SAzewqo51ru27CQoT3URThoKgtUaNR8t4j8DRE/5TrzAUj +lUC5B3ilJfYKvUWG6Nm9wASOhURh73+nyfrBJcyFLGM/BWBzSQXgYHiVEEvc+RFZ +znF/QJuKqiTfC0Li21a8StKlDJu3Qz7dg9MmEALP6iPESU7l0+m0iKsMrmKS1GWH +2WrX9IWf5DMiJaXlyDO6w8dB3F/GaswADm0yqLaHNgBid5seHzTLkDx4iHQF63n1 +k3Flyp3HaxgtPVxO59X4PzF9j4fsCiIvI+n+u33J4PTs63zEsMMtYrWacdaxaujs +2e3Vcuy+VwHOBVWf3tFgiBCzAgMBAAGjNjA0MA8GA1UdEwEB/wQFMAMBAf8wEQYD +VR0OBAoECERqlWdVeRFPMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOC +AQEAVdRU0VlIXLOThaq/Yy/kgM40ozRiPvbY7meIMQQDbwvUB/tOdQ/TLtPAF8fG +KOwGDREkDg6lXb+MshOWcdzUzg4NCmgybLlBMRmrsQd7TZjTXLDR8KdCoLXEjq/+ +8T/0709GAHbrAvv5ndJAlseIOrifEXnzgGWovR/TeIGgUUw3tKZdJXDRZslo+S4R +FGjxVJgIrCaSD96JntT6s3kr0qN51OyLrIdTaEJMUVF0HhsnLuP1Hyl0Te2v9+GS +mYHovjrHF1D2t8b8m7CKa9aIA5GPBnc6hQLdmNVDeD/GMBWsm2vLV7eJUYs66MmE +DNuxUCAKGkq6ahq97BvIxYSazQ== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIGFDCCA/ygAwIBAgIIU+w77vuySF8wDQYJKoZIhvcNAQEFBQAwUTELMAkGA1UE +BhMCRVMxQjBABgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1h +cHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2ODAeFw0wOTA1MjAwODM4MTVaFw0zMDEy +MzEwODM4MTVaMFExCzAJBgNVBAYTAkVTMUIwQAYDVQQDDDlBdXRvcmlkYWQgZGUg +Q2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBBNjI2MzQwNjgwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDDUtd9 +thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQM +cas9UX4PB99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefG +L9ItWY16Ck6WaVICqjaY7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15i +NA9wBj4gGFrO93IbJWyTdBSTo3OxDqqHECNZXyAFGUftaI6SEspd/NYrspI8IM/h +X68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyIplD9amML9ZMWGxmPsu2b +m8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctXMbScyJCy +Z/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirja +EbsXLZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/T +KI8xWVvTyQKmtFLKbpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF +6NkBiDkal4ZkQdU7hwxu+g/GvUgUvzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVh +OSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMBIGA1UdEwEB/wQIMAYBAf8CAQEwDgYD +VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRlzeurNR4APn7VdMActHNHDhpkLzCBpgYD +VR0gBIGeMIGbMIGYBgRVHSAAMIGPMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmZp +cm1hcHJvZmVzaW9uYWwuY29tL2NwczBcBggrBgEFBQcCAjBQHk4AUABhAHMAZQBv +ACAAZABlACAAbABhACAAQgBvAG4AYQBuAG8AdgBhACAANAA3ACAAQgBhAHIAYwBl +AGwAbwBuAGEAIAAwADgAMAAxADcwDQYJKoZIhvcNAQEFBQADggIBABd9oPm03cXF +661LJLWhAqvdpYhKsg9VSytXjDvlMd3+xDLx51tkljYyGOylMnfX40S2wBEqgLk9 +am58m9Ot/MPWo+ZkKXzR4Tgegiv/J2Wv+xYVxC5xhOW1//qkR71kMrv2JYSiJ0L1 +ILDCExARzRAVukKQKtJE4ZYm6zFIEv0q2skGz3QeqUvVhyj5eTSSPi5E6PaPT481 +PyWzOdxjKpBrIF/EUhJOlywqrJ2X3kjyo2bbwtKDlaZmp54lD+kLM5FlClrD2VQS +3a/DTg4fJl4N3LON7NWBcN7STyQF82xO9UxJZo3R/9ILJUFI/lGExkKvgATP0H5k +SeTy36LssUzAKh3ntLFlosS88Zj0qnAHY7S42jtM+kAiMFsRpvAFDsYCA0irhpuF +3dvd6qJ2gHN99ZwExEWN57kci57q13XRcrHedUTnQn3iV2t93Jm8PYMo6oCTjcVM +ZcFwgbg4/EMxsvYDNEeyrPsiBsse3RdHHF9mudMaotoRsaS8I8nkvof/uZS2+F0g +StRf571oe2XyFR7SOqkt6dhrJKyXWERHrVkY8SFlcN7ONGCoQPHzPKTDKCOM/icz +Q0CgFzzr6juwcqajuUpLXhZI9LK8yIySxZ2frHI2vDSANGupi5LAuBft7HZT9SQB +jLMi6Et8Vcad+qMUu2WFbm5PEn4KPJ2V +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIDUzCCAjugAwIBAgIBATANBgkqhkiG9w0BAQUFADBLMQswCQYDVQQGEwJOTzEd +MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxHTAbBgNVBAMMFEJ1eXBhc3Mg +Q2xhc3MgMiBDQSAxMB4XDTA2MTAxMzEwMjUwOVoXDTE2MTAxMzEwMjUwOVowSzEL +MAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MR0wGwYD +VQQDDBRCdXlwYXNzIENsYXNzIDIgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBAIs8B0XY9t/mx8q6jUPFR42wWsE425KEHK8T1A9vNkYgxC7McXA0 +ojTTNy7Y3Tp3L8DrKehc0rWpkTSHIln+zNvnma+WwajHQN2lFYxuyHyXA8vmIPLX +l18xoS830r7uvqmtqEyeIWZDO6i88wmjONVZJMHCR3axiFyCO7srpgTXjAePzdVB +HfCuuCkslFJgNJQ72uA40Z0zPhX0kzLFANq1KWYOOngPIVJfAuWSeyXTkh4vFZ2B +5J2O6O+JzhRMVB0cgRJNcKi+EAUXfh/RuFdV7c27UsKwHnjCTTZoy1YmwVLBvXb3 +WNVyfh9EdrsAiR0WnVE1703CVu9r4Iw7DekCAwEAAaNCMEAwDwYDVR0TAQH/BAUw +AwEB/zAdBgNVHQ4EFgQUP42aWYv8e3uco684sDntkHGA1sgwDgYDVR0PAQH/BAQD +AgEGMA0GCSqGSIb3DQEBBQUAA4IBAQAVGn4TirnoB6NLJzKyQJHyIdFkhb5jatLP +gcIV1Xp+DCmsNx4cfHZSldq1fyOhKXdlyTKdqC5Wq2B2zha0jX94wNWZUYN/Xtm+ +DKhQ7SLHrQVMdvvt7h5HZPb3J31cKA9FxVxiXqaakZG3Uxcu3K1gnZZkOb1naLKu +BctN518fV4bVIJwo+28TOPX2EZL2fZleHwzoq0QkKXJAPTZSr4xYkHPB7GEseaHs +h7U/2k3ZIQAw3pDaDtMaSKk+hQsUi4y8QZ5q9w5wwDX3OaJdZtB7WZ+oRxKaJyOk +LY4ng5IgodcVf/EuGO70SH8vf/GhGLWhC5SgYiAynB321O+/TIho +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd +MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg +Q2xhc3MgMiBSb290IENBMB4XDTEwMTAyNjA4MzgwM1oXDTQwMTAyNjA4MzgwM1ow +TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw +HgYDVQQDDBdCdXlwYXNzIENsYXNzIDIgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB +BQADggIPADCCAgoCggIBANfHXvfBB9R3+0Mh9PT1aeTuMgHbo4Yf5FkNuud1g1Lr +6hxhFUi7HQfKjK6w3Jad6sNgkoaCKHOcVgb/S2TwDCo3SbXlzwx87vFKu3MwZfPV +L4O2fuPn9Z6rYPnT8Z2SdIrkHJasW4DptfQxh6NR/Md+oW+OU3fUl8FVM5I+GC91 +1K2GScuVr1QGbNgGE41b/+EmGVnAJLqBcXmQRFBoJJRfuLMR8SlBYaNByyM21cHx +MlAQTn/0hpPshNOOvEu/XAFOBz3cFIqUCqTqc/sLUegTBxj6DvEr0VQVfTzh97QZ +QmdiXnfgolXsttlpF9U6r0TtSsWe5HonfOV116rLJeffawrbD02TTqigzXsu8lkB +arcNuAeBfos4GzjmCleZPe4h6KP1DBbdi+w0jpwqHAAVF41og9JwnxgIzRFo1clr +Us3ERo/ctfPYV3Me6ZQ5BL/T3jjetFPsaRyifsSP5BtwrfKi+fv3FmRmaZ9JUaLi +FRhnBkp/1Wy1TbMz4GHrXb7pmA8y1x1LPC5aAVKRCfLf6o3YBkBjqhHk/sM3nhRS +P/TizPJhk9H9Z2vXUq6/aKtAQ6BXNVN48FP4YUIHZMbXb5tMOA1jrGKvNouicwoN +9SG9dKpN6nIDSdvHXx1iY8f93ZHsM+71bbRuMGjeyNYmsHVee7QHIJihdjK4TWxP +AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMmAd+BikoL1Rpzz +uvdMw964o605MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAU18h +9bqwOlI5LJKwbADJ784g7wbylp7ppHR/ehb8t/W2+xUbP6umwHJdELFx7rxP462s +A20ucS6vxOOto70MEae0/0qyexAQH6dXQbLArvQsWdZHEIjzIVEpMMpghq9Gqx3t +OluwlN5E40EIosHsHdb9T7bWR9AUC8rmyrV7d35BH16Dx7aMOZawP5aBQW9gkOLo ++fsicdl9sz1Gv7SEr5AcD48Saq/v7h56rgJKihcrdv6sVIkkLE8/trKnToyokZf7 +KcZ7XC25y2a2t6hbElGFtQl+Ynhw/qlqYLYdDnkM/crqJIByw5c/8nerQyIKx+u2 +DISCLIBrQYoIwOula9+ZEsuK1V6ADJHgJgg2SMX6OBE1/yWDLfJ6v9r9jv6ly0Us +H8SIU653DtmadsWOLB2jutXsMq7Aqqz30XpN69QH4kj3Io6wpJ9qzo6ysmD0oyLQ +I+uUWnpp3Q+/QFesa1lQ2aOZ4W7+jQF5JyMV3pKdewlNWudLSDBaGOYKbeaP4NK7 +5t98biGCwWg5TbSYWGZizEqQXsP6JwSxeRV0mcy+rSDeJmAc61ZRpqPq5KM/p/9h +3PFaTWwyI0PurKju7koSCTxdccK+efrCh2gdC/1cacwG0Jp9VJkqyTkaGa9LKkPz +Y11aWOIv4x3kqdbQCtCev9eBCfHJxyYNrJgWVqA= +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIDUzCCAjugAwIBAgIBAjANBgkqhkiG9w0BAQUFADBLMQswCQYDVQQGEwJOTzEd +MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxHTAbBgNVBAMMFEJ1eXBhc3Mg +Q2xhc3MgMyBDQSAxMB4XDTA1MDUwOTE0MTMwM1oXDTE1MDUwOTE0MTMwM1owSzEL +MAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MR0wGwYD +VQQDDBRCdXlwYXNzIENsYXNzIDMgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBAKSO13TZKWTeXx+HgJHqTjnmGcZEC4DVC69TB4sSveZn8AKxifZg +isRbsELRwCGoy+Gb72RRtqfPFfV0gGgEkKBYouZ0plNTVUhjP5JW3SROjvi6K//z +NIqeKNc0n6wv1g/xpC+9UrJJhW05NfBEMJNGJPO251P7vGGvqaMU+8IXF4Rs4HyI ++MkcVyzwPX6UvCWThOiaAJpFBUJXgPROztmuOfbIUxAMZTpHe2DC1vqRycZxbL2R +hzyRhkmr8w+gbCZ2Xhysm3HljbybIR6c1jh+JIAVMYKWsUnTYjdbiAwKYjT+p0h+ +mbEwi5A3lRyoH6UsjfRVyNvdWQrCrXig9IsCAwEAAaNCMEAwDwYDVR0TAQH/BAUw +AwEB/zAdBgNVHQ4EFgQUOBTmyPCppAP0Tj4io1vy1uCtQHQwDgYDVR0PAQH/BAQD +AgEGMA0GCSqGSIb3DQEBBQUAA4IBAQABZ6OMySU9E2NdFm/soT4JXJEVKirZgCFP +Bdy7pYmrEzMqnji3jG8CcmPHc3ceCQa6Oyh7pEfJYWsICCD8igWKH7y6xsL+z27s +EzNxZy5p+qksP2bAEllNC1QCkoS72xLvg3BweMhT+t/Gxv/ciC8HwEmdMldg0/L2 +mSlf56oBzKwzqBwKu5HEA6BvtjT5htOzdlSY9EqBs1OdTUDs5XcTRa9bqh/YL0yC +e/4qxFi7T/ye/QNlGioOw6UgFpRreaaiErS7GqQjel/wroQk5PMr+4okoyeYZdow +dXb8GZHo2+ubPzK/QJcHJrrM85SFSnonk8+QQtS4Wxam58tAA915 +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd +MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg +Q2xhc3MgMyBSb290IENBMB4XDTEwMTAyNjA4Mjg1OFoXDTQwMTAyNjA4Mjg1OFow +TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw +HgYDVQQDDBdCdXlwYXNzIENsYXNzIDMgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB +BQADggIPADCCAgoCggIBAKXaCpUWUOOV8l6ddjEGMnqb8RB2uACatVI2zSRHsJ8Y +ZLya9vrVediQYkwiL944PdbgqOkcLNt4EemOaFEVcsfzM4fkoF0LXOBXByow9c3E +N3coTRiR5r/VUv1xLXA+58bEiuPwKAv0dpihi4dVsjoT/Lc+JzeOIuOoTyrvYLs9 +tznDDgFHmV0ST9tD+leh7fmdvhFHJlsTmKtdFoqwNxxXnUX/iJY2v7vKB3tvh2PX +0DJq1l1sDPGzbjniazEuOQAnFN44wOwZZoYS6J1yFhNkUsepNxz9gjDthBgd9K5c +/3ATAOux9TN6S9ZV+AWNS2mw9bMoNlwUxFFzTWsL8TQH2xc519woe2v1n/MuwU8X +KhDzzMro6/1rqy6any2CbgTUUgGTLT2G/H783+9CHaZr77kgxve9oKeV/afmiSTY +zIw0bOIjL9kSGiG5VZFvC5F5GQytQIgLcOJ60g7YaEi7ghM5EFjp2CoHxhLbWNvS +O1UQRwUVZ2J+GGOmRj8JDlQyXr8NYnon74Do29lLBlo3WiXQCBJ31G8JUJc9yB3D +34xFMFbG02SrZvPAXpacw8Tvw3xrizp5f7NJzz3iiZ+gMEuFuZyUJHmPfWupRWgP +K9Dx2hzLabjKSWJtyNBjYt1gD1iqj6G8BaVmos8bdrKEZLFMOVLAMLrwjEsCsLa3 +AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFEe4zf/lb+74suwv +Tg75JbCOPGvDMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAACAj +QTUEkMJAYmDv4jVM1z+s4jSQuKFvdvoWFqRINyzpkMLyPPgKn9iB5btb2iUspKdV +cSQy9sgL8rxq+JOssgfCX5/bzMiKqr5qb+FJEMwx14C7u8jYog5kV+qi9cKpMRXS +IGrs/CIBKM+GuIAeqcwRpTzyFrNHnfzSgCHEy9BHcEGhyoMZCCxt8l13nIoUE9Q2 +HJLw5QY33KbmkJs4j1xrG0aGQ0JfPgEHU1RdZX33inOhmlRaHylDFCfChQ+1iHsa +O5S3HWCntZznKWlXWpuTekMwGwPXYshApqr8ZORK15FTAaggiG6cX0S5y2CBNOxv +033aSF/rtJC8LakcC6wc1aJoIIAE1vyxjy+7SjENSoYc6+I2KSb12tjE8nVhz36u +dmNKekBlk4f4HoCMhuWG1o8O/FMsYOgWYRqiPkN7zTlgVGr18okmAWiDSKIz6MkE +kbIRNBE+6tBDGR8Dk5AM/1E9V/RBbuHLoL7ryWPNbczk+DaqaJ3tvV2XcEQNtg41 +3OEMXbugUZTLfhbrES+jkkXITHHZvMmZUldGL1DPvTVp9D0VzgalLA8+9oG6lLvD +u79leNKGef9JOxqDDPDeeOzI8k1MGt6CKfjBWtrt7uYnXuhF0J0cUahoq0Tj0Itq +4/g7u9xN12TyUb7mqqta6THuBrxzvxNiCp/HuZc= +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIEDzCCAvegAwIBAgIBATANBgkqhkiG9w0BAQUFADBKMQswCQYDVQQGEwJTSzET +MBEGA1UEBxMKQnJhdGlzbGF2YTETMBEGA1UEChMKRGlzaWcgYS5zLjERMA8GA1UE +AxMIQ0EgRGlzaWcwHhcNMDYwMzIyMDEzOTM0WhcNMTYwMzIyMDEzOTM0WjBKMQsw +CQYDVQQGEwJTSzETMBEGA1UEBxMKQnJhdGlzbGF2YTETMBEGA1UEChMKRGlzaWcg +YS5zLjERMA8GA1UEAxMIQ0EgRGlzaWcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw +ggEKAoIBAQCS9jHBfYj9mQGp2HvycXXxMcbzdWb6UShGhJd4NLxs/LxFWYgmGErE +Nx+hSkS943EE9UQX4j/8SFhvXJ56CbpRNyIjZkMhsDxkovhqFQ4/61HhVKndBpnX +mjxUizkDPw/Fzsbrg3ICqB9x8y34dQjbYkzo+s7552oftms1grrijxaSfQUMbEYD +XcDtab86wYqg6I7ZuUUohwjstMoVvoLdtUSLLa2GDGhibYVW8qwUYzrG0ZmsNHhW +S8+2rT+MitcE5eN4TPWGqvWP+j1scaMtymfraHtuM6kMgiioTGohQBUgDCZbg8Kp +FhXAJIJdKxatymP2dACw30PEEGBWZ2NFAgMBAAGjgf8wgfwwDwYDVR0TAQH/BAUw +AwEB/zAdBgNVHQ4EFgQUjbJJaJ1yCCW5wCf1UJNWSEZx+Y8wDgYDVR0PAQH/BAQD +AgEGMDYGA1UdEQQvMC2BE2Nhb3BlcmF0b3JAZGlzaWcuc2uGFmh0dHA6Ly93d3cu +ZGlzaWcuc2svY2EwZgYDVR0fBF8wXTAtoCugKYYnaHR0cDovL3d3dy5kaXNpZy5z +ay9jYS9jcmwvY2FfZGlzaWcuY3JsMCygKqAohiZodHRwOi8vY2EuZGlzaWcuc2sv +Y2EvY3JsL2NhX2Rpc2lnLmNybDAaBgNVHSAEEzARMA8GDSuBHpGT5goAAAABAQEw +DQYJKoZIhvcNAQEFBQADggEBAF00dGFMrzvY/59tWDYcPQuBDRIrRhCA/ec8J9B6 +yKm2fnQwM6M6int0wHl5QpNt/7EpFIKrIYwvF/k/Ji/1WcbvgAa3mkkp7M5+cTxq +EEHA9tOasnxakZzArFvITV734VP/Q3f8nktnbNfzg9Gg4H8l37iYC5oyOGwwoPP/ +CBUz91BKez6jPiCp3C9WgArtQVCwyfTssuMmRAAOb54GvCKWU3BlxFAKRmukLyeB +EicTXxChds6KezfqwzlhA5WYOudsiCUI/HloDYd9Yvi0X/vF2Ey9WLw/Q1vUHgFN +PGO+I++MzVpQuGhU+QqZMxEA4Z7CRneC9VkGjCFMhwnN5ag= +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIFaTCCA1GgAwIBAgIJAMMDmu5QkG4oMA0GCSqGSIb3DQEBBQUAMFIxCzAJBgNV +BAYTAlNLMRMwEQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMu +MRkwFwYDVQQDExBDQSBEaXNpZyBSb290IFIxMB4XDTEyMDcxOTA5MDY1NloXDTQy +MDcxOTA5MDY1NlowUjELMAkGA1UEBhMCU0sxEzARBgNVBAcTCkJyYXRpc2xhdmEx +EzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERpc2lnIFJvb3QgUjEw +ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCqw3j33Jijp1pedxiy3QRk +D2P9m5YJgNXoqqXinCaUOuiZc4yd39ffg/N4T0Dhf9Kn0uXKE5Pn7cZ3Xza1lK/o +OI7bm+V8u8yN63Vz4STN5qctGS7Y1oprFOsIYgrY3LMATcMjfF9DCCMyEtztDK3A +fQ+lekLZWnDZv6fXARz2m6uOt0qGeKAeVjGu74IKgEH3G8muqzIm1Cxr7X1r5OJe +IgpFy4QxTaz+29FHuvlglzmxZcfe+5nkCiKxLU3lSCZpq+Kq8/v8kiky6bM+TR8n +oc2OuRf7JT7JbvN32g0S9l3HuzYQ1VTW8+DiR0jm3hTaYVKvJrT1cU/J19IG32PK +/yHoWQbgCNWEFVP3Q+V8xaCJmGtzxmjOZd69fwX3se72V6FglcXM6pM6vpmumwKj +rckWtc7dXpl4fho5frLABaTAgqWjR56M6ly2vGfb5ipN0gTco65F97yLnByn1tUD +3AjLLhbKXEAz6GfDLuemROoRRRw1ZS0eRWEkG4IupZ0zXWX4Qfkuy5Q/H6MMMSRE +7cderVC6xkGbrPAXZcD4XW9boAo0PO7X6oifmPmvTiT6l7Jkdtqr9O3jw2Dv1fkC +yC2fg69naQanMVXVz0tv/wQFx1isXxYb5dKj6zHbHzMVTdDypVP1y+E9Tmgt2BLd +qvLmTZtJ5cUoobqwWsagtQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud +DwEB/wQEAwIBBjAdBgNVHQ4EFgQUiQq0OJMa5qvum5EY+fU8PjXQ04IwDQYJKoZI +hvcNAQEFBQADggIBADKL9p1Kyb4U5YysOMo6CdQbzoaz3evUuii+Eq5FLAR0rBNR +xVgYZk2C2tXck8An4b58n1KeElb21Zyp9HWc+jcSjxyT7Ff+Bw+r1RL3D65hXlaA +SfX8MPWbTx9BLxyE04nH4toCdu0Jz2zBuByDHBb6lM19oMgY0sidbvW9adRtPTXo +HqJPYNcHKfyyo6SdbhWSVhlMCrDpfNIZTUJG7L399ldb3Zh+pE3McgODWF3vkzpB +emOqfDqo9ayk0d2iLbYq/J8BjuIQscTK5GfbVSUZP/3oNn6z4eGBrxEWi1CXYBmC +AMBrTXO40RMHPuq2MU/wQppt4hF05ZSsjYSVPCGvxdpHyN85YmLLW1AL14FABZyb +7bq2ix4Eb5YgOe2kfSnbSM6C3NQCjR0EMVrHS/BsYVLXtFHCgWzN4funodKSds+x +DzdYpPJScWc/DIh4gInByLUfkmO+p3qKViwaqKactV2zY9ATIKHrkWzQjX2v3wvk +F7mGnjixlAxYjOBVqjtjbZqJYLhkKpLGN/R+Q0O3c+gB53+XD9fyexn9GtePyfqF +a3qdnom2piiZk4hA9z7NUaPK6u95RyG1/jLix8NRb76AdPCkwzryT+lf3xkK8jsT +Q6wxpLPn6/wY1gGp8yqPNg7rtLG8t0zJa7+h89n07eLw4+1knj0vllJPgFOL +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIFaTCCA1GgAwIBAgIJAJK4iNuwisFjMA0GCSqGSIb3DQEBCwUAMFIxCzAJBgNV +BAYTAlNLMRMwEQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMu +MRkwFwYDVQQDExBDQSBEaXNpZyBSb290IFIyMB4XDTEyMDcxOTA5MTUzMFoXDTQy +MDcxOTA5MTUzMFowUjELMAkGA1UEBhMCU0sxEzARBgNVBAcTCkJyYXRpc2xhdmEx +EzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERpc2lnIFJvb3QgUjIw +ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCio8QACdaFXS1tFPbCw3Oe +NcJxVX6B+6tGUODBfEl45qt5WDza/3wcn9iXAng+a0EE6UG9vgMsRfYvZNSrXaNH +PWSb6WiaxswbP7q+sos0Ai6YVRn8jG+qX9pMzk0DIaPY0jSTVpbLTAwAFjxfGs3I +x2ymrdMxp7zo5eFm1tL7A7RBZckQrg4FY8aAamkw/dLukO8NJ9+flXP04SXabBbe +QTg06ov80egEFGEtQX6sx3dOy1FU+16SGBsEWmjGycT6txOgmLcRK7fWV8x8nhfR +yyX+hk4kLlYMeE2eARKmK6cBZW58Yh2EhN/qwGu1pSqVg8NTEQxzHQuyRpDRQjrO +QG6Vrf/GlK1ul4SOfW+eioANSW1z4nuSHsPzwfPrLgVv2RvPN3YEyLRa5Beny912 +H9AZdugsBbPWnDTYltxhh5EF5EQIM8HauQhl1K6yNg3ruji6DOWbnuuNZt2Zz9aJ +QfYEkoopKW1rOhzndX0CcQ7zwOe9yxndnWCywmZgtrEE7snmhrmaZkCo5xHtgUUD +i/ZnWejBBhG93c+AAk9lQHhcR1DIm+YfgXvkRKhbhZri3lrVx/k6RGZL5DJUfORs +nLMOPReisjQS1n6yqEm70XooQL6iFh/f5DcfEXP7kAplQ6INfPgGAVUzfbANuPT1 +rqVCV3w2EYx7XsQDnYx5nQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud +DwEB/wQEAwIBBjAdBgNVHQ4EFgQUtZn4r7CU9eMg1gqtzk5WpC5uQu0wDQYJKoZI +hvcNAQELBQADggIBACYGXnDnZTPIgm7ZnBc6G3pmsgH2eDtpXi/q/075KMOYKmFM +tCQSin1tERT3nLXK5ryeJ45MGcipvXrA1zYObYVybqjGom32+nNjf7xueQgcnYqf +GopTpti72TVVsRHFqQOzVju5hJMiXn7B9hJSi+osZ7z+Nkz1uM/Rs0mSO9MpDpkb +lvdhuDvEK7Z4bLQjb/D907JedR+Zlais9trhxTF7+9FGs9K8Z7RiVLoJ92Owk6Ka ++elSLotgEqv89WBW7xBci8QaQtyDW2QOy7W81k/BfDxujRNt+3vrMNDcTa/F1bal +TFtxyegxvug4BkihGuLq0t4SOVga/4AOgnXmt8kHbA7v/zjxmHHEt38OFdAlab0i +nSvtBfZGR6ztwPDUO+Ls7pZbkBNOHlY667DvlruWIxG68kOGdGSVyCh13x01utI3 +gzhTODY7z2zp+WsO0PsE6E9312UBeIYMej4hYvF/Y3EMyZ9E26gnonW+boE+18Dr +G5gPcFw0sorMwIUY6256s/daoQe/qUKS82Ail+QUoQebTnbAjn39pCXHR+3/H3Os +zMOl6W8KjptlwlCFtaOgUxLMVYdh84GuEEZhvUQhuMI9dM9+JDX6HAcOmz0iyu8x +L4ysEr3vQCj8KWefshNPZiTEUxnpHikV7+ZtsH8tZ/3zbBt1RqPlShfppNcL +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIDqDCCApCgAwIBAgIJAP7c4wEPyUj/MA0GCSqGSIb3DQEBBQUAMDQxCzAJBgNV +BAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hMB4X +DTA3MDYyOTE1MTMwNVoXDTI3MDYyOTE1MTMwNVowNDELMAkGA1UEBhMCRlIxEjAQ +BgNVBAoMCURoaW15b3RpczERMA8GA1UEAwwIQ2VydGlnbmEwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQDIaPHJ1tazNHUmgh7stL7qXOEm7RFHYeGifBZ4 +QCHkYJ5ayGPhxLGWkv8YbWkj4Sti993iNi+RB7lIzw7sebYs5zRLcAglozyHGxny +gQcPOJAZ0xH+hrTy0V4eHpbNgGzOOzGTtvKg0KmVEn2lmsxryIRWijOp5yIVUxbw +zBfsV1/pogqYCd7jX5xv3EjjhQsVWqa6n6xI4wmy9/Qy3l40vhx4XUJbzg4ij02Q +130yGLMLLGq/jj8UEYkgDncUtT2UCIf3JR7VsmAA7G8qKCVuKj4YYxclPz5EIBb2 +JsglrgVKtOdjLPOMFlN+XPsRGgjBRmKfIrjxwo1p3Po6WAbfAgMBAAGjgbwwgbkw +DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUGu3+QTmQtCRZvgHyUtVF9lo53BEw +ZAYDVR0jBF0wW4AUGu3+QTmQtCRZvgHyUtVF9lo53BGhOKQ2MDQxCzAJBgNVBAYT +AkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hggkA/tzj +AQ/JSP8wDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzANBgkqhkiG +9w0BAQUFAAOCAQEAhQMeknH2Qq/ho2Ge6/PAD/Kl1NqV5ta+aDY9fm4fTIrv0Q8h +bV6lUmPOEvjvKtpv6zf+EwLHyzs+ImvaYS5/1HI93TDhHkxAGYwP15zRgzB7mFnc +fca5DClMoTOi62c6ZYTTluLtdkVwj7Ur3vkj1kluPBS1xp81HlDQwY9qcEQCYsuu +HWhBp6pX6FOqB9IG9tUUBguRA3UsbHK1YZWaDYu5Def131TN3ubY1gkIl2PlwS6w +t0QmwCbAr1UwnjvVNioZBPRcHv/PLLf/0P2HQBHVESO7SMAhqaQoLf0V+LBOK/Qw +WyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIFnDCCA4SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJGUjET +MBEGA1UEChMKQ2VydGlub21pczEXMBUGA1UECxMOMDAwMiA0MzM5OTg5MDMxJjAk +BgNVBAMMHUNlcnRpbm9taXMgLSBBdXRvcml0w6kgUmFjaW5lMB4XDTA4MDkxNzA4 +Mjg1OVoXDTI4MDkxNzA4Mjg1OVowYzELMAkGA1UEBhMCRlIxEzARBgNVBAoTCkNl +cnRpbm9taXMxFzAVBgNVBAsTDjAwMDIgNDMzOTk4OTAzMSYwJAYDVQQDDB1DZXJ0 +aW5vbWlzIC0gQXV0b3JpdMOpIFJhY2luZTCCAiIwDQYJKoZIhvcNAQEBBQADggIP +ADCCAgoCggIBAJ2Fn4bT46/HsmtuM+Cet0I0VZ35gb5j2CN2DpdUzZlMGvE5x4jY +F1AMnmHawE5V3udauHpOd4cN5bjr+p5eex7Ezyh0x5P1FMYiKAT5kcOrJ3NqDi5N +8y4oH3DfVS9O7cdxbwlyLu3VMpfQ8Vh30WC8Tl7bmoT2R2FFK/ZQpn9qcSdIhDWe +rP5pqZ56XjUl+rSnSTV3lqc2W+HN3yNw2F1MpQiD8aYkOBOo7C+ooWfHpi2GR+6K +/OybDnT0K0kCe5B1jPyZOQE51kqJ5Z52qz6WKDgmi92NjMD2AR5vpTESOH2VwnHu +7XSu5DaiQ3XV8QCb4uTXzEIDS3h65X27uK4uIJPT5GHfceF2Z5c/tt9qc1pkIuVC +28+BA5PY9OMQ4HL2AHCs8MF6DwV/zzRpRbWT5BnbUhYjBYkOjUjkJW+zeL9i9Qf6 +lSTClrLooyPCXQP8w9PlfMl1I9f09bze5N/NgL+RiH2nE7Q5uiy6vdFrzPOlKO1E +nn1So2+WLhl+HPNbxxaOu2B9d2ZHVIIAEWBsMsGoOBvrbpgT1u449fCfDu/+MYHB +0iSVL1N6aaLwD4ZFjliCK0wi1F6g530mJ0jfJUaNSih8hp75mxpZuWW/Bd22Ql09 +5gBIgl4g9xGC3srYn+Y3RyYe63j3YcNBZFgCQfna4NH4+ej9Uji29YnfAgMBAAGj +WzBZMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBQN +jLZh2kS40RR9w759XkjwzspqsDAXBgNVHSAEEDAOMAwGCiqBegFWAgIAAQEwDQYJ +KoZIhvcNAQEFBQADggIBACQ+YAZ+He86PtvqrxyaLAEL9MW12Ukx9F1BjYkMTv9s +ov3/4gbIOZ/xWqndIlgVqIrTseYyCYIDbNc/CMf4uboAbbnW/FIyXaR/pDGUu7ZM +OH8oMDX/nyNTt7buFHAAQCvaR6s0fl6nVjBhK4tDrP22iCj1a7Y+YEq6QpA0Z43q +619FVDsXrIvkxmUP7tCMXWY5zjKn2BCXwH40nJ+U8/aGH88bc62UeYdocMMzpXDn +2NU4lG9jeeu/Cg4I58UvD0KgKxRA/yHgBcUn4YQRE7rWhh1BCxMjidPJC+iKunqj +o3M3NYB9Ergzd0A4wPpeMNLytqOx1qKVl4GbUu1pTP+A5FPbVFsDbVRfsbjvJL1v +nxHDx2TCDyhihWZeGnuyt++uNckZM6i4J9szVb9o4XVIRFb7zdNIu0eJOqxp9YDG +5ERQL1TEqkPFMTFYvZbF6nVsmnWxTfj3l/+WFvKXTej28xH5On2KOG4Ey+HTRRWq +pdEdnV1j6CTmNhTih60bWfVEm/vXd3wfAXBioSAaosUaKPQhA+4u2cGA6rnZgtZb +dsLLO7XSAPCjDuGtbkD326C00EauFddEwk01+dIL8hf2rGbVJLJP0RyZwG71fet0 +BLj5TXcJ17TPBzAJ8bgAVtkXFhYKK4bfjwEZGuW7gmP/vgt2Fl43N+bYdJeimUV5 +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIDkjCCAnqgAwIBAgIRAIW9S/PY2uNp9pTXX8OlRCMwDQYJKoZIhvcNAQEFBQAw +PTELMAkGA1UEBhMCRlIxETAPBgNVBAoTCENlcnRwbHVzMRswGQYDVQQDExJDbGFz +cyAyIFByaW1hcnkgQ0EwHhcNOTkwNzA3MTcwNTAwWhcNMTkwNzA2MjM1OTU5WjA9 +MQswCQYDVQQGEwJGUjERMA8GA1UEChMIQ2VydHBsdXMxGzAZBgNVBAMTEkNsYXNz +IDIgUHJpbWFyeSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANxQ +ltAS+DXSCHh6tlJw/W/uz7kRy1134ezpfgSN1sxvc0NXYKwzCkTsA18cgCSR5aiR +VhKC9+Ar9NuuYS6JEI1rbLqzAr3VNsVINyPi8Fo3UjMXEuLRYE2+L0ER4/YXJQyL +kcAbmXuZVg2v7tK8R1fjeUl7NIknJITesezpWE7+Tt9avkGtrAjFGA7v0lPubNCd +EgETjdyAYveVqUSISnFOYFWe2yMZeVYHDD9jC1yw4r5+FfyUM1hBOHTE4Y+L3yas +H7WLO7dDWWuwJKZtkIvEcupdM5i3y95ee++U8Rs+yskhwcWYAqqi9lt3m/V+llU0 +HGdpwPFC40es/CgcZlUCAwEAAaOBjDCBiTAPBgNVHRMECDAGAQH/AgEKMAsGA1Ud +DwQEAwIBBjAdBgNVHQ4EFgQU43Mt38sOKAze3bOkynm4jrvoMIkwEQYJYIZIAYb4 +QgEBBAQDAgEGMDcGA1UdHwQwMC4wLKAqoCiGJmh0dHA6Ly93d3cuY2VydHBsdXMu +Y29tL0NSTC9jbGFzczIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCnVM+IRBnL39R/ +AN9WM2K191EBkOvDP9GIROkkXe/nFL0gt5o8AP5tn9uQ3Nf0YtaLcF3n5QRIqWh8 +yfFC82x/xXp8HVGIutIKPidd3i1RTtMTZGnkLuPT55sJmabglZvOGtd/vjzOUrMR +FcEPF80Du5wlFbqidon8BvEY0JNLDnyCt6X09l/+7UCmnYR0ObncHoUW2ikbhiMA +ybuJfm6AiB4vFLQDJKgybwOaRywwvlbGp0ICcBvqQNi6BQNwB6SW//1IMwrh3KWB +kJtN3X3n57LNXMhqlfil9o3EXXgIvnsG1knPGTZQIy4I5p4FTUcY1Rbpsda2ENW7 +l7+ijrRU +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIDODCCAiCgAwIBAgIGIAYFFnACMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNVBAYT +AlJPMREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBD +QTAeFw0wNjA3MDQxNzIwMDRaFw0zMTA3MDQxNzIwMDRaMDsxCzAJBgNVBAYTAlJP +MREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBDQTCC +ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALczuX7IJUqOtdu0KBuqV5Do +0SLTZLrTk+jUrIZhQGpgV2hUhE28alQCBf/fm5oqrl0Hj0rDKH/v+yv6efHHrfAQ +UySQi2bJqIirr1qjAOm+ukbuW3N7LBeCgV5iLKECZbO9xSsAfsT8AzNXDe3i+s5d +RdY4zTW2ssHQnIFKquSyAVwdj1+ZxLGt24gh65AIgoDzMKND5pCCrlUoSe1b16kQ +OA7+j0xbm0bqQfWwCHTD0IgztnzXdN/chNFDDnU5oSVAKOp4yw4sLjmdjItuFhwv +JoIQ4uNllAoEwF73XVv4EOLQunpL+943AAAaWyjj0pxzPjKHmKHJUS/X3qwzs08C +AwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAcYwHQYDVR0O +BBYEFOCMm9slSbPxfIbWskKHC9BroNnkMA0GCSqGSIb3DQEBBQUAA4IBAQA+0hyJ +LjX8+HXd5n9liPRyTMks1zJO890ZeUe9jjtbkw9QSSQTaxQGcu8J06Gh40CEyecY +MnQ8SG4Pn0vU9x7Tk4ZkVJdjclDVVc/6IJMCopvDI5NOFlV2oHB5bc0hH88vLbwZ +44gx+FkagQnIl6Z0x2DEW8xXjrJ1/RsCCdtZb3KTafcxQdaIOL+Hsr0Wefmq5L6I +Jd1hJyMctTEHBDa0GpC9oHRxUIltvBTjD4au8as+x6AJzKNI0eDbZOeStc+vckNw +i/nDhDwTqn6Sm1dTk/pwwpEOMfmbZ13pljheX7NzTogVZ96edhBiIL5VaZVDADlN +9u6wWk5JRFRYX0KD +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBM +MSIwIAYDVQQKExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5D +ZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBU +cnVzdGVkIE5ldHdvcmsgQ0EwHhcNMDgxMDIyMTIwNzM3WhcNMjkxMjMxMTIwNzM3 +WjB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBUZWNobm9sb2dpZXMg +Uy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MSIw +IAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEA4/t9o3K6wvDJFIf1awFO4W5AB7ptJ11/91sts1rH +UV+rpDKmYYe2bg+G0jACl/jXaVehGDldamR5xgFZrDwxSjh80gTSSyjoIF87B6LM +TXPb865Px1bVWqeWifrzq2jUI4ZZJ88JJ7ysbnKDHDBy3+Ci6dLhdHUZvSqeexVU +BBvXQzmtVSjF4hq79MDkrjhJM8x2hZ85RdKknvISjFH4fOQtf/WsX+sWn7Et0brM +kUJ3TCXJkDhv2/DM+44el1k+1WBO5gUo7Ul5E0u6SNsv+XLTOcr+H9g0cvW0QM8x +AcPs3hEtF10fuFDRXhmnad4HMyjKUJX5p1TLVIZQRan5SQIDAQABo0IwQDAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNV +HQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQADggEBAKaorSLOAT2mo/9i0Eidi15y +sHhE49wcrwn9I0j6vSrEuVUEtRCjjSfeC4Jj0O7eDDd5QVsisrCaQVymcODU0HfL +I9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1mS1FhIrlQgnXdAIv94nYmem8 +J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5ajZt3hrvJBW8qY +VoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI +03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw= +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIFjTCCA3WgAwIBAgIEGErM1jANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJD +TjEwMC4GA1UECgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9y +aXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJPT1QwHhcNMTIwODA4MDMwNzAxWhcNMjkx +MjMxMDMwNzAxWjBWMQswCQYDVQQGEwJDTjEwMC4GA1UECgwnQ2hpbmEgRmluYW5j +aWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJP +T1QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDXXWvNED8fBVnVBU03 +sQ7smCuOFR36k0sXgiFxEFLXUWRwFsJVaU2OFW2fvwwbwuCjZ9YMrM8irq93VCpL +TIpTUnrD7i7es3ElweldPe6hL6P3KjzJIx1qqx2hp/Hz7KDVRM8Vz3IvHWOX6Jn5 +/ZOkVIBMUtRSqy5J35DNuF++P96hyk0g1CXohClTt7GIH//62pCfCqktQT+x8Rgp +7hZZLDRJGqgG16iI0gNyejLi6mhNbiyWZXvKWfry4t3uMCz7zEasxGPrb382KzRz +EpR/38wmnvFyXVBlWY9ps4deMm/DGIq1lY+wejfeWkU7xzbh72fROdOXW3NiGUgt +hxwG+3SYIElz8AXSG7Ggo7cbcNOIabla1jj0Ytwli3i/+Oh+uFzJlU9fpy25IGvP +a931DfSCt/SyZi4QKPaXWnuWFo8BGS1sbn85WAZkgwGDg8NNkt0yxoekN+kWzqot +aK8KgWU6cMGbrU1tVMoqLUuFG7OA5nBFDWteNfB/O7ic5ARwiRIlk9oKmSJgamNg +TnYGmE69g60dWIolhdLHZR4tjsbftsbhf4oEIRUpdPA+nJCdDC7xij5aqgwJHsfV +PKPtl8MeNPo4+QgO48BdK4PRVmrJtqhUUy54Mmc9gn900PvhtgVguXDbjgv5E1hv +cWAQUhC5wUEJ73IfZzF4/5YFjQIDAQABo2MwYTAfBgNVHSMEGDAWgBTj/i39KNAL +tbq2osS/BqoFjJP7LzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAd +BgNVHQ4EFgQU4/4t/SjQC7W6tqLEvwaqBYyT+y8wDQYJKoZIhvcNAQELBQADggIB +ACXGumvrh8vegjmWPfBEp2uEcwPenStPuiB/vHiyz5ewG5zz13ku9Ui20vsXiObT +ej/tUxPQ4i9qecsAIyjmHjdXNYmEwnZPNDatZ8POQQaIxffu2Bq41gt/UP+TqhdL +jOztUmCypAbqTuv0axn96/Ua4CUqmtzHQTb3yHQFhDmVOdYLO6Qn+gjYXB74BGBS +ESgoA//vU2YApUo0FmZ8/Qmkrp5nGm9BC2sGE5uPhnEFtC+NiWYzKXZUmhH4J/qy +P5Hgzg0b8zAarb8iXRvTvyUFTeGSGn+ZnzxEk8rUQElsgIfXBDrDMlI1Dlb4pd19 +xIsNER9Tyx6yF7Zod1rg1MvIB671Oi6ON7fQAUtDKXeMOZePglr4UeWJoBjnaH9d +Ci77o0cOPaYjesYBx4/IXr9tgFa+iiS6M+qf4TIRnvHST4D2G0CvOJ4RUHlzEhLN +5mydLIhyPDCBBpEi6lmt2hkuIsKNuYyH4Ga8cyNfIWRjgEj1oDwYPZTISEEdQLpe +/v5WOaHIz16eGWRGENoXkbcFgKyLmZJ956LYBws2J+dIeWCKw9cTXPhyQN9Ky8+Z +AAoACxGV2lZFA4gKn2fQ1XmxqI1AbQ3CekD6819kR5LLU7m7Wc5P/dAVUwHY3+vZ +5nbv0CO7O6l5s9UCKc2Jo5YPSjXnTkLAdc0Hz+Ys63su +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIHTzCCBTegAwIBAgIJAKPaQn6ksa7aMA0GCSqGSIb3DQEBBQUAMIGuMQswCQYD +VQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0 +IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3 +MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xKTAnBgNVBAMTIENoYW1iZXJz +IG9mIENvbW1lcmNlIFJvb3QgLSAyMDA4MB4XDTA4MDgwMTEyMjk1MFoXDTM4MDcz +MTEyMjk1MFowga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNlZSBj +dXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29tL2FkZHJlc3MpMRIw +EAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVyZmlybWEgUy5BLjEp +MCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDgwggIiMA0G +CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCvAMtwNyuAWko6bHiUfaN/Gh/2NdW9 +28sNRHI+JrKQUrpjOyhYb6WzbZSm891kDFX29ufyIiKAXuFixrYp4YFs8r/lfTJq +VKAyGVn+H4vXPWCGhSRv4xGzdz4gljUha7MI2XAuZPeEklPWDrCQiorjh40G072Q +DuKZoRuGDtqaCrsLYVAGUvGef3bsyw/QHg3PmTA9HMRFEFis1tPo1+XqxQEHd9ZR +5gN/ikilTWh1uem8nk4ZcfUyS5xtYBkL+8ydddy/Js2Pk3g5eXNeJQ7KXOt3EgfL +ZEFHcpOrUMPrCXZkNNI5t3YRCQ12RcSprj1qr7V9ZS+UWBDsXHyvfuK2GNnQm05a +Sd+pZgvMPMZ4fKecHePOjlO+Bd5gD2vlGts/4+EhySnB8esHnFIbAURRPHsl18Tl +UlRdJQfKFiC4reRB7noI/plvg6aRArBsNlVq5331lubKgdaX8ZSD6e2wsWsSaR6s ++12pxZjptFtYer49okQ6Y1nUCyXeG0+95QGezdIp1Z8XGQpvvwyQ0wlf2eOKNcx5 +Wk0ZN5K3xMGtr/R5JJqyAQuxr1yW84Ay+1w9mPGgP0revq+ULtlVmhduYJ1jbLhj +ya6BXBg14JC7vjxPNyK5fuvPnnchpj04gftI2jE9K+OJ9dC1vX7gUMQSibMjmhAx +hduub+84Mxh2EQIDAQABo4IBbDCCAWgwEgYDVR0TAQH/BAgwBgEB/wIBDDAdBgNV +HQ4EFgQU+SSsD7K1+HnA+mCIG8TZTQKeFxkwgeMGA1UdIwSB2zCB2IAU+SSsD7K1 ++HnA+mCIG8TZTQKeFxmhgbSkgbEwga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpN +YWRyaWQgKHNlZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29t +L2FkZHJlc3MpMRIwEAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVy +ZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAt +IDIwMDiCCQCj2kJ+pLGu2jAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRV +HSAAMCowKAYIKwYBBQUHAgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20w +DQYJKoZIhvcNAQEFBQADggIBAJASryI1wqM58C7e6bXpeHxIvj99RZJe6dqxGfwW +PJ+0W2aeaufDuV2I6A+tzyMP3iU6XsxPpcG1Lawk0lgH3qLPaYRgM+gQDROpI9CF +5Y57pp49chNyM/WqfcZjHwj0/gF/JM8rLFQJ3uIrbZLGOU8W6jx+ekbURWpGqOt1 +glanq6B8aBMz9p0w8G8nOSQjKpD9kCk18pPfNKXG9/jvjA9iSnyu0/VU+I22mlaH +FoI6M6taIgj3grrqLuBHmrS1RaMFO9ncLkVAO+rcf+g769HsJtg1pDDFOqxXnrN2 +pSB7+R5KBWIBpih1YJeSDW4+TTdDDZIVnBgizVGZoCkaPF+KMjNbMMeJL0eYD6MD +xvbxrN8y8NmBGuScvfaAFPDRLLmF9dijscilIeUcE5fuDr3fKanvNFNb0+RqE4QG +tjICxFKuItLcsiFCGtpA8CnJ7AoMXOLQusxI0zcKzBIKinmwPQN/aUv0NCB9szTq +jktk9T79syNnFQ0EuPAtwQlRPLJsFfClI9eDdOTlLsn+mCdCxqvGnrDQWzilm1De +fhiYtUU79nm06PcaewaD+9CL2rvHvRirCG88gGtAPxkZumWK5r7VXNM21+9AUiRg +OGcEMeyP84LG3rlV8zsxkVrctQgVrXYlCg17LofiDKYGvCYQbTed7N14jHyAxfDZ +d0jQ +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIID9zCCAt+gAwIBAgIESJ8AATANBgkqhkiG9w0BAQUFADCBijELMAkGA1UEBhMC +Q04xMjAwBgNVBAoMKUNoaW5hIEludGVybmV0IE5ldHdvcmsgSW5mb3JtYXRpb24g +Q2VudGVyMUcwRQYDVQQDDD5DaGluYSBJbnRlcm5ldCBOZXR3b3JrIEluZm9ybWF0 +aW9uIENlbnRlciBFViBDZXJ0aWZpY2F0ZXMgUm9vdDAeFw0xMDA4MzEwNzExMjVa +Fw0zMDA4MzEwNzExMjVaMIGKMQswCQYDVQQGEwJDTjEyMDAGA1UECgwpQ2hpbmEg +SW50ZXJuZXQgTmV0d29yayBJbmZvcm1hdGlvbiBDZW50ZXIxRzBFBgNVBAMMPkNo +aW5hIEludGVybmV0IE5ldHdvcmsgSW5mb3JtYXRpb24gQ2VudGVyIEVWIENlcnRp +ZmljYXRlcyBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAm35z +7r07eKpkQ0H1UN+U8i6yjUqORlTSIRLIOTJCBumD1Z9S7eVnAztUwYyZmczpwA// +DdmEEbK40ctb3B75aDFk4Zv6dOtouSCV98YPjUesWgbdYavi7NifFy2cyjw1l1Vx +zUOFsUcW9SxTgHbP0wBkvUCZ3czY28Sf1hNfQYOL+Q2HklY0bBoQCxfVWhyXWIQ8 +hBouXJE0bhlffxdpxWXvayHG1VA6v2G5BY3vbzQ6sm8UY78WO5upKv23KzhmBsUs +4qpnHkWnjQRmQvaPK++IIGmPMowUc9orhpFjIpryp9vOiYurXccUwVswah+xt54u +gQEC7c+WXmPbqOY4twIDAQABo2MwYTAfBgNVHSMEGDAWgBR8cks5x8DbYqVPm6oY +NJKiyoOCWTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4E +FgQUfHJLOcfA22KlT5uqGDSSosqDglkwDQYJKoZIhvcNAQEFBQADggEBACrDx0M3 +j92tpLIM7twUbY8opJhJywyA6vPtI2Z1fcXTIWd50XPFtQO3WKwMVC/GVhMPMdoG +52U7HW8228gd+f2ABsqjPWYWqJ1MFn3AlUa1UeTiH9fqBk1jjZaM7+czV0I664zB +echNdn3e9rG3geCg+aF4RhcaVpjwTj2rHO3sOdwHSPdj/gauwqRcalsyiMXHM4Ws +ZkJHwlgkmeHlPuV1LI5D1l08eB6olYIpUNHRFrrvwb562bTYzB5MRuF3sTGrvSrI +zo9uoV1/A3U05K2JRVRevq4opbs/eHnrc7MKDf2+yfdWrPa37S+bISnHOLaVxATy +wy39FCqQmbkHzJ8= +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIDVTCCAj2gAwIBAgIESTMAATANBgkqhkiG9w0BAQUFADAyMQswCQYDVQQGEwJD +TjEOMAwGA1UEChMFQ05OSUMxEzARBgNVBAMTCkNOTklDIFJPT1QwHhcNMDcwNDE2 +MDcwOTE0WhcNMjcwNDE2MDcwOTE0WjAyMQswCQYDVQQGEwJDTjEOMAwGA1UEChMF +Q05OSUMxEzARBgNVBAMTCkNOTklDIFJPT1QwggEiMA0GCSqGSIb3DQEBAQUAA4IB +DwAwggEKAoIBAQDTNfc/c3et6FtzF8LRb+1VvG7q6KR5smzDo+/hn7E7SIX1mlwh +IhAsxYLO2uOabjfhhyzcuQxauohV3/2q2x8x6gHx3zkBwRP9SFIhxFXf2tizVHa6 +dLG3fdfA6PZZxU3Iva0fFNrfWEQlMhkqx35+jq44sDB7R3IJMfAw28Mbdim7aXZO +V/kbZKKTVrdvmW7bCgScEeOAH8tjlBAKqeFkgjH5jCftppkA9nCTGPihNIaj3XrC +GHn2emU1z5DrvTOTn1OrczvmmzQgLx3vqR1jGqCA2wMv+SYahtKNu6m+UjqHZ0gN +v7Sg2Ca+I19zN38m5pIEo3/PIKe38zrKy5nLAgMBAAGjczBxMBEGCWCGSAGG+EIB +AQQEAwIABzAfBgNVHSMEGDAWgBRl8jGtKvf33VKWCscCwQ7vptU7ETAPBgNVHRMB +Af8EBTADAQH/MAsGA1UdDwQEAwIB/jAdBgNVHQ4EFgQUZfIxrSr3991SlgrHAsEO +76bVOxEwDQYJKoZIhvcNAQEFBQADggEBAEs17szkrr/Dbq2flTtLP1se31cpolnK +OOK5Gv+e5m4y3R6u6jW39ZORTtpC4cMXYFDy0VwmuYK36m3knITnA3kXr5g9lNvH +ugDnuL8BV8F3RTIMO/G0HAiw/VGgod2aHRM2mm23xzy54cXZF/qD1T0VoDy7Hgvi +yJA/qIYM/PmLXoXLT1tLYhFHxUV8BS9BsZ4QaRuZluBVeftOhpm4lNqGOGqTo+fL +buXf6iFViZx9fX+Y9QCJ7uOEwFyWtcVG6kbghVW2G8kS1sHNzYDzAgE8yGnLRUhj +2JTQ7IUOO04RZfSCjKY9ri4ilAnIXOo8gV0WKgOXFlUJ24pBgp5mmxE= +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCB +gTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G +A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNV +BAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEyMDEwMDAw +MDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3Jl +YXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01P +RE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0 +aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3 +UcEbVASY06m/weaKXTuH+7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI +2GqGd0S7WWaXUF601CxwRM/aN5VCaTwwxHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8 +Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV4EajcNxo2f8ESIl33rXp ++2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA1KGzqSX+ +DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5O +nKVIrLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW +/zAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6g +PKA6hjhodHRwOi8vY3JsLmNvbW9kb2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9u +QXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOCAQEAPpiem/Yb6dc5t3iuHXIY +SdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CPOGEIqB6BCsAv +IC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/ +RxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4 +zJVSk/BwJVmcIGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5dd +BA6+C4OmF4O5MBKgxTMVBbkN+8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IB +ZQ== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTEL +MAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE +BxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMT +IkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwMzA2MDAw +MDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdy +ZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09N +T0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlv +biBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSR +FtSrYpn1PlILBs5BAH+X4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0J +cfRK9ChQtP6IHG4/bC8vCVlbpVsLM5niwz2J+Wos77LTBumjQjBAMB0GA1UdDgQW +BBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ +BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VGFAkK+qDm +fQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdv +GDeAU/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY= +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIF2DCCA8CgAwIBAgIQTKr5yttjb+Af907YWwOGnTANBgkqhkiG9w0BAQwFADCB +hTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G +A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNV +BAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMTE5 +MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgT +EkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR +Q09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCR +6FSS0gpWsawNJN3Fz0RndJkrN6N9I3AAcbxT38T6KhKPS38QVr2fcHK3YX/JSw8X +pz3jsARh7v8Rl8f0hj4K+j5c+ZPmNHrZFGvnnLOFoIJ6dq9xkNfs/Q36nGz637CC +9BR++b7Epi9Pf5l/tfxnQ3K9DADWietrLNPtj5gcFKt+5eNu/Nio5JIk2kNrYrhV +/erBvGy2i/MOjZrkm2xpmfh4SDBF1a3hDTxFYPwyllEnvGfDyi62a+pGx8cgoLEf +Zd5ICLqkTqnyg0Y3hOvozIFIQ2dOciqbXL1MGyiKXCJ7tKuY2e7gUYPDCUZObT6Z ++pUX2nwzV0E8jVHtC7ZcryxjGt9XyD+86V3Em69FmeKjWiS0uqlWPc9vqv9JWL7w +qP/0uK3pN/u6uPQLOvnoQ0IeidiEyxPx2bvhiWC4jChWrBQdnArncevPDt09qZah +SL0896+1DSJMwBGB7FY79tOi4lu3sgQiUpWAk2nojkxl8ZEDLXB0AuqLZxUpaVIC +u9ffUGpVRr+goyhhf3DQw6KqLCGqR84onAZFdr+CGCe01a60y1Dma/RMhnEw6abf +Fobg2P9A3fvQQoh/ozM6LlweQRGBY84YcWsr7KaKtzFcOmpH4MN5WdYgGq/yapiq +crxXStJLnbsQ/LBMQeXtHT1eKJ2czL+zUdqnR+WEUwIDAQABo0IwQDAdBgNVHQ4E +FgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB +/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAArx1UaEt65Ru2yyTUEUAJNMnMvl +wFTPoCWOAvn9sKIN9SCYPBMtrFaisNZ+EZLpLrqeLppysb0ZRGxhNaKatBYSaVqM +4dc+pBroLwP0rmEdEBsqpIt6xf4FpuHA1sj+nq6PK7o9mfjYcwlYRm6mnPTXJ9OV +2jeDchzTc+CiR5kDOF3VSXkAKRzH7JsgHAckaVd4sjn8OoSgtZx8jb8uk2Intzna +FxiuvTwJaP+EmzzV1gsD41eeFPfR60/IvYcjt7ZJQ3mFXLrrkguhxuhoqEwWsRqZ +CuhTLJK7oQkYdQxlqHvLI7cawiiFwxv/0Cti76R7CZGYZ4wUAc1oBmpjIXUDgIiK +boHGhfKppC3n9KUkEEeDys30jXlYsQab5xoq2Z0B15R97QNKyvDb6KkBPvVWmcke +jkk9u+UJueBPSZI9FoJAzMxZxuY67RIuaTxslbH9qh17f4a+Hg4yRvv7E491f0yL +S0Zj/gA0QHDBw7mh3aZw4gSzQbzpgJHqZJx64SIDqZxubw5lT2yHh17zbqD5daWb +QOhTsiedSrnAdyGN/4fy3ryM7xfft0kL0fJuMAsaDk527RH89elWsn2/x20Kk4yl +0MC2Hb46TpSi125sC8KKfPog88Tk5c0NqMuRkrF8hey1FGlmDoLnzc7ILaZRfyHB +NVOFBkpdn627G190 +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIDkzCCAnugAwIBAgIQFBOWgxRVjOp7Y+X8NId3RDANBgkqhkiG9w0BAQUFADA0 +MRMwEQYDVQQDEwpDb21TaWduIENBMRAwDgYDVQQKEwdDb21TaWduMQswCQYDVQQG +EwJJTDAeFw0wNDAzMjQxMTMyMThaFw0yOTAzMTkxNTAyMThaMDQxEzARBgNVBAMT +CkNvbVNpZ24gQ0ExEDAOBgNVBAoTB0NvbVNpZ24xCzAJBgNVBAYTAklMMIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8ORUaSvTx49qROR+WCf4C9DklBKK +8Rs4OC8fMZwG1Cyn3gsqrhqg455qv588x26i+YtkbDqthVVRVKU4VbirgwTyP2Q2 +98CNQ0NqZtH3FyrV7zb6MBBC11PN+fozc0yz6YQgitZBJzXkOPqUm7h65HkfM/sb +2CEJKHxNGGleZIp6GZPKfuzzcuc3B1hZKKxC+cX/zT/npfo4sdAMx9lSGlPWgcxC +ejVb7Us6eva1jsz/D3zkYDaHL63woSV9/9JLEYhwVKZBqGdTUkJe5DSe5L6j7Kpi +Xd3DTKaCQeQzC6zJMw9kglcq/QytNuEMrkvF7zuZ2SOzW120V+x0cAwqTwIDAQAB +o4GgMIGdMAwGA1UdEwQFMAMBAf8wPQYDVR0fBDYwNDAyoDCgLoYsaHR0cDovL2Zl +ZGlyLmNvbXNpZ24uY28uaWwvY3JsL0NvbVNpZ25DQS5jcmwwDgYDVR0PAQH/BAQD +AgGGMB8GA1UdIwQYMBaAFEsBmz5WGmU2dst7l6qSBe4y5ygxMB0GA1UdDgQWBBRL +AZs+VhplNnbLe5eqkgXuMucoMTANBgkqhkiG9w0BAQUFAAOCAQEA0Nmlfv4pYEWd +foPPbrxHbvUanlR2QnG0PFg/LUAlQvaBnPGJEMgOqnhPOAlXsDzACPw1jvFIUY0M +cXS6hMTXcpuEfDhOZAYnKuGntewImbQKDdSFc8gS4TXt8QUxHXOZDOuWyt3T5oWq +8Ir7dcHyCTxlZWTzTNity4hp8+SDtwy9F1qWF8pb/627HOkthIDYIb6FUtnUdLlp +hbpN7Sgy6/lhSuTENh4Z3G+EER+V9YMoGKgzkkMn3V0TBEVPh9VGzT2ouvDzuFYk +Res3x+F2T3I5GN9+dHLHcy056mDmrRGiVod7w2ia/viMcKjfZTL0pECMocJEAw6U +AGegcQCCSA== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIDqzCCApOgAwIBAgIRAMcoRwmzuGxFjB36JPU2TukwDQYJKoZIhvcNAQEFBQAw +PDEbMBkGA1UEAxMSQ29tU2lnbiBTZWN1cmVkIENBMRAwDgYDVQQKEwdDb21TaWdu +MQswCQYDVQQGEwJJTDAeFw0wNDAzMjQxMTM3MjBaFw0yOTAzMTYxNTA0NTZaMDwx +GzAZBgNVBAMTEkNvbVNpZ24gU2VjdXJlZCBDQTEQMA4GA1UEChMHQ29tU2lnbjEL +MAkGA1UEBhMCSUwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDGtWhf +HZQVw6QIVS3joFd67+l0Kru5fFdJGhFeTymHDEjWaueP1H5XJLkGieQcPOqs49oh +gHMhCu95mGwfCP+hUH3ymBvJVG8+pSjsIQQPRbsHPaHA+iqYHU4Gk/v1iDurX8sW +v+bznkqH7Rnqwp9D5PGBpX8QTz7RSmKtUxvLg/8HZaWSLWapW7ha9B20IZFKF3ue +Mv5WJDmyVIRD9YTC2LxBkMyd1mja6YJQqTtoz7VdApRgFrFD2UNd3V2Hbuq7s8lr +9gOUCXDeFhF6K+h2j0kQmHe5Y1yLM5d19guMsqtb3nQgJT/j8xH5h2iGNXHDHYwt +6+UarA9z1YJZQIDTAgMBAAGjgacwgaQwDAYDVR0TBAUwAwEB/zBEBgNVHR8EPTA7 +MDmgN6A1hjNodHRwOi8vZmVkaXIuY29tc2lnbi5jby5pbC9jcmwvQ29tU2lnblNl +Y3VyZWRDQS5jcmwwDgYDVR0PAQH/BAQDAgGGMB8GA1UdIwQYMBaAFMFL7XC29z58 +ADsAj8c+DkWfHl3sMB0GA1UdDgQWBBTBS+1wtvc+fAA7AI/HPg5Fnx5d7DANBgkq +hkiG9w0BAQUFAAOCAQEAFs/ukhNQq3sUnjO2QiBq1BW9Cav8cujvR3qQrFHBZE7p +iL1DRYHjZiM/EoZNGeQFsOY3wo3aBijJD4mkU6l1P7CW+6tMM1X5eCZGbxs2mPtC +dsGCuY7e+0X5YxtiOzkGynd6qDwJz2w2PQ8KRUtpFhpFfTMDZflScZAmlaxMDPWL +kz/MdXSFmLr/YnpNH4n+rr2UAJm/EaXc4HnFFgt9AmEd6oX5AhVP51qJThRv4zdL +hfXBPGHg/QVBspJ/wx2g0K5SZGBrGMYmnNj1ZOQ2GmKfig8+/21OGVZOIJFsnzQz +OjRXUDpvgV4GxvU+fE6OK85lBi5d0ipTdF7Tbieejw== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIDoTCCAomgAwIBAgILBAAAAAABD4WqLUgwDQYJKoZIhvcNAQEFBQAwOzEYMBYG +A1UEChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2Jh +bCBSb290MB4XDTA2MTIxNTA4MDAwMFoXDTIxMTIxNTA4MDAwMFowOzEYMBYGA1UE +ChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2JhbCBS +b290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA+Mi8vRRQZhP/8NN5 +7CPytxrHjoXxEnOmGaoQ25yiZXRadz5RfVb23CO21O1fWLE3TdVJDm71aofW0ozS +J8bi/zafmGWgE07GKmSb1ZASzxQG9Dvj1Ci+6A74q05IlG2OlTEQXO2iLb3VOm2y +HLtgwEZLAfVJrn5GitB0jaEMAs7u/OePuGtm839EAL9mJRQr3RAwHQeWP032a7iP +t3sMpTjr3kfb1V05/Iin89cqdPHoWqI7n1C6poxFNcJQZZXcY4Lv3b93TZxiyWNz +FtApD0mpSPCzqrdsxacwOUBdrsTiXSZT8M4cIwhhqJQZugRiQOwfOHB3EgZxpzAY +XSUnpQIDAQABo4GlMIGiMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/ +MB0GA1UdDgQWBBS2CHsNesysIEyGVjJez6tuhS1wVzA/BgNVHR8EODA2MDSgMqAw +hi5odHRwOi8vd3d3Mi5wdWJsaWMtdHJ1c3QuY29tL2NybC9jdC9jdHJvb3QuY3Js +MB8GA1UdIwQYMBaAFLYIew16zKwgTIZWMl7Pq26FLXBXMA0GCSqGSIb3DQEBBQUA +A4IBAQBW7wojoFROlZfJ+InaRcHUowAl9B8Tq7ejhVhpwjCt2BWKLePJzYFa+HMj +Wqd8BfP9IjsO0QbE2zZMcwSO5bAi5MXzLqXZI+O4Tkogp24CJJ8iYGd7ix1yCcUx +XOl5n4BHPa2hCwcUPUf/A2kaDAtE52Mlp3+yybh2hO0j9n0Hq0V+09+zv+mKts2o +omcrUtW3ZfA5TGOgkXmTUg9U3YO7n9GPp1Nzw8v/MOx8BLjYRB+TX3EJIrduPuoc +A06dGiBh+4E37F78CkWr1+cXVdCg6mCbpvbjjFspwgZgFJ0tl0ypkxWdYcQBX0jW +WL1WMRJOEcgh4LMRkWXbtKaIOM5V +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIDnzCCAoegAwIBAgIBJjANBgkqhkiG9w0BAQUFADBxMQswCQYDVQQGEwJERTEc +MBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxlU2Vj +IFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290IENB +IDIwHhcNOTkwNzA5MTIxMTAwWhcNMTkwNzA5MjM1OTAwWjBxMQswCQYDVQQGEwJE +RTEcMBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxl +U2VjIFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290 +IENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrC6M14IspFLEU +ha88EOQ5bzVdSq7d6mGNlUn0b2SjGmBmpKlAIoTZ1KXleJMOaAGtuU1cOs7TuKhC +QN/Po7qCWWqSG6wcmtoIKyUn+WkjR/Hg6yx6m/UTAtB+NHzCnjwAWav12gz1Mjwr +rFDa1sPeg5TKqAyZMg4ISFZbavva4VhYAUlfckE8FQYBjl2tqriTtM2e66foai1S +NNs671x1Udrb8zH57nGYMsRUFUQM+ZtV7a3fGAigo4aKSe5TBY8ZTNXeWHmb0moc +QqvF1afPaA+W5OFhmHZhyJF81j4A4pFQh+GdCuatl9Idxjp9y7zaAzTVjlsB9WoH +txa2bkp/AgMBAAGjQjBAMB0GA1UdDgQWBBQxw3kbuvVT1xfgiXotF2wKsyudMzAP +BgNVHRMECDAGAQH/AgEFMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOC +AQEAlGRZrTlk5ynrE/5aw4sTV8gEJPB0d8Bg42f76Ymmg7+Wgnxu1MM9756Abrsp +tJh6sTtU6zkXR34ajgv8HzFZMQSyzhfzLMdiNlXiItiJVbSYSKpk+tYcNthEeFpa +IzpXl/V6ME+un2pMSyuOoAPjPuCp1NJ70rOo4nI8rZ7/gFnkm0W09juwzTkZmDLl +6iFhkOQxIY40sfcvNUqFENrnijchvllj4PKFiDFT1FQUhXB59C4Gdyd1Lx+4ivn+ +xbrYNuSD7Odlt79jWvNGr4GUN9RBjNYj1h7P9WgbRGOiWrqnNVmh5XAFmw4jV5mU +Cm26OWMohpLzGITY+9HPBVZkVw== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIDljCCAn6gAwIBAgIQC5McOtY5Z+pnI7/Dr5r0SzANBgkqhkiG9w0BAQsFADBl +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv +b3QgRzIwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl +cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZ5ygvUj82ckmIkzTz+GoeMVSA +n61UQbVH35ao1K+ALbkKz3X9iaV9JPrjIgwrvJUXCzO/GU1BBpAAvQxNEP4Htecc +biJVMWWXvdMX0h5i89vqbFCMP4QMls+3ywPgym2hFEwbid3tALBSfK+RbLE4E9Hp +EgjAALAcKxHad3A2m67OeYfcgnDmCXRwVWmvo2ifv922ebPynXApVfSr/5Vh88lA +bx3RvpO704gqu52/clpWcTs/1PPRCv4o76Pu2ZmvA9OPYLfykqGxvYmJHzDNw6Yu +YjOuFgJ3RFrngQo8p0Quebg/BLxcoIfhG69Rjs3sLPr4/m3wOnyqi+RnlTGNAgMB +AAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQW +BBTOw0q5mVXyuNtgv6l+vVa1lzan1jANBgkqhkiG9w0BAQsFAAOCAQEAyqVVjOPI +QW5pJ6d1Ee88hjZv0p3GeDgdaZaikmkuOGybfQTUiaWxMTeKySHMq2zNixya1r9I +0jJmwYrA8y8678Dj1JGG0VDjA9tzd29KOVPt3ibHtX2vK0LRdWLjSisCx1BL4Gni +lmwORGYQRI+tBev4eaymG+g3NJ1TyWGqolKvSnAWhsI6yLETcDbYz+70CjTVW0z9 +B5yiutkBclzzTcHdDrEcDcRjvq30FPuJ7KJBDkzMyFdA0G4Dqs0MjomZmWzwPDCv +ON9vvKO+KSAnq3T/EyJ43pdSVR6DtVQgA+6uwE9W3jfMw3+qBCe703e4YtsXfJwo +IhNzbM8m9Yop5w== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIICRjCCAc2gAwIBAgIQC6Fa+h3foLVJRK/NJKBs7DAKBggqhkjOPQQDAzBlMQsw +CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu +ZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3Qg +RzMwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQGEwJV +UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu +Y29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwdjAQBgcq +hkjOPQIBBgUrgQQAIgNiAAQZ57ysRGXtzbg/WPuNsVepRC0FFfLvC/8QdJ+1YlJf +Zn4f5dwbRXkLzMZTCp2NXQLZqVneAlr2lSoOjThKiknGvMYDOAdfVdp+CW7if17Q +RSAPWXYQ1qAk8C3eNvJsKTmjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/ +BAQDAgGGMB0GA1UdDgQWBBTL0L2p4ZgFUaFNN6KDec6NHSrkhDAKBggqhkjOPQQD +AwNnADBkAjAlpIFFAmsSS3V0T8gj43DydXLefInwz5FyYZ5eEJJZVrmDxxDnOOlY +JjZ91eQ0hjkCMHw2U/Aw5WJjOpnitqM7mzT6HtoQknFekROn3aRukswy1vUhZscv +6pZjamVFkpUBtA== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH +MjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j +b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI +2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx +1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ +q2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz +tCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ +vIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo0IwQDAP +BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV +5uNu5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY +1Yl9PMWLSn/pvtsrF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4 +NeF22d+mQrvHRAiGfzZ0JFrabA0UWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NG +Fdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91 +8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe +pLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl +MrY= +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIICPzCCAcWgAwIBAgIQBVVWvPJepDU1w6QP1atFcjAKBggqhkjOPQQDAzBhMQsw +CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu +ZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMzAe +Fw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVTMRUw +EwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20x +IDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEczMHYwEAYHKoZIzj0CAQYF +K4EEACIDYgAE3afZu4q4C/sLfyHS8L6+c/MzXRq8NOrexpu80JX28MzQC7phW1FG +fp4tn+6OYwwX7Adw9c+ELkCDnOg/QW07rdOkFFk2eJ0DQ+4QE2xy3q6Ip6FrtUPO +Z9wj/wMco+I+o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAd +BgNVHQ4EFgQUs9tIpPmhxdiuNkHMEWNpYim8S8YwCgYIKoZIzj0EAwMDaAAwZQIx +AK288mw/EkrRLTnDCgmXc/SINoyIJ7vmiI1Qhadj+Z4y3maTD/HMsQmP3Wyr+mt/ +oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34VOKa5Vt8 +sycX +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIFkDCCA3igAwIBAgIQBZsbV56OITLiOQe9p3d1XDANBgkqhkiG9w0BAQwFADBi +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3Qg +RzQwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBiMQswCQYDVQQGEwJV +UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu +Y29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz7MKnJS7JIT3y +ithZwuEppz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS5F/WBTxSD1If +xp4VpX6+n6lXFllVcq9ok3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7bXHiLQwb7iDV +ySAdYyktzuxeTsiT+CFhmzTrBcZe7FsavOvJz82sNEBfsXpm7nfISKhmV1efVFiO +DCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGYQJB5w3jHtrHEtWoYOAMQ +jdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14Ztk6MUSaM0C/ +CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2h4mXaXpI8OCi +EhtmmnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt6zPZxd9LBADM +fRyVw4/3IbKyEbe7f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPRiQfhvbfmQ6QY +uKZ3AeEPlAwhHbJUKSWJbOUOUlFHdL4mrLZBdd56rF+NP8m800ERElvlEFDrMcXK +chYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8oR7FwI+isX4KJpn15GkvmB0t +9dmpsh3lGwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +hjAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wDQYJKoZIhvcNAQEMBQAD +ggIBALth2X2pbL4XxJEbw6GiAI3jZGgPVs93rnD5/ZpKmbnJeFwMDF/k5hQpVgs2 +SV1EY+CtnJYYZhsjDT156W1r1lT40jzBQ0CuHVD1UvyQO7uYmWlrx8GnqGikJ9yd ++SeuMIW59mdNOj6PWTkiU0TryF0Dyu1Qen1iIQqAyHNm0aAFYF/opbSnr6j3bTWc +fFqK1qI4mfN4i/RN0iAL3gTujJtHgXINwBQy7zBZLq7gcfJW5GqXb5JQbZaNaHqa +sjYUegbyJLkJEVDXCLG4iXqEI2FCKeWjzaIgQdfRnGTZ6iahixTXTBmyUEFxPT9N +cCOGDErcgdLMMpSEDQgJlxxPwO5rIHQw0uA5NBCFIRUBCOhVMt5xSdkoF1BN5r5N +0XWs0Mr7QbhDparTwwVETyw2m+L64kW4I1NsBm9nVX9GtUw/bihaeSbSpKhil9Ie +4u1Ki7wb/UdKDd9nZn6yW0HQO+T0O/QEY+nvwlQAUaCKKsnOeMzV6ocEGLPOr0mI +r/OSmbaz5mEP0oUA51Aa5BuVnRmhuZyxm7EAHu/QD09CbMkKvO5D+jpxpchNJqU1 +/YldvIViHTLSoCtU7ZpXwdv6EM8Zt4tKG48BtieVU+i2iW1bvGjUI+iLUaJW+fCm +gKDWHrO8Dw9TdSmq6hN35N6MgSGtBxBHEa2HPQfRdbzP82Z+ +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIECTCCAvGgAwIBAgIQDV6ZCtadt3js2AdWO4YV2TANBgkqhkiG9w0BAQUFADBb +MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3Qx +ETAPBgNVBAsTCERTVCBBQ0VTMRcwFQYDVQQDEw5EU1QgQUNFUyBDQSBYNjAeFw0w +MzExMjAyMTE5NThaFw0xNzExMjAyMTE5NThaMFsxCzAJBgNVBAYTAlVTMSAwHgYD +VQQKExdEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdDERMA8GA1UECxMIRFNUIEFDRVMx +FzAVBgNVBAMTDkRTVCBBQ0VTIENBIFg2MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAuT31LMmU3HWKlV1j6IR3dma5WZFcRt2SPp/5DgO0PWGSvSMmtWPu +ktKe1jzIDZBfZIGxqAgNTNj50wUoUrQBJcWVHAx+PhCEdc/BGZFjz+iokYi5Q1K7 +gLFViYsx+tC3dr5BPTCapCIlF3PoHuLTrCq9Wzgh1SpL11V94zpVvddtawJXa+ZH +fAjIgrrep4c9oW24MFbCswKBXy314powGCi4ZtPLAZZv6opFVdbgnf9nKxcCpk4a +ahELfrd755jWjHZvwTvbUJN+5dCOHze4vbrGn2zpfDPyMjwmR/onJALJfh1biEIT +ajV8fTXpLmaRcpPVMibEdPVTo7NdmvYJywIDAQABo4HIMIHFMA8GA1UdEwEB/wQF +MAMBAf8wDgYDVR0PAQH/BAQDAgHGMB8GA1UdEQQYMBaBFHBraS1vcHNAdHJ1c3Rk +c3QuY29tMGIGA1UdIARbMFkwVwYKYIZIAWUDAgEBATBJMEcGCCsGAQUFBwIBFjto +dHRwOi8vd3d3LnRydXN0ZHN0LmNvbS9jZXJ0aWZpY2F0ZXMvcG9saWN5L0FDRVMt +aW5kZXguaHRtbDAdBgNVHQ4EFgQUCXIGThhDD+XWzMNqizF7eI+og7gwDQYJKoZI +hvcNAQEFBQADggEBAKPYjtay284F5zLNAdMEA+V25FYrnJmQ6AgwbN99Pe7lv7Uk +QIRJ4dEorsTCOlMwiPH1d25Ryvr/ma8kXxug/fKshMrfqfBfBC6tFr8hlxCBPeP/ +h40y3JTlR4peahPJlJU90u7INJXQgNStMgiAVDzgvVJT11J8smk/f3rPanTK+gQq +nExaBqXpIK1FZg9p8d2/6eMyi/rgwYZNcjwu2JN4Cir42NInPRmJX1p7ijvMDNpR +rscL9yuwNwXsvFcj4jjSm2jzVhKIT0J8uDHEtdvkyCE06UgRNe76x5JXxZ805Mf2 +9w4LTJxoeHtxMcfrHuBnQfO3oKfN5XozNmr6mis= +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/ +MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT +DkRTVCBSb290IENBIFgzMB4XDTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVow +PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD +Ew5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +AN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmTrE4O +rz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEq +OLl5CjH9UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9b +xiqKqy69cK3FCxolkHRyxXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw +7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40dutolucbY38EVAjqr2m7xPi71XAicPNaD +aeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV +HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQMA0GCSqG +SIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69 +ikugdB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXr +AvHRAosZy5Q6XkjEGB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZz +R8srzJmwN0jP41ZL9c8PDHIyh8bwRLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5 +JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL+T0yjWW06XyxV3bqxbYo +Ob8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIEMzCCAxugAwIBAgIDCYPzMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNVBAYTAkRF +MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBD +bGFzcyAzIENBIDIgMjAwOTAeFw0wOTExMDUwODM1NThaFw0yOTExMDUwODM1NTha +ME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMM +HkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBANOySs96R+91myP6Oi/WUEWJNTrGa9v+2wBoqOADER03 +UAifTUpolDWzU9GUY6cgVq/eUXjsKj3zSEhQPgrfRlWLJ23DEE0NkVJD2IfgXU42 +tSHKXzlABF9bfsyjxiupQB7ZNoTWSPOSHjRGICTBpFGOShrvUD9pXRl/RcPHAY9R +ySPocq60vFYJfxLLHLGvKZAKyVXMD9O0Gu1HNVpK7ZxzBCHQqr0ME7UAyiZsxGsM +lFqVlNpQmvH/pStmMaTJOKDfHR+4CS7zp+hnUquVH+BGPtikw8paxTGA6Eian5Rp +/hnd2HN8gcqW3o7tszIFZYQ05ub9VxC1X3a/L7AQDcUCAwEAAaOCARowggEWMA8G +A1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP3aFMSfMN4hvR5COfyrYyNJ4PGEMA4G +A1UdDwEB/wQEAwIBBjCB0wYDVR0fBIHLMIHIMIGAoH6gfIZ6bGRhcDovL2RpcmVj +dG9yeS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwUm9vdCUyMENsYXNzJTIwMyUy +MENBJTIwMiUyMDIwMDksTz1ELVRydXN0JTIwR21iSCxDPURFP2NlcnRpZmljYXRl +cmV2b2NhdGlvbmxpc3QwQ6BBoD+GPWh0dHA6Ly93d3cuZC10cnVzdC5uZXQvY3Js +L2QtdHJ1c3Rfcm9vdF9jbGFzc18zX2NhXzJfMjAwOS5jcmwwDQYJKoZIhvcNAQEL +BQADggEBAH+X2zDI36ScfSF6gHDOFBJpiBSVYEQBrLLpME+bUMJm2H6NMLVwMeni +acfzcNsgFYbQDfC+rAF1hM5+n02/t2A7nPPKHeJeaNijnZflQGDSNiH+0LS4F9p0 +o3/U37CYAqxva2ssJSRyoWXuJVrl5jLn8t+rSfrzkGkj2wTZ51xY/GXUl77M/C4K +zCUqNQT4YJEVdT1B/yMfGchs64JTBKbkTCJNjYy6zltz7GRUUG3RnFX7acM2w4y8 +PIWmawomDeCTmGCufsYkl4phX5GOZpIJhzbNi5stPvZR1FDUWSi9g/LMKHtThm3Y +Johw1+qRzT65ysCQblrGXnRl11z+o+I= +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIEQzCCAyugAwIBAgIDCYP0MA0GCSqGSIb3DQEBCwUAMFAxCzAJBgNVBAYTAkRF +MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBD +bGFzcyAzIENBIDIgRVYgMjAwOTAeFw0wOTExMDUwODUwNDZaFw0yOTExMDUwODUw +NDZaMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNV +BAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAwOTCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAJnxhDRwui+3MKCOvXwEz75ivJn9gpfSegpn +ljgJ9hBOlSJzmY3aFS3nBfwZcyK3jpgAvDw9rKFs+9Z5JUut8Mxk2og+KbgPCdM0 +3TP1YtHhzRnp7hhPTFiu4h7WDFsVWtg6uMQYZB7jM7K1iXdODL/ZlGsTl28So/6Z +qQTMFexgaDbtCHu39b+T7WYxg4zGcTSHThfqr4uRjRxWQa4iN1438h3Z0S0NL2lR +p75mpoo6Kr3HGrHhFPC+Oh25z1uxav60sUYgovseO3Dvk5h9jHOW8sXvhXCtKSb8 +HgQ+HKDYD8tSg2J87otTlZCpV6LqYQXY+U3EJ/pure3511H3a6UCAwEAAaOCASQw +ggEgMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNOUikxiEyoZLsyvcop9Ntea +HNxnMA4GA1UdDwEB/wQEAwIBBjCB3QYDVR0fBIHVMIHSMIGHoIGEoIGBhn9sZGFw +Oi8vZGlyZWN0b3J5LmQtdHJ1c3QubmV0L0NOPUQtVFJVU1QlMjBSb290JTIwQ2xh +c3MlMjAzJTIwQ0ElMjAyJTIwRVYlMjAyMDA5LE89RC1UcnVzdCUyMEdtYkgsQz1E +RT9jZXJ0aWZpY2F0ZXJldm9jYXRpb25saXN0MEagRKBChkBodHRwOi8vd3d3LmQt +dHJ1c3QubmV0L2NybC9kLXRydXN0X3Jvb3RfY2xhc3NfM19jYV8yX2V2XzIwMDku +Y3JsMA0GCSqGSIb3DQEBCwUAA4IBAQA07XtaPKSUiO8aEXUHL7P+PPoeUSbrh/Yp +3uDx1MYkCenBz1UbtDDZzhr+BlGmFaQt77JLvyAoJUnRpjZ3NOhk31KxEcdzes05 +nsKtjHEh8lprr988TlWvsoRlFIm5d8sqMb7Po23Pb0iUMkZv53GMoKaEGTcH8gNF +CSuGdXzfX2lXANtu2KZyIktQ1HWYVt+3GP9DQ1CuekR78HlR10M9p9OB0/DJT7na +xpeG0ILD5EJt/rDiZE4OJudANCa1CInXCGNjOCd1HjPqbqjdn5lPdE2BiYBL3ZqX +KVwvvoFBuYz/6n1gBp7N1z3TLqMVvKjmJuVvw9y4AyHqnxbxLFS1 +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIF5zCCA8+gAwIBAgIITK9zQhyOdAIwDQYJKoZIhvcNAQEFBQAwgYAxODA2BgNV +BAMML0VCRyBFbGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sx +c8SxMTcwNQYDVQQKDC5FQkcgQmlsacWfaW0gVGVrbm9sb2ppbGVyaSB2ZSBIaXpt +ZXRsZXJpIEEuxZ4uMQswCQYDVQQGEwJUUjAeFw0wNjA4MTcwMDIxMDlaFw0xNjA4 +MTQwMDMxMDlaMIGAMTgwNgYDVQQDDC9FQkcgRWxla3Ryb25payBTZXJ0aWZpa2Eg +SGl6bWV0IFNhxJ9sYXnEsWPEsXPEsTE3MDUGA1UECgwuRUJHIEJpbGnFn2ltIFRl +a25vbG9qaWxlcmkgdmUgSGl6bWV0bGVyaSBBLsWeLjELMAkGA1UEBhMCVFIwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDuoIRh0DpqZhAy2DE4f6en5f2h +4fuXd7hxlugTlkaDT7byX3JWbhNgpQGR4lvFzVcfd2NR/y8927k/qqk153nQ9dAk +tiHq6yOU/im/+4mRDGSaBUorzAzu8T2bgmmkTPiab+ci2hC6X5L8GCcKqKpE+i4s +tPtGmggDg3KriORqcsnlZR9uKg+ds+g75AxuetpX/dfreYteIAbTdgtsApWjluTL +dlHRKJ2hGvxEok3MenaoDT2/F08iiFD9rrbskFBKW5+VQarKD7JK/oCZTqNGFav4 +c0JqwmZ2sQomFd2TkuzbqV9UIlKRcF0T6kjsbgNs2d1s/OsNA/+mgxKb8amTD8Um +TDGyY5lhcucqZJnSuOl14nypqZoaqsNW2xCaPINStnuWt6yHd6i58mcLlEOzrz5z ++kI2sSXFCjEmN1ZnuqMLfdb3ic1nobc6HmZP9qBVFCVMLDMNpkGMvQQxahByCp0O +Lna9XvNRiYuoP1Vzv9s6xiQFlpJIqkuNKgPlV5EQ9GooFW5Hd4RcUXSfGenmHmMW +OeMRFeNYGkS9y8RsZteEBt8w9DeiQyJ50hBs37vmExH8nYQKE3vwO9D8owrXieqW +fo1IhR5kX9tUoqzVegJ5a9KK8GfaZXINFHDk6Y54jzJ0fFfy1tb0Nokb+Clsi7n2 +l9GkLqq+CxnCRelwXQIDAJ3Zo2MwYTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB +/wQEAwIBBjAdBgNVHQ4EFgQU587GT/wWZ5b6SqMHwQSny2re2kcwHwYDVR0jBBgw +FoAU587GT/wWZ5b6SqMHwQSny2re2kcwDQYJKoZIhvcNAQEFBQADggIBAJuYml2+ +8ygjdsZs93/mQJ7ANtyVDR2tFcU22NU57/IeIl6zgrRdu0waypIN30ckHrMk2pGI +6YNw3ZPX6bqz3xZaPt7gyPvT/Wwp+BVGoGgmzJNSroIBk5DKd8pNSe/iWtkqvTDO +TLKBtjDOWU/aWR1qeqRFsIImgYZ29fUQALjuswnoT4cCB64kXPBfrAowzIpAoHME +wfuJJPaaHFy3PApnNgUIMbOv2AFoKuB4j3TeuFGkjGwgPaL7s9QJ/XvCgKqTbCmY +Iai7FvOpEl90tYeY8pUm3zTvilORiF0alKM/fCL414i6poyWqD1SNGKfAB5UVUJn +xk1Gj7sURT0KlhaOEKGXmdXTMIXM3rRyt7yKPBgpaP3ccQfuJDlq+u2lrDgv+R4Q +DgZxGhBM/nV+/x5XOULK1+EVoVZVWRvRo68R2E7DpSvvkL/A7IITW43WciyTTo9q +Kd+FPNMN4KIYEsxVL0e3p5sC/kH2iExt2qkBR4NkJ2IQgtYSe14DHzSpyZH+r11t +hie3I6p1GMog57AP14kOpmciY/SDQSsGS7tY1dHXt7kQY9iJSrSq3RZj9W6+YKH4 +7ejWkE8axsWgKdOnIaj1Wjz3x0miIZpKlVIglnKaZsv30oZDfCK+lvm9AahH3eU7 +QPl1K5srRmSGjR70j/sHd9DqSaIcjVIUpgqT +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIFVjCCBD6gAwIBAgIQ7is969Qh3hSoYqwE893EATANBgkqhkiG9w0BAQUFADCB +8zELMAkGA1UEBhMCRVMxOzA5BgNVBAoTMkFnZW5jaWEgQ2F0YWxhbmEgZGUgQ2Vy +dGlmaWNhY2lvIChOSUYgUS0wODAxMTc2LUkpMSgwJgYDVQQLEx9TZXJ2ZWlzIFB1 +YmxpY3MgZGUgQ2VydGlmaWNhY2lvMTUwMwYDVQQLEyxWZWdldSBodHRwczovL3d3 +dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbCAoYykwMzE1MDMGA1UECxMsSmVyYXJxdWlh +IEVudGl0YXRzIGRlIENlcnRpZmljYWNpbyBDYXRhbGFuZXMxDzANBgNVBAMTBkVD +LUFDQzAeFw0wMzAxMDcyMzAwMDBaFw0zMTAxMDcyMjU5NTlaMIHzMQswCQYDVQQG +EwJFUzE7MDkGA1UEChMyQWdlbmNpYSBDYXRhbGFuYSBkZSBDZXJ0aWZpY2FjaW8g +KE5JRiBRLTA4MDExNzYtSSkxKDAmBgNVBAsTH1NlcnZlaXMgUHVibGljcyBkZSBD +ZXJ0aWZpY2FjaW8xNTAzBgNVBAsTLFZlZ2V1IGh0dHBzOi8vd3d3LmNhdGNlcnQu +bmV0L3ZlcmFycmVsIChjKTAzMTUwMwYDVQQLEyxKZXJhcnF1aWEgRW50aXRhdHMg +ZGUgQ2VydGlmaWNhY2lvIENhdGFsYW5lczEPMA0GA1UEAxMGRUMtQUNDMIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsyLHT+KXQpWIR4NA9h0X84NzJB5R +85iKw5K4/0CQBXCHYMkAqbWUZRkiFRfCQ2xmRJoNBD45b6VLeqpjt4pEndljkYRm +4CgPukLjbo73FCeTae6RDqNfDrHrZqJyTxIThmV6PttPB/SnCWDaOkKZx7J/sxaV +HMf5NLWUhdWZXqBIoH7nF2W4onW4HvPlQn2v7fOKSGRdghST2MDk/7NQcvJ29rNd +QlB50JQ+awwAvthrDk4q7D7SzIKiGGUzE3eeml0aE9jD2z3Il3rucO2n5nzbcc8t +lGLfbdb1OL4/pYUKGbio2Al1QnDE6u/LDsg0qBIimAy4E5S2S+zw0JDnJwIDAQAB +o4HjMIHgMB0GA1UdEQQWMBSBEmVjX2FjY0BjYXRjZXJ0Lm5ldDAPBgNVHRMBAf8E +BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUoMOLRKo3pUW/l4Ba0fF4 +opvpXY0wfwYDVR0gBHgwdjB0BgsrBgEEAfV4AQMBCjBlMCwGCCsGAQUFBwIBFiBo +dHRwczovL3d3dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbDA1BggrBgEFBQcCAjApGidW +ZWdldSBodHRwczovL3d3dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbCAwDQYJKoZIhvcN +AQEFBQADggEBAKBIW4IB9k1IuDlVNZyAelOZ1Vr/sXE7zDkJlF7W2u++AVtd0x7Y +/X1PzaBB4DSTv8vihpw3kpBWHNzrKQXlxJ7HNd+KDM3FIUPpqojlNcAZQmNaAl6k +SBg6hW/cnbw/nZzBh7h6YQjpdwt/cKt63dmXLGQehb+8dJahw3oS7AwaboMMPOhy +Rp/7SNVel+axofjk70YllJyJ22k4vuxcDlbHZVHlUIiIv0LVKz3l+bqeLrPK9HOS +Agu+TGbrIP65y7WZf+a2E/rKS03Z7lNGBjvGTq2TWoF+bCpLagVFjPIhpDGQh2xl +nJ2lYJU6Un/10asIbvPuW/mIPX64b24D5EI= +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIEAzCCAuugAwIBAgIQVID5oHPtPwBMyonY43HmSjANBgkqhkiG9w0BAQUFADB1 +MQswCQYDVQQGEwJFRTEiMCAGA1UECgwZQVMgU2VydGlmaXRzZWVyaW1pc2tlc2t1 +czEoMCYGA1UEAwwfRUUgQ2VydGlmaWNhdGlvbiBDZW50cmUgUm9vdCBDQTEYMBYG +CSqGSIb3DQEJARYJcGtpQHNrLmVlMCIYDzIwMTAxMDMwMTAxMDMwWhgPMjAzMDEy +MTcyMzU5NTlaMHUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKDBlBUyBTZXJ0aWZpdHNl +ZXJpbWlza2Vza3VzMSgwJgYDVQQDDB9FRSBDZXJ0aWZpY2F0aW9uIENlbnRyZSBS +b290IENBMRgwFgYJKoZIhvcNAQkBFglwa2lAc2suZWUwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQDIIMDs4MVLqwd4lfNE7vsLDP90jmG7sWLqI9iroWUy +euuOF0+W2Ap7kaJjbMeMTC55v6kF/GlclY1i+blw7cNRfdCT5mzrMEvhvH2/UpvO +bntl8jixwKIy72KyaOBhU8E2lf/slLo2rpwcpzIP5Xy0xm90/XsY6KxX7QYgSzIw +WFv9zajmofxwvI6Sc9uXp3whrj3B9UiHbCe9nyV0gVWw93X2PaRka9ZP585ArQ/d +MtO8ihJTmMmJ+xAdTX7Nfh9WDSFwhfYggx/2uh8Ej+p3iDXE/+pOoYtNP2MbRMNE +1CV2yreN1x5KZmTNXMWcg+HCCIia7E6j8T4cLNlsHaFLAgMBAAGjgYowgYcwDwYD +VR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBLyWj7qVhy/ +zQas8fElyalL1BSZMEUGA1UdJQQ+MDwGCCsGAQUFBwMCBggrBgEFBQcDAQYIKwYB +BQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCAYIKwYBBQUHAwkwDQYJKoZIhvcNAQEF +BQADggEBAHv25MANqhlHt01Xo/6tu7Fq1Q+e2+RjxY6hUFaTlrg4wCQiZrxTFGGV +v9DHKpY5P30osxBAIWrEr7BSdxjhlthWXePdNl4dp1BUoMUq5KqMlIpPnTX/dqQG +E5Gion0ARD9V04I8GtVbvFZMIi5GQ4okQC3zErg7cBqklrkar4dBGmoYDQZPxz5u +uSlNDUmJEYcyW+ZLBMjkXOZ0c5RdFpgTlf7727FE5TpwrDdr5rMzcijJs1eg9gIW +iAYLtqZLICjU3j2LrTcFU3T+bsy8QxdxXvnFzBqpYe73dgzzcvRyrc9yAjYHR8/v +GVCJYMzpJJUPwssd8m92kMfMdcGWxZ0= +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIEKjCCAxKgAwIBAgIEOGPe+DANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChML +RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBp +bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5 +IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENlcnRp +ZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQxNzUwNTFaFw0yOTA3 +MjQxNDE1MTJaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3d3d3 +LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxp +YWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEG +A1UEAxMqRW50cnVzdC5uZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgp +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArU1LqRKGsuqjIAcVFmQq +K0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOLGp18EzoOH1u3Hs/lJBQe +sYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSrhRSGlVuX +MlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVT +XTzWnLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/ +HoZdenoVve8AjhUiVBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH +4QIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV +HQ4EFgQUVeSB0RGAvtiJuQijMfmhJAkWuXAwDQYJKoZIhvcNAQEFBQADggEBADub +j1abMOdTmXx6eadNl9cZlZD7Bh/KM3xGY4+WZiT6QBshJ8rmcnPyT/4xmf3IDExo +U8aAghOY+rat2l098c5u9hURlIIM7j+VrxGrD9cv3h8Dj1csHsm7mhpElesYT6Yf +zX1XEC+bBAlahLVu2B064dae0Wx5XnkcFMXj0EyTO2U87d89vqbllRrDtRnDvV5b +u/8j72gZyxKTJ1wDLW8w0B62GqzeWvfRqqgnpv55gcR5mTNXuhKwqeBCbJPKVt7+ +bYQLCIt+jerXmCHG8+c8eS9enNFMFY3h7CI3zJpDC5fcgJCNs2ebb0gIFVbPv/Er +fF6adulZkMV8gzURZVE= +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMC +VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0 +Lm5ldC9DUFMgaXMgaW5jb3Jwb3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMW +KGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsGA1UEAxMkRW50cnVzdCBSb290IENl +cnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0MloXDTI2MTEyNzIw +NTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMTkw +NwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSBy +ZWZlcmVuY2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNV +BAMTJEVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJ +KoZIhvcNAQEBBQADggEPADCCAQoCggEBALaVtkNC+sZtKm9I35RMOVcF7sN5EUFo +Nu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYszA9u3g3s+IIRe7bJWKKf4 +4LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOwwCj0Yzfv9 +KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGI +rb68j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi +94DkZfs0Nw4pgHBNrziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOB +sDCBrTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAi +gA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1MzQyWjAfBgNVHSMEGDAWgBRo +kORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DHhmak8fdLQ/uE +vW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA +A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9t +O1KzKtvn1ISMY/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6Zua +AGAT/3B+XxFNSRuzFVJ7yVTav52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP +9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTSW3iDVuycNsMm4hH2Z0kdkquM++v/ +eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0tHuu2guQOHXvgR1m +0vdXcDazv/wor3ElhVsT/h5/WrQ8 +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIC+TCCAoCgAwIBAgINAKaLeSkAAAAAUNCR+TAKBggqhkjOPQQDAzCBvzELMAkG +A1UEBhMCVVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3 +d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDEyIEVu +dHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEzMDEGA1UEAxMq +RW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRUMxMB4XDTEy +MTIxODE1MjUzNloXDTM3MTIxODE1NTUzNlowgb8xCzAJBgNVBAYTAlVTMRYwFAYD +VQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0 +L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxMiBFbnRydXN0LCBJbmMuIC0g +Zm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMzAxBgNVBAMTKkVudHJ1c3QgUm9vdCBD +ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEVDMTB2MBAGByqGSM49AgEGBSuBBAAi +A2IABIQTydC6bUF74mzQ61VfZgIaJPRbiWlH47jCffHyAsWfoPZb1YsGGYZPUxBt +ByQnoaD41UcZYUx9ypMn6nQM72+WCf5j7HBdNq1nd67JnXxVRDqiY1Ef9eNi1KlH +Bz7MIKNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O +BBYEFLdj5xrdjekIplWDpOBqUEFlEUJJMAoGCCqGSM49BAMDA2cAMGQCMGF52OVC +R98crlOZF7ZvHH3hvxGU0QOIdeSNiaSKd0bebWHvAvX7td/M/k7//qnmpwIwW5nX +hTcGtXsI/esni0qU+eH6p44mCOh8kmhtc9hvJqwhAriZtyZBWyVgrtBIGu4G +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIEPjCCAyagAwIBAgIESlOMKDANBgkqhkiG9w0BAQsFADCBvjELMAkGA1UEBhMC +VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50 +cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3Qs +IEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVz +dCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIwHhcNMDkwNzA3MTcy +NTU0WhcNMzAxMjA3MTc1NTU0WjCBvjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUVu +dHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwt +dGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0 +aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmlj +YXRpb24gQXV0aG9yaXR5IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQC6hLZy254Ma+KZ6TABp3bqMriVQRrJ2mFOWHLP/vaCeb9zYQYKpSfYs1/T +RU4cctZOMvJyig/3gxnQaoCAAEUesMfnmr8SVycco2gvCoe9amsOXmXzHHfV1IWN +cCG0szLni6LVhjkCsbjSR87kyUnEO6fe+1R9V77w6G7CebI6C1XiUJgWMhNcL3hW +wcKUs/Ja5CeanyTXxuzQmyWC48zCxEXFjJd6BmsqEZ+pCm5IO2/b1BEZQvePB7/1 +U1+cPvQXLOZprE4yTGJ36rfo5bs0vBmLrpxR57d+tVOxMyLlbc9wPBr64ptntoP0 +jaWvYkxN4FisZDQSA/i2jZRjJKRxAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAP +BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqciZ60B7vfec7aVHUbI2fkBJmqzAN +BgkqhkiG9w0BAQsFAAOCAQEAeZ8dlsa2eT8ijYfThwMEYGprmi5ZiXMRrEPR9RP/ +jTkrwPK9T3CMqS/qF8QLVJ7UG5aYMzyorWKiAHarWWluBh1+xLlEjZivEtRh2woZ +Rkfz6/djwUAFQKXSt/S1mja/qYh2iARVBCuch38aNzx+LaUa2NSJXsq9rD1s2G2v +1fN2D807iDginWyTmsQ9v4IbZT+mD12q/OWyFcq1rca8PdCE6OoGcrBNOTJ4vz4R +nAuknZoh8/CbCzB428Hch0P+vGOaysXCHMnHjf87ElgI5rY97HosTvuDls4MPGmH +VHOkc8KT/1EQrBVUAdj8BbGJoX90g5pJ19xOe4pIb4tF9g== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIFsDCCA5igAwIBAgIQFci9ZUdcr7iXAF7kBtK8nTANBgkqhkiG9w0BAQUFADBe +MQswCQYDVQQGEwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0 +ZC4xKjAoBgNVBAsMIWVQS0kgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe +Fw0wNDEyMjAwMjMxMjdaFw0zNDEyMjAwMjMxMjdaMF4xCzAJBgNVBAYTAlRXMSMw +IQYDVQQKDBpDaHVuZ2h3YSBUZWxlY29tIENvLiwgTHRkLjEqMCgGA1UECwwhZVBL +SSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0BAQEF +AAOCAg8AMIICCgKCAgEA4SUP7o3biDN1Z82tH306Tm2d0y8U82N0ywEhajfqhFAH +SyZbCUNsIZ5qyNUD9WBpj8zwIuQf5/dqIjG3LBXy4P4AakP/h2XGtRrBp0xtInAh +ijHyl3SJCRImHJ7K2RKilTza6We/CKBk49ZCt0Xvl/T29de1ShUCWH2YWEtgvM3X +DZoTM1PRYfl61dd4s5oz9wCGzh1NlDivqOx4UXCKXBCDUSH3ET00hl7lSM2XgYI1 +TBnsZfZrxQWh7kcT1rMhJ5QQCtkkO7q+RBNGMD+XPNjX12ruOzjjK9SXDrkb5wdJ +fzcq+Xd4z1TtW0ado4AOkUPB1ltfFLqfpo0kR0BZv3I4sjZsN/+Z0V0OWQqraffA +sgRFelQArr5T9rXn4fg8ozHSqf4hUmTFpmfwdQcGlBSBVcYn5AGPF8Fqcde+S/uU +WH1+ETOxQvdibBjWzwloPn9s9h6PYq2lY9sJpx8iQkEeb5mKPtf5P0B6ebClAZLS +nT0IFaUQAS2zMnaolQ2zepr7BxB4EW/hj8e6DyUadCrlHJhBmd8hh+iVBmoKs2pH +dmX2Os+PYhcZewoozRrSgx4hxyy/vv9haLdnG7t4TY3OZ+XkwY63I2binZB1NJip +NiuKmpS5nezMirH4JYlcWrYvjB9teSSnUmjDhDXiZo1jDiVN1Rmy5nk3pyKdVDEC +AwEAAaNqMGgwHQYDVR0OBBYEFB4M97Zn8uGSJglFwFU5Lnc/QkqiMAwGA1UdEwQF +MAMBAf8wOQYEZyoHAAQxMC8wLQIBADAJBgUrDgMCGgUAMAcGBWcqAwAABBRFsMLH +ClZ87lt4DJX5GFPBphzYEDANBgkqhkiG9w0BAQUFAAOCAgEACbODU1kBPpVJufGB +uvl2ICO1J2B01GqZNF5sAFPZn/KmsSQHRGoqxqWOeBLoR9lYGxMqXnmbnwoqZ6Yl +PwZpVnPDimZI+ymBV3QGypzqKOg4ZyYr8dW1P2WT+DZdjo2NQCCHGervJ8A9tDkP +JXtoUHRVnAxZfVo9QZQlUgjgRywVMRnVvwdVxrsStZf0X4OFunHB2WyBEXYKCrC/ +gpf36j36+uwtqSiUO1bd0lEursC9CBWMd1I0ltabrNMdjmEPNXubrjlpC2JgQCA2 +j6/7Nu4tCEoduL+bXPjqpRugc6bY+G7gMwRfaKonh+3ZwZCc7b3jajWvY9+rGNm6 +5ulK6lCKD2GTHuItGeIwlDWSXQ62B68ZgI9HkFFLLk3dheLSClIKF5r8GrBQAuUB +o2M3IUxExJtRmREOc5wGj1QupyheRDmHVi03vYVElOEMSyycw5KFNGHLD7ibSkNS +/jQ6fbjpKdx2qcgw+BRxgMYeNkh0IkFch4LoGHGLQYlE535YW6i4jRPpp2zDR+2z +Gp1iro2C6pSe3VkQw63d4k3jMdXH7OjysP6SHhYKGvzZ8/gntsm+HbRsZJB/9OTE +W9c3rkIO3aQab3yIVMUWbuF6aC74Or8NpDyJO3inTmODBCEIZ43ygknQW/2xzQ+D +hNQ+IIX3Sj0rnP0qCglN6oH4EZw= +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIGSzCCBDOgAwIBAgIIamg+nFGby1MwDQYJKoZIhvcNAQELBQAwgbIxCzAJBgNV +BAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExQDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBC +aWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhpem1ldGxlcmkgQS7Fni4xJjAkBgNV +BAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBNZXJrZXppMSgwJgYDVQQDDB9FLVR1 +Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTEzMDMwNTEyMDk0OFoXDTIz +MDMwMzEyMDk0OFowgbIxCzAJBgNVBAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExQDA+ +BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhp +em1ldGxlcmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBN +ZXJrZXppMSgwJgYDVQQDDB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5 +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA4vU/kwVRHoViVF56C/UY +B4Oufq9899SKa6VjQzm5S/fDxmSJPZQuVIBSOTkHS0vdhQd2h8y/L5VMzH2nPbxH +D5hw+IyFHnSOkm0bQNGZDbt1bsipa5rAhDGvykPL6ys06I+XawGb1Q5KCKpbknSF +Q9OArqGIW66z6l7LFpp3RMih9lRozt6Plyu6W0ACDGQXwLWTzeHxE2bODHnv0ZEo +q1+gElIwcxmOj+GMB6LDu0rw6h8VqO4lzKRG+Bsi77MOQ7osJLjFLFzUHPhdZL3D +k14opz8n8Y4e0ypQBaNV2cvnOVPAmJ6MVGKLJrD3fY185MaeZkJVgkfnsliNZvcH +fC425lAcP9tDJMW/hkd5s3kc91r0E+xs+D/iWR+V7kI+ua2oMoVJl0b+SzGPWsut +dEcf6ZG33ygEIqDUD13ieU/qbIWGvaimzuT6w+Gzrt48Ue7LE3wBf4QOXVGUnhMM +ti6lTPk5cDZvlsouDERVxcr6XQKj39ZkjFqzAQqptQpHF//vkUAqjqFGOjGY5RH8 +zLtJVor8udBhmm9lbObDyz51Sf6Pp+KJxWfXnUYTTjF2OySznhFlhqt/7x3U+Lzn +rFpct1pHXFXOVbQicVtbC/DP3KBhZOqp12gKY6fgDT+gr9Oq0n7vUaDmUStVkhUX +U8u3Zg5mTPj5dUyQ5xJwx0UCAwEAAaNjMGEwHQYDVR0OBBYEFC7j27JJ0JxUeVz6 +Jyr+zE7S6E5UMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAULuPbsknQnFR5 +XPonKv7MTtLoTlQwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQAF +Nzr0TbdF4kV1JI+2d1LoHNgQk2Xz8lkGpD4eKexd0dCrfOAKkEh47U6YA5n+KGCR +HTAduGN8qOY1tfrTYXbm1gdLymmasoR6d5NFFxWfJNCYExL/u6Au/U5Mh/jOXKqY +GwXgAEZKgoClM4so3O0409/lPun++1ndYYRP0lSWE2ETPo+Aab6TR7U1Q9Jauz1c +77NCR807VRMGsAnb/WP2OogKmW9+4c4bU2pEZiNRCHu8W1Ki/QY3OEBhj0qWuJA3 ++GbHeJAAFS6LrVE1Uweoa2iu+U48BybNCAVwzDk/dr2l02cmAYamU9JgO3xDf1WK +vJUawSg5TB9D0pH0clmKuVb8P7Sd2nCcdlqMQ1DujjByTd//SffGqWfZbawCEeI6 +FiWnWAjLb1NBnEg4R2gz0dfHj9R0IdTDBZB6/86WiLEVKV0jq9BgoRJP3vQXzTLl +yb/IQ639Lo7xr+L0mPoSHyDYwKcMhcWQ9DstliaxLL5Mq+ux0orJ23gTDx4JnW2P +AJ8C2sH6H3p6CcRK5ogql5+Ji/03X186zjhZhkuvcQu02PJwT58yE+Owp1fl2tpD +y4Q08ijE6m30Ku/Ba3ba+367hTzSU8JNvnHhRdH9I2cNE3X7z2VnIp2usAnRCf8d +NL/+I5c30jn6PQ0GC7TbO6Orb1wdtn7os4I07QZcJA== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIDZjCCAk6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBEMQswCQYDVQQGEwJVUzEW +MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMUR2VvVHJ1c3QgR2xvYmFs +IENBIDIwHhcNMDQwMzA0MDUwMDAwWhcNMTkwMzA0MDUwMDAwWjBEMQswCQYDVQQG +EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMUR2VvVHJ1c3Qg +R2xvYmFsIENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDvPE1A +PRDfO1MA4Wf+lGAVPoWI8YkNkMgoI5kF6CsgncbzYEbYwbLVjDHZ3CB5JIG/NTL8 +Y2nbsSpr7iFY8gjpeMtvy/wWUsiRxP89c96xPqfCfWbB9X5SJBri1WeR0IIQ13hL +TytCOb1kLUCgsBDTOEhGiKEMuzozKmKY+wCdE1l/bztyqu6mD4b5BWHqZ38MN5aL +5mkWRxHCJ1kDs6ZgwiFAVvqgx306E+PsV8ez1q6diYD3Aecs9pYrEw15LNnA5IZ7 +S4wMcoKK+xfNAGw6EzywhIdLFnopsk/bHdQL82Y3vdj2V7teJHq4PIu5+pIaGoSe +2HSPqht/XvT+RSIhAgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE +FHE4NvICMVNHK266ZUapEBVYIAUJMB8GA1UdIwQYMBaAFHE4NvICMVNHK266ZUap +EBVYIAUJMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQUFAAOCAQEAA/e1K6td +EPx7srJerJsOflN4WT5CBP51o62sgU7XAotexC3IUnbHLB/8gTKY0UvGkpMzNTEv +/NgdRN3ggX+d6YvhZJFiCzkIjKx0nVnZellSlxG5FntvRdOW2TF9AjYPnDtuzywN +A0ZF66D0f0hExghAzN4bcLUprbqLOzRldRtxIR0sFAqwlpW41uryZfspuk/qkZN0 +abby/+Ea0AzRdoXLiiW9l14sbxWZJue2Kf8i7MkCx1YAzUm5s2x7UwQa4qjJqhIF +I8LO57sEAszAR6LkxCkvW0VXiVHuPOtSCP8HNR6fNWpHSlaY0VqFH4z1Ir+rzoPz +4iIprn2DQKi6bA== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIDfDCCAmSgAwIBAgIQGKy1av1pthU6Y2yv2vrEoTANBgkqhkiG9w0BAQUFADBY +MQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjExMC8GA1UEAxMo +R2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEx +MjcwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMFgxCzAJBgNVBAYTAlVTMRYwFAYDVQQK +Ew1HZW9UcnVzdCBJbmMuMTEwLwYDVQQDEyhHZW9UcnVzdCBQcmltYXJ5IENlcnRp +ZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEAvrgVe//UfH1nrYNke8hCUy3f9oQIIGHWAVlqnEQRr+92/ZV+zmEwu3qDXwK9 +AWbK7hWNb6EwnL2hhZ6UOvNWiAAxz9juapYC2e0DjPt1befquFUWBRaa9OBesYjA +ZIVcFU2Ix7e64HXprQU9nceJSOC7KMgD4TCTZF5SwFlwIjVXiIrxlQqD17wxcwE0 +7e9GceBrAqg1cmuXm2bgyxx5X9gaBGgeRwLmnWDiNpcB3841kt++Z8dtd1k7j53W +kBWUvEI0EME5+bEnPn7WinXFsq+W06Lem+SYvn3h6YGttm/81w7a4DSwDRp35+MI +mO9Y+pyEtzavwt+s0vQQBnBxNQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4G +A1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQULNVQQZcVi/CPNmFbSvtr2ZnJM5IwDQYJ +KoZIhvcNAQEFBQADggEBAFpwfyzdtzRP9YZRqSa+S7iq8XEN3GHHoOo0Hnp3DwQ1 +6CePbJC/kRYkRj5KTs4rFtULUh38H2eiAkUxT87z+gOneZ1TatnaYzr4gNfTmeGl +4b7UVXGYNTq+k+qurUKykG/g/CFNNWMziUnWm07Kx+dOCQD32sfvmWKZd7aVIl6K +oKv0uHiYyjgZmclynnjNS6yvGaBzEi38wkG6gZHaFloxt/m0cYASSJlyc1pZU8Fj +UjPtp8nSOQJw+uCxQmYpqptR7TBUIhRf2asdweSU8Pj1K/fqynhG1riR/aYNKxoU +AT6A8EKglQdebc3MS6RFjasS6LPeWuWgfOgPIh1a6Vk= +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIICrjCCAjWgAwIBAgIQPLL0SAoA4v7rJDteYD7DazAKBggqhkjOPQQDAzCBmDEL +MAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChj +KSAyMDA3IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2 +MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0 +eSAtIEcyMB4XDTA3MTEwNTAwMDAwMFoXDTM4MDExODIzNTk1OVowgZgxCzAJBgNV +BAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykgMjAw +NyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNV +BAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBH +MjB2MBAGByqGSM49AgEGBSuBBAAiA2IABBWx6P0DFUPlrOuHNxFi79KDNlJ9RVcL +So17VDs6bl8VAsBQps8lL33KSLjHUGMcKiEIfJo22Av+0SbFWDEwKCXzXV2juLal +tJLtbCyf691DiaI8S0iRHVDsJt/WYC69IaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO +BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBVfNVdRVfslsq0DafwBo/q+EVXVMAoG +CCqGSM49BAMDA2cAMGQCMGSWWaboCd6LuvpaiIjwH5HTRqjySkwCY/tsXzjbLkGT +qQ7mndwxHLKgpxgceeHHNgIwOlavmnRs9vuD4DPTCF+hnMJbn0bWtsuRBmOiBucz +rD6ogRLQy7rQkgu2npaqBA+K +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIID/jCCAuagAwIBAgIQFaxulBmyeUtB9iepwxgPHzANBgkqhkiG9w0BAQsFADCB +mDELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsT +MChjKSAyMDA4IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25s +eTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhv +cml0eSAtIEczMB4XDTA4MDQwMjAwMDAwMFoXDTM3MTIwMTIzNTk1OVowgZgxCzAJ +BgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykg +MjAwOCBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0 +BgNVBAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg +LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANziXmJYHTNXOTIz ++uvLh4yn1ErdBojqZI4xmKU4kB6Yzy5jK/BGvESyiaHAKAxJcCGVn2TAppMSAmUm +hsalifD614SgcK9PGpc/BkTVyetyEH3kMSj7HGHmKAdEc5IiaacDiGydY8hS2pgn +5whMcD60yRLBxWeDXTPzAxHsatBT4tG6NmCUgLthY2xbF37fQJQeqw3CIShwiP/W +JmxsYAQlTlV+fe+/lEjetx3dcI0FX4ilm/LC7urRQEFtYjgdVgbFA0dRIBn8exAL +DmKudlW/X3e+PkkBUz2YJQN2JFodtNuJ6nnltrM7P7pMKEF/BqxqjsHQ9gUdfeZC +huOl1UcCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYw +HQYDVR0OBBYEFMR5yo6hTgMdHNxr2zFblD4/MH8tMA0GCSqGSIb3DQEBCwUAA4IB +AQAtxRPPVoB7eni9n64smefv2t+UXglpp+duaIy9cr5HqQ6XErhK8WTTOd8lNNTB +zU6B8A8ExCSzNJbGpqow32hhc9f5joWJ7w5elShKKiePEI4ufIbEAp7aDHdlDkQN +kv39sxY2+hENHYwOB4lqKVb3cvTdFZx3NWZXqxNT2I7BQMXXExZacse3aQHEerGD +AWh9jUGhlBjBJVz88P6DAod8DQ3PLghcSkANPuyBYeYk28rgDi0Hsj5W3I31QYUH +SJsMC8tJP33st/3LjWeJGqvtux6jAAgIFyqCXDFdRootD4abdNlF+9RAsXqqaC2G +spki4cErx5z481+oghLrGREt +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIFaDCCA1CgAwIBAgIBATANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJVUzEW +MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEeMBwGA1UEAxMVR2VvVHJ1c3QgVW5pdmVy +c2FsIENBMB4XDTA0MDMwNDA1MDAwMFoXDTI5MDMwNDA1MDAwMFowRTELMAkGA1UE +BhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xHjAcBgNVBAMTFUdlb1RydXN0 +IFVuaXZlcnNhbCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKYV +VaCjxuAfjJ0hUNfBvitbtaSeodlyWL0AG0y/YckUHUWCq8YdgNY96xCcOq9tJPi8 +cQGeBvV8Xx7BDlXKg5pZMK4ZyzBIle0iN430SppyZj6tlcDgFgDgEB8rMQ7XlFTT +QjOgNB0eRXbdT8oYN+yFFXoZCPzVx5zw8qkuEKmS5j1YPakWaDwvdSEYfyh3peFh +F7em6fgemdtzbvQKoiFs7tqqhZJmr/Z6a4LauiIINQ/PQvE1+mrufislzDoR5G2v +c7J2Ha3QsnhnGqQ5HFELZ1aD/ThdDc7d8Lsrlh/eezJS/R27tQahsiFepdaVaH/w +mZ7cRQg+59IJDTWU3YBOU5fXtQlEIGQWFwMCTFMNaN7VqnJNk22CDtucvc+081xd +VHppCZbW2xHBjXWotM85yM48vCR85mLK4b19p71XZQvk/iXttmkQ3CgaRr0BHdCX +teGYO8A3ZNY9lO4L4fUorgtWv3GLIylBjobFS1J72HGrH4oVpjuDWtdYAVHGTEHZ +f9hBZ3KiKN9gg6meyHv8U3NyWfWTehd2Ds735VzZC1U0oqpbtWpU5xPKV+yXbfRe +Bi9Fi1jUIxaS5BZuKGNZMN9QAZxjiRqf2xeUgnA3wySemkfWWspOqGmJch+RbNt+ +nhutxx9z3SxPGWX9f5NAEC7S8O08ni4oPmkmM8V7AgMBAAGjYzBhMA8GA1UdEwEB +/wQFMAMBAf8wHQYDVR0OBBYEFNq7LqqwDLiIJlF0XG0D08DYj3rWMB8GA1UdIwQY +MBaAFNq7LqqwDLiIJlF0XG0D08DYj3rWMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG +9w0BAQUFAAOCAgEAMXjmx7XfuJRAyXHEqDXsRh3ChfMoWIawC/yOsjmPRFWrZIRc +aanQmjg8+uUfNeVE44B5lGiku8SfPeE0zTBGi1QrlaXv9z+ZhP015s8xxtxqv6fX +IwjhmF7DWgh2qaavdy+3YL1ERmrvl/9zlcGO6JP7/TG37FcREUWbMPEaiDnBTzyn +ANXH/KttgCJwpQzgXQQpAvvLoJHRfNbDflDVnVi+QTjruXU8FdmbyUqDWcDaU/0z +uzYYm4UPFd3uLax2k7nZAY1IEKj79TiG8dsKxr2EoyNB3tZ3b4XUhRxQ4K5RirqN +Pnbiucon8l+f725ZDQbYKxek0nxru18UGkiPGkzns0ccjkxFKyDuSN/n3QmOGKja +QI2SJhFTYXNd673nxE0pN2HrrDktZy4W1vUAg4WhzH92xH3kt0tm7wNFYGm2DFKW +koRepqO1pD4r2czYG0eq8kTaT/kD6PAUyz/zg97QwVTjt+gKN02LIFkDMBmhLMi9 +ER/frslKxfMnZmaGrGiR/9nmUxwPi1xpZQomyB40w11Re9epnAahNt3ViZS82eQt +DF4JbAiXfKM9fJP/P6EUp8+1Xevb2xzEdt+Iub1FBZUbrvxGakyvSOPOrg/Sfuvm +bJxPgWp6ZKy7PtXny3YuxadIwVyQD8vIP/rmMuGNG2+k5o7Y+SlIis5z/iw= +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIFbDCCA1SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBHMQswCQYDVQQGEwJVUzEW +MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVy +c2FsIENBIDIwHhcNMDQwMzA0MDUwMDAwWhcNMjkwMzA0MDUwMDAwWjBHMQswCQYD +VQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1 +c3QgVW5pdmVyc2FsIENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC +AQCzVFLByT7y2dyxUxpZKeexw0Uo5dfR7cXFS6GqdHtXr0om/Nj1XqduGdt0DE81 +WzILAePb63p3NeqqWuDW6KFXlPCQo3RWlEQwAx5cTiuFJnSCegx2oG9NzkEtoBUG +FF+3Qs17j1hhNNwqCPkuwwGmIkQcTAeC5lvO0Ep8BNMZcyfwqph/Lq9O64ceJHdq +XbboW0W63MOhBW9Wjo8QJqVJwy7XQYci4E+GymC16qFjwAGXEHm9ADwSbSsVsaxL +se4YuU6W3Nx2/zu+z18DwPw76L5GG//aQMJS9/7jOvdqdzXQ2o3rXhhqMcceujwb +KNZrVMaqW9eiLBsZzKIC9ptZvTdrhrVtgrrY6slWvKk2WP0+GfPtDCapkzj4T8Fd +IgbQl+rhrcZV4IErKIM6+vR7IVEAvlI4zs1meaj0gVbi0IMJR1FbUGrP20gaXT73 +y/Zl92zxlfgCOzJWgjl6W70viRu/obTo/3+NjN8D8WBOWBFM66M/ECuDmgFz2ZRt +hAAnZqzwcEAJQpKtT5MNYQlRJNiS1QuUYbKHsu3/mjX/hVTK7URDrBs8FmtISgoc +QIgfksILAAX/8sgCSqSqqcyZlpwvWOB94b67B9xfBHJcMTTD7F8t4D1kkCLm0ey4 +Lt1ZrtmhN79UNdxzMk+MBB4zsslG8dhcyFVQyWi9qLo2CQIDAQABo2MwYTAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAfBgNV +HSMEGDAWgBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAOBgNVHQ8BAf8EBAMCAYYwDQYJ +KoZIhvcNAQEFBQADggIBAGbBxiPz2eAubl/oz66wsCVNK/g7WJtAJDday6sWSf+z +dXkzoS9tcBc0kf5nfo/sm+VegqlVHy/c1FEHEv6sFj4sNcZj/NwQ6w2jqtB8zNHQ +L1EuxBRa3ugZ4T7GzKQp5y6EqgYweHZUcyiYWTjgAA1i00J9IZ+uPTqM1fp3DRgr +Fg5fNuH8KrUwJM/gYwx7WBr+mbpCErGR9Hxo4sjoryzqyX6uuyo9DRXcNJW2GHSo +ag/HtPQTxORb7QrSpJdMKu0vbBKJPfEncKpqA1Ihn0CoZ1Dy81of398j9tx4TuaY +T1U6U+Pv8vSfx3zYWK8pIpe44L2RLrB27FcRz+8pRPPphXpgY+RdM4kX2TGq2tbz +GDVyz4crL2MjhF2EjD9XoIj8mZEoJmmZ1I+XRL6O1UixpCgp8RW04eWe3fiPpm8m +1wk8OhwRDqZsN/etRIcsKMfYdIKz0G9KV7s1KSegi+ghp4dkNl3M2Basx7InQJJV +OCiNUW7dFGdTbHFcJoRNdVq2fmBWqU2t+5sel/MN2dKXVHfaPRK34B7vCAas+YWH +6aLcr34YEoP9VhdBLtUpgn2Z9DH2canPLAEnpQW5qrJITirvn5NSUZU8UnOOVkwX +QMAJKOSLakhT2+zNVVXxxvjpoixMptEmX36vWkzaH6byHCx+rgIW0lbQL1dTR+iS +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIHSTCCBTGgAwIBAgIJAMnN0+nVfSPOMA0GCSqGSIb3DQEBBQUAMIGsMQswCQYD +VQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0 +IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3 +MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAlBgNVBAMTHkdsb2JhbCBD +aGFtYmVyc2lnbiBSb290IC0gMjAwODAeFw0wODA4MDExMjMxNDBaFw0zODA3MzEx +MjMxNDBaMIGsMQswCQYDVQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3Vy +cmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAG +A1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAl +BgNVBAMTHkdsb2JhbCBDaGFtYmVyc2lnbiBSb290IC0gMjAwODCCAiIwDQYJKoZI +hvcNAQEBBQADggIPADCCAgoCggIBAMDfVtPkOpt2RbQT2//BthmLN0EYlVJH6xed +KYiONWwGMi5HYvNJBL99RDaxccy9Wglz1dmFRP+RVyXfXjaOcNFccUMd2drvXNL7 +G706tcuto8xEpw2uIRU/uXpbknXYpBI4iRmKt4DS4jJvVpyR1ogQC7N0ZJJ0YPP2 +zxhPYLIj0Mc7zmFLmY/CDNBAspjcDahOo7kKrmCgrUVSY7pmvWjg+b4aqIG7HkF4 +ddPB/gBVsIdU6CeQNR1MM62X/JcumIS/LMmjv9GYERTtY/jKmIhYF5ntRQOXfjyG +HoiMvvKRhI9lNNgATH23MRdaKXoKGCQwoze1eqkBfSbW+Q6OWfH9GzO1KTsXO0G2 +Id3UwD2ln58fQ1DJu7xsepeY7s2MH/ucUa6LcL0nn3HAa6x9kGbo1106DbDVwo3V +yJ2dwW3Q0L9R5OP4wzg2rtandeavhENdk5IMagfeOx2YItaswTXbo6Al/3K1dh3e +beksZixShNBFks4c5eUzHdwHU1SjqoI7mjcv3N2gZOnm3b2u/GSFHTynyQbehP9r +6GsaPMWis0L7iwk+XwhSx2LE1AVxv8Rk5Pihg+g+EpuoHtQ2TS9x9o0o9oOpE9Jh +wZG7SMA0j0GMS0zbaRL/UJScIINZc+18ofLx/d33SdNDWKBWY8o9PeU1VlnpDsog +zCtLkykPAgMBAAGjggFqMIIBZjASBgNVHRMBAf8ECDAGAQH/AgEMMB0GA1UdDgQW +BBS5CcqcHtvTbDprru1U8VuTBjUuXjCB4QYDVR0jBIHZMIHWgBS5CcqcHtvTbDpr +ru1U8VuTBjUuXqGBsqSBrzCBrDELMAkGA1UEBhMCRVUxQzBBBgNVBAcTOk1hZHJp +ZCAoc2VlIGN1cnJlbnQgYWRkcmVzcyBhdCB3d3cuY2FtZXJmaXJtYS5jb20vYWRk +cmVzcykxEjAQBgNVBAUTCUE4Mjc0MzI4NzEbMBkGA1UEChMSQUMgQ2FtZXJmaXJt +YSBTLkEuMScwJQYDVQQDEx5HbG9iYWwgQ2hhbWJlcnNpZ24gUm9vdCAtIDIwMDiC +CQDJzdPp1X0jzjAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRVHSAAMCow +KAYIKwYBBQUHAgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wDQYJKoZI +hvcNAQEFBQADggIBAICIf3DekijZBZRG/5BXqfEv3xoNa/p8DhxJJHkn2EaqbylZ +UohwEurdPfWbU1Rv4WCiqAm57OtZfMY18dwY6fFn5a+6ReAJ3spED8IXDneRRXoz +X1+WLGiLwUePmJs9wOzL9dWCkoQ10b42OFZyMVtHLaoXpGNR6woBrX/sdZ7LoR/x +fxKxueRkf2fWIyr0uDldmOghp+G9PUIadJpwr2hsUF1Jz//7Dl3mLEfXgTpZALVz +a2Mg9jFFCDkO9HB+QHBaP9BrQql0PSgvAm11cpUJjUhjxsYjV5KTXjXBjfkK9yyd +Yhz2rXzdpjEetrHHfoUm+qRqtdpjMNHvkzeyZi99Bffnt0uYlDXA2TopwZ2yUDMd +SqlapskD7+3056huirRXhOukP9DuqqqHW2Pok+JrqNS4cnhrG+055F3Lm6qH1U9O +AP7Zap88MQ8oAgF9mOinsKJknnn4SPIVqczmyETrP3iZ8ntxPjzxmKfFGBI/5rso +M0LpRQp8bfKGeS/Fghl9CYl8slR2iK7ewfPM4W7bMdaTrpmg7yVqc5iJWzouE4ge +v8CSlDQb4ye3ix5vQv/n6TebUB0tovkC7stYWDpxvGjjqsGvHCgfotwjZT+B6q6Z +09gwzxMNTxXJhLynSC34MCN32EZLeW32jO06f2ARePTpm67VVMB0gNELQp/B +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIB4TCCAYegAwIBAgIRKjikHJYKBN5CsiilC+g0mAIwCgYIKoZIzj0EAwIwUDEk +MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpH +bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX +DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD +QSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu +MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEuMZ5049sJQ6fLjkZHAOkrprlOQcJ +FspjsbmG+IpXwVfOQvpzofdlQv8ewQCybnMO/8ch5RikqtlxP6jUuc6MHaNCMEAw +DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFFSwe61F +uOJAf/sKbvu+M8k8o4TVMAoGCCqGSM49BAMCA0gAMEUCIQDckqGgE6bPA7DmxCGX +kPoUVy0D7O48027KqGx2vKLeuwIgJ6iFJzWbVsaj8kfSt24bAgAXqmemFZHe+pTs +ewv4n4Q= +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIICHjCCAaSgAwIBAgIRYFlJ4CYuu1X5CneKcflK2GwwCgYIKoZIzj0EAwMwUDEk +MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpH +bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX +DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD +QSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu +MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAER0UOlvt9Xb/pOdEh+J8LttV7HpI6SFkc +8GIxLcB6KP4ap1yztsyX50XUWPrRd21DosCHZTQKH3rd6zwzocWdTaRvQZU4f8ke +hOvRnkmSh5SHDDqFSmafnVmTTZdhBoZKo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYD +VR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUPeYpSJvqB8ohREom3m7e0oPQn1kwCgYI +KoZIzj0EAwMDaAAwZQIxAOVpEslu28YxuglB4Zf4+/2a4n0Sye18ZNPLBSWLVtmg +515dTguDnFt2KaAJJiFqYgIwcdK1j1zqO+F4CYWodZI7yFz9SO8NdCKoCOJuxUnO +xwy8p2Fp8fc74SrL+SvzZpA3 +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4G +A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNp +Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1 +MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEG +A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6ErPL +v4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8 +eoLrvozps6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklq +tTleiDTsvHgMCJiEbKjNS7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzd +C9XZzPnqJworc5HGnRusyMvo4KD0L5CLTfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pa +zq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6CygPCm48CAwEAAaOBnDCB +mTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUm+IH +V2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5n +bG9iYWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG +3lm0mi3f3BmGLjANBgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4Gs +J0/WwbgcQ3izDJr86iw8bmEbTUsp9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO +291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu01yiPqFbQfXf5WRDLenVOavS +ot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG79G+dwfCMNYxd +AfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7 +TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4G +A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNp +Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4 +MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMzETMBEG +A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWtiHL8 +RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsT +gHeMCOFJ0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmm +KPZpO/bLyCiR5Z2KYVc3rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zd +QQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjlOCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZ +XriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2xmmFghcCAwEAAaNCMEAw +DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI/wS3+o +LkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZU +RUm7lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMp +jjM5RcOO5LlXbKr8EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK +6fBdRoyV3XpYKBovHd7NADdBj+1EbddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQX +mcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18YIvDQVETI53O9zJrlAGomecs +Mx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7rkpeDMdmztcpH +WD9f +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx +EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT +EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp +ZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIz +NTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH +EwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8GA1UE +AxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKD +E6bFIEMBO4Tx5oVJnyfq9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH +/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD+qK+ihVqf94Lw7YZFAXK6sOoBJQ7Rnwy +DfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutdfMh8+7ArU6SSYmlRJQVh +GkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMlNAJWJwGR +tDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEA +AaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE +FDqahQcQZyi27/a9BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmX +WWcDYfF+OwYxdS2hII5PZYe096acvNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu +9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r5N9ss4UXnT3ZJE95kTXWXwTr +gIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYVN8Gb5DKj7Tjo +2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO +LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI +4uJEvlz36hz1 +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIEMTCCAxmgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBlTELMAkGA1UEBhMCR1Ix +RDBCBgNVBAoTO0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1 +dGlvbnMgQ2VydC4gQXV0aG9yaXR5MUAwPgYDVQQDEzdIZWxsZW5pYyBBY2FkZW1p +YyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIFJvb3RDQSAyMDExMB4XDTExMTIw +NjEzNDk1MloXDTMxMTIwMTEzNDk1MlowgZUxCzAJBgNVBAYTAkdSMUQwQgYDVQQK +EztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIENl +cnQuIEF1dGhvcml0eTFAMD4GA1UEAxM3SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl +c2VhcmNoIEluc3RpdHV0aW9ucyBSb290Q0EgMjAxMTCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBAKlTAOMupvaO+mDYLZU++CwqVE7NuYRhlFhPjz2L5EPz +dYmNUeTDN9KKiE15HrcS3UN4SoqS5tdI1Q+kOilENbgH9mgdVc04UfCMJDGFr4PJ +fel3r+0ae50X+bOdOFAPplp5kYCvN66m0zH7tSYJnTxa71HFK9+WXesyHgLacEns +bgzImjeN9/E2YEsmLIKe0HjzDQ9jpFEw4fkrJxIH2Oq9GGKYsFk3fb7u8yBRQlqD +75O6aRXxYp2fmTmCobd0LovUxQt7L/DICto9eQqakxylKHJzkUOap9FNhYS5qXSP +FEDH3N6sQWRstBmbAmNtJGSPRLIl6s5ddAxjMlyNh+UCAwEAAaOBiTCBhjAPBgNV +HRMBAf8EBTADAQH/MAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQUppFC/RNhSiOeCKQp +5dgTBCPuQSUwRwYDVR0eBEAwPqA8MAWCAy5ncjAFggMuZXUwBoIELmVkdTAGggQu +b3JnMAWBAy5ncjAFgQMuZXUwBoEELmVkdTAGgQQub3JnMA0GCSqGSIb3DQEBBQUA +A4IBAQAf73lB4XtuP7KMhjdCSk4cNx6NZrokgclPEg8hwAOXhiVtXdMiKahsog2p +6z0GW5k6x8zDmjR/qw7IThzh+uTczQ2+vyT+bOdrwg3IBp5OjWEopmr95fZi6hg8 +TqBTnbI6nOulnJEWtk2C4AwFSKls9cz4y51JtPACpf1wA+2KIaWuE4ZJwzNzvoc7 +dIsXRSZMFpGD/md9zU1jZ/rzAxKWeAaNsWftjj++n08C9bMJL/NMh98qy5V8Acys +Nnq/onN694/BtZqhFLKPM58N7yLcZnuEvUUXBj08yrl3NI/K6s8/MT7jiOOASSXI +l7WdmplNsDz4SgCbZN2fOUvRJ9e4 +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIDMDCCAhigAwIBAgICA+gwDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCSEsx +FjAUBgNVBAoTDUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3Qg +Um9vdCBDQSAxMB4XDTAzMDUxNTA1MTMxNFoXDTIzMDUxNTA0NTIyOVowRzELMAkG +A1UEBhMCSEsxFjAUBgNVBAoTDUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdr +b25nIFBvc3QgUm9vdCBDQSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEArP84tulmAknjorThkPlAj3n54r15/gK97iSSHSL22oVyaf7XPwnU3ZG1ApzQ +jVrhVcNQhrkpJsLj2aDxaQMoIIBFIi1WpztUlVYiWR8o3x8gPW2iNr4joLFutbEn +PzlTCeqrauh0ssJlXI6/fMN4hM2eFvz1Lk8gKgifd/PFHsSaUmYeSF7jEAaPIpjh +ZY4bXSNmO7ilMlHIhqqhqZ5/dpTCpmy3QfDVyAY45tQM4vM7TG1QjMSDJ8EThFk9 +nnV0ttgCXjqQesBCNnLsak3c78QA3xMYV18meMjWCnl3v/evt3a5pQuEF10Q6m/h +q5URX208o1xNg1vysxmKgIsLhwIDAQABoyYwJDASBgNVHRMBAf8ECDAGAQH/AgED +MA4GA1UdDwEB/wQEAwIBxjANBgkqhkiG9w0BAQUFAAOCAQEADkbVPK7ih9legYsC +mEEIjEy82tvuJxuC52pF7BaLT4Wg87JwvVqWuspube5Gi27nKi6Wsxkz67SfqLI3 +7piol7Yutmcn1KZJ/RyTZXaeQi/cImyaT/JaFTmxcdcrUehtHJjA2Sr0oYJ71clB +oiMBdDhViw+5LmeiIAQ32pwL0xch4I+XeTRvhEgCIDMb5jREn5Fw9IBehEPCKdJs +EhTkYY2sEJCehFC78JZvRZ+K88psT/oROhUVRsPNH4NbLUES7VBnQRM9IauUiqpO +fMGx+6fWtScvl6tu4B3i0RwsH0Ti/L6RoZz71ilTc4afU9hDDl3WY4JxHYB0yvbi +AmvZWg== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIQCgFCgAAAAUUjyES1AAAAAjANBgkqhkiG9w0BAQsFADBK +MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVu +VHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwHhcNMTQwMTE2MTgxMjIzWhcNMzQw +MTE2MTgxMjIzWjBKMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScw +JQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCnUBneP5k91DNG8W9RYYKyqU+PZ4ldhNlT +3Qwo2dfw/66VQ3KZ+bVdfIrBQuExUHTRgQ18zZshq0PirK1ehm7zCYofWjK9ouuU ++ehcCuz/mNKvcbO0U59Oh++SvL3sTzIwiEsXXlfEU8L2ApeN2WIrvyQfYo3fw7gp +S0l4PJNgiCL8mdo2yMKi1CxUAGc1bnO/AljwpN3lsKImesrgNqUZFvX9t++uP0D1 +bVoE/c40yiTcdCMbXTMTEl3EASX2MN0CXZ/g1Ue9tOsbobtJSdifWwLziuQkkORi +T0/Br4sOdBeo0XKIanoBScy0RnnGF7HamB4HWfp1IYVl3ZBWzvurpWCdxJ35UrCL +vYf5jysjCiN2O/cz4ckA82n5S6LgTrx+kzmEB/dEcH7+B1rlsazRGMzyNeVJSQjK +Vsk9+w8YfYs7wRPCTY/JTw436R+hDmrfYi7LNQZReSzIJTj0+kuniVyc0uMNOYZK +dHzVWYfCP04MXFL0PfdSgvHqo6z9STQaKPNBiDoT7uje/5kdX7rL6B7yuVBgwDHT +c+XvvqDtMwt0viAgxGds8AgDelWAf0ZOlqf0Hj7h9tgJ4TNkK2PXMl6f+cB7D3hv +l7yTmvmcEpB4eoCHFddydJxVdHixuuFucAS6T6C6aMN7/zHwcz09lCqxC0EOoP5N +iGVreTO01wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB +/zAdBgNVHQ4EFgQU7UQZwNPwBovupHu+QucmVMiONnYwDQYJKoZIhvcNAQELBQAD +ggIBAA2ukDL2pkt8RHYZYR4nKM1eVO8lvOMIkPkp165oCOGUAFjvLi5+U1KMtlwH +6oi6mYtQlNeCgN9hCQCTrQ0U5s7B8jeUeLBfnLOic7iPBZM4zY0+sLj7wM+x8uwt +LRvM7Kqas6pgghstO8OEPVeKlh6cdbjTMM1gCIOQ045U8U1mwF10A0Cj7oV+wh93 +nAbowacYXVKV7cndJZ5t+qntozo00Fl72u1Q8zW/7esUTTHHYPTa8Yec4kjixsU3 ++wYQ+nVZZjFHKdp2mhzpgq7vmrlR94gjmmmVYjzlVYA211QC//G5Xc7UI2/YRYRK +W2XviQzdFKcgyxilJbQN+QHwotL0AMh0jqEqSI5l2xPE4iUXfeu+h1sXIFRRk0pT +AwvsXcoz7WL9RccvW9xYoIA55vrX/hMUpu09lEpCdNTDd1lzzY9GvlU47/rokTLq +l1gEIt44w8y8bckzOmoKaT+gyOpyj4xjhiO9bTyWnpXgSUyqorkqG5w2gXjtw+hG +4iZZRHUe2XWJUc0QhJ1hYMtd+ZciTY6Y5uN/9lu7rs3KSoFrXgvzUeF0K+l+J6fZ +mUlO+KWA2yUPHGNiiskzZ2s8EIPGrd6ozRaOjfAHN3Gf8qv8QfXBi+wAN10J5U6A +7/qxXDgGpRtK4dw4LTzcqx+QGtVKnO7RcGzM7vRX+Bi6hG6H +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIFZjCCA06gAwIBAgIQCgFCgAAAAUUjz0Z8AAAAAjANBgkqhkiG9w0BAQsFADBN +MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVu +VHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwHhcNMTQwMTE2MTc1MzMyWhcN +MzQwMTE2MTc1MzMyWjBNMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0 +MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2IpT8pEiv6EdrCvsnduTyP4o7 +ekosMSqMjbCpwzFrqHd2hCa2rIFCDQjrVVi7evi8ZX3yoG2LqEfpYnYeEe4IFNGy +RBb06tD6Hi9e28tzQa68ALBKK0CyrOE7S8ItneShm+waOh7wCLPQ5CQ1B5+ctMlS +bdsHyo+1W/CD80/HLaXIrcuVIKQxKFdYWuSNG5qrng0M8gozOSI5Cpcu81N3uURF +/YTLNiCBWS2ab21ISGHKTN9T0a9SvESfqy9rg3LvdYDaBjMbXcjaY8ZNzaxmMc3R +3j6HEDbhuaR672BQssvKplbgN6+rNBM5Jeg5ZuSYeqoSmJxZZoY+rfGwyj4GD3vw +EUs3oERte8uojHH01bWRNszwFcYr3lEXsZdMUD2xlVl8BX0tIdUAvwFnol57plzy +9yLxkA2T26pEUWbMfXYD62qoKjgZl3YNa4ph+bz27nb9cCvdKTz4Ch5bQhyLVi9V +GxyhLrXHFub4qjySjmm2AcG1hp2JDws4lFTo6tyePSW8Uybt1as5qsVATFSrsrTZ +2fjXctscvG29ZV/viDUqZi/u9rNl8DONfJhBaUYPQxxp+pu10GFqzcpL2UyQRqsV +WaFHVCkugyhfHMKiq3IXAAaOReyL4jM9f9oZRORicsPfIsbyVtTdX5Vy7W1f90gD +W/3FKqD2cyOEEBsB5wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ +BAUwAwEB/zAdBgNVHQ4EFgQU43HgntinQtnbcZFrlJPrw6PRFKMwDQYJKoZIhvcN +AQELBQADggIBAEf63QqwEZE4rU1d9+UOl1QZgkiHVIyqZJnYWv6IAcVYpZmxI1Qj +t2odIFflAWJBF9MJ23XLblSQdf4an4EKwt3X9wnQW3IV5B4Jaj0z8yGa5hV+rVHV +DRDtfULAj+7AmgjVQdZcDiFpboBhDhXAuM/FSRJSzL46zNQuOAXeNf0fb7iAaJg9 +TaDKQGXSc3z1i9kKlT/YPyNtGtEqJBnZhbMX73huqVjRI9PHE+1yJX9dsXNw0H8G +lwmEKYBhHfpe/3OsoOOJuBxxFcbeMX8S3OFtm6/n6J91eEyrRjuazr8FGF1NFTwW +mhlQBJqymm9li1JfPFgEKCXAZmExfrngdbkaqIHWchezxQMxNRF4eKLg6TCMf4Df +WN88uieW4oA0beOY02QnrEh+KHdcxiVhJfiFDGX6xDIvpZgF5PgLZxYWxoK4Mhn5 ++bl53B/N66+rDt0b20XkeucC4pVd/GnwU2lhlXV5C15V5jgclKlZM57IcXR5f1GJ +tshquDDIajjDbp7hNxbqBWJMWxJH7ae0s1hWx0nzfxJoCTFx8G34Tkf71oXuxVhA +GaQdp/lLQzfcaFpPz+vCZHTetBXZ9FRUGi8c15dxVJCO2SCdUyt/q4/i6jC8UDfv +8Ue1fXwsBOxonbRJRBD0ckscZOf85muQ3Wl9af0AVqW3rLatt8o+Ae+c +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIEAjCCAuqgAwIBAgIFORFFEJQwDQYJKoZIhvcNAQEFBQAwgYUxCzAJBgNVBAYT +AkZSMQ8wDQYDVQQIEwZGcmFuY2UxDjAMBgNVBAcTBVBhcmlzMRAwDgYDVQQKEwdQ +TS9TR0ROMQ4wDAYDVQQLEwVEQ1NTSTEOMAwGA1UEAxMFSUdDL0ExIzAhBgkqhkiG +9w0BCQEWFGlnY2FAc2dkbi5wbS5nb3V2LmZyMB4XDTAyMTIxMzE0MjkyM1oXDTIw +MTAxNzE0MjkyMlowgYUxCzAJBgNVBAYTAkZSMQ8wDQYDVQQIEwZGcmFuY2UxDjAM +BgNVBAcTBVBhcmlzMRAwDgYDVQQKEwdQTS9TR0ROMQ4wDAYDVQQLEwVEQ1NTSTEO +MAwGA1UEAxMFSUdDL0ExIzAhBgkqhkiG9w0BCQEWFGlnY2FAc2dkbi5wbS5nb3V2 +LmZyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsh/R0GLFMzvABIaI +s9z4iPf930Pfeo2aSVz2TqrMHLmh6yeJ8kbpO0px1R2OLc/mratjUMdUC24SyZA2 +xtgv2pGqaMVy/hcKshd+ebUyiHDKcMCWSo7kVc0dJ5S/znIq7Fz5cyD+vfcuiWe4 +u0dzEvfRNWk68gq5rv9GQkaiv6GFGvm/5P9JhfejcIYyHF2fYPepraX/z9E0+X1b +F8bc1g4oa8Ld8fUzaJ1O/Id8NhLWo4DoQw1VYZTqZDdH6nfK0LJYBcNdfrGoRpAx +Vs5wKpayMLh35nnAvSk7/ZR3TL0gzUEl4C7HG7vupARB0l2tEmqKm0f7yd1GQOGd +PDPQtQIDAQABo3cwdTAPBgNVHRMBAf8EBTADAQH/MAsGA1UdDwQEAwIBRjAVBgNV +HSAEDjAMMAoGCCqBegF5AQEBMB0GA1UdDgQWBBSjBS8YYFDCiQrdKyFP/45OqDAx +NjAfBgNVHSMEGDAWgBSjBS8YYFDCiQrdKyFP/45OqDAxNjANBgkqhkiG9w0BAQUF +AAOCAQEABdwm2Pp3FURo/C9mOnTgXeQp/wYHE4RKq89toB9RlPhJy3Q2FLwV3duJ +L92PoF189RLrn544pEfMs5bZvpwlqwN+Mw+VgQ39FuCIvjfwbF3QMZsyK10XZZOY +YLxuj7GoPB7ZHPOpJkL5ZB3C55L29B5aqhlSXa/oovdgoPaN8In1buAKBQGVyYsg +Crpa/JosPL3Dt8ldeCUFP1YUmwza+zpI/pdpXsoQhvdOlgQITeywvl3cO45Pwf2a +NjSaTFR+FwNIlQgRHAdvhQh+XU3Endv7rs6y0bO4g2wdsrN58dhwmX7wEwLOXt1R +0982gaEbeC9xs/FZTEYYKKuF0mBWWg== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIF8TCCA9mgAwIBAgIQALC3WhZIX7/hy/WL1xnmfTANBgkqhkiG9w0BAQsFADA4 +MQswCQYDVQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6 +ZW5wZS5jb20wHhcNMDcxMjEzMTMwODI4WhcNMzcxMjEzMDgyNzI1WjA4MQswCQYD +VQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6ZW5wZS5j +b20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDJ03rKDx6sp4boFmVq +scIbRTJxldn+EFvMr+eleQGPicPK8lVx93e+d5TzcqQsRNiekpsUOqHnJJAKClaO +xdgmlOHZSOEtPtoKct2jmRXagaKH9HtuJneJWK3W6wyyQXpzbm3benhB6QiIEn6H +LmYRY2xU+zydcsC8Lv/Ct90NduM61/e0aL6i9eOBbsFGb12N4E3GVFWJGjMxCrFX +uaOKmMPsOzTFlUFpfnXCPCDFYbpRR6AgkJOhkEvzTnyFRVSa0QUmQbC1TR0zvsQD +yCV8wXDbO/QJLVQnSKwv4cSsPsjLkkxTOTcj7NMB+eAJRE1NZMDhDVqHIrytG6P+ +JrUV86f8hBnp7KGItERphIPzidF0BqnMC9bC3ieFUCbKF7jJeodWLBoBHmy+E60Q +rLUk9TiRodZL2vG70t5HtfG8gfZZa88ZU+mNFctKy6lvROUbQc/hhqfK0GqfvEyN +BjNaooXlkDWgYlwWTvDjovoDGrQscbNYLN57C9saD+veIR8GdwYDsMnvmfzAuU8L +hij+0rnq49qlw0dpEuDb8PYZi+17cNcC1u2HGCgsBCRMd+RIihrGO5rUD8r6ddIB +QFqNeb+Lz0vPqhbBleStTIo+F5HUsWLlguWABKQDfo2/2n+iD5dPDNMN+9fR5XJ+ +HMh3/1uaD7euBUbl8agW7EekFwIDAQABo4H2MIHzMIGwBgNVHREEgagwgaWBD2lu +Zm9AaXplbnBlLmNvbaSBkTCBjjFHMEUGA1UECgw+SVpFTlBFIFMuQS4gLSBDSUYg +QTAxMzM3MjYwLVJNZXJjLlZpdG9yaWEtR2FzdGVpeiBUMTA1NSBGNjIgUzgxQzBB +BgNVBAkMOkF2ZGEgZGVsIE1lZGl0ZXJyYW5lbyBFdG9yYmlkZWEgMTQgLSAwMTAx +MCBWaXRvcmlhLUdhc3RlaXowDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC +AQYwHQYDVR0OBBYEFB0cZQ6o8iV7tJHP5LGx5r1VdGwFMA0GCSqGSIb3DQEBCwUA +A4ICAQB4pgwWSp9MiDrAyw6lFn2fuUhfGI8NYjb2zRlrrKvV9pF9rnHzP7MOeIWb +laQnIUdCSnxIOvVFfLMMjlF4rJUT3sb9fbgakEyrkgPH7UIBzg/YsfqikuFgba56 +awmqxinuaElnMIAkejEWOVt+8Rwu3WwJrfIxwYJOubv5vr8qhT/AQKM6WfxZSzwo +JNu0FXWuDYi6LnPAvViH5ULy617uHjAimcs30cQhbIHsvm0m5hzkQiCeR7Csg1lw +LDXWrzY0tM07+DKo7+N4ifuNRSzanLh+QBxh5z6ikixL8s36mLYp//Pye6kfLqCT +VyvehQP5aTfLnnhqBbTFMXiJ7HqnheG5ezzevh55hM6fcA5ZwjUukCox2eRFekGk +LhObNA5me0mrZJfQRsN5nXJQY6aYWwa9SG3YOYNw6DXwBdGqvOPbyALqfP2C2sJb +UjWumDqtujWTI6cfSN01RpiyEGjkpTHCClguGYEQyVB1/OpaFs4R1+7vUIgtYf8/ +QnMFlEPVjjxOAToZpR9GTnfQXeWBIiGH/pR9hNiTrdZoQ0iy2+tzJOeRf1SktoA+ +naM8THLCV8Sg1Mw4J87VBp6iSNnpn86CcDaTmjvfliHjWbcM2pE38P1ZWrOZyGls +QyYBNWNgVYkDOnXYukrZVP/u3oDYLdE41V4tC5h9Pmzb/CaIxw== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIE5jCCA86gAwIBAgIEO45L/DANBgkqhkiG9w0BAQUFADBdMRgwFgYJKoZIhvcN +AQkBFglwa2lAc2suZWUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKExlBUyBTZXJ0aWZp +dHNlZXJpbWlza2Vza3VzMRAwDgYDVQQDEwdKdXVyLVNLMB4XDTAxMDgzMDE0MjMw +MVoXDTE2MDgyNjE0MjMwMVowXTEYMBYGCSqGSIb3DQEJARYJcGtpQHNrLmVlMQsw +CQYDVQQGEwJFRTEiMCAGA1UEChMZQVMgU2VydGlmaXRzZWVyaW1pc2tlc2t1czEQ +MA4GA1UEAxMHSnV1ci1TSzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +AIFxNj4zB9bjMI0TfncyRsvPGbJgMUaXhvSYRqTCZUXP00B841oiqBB4M8yIsdOB +SvZiF3tfTQou0M+LI+5PAk676w7KvRhj6IAcjeEcjT3g/1tf6mTll+g/mX8MCgkz +ABpTpyHhOEvWgxutr2TC+Rx6jGZITWYfGAriPrsfB2WThbkasLnE+w0R9vXW+RvH +LCu3GFH+4Hv2qEivbDtPL+/40UceJlfwUR0zlv/vWT3aTdEVNMfqPxZIe5EcgEMP +PbgFPtGzlc3Yyg/CQ2fbt5PgIoIuvvVoKIO5wTtpeyDaTpxt4brNj3pssAki14sL +2xzVWiZbDcDq5WDQn/413z8CAwEAAaOCAawwggGoMA8GA1UdEwEB/wQFMAMBAf8w +ggEWBgNVHSAEggENMIIBCTCCAQUGCisGAQQBzh8BAQEwgfYwgdAGCCsGAQUFBwIC +MIHDHoHAAFMAZQBlACAAcwBlAHIAdABpAGYAaQBrAGEAYQB0ACAAbwBuACAAdgDk +AGwAagBhAHMAdABhAHQAdQBkACAAQQBTAC0AaQBzACAAUwBlAHIAdABpAGYAaQB0 +AHMAZQBlAHIAaQBtAGkAcwBrAGUAcwBrAHUAcwAgAGEAbABhAG0ALQBTAEsAIABz +AGUAcgB0AGkAZgBpAGsAYQBhAHQAaQBkAGUAIABrAGkAbgBuAGkAdABhAG0AaQBz +AGUAawBzMCEGCCsGAQUFBwIBFhVodHRwOi8vd3d3LnNrLmVlL2Nwcy8wKwYDVR0f +BCQwIjAgoB6gHIYaaHR0cDovL3d3dy5zay5lZS9qdXVyL2NybC8wHQYDVR0OBBYE +FASqekej5ImvGs8KQKcYP2/v6X2+MB8GA1UdIwQYMBaAFASqekej5ImvGs8KQKcY +P2/v6X2+MA4GA1UdDwEB/wQEAwIB5jANBgkqhkiG9w0BAQUFAAOCAQEAe8EYlFOi +CfP+JmeaUOTDBS8rNXiRTHyoERF5TElZrMj3hWVcRrs7EKACr81Ptcw2Kuxd/u+g +kcm2k298gFTsxwhwDY77guwqYHhpNjbRxZyLabVAyJRld/JXIWY7zoVAtjNjGr95 +HvxcHdMdkxuLDF2FvZkwMhgJkVLpfKG6/2SSmuz+Ne6ML678IIbsSt4beDI3poHS +na9aEhbKmVv8b20OxaAehsmR0FyYgl9jDIpaq9iVpszLita/ZEuOyoqysOkhMp6q +qIWYNIE5ITuoOlIyPfZrN4YGWhWY3PARZv40ILcD9EEQfTmEeZZyY7aWAuVrua0Z +TbvGRNs2yyqcjg== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIECjCCAvKgAwIBAgIJAMJ+QwRORz8ZMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYD +VQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0 +ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0G +CSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5odTAeFw0wOTA2MTYxMTMwMThaFw0y +OTEyMzAxMTMwMThaMIGCMQswCQYDVQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3Qx +FjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3pp +Z25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5o +dTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOn4j/NjrdqG2KfgQvvP +kd6mJviZpWNwrZuuyjNAfW2WbqEORO7hE52UQlKavXWFdCyoDh2Tthi3jCyoz/tc +cbna7P7ofo/kLx2yqHWH2Leh5TvPmUpG0IMZfcChEhyVbUr02MelTTMuhTlAdX4U +fIASmFDHQWe4oIBhVKZsTh/gnQ4H6cm6M+f+wFUoLAKApxn1ntxVUwOXewdI/5n7 +N4okxFnMUBBjjqqpGrCEGob5X7uxUG6k0QrM1XF+H6cbfPVTbiJfyyvm1HxdrtbC +xkzlBQHZ7Vf8wSN5/PrIJIOV87VqUQHQd9bpEqH5GoP7ghu5sJf0dgYzQ0mg/wu1 ++rUCAwEAAaOBgDB+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G +A1UdDgQWBBTLD8bfQkPMPcu1SCOhGnqmKrs0aDAfBgNVHSMEGDAWgBTLD8bfQkPM +Pcu1SCOhGnqmKrs0aDAbBgNVHREEFDASgRBpbmZvQGUtc3ppZ25vLmh1MA0GCSqG +SIb3DQEBCwUAA4IBAQDJ0Q5eLtXMs3w+y/w9/w0olZMEyL/azXm4Q5DwpL7v8u8h +mLzU1F0G9u5C7DBsoKqpyvGvivo/C3NqPuouQH4frlRheesuCDfXI/OMn74dseGk +ddug4lQUsbocKaQY9hK6ohQU4zE1yED/t+AFdlfBHFny+L/k7SViXITwfn4fs775 +tyERzAMBVnCnEJIeGzSBHq2cGsMEPO0CYdYeBvNfOofyK/FFh+U9rNHHV4S9a67c +2Pm2G2JwCz02yULyMtd6YebS2z3PyKnJm9zbWETXbzivf3jTo60adbocwTZ8jx5t +HMN1Rq41Bab2XD0h7lbwyYIiLXpUq3DDfSJlgnCW +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIHqDCCBpCgAwIBAgIRAMy4579OKRr9otxmpRwsDxEwDQYJKoZIhvcNAQEFBQAw +cjELMAkGA1UEBhMCSFUxETAPBgNVBAcTCEJ1ZGFwZXN0MRYwFAYDVQQKEw1NaWNy +b3NlYyBMdGQuMRQwEgYDVQQLEwtlLVN6aWdubyBDQTEiMCAGA1UEAxMZTWljcm9z +ZWMgZS1Temlnbm8gUm9vdCBDQTAeFw0wNTA0MDYxMjI4NDRaFw0xNzA0MDYxMjI4 +NDRaMHIxCzAJBgNVBAYTAkhVMREwDwYDVQQHEwhCdWRhcGVzdDEWMBQGA1UEChMN +TWljcm9zZWMgTHRkLjEUMBIGA1UECxMLZS1Temlnbm8gQ0ExIjAgBgNVBAMTGU1p +Y3Jvc2VjIGUtU3ppZ25vIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw +ggEKAoIBAQDtyADVgXvNOABHzNuEwSFpLHSQDCHZU4ftPkNEU6+r+ICbPHiN1I2u +uO/TEdyB5s87lozWbxXGd36hL+BfkrYn13aaHUM86tnsL+4582pnS4uCzyL4ZVX+ +LMsvfUh6PXX5qqAnu3jCBspRwn5mS6/NoqdNAoI/gqyFxuEPkEeZlApxcpMqyabA +vjxWTHOSJ/FrtfX9/DAFYJLG65Z+AZHCabEeHXtTRbjcQR/Ji3HWVBTji1R4P770 +Yjtb9aPs1ZJ04nQw7wHb4dSrmZsqa/i9phyGI0Jf7Enemotb9HI6QMVJPqW+jqpx +62z69Rrkav17fVVA71hu5tnVvCSrwe+3AgMBAAGjggQ3MIIEMzBnBggrBgEFBQcB +AQRbMFkwKAYIKwYBBQUHMAGGHGh0dHBzOi8vcmNhLmUtc3ppZ25vLmh1L29jc3Aw +LQYIKwYBBQUHMAKGIWh0dHA6Ly93d3cuZS1zemlnbm8uaHUvUm9vdENBLmNydDAP +BgNVHRMBAf8EBTADAQH/MIIBcwYDVR0gBIIBajCCAWYwggFiBgwrBgEEAYGoGAIB +AQEwggFQMCgGCCsGAQUFBwIBFhxodHRwOi8vd3d3LmUtc3ppZ25vLmh1L1NaU1ov +MIIBIgYIKwYBBQUHAgIwggEUHoIBEABBACAAdABhAG4A+gBzAO0AdAB2AOEAbgB5 +ACAA6QByAHQAZQBsAG0AZQB6AOkAcwDpAGgAZQB6ACAA6QBzACAAZQBsAGYAbwBn +AGEAZADhAHMA4QBoAG8AegAgAGEAIABTAHoAbwBsAGcA4QBsAHQAYQB0APMAIABT +AHoAbwBsAGcA4QBsAHQAYQB0AOEAcwBpACAAUwB6AGEAYgDhAGwAeQB6AGEAdABh +ACAAcwB6AGUAcgBpAG4AdAAgAGsAZQBsAGwAIABlAGwAagDhAHIAbgBpADoAIABo +AHQAdABwADoALwAvAHcAdwB3AC4AZQAtAHMAegBpAGcAbgBvAC4AaAB1AC8AUwBa +AFMAWgAvMIHIBgNVHR8EgcAwgb0wgbqggbeggbSGIWh0dHA6Ly93d3cuZS1zemln +bm8uaHUvUm9vdENBLmNybIaBjmxkYXA6Ly9sZGFwLmUtc3ppZ25vLmh1L0NOPU1p +Y3Jvc2VjJTIwZS1Temlnbm8lMjBSb290JTIwQ0EsT1U9ZS1Temlnbm8lMjBDQSxP +PU1pY3Jvc2VjJTIwTHRkLixMPUJ1ZGFwZXN0LEM9SFU/Y2VydGlmaWNhdGVSZXZv +Y2F0aW9uTGlzdDtiaW5hcnkwDgYDVR0PAQH/BAQDAgEGMIGWBgNVHREEgY4wgYuB +EGluZm9AZS1zemlnbm8uaHWkdzB1MSMwIQYDVQQDDBpNaWNyb3NlYyBlLVN6aWdu +w7MgUm9vdCBDQTEWMBQGA1UECwwNZS1TemlnbsOzIEhTWjEWMBQGA1UEChMNTWlj +cm9zZWMgS2Z0LjERMA8GA1UEBxMIQnVkYXBlc3QxCzAJBgNVBAYTAkhVMIGsBgNV +HSMEgaQwgaGAFMegSXUWYYTbMUuE0vE3QJDvTtz3oXakdDByMQswCQYDVQQGEwJI +VTERMA8GA1UEBxMIQnVkYXBlc3QxFjAUBgNVBAoTDU1pY3Jvc2VjIEx0ZC4xFDAS +BgNVBAsTC2UtU3ppZ25vIENBMSIwIAYDVQQDExlNaWNyb3NlYyBlLVN6aWdubyBS +b290IENBghEAzLjnv04pGv2i3GalHCwPETAdBgNVHQ4EFgQUx6BJdRZhhNsxS4TS +8TdAkO9O3PcwDQYJKoZIhvcNAQEFBQADggEBANMTnGZjWS7KXHAM/IO8VbH0jgds +ZifOwTsgqRy7RlRw7lrMoHfqaEQn6/Ip3Xep1fvj1KcExJW4C+FEaGAHQzAxQmHl +7tnlJNUb3+FKG6qfx1/4ehHqE5MAyopYse7tDk2016g2JnzgOsHVV4Lxdbb9iV/a +86g4nzUGCM4ilb7N1fy+W955a9x6qWVmvrElWl/tftOsRm1M9DKHtCAE4Gx4sHfR +hUZLphK3dehKyVZs15KrnfVJONJPU+NVkBHbmJbGSfI+9J8b4PeI3CVimUTYc78/ +MPMMNz7UwiiAc7EBt51alhQBS6kRnSlqLtBdgcDPsiBDxwPgN05dCtxZICU= +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQG +EwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3 +MDUGA1UECwwuVGFuw7pzw610dsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNl +cnZpY2VzKTE1MDMGA1UEAwwsTmV0TG9jayBBcmFueSAoQ2xhc3MgR29sZCkgRsWR +dGFuw7pzw610dsOhbnkwHhcNMDgxMjExMTUwODIxWhcNMjgxMjA2MTUwODIxWjCB +pzELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRUwEwYDVQQKDAxOZXRM +b2NrIEtmdC4xNzA1BgNVBAsMLlRhbsO6c8OtdHbDoW55a2lhZMOzayAoQ2VydGlm +aWNhdGlvbiBTZXJ2aWNlcykxNTAzBgNVBAMMLE5ldExvY2sgQXJhbnkgKENsYXNz +IEdvbGQpIEbFkXRhbsO6c8OtdHbDoW55MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAxCRec75LbRTDofTjl5Bu0jBFHjzuZ9lk4BqKf8owyoPjIMHj9DrT +lF8afFttvzBPhCf2nx9JvMaZCpDyD/V/Q4Q3Y1GLeqVw/HpYzY6b7cNGbIRwXdrz +AZAj/E4wqX7hJ2Pn7WQ8oLjJM2P+FpD/sLj916jAwJRDC7bVWaaeVtAkH3B5r9s5 +VA1lddkVQZQBr17s9o3x/61k/iCa11zr/qYfCGSji3ZVrR47KGAuhyXoqq8fxmRG +ILdwfzzeSNuWU7c5d+Qa4scWhHaXWy+7GRWF+GmF9ZmnqfI0p6m2pgP8b4Y9VHx2 +BJtr+UBdADTHLpl1neWIA6pN+APSQnbAGwIDAKiLo0UwQzASBgNVHRMBAf8ECDAG +AQH/AgEEMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUzPpnk/C2uNClwB7zU/2M +U9+D15YwDQYJKoZIhvcNAQELBQADggEBAKt/7hwWqZw8UQCgwBEIBaeZ5m8BiFRh +bvG5GK1Krf6BQCOUL/t1fC8oS2IkgYIL9WHxHG64YTjrgfpioTtaYtOUZcTh5m2C ++C8lcLIhJsFyUR+MLMOEkMNaj7rP9KdlpeuY0fsFskZ1FSNqb4VjMIDw1Z4fKRzC +bLBQWV2QWzuoDTDPv31/zvGdg73JRm4gpvlhUbohL3u+pRVjodSVh/GeufOJ8z2F +uLjbvrW5KfnaNwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2 +XjG4Kvte9nHfRCaexOYNkbQudZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E= +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIID5jCCAs6gAwIBAgIQV8szb8JcFuZHFhfjkDFo4DANBgkqhkiG9w0BAQUFADBi +MQswCQYDVQQGEwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMu +MTAwLgYDVQQDEydOZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3Jp +dHkwHhcNMDYxMjAxMDAwMDAwWhcNMjkxMjMxMjM1OTU5WjBiMQswCQYDVQQGEwJV +UzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMuMTAwLgYDVQQDEydO +ZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkvH6SMG3G2I4rC7xGzuAnlt7e+foS0zwz +c7MEL7xxjOWftiJgPl9dzgn/ggwbmlFQGiaJ3dVhXRncEg8tCqJDXRfQNJIg6nPP +OCwGJgl6cvf6UDL4wpPTaaIjzkGxzOTVHzbRijr4jGPiFFlp7Q3Tf2vouAPlT2rl +mGNpSAW+Lv8ztumXWWn4Zxmuk2GWRBXTcrA/vGp97Eh/jcOrqnErU2lBUzS1sLnF +BgrEsEX1QV1uiUV7PTsmjHTC5dLRfbIR1PtYMiKagMnc/Qzpf14Dl847ABSHJ3A4 +qY5usyd2mFHgBeMhqxrVhSI8KbWaFsWAqPS7azCPL0YCorEMIuDTAgMBAAGjgZcw +gZQwHQYDVR0OBBYEFCEwyfsA106Y2oeqKtCnLrFAMadMMA4GA1UdDwEB/wQEAwIB +BjAPBgNVHRMBAf8EBTADAQH/MFIGA1UdHwRLMEkwR6BFoEOGQWh0dHA6Ly9jcmwu +bmV0c29sc3NsLmNvbS9OZXR3b3JrU29sdXRpb25zQ2VydGlmaWNhdGVBdXRob3Jp +dHkuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQC7rkvnt1frf6ott3NHhWrB5KUd5Oc8 +6fRZZXe1eltajSU24HqXLjjAV2CDmAaDn7l2em5Q4LqILPxFzBiwmZVRDuwduIj/ +h1AcgsLj4DKAv6ALR8jDMe+ZZzKATxcheQxpXN5eNK4CtSbqUN9/GGUsyfJj4akH +/nxxH2szJGoeBfcFaMBqEssuXmHLrijTfsK0ZpEmXzwuJF/LWA/rKOyvEZbz3Htv +wKeI8lN3s2Berq4o2jUsbzRF0ybh3uxbTydrFny9RAQYgrOJeRcQcT16ohZO9QHN +pGxlaKFJdlxDydi8NmdspZS11My5vWo1ViHe2MPr+8ukYEywVaCge1ey +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIID8TCCAtmgAwIBAgIQQT1yx/RrH4FDffHSKFTfmjANBgkqhkiG9w0BAQUFADCB +ijELMAkGA1UEBhMCQ0gxEDAOBgNVBAoTB1dJU2VLZXkxGzAZBgNVBAsTEkNvcHly +aWdodCAoYykgMjAwNTEiMCAGA1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNl +ZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwgUm9vdCBHQSBDQTAeFw0w +NTEyMTExNjAzNDRaFw0zNzEyMTExNjA5NTFaMIGKMQswCQYDVQQGEwJDSDEQMA4G +A1UEChMHV0lTZUtleTEbMBkGA1UECxMSQ29weXJpZ2h0IChjKSAyMDA1MSIwIAYD +VQQLExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBX +SVNlS2V5IEdsb2JhbCBSb290IEdBIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAy0+zAJs9Nt350UlqaxBJH+zYK7LG+DKBKUOVTJoZIyEVRd7jyBxR +VVuuk+g3/ytr6dTqvirdqFEr12bDYVxgAsj1znJ7O7jyTmUIms2kahnBAbtzptf2 +w93NvKSLtZlhuAGio9RN1AU9ka34tAhxZK9w8RxrfvbDd50kc3vkDIzh2TbhmYsF +mQvtRTEJysIA2/dyoJaqlYfQjse2YXMNdmaM3Bu0Y6Kff5MTMPGhJ9vZ/yxViJGg +4E8HsChWjBgbl0SOid3gF27nKu+POQoxhILYQBRJLnpB5Kf+42TMwVlxSywhp1t9 +4B3RLoGbw9ho972WG6xwsRYUC9tguSYBBQIDAQABo1EwTzALBgNVHQ8EBAMCAYYw +DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUswN+rja8sHnR3JQmthG+IbJphpQw +EAYJKwYBBAGCNxUBBAMCAQAwDQYJKoZIhvcNAQEFBQADggEBAEuh/wuHbrP5wUOx +SPMowB0uyQlB+pQAHKSkq0lPjz0e701vvbyk9vImMMkQyh2I+3QZH4VFvbBsUfk2 +ftv1TDI6QU9bR8/oCy22xBmddMVHxjtqD6wU2zz0c5ypBd8A3HR4+vg1YFkCExh8 +vPtNsCBtQ7tgMHpnM1zFmdH4LTlSc/uMqpclXHLZCB6rTjzjgTGfA6b7wP4piFXa +hNVQA7bihKOmNqoROgHhGEvWRGizPflTdISzRpFGlgC3gCy24eMQ4tui5yiPAZZi +Fj4A4xylNoEYokxSdsARo27mHbrjWr42U8U+dY+GaSlYU7Wcu2+fXMUY7N0v4ZjJ +/L7fCg0= +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIJhjCCB26gAwIBAgIBCzANBgkqhkiG9w0BAQsFADCCAR4xPjA8BgNVBAMTNUF1 +dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIFJhaXogZGVsIEVzdGFkbyBWZW5lem9s +YW5vMQswCQYDVQQGEwJWRTEQMA4GA1UEBxMHQ2FyYWNhczEZMBcGA1UECBMQRGlz +dHJpdG8gQ2FwaXRhbDE2MDQGA1UEChMtU2lzdGVtYSBOYWNpb25hbCBkZSBDZXJ0 +aWZpY2FjaW9uIEVsZWN0cm9uaWNhMUMwQQYDVQQLEzpTdXBlcmludGVuZGVuY2lh +IGRlIFNlcnZpY2lvcyBkZSBDZXJ0aWZpY2FjaW9uIEVsZWN0cm9uaWNhMSUwIwYJ +KoZIhvcNAQkBFhZhY3JhaXpAc3VzY2VydGUuZ29iLnZlMB4XDTEwMTIyODE2NTEw +MFoXDTIwMTIyNTIzNTk1OVowgdExJjAkBgkqhkiG9w0BCQEWF2NvbnRhY3RvQHBy +b2NlcnQubmV0LnZlMQ8wDQYDVQQHEwZDaGFjYW8xEDAOBgNVBAgTB01pcmFuZGEx +KjAoBgNVBAsTIVByb3ZlZWRvciBkZSBDZXJ0aWZpY2Fkb3MgUFJPQ0VSVDE2MDQG +A1UEChMtU2lzdGVtYSBOYWNpb25hbCBkZSBDZXJ0aWZpY2FjaW9uIEVsZWN0cm9u +aWNhMQswCQYDVQQGEwJWRTETMBEGA1UEAxMKUFNDUHJvY2VydDCCAiIwDQYJKoZI +hvcNAQEBBQADggIPADCCAgoCggIBANW39KOUM6FGqVVhSQ2oh3NekS1wwQYalNo9 +7BVCwfWMrmoX8Yqt/ICV6oNEolt6Vc5Pp6XVurgfoCfAUFM+jbnADrgV3NZs+J74 +BCXfgI8Qhd19L3uA3VcAZCP4bsm+lU/hdezgfl6VzbHvvnpC2Mks0+saGiKLt38G +ieU89RLAu9MLmV+QfI4tL3czkkohRqipCKzx9hEC2ZUWno0vluYC3XXCFCpa1sl9 +JcLB/KpnheLsvtF8PPqv1W7/U0HU9TI4seJfxPmOEO8GqQKJ/+MMbpfg353bIdD0 +PghpbNjU5Db4g7ayNo+c7zo3Fn2/omnXO1ty0K+qP1xmk6wKImG20qCZyFSTXai2 +0b1dCl53lKItwIKOvMoDKjSuc/HUtQy9vmebVOvh+qBa7Dh+PsHMosdEMXXqP+UH +0quhJZb25uSgXTcYOWEAM11G1ADEtMo88aKjPvM6/2kwLkDd9p+cJsmWN63nOaK/ +6mnbVSKVUyqUtd+tFjiBdWbjxywbk5yqjKPK2Ww8F22c3HxT4CAnQzb5EuE8XL1m +v6JpIzi4mWCZDlZTOpx+FIywBm/xhnaQr/2v/pDGj59/i5IjnOcVdo/Vi5QTcmn7 +K2FjiO/mpF7moxdqWEfLcU8UC17IAggmosvpr2uKGcfLFFb14dq12fy/czja+eev +bqQ34gcnAgMBAAGjggMXMIIDEzASBgNVHRMBAf8ECDAGAQH/AgEBMDcGA1UdEgQw +MC6CD3N1c2NlcnRlLmdvYi52ZaAbBgVghl4CAqASDBBSSUYtRy0yMDAwNDAzNi0w +MB0GA1UdDgQWBBRBDxk4qpl/Qguk1yeYVKIXTC1RVDCCAVAGA1UdIwSCAUcwggFD +gBStuyIdxuDSAaj9dlBSk+2YwU2u06GCASakggEiMIIBHjE+MDwGA1UEAxM1QXV0 +b3JpZGFkIGRlIENlcnRpZmljYWNpb24gUmFpeiBkZWwgRXN0YWRvIFZlbmV6b2xh +bm8xCzAJBgNVBAYTAlZFMRAwDgYDVQQHEwdDYXJhY2FzMRkwFwYDVQQIExBEaXN0 +cml0byBDYXBpdGFsMTYwNAYDVQQKEy1TaXN0ZW1hIE5hY2lvbmFsIGRlIENlcnRp +ZmljYWNpb24gRWxlY3Ryb25pY2ExQzBBBgNVBAsTOlN1cGVyaW50ZW5kZW5jaWEg +ZGUgU2VydmljaW9zIGRlIENlcnRpZmljYWNpb24gRWxlY3Ryb25pY2ExJTAjBgkq +hkiG9w0BCQEWFmFjcmFpekBzdXNjZXJ0ZS5nb2IudmWCAQowDgYDVR0PAQH/BAQD +AgEGME0GA1UdEQRGMESCDnByb2NlcnQubmV0LnZloBUGBWCGXgIBoAwMClBTQy0w +MDAwMDKgGwYFYIZeAgKgEgwQUklGLUotMzE2MzUzNzMtNzB2BgNVHR8EbzBtMEag +RKBChkBodHRwOi8vd3d3LnN1c2NlcnRlLmdvYi52ZS9sY3IvQ0VSVElGSUNBRE8t +UkFJWi1TSEEzODRDUkxERVIuY3JsMCOgIaAfhh1sZGFwOi8vYWNyYWl6LnN1c2Nl +cnRlLmdvYi52ZTA3BggrBgEFBQcBAQQrMCkwJwYIKwYBBQUHMAGGG2h0dHA6Ly9v +Y3NwLnN1c2NlcnRlLmdvYi52ZTBBBgNVHSAEOjA4MDYGBmCGXgMBAjAsMCoGCCsG +AQUFBwIBFh5odHRwOi8vd3d3LnN1c2NlcnRlLmdvYi52ZS9kcGMwDQYJKoZIhvcN +AQELBQADggIBACtZ6yKZu4SqT96QxtGGcSOeSwORR3C7wJJg7ODU523G0+1ng3dS +1fLld6c2suNUvtm7CpsR72H0xpkzmfWvADmNg7+mvTV+LFwxNG9s2/NkAZiqlCxB +3RWGymspThbASfzXg0gTB1GEMVKIu4YXx2sviiCtxQuPcD4quxtxj7mkoP3Yldmv +Wb8lK5jpY5MvYB7Eqvh39YtsL+1+LrVPQA3uvFd359m21D+VJzog1eWuq2w1n8Gh +HVnchIHuTQfiSLaeS5UtQbHh6N5+LwUeaO6/u5BlOsju6rEYNxxik6SgMexxbJHm +pHmJWhSnFFAFTKQAVzAswbVhltw+HoSvOULP5dAssSS830DD7X9jSr3hTxJkhpXz +sOfIt+FTvZLm8wyWuevo5pLtp4EJFAv8lXrPj9Y0TzYS3F7RNHXGRoAvlQSMx4bE +qCaJqD8Zm4G7UaRKhqsLEQ+xrmNTbSjq3TNWOByyrYDT13K9mmyZY+gAu0F2Bbdb +mRiKw7gSXFbPVgx96OLP7bx0R/vu0xdOIk9W/1DzLuY5poLWccret9W6aAjtmcz9 +opLLabid+Qqkpj5PkygqYWwHJgD/ll9ohri4zspV4KuxPX+Y1zMOWj3YeMLEYC/H +YvBhkdI4sPaeVdtAgAUSM84dkpvRabP/v/GSCmE1P93+hvS84Bpxs2Km +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIUeFhfLq0sGUvjNwc1NBMotZbUZZMwDQYJKoZIhvcNAQEL +BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc +BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMSBHMzAeFw0xMjAxMTIxNzI3NDRaFw00 +MjAxMTIxNzI3NDRaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM +aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDEgRzMwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCgvlAQjunybEC0BJyFuTHK3C3kEakEPBtV +wedYMB0ktMPvhd6MLOHBPd+C5k+tR4ds7FtJwUrVu4/sh6x/gpqG7D0DmVIB0jWe +rNrwU8lmPNSsAgHaJNM7qAJGr6Qc4/hzWHa39g6QDbXwz8z6+cZM5cOGMAqNF341 +68Xfuw6cwI2H44g4hWf6Pser4BOcBRiYz5P1sZK0/CPTz9XEJ0ngnjybCKOLXSoh +4Pw5qlPafX7PGglTvFOFBM+hSo+LdoINofjSxxR3W5A2B4GbPgb6Ul5jxaYA/qXp +UhtStZI5cgMJYr2wYBZupt0lwgNm3fME0UDiTouG9G/lg6AnhF4EwfWQvTA9xO+o +abw4m6SkltFi2mnAAZauy8RRNOoMqv8hjlmPSlzkYZqn0ukqeI1RPToV7qJZjqlc +3sX5kCLliEVx3ZGZbHqfPT2YfF72vhZooF6uCyP8Wg+qInYtyaEQHeTTRCOQiJ/G +KubX9ZqzWB4vMIkIG1SitZgj7Ah3HJVdYdHLiZxfokqRmu8hqkkWCKi9YSgxyXSt +hfbZxbGL0eUQMk1fiyA6PEkfM4VZDdvLCXVDaXP7a3F98N/ETH3Goy7IlXnLc6KO +Tk0k+17kBL5yG6YnLUlamXrXXAkgt3+UuU/xDRxeiEIbEbfnkduebPRq34wGmAOt +zCjvpUfzUwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +BjAdBgNVHQ4EFgQUo5fW816iEOGrRZ88F2Q87gFwnMwwDQYJKoZIhvcNAQELBQAD +ggIBABj6W3X8PnrHX3fHyt/PX8MSxEBd1DKquGrX1RUVRpgjpeaQWxiZTOOtQqOC +MTaIzen7xASWSIsBx40Bz1szBpZGZnQdT+3Btrm0DWHMY37XLneMlhwqI2hrhVd2 +cDMT/uFPpiN3GPoajOi9ZcnPP/TJF9zrx7zABC4tRi9pZsMbj/7sPtPKlL92CiUN +qXsCHKnQO18LwIE6PWThv6ctTr1NxNgpxiIY0MWscgKCP6o6ojoilzHdCGPDdRS5 +YCgtW2jgFqlmgiNR9etT2DGbe+m3nUvriBbP+V04ikkwj+3x6xn0dxoxGE1nVGwv +b2X52z3sIexe9PSLymBlVNFxZPT5pqOBMzYzcfCkeF9OrYMh3jRJjehZrJ3ydlo2 +8hP0r+AJx2EqbPfgna67hkooby7utHnNkDPDs3b69fBsnQGQ+p6Q9pxyz0fawx/k +NSBT8lTR32GDpgLiJTjehTItXnOQUl1CxM49S+H5GYQd1aJQzEH7QRTDvdbJWqNj +ZgKAvQU6O0ec7AAmTPWIUb+oI38YB7AL7YsmoWTTYUrrXJ/es69nA7Mf3W1daWhp +q1467HxpvMc7hU6eFbm0FU/DlXpY18ls6Wy58yljXrQs8C097Vpl4KlbQMJImYFt +nh8GKjwStIsPm6Ik8KaN1nrgS7ZklmOVhMJKzRwuJIczYOXD +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIFtzCCA5+gAwIBAgICBQkwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x +GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv +b3QgQ0EgMjAeFw0wNjExMjQxODI3MDBaFw0zMTExMjQxODIzMzNaMEUxCzAJBgNV +BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W +YWRpcyBSb290IENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCa +GMpLlA0ALa8DKYrwD4HIrkwZhR0In6spRIXzL4GtMh6QRr+jhiYaHv5+HBg6XJxg +Fyo6dIMzMH1hVBHL7avg5tKifvVrbxi3Cgst/ek+7wrGsxDp3MJGF/hd/aTa/55J +WpzmM+Yklvc/ulsrHHo1wtZn/qtmUIttKGAr79dgw8eTvI02kfN/+NsRE8Scd3bB +rrcCaoF6qUWD4gXmuVbBlDePSHFjIuwXZQeVikvfj8ZaCuWw419eaxGrDPmF60Tp ++ARz8un+XJiM9XOva7R+zdRcAitMOeGylZUtQofX1bOQQ7dsE/He3fbE+Ik/0XX1 +ksOR1YqI0JDs3G3eicJlcZaLDQP9nL9bFqyS2+r+eXyt66/3FsvbzSUr5R/7mp/i +Ucw6UwxI5g69ybR2BlLmEROFcmMDBOAENisgGQLodKcftslWZvB1JdxnwQ5hYIiz +PtGo/KPaHbDRsSNU30R2be1B2MGyIrZTHN81Hdyhdyox5C315eXbyOD/5YDXC2Og +/zOhD7osFRXql7PSorW+8oyWHhqPHWykYTe5hnMz15eWniN9gqRMgeKh0bpnX5UH +oycR7hYQe7xFSkyyBNKr79X9DFHOUGoIMfmR2gyPZFwDwzqLID9ujWc9Otb+fVuI +yV77zGHcizN300QyNQliBJIWENieJ0f7OyHj+OsdWwIDAQABo4GwMIGtMA8GA1Ud +EwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBQahGK8SEwzJQTU7tD2 +A8QZRtGUazBuBgNVHSMEZzBlgBQahGK8SEwzJQTU7tD2A8QZRtGUa6FJpEcwRTEL +MAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMT +ElF1b1ZhZGlzIFJvb3QgQ0EgMoICBQkwDQYJKoZIhvcNAQEFBQADggIBAD4KFk2f +BluornFdLwUvZ+YTRYPENvbzwCYMDbVHZF34tHLJRqUDGCdViXh9duqWNIAXINzn +g/iN/Ae42l9NLmeyhP3ZRPx3UIHmfLTJDQtyU/h2BwdBR5YM++CCJpNVjP4iH2Bl +fF/nJrP3MpCYUNQ3cVX2kiF495V5+vgtJodmVjB3pjd4M1IQWK4/YY7yarHvGH5K +WWPKjaJW1acvvFYfzznB4vsKqBUsfU16Y8Zsl0Q80m/DShcK+JDSV6IZUaUtl0Ha +B0+pUNqQjZRG4T7wlP0QADj1O+hA4bRuVhogzG9Yje0uRY/W6ZM/57Es3zrWIozc +hLsib9D45MY56QSIPMO661V6bYCZJPVsAfv4l7CUW+v90m/xd2gNNWQjrLhVoQPR +TUIZ3Ph1WVaj+ahJefivDrkRoHy3au000LYmYjgahwz46P0u05B/B5EqHdZ+XIWD +mbA4CD/pXvk1B+TJYm5Xf6dQlfe6yJvmjqIBxdZmv3lh8zwc4bmCXF2gw+nYSL0Z +ohEUGW6yhhtoPkg3Goi3XZZenMfvJ2II4pEZXNLxId26F0KCl3GBUzGpn/Z9Yr9y +4aOTHcyKJloJONDO1w2AFrR4pTqHTI2KpdVGl/IsELm8VCLAAVBpQ570su9t+Oza +8eOx79+Rj1QqCyXBJhnEUhAFZdWCEOrCMc0u +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIURFc0JFuBiZs18s64KztbpybwdSgwDQYJKoZIhvcNAQEL +BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc +BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMiBHMzAeFw0xMjAxMTIxODU5MzJaFw00 +MjAxMTIxODU5MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM +aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDIgRzMwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQChriWyARjcV4g/Ruv5r+LrI3HimtFhZiFf +qq8nUeVuGxbULX1QsFN3vXg6YOJkApt8hpvWGo6t/x8Vf9WVHhLL5hSEBMHfNrMW +n4rjyduYNM7YMxcoRvynyfDStNVNCXJJ+fKH46nafaF9a7I6JaltUkSs+L5u+9ym +c5GQYaYDFCDy54ejiK2toIz/pgslUiXnFgHVy7g1gQyjO/Dh4fxaXc6AcW34Sas+ +O7q414AB+6XrW7PFXmAqMaCvN+ggOp+oMiwMzAkd056OXbxMmO7FGmh77FOm6RQ1 +o9/NgJ8MSPsc9PG/Srj61YxxSscfrf5BmrODXfKEVu+lV0POKa2Mq1W/xPtbAd0j +IaFYAI7D0GoT7RPjEiuA3GfmlbLNHiJuKvhB1PLKFAeNilUSxmn1uIZoL1NesNKq +IcGY5jDjZ1XHm26sGahVpkUG0CM62+tlXSoREfA7T8pt9DTEceT/AFr2XK4jYIVz +8eQQsSWu1ZK7E8EM4DnatDlXtas1qnIhO4M15zHfeiFuuDIIfR0ykRVKYnLP43eh +vNURG3YBZwjgQQvD6xVu+KQZ2aKrr+InUlYrAoosFCT5v0ICvybIxo/gbjh9Uy3l +7ZizlWNof/k19N+IxWA1ksB8aRxhlRbQ694Lrz4EEEVlWFA4r0jyWbYW8jwNkALG +cC4BrTwV1wIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +BjAdBgNVHQ4EFgQU7edvdlq/YOxJW8ald7tyFnGbxD0wDQYJKoZIhvcNAQELBQAD +ggIBAJHfgD9DCX5xwvfrs4iP4VGyvD11+ShdyLyZm3tdquXK4Qr36LLTn91nMX66 +AarHakE7kNQIXLJgapDwyM4DYvmL7ftuKtwGTTwpD4kWilhMSA/ohGHqPHKmd+RC +roijQ1h5fq7KpVMNqT1wvSAZYaRsOPxDMuHBR//47PERIjKWnML2W2mWeyAMQ0Ga +W/ZZGYjeVYg3UQt4XAoeo0L9x52ID8DyeAIkVJOviYeIyUqAHerQbj5hLja7NQ4n +lv1mNDthcnPxFlxHBlRJAHpYErAK74X9sbgzdWqTHBLmYF5vHX/JHyPLhGGfHoJE ++V+tYlUkmlKY7VHnoX6XOuYvHxHaU4AshZ6rNRDbIl9qxV6XU/IyAgkwo1jwDQHV +csaxfGl7w/U2Rcxhbl5MlMVerugOXou/983g7aEOGzPuVBj+D77vfoRrQ+NwmNtd +dbINWQeFFSM51vHfqSYP1kjHs6Yi9TM3WpVHn3u6GBVv/9YUZINJ0gpnIdsPNWNg +KCLjsZWDzYWm3S8P52dSbrsvhXz1SnPnxT7AvSESBT/8twNJAlvIJebiVDj1eYeM +HVOyToV7BjjHLPj4sHKNJeV3UvQDHEimUF+IIDBu8oJDqz2XhOdT+yHBTw8imoa4 +WSr2Rz0ZiC3oheGe7IUIarFsNMkd7EgrO3jtZsSOeWmD3n+M +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIGnTCCBIWgAwIBAgICBcYwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x +GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv +b3QgQ0EgMzAeFw0wNjExMjQxOTExMjNaFw0zMTExMjQxOTA2NDRaMEUxCzAJBgNV +BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W +YWRpcyBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDM +V0IWVJzmmNPTTe7+7cefQzlKZbPoFog02w1ZkXTPkrgEQK0CSzGrvI2RaNggDhoB +4hp7Thdd4oq3P5kazethq8Jlph+3t723j/z9cI8LoGe+AaJZz3HmDyl2/7FWeUUr +H556VOijKTVopAFPD6QuN+8bv+OPEKhyq1hX51SGyMnzW9os2l2ObjyjPtr7guXd +8lyyBTNvijbO0BNO/79KDDRMpsMhvVAEVeuxu537RR5kFd5VAYwCdrXLoT9Cabwv +vWhDFlaJKjdhkf2mrk7AyxRllDdLkgbvBNDInIjbC3uBr7E9KsRlOni27tyAsdLT +mZw67mtaa7ONt9XOnMK+pUsvFrGeaDsGb659n/je7Mwpp5ijJUMv7/FfJuGITfhe +btfZFG4ZM2mnO4SJk8RTVROhUXhA+LjJou57ulJCg54U7QVSWllWp5f8nT8KKdjc +T5EOE7zelaTfi5m+rJsziO+1ga8bxiJTyPbH7pcUsMV8eFLI8M5ud2CEpukqdiDt +WAEXMJPpGovgc2PZapKUSU60rUqFxKMiMPwJ7Wgic6aIDFUhWMXhOp8q3crhkODZ +c6tsgLjoC2SToJyMGf+z0gzskSaHirOi4XCPLArlzW1oUevaPwV/izLmE1xr/l9A +4iLItLRkT9a6fUg+qGkM17uGcclzuD87nSVL2v9A6wIDAQABo4IBlTCCAZEwDwYD +VR0TAQH/BAUwAwEB/zCB4QYDVR0gBIHZMIHWMIHTBgkrBgEEAb5YAAMwgcUwgZMG +CCsGAQUFBwICMIGGGoGDQW55IHVzZSBvZiB0aGlzIENlcnRpZmljYXRlIGNvbnN0 +aXR1dGVzIGFjY2VwdGFuY2Ugb2YgdGhlIFF1b1ZhZGlzIFJvb3QgQ0EgMyBDZXJ0 +aWZpY2F0ZSBQb2xpY3kgLyBDZXJ0aWZpY2F0aW9uIFByYWN0aWNlIFN0YXRlbWVu +dC4wLQYIKwYBBQUHAgEWIWh0dHA6Ly93d3cucXVvdmFkaXNnbG9iYWwuY29tL2Nw +czALBgNVHQ8EBAMCAQYwHQYDVR0OBBYEFPLAE+CCQz777i9nMpY1XNu4ywLQMG4G +A1UdIwRnMGWAFPLAE+CCQz777i9nMpY1XNu4ywLQoUmkRzBFMQswCQYDVQQGEwJC +TTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDEbMBkGA1UEAxMSUXVvVmFkaXMg +Um9vdCBDQSAzggIFxjANBgkqhkiG9w0BAQUFAAOCAgEAT62gLEz6wPJv92ZVqyM0 +7ucp2sNbtrCD2dDQ4iH782CnO11gUyeim/YIIirnv6By5ZwkajGxkHon24QRiSem +d1o417+shvzuXYO8BsbRd2sPbSQvS3pspweWyuOEn62Iix2rFo1bZhfZFvSLgNLd ++LJ2w/w4E6oM3kJpK27zPOuAJ9v1pkQNn1pVWQvVDVJIxa6f8i+AxeoyUDUSly7B +4f/xI4hROJ/yZlZ25w9Rl6VSDE1JUZU2Pb+iSwwQHYaZTKrzchGT5Or2m9qoXadN +t54CrnMAyNojA+j56hl0YgCUyyIgvpSnWbWCar6ZeXqp8kokUvd0/bpO5qgdAm6x +DYBEwa7TIzdfu4V8K5Iu6H6li92Z4b8nby1dqnuH/grdS/yO9SbkbnBCbjPsMZ57 +k8HkyWkaPcBrTiJt7qtYTcbQQcEr6k8Sh17rRdhs9ZgC06DYVYoGmRmioHfRMJ6s +zHXug/WwYjnPbFfiTNKRCw51KBuav/0aQ/HKd/s7j2G4aSgWQgRecCocIdiP4b0j +Wy10QJLZYxkNc91pvGJHvOB0K7Lrfb5BG7XARsWhIstfTsEokt4YutUqKLsRixeT +mJlglFwjz1onl14LBQaTNx47aTbrqZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK +4SVhM7JZG+Ju1zdXtg2pEto= +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIULvWbAiin23r/1aOp7r0DoM8Sah0wDQYJKoZIhvcNAQEL +BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc +BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMyBHMzAeFw0xMjAxMTIyMDI2MzJaFw00 +MjAxMTIyMDI2MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM +aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDMgRzMwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCzyw4QZ47qFJenMioKVjZ/aEzHs286IxSR +/xl/pcqs7rN2nXrpixurazHb+gtTTK/FpRp5PIpM/6zfJd5O2YIyC0TeytuMrKNu +FoM7pmRLMon7FhY4futD4tN0SsJiCnMK3UmzV9KwCoWdcTzeo8vAMvMBOSBDGzXR +U7Ox7sWTaYI+FrUoRqHe6okJ7UO4BUaKhvVZR74bbwEhELn9qdIoyhA5CcoTNs+c +ra1AdHkrAj80//ogaX3T7mH1urPnMNA3I4ZyYUUpSFlob3emLoG+B01vr87ERROR +FHAGjx+f+IdpsQ7vw4kZ6+ocYfx6bIrc1gMLnia6Et3UVDmrJqMz6nWB2i3ND0/k +A9HvFZcba5DFApCTZgIhsUfei5pKgLlVj7WiL8DWM2fafsSntARE60f75li59wzw +eyuxwHApw0BiLTtIadwjPEjrewl5qW3aqDCYz4ByA4imW0aucnl8CAMhZa634Ryl +sSqiMd5mBPfAdOhx3v89WcyWJhKLhZVXGqtrdQtEPREoPHtht+KPZ0/l7DxMYIBp +VzgeAVuNVejH38DMdyM0SXV89pgR6y3e7UEuFAUCf+D+IOs15xGsIs5XPd7JMG0Q +A4XN8f+MFrXBsj6IbGB/kE+V9/YtrQE5BwT6dYB9v0lQ7e/JxHwc64B+27bQ3RP+ +ydOc17KXqQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +BjAdBgNVHQ4EFgQUxhfQvKjqAkPyGwaZXSuQILnXnOQwDQYJKoZIhvcNAQELBQAD +ggIBADRh2Va1EodVTd2jNTFGu6QHcrxfYWLopfsLN7E8trP6KZ1/AvWkyaiTt3px +KGmPc+FSkNrVvjrlt3ZqVoAh313m6Tqe5T72omnHKgqwGEfcIHB9UqM+WXzBusnI +FUBhynLWcKzSt/Ac5IYp8M7vaGPQtSCKFWGafoaYtMnCdvvMujAWzKNhxnQT5Wvv +oxXqA/4Ti2Tk08HS6IT7SdEQTXlm66r99I0xHnAUrdzeZxNMgRVhvLfZkXdxGYFg +u/BYpbWcC/ePIlUnwEsBbTuZDdQdm2NnL9DuDcpmvJRPpq3t/O5jrFc/ZSXPsoaP +0Aj/uHYUbt7lJ+yreLVTubY/6CD50qi+YUbKh4yE8/nxoGibIh6BJpsQBJFxwAYf +3KDTuVan45gtf4Od34wrnDKOMpTwATwiKp9Dwi7DmDkHOHv8XgBCH/MyJnmDhPbl +8MFREsALHgQjDFSlTC9JxUrRtm5gDWv8a4uFJGS3iQ6rJUdbPM9+Sb3H6QrG2vd+ +DhcI00iX0HGS8A85PjRqHH3Y8iKuu2n0M7SmSFXRDw4m6Oy2Cy2nhTXN/VnIn9HN +PlopNLk9hM6xZdRZkZFWdSHBd575euFgndOtBBj0fOtek49TSiIp+EgrPk2GrFt/ +ywaZWWDYWGWVjUTR939+J399roD1B0y2PpxxVJkES/1Y+Zj0 +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIGizCCBXOgAwIBAgIEO0XlaDANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJF +UzEfMB0GA1UEChMWR2VuZXJhbGl0YXQgVmFsZW5jaWFuYTEPMA0GA1UECxMGUEtJ +R1ZBMScwJQYDVQQDEx5Sb290IENBIEdlbmVyYWxpdGF0IFZhbGVuY2lhbmEwHhcN +MDEwNzA2MTYyMjQ3WhcNMjEwNzAxMTUyMjQ3WjBoMQswCQYDVQQGEwJFUzEfMB0G +A1UEChMWR2VuZXJhbGl0YXQgVmFsZW5jaWFuYTEPMA0GA1UECxMGUEtJR1ZBMScw +JQYDVQQDEx5Sb290IENBIEdlbmVyYWxpdGF0IFZhbGVuY2lhbmEwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDGKqtXETcvIorKA3Qdyu0togu8M1JAJke+ +WmmmO3I2F0zo37i7L3bhQEZ0ZQKQUgi0/6iMweDHiVYQOTPvaLRfX9ptI6GJXiKj +SgbwJ/BXufjpTjJ3Cj9BZPPrZe52/lSqfR0grvPXdMIKX/UIKFIIzFVd0g/bmoGl +u6GzwZTNVOAydTGRGmKy3nXiz0+J2ZGQD0EbtFpKd71ng+CT516nDOeB0/RSrFOy +A8dEJvt55cs0YFAQexvba9dHq198aMpunUEDEO5rmXteJajCq+TA81yc477OMUxk +Hl6AovWDfgzWyoxVjr7gvkkHD6MkQXpYHYTqWBLI4bft75PelAgxAgMBAAGjggM7 +MIIDNzAyBggrBgEFBQcBAQQmMCQwIgYIKwYBBQUHMAGGFmh0dHA6Ly9vY3NwLnBr +aS5ndmEuZXMwEgYDVR0TAQH/BAgwBgEB/wIBAjCCAjQGA1UdIASCAiswggInMIIC +IwYKKwYBBAG/VQIBADCCAhMwggHoBggrBgEFBQcCAjCCAdoeggHWAEEAdQB0AG8A +cgBpAGQAYQBkACAAZABlACAAQwBlAHIAdABpAGYAaQBjAGEAYwBpAPMAbgAgAFIA +YQDtAHoAIABkAGUAIABsAGEAIABHAGUAbgBlAHIAYQBsAGkAdABhAHQAIABWAGEA +bABlAG4AYwBpAGEAbgBhAC4ADQAKAEwAYQAgAEQAZQBjAGwAYQByAGEAYwBpAPMA +bgAgAGQAZQAgAFAAcgDhAGMAdABpAGMAYQBzACAAZABlACAAQwBlAHIAdABpAGYA +aQBjAGEAYwBpAPMAbgAgAHEAdQBlACAAcgBpAGcAZQAgAGUAbAAgAGYAdQBuAGMA +aQBvAG4AYQBtAGkAZQBuAHQAbwAgAGQAZQAgAGwAYQAgAHAAcgBlAHMAZQBuAHQA +ZQAgAEEAdQB0AG8AcgBpAGQAYQBkACAAZABlACAAQwBlAHIAdABpAGYAaQBjAGEA +YwBpAPMAbgAgAHMAZQAgAGUAbgBjAHUAZQBuAHQAcgBhACAAZQBuACAAbABhACAA +ZABpAHIAZQBjAGMAaQDzAG4AIAB3AGUAYgAgAGgAdAB0AHAAOgAvAC8AdwB3AHcA +LgBwAGsAaQAuAGcAdgBhAC4AZQBzAC8AYwBwAHMwJQYIKwYBBQUHAgEWGWh0dHA6 +Ly93d3cucGtpLmd2YS5lcy9jcHMwHQYDVR0OBBYEFHs100DSHHgZZu90ECjcPk+y +eAT8MIGVBgNVHSMEgY0wgYqAFHs100DSHHgZZu90ECjcPk+yeAT8oWykajBoMQsw +CQYDVQQGEwJFUzEfMB0GA1UEChMWR2VuZXJhbGl0YXQgVmFsZW5jaWFuYTEPMA0G +A1UECxMGUEtJR1ZBMScwJQYDVQQDEx5Sb290IENBIEdlbmVyYWxpdGF0IFZhbGVu +Y2lhbmGCBDtF5WgwDQYJKoZIhvcNAQEFBQADggEBACRhTvW1yEICKrNcda3Fbcrn +lD+laJWIwVTAEGmiEi8YPyVQqHxK6sYJ2fR1xkDar1CdPaUWu20xxsdzCkj+IHLt +b8zog2EWRpABlUt9jppSCS/2bxzkoXHPjCpaF3ODR00PNvsETUlR4hTJZGH71BTg +9J63NI8KJr2XXPR5OkowGcytT6CYirQxlyric21+eLj4iIlPsSKRZEv1UN4D2+XF +ducTZnV+ZfsBn5OHiJ35Rld8TWCvmHMTI6QgkYH60GFmuH3Rr9ZvHmw96RH9qfmC +IoaZM3Fa6hlXPZHNqcCjbgcTpsnt+GijnsNacgmHKNHEc8RzGF9QdRYxn7fofMM= +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIDvDCCAqSgAwIBAgIQB1YipOjUiolN9BPI8PjqpTANBgkqhkiG9w0BAQUFADBK +MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x +GTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwHhcNMDYxMTA3MTk0MjI4WhcNMjkx +MjMxMTk1MjA2WjBKMQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3Qg +Q29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvNS7YrGxVaQZx5RNoJLNP2MwhR/jxYDiJ +iQPpvepeRlMJ3Fz1Wuj3RSoC6zFh1ykzTM7HfAo3fg+6MpjhHZevj8fcyTiW89sa +/FHtaMbQbqR8JNGuQsiWUGMu4P51/pinX0kuleM5M2SOHqRfkNJnPLLZ/kG5VacJ +jnIFHovdRIWCQtBJwB1g8NEXLJXr9qXBkqPFwqcIYA1gBBCWeZ4WNOaptvolRTnI +HmX5k/Wq8VLcmZg9pYYaDDUz+kulBAYVHDGA76oYa8J719rO+TMg1fW9ajMtgQT7 +sFzUnKPiXB3jqUJ1XnvUd+85VLrJChgbEplJL4hL/VBi0XPnj3pDAgMBAAGjgZ0w +gZowEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQF +MAMBAf8wHQYDVR0OBBYEFK9EBMJBfkiD2045AuzshHrmzsmkMDQGA1UdHwQtMCsw +KaAnoCWGI2h0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NHQ0EuY3JsMBAGCSsG +AQQBgjcVAQQDAgEAMA0GCSqGSIb3DQEBBQUAA4IBAQBjGghAfaReUw132HquHw0L +URYD7xh8yOOvaliTFGCRsoTciE6+OYo68+aCiV0BN7OrJKQVDpI1WkpEXk5X+nXO +H0jOZvQ8QCaSmGwb7iRGDBezUqXbpZGRzzfTb+cnCDpOGR86p1hcF895P4vkp9Mm +I50mD1hp/Ed+stCNi5O/KU9DaXR2Z0vPB4zmAve14bRDtUstFJ/53CYNv6ZHdAbY +iNE6KTCEztI5gGIbqMdXSbxqVVFnFUq+NQfk1XWYN3kwFNspnWzFacxHVaIw98xc +f8LDmBxrThaA63p4ZUWiABqvDA1VZDRIuJK58bRQKfJPIx/abKwfROHdI3hRW8cW +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIDbTCCAlWgAwIBAgIBATANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQGEwJKUDEr +MCkGA1UEChMiSmFwYW4gQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcywgSW5jLjEcMBoG +A1UEAxMTU2VjdXJlU2lnbiBSb290Q0ExMTAeFw0wOTA0MDgwNDU2NDdaFw0yOTA0 +MDgwNDU2NDdaMFgxCzAJBgNVBAYTAkpQMSswKQYDVQQKEyJKYXBhbiBDZXJ0aWZp +Y2F0aW9uIFNlcnZpY2VzLCBJbmMuMRwwGgYDVQQDExNTZWN1cmVTaWduIFJvb3RD +QTExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/XeqpRyQBTvLTJsz +i1oURaTnkBbR31fSIRCkF/3frNYfp+TbfPfs37gD2pRY/V1yfIw/XwFndBWW4wI8 +h9uuywGOwvNmxoVF9ALGOrVisq/6nL+k5tSAMJjzDbaTj6nU2DbysPyKyiyhFTOV +MdrAG/LuYpmGYz+/3ZMqg6h2uRMft85OQoWPIucuGvKVCbIFtUROd6EgvanyTgp9 +UK31BQ1FT0Zx/Sg+U/sE2C3XZR1KG/rPO7AxmjVuyIsG0wCR8pQIZUyxNAYAeoni +8McDWc/V1uinMrPmmECGxc0nEovMe863ETxiYAcjPitAbpSACW22s293bzUIUPsC +h8U+iQIDAQABo0IwQDAdBgNVHQ4EFgQUW/hNT7KlhtQ60vFjmqC+CfZXt94wDgYD +VR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEB +AKChOBZmLqdWHyGcBvod7bkixTgm2E5P7KN/ed5GIaGHd48HCJqypMWvDzKYC3xm +KbabfSVSSUOrTC4rbnpwrxYO4wJs+0LmGJ1F2FXI6Dvd5+H0LgscNFxsWEr7jIhQ +X5Ucv+2rIrVls4W6ng+4reV6G4pQOh29Dbx7VFALuUKvVaAYga1lme++5Jy/xIWr +QbJUb9wlze144o4MjQlJ3WN7WmmWAiGovVJZ6X01y8hSyn+B/tlr0/cR7SXf+Of5 +pPpyl4RTDaXQMhhRdlkUbA/r7F+AjHVDg8OFmP9Mni0N5HeDk061lgeLKBObjBmN +QSdJQO7e5iNEOdyhIta6A/I= +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBI +MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x +FzAVBgNVBAMTDlNlY3VyZVRydXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIz +MTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAeBgNVBAoTF1NlY3VyZVRydXN0IENv +cnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQXOZEz +Zum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO +0gMdA+9tDWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIao +wW8xQmxSPmjL8xk037uHGFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj +7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b01k/unK8RCSc43Oz969XL0Imnal0ugBS +8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmHursCAwEAAaOBnTCBmjAT +BgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB +/zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCeg +JYYjaHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGC +NxUBBAMCAQAwDQYJKoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt3 +6Z3q059c4EVlew3KW+JwULKUBRSuSceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/ +3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHfmbx8IVQr5Fiiu1cprp6poxkm +D5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZnMUFdAvnZyPS +CPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR +3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE= +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIDfTCCAmWgAwIBAgIBADANBgkqhkiG9w0BAQUFADBgMQswCQYDVQQGEwJKUDEl +MCMGA1UEChMcU0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEqMCgGA1UECxMh +U2VjdXJpdHkgQ29tbXVuaWNhdGlvbiBFViBSb290Q0ExMB4XDTA3MDYwNjAyMTIz +MloXDTM3MDYwNjAyMTIzMlowYDELMAkGA1UEBhMCSlAxJTAjBgNVBAoTHFNFQ09N +IFRydXN0IFN5c3RlbXMgQ08uLExURC4xKjAoBgNVBAsTIVNlY3VyaXR5IENvbW11 +bmljYXRpb24gRVYgUm9vdENBMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBALx/7FebJOD+nLpCeamIivqA4PUHKUPqjgo0No0c+qe1OXj/l3X3L+SqawSE +RMqm4miO/VVQYg+kcQ7OBzgtQoVQrTyWb4vVog7P3kmJPdZkLjjlHmy1V4qe70gO +zXppFodEtZDkBp2uoQSXWHnvIEqCa4wiv+wfD+mEce3xDuS4GBPMVjZd0ZoeUWs5 +bmB2iDQL87PRsJ3KYeJkHcFGB7hj3R4zZbOOCVVSPbW9/wfrrWFVGCypaZhKqkDF +MxRldAD5kd6vA0jFQFTcD4SQaCDFkpbcLuUCRarAX1T4bepJz11sS6/vmsJWXMY1 +VkJqMF/Cq/biPT+zyRGPMUzXn0kCAwEAAaNCMEAwHQYDVR0OBBYEFDVK9U2vP9eC +OKyrcWUXdYydVZPmMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0G +CSqGSIb3DQEBBQUAA4IBAQCoh+ns+EBnXcPBZsdAS5f8hxOQWsTvoMpfi7ent/HW +tWS3irO4G8za+6xmiEHO6Pzk2x6Ipu0nUBsCMCRGef4Eh3CXQHPRwMFXGZpppSeZ +q51ihPZRwSzJIxXYKLerJRO1RuGGAv8mjMSIkh1W/hln8lXkgKNrnKt34VFxDSDb +EJrbvXZ5B3eZKK2aXtqxT0QsNY6llsf9g/BYxnnWmHyojf6GPgcWkuF75x3sM3Z+ +Qi5KhfmRiWiEA4Glm5q+4zfFVKtWOxgtQaQM+ELbmaDgcm+7XeEWT1MKZPlO9L9O +VL14bIjqv5wTJMJwaaJ/D8g8rQjJsJhAoyrniIPtd490 +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIBADANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJKUDEl +MCMGA1UEChMcU0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UECxMe +U2VjdXJpdHkgQ29tbXVuaWNhdGlvbiBSb290Q0EyMB4XDTA5MDUyOTA1MDAzOVoX +DTI5MDUyOTA1MDAzOVowXTELMAkGA1UEBhMCSlAxJTAjBgNVBAoTHFNFQ09NIFRy +dXN0IFN5c3RlbXMgQ08uLExURC4xJzAlBgNVBAsTHlNlY3VyaXR5IENvbW11bmlj +YXRpb24gUm9vdENBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANAV +OVKxUrO6xVmCxF1SrjpDZYBLx/KWvNs2l9amZIyoXvDjChz335c9S672XewhtUGr +zbl+dp+++T42NKA7wfYxEUV0kz1XgMX5iZnK5atq1LXaQZAQwdbWQonCv/Q4EpVM +VAX3NuRFg3sUZdbcDE3R3n4MqzvEFb46VqZab3ZpUql6ucjrappdUtAtCms1FgkQ +hNBqyjoGADdH5H5XTz+L62e4iKrFvlNVspHEfbmwhRkGeC7bYRr6hfVKkaHnFtWO +ojnflLhwHyg/i/xAXmODPIMqGplrz95Zajv8bxbXH/1KEOtOghY6rCcMU/Gt1SSw +awNQwS08Ft1ENCcadfsCAwEAAaNCMEAwHQYDVR0OBBYEFAqFqXdlBZh8QIH4D5cs +OPEK7DzPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3 +DQEBCwUAA4IBAQBMOqNErLlFsceTfsgLCkLfZOoc7llsCLqJX2rKSpWeeo8HxdpF +coJxDjrSzG+ntKEju/Ykn8sX/oymzsLS28yN/HH8AynBbF0zX2S2ZTuJbxh2ePXc +okgfGT+Ok+vx+hfuzU7jBBJV1uXk3fs+BXziHV7Gp7yXT2g69ekuCkO2r1dcYmh8 +t/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6qtnRGEmyR7jTV7JqR50S+kDFy +1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29mvVXIwAHIRc/ +SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03 +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIGGTCCBAGgAwIBAgIIPtVRGeZNzn4wDQYJKoZIhvcNAQELBQAwajEhMB8GA1UE +AxMYU0cgVFJVU1QgU0VSVklDRVMgUkFDSU5FMRwwGgYDVQQLExMwMDAyIDQzNTI1 +Mjg5NTAwMDIyMRowGAYDVQQKExFTRyBUUlVTVCBTRVJWSUNFUzELMAkGA1UEBhMC +RlIwHhcNMTAwOTA2MTI1MzQyWhcNMzAwOTA1MTI1MzQyWjBqMSEwHwYDVQQDExhT +RyBUUlVTVCBTRVJWSUNFUyBSQUNJTkUxHDAaBgNVBAsTEzAwMDIgNDM1MjUyODk1 +MDAwMjIxGjAYBgNVBAoTEVNHIFRSVVNUIFNFUlZJQ0VTMQswCQYDVQQGEwJGUjCC +AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANqoVgLsfJXwTukK0rcHoyKL +ULO5Lhk9V9sZqtIr5M5C4myh5F0lHjMdtkXRtPpZilZwyW0IdmlwmubHnAgwE/7m +0ZJoYT5MEfJu8rF7V1ZLCb3cD9lxDOiaN94iEByZXtaxFwfTpDktwhpz/cpLKQfC +eSnIyCauLMT8I8hL4oZWDyj9tocbaF85ZEX9aINsdSQePHWZYfrSFPipS7HYfad4 +0hNiZbXWvn5qA7y1svxkMMPQwpk9maTTzdGxxFOHe0wTE2Z/v9VlU2j5XB7ltP82 +mUWjn2LAfxGCAVTeD2WlOa6dSEyJoxA74OaD9bDaLB56HFwfAKzMq6dgZLPGxXvH +VUZ0PJCBDkqOWZ1UsEixUkw7mO6r2jS3U81J2i/rlb4MVxH2lkwEeVyZ1eXkvm/q +R+5RS+8iJq612BGqQ7t4vwt+tN3PdB0lqYljseI0gcSINTjiAg0PE8nVKoIV8IrE +QzJW5FMdHay2z32bll0eZOl0c8RW5BZKUm2SOdPhTQ4/YrnerbUdZbldUv5dCamc +tKQM2S9FdqXPjmqanqqwEaHrYcbrPx78ZrQSnUZ/MhaJvnFFr5Eh2f2Tv7QCkUL/ +SR/tixVo3R+OrJvdggWcRGkWZBdWX0EPSk8ED2VQhpOX7EW/XcIc3M/E2DrmeAXQ +xVVVqV7+qzohu+VyFPcLAgMBAAGjgcIwgb8wHQYDVR0OBBYEFCkgy/HDD9oGjhOT +h/5fYBopu/O2MA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUKSDL8cMP2gaO +E5OH/l9gGim787YwEQYDVR0gBAowCDAGBgRVHSAAMEkGA1UdHwRCMEAwPqA8oDqG +OGh0dHA6Ly9jcmwuc2d0cnVzdHNlcnZpY2VzLmNvbS9yYWNpbmUtR3JvdXBlU0cv +TGF0ZXN0Q1JMMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEATEZn +4ERQ9cW2urJRCiUTHbfHiC4fuStkoMuTiFJZqmD1zClSF/8E5ze0MRFGfisebKeL +PEeaXvSqXZA7RT2fSsmKe47A7j55i5KjyJRKuCgRa6YlX129x8j7g09VMeZc8BN8 +471/Kiw3N5RJr4QfFCeiWBCPCjk3GhIgQY8Z9qkfGe2yNLKtfTNEi18KB0PydkVF +La3kjQ4A/QQIqudr+xe9sAhWDjUqcvCz5006Tw3c82ASszhkjNv54SaNL+9O6CRH +PjY0imkPKGuLh8a9hSb50+tpIVZgkdb34GLCqHGuLt5mI7VSRqakSDcsfwEWVxH3 +Jw0O5Q/WkEXhHj8h3NL8FhgTPk1qsiZqQF4leP049KxYejcbmEAEx47J1MRnYbGY +rvDNDty5r2WDewoEij9hqvddQYbmxkzCTzpcVuooO6dEz8hKZPVyYC3jQ7hK4HU8 +MuSqFtcRucFF2ZtmY2blIrc07rrVdC8lZPOBVMt33lfUk+OsBzE6PlwDg1dTx/D+ +aNglUE0SyObhlY1nqzyTPxcCujjXnvcwpT09RAEzGpqfjtCf8e4wiHPvriQZupdz +FcHscQyEZLV77LxpPqRtCRY2yko5isune8YdfucziMm+MG2chZUh6Uc7Bn6B4upG +5nBYgOao8p0LadEziVkw82TTC/bOKwn7fRB2LhA= +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIFcDCCA1igAwIBAgIEAJiWjTANBgkqhkiG9w0BAQsFADBYMQswCQYDVQQGEwJO +TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSkwJwYDVQQDDCBTdGFh +dCBkZXIgTmVkZXJsYW5kZW4gRVYgUm9vdCBDQTAeFw0xMDEyMDgxMTE5MjlaFw0y +MjEyMDgxMTEwMjhaMFgxCzAJBgNVBAYTAk5MMR4wHAYDVQQKDBVTdGFhdCBkZXIg +TmVkZXJsYW5kZW4xKTAnBgNVBAMMIFN0YWF0IGRlciBOZWRlcmxhbmRlbiBFViBS +b290IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA48d+ifkkSzrS +M4M1LGns3Amk41GoJSt5uAg94JG6hIXGhaTK5skuU6TJJB79VWZxXSzFYGgEt9nC +UiY4iKTWO0Cmws0/zZiTs1QUWJZV1VD+hq2kY39ch/aO5ieSZxeSAgMs3NZmdO3d +Z//BYY1jTw+bbRcwJu+r0h8QoPnFfxZpgQNH7R5ojXKhTbImxrpsX23Wr9GxE46p +rfNeaXUmGD5BKyF/7otdBwadQ8QpCiv8Kj6GyzyDOvnJDdrFmeK8eEEzduG/L13l +pJhQDBXd4Pqcfzho0LKmeqfRMb1+ilgnQ7O6M5HTp5gVXJrm0w912fxBmJc+qiXb +j5IusHsMX/FjqTf5m3VpTCgmJdrV8hJwRVXj33NeN/UhbJCONVrJ0yPr08C+eKxC +KFhmpUZtcALXEPlLVPxdhkqHz3/KRawRWrUgUY0viEeXOcDPusBCAUCZSCELa6fS +/ZbV0b5GnUngC6agIk440ME8MLxwjyx1zNDFjFE7PZQIZCZhfbnDZY8UnCHQqv0X +cgOPvZuM5l5Tnrmd74K74bzickFbIZTTRTeU0d8JOV3nI6qaHcptqAqGhYqCvkIH +1vI4gnPah1vlPNOePqc7nvQDs/nxfRN0Av+7oeX6AHkcpmZBiFxgV6YuCcS6/ZrP +px9Aw7vMWgpVSzs4dlG4Y4uElBbmVvMCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB +/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFP6rAJCYniT8qcwaivsnuL8wbqg7 +MA0GCSqGSIb3DQEBCwUAA4ICAQDPdyxuVr5Os7aEAJSrR8kN0nbHhp8dB9O2tLsI +eK9p0gtJ3jPFrK3CiAJ9Brc1AsFgyb/E6JTe1NOpEyVa/m6irn0F3H3zbPB+po3u +2dfOWBfoqSmuc0iH55vKbimhZF8ZE/euBhD/UcabTVUlT5OZEAFTdfETzsemQUHS +v4ilf0X8rLiltTMMgsT7B/Zq5SWEXwbKwYY5EdtYzXc7LMJMD16a4/CrPmEbUCTC +wPTxGfARKbalGAKb12NMcIxHowNDXLldRqANb/9Zjr7dn3LDWyvfjFvO5QxGbJKy +CqNMVEIYFRIYvdr8unRu/8G2oGTYqV9Vrp9canaW2HNnh/tNf1zuacpzEPuKqf2e +vTY4SUmH9A4U8OmHuD+nT3pajnnUk+S7aFKErGzp85hwVXIy+TSrK0m1zSBi5Dp6 +Z2Orltxtrpfs/J92VoguZs9btsmksNcFuuEnL5O7Jiqik7Ab846+HUCjuTaPPoIa +Gl6I6lD4WeKDRikL40Rc4ZW2aZCaFG+XroHPaO+Zmr615+F/+PoTRxZMzG0IQOeL +eG9QgkRQP2YGiqtDhFZKDyAthg710tvSeopLzaXoTvFeJiUBWSOgftL2fiFX1ye8 +FVdMpEbB4IMeDExNH08GGeL5qPQ6gqGyeUN51q1veieQA6TqJIc/2b3Z6fJfUEkc +7uzXLg== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIFyjCCA7KgAwIBAgIEAJiWjDANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJO +TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFh +dCBkZXIgTmVkZXJsYW5kZW4gUm9vdCBDQSAtIEcyMB4XDTA4MDMyNjExMTgxN1oX +DTIwMDMyNTExMDMxMFowWjELMAkGA1UEBhMCTkwxHjAcBgNVBAoMFVN0YWF0IGRl +ciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5lZGVybGFuZGVuIFJv +b3QgQ0EgLSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMVZ5291 +qj5LnLW4rJ4L5PnZyqtdj7U5EILXr1HgO+EASGrP2uEGQxGZqhQlEq0i6ABtQ8Sp +uOUfiUtnvWFI7/3S4GCI5bkYYCjDdyutsDeqN95kWSpGV+RLufg3fNU254DBtvPU +Z5uW6M7XxgpT0GtJlvOjCwV3SPcl5XCsMBQgJeN/dVrlSPhOewMHBPqCYYdu8DvE +pMfQ9XQ+pV0aCPKbJdL2rAQmPlU6Yiile7Iwr/g3wtG61jj99O9JMDeZJiFIhQGp +5Rbn3JBV3w/oOM2ZNyFPXfUib2rFEhZgF1XyZWampzCROME4HYYEhLoaJXhena/M +UGDWE4dS7WMfbWV9whUYdMrhfmQpjHLYFhN9C0lK8SgbIHRrxT3dsKpICT0ugpTN +GmXZK4iambwYfp/ufWZ8Pr2UuIHOzZgweMFvZ9C+X+Bo7d7iscksWXiSqt8rYGPy +5V6548r6f1CGPqI0GAwJaCgRHOThuVw+R7oyPxjMW4T182t0xHJ04eOLoEq9jWYv +6q012iDTiIJh8BIitrzQ1aTsr1SIJSQ8p22xcik/Plemf1WvbibG/ufMQFxRRIEK +eN5KzlW/HdXZt1bv8Hb/C3m1r737qWmRRpdogBQ2HbN/uymYNqUg+oJgYjOk7Na6 +B6duxc8UpufWkjTYgfX8HV2qXB72o007uPc5AgMBAAGjgZcwgZQwDwYDVR0TAQH/ +BAUwAwEB/zBSBgNVHSAESzBJMEcGBFUdIAAwPzA9BggrBgEFBQcCARYxaHR0cDov +L3d3dy5wa2lvdmVyaGVpZC5ubC9wb2xpY2llcy9yb290LXBvbGljeS1HMjAOBgNV +HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJFoMocVHYnitfGsNig0jQt8YojrMA0GCSqG +SIb3DQEBCwUAA4ICAQCoQUpnKpKBglBu4dfYszk78wIVCVBR7y29JHuIhjv5tLyS +CZa59sCrI2AGeYwRTlHSeYAz+51IvuxBQ4EffkdAHOV6CMqqi3WtFMTC6GY8ggen +5ieCWxjmD27ZUD6KQhgpxrRW/FYQoAUXvQwjf/ST7ZwaUb7dRUG/kSS0H4zpX897 +IZmflZ85OkYcbPnNe5yQzSipx6lVu6xiNGI1E0sUOlWDuYaNkqbG9AclVMwWVxJK +gnjIFNkXgiYtXSAfea7+1HAWFpWD2DU5/1JddRwWxRNVz0fMdWVSSt7wsKfkCpYL ++63C4iWEst3kvX5ZbJvw8NjnyvLplzh+ib7M+zkXYT9y2zqR2GUBGR2tUKRXCnxL +vJxxcypFURmFzI79R6d0lR2o0a9OF7FpJsKqeFdbxU2n5Z4FF5TKsl+gSRiNNOkm +bEgeqmiSBeGCc1qb3AdbCG19ndeNIdn8FCCqwkXfP+cAslHkwvgFuXkajDTznlvk +N1trSt8sV4pAWja63XVECDdCcAz+3F4hoKOKwJCcaNpQ5kUQR3i2TtJlycM33+FC +Y7BXN0Ute4qcvwXqZVUz9zkQxSgqIXobisQk+T8VyJoVIPVVYpbtbZNQvOSqeK3Z +ywplh6ZmwcSBo3c6WB4L7oOLnR7SUqTMHW+wmG2UMbX4cQrcufx9MmDm66+KAQ== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIFdDCCA1ygAwIBAgIEAJiiOTANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJO +TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFh +dCBkZXIgTmVkZXJsYW5kZW4gUm9vdCBDQSAtIEczMB4XDTEzMTExNDExMjg0MloX +DTI4MTExMzIzMDAwMFowWjELMAkGA1UEBhMCTkwxHjAcBgNVBAoMFVN0YWF0IGRl +ciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5lZGVybGFuZGVuIFJv +b3QgQ0EgLSBHMzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAL4yolQP +cPssXFnrbMSkUeiFKrPMSjTysF/zDsccPVMeiAho2G89rcKezIJnByeHaHE6n3WW +IkYFsO2tx1ueKt6c/DrGlaf1F2cY5y9JCAxcz+bMNO14+1Cx3Gsy8KL+tjzk7FqX +xz8ecAgwoNzFs21v0IJyEavSgWhZghe3eJJg+szeP4TrjTgzkApyI/o1zCZxMdFy +KJLZWyNtZrVtB0LrpjPOktvA9mxjeM3KTj215VKb8b475lRgsGYeCasH/lSJEULR +9yS6YHgamPfJEf0WwTUaVHXvQ9Plrk7O53vDxk5hUUurmkVLoR9BvUhTFXFkC4az +5S6+zqQbwSmEorXLCCN2QyIkHxcE1G6cxvx/K2Ya7Irl1s9N9WMJtxU51nus6+N8 +6U78dULI7ViVDAZCopz35HCz33JvWjdAidiFpNfxC95DGdRKWCyMijmev4SH8RY7 +Ngzp07TKbBlBUgmhHbBqv4LvcFEhMtwFdozL92TkA1CvjJFnq8Xy7ljY3r735zHP +bMk7ccHViLVlvMDoFxcHErVc0qsgk7TmgoNwNsXNo42ti+yjwUOH5kPiNL6VizXt +BznaqB16nzaeErAMZRKQFWDZJkBE41ZgpRDUajz9QdwOWke275dhdU/Z/seyHdTt +XUmzqWrLZoQT1Vyg3N9udwbRcXXIV2+vD3dbAgMBAAGjQjBAMA8GA1UdEwEB/wQF +MAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRUrfrHkleuyjWcLhL75Lpd +INyUVzANBgkqhkiG9w0BAQsFAAOCAgEAMJmdBTLIXg47mAE6iqTnB/d6+Oea31BD +U5cqPco8R5gu4RV78ZLzYdqQJRZlwJ9UXQ4DO1t3ApyEtg2YXzTdO2PCwyiBwpwp +LiniyMMB8jPqKqrMCQj3ZWfGzd/TtiunvczRDnBfuCPRy5FOCvTIeuXZYzbB1N/8 +Ipf3YF3qKS9Ysr1YvY2WTxB1v0h7PVGHoTx0IsL8B3+A3MSs/mrBcDCw6Y5p4ixp +gZQJut3+TcCDjJRYwEYgr5wfAvg1VUkvRtTA8KCWAg8zxXHzniN9lLf9OtMJgwYh +/WA9rjLA0u6NpvDntIJ8CsxwyXmA+P5M9zWEGYox+wrZ13+b8KKaa8MFSu1BYBQw +0aoRQm7TIwIEC8Zl3d1Sd9qBa7Ko+gE4uZbqKmxnl4mUnrzhVNXkanjvSr0rmj1A +fsbAddJu+2gw7OyLnflJNZoaLNmzlTnVHpL3prllL+U9bTpITAjc5CgSKL59NVzq +4BZ+Extq1z7XnvwtdbLBFNUjA9tbbws+eC8N3jONFrdI54OagQ97wUNNVQQXOEpR +1VmiiXTTn74eS9fGbbeIJG9gkaSChVtWQbzQRKtqE77RLFi3EjNYsjdj3BP1lB0/ +QFH1T/U67cjF68IeHRaVesd+QnGTbksVtzDfqu1XhUisHWrdOWnk4Xl4vs4Fv6EM +94B7IWcnMFk= +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx +EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT +HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVs +ZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAw +MFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6 +b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQgVGVj +aG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZp +Y2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBAL3twQP89o/8ArFvW59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMg +nLRJdzIpVv257IzdIvpy3Cdhl+72WoTsbhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1 +HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNkN3mSwOxGXn/hbVNMYq/N +Hwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7NfZTD4p7dN +dloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0 +HZbUJtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO +BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0G +CSqGSIb3DQEBCwUAA4IBAQARWfolTwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjU +sHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx4mcujJUDJi5DnUox9g61DLu3 +4jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUwF5okxBDgBPfg +8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K +pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1 +mMpYjn0q7pBZc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0 +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMx +EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT +HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVs +ZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5 +MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNVBAYTAlVTMRAwDgYD +VQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFy +ZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2Vy +dmljZXMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20p +OsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm2 +8xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4PahHQUw2eeBGg6345AWh1K +Ts9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLPLJGmpufe +hRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk +6mFBrMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAw +DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+q +AdcwKziIorhtSpzyEZGDMA0GCSqGSIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMI +bw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPPE95Dz+I0swSdHynVv/heyNXB +ve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTyxQGjhdByPq1z +qwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd +iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn +0q23KXB56jzaYyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCN +sSi6 +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIHhzCCBW+gAwIBAgIBLTANBgkqhkiG9w0BAQsFADB9MQswCQYDVQQGEwJJTDEW +MBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwg +Q2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0NjM3WhcNMzYwOTE3MTk0NjM2WjB9 +MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMi +U2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3Rh +cnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUA +A4ICDwAwggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZk +pMyONvg45iPwbm2xPN1yo4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rf +OQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/C +Ji/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/deMotHweXMAEtcnn6RtYT +Kqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt2PZE4XNi +HzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMM +Av+Z6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w ++2OqqGwaVLRcJXrJosmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+ +Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3 +Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVcUjyJthkqcwEKDwOzEmDyei+B +26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT37uMdBNSSwID +AQABo4ICEDCCAgwwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD +VR0OBBYEFE4L7xqkQFulF2mHMMo0aEPQQa7yMB8GA1UdIwQYMBaAFE4L7xqkQFul +F2mHMMo0aEPQQa7yMIIBWgYDVR0gBIIBUTCCAU0wggFJBgsrBgEEAYG1NwEBATCC +ATgwLgYIKwYBBQUHAgEWImh0dHA6Ly93d3cuc3RhcnRzc2wuY29tL3BvbGljeS5w +ZGYwNAYIKwYBBQUHAgEWKGh0dHA6Ly93d3cuc3RhcnRzc2wuY29tL2ludGVybWVk +aWF0ZS5wZGYwgc8GCCsGAQUFBwICMIHCMCcWIFN0YXJ0IENvbW1lcmNpYWwgKFN0 +YXJ0Q29tKSBMdGQuMAMCAQEagZZMaW1pdGVkIExpYWJpbGl0eSwgcmVhZCB0aGUg +c2VjdGlvbiAqTGVnYWwgTGltaXRhdGlvbnMqIG9mIHRoZSBTdGFydENvbSBDZXJ0 +aWZpY2F0aW9uIEF1dGhvcml0eSBQb2xpY3kgYXZhaWxhYmxlIGF0IGh0dHA6Ly93 +d3cuc3RhcnRzc2wuY29tL3BvbGljeS5wZGYwEQYJYIZIAYb4QgEBBAQDAgAHMDgG +CWCGSAGG+EIBDQQrFilTdGFydENvbSBGcmVlIFNTTCBDZXJ0aWZpY2F0aW9uIEF1 +dGhvcml0eTANBgkqhkiG9w0BAQsFAAOCAgEAjo/n3JR5fPGFf59Jb2vKXfuM/gTF +wWLRfUKKvFO3lANmMD+x5wqnUCBVJX92ehQN6wQOQOY+2IirByeDqXWmN3PH/UvS +Ta0XQMhGvjt/UfzDtgUx3M2FIk5xt/JxXrAaxrqTi3iSSoX4eA+D/i+tLPfkpLst +0OcNOrg+zvZ49q5HJMqjNTbOx8aHmNrs++myziebiMMEofYLWWivydsQD032ZGNc +pRJvkrKTlMeIFw6Ttn5ii5B/q06f/ON1FE8qMt9bDeD1e5MNq6HPh+GlBEXoPBKl +CcWw0bdT82AUuoVpaiF8H3VhFyAXe2w7QSlc4axa0c2Mm+tgHRns9+Ww2vl5GKVF +P0lDV9LdJNUso/2RjSe15esUBppMeyG7Oq0wBhjA2MFrLH9ZXF2RsXAiV+uKa0hK +1Q8p7MZAwC+ITGgBF3f0JBlPvfrhsiAhS90a2Cl9qrjeVOwhVYBsHvUwyKMQ5bLm +KhQxw4UtjJixhlpPiVktucf3HMiKf8CdBUrmQk9io20ppB+Fq9vlgcitKj1MXVuE +JnHEhV5xJMqlG2zYYdMa4FTbzrqpMrUi9nNBCV24F10OD5mQ1kfabwo6YigUZ4LZ +8dCAWZvLMdibD4x3TrVoivJs9iQOLWxwxXPR3hTQcY+203sC9uO41Alua551hDnm +fyWl8kgAwKQB2j8= +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIFYzCCA0ugAwIBAgIBOzANBgkqhkiG9w0BAQsFADBTMQswCQYDVQQGEwJJTDEW +MBQGA1UEChMNU3RhcnRDb20gTHRkLjEsMCoGA1UEAxMjU3RhcnRDb20gQ2VydGlm +aWNhdGlvbiBBdXRob3JpdHkgRzIwHhcNMTAwMTAxMDEwMDAxWhcNMzkxMjMxMjM1 +OTAxWjBTMQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjEsMCoG +A1UEAxMjU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgRzIwggIiMA0G +CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2iTZbB7cgNr2Cu+EWIAOVeq8Oo1XJ +JZlKxdBWQYeQTSFgpBSHO839sj60ZwNq7eEPS8CRhXBF4EKe3ikj1AENoBB5uNsD +vfOpL9HG4A/LnooUCri99lZi8cVytjIl2bLzvWXFDSxu1ZJvGIsAQRSCb0AgJnoo +D/Uefyf3lLE3PbfHkffiAez9lInhzG7TNtYKGXmu1zSCZf98Qru23QumNK9LYP5/ +Q0kGi4xDuFby2X8hQxfqp0iVAXV16iulQ5XqFYSdCI0mblWbq9zSOdIxHWDirMxW +RST1HFSr7obdljKF+ExP6JV2tgXdNiNnvP8V4so75qbsO+wmETRIjfaAKxojAuuK +HDp2KntWFhxyKrOq42ClAJ8Em+JvHhRYW6Vsi1g8w7pOOlz34ZYrPu8HvKTlXcxN +nw3h3Kq74W4a7I/htkxNeXJdFzULHdfBR9qWJODQcqhaX2YtENwvKhOuJv4KHBnM +0D4LnMgJLvlblnpHnOl68wVQdJVznjAJ85eCXuaPOQgeWeU1FEIT/wCc976qUM/i +UUjXuG+v+E5+M5iSFGI6dWPPe/regjupuznixL0sAA7IF6wT700ljtizkC+p2il9 +Ha90OrInwMEePnWjFqmveiJdnxMaz6eg6+OGCtP95paV1yPIN93EfKo2rJgaErHg +TuixO/XWb/Ew1wIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQE +AwIBBjAdBgNVHQ4EFgQUS8W0QGutHLOlHGVuRjaJhwUMDrYwDQYJKoZIhvcNAQEL +BQADggIBAHNXPyzVlTJ+N9uWkusZXn5T50HsEbZH77Xe7XRcxfGOSeD8bpkTzZ+K +2s06Ctg6Wgk/XzTQLwPSZh0avZyQN8gMjgdalEVGKua+etqhqaRpEpKwfTbURIfX +UfEpY9Z1zRbkJ4kd+MIySP3bmdCPX1R0zKxnNBFi2QwKN4fRoxdIjtIXHfbX/dtl +6/2o1PXWT6RbdejF0mCy2wl+JYt7ulKSnj7oxXehPOBKc2thz4bcQ///If4jXSRK +9dNtD2IEBVeC2m6kMyV5Sy5UGYvMLD0w6dEG/+gyRr61M3Z3qAFdlsHB1b6uJcDJ +HgoJIIihDsnzb02CVAAgp9KP5DlUFy6NHrgbuxu9mk47EDTcnIhT76IxW1hPkWLI +wpqazRVdOKnWvvgTtZ8SafJQYqz7Fzf07rh1Z2AQ+4NQ+US1dZxAF7L+/XldblhY +XzD8AK6vM8EOTmy6p6ahfzLbOOCxchcKK5HsamMm7YnUeMx0HgX4a/6ManY5Ka5l +IxKVCCIcl85bBu4M4ru8H0ST9tg4RQUh7eStqxK2A6RCLi3ECToDZ2mEmuFZkIoo +hdVddLHRDiBYmxOlsGOm7XtH/UVVMKTumtTm4ofvmMkyghEpIrwACjFeLQ/Ajulr +so8uBtjRkcfGEvRM/TAXw8HaOFvjqermobp573PYtlNXLfbQ4ddI +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIEezCCA2OgAwIBAgIQNxkY5lNUfBq1uMtZWts1tzANBgkqhkiG9w0BAQUFADCB +rjELMAkGA1UEBhMCREUxIDAeBgNVBAgTF0JhZGVuLVd1ZXJ0dGVtYmVyZyAoQlcp +MRIwEAYDVQQHEwlTdHV0dGdhcnQxKTAnBgNVBAoTIERldXRzY2hlciBTcGFya2Fz +c2VuIFZlcmxhZyBHbWJIMT4wPAYDVQQDEzVTLVRSVVNUIEF1dGhlbnRpY2F0aW9u +IGFuZCBFbmNyeXB0aW9uIFJvb3QgQ0EgMjAwNTpQTjAeFw0wNTA2MjIwMDAwMDBa +Fw0zMDA2MjEyMzU5NTlaMIGuMQswCQYDVQQGEwJERTEgMB4GA1UECBMXQmFkZW4t +V3VlcnR0ZW1iZXJnIChCVykxEjAQBgNVBAcTCVN0dXR0Z2FydDEpMCcGA1UEChMg +RGV1dHNjaGVyIFNwYXJrYXNzZW4gVmVybGFnIEdtYkgxPjA8BgNVBAMTNVMtVFJV +U1QgQXV0aGVudGljYXRpb24gYW5kIEVuY3J5cHRpb24gUm9vdCBDQSAyMDA1OlBO +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2bVKwdMz6tNGs9HiTNL1 +toPQb9UY6ZOvJ44TzbUlNlA0EmQpoVXhOmCTnijJ4/Ob4QSwI7+Vio5bG0F/WsPo +TUzVJBY+h0jUJ67m91MduwwA7z5hca2/OnpYH5Q9XIHV1W/fuJvS9eXLg3KSwlOy +ggLrra1fFi2SU3bxibYs9cEv4KdKb6AwajLrmnQDaHgTncovmwsdvs91DSaXm8f1 +XgqfeN+zvOyauu9VjxuapgdjKRdZYgkqeQd3peDRF2npW932kKvimAoA0SVtnteF +hy+S8dF2g08LOlk3KC8zpxdQ1iALCvQm+Z845y2kuJuJja2tyWp9iRe79n+Ag3rm +7QIDAQABo4GSMIGPMBIGA1UdEwEB/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQDAgEG +MCkGA1UdEQQiMCCkHjAcMRowGAYDVQQDExFTVFJvbmxpbmUxLTIwNDgtNTAdBgNV +HQ4EFgQUD8oeXHngovMpttKFswtKtWXsa1IwHwYDVR0jBBgwFoAUD8oeXHngovMp +ttKFswtKtWXsa1IwDQYJKoZIhvcNAQEFBQADggEBAK8B8O0ZPCjoTVy7pWMciDMD +pwCHpB8gq9Yc4wYfl35UvbfRssnV2oDsF9eK9XvCAPbpEW+EoFolMeKJ+aQAPzFo +LtU96G7m1R08P7K9n3frndOMusDXtk3sU5wPBG7qNWdX4wple5A64U8+wwCSersF +iXOMy6ZNwPv2AtawB6MDwidAnwzkhYItr5pCHdDHjfhA7p0GVxzZotiAFP7hYy0y +h9WUUpY6RsZxlj33mA6ykaqP2vROJAA5VeitF7nTNCtKqUDMFypVZUF0Qn71wK/I +k63yGFs9iQzbRzkk+OBM8h+wPQrKBU6JIRrjKpms/H+h8Q8bHz2eBIPdltkdOpQ= +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIID2DCCAsCgAwIBAgIQYFbFSyNAW2TU7SXa2dYeHjANBgkqhkiG9w0BAQsFADCB +hTELMAkGA1UEBhMCREUxKTAnBgNVBAoTIERldXRzY2hlciBTcGFya2Fzc2VuIFZl +cmxhZyBHbWJIMScwJQYDVQQLEx5TLVRSVVNUIENlcnRpZmljYXRpb24gU2Vydmlj +ZXMxIjAgBgNVBAMTGVMtVFJVU1QgVW5pdmVyc2FsIFJvb3QgQ0EwHhcNMTMxMDIy +MDAwMDAwWhcNMzgxMDIxMjM1OTU5WjCBhTELMAkGA1UEBhMCREUxKTAnBgNVBAoT +IERldXRzY2hlciBTcGFya2Fzc2VuIFZlcmxhZyBHbWJIMScwJQYDVQQLEx5TLVRS +VVNUIENlcnRpZmljYXRpb24gU2VydmljZXMxIjAgBgNVBAMTGVMtVFJVU1QgVW5p +dmVyc2FsIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCo +4wvfETeFgpq1bGZ8YT/ARxodRuOwVWTluII5KAd+F//0m4rwkYHqOD8heGxI7Gsv +otOKcrKn19nqf7TASWswJYmM67fVQGGY4tw8IJLNZUpynxqOjPolFb/zIYMoDYuv +WRGCQ1ybTSVRf1gYY2A7s7WKi1hjN0hIkETCQN1d90NpKZhcEmVeq5CSS2bf1XUS +U1QYpt6K1rtXAzlZmRgFDPn9FcaQZEYXgtfCSkE9/QC+V3IYlHcbU1qJAfYzcg6T +OtzoHv0FBda8c+CI3KtP7LUYhk95hA5IKmYq3TLIeGXIC51YAQVx7YH1aBduyw20 +S9ih7K446xxYL6FlAzQvAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0P +AQH/BAQDAgEGMB0GA1UdDgQWBBSafdfr639UmEUptCCrbQuWIxmkwjANBgkqhkiG +9w0BAQsFAAOCAQEATpYS2353XpInniEXGIJ22D+8pQkEZoiJrdtVszNqxmXEj03z +MjbceQSWqXcy0Zf1GGuMuu3OEdBEx5LxtESO7YhSSJ7V/Vn4ox5R+wFS5V/let2q +JE8ii912RvaloA812MoPmLkwXSBvwoEevb3A/hXTOCoJk5gnG5N70Cs0XmilFU/R +UsOgyqCDRR319bdZc11ZAY+qwkcvFHHVKeMQtUeTJcwjKdq3ctiR1OwbSIoi5MEq +9zpok59FGW5Dt8z+uJGaYRo2aWNkkijzb2GShROfyQcsi1fc65551cLeCNVUsldO +KjKNoeI60RAgIjl9NEVvcTvDHfz/sk+o4vYwHg== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIF2TCCA8GgAwIBAgIQXAuFXAvnWUHfV8w/f52oNjANBgkqhkiG9w0BAQUFADBk +MQswCQYDVQQGEwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsTHERpZ2l0 +YWwgQ2VydGlmaWNhdGUgU2VydmljZXMxGzAZBgNVBAMTElN3aXNzY29tIFJvb3Qg +Q0EgMTAeFw0wNTA4MTgxMjA2MjBaFw0yNTA4MTgyMjA2MjBaMGQxCzAJBgNVBAYT +AmNoMREwDwYDVQQKEwhTd2lzc2NvbTElMCMGA1UECxMcRGlnaXRhbCBDZXJ0aWZp +Y2F0ZSBTZXJ2aWNlczEbMBkGA1UEAxMSU3dpc3Njb20gUm9vdCBDQSAxMIICIjAN +BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0LmwqAzZuz8h+BvVM5OAFmUgdbI9 +m2BtRsiMMW8Xw/qabFbtPMWRV8PNq5ZJkCoZSx6jbVfd8StiKHVFXqrWW/oLJdih +FvkcxC7mlSpnzNApbjyFNDhhSbEAn9Y6cV9Nbc5fuankiX9qUvrKm/LcqfmdmUc/ +TilftKaNXXsLmREDA/7n29uj/x2lzZAeAR81sH8A25Bvxn570e56eqeqDFdvpG3F +EzuwpdntMhy0XmeLVNxzh+XTF3xmUHJd1BpYwdnP2IkCb6dJtDZd0KTeByy2dbco +kdaXvij1mB7qWybJvbCXc9qukSbraMH5ORXWZ0sKbU/Lz7DkQnGMU3nn7uHbHaBu +HYwadzVcFh4rUx80i9Fs/PJnB3r1re3WmquhsUvhzDdf/X/NTa64H5xD+SpYVUNF +vJbNcA78yeNmuk6NO4HLFWR7uZToXTNShXEuT46iBhFRyePLoW4xCGQMwtI89Tbo +19AOeCMgkckkKmUpWyL3Ic6DXqTz3kvTaI9GdVyDCW4pa8RwjPWd1yAv/0bSKzjC +L3UcPX7ape8eYIVpQtPM+GP+HkM5haa2Y0EQs3MevNP6yn0WR+Kn1dCjigoIlmJW +bjTb2QK5MHXjBNLnj8KwEUAKrNVxAmKLMb7dxiNYMUJDLXT5xp6mig/p/r+D5kNX +JLrvRjSq1xIBOO0CAwEAAaOBhjCBgzAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0hBBYw +FDASBgdghXQBUwABBgdghXQBUwABMBIGA1UdEwEB/wQIMAYBAf8CAQcwHwYDVR0j +BBgwFoAUAyUv3m+CATpcLNwroWm1Z9SM0/0wHQYDVR0OBBYEFAMlL95vggE6XCzc +K6FptWfUjNP9MA0GCSqGSIb3DQEBBQUAA4ICAQA1EMvspgQNDQ/NwNurqPKIlwzf +ky9NfEBWMXrrpA9gzXrzvsMnjgM+pN0S734edAY8PzHyHHuRMSG08NBsl9Tpl7Ik +Vh5WwzW9iAUPWxAaZOHHgjD5Mq2eUCzneAXQMbFamIp1TpBcahQq4FJHgmDmHtqB +sfsUC1rxn9KVuj7QG9YVHaO+htXbD8BJZLsuUBlL0iT43R4HVtA4oJVwIHaM190e +3p9xxCPvgxNcoyQVTSlAPGrEqdi3pkSlDfTgnXceQHAm/NrZNuR55LU/vJtlvrsR +ls/bxig5OgjOR1tTWsWZ/l2p3e9M1MalrQLmjAcSHm8D0W+go/MpvRLHUKKwf4ip +mXeascClOS5cfGniLLDqN2qk4Vrh9VDlg++luyqI54zb/W1elxmofmZ1a3Hqv7HH +b6D0jqTsNFFbjCYDcKF31QESVwA12yPeDooomf2xEG9L/zgtYE4snOtnta1J7ksf +rK/7DZBaZmBwXarNeNQk7shBoJMBkpxqnvy5JMWzFYJ+vq6VK+uxwNrjAWALXmms +hFZhvnEX/h0TD/7Gh0Xp/jKgGg0TpJRVcaUWi7rKibCyx/yP2FS1k2Kdzs9Z+z0Y +zirLNRWCXf9UIltxUvu3yf5gmwBBZPCqKuy2QkPOiWaByIufOVQDJdMWNY6E0F/6 +MBr1mmz0DlP5OlvRHA== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIF2TCCA8GgAwIBAgIQHp4o6Ejy5e/DfEoeWhhntjANBgkqhkiG9w0BAQsFADBk +MQswCQYDVQQGEwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsTHERpZ2l0 +YWwgQ2VydGlmaWNhdGUgU2VydmljZXMxGzAZBgNVBAMTElN3aXNzY29tIFJvb3Qg +Q0EgMjAeFw0xMTA2MjQwODM4MTRaFw0zMTA2MjUwNzM4MTRaMGQxCzAJBgNVBAYT +AmNoMREwDwYDVQQKEwhTd2lzc2NvbTElMCMGA1UECxMcRGlnaXRhbCBDZXJ0aWZp +Y2F0ZSBTZXJ2aWNlczEbMBkGA1UEAxMSU3dpc3Njb20gUm9vdCBDQSAyMIICIjAN +BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAlUJOhJ1R5tMJ6HJaI2nbeHCOFvEr +jw0DzpPMLgAIe6szjPTpQOYXTKueuEcUMncy3SgM3hhLX3af+Dk7/E6J2HzFZ++r +0rk0X2s682Q2zsKwzxNoysjL67XiPS4h3+os1OD5cJZM/2pYmLcX5BtS5X4HAB1f +2uY+lQS3aYg5oUFgJWFLlTloYhyxCwWJwDaCFCE/rtuh/bxvHGCGtlOUSbkrRsVP +ACu/obvLP+DHVxxX6NZp+MEkUp2IVd3Chy50I9AU/SpHWrumnf2U5NGKpV+GY3aF +y6//SSj8gO1MedK75MDvAe5QQQg1I3ArqRa0jG6F6bYRzzHdUyYb3y1aSgJA/MTA +tukxGggo5WDDH8SQjhBiYEQN7Aq+VRhxLKX0srwVYv8c474d2h5Xszx+zYIdkeNL +6yxSNLCK/RJOlrDrcH+eOfdmQrGrrFLadkBXeyq96G4DsguAhYidDMfCd7Camlf0 +uPoTXGiTOmekl9AbmbeGMktg2M7v0Ax/lZ9vh0+Hio5fCHyqW/xavqGRn1V9TrAL +acywlKinh/LTSlDcX3KwFnUey7QYYpqwpzmqm59m2I2mbJYV4+by+PGDYmy7Velh +k6M99bFXi08jsJvllGov34zflVEpYKELKeRcVVi3qPyZ7iVNTA6z00yPhOgpD/0Q +VAKFyPnlw4vP5w8CAwEAAaOBhjCBgzAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0hBBYw +FDASBgdghXQBUwIBBgdghXQBUwIBMBIGA1UdEwEB/wQIMAYBAf8CAQcwHQYDVR0O +BBYEFE0mICKJS9PVpAqhb97iEoHF8TwuMB8GA1UdIwQYMBaAFE0mICKJS9PVpAqh +b97iEoHF8TwuMA0GCSqGSIb3DQEBCwUAA4ICAQAyCrKkG8t9voJXiblqf/P0wS4R +fbgZPnm3qKhyN2abGu2sEzsOv2LwnN+ee6FTSA5BesogpxcbtnjsQJHzQq0Qw1zv +/2BZf82Fo4s9SBwlAjxnffUy6S8w5X2lejjQ82YqZh6NM4OKb3xuqFp1mrjX2lhI +REeoTPpMSQpKwhI3qEAMw8jh0FcNlzKVxzqfl9NX+Ave5XLzo9v/tdhZsnPdTSpx +srpJ9csc1fV5yJmz/MFMdOO0vSk3FQQoHt5FRnDsr7p4DooqzgB53MBfGWcsa0vv +aGgLQ+OswWIJ76bdZWGgr4RVSJFSHMYlkSrQwSIjYVmvRRGFHQEkNI/Ps/8XciAT +woCqISxxOQ7Qj1zB09GOInJGTB2Wrk9xseEFKZZZ9LuedT3PDTcNYtsmjGOpI99n +Bjx8Oto0QuFmtEYE3saWmA9LSHokMnWRn6z3aOkquVVlzl1h0ydw2Df+n7mvoC5W +t6NlUe07qxS/TFED6F+KBZvuim6c779o+sjaC+NCydAXFJy3SuCvkychVSa1ZC+N +8f+mQAWFBVzKBxlcCxMoTFh/wqXvRdpg065lYZ1Tg3TCrvJcwhbtkj6EPnNgiLx2 +9CzP0H1907he0ZESEOnN3col49XtmS++dYFLJPlFRpTJKSFTnCZFqhMX5OfNeOI5 +wSsSnqaeG8XmDtkx2Q== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIF4DCCA8igAwIBAgIRAPL6ZOJ0Y9ON/RAdBB92ylgwDQYJKoZIhvcNAQELBQAw +ZzELMAkGA1UEBhMCY2gxETAPBgNVBAoTCFN3aXNzY29tMSUwIwYDVQQLExxEaWdp +dGFsIENlcnRpZmljYXRlIFNlcnZpY2VzMR4wHAYDVQQDExVTd2lzc2NvbSBSb290 +IEVWIENBIDIwHhcNMTEwNjI0MDk0NTA4WhcNMzEwNjI1MDg0NTA4WjBnMQswCQYD +VQQGEwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsTHERpZ2l0YWwgQ2Vy +dGlmaWNhdGUgU2VydmljZXMxHjAcBgNVBAMTFVN3aXNzY29tIFJvb3QgRVYgQ0Eg +MjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMT3HS9X6lds93BdY7Bx +UglgRCgzo3pOCvrY6myLURYaVa5UJsTMRQdBTxB5f3HSek4/OE6zAMaVylvNwSqD +1ycfMQ4jFrclyxy0uYAyXhqdk/HoPGAsp15XGVhRXrwsVgu42O+LgrQ8uMIkqBPH +oCE2G3pXKSinLr9xJZDzRINpUKTk4RtiGZQJo/PDvO/0vezbE53PnUgJUmfANykR +HvvSEaeFGHR55E+FFOtSN+KxRdjMDUN/rhPSays/p8LiqG12W0OfvrSdsyaGOx9/ +5fLoZigWJdBLlzin5M8J0TbDC77aO0RYjb7xnglrPvMyxyuHxuxenPaHZa0zKcQv +idm5y8kDnftslFGXEBuGCxobP/YCfnvUxVFkKJ3106yDgYjTdLRZncHrYTNaRdHL +OdAGalNgHa/2+2m8atwBz735j9m9W8E6X47aD0upm50qKGsaCnw8qyIL5XctcfaC +NYGu+HuB5ur+rPQam3Rc6I8k9l2dRsQs0h4rIWqDJ2dVSqTjyDKXZpBy2uPUZC5f +46Fq9mDU5zXNysRojddxyNMkM3OxbPlq4SjbX8Y96L5V5jcb7STZDxmPX2MYWFCB +UWVv8p9+agTnNCRxunZLWB4ZvRVgRaoMEkABnRDixzgHcgplwLa7JSnaFp6LNYth +7eVxV4O1PHGf40+/fh6Bn0GXAgMBAAGjgYYwgYMwDgYDVR0PAQH/BAQDAgGGMB0G +A1UdIQQWMBQwEgYHYIV0AVMCAgYHYIV0AVMCAjASBgNVHRMBAf8ECDAGAQH/AgED +MB0GA1UdDgQWBBRF2aWBbj2ITY1x0kbBbkUe88SAnTAfBgNVHSMEGDAWgBRF2aWB +bj2ITY1x0kbBbkUe88SAnTANBgkqhkiG9w0BAQsFAAOCAgEAlDpzBp9SSzBc1P6x +XCX5145v9Ydkn+0UjrgEjihLj6p7jjm02Vj2e6E1CqGdivdj5eu9OYLU43otb98T +PLr+flaYC/NUn81ETm484T4VvwYmneTwkLbUwp4wLh/vx3rEUMfqe9pQy3omywC0 +Wqu1kx+AiYQElY2NfwmTv9SoqORjbdlk5LgpWgi/UOGED1V7XwgiG/W9mR4U9s70 +WBCCswo9GcG/W6uqmdjyMb3lOGbcWAXH7WMaLgqXfIeTK7KK4/HsGOV1timH59yL +Gn602MnTihdsfSlEvoqq9X46Lmgxk7lq2prg2+kupYTNHAq4Sgj5nPFhJpiTt3tm +7JFe3VE/23MPrQRYCd0EApUKPtN236YQHoA96M2kZNEzx5LH4k5E4wnJTsJdhw4S +nr8PyQUQ3nqjsTzyP6WqJ3mtMX0f/fwZacXduT98zca0wjAefm6S139hdlqP65VN +vBFuIXxZN5nQBrz5Bm0yFqXZaajh3DyAHmBR3NdUIR7KYndP+tiPsys6DXhyyWhB +WkdKwqPrGtcKqzwyVcgKEZzfdNbwQBUdyLmPtTbFr/giuMod89a2GQ+fYWVq6nTI +fI/DT11lgh/ZDYnadXL77/FHZxOzyNEZiCcmmpl5fx7kLD977vHeTYuWl8PVP3wb +I+2ksx0WckNLIOFZfsLorSa/ovc= +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIFujCCA6KgAwIBAgIJALtAHEP1Xk+wMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV +BAYTAkNIMRUwEwYDVQQKEwxTd2lzc1NpZ24gQUcxHzAdBgNVBAMTFlN3aXNzU2ln +biBHb2xkIENBIC0gRzIwHhcNMDYxMDI1MDgzMDM1WhcNMzYxMDI1MDgzMDM1WjBF +MQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dpc3NTaWduIEFHMR8wHQYDVQQDExZT +d2lzc1NpZ24gR29sZCBDQSAtIEcyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC +CgKCAgEAr+TufoskDhJuqVAtFkQ7kpJcyrhdhJJCEyq8ZVeCQD5XJM1QiyUqt2/8 +76LQwB8CJEoTlo8jE+YoWACjR8cGp4QjK7u9lit/VcyLwVcfDmJlD909Vopz2q5+ +bbqBHH5CjCA12UNNhPqE21Is8w4ndwtrvxEvcnifLtg+5hg3Wipy+dpikJKVyh+c +6bM8K8vzARO/Ws/BtQpgvd21mWRTuKCWs2/iJneRjOBiEAKfNA+k1ZIzUd6+jbqE +emA8atufK+ze3gE/bk3lUIbLtK/tREDFylqM2tIrfKjuvqblCqoOpd8FUrdVxyJd +MmqXl2MT28nbeTZ7hTpKxVKJ+STnnXepgv9VHKVxaSvRAiTysybUa9oEVeXBCsdt +MDeQKuSeFDNeFhdVxVu1yzSJkvGdJo+hB9TGsnhQ2wwMC3wLjEHXuendjIj3o02y +MszYF9rNt85mndT9Xv+9lz4pded+p2JYryU0pUHHPbwNUMoDAw8IWh+Vc3hiv69y +FGkOpeUDDniOJihC8AcLYiAQZzlG+qkDzAQ4embvIIO1jEpWjpEA/I5cgt6IoMPi +aG59je883WX0XaxR7ySArqpWl2/5rX3aYT+YdzylkbYcjCbaZaIJbcHiVOO5ykxM +gI93e2CaHt+28kgeDrpOVG2Y4OGiGqJ3UM/EY5LsRxmd6+ZrzsECAwEAAaOBrDCB +qTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUWyV7 +lqRlUX64OfPAeGZe6Drn8O4wHwYDVR0jBBgwFoAUWyV7lqRlUX64OfPAeGZe6Drn +8O4wRgYDVR0gBD8wPTA7BglghXQBWQECAQEwLjAsBggrBgEFBQcCARYgaHR0cDov +L3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBACe6 +45R88a7A3hfm5djV9VSwg/S7zV4Fe0+fdWavPOhWfvxyeDgD2StiGwC5+OlgzczO +UYrHUDFu4Up+GC9pWbY9ZIEr44OE5iKHjn3g7gKZYbge9LgriBIWhMIxkziWMaa5 +O1M/wySTVltpkuzFwbs4AOPsF6m43Md8AYOfMke6UiI0HTJ6CVanfCU2qT1L2sCC +bwq7EsiHSycR+R4tx5M/nttfJmtS2S6K8RTGRI0Vqbe/vd6mGu6uLftIdxf+u+yv +GPUqUfA5hJeVbG4bwyvEdGB5JbAKJ9/fXtI5z0V9QkvfsywexcZdylU6oJxpmo/a +77KwPJ+HbBIrZXAVUjEaJM9vMSNQH4xPjyPDdEFjHFWoFN0+4FFQz/EbMFYOkrCC +hdiDyyJkvC24JdVUorgG6q2SpCSgwYa1ShNqR88uC1aVVMvOmttqtKay20EIhid3 +92qgQmwLOM7XdVAyksLfKzAiSNDVQTglXaTpXZ/GlHXQRf0wl0OPkKsKx4ZzYEpp +Ld6leNcG2mqeSz53OiATIgHQv2ieY2BrNU0LbbqhPcCT4H8js1WtciVORvnSFu+w +ZMEBnunKoGqYDs/YYPIvSbjkQuE4NRb0yG5P94FW6LqjviOvrv1vA+ACOzB2+htt +Qc8Bsem4yWb02ybzOqR08kkkW8mw0FfB+j564ZfJ +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIFwTCCA6mgAwIBAgIITrIAZwwDXU8wDQYJKoZIhvcNAQEFBQAwSTELMAkGA1UE +BhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEjMCEGA1UEAxMaU3dpc3NTaWdu +IFBsYXRpbnVtIENBIC0gRzIwHhcNMDYxMDI1MDgzNjAwWhcNMzYxMDI1MDgzNjAw +WjBJMQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dpc3NTaWduIEFHMSMwIQYDVQQD +ExpTd2lzc1NpZ24gUGxhdGludW0gQ0EgLSBHMjCCAiIwDQYJKoZIhvcNAQEBBQAD +ggIPADCCAgoCggIBAMrfogLi2vj8Bxax3mCq3pZcZB/HL37PZ/pEQtZ2Y5Wu669y +IIpFR4ZieIbWIDkm9K6j/SPnpZy1IiEZtzeTIsBQnIJ71NUERFzLtMKfkr4k2Htn +IuJpX+UFeNSH2XFwMyVTtIc7KZAoNppVRDBopIOXfw0enHb/FZ1glwCNioUD7IC+ +6ixuEFGSzH7VozPY1kneWCqv9hbrS3uQMpe5up1Y8fhXSQQeol0GcN1x2/ndi5ob +jM89o03Oy3z2u5yg+gnOI2Ky6Q0f4nIoj5+saCB9bzuohTEJfwvH6GXp43gOCWcw +izSC+13gzJ2BbWLuCB4ELE6b7P6pT1/9aXjvCR+htL/68++QHkwFix7qepF6w9fl ++zC8bBsQWJj3Gl/QKTIDE0ZNYWqFTFJ0LwYfexHihJfGmfNtf9dng34TaNhxKFrY +zt3oEBSa/m0jh26OWnA81Y0JAKeqvLAxN23IhBQeW71FYyBrS3SMvds6DsHPWhaP +pZjydomyExI7C3d3rLvlPClKknLKYRorXkzig3R3+jVIeoVNjZpTxN94ypeRSCtF +KwH3HBqi7Ri6Cr2D+m+8jVeTO9TUps4e8aCxzqv9KyiaTxvXw3LbpMS/XUz13XuW +ae5ogObnmLo2t/5u7Su9IPhlGdpVCX4l3P5hYnL5fhgC72O00Puv5TtjjGePAgMB +AAGjgawwgakwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O +BBYEFFCvzAeHFUdvOMW0ZdHelarp35zMMB8GA1UdIwQYMBaAFFCvzAeHFUdvOMW0 +ZdHelarp35zMMEYGA1UdIAQ/MD0wOwYJYIV0AVkBAQEBMC4wLAYIKwYBBQUHAgEW +IGh0dHA6Ly9yZXBvc2l0b3J5LnN3aXNzc2lnbi5jb20vMA0GCSqGSIb3DQEBBQUA +A4ICAQAIhab1Fgz8RBrBY+D5VUYI/HAcQiiWjrfFwUF1TglxeeVtlspLpYhg0DB0 +uMoI3LQwnkAHFmtllXcBrqS3NQuB2nEVqXQXOHtYyvkv+8Bldo1bAbl93oI9ZLi+ +FHSjClTTLJUYFzX1UWs/j6KWYTl4a0vlpqD4U99REJNi54Av4tHgvI42Rncz7Lj7 +jposiU0xEQ8mngS7twSNC/K5/FqdOxa3L8iYq/6KUFkuozv8KV2LwUvJ4ooTHbG/ +u0IdUt1O2BReEMYxB+9xJ/cbOQncguqLs5WGXv312l0xpuAxtpTmREl0xRbl9x8D +YSjFyMsSoEJL+WuICI20MhjzdZ/EfwBPBZWcoxcCw7NTm6ogOSkrZvqdr16zktK1 +puEa+S1BaYEUtLS17Yk9zvupnTVCRLEcFHOBzyoBNZox1S2PbYTfgE1X4z/FhHXa +icYwu+uPyyIIoK6q8QNsOktNCaUOcsZWayFCTiMlFGiudgp8DAdwZPmaL/YFOSbG +DI8Zf0NebvRbFS/bYV3mZy8/CJT5YLSYMdp08YSTcU1f+2BY0fvEwW2JorsgH51x +kcsymxM9Pn2SUjWskpSi0xjCfMfqr3YFFt1nJ8J+HAciIfNAChs0B0QTwoRqjt8Z +Wr9/6x3iGjjRXK9HkmuAtTClyY3YqzGBH9/CZjfTk6mFhnll0g== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIFvTCCA6WgAwIBAgIITxvUL1S7L0swDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UE +BhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWdu +IFNpbHZlciBDQSAtIEcyMB4XDTA2MTAyNTA4MzI0NloXDTM2MTAyNTA4MzI0Nlow +RzELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMY +U3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A +MIICCgKCAgEAxPGHf9N4Mfc4yfjDmUO8x/e8N+dOcbpLj6VzHVxumK4DV644N0Mv +Fz0fyM5oEMF4rhkDKxD6LHmD9ui5aLlV8gREpzn5/ASLHvGiTSf5YXu6t+WiE7br +YT7QbNHm+/pe7R20nqA1W6GSy/BJkv6FCgU+5tkL4k+73JU3/JHpMjUi0R86TieF +nbAVlDLaYQ1HTWBCrpJH6INaUFjpiou5XaHc3ZlKHzZnu0jkg7Y360g6rw9njxcH +6ATK72oxh9TAtvmUcXtnZLi2kUpCe2UuMGoM9ZDulebyzYLs2aFK7PayS+VFheZt +eJMELpyCbTapxDFkH4aDCyr0NQp4yVXPQbBH6TCfmb5hqAaEuSh6XzjZG6k4sIN/ +c8HDO0gqgg8hm7jMqDXDhBuDsz6+pJVpATqJAHgE2cn0mRmrVn5bi4Y5FZGkECwJ +MoBgs5PAKrYYC51+jUnyEEp/+dVGLxmSo5mnJqy7jDzmDrxHB9xzUfFwZC8I+bRH +HTBsROopN4WSaGa8gzj+ezku01DwH/teYLappvonQfGbGHLy9YR0SslnxFSuSGTf +jNFusB3hB48IHpmccelM2KX3RxIfdNFRnobzwqIjQAtz20um53MGjMGg6cFZrEb6 +5i/4z3GcRm25xBWNOHkDRUjvxF3XCO6HOSKGsg0PWEP3calILv3q1h8CAwEAAaOB +rDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU +F6DNweRBtjpbO8tFnb0cwpj6hlgwHwYDVR0jBBgwFoAUF6DNweRBtjpbO8tFnb0c +wpj6hlgwRgYDVR0gBD8wPTA7BglghXQBWQEDAQEwLjAsBggrBgEFBQcCARYgaHR0 +cDovL3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIB +AHPGgeAn0i0P4JUw4ppBf1AsX19iYamGamkYDHRJ1l2E6kFSGG9YrVBWIGrGvShp +WJHckRE1qTodvBqlYJ7YH39FkWnZfrt4csEGDyrOj4VwYaygzQu4OSlWhDJOhrs9 +xCrZ1x9y7v5RoSJBsXECYxqCsGKrXlcSH9/L3XWgwF15kIwb4FDm3jH+mHtwX6WQ +2K34ArZv02DdQEsixT2tOnqfGhpHkXkzuoLcMmkDlm4fS/Bx/uNncqCxv1yL5PqZ +IseEuRuNI5c/7SXgz2W79WEE790eslpBIlqhn10s6FvJbakMDHiqYMZWjwFaDGi8 +aRl5xB9+lwW/xekkUV7U1UtT7dkjWjYDZaPBA61BMPNGG4WQr2W11bHkFlt4dR2X +em1ZqSqPe97Dh4kQmUlzeMg9vVE1dCrV8X5pGyq7O70luJpaPXJhkGaH7gzWTdQR +dAtq/gsD/KNVV4n+SsuuWxcFyPKNIzFTONItaj+CuY0IavdeQXRuwxF+B6wpYJE/ +OMpXEA29MC/HpeZBoNquBYeaoKRlbEwJDIm6uNO5wJOKMPqN5ZprFQFOZ6raYlY+ +hAhm0sQ2fac+EPyI4NSA5QC9qvNOBqN6avlicuMJT+ubDgEj8Z+7fNzcbBGXJbLy +tGMU0gYqZ4yD9c7qB9iaah7s5Aq7KkzrCWA5zspi2C5u +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIFcjCCA1qgAwIBAgIQH51ZWtcvwgZEpYAIaeNe9jANBgkqhkiG9w0BAQUFADA/ +MQswCQYDVQQGEwJUVzEwMC4GA1UECgwnR292ZXJubWVudCBSb290IENlcnRpZmlj +YXRpb24gQXV0aG9yaXR5MB4XDTAyMTIwNTEzMjMzM1oXDTMyMTIwNTEzMjMzM1ow +PzELMAkGA1UEBhMCVFcxMDAuBgNVBAoMJ0dvdmVybm1lbnQgUm9vdCBDZXJ0aWZp +Y2F0aW9uIEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB +AJoluOzMonWoe/fOW1mKydGGEghU7Jzy50b2iPN86aXfTEc2pBsBHH8eV4qNw8XR +IePaJD9IK/ufLqGU5ywck9G/GwGHU5nOp/UKIXZ3/6m3xnOUT0b3EEk3+qhZSV1q +gQdW8or5BtD3cCJNtLdBuTK4sfCxw5w/cP1T3YGq2GN49thTbqGsaoQkclSGxtKy +yhwOeYHWtXBiCAEuTk8O1RGvqa/lmr/czIdtJuTJV6L7lvnM4T9TjGxMfptTCAts +F/tnyMKtsc2AtJfcdgEWFelq16TheEfOhtX7MfP6Mb40qij7cEwdScevLJ1tZqa2 +jWR+tSBqnTuBto9AAGdLiYa4zGX+FVPpBMHWXx1E1wovJ5pGfaENda1UhhXcSTvx +ls4Pm6Dso3pdvtUqdULle96ltqqvKKyskKw4t9VoNSZ63Pc78/1Fm9G7Q3hub/FC +VGqY8A2tl+lSXunVanLeavcbYBT0peS2cWeqH+riTcFCQP5nRhc4L0c/cZyu5SHK +YS1tB6iEfC3uUSXxY5Ce/eFXiGvviiNtsea9P63RPZYLhY3Naye7twWb7LuRqQoH +EgKXTiCQ8P8NHuJBO9NAOueNXdpm5AKwB1KYXA6OM5zCppX7VRluTI6uSw+9wThN +Xo+EHWbNxWCWtFJaBYmOlXqYwZE8lSOyDvR5tMl8wUohAgMBAAGjajBoMB0GA1Ud +DgQWBBTMzO/MKWCkO7GStjz6MmKPrCUVOzAMBgNVHRMEBTADAQH/MDkGBGcqBwAE +MTAvMC0CAQAwCQYFKw4DAhoFADAHBgVnKgMAAAQUA5vwIhP/lSg209yewDL7MTqK +UWUwDQYJKoZIhvcNAQEFBQADggIBAECASvomyc5eMN1PhnR2WPWus4MzeKR6dBcZ +TulStbngCnRiqmjKeKBMmo4sIy7VahIkv9Ro04rQ2JyftB8M3jh+Vzj8jeJPXgyf +qzvS/3WXy6TjZwj/5cAWtUgBfen5Cv8b5Wppv3ghqMKnI6mGq3ZW6A4M9hPdKmaK +ZEk9GhiHkASfQlK3T8v+R0F2Ne//AHY2RTKbxkaFXeIksB7jSJaYV0eUVXoPQbFE +JPPB/hprv4j9wabak2BegUqZIJxIZhm1AHlUD7gsL0u8qV1bYH+Mh6XgUmMqvtg7 +hUAV/h62ZT/FS9p+tXo1KaMuephgIqP0fSdOLeq0dDzpD6QzDxARvBMB1uUO07+1 +EqLhRSPAzAhuYbeJq4PjJB7mXQfnHyA+z2fI56wwbSdLaG5LKlwCCDTb+HbkZ6Mm +nD+iMsJKxYEYMRBWqoTvLQr/uB930r+lWKBi5NdLkXWNiYCYfm3LU05er/ayl4WX +udpVBrkk7tfGOB5jGxI7leFYrPLfhNVfmS8NVVvmONsuP3LpSIXLuykTjx44Vbnz +ssQwmSNOXfJIoRIM3BKQCZBUkQM8R+XVyWXgt0t97EfTsws+rZ7QdAAO671RrcDe +LMDDav7v3Aun+kbfYNucpllQdSNpc5Oy+fwC00fmcc4QAu4njIT/rEUNE1yDMuAl +pYYsfPQS +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIEqjCCA5KgAwIBAgIOLmoAAQACH9dSISwRXDswDQYJKoZIhvcNAQEFBQAwdjEL +MAkGA1UEBhMCREUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxIjAgBgNV +BAsTGVRDIFRydXN0Q2VudGVyIENsYXNzIDIgQ0ExJTAjBgNVBAMTHFRDIFRydXN0 +Q2VudGVyIENsYXNzIDIgQ0EgSUkwHhcNMDYwMTEyMTQzODQzWhcNMjUxMjMxMjI1 +OTU5WjB2MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1c3RDZW50ZXIgR21i +SDEiMCAGA1UECxMZVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMiBDQTElMCMGA1UEAxMc +VEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMiBDQSBJSTCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBAKuAh5uO8MN8h9foJIIRszzdQ2Lu+MNF2ujhoF/RKrLqk2jf +tMjWQ+nEdVl//OEd+DFwIxuInie5e/060smp6RQvkL4DUsFJzfb95AhmC1eKokKg +uNV/aVyQMrKXDcpK3EY+AlWJU+MaWss2xgdW94zPEfRMuzBwBJWl9jmM/XOBCH2J +XjIeIqkiRUuwZi4wzJ9l/fzLganx4Duvo4bRierERXlQXa7pIXSSTYtZgo+U4+lK +8edJsBTj9WLL1XK9H7nSn6DNqPoByNkN39r8R52zyFTfSUrxIan+GE7uSNQZu+99 +5OKdy1u2bv/jzVrndIIFuoAlOMvkaZ6vQaoahPUCAwEAAaOCATQwggEwMA8GA1Ud +EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTjq1RMgKHbVkO3 +kUrL84J6E1wIqzCB7QYDVR0fBIHlMIHiMIHfoIHcoIHZhjVodHRwOi8vd3d3LnRy +dXN0Y2VudGVyLmRlL2NybC92Mi90Y19jbGFzc18yX2NhX0lJLmNybIaBn2xkYXA6 +Ly93d3cudHJ1c3RjZW50ZXIuZGUvQ049VEMlMjBUcnVzdENlbnRlciUyMENsYXNz +JTIwMiUyMENBJTIwSUksTz1UQyUyMFRydXN0Q2VudGVyJTIwR21iSCxPVT1yb290 +Y2VydHMsREM9dHJ1c3RjZW50ZXIsREM9ZGU/Y2VydGlmaWNhdGVSZXZvY2F0aW9u +TGlzdD9iYXNlPzANBgkqhkiG9w0BAQUFAAOCAQEAjNfffu4bgBCzg/XbEeprS6iS +GNn3Bzn1LL4GdXpoUxUc6krtXvwjshOg0wn/9vYua0Fxec3ibf2uWWuFHbhOIprt +ZjluS5TmVfwLG4t3wVMTZonZKNaL80VKY7f9ewthXbhtvsPcW3nS7Yblok2+XnR8 +au0WOB9/WIFaGusyiC2y8zl3gK9etmF1KdsjTYjKUCjLhdLTEKJZbtOTVAB6okaV +hgWcqRmY5TFyDADiZ9lA4CQze28suVyrZZ0srHbqNZn1l7kPJOzHdiEoZa5X6AeI +dUpWoNIFOqTmjZKILPPy4cHGYdtBxceb9w4aUUXCYWvcZCcXjFq32nQozZfkvQ== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIEqjCCA5KgAwIBAgIOSkcAAQAC5aBd1j8AUb8wDQYJKoZIhvcNAQEFBQAwdjEL +MAkGA1UEBhMCREUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxIjAgBgNV +BAsTGVRDIFRydXN0Q2VudGVyIENsYXNzIDMgQ0ExJTAjBgNVBAMTHFRDIFRydXN0 +Q2VudGVyIENsYXNzIDMgQ0EgSUkwHhcNMDYwMTEyMTQ0MTU3WhcNMjUxMjMxMjI1 +OTU5WjB2MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1c3RDZW50ZXIgR21i +SDEiMCAGA1UECxMZVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMyBDQTElMCMGA1UEAxMc +VEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMyBDQSBJSTCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBALTgu1G7OVyLBMVMeRwjhjEQY0NVJz/GRcekPewJDRoeIMJW +Ht4bNwcwIi9v8Qbxq63WyKthoy9DxLCyLfzDlml7forkzMA5EpBCYMnMNWju2l+Q +Vl/NHE1bWEnrDgFPZPosPIlY2C8u4rBo6SI7dYnWRBpl8huXJh0obazovVkdKyT2 +1oQDZogkAHhg8fir/gKya/si+zXmFtGt9i4S5Po1auUZuV3bOx4a+9P/FRQI2Alq +ukWdFHlgfa9Aigdzs5OW03Q0jTo3Kd5c7PXuLjHCINy+8U9/I1LZW+Jk2ZyqBwi1 +Rb3R0DHBq1SfqdLDYmAD8bs5SpJKPQq5ncWg/jcCAwEAAaOCATQwggEwMA8GA1Ud +EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTUovyfs8PYA9NX +XAek0CSnwPIA1DCB7QYDVR0fBIHlMIHiMIHfoIHcoIHZhjVodHRwOi8vd3d3LnRy +dXN0Y2VudGVyLmRlL2NybC92Mi90Y19jbGFzc18zX2NhX0lJLmNybIaBn2xkYXA6 +Ly93d3cudHJ1c3RjZW50ZXIuZGUvQ049VEMlMjBUcnVzdENlbnRlciUyMENsYXNz +JTIwMyUyMENBJTIwSUksTz1UQyUyMFRydXN0Q2VudGVyJTIwR21iSCxPVT1yb290 +Y2VydHMsREM9dHJ1c3RjZW50ZXIsREM9ZGU/Y2VydGlmaWNhdGVSZXZvY2F0aW9u +TGlzdD9iYXNlPzANBgkqhkiG9w0BAQUFAAOCAQEANmDkcPcGIEPZIxpC8vijsrlN +irTzwppVMXzEO2eatN9NDoqTSheLG43KieHPOh6sHfGcMrSOWXaiQYUlN6AT0PV8 +TtXqluJucsG7Kv5sbviRmEb8yRtXW+rIGjs/sFGYPAfaLFkB2otE6OF0/ado3VS6 +g0bsyEa1+K+XwDsJHI/OcpY9M1ZwvJbL2NV9IJqDnxrcOfHFcqMRA/07QlIp2+gB +95tejNaNhk4Z+rwcvsUhpYeeeC422wlxo3I0+GzjBgnyXlal092Y+tTmBvTwtiBj +S+opvaqCZh77gaqnN60TGOaSw4HBM7uIHqHn4rS9MWwOUT1v+5ZWgOI2F9Hc5A== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIID3TCCAsWgAwIBAgIOHaIAAQAC7LdggHiNtgYwDQYJKoZIhvcNAQEFBQAweTEL +MAkGA1UEBhMCREUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxJDAiBgNV +BAsTG1RDIFRydXN0Q2VudGVyIFVuaXZlcnNhbCBDQTEmMCQGA1UEAxMdVEMgVHJ1 +c3RDZW50ZXIgVW5pdmVyc2FsIENBIEkwHhcNMDYwMzIyMTU1NDI4WhcNMjUxMjMx +MjI1OTU5WjB5MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1c3RDZW50ZXIg +R21iSDEkMCIGA1UECxMbVEMgVHJ1c3RDZW50ZXIgVW5pdmVyc2FsIENBMSYwJAYD +VQQDEx1UQyBUcnVzdENlbnRlciBVbml2ZXJzYWwgQ0EgSTCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBAKR3I5ZEr5D0MacQ9CaHnPM42Q9e3s9B6DGtxnSR +JJZ4Hgmgm5qVSkr1YnwCqMqs+1oEdjneX/H5s7/zA1hV0qq34wQi0fiU2iIIAI3T +fCZdzHd55yx4Oagmcw6iXSVphU9VDprvxrlE4Vc93x9UIuVvZaozhDrzznq+VZeu +jRIPFDPiUHDDSYcTvFHe15gSWu86gzOSBnWLknwSaHtwag+1m7Z3W0hZneTvWq3z +wZ7U10VOylY0Ibw+F1tvdwxIAUMpsN0/lm7mlaoMwCC2/T42J5zjXM9OgdwZu5GQ +fezmlwQek8wiSdeXhrYTCjxDI3d+8NzmzSQfO4ObNDqDNOMCAwEAAaNjMGEwHwYD +VR0jBBgwFoAUkqR1LKSevoFE63n8isWVpesQdXMwDwYDVR0TAQH/BAUwAwEB/zAO +BgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFJKkdSyknr6BROt5/IrFlaXrEHVzMA0G +CSqGSIb3DQEBBQUAA4IBAQAo0uCG1eb4e/CX3CJrO5UUVg8RMKWaTzqwOuAGy2X1 +7caXJ/4l8lfmXpWMPmRgFVp/Lw0BxbFg/UU1z/CyvwbZ71q+s2IhtNerNXxTPqYn +8aEt2hojnczd7Dwtnic0XQ/CNnm8yUpiLe1r2X1BQ3y2qsrtYbE3ghUJGooWMNjs +ydZHcnhLEEYUjl8Or+zHL6sQ17bxbuyGssLoDZJz3KL0Dzq/YSMQiZxIQG5wALPT +ujdEWBF6AmqI8Dc08BnprNRlc/ZpjGSUOnmFKbAWKwyCPwacx/0QK54PLLae4xW/ +2TYcuiUaUj0a7CIMHOCkoj3w6DnPgcB77V0fb8XQC9eY +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIFODCCAyCgAwIBAgIRAJW+FqD3LkbxezmCcvqLzZYwDQYJKoZIhvcNAQEFBQAw +NzEUMBIGA1UECgwLVGVsaWFTb25lcmExHzAdBgNVBAMMFlRlbGlhU29uZXJhIFJv +b3QgQ0EgdjEwHhcNMDcxMDE4MTIwMDUwWhcNMzIxMDE4MTIwMDUwWjA3MRQwEgYD +VQQKDAtUZWxpYVNvbmVyYTEfMB0GA1UEAwwWVGVsaWFTb25lcmEgUm9vdCBDQSB2 +MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMK+6yfwIaPzaSZVfp3F +VRaRXP3vIb9TgHot0pGMYzHw7CTww6XScnwQbfQ3t+XmfHnqjLWCi65ItqwA3GV1 +7CpNX8GH9SBlK4GoRz6JI5UwFpB/6FcHSOcZrr9FZ7E3GwYq/t75rH2D+1665I+X +Z75Ljo1kB1c4VWk0Nj0TSO9P4tNmHqTPGrdeNjPUtAa9GAH9d4RQAEX1jF3oI7x+ +/jXh7VB7qTCNGdMJjmhnXb88lxhTuylixcpecsHHltTbLaC0H2kD7OriUPEMPPCs +81Mt8Bz17Ww5OXOAFshSsCPN4D7c3TxHoLs1iuKYaIu+5b9y7tL6pe0S7fyYGKkm +dtwoSxAgHNN/Fnct7W+A90m7UwW7XWjH1Mh1Fj+JWov3F0fUTPHSiXk+TT2YqGHe +Oh7S+F4D4MHJHIzTjU3TlTazN19jY5szFPAtJmtTfImMMsJu7D0hADnJoWjiUIMu +sDor8zagrC/kb2HCUQk5PotTubtn2txTuXZZNp1D5SDgPTJghSJRt8czu90VL6R4 +pgd7gUY2BIbdeTXHlSw7sKMXNeVzH7RcWe/a6hBle3rQf5+ztCo3O3CLm1u5K7fs +slESl1MpWtTwEhDcTwK7EpIvYtQ/aUN8Ddb8WHUBiJ1YFkveupD/RwGJBmr2X7KQ +arMCpgKIv7NHfirZ1fpoeDVNAgMBAAGjPzA9MA8GA1UdEwEB/wQFMAMBAf8wCwYD +VR0PBAQDAgEGMB0GA1UdDgQWBBTwj1k4ALP1j5qWDNXr+nuqF+gTEjANBgkqhkiG +9w0BAQUFAAOCAgEAvuRcYk4k9AwI//DTDGjkk0kiP0Qnb7tt3oNmzqjMDfz1mgbl +dxSR651Be5kqhOX//CHBXfDkH1e3damhXwIm/9fH907eT/j3HEbAek9ALCI18Bmx +0GtnLLCo4MBANzX2hFxc469CeP6nyQ1Q6g2EdvZR74NTxnr/DlZJLo961gzmJ1Tj +TQpgcmLNkQfWpb/ImWvtxBnmq0wROMVvMeJuScg/doAmAyYp4Db29iBT4xdwNBed +Y2gea+zDTYa4EzAvXUYNR0PVG6pZDrlcjQZIrXSHX8f8MVRBE+LHIQ6e4B4N4cB7 +Q4WQxYpYxmUKeFfyxiMPAdkgS94P+5KFdSpcc41teyWRyu5FrgZLAMzTsVlQ2jqI +OylDRl6XK1TOU2+NSueW+r9xDkKLfP0ooNBIytrEgUy7onOTJsjrDNYmiLbAJM+7 +vVvrdX3pCI6GMyx5dwlppYn8s3CQh3aP0yK7Qs69cwsgJirQmz1wHiRszYd2qReW +t88NkvuOGKmYSdGe/mBEciG5Ge3C9THxOUiIkCR1VBatzvT4aRRkOfujuLpwQMcn +HL/EVlP6Y2XQ8xwOFvVrhlhNGNTkDY6lnVuR3HYkUD/GKvvZt5y11ubQ2egZixVx +SK236thZiNSQvxaz2emsWWFUyBy6ysHK4bkgTI86k4mloMy/0/Z1pHWWbVY= +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIDNjCCAp+gAwIBAgIQNhIilsXjOKUgodJfTNcJVDANBgkqhkiG9w0BAQUFADCB +zjELMAkGA1UEBhMCWkExFTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJ +Q2FwZSBUb3duMR0wGwYDVQQKExRUaGF3dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UE +CxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEhMB8GA1UEAxMYVGhh +d3RlIFByZW1pdW0gU2VydmVyIENBMSgwJgYJKoZIhvcNAQkBFhlwcmVtaXVtLXNl +cnZlckB0aGF3dGUuY29tMB4XDTk2MDgwMTAwMDAwMFoXDTIxMDEwMTIzNTk1OVow +gc4xCzAJBgNVBAYTAlpBMRUwEwYDVQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNVBAcT +CUNhcGUgVG93bjEdMBsGA1UEChMUVGhhd3RlIENvbnN1bHRpbmcgY2MxKDAmBgNV +BAsTH0NlcnRpZmljYXRpb24gU2VydmljZXMgRGl2aXNpb24xITAfBgNVBAMTGFRo +YXd0ZSBQcmVtaXVtIFNlcnZlciBDQTEoMCYGCSqGSIb3DQEJARYZcHJlbWl1bS1z +ZXJ2ZXJAdGhhd3RlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA0jY2 +aovXwlue2oFBYo847kkEVdbQ7xwblRZH7xhINTpS9CtqBo87L+pW46+GjZ4X9560 +ZXUCTe/LCaIhUdib0GfQug2SBhRz1JPLlyoAnFxODLz6FVL88kRu2hFKbgifLy3j ++ao6hnO2RlNYyIkFvYMRuHM/qgeN9EJN50CdHDcCAwEAAaMTMBEwDwYDVR0TAQH/ +BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQBlkKyID1bZ5jA01CbH0FDxkt5r1DmI +CSLGpmODA/eZd9iy5Ri4XWPz1HP7bJyZePFLeH0ZJMMrAoT4vCLZiiLXoPxx7JGH +IPG47LHlVYCsPVLIOQ7C8MAFT9aCdYy9X9LcdpoFEsmvcsPcJX6kTY4XpeCHf+Ga +WuFg3GQjPEIuTQ== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIEIDCCAwigAwIBAgIQNE7VVyDV7exJ9C/ON9srbTANBgkqhkiG9w0BAQUFADCB +qTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf +Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw +MDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNV +BAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMDYxMTE3MDAwMDAwWhcNMzYw +NzE2MjM1OTU5WjCBqTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5j +LjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYG +A1UECxMvKGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl +IG9ubHkxHzAdBgNVBAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCsoPD7gFnUnMekz52hWXMJEEUMDSxuaPFs +W0hoSVk3/AszGcJ3f8wQLZU0HObrTQmnHNK4yZc2AreJ1CRfBsDMRJSUjQJib+ta +3RGNKJpchJAQeg29dGYvajig4tVUROsdB58Hum/u6f1OCyn1PoSgAfGcq/gcfomk +6KHYcWUNo1F77rzSImANuVud37r8UVsLr5iy6S7pBOhih94ryNdOwUxkHt3Ph1i6 +Sk/KaAcdHJ1KxtUvkcx8cXIcxcBn6zL9yZJclNqFwJu/U30rCfSMnZEfl2pSy94J +NqR32HuHUETVPm4pafs5SSYeCaWAe0At6+gnhcn+Yf1+5nyXHdWdAgMBAAGjQjBA +MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBR7W0XP +r87Lev0xkhpqtvNG61dIUDANBgkqhkiG9w0BAQUFAAOCAQEAeRHAS7ORtvzw6WfU +DW5FvlXok9LOAz/t2iWwHVfLHjp2oEzsUHboZHIMpKnxuIvW1oeEuzLlQRHAd9mz +YJ3rG9XRbkREqaYB7FViHXe4XI5ISXycO1cRrK1zN44veFyQaEfZYGDm/Ac9IiAX +xPcW6cTYcvnIc3zfFi8VqT79aie2oetaupgf1eNNZAqdE8hhuvU5HIe6uL17In/2 +/qxAeeWsEG89jxt5dovEN7MhGITlNgDrYyCZuen+MwS7QcjBAvlEYyCegc5C09Y/ +LHbTY5xZ3Y+m4Q6gLkH3LpVHz7z9M/P2C2F+fpErgUfCJzDupxBdN49cOSvkBPB7 +jVaMaA== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIICiDCCAg2gAwIBAgIQNfwmXNmET8k9Jj1Xm67XVjAKBggqhkjOPQQDAzCBhDEL +MAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjE4MDYGA1UECxMvKGMp +IDIwMDcgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAi +BgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMjAeFw0wNzExMDUwMDAw +MDBaFw0zODAxMTgyMzU5NTlaMIGEMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhh +d3RlLCBJbmMuMTgwNgYDVQQLEy8oYykgMjAwNyB0aGF3dGUsIEluYy4gLSBGb3Ig +YXV0aG9yaXplZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9v +dCBDQSAtIEcyMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEotWcgnuVnfFSeIf+iha/ +BebfowJPDQfGAFG6DAJSLSKkQjnE/o/qycG+1E3/n3qe4rF8mq2nhglzh9HnmuN6 +papu+7qzcMBniKI11KOasf2twu8x+qi58/sIxpHR+ymVo0IwQDAPBgNVHRMBAf8E +BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUmtgAMADna3+FGO6Lts6K +DPgR4bswCgYIKoZIzj0EAwMDaQAwZgIxAN344FdHW6fmCsO99YCKlzUNG4k8VIZ3 +KMqh9HneteY4sPBlcIx/AlTCv//YoT7ZzwIxAMSNlPzcU9LcnXgWHxUzI1NS41ox +XZ3Krr0TKUQNJ1uo52icEvdYPy5yAlejj6EULg== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIEKjCCAxKgAwIBAgIQYAGXt0an6rS0mtZLL/eQ+zANBgkqhkiG9w0BAQsFADCB +rjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf +Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw +MDggdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAiBgNV +BAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMzAeFw0wODA0MDIwMDAwMDBa +Fw0zNzEyMDEyMzU5NTlaMIGuMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhhd3Rl +LCBJbmMuMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlzaW9u +MTgwNgYDVQQLEy8oYykgMjAwOCB0aGF3dGUsIEluYy4gLSBGb3IgYXV0aG9yaXpl +ZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAtIEcz +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsr8nLPvb2FvdeHsbnndm +gcs+vHyu86YnmjSjaDFxODNi5PNxZnmxqWWjpYvVj2AtP0LMqmsywCPLLEHd5N/8 +YZzic7IilRFDGF/Eth9XbAoFWCLINkw6fKXRz4aviKdEAhN0cXMKQlkC+BsUa0Lf +b1+6a4KinVvnSr0eAXLbS3ToO39/fR8EtCab4LRarEc9VbjXsCZSKAExQGbY2SS9 +9irY7CFJXJv2eul/VTV+lmuNk5Mny5K76qxAwJ/C+IDPXfRa3M50hqY+bAtTyr2S +zhkGcuYMXDhpxwTWvGzOW/b3aJzcJRVIiKHpqfiYnODz1TEoYRFsZ5aNOZnLwkUk +OQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNV +HQ4EFgQUrWyqlGCc7eT/+j4KdCtjA/e2Wb8wDQYJKoZIhvcNAQELBQADggEBABpA +2JVlrAmSicY59BDlqQ5mU1143vokkbvnRFHfxhY0Cu9qRFHqKweKA3rD6z8KLFIW +oCtDuSWQP3CpMyVtRRooOyfPqsMpQhvfO0zAMzRbQYi/aytlryjvsvXDqmbOe1bu +t8jLZ8HJnBoYuMTDSQPxYA5QzUbF83d597YV4Djbxy8ooAw/dyZ02SUS2jHaGh7c +KUGRIjxpp7sC8rZcJwOJ9Abqm+RyguOhCcHpABnTPtRwa7pxpqpYrvS76Wy274fM +m7v/OeZWYdMKp8RcTGB7BXcmer/YB1IsYvdwY9k5vG8cwnncdimvzsUsZAReiDZu +MdRAGmI0Nj81Aa6sY6A= +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIDZzCCAk+gAwIBAgIQGx+ttiD5JNM2a/fH8YygWTANBgkqhkiG9w0BAQUFADBF +MQswCQYDVQQGEwJHQjEYMBYGA1UEChMPVHJ1c3RpcyBMaW1pdGVkMRwwGgYDVQQL +ExNUcnVzdGlzIEZQUyBSb290IENBMB4XDTAzMTIyMzEyMTQwNloXDTI0MDEyMTEx +MzY1NFowRTELMAkGA1UEBhMCR0IxGDAWBgNVBAoTD1RydXN0aXMgTGltaXRlZDEc +MBoGA1UECxMTVHJ1c3RpcyBGUFMgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBAMVQe547NdDfxIzNjpvto8A2mfRC6qc+gIMPpqdZh8mQRUN+ +AOqGeSoDvT03mYlmt+WKVoaTnGhLaASMk5MCPjDSNzoiYYkchU59j9WvezX2fihH +iTHcDnlkH5nSW7r+f2C/revnPDgpai/lkQtV/+xvWNUtyd5MZnGPDNcE2gfmHhjj +vSkCqPoc4Vu5g6hBSLwacY3nYuUtsuvffM/bq1rKMfFMIvMFE/eC+XN5DL7XSxzA +0RU8k0Fk0ea+IxciAIleH2ulrG6nS4zto3Lmr2NNL4XSFDWaLk6M6jKYKIahkQlB +OrTh4/L68MkKokHdqeMDx4gVOxzUGpTXn2RZEm0CAwEAAaNTMFEwDwYDVR0TAQH/ +BAUwAwEB/zAfBgNVHSMEGDAWgBS6+nEleYtXQSUhhgtx67JkDoshZzAdBgNVHQ4E +FgQUuvpxJXmLV0ElIYYLceuyZA6LIWcwDQYJKoZIhvcNAQEFBQADggEBAH5Y//01 +GX2cGE+esCu8jowU/yyg2kdbw++BLa8F6nRIW/M+TgfHbcWzk88iNVy2P3UnXwmW +zaD+vkAMXBJV+JOCyinpXj9WV4s4NvdFGkwozZ5BuO1WTISkQMi4sKUraXAEasP4 +1BIy+Q7DsdwyhEQsb8tGD+pmQQ9P8Vilpg0ND2HepZ5dfWWhPBfnqFVO76DH7cZE +f1T1o+CP8HxVIo8ptoGj4W1OLBuAZ+ytIJ8MYmHVl/9D7S3B2l0pKoU/rGXuhg8F +jZBf3+6f9L/uHfuY5H+QK4R4EA5sSVPvFVtlRkpdr7r7OnIdzfYliB6XzCGcKQEN +ZetX2fNXlrtIzYE= +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx +KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd +BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl +YyBHbG9iYWxSb290IENsYXNzIDIwHhcNMDgxMDAxMTA0MDE0WhcNMzMxMDAxMjM1 +OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy +aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50 +ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCqX9obX+hzkeXaXPSi5kfl82hVYAUd +AqSzm1nzHoqvNK38DcLZSBnuaY/JIPwhqgcZ7bBcrGXHX+0CfHt8LRvWurmAwhiC +FoT6ZrAIxlQjgeTNuUk/9k9uN0goOA/FvudocP05l03Sx5iRUKrERLMjfTlH6VJi +1hKTXrcxlkIF+3anHqP1wvzpesVsqXFP6st4vGCvx9702cu+fjOlbpSD8DT6Iavq +jnKgP6TeMFvvhk1qlVtDRKgQFRzlAVfFmPHmBiiRqiDFt1MmUUOyCxGVWOHAD3bZ +wI18gfNycJ5v/hqO2V81xrJvNHy+SE/iWjnX2J14np+GPgNeGYtEotXHAgMBAAGj +QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS/ +WSA2AHmgoCJrjNXyYdK4LMuCSjANBgkqhkiG9w0BAQsFAAOCAQEAMQOiYQsfdOhy +NsZt+U2e+iKo4YFWz827n+qrkRk4r6p8FU3ztqONpfSO9kSpp+ghla0+AGIWiPAC +uvxhI+YzmzB6azZie60EI4RYZeLbK4rnJVM3YlNfvNoBYimipidx5joifsFvHZVw +IEoHNN/q/xWA5brXethbdXwFeilHfkCoMRN3zUA7tFFHei4R40cR3p1m0IvVVGb6 +g1XqfMIpiRvpb7PO4gWEyS8+eIVibslfwXhjdFjASBgMmTnrpMwatXlajRWc2BQN +9noHV8cigwUtPJslJj0Ys6lDfMjIq2SPDqO/nBudMNva0Bkuqjzx+zOAduTNrRlP +BSeOE6Fuwg== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx +KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd +BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl +YyBHbG9iYWxSb290IENsYXNzIDMwHhcNMDgxMDAxMTAyOTU2WhcNMzMxMDAxMjM1 +OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy +aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50 +ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC9dZPwYiJvJK7genasfb3ZJNW4t/zN +8ELg63iIVl6bmlQdTQyK9tPPcPRStdiTBONGhnFBSivwKixVA9ZIw+A5OO3yXDw/ +RLyTPWGrTs0NvvAgJ1gORH8EGoel15YUNpDQSXuhdfsaa3Ox+M6pCSzyU9XDFES4 +hqX2iys52qMzVNn6chr3IhUciJFrf2blw2qAsCTz34ZFiP0Zf3WHHx+xGwpzJFu5 +ZeAsVMhg02YXP+HMVDNzkQI6pn97djmiH5a2OK61yJN0HZ65tOVgnS9W0eDrXltM +EnAMbEQgqxHY9Bn20pxSN+f6tsIxO0rUFJmtxxr1XV/6B7h8DR/Wgx6zAgMBAAGj +QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS1 +A/d2O2GCahKqGFPrAyGUv/7OyjANBgkqhkiG9w0BAQsFAAOCAQEAVj3vlNW92nOy +WL6ukK2YJ5f+AbGwUgC4TeQbIXQbfsDuXmkqJa9c1h3a0nnJ85cp4IaH3gRZD/FZ +1GSFS5mvJQQeyUapl96Cshtwn5z2r3Ex3XsFpSzTucpH9sry9uetuUg/vBa3wW30 +6gmv7PO15wWeph6KU1HWk4HMdJP2udqmJQV0eVp+QD6CSyYRMG7hP0HHRwA11fXT +91Q+gT3aSWqas+8QPebrb9HIIkfLzM8BMZLZGOMivgkeGj5asuRrDFR6fUNOuIml +e9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4p +TpPDpFQUWw== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIFFzCCA/+gAwIBAgIBETANBgkqhkiG9w0BAQUFADCCASsxCzAJBgNVBAYTAlRS +MRgwFgYDVQQHDA9HZWJ6ZSAtIEtvY2FlbGkxRzBFBgNVBAoMPlTDvHJraXllIEJp +bGltc2VsIHZlIFRla25vbG9qaWsgQXJhxZ90xLFybWEgS3VydW11IC0gVMOcQsSw +VEFLMUgwRgYDVQQLDD9VbHVzYWwgRWxla3Ryb25payB2ZSBLcmlwdG9sb2ppIEFy +YcWfdMSxcm1hIEVuc3RpdMO8c8O8IC0gVUVLQUUxIzAhBgNVBAsMGkthbXUgU2Vy +dGlmaWthc3lvbiBNZXJrZXppMUowSAYDVQQDDEFUw5xCxLBUQUsgVUVLQUUgS8O2 +ayBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsSAtIFPDvHLDvG0gMzAe +Fw0wNzA4MjQxMTM3MDdaFw0xNzA4MjExMTM3MDdaMIIBKzELMAkGA1UEBhMCVFIx +GDAWBgNVBAcMD0dlYnplIC0gS29jYWVsaTFHMEUGA1UECgw+VMO8cmtpeWUgQmls +aW1zZWwgdmUgVGVrbm9sb2ppayBBcmHFn3TEsXJtYSBLdXJ1bXUgLSBUw5xCxLBU +QUsxSDBGBgNVBAsMP1VsdXNhbCBFbGVrdHJvbmlrIHZlIEtyaXB0b2xvamkgQXJh +xZ90xLFybWEgRW5zdGl0w7xzw7wgLSBVRUtBRTEjMCEGA1UECwwaS2FtdSBTZXJ0 +aWZpa2FzeW9uIE1lcmtlemkxSjBIBgNVBAMMQVTDnELEsFRBSyBVRUtBRSBLw7Zr +IFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxIC0gU8O8csO8bSAzMIIB +IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAim1L/xCIOsP2fpTo6iBkcK4h +gb46ezzb8R1Sf1n68yJMlaCQvEhOEav7t7WNeoMojCZG2E6VQIdhn8WebYGHV2yK +O7Rm6sxA/OOqbLLLAdsyv9Lrhc+hDVXDWzhXcLh1xnnRFDDtG1hba+818qEhTsXO +fJlfbLm4IpNQp81McGq+agV/E5wrHur+R84EpW+sky58K5+eeROR6Oqeyjh1jmKw +lZMq5d/pXpduIF9fhHpEORlAHLpVK/swsoHvhOPc7Jg4OQOFCKlUAwUp8MmPi+oL +hmUZEdPpCSPeaJMDyTYcIW7OjGbxmTDY17PDHfiBLqi9ggtm/oLL4eAagsNAgQID +AQABo0IwQDAdBgNVHQ4EFgQUvYiHyY/2pAoLquvF/pEjnatKijIwDgYDVR0PAQH/ +BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAB18+kmP +NOm3JpIWmgV050vQbTlswyb2zrgxvMTfvCr4N5EY3ATIZJkrGG2AA1nJrvhY0D7t +wyOfaTyGOBye79oneNGEN3GKPEs5z35FBtYt2IpNeBLWrcLTy9LQQfMmNkqblWwM +7uXRQydmwYj3erMgbOqwaSvHIOgMA8RBBZniP+Rr+KCGgceExh/VS4ESshYhLBOh +gLJeDEoTniDYYkCrkOpkSi+sDQESeUWoL4cZaMjihccwsnX5OD+ywJO0a+IDRM5n +oN+J1q2MdqMTw5RhK2vZbMEHCiIHhWyFJEapvj+LeISCfiQMnf2BN+MlqO02TpUs +yZyQ2uypQjyttgI= +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIID+zCCAuOgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBtzE/MD0GA1UEAww2VMOc +UktUUlVTVCBFbGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sx +c8SxMQswCQYDVQQGDAJUUjEPMA0GA1UEBwwGQU5LQVJBMVYwVAYDVQQKDE0oYykg +MjAwNSBUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmlsacWfaW0gR8O8 +dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLjAeFw0wNTA1MTMxMDI3MTdaFw0xNTAz +MjIxMDI3MTdaMIG3MT8wPQYDVQQDDDZUw5xSS1RSVVNUIEVsZWt0cm9uaWsgU2Vy +dGlmaWthIEhpem1ldCBTYcSfbGF5xLFjxLFzxLExCzAJBgNVBAYMAlRSMQ8wDQYD +VQQHDAZBTktBUkExVjBUBgNVBAoMTShjKSAyMDA1IFTDnFJLVFJVU1QgQmlsZ2kg +xLBsZXRpxZ9pbSB2ZSBCaWxpxZ9pbSBHw7x2ZW5sacSfaSBIaXptZXRsZXJpIEEu +xZ4uMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAylIF1mMD2Bxf3dJ7 +XfIMYGFbazt0K3gNfUW9InTojAPBxhEqPZW8qZSwu5GXyGl8hMW0kWxsE2qkVa2k +heiVfrMArwDCBRj1cJ02i67L5BuBf5OI+2pVu32Fks66WJ/bMsW9Xe8iSi9BB35J +YbOG7E6mQW6EvAPs9TscyB/C7qju6hJKjRTP8wrgUDn5CDX4EVmt5yLqS8oUBt5C +urKZ8y1UiBAG6uEaPj1nH/vO+3yC6BFdSsG5FOpU2WabfIl9BJpiyelSPJ6c79L1 +JuTm5Rh8i27fbMx4W09ysstcP4wFjdFMjK2Sx+F4f2VsSQZQLJ4ywtdKxnWKWU51 +b0dewQIDAQABoxAwDjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQAV +9VX/N5aAWSGk/KEVTCD21F/aAyT8z5Aa9CEKmu46sWrv7/hg0Uw2ZkUd82YCdAR7 +kjCo3gp2D++Vbr3JN+YaDayJSFvMgzbC9UZcWYJWtNX+I7TYVBxEq8Sn5RTOPEFh +fEPmzcSBCYsk+1Ql1haolgxnB2+zUEfjHCQo3SqYpGH+2+oSN7wBGjSFvW5P55Fy +B0SFHljKVETd96y5y4khctuPwGkplyqjrhgjlxxBKot8KsF8kOipKMDTkcatKIdA +aLX/7KfS0zgYnNN9aV3wxqUeJBujR/xpB2jn5Jq07Q+hh4cCzofSSE7hvP/L8XKS +RGQDJereW26fyfJOrN3H +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIEPTCCAyWgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBvzE/MD0GA1UEAww2VMOc +UktUUlVTVCBFbGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sx +c8SxMQswCQYDVQQGEwJUUjEPMA0GA1UEBwwGQW5rYXJhMV4wXAYDVQQKDFVUw5xS +S1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmlsacWfaW0gR8O8dmVubGnEn2kg +SGl6bWV0bGVyaSBBLsWeLiAoYykgQXJhbMSxayAyMDA3MB4XDTA3MTIyNTE4Mzcx +OVoXDTE3MTIyMjE4MzcxOVowgb8xPzA9BgNVBAMMNlTDnFJLVFJVU1QgRWxla3Ry +b25payBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsTELMAkGA1UEBhMC +VFIxDzANBgNVBAcMBkFua2FyYTFeMFwGA1UECgxVVMOcUktUUlVTVCBCaWxnaSDE +sGxldGnFn2ltIHZlIEJpbGnFn2ltIEfDvHZlbmxpxJ9pIEhpem1ldGxlcmkgQS7F +ni4gKGMpIEFyYWzEsWsgMjAwNzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBAKu3PgqMyKVYFeaK7yc9SrToJdPNM8Ig3BnuiD9NYvDdE3ePYakqtdTyuTFY +KTsvP2qcb3N2Je40IIDu6rfwxArNK4aUyeNgsURSsloptJGXg9i3phQvKUmi8wUG ++7RP2qFsmmaf8EMJyupyj+sA1zU511YXRxcw9L6/P8JorzZAwan0qafoEGsIiveG +HtyaKhUG9qPw9ODHFNRRf8+0222vR5YXm3dx2KdxnSQM9pQ/hTEST7ruToK4uT6P +IzdezKKqdfcYbwnTrqdUKDT74eA7YH2gvnmJhsifLfkKS8RQouf9eRbHegsYz85M +733WB2+Y8a+xwXrXgTW4qhe04MsCAwEAAaNCMEAwHQYDVR0OBBYEFCnFkKslrxHk +Yb+j/4hhkeYO/pyBMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0G +CSqGSIb3DQEBBQUAA4IBAQAQDdr4Ouwo0RSVgrESLFF6QSU2TJ/sPx+EnWVUXKgW +AkD6bho3hO9ynYYKVZ1WKKxmLNA6VpM0ByWtCLCPyA8JWcqdmBzlVPi5RX9ql2+I +aE1KBiY3iAIOtsbWcpnOa3faYjGkVh+uX4132l32iPwa2Z61gfAyuOOI0JzzaqC5 +mxRZNTZPz/OOXl0XrRWV2N2y1RVuAE6zS89mlOTgzbUF2mNXi+WzqtvALhyQRNsa +XRik7r4EW5nVcV9VZWRi1aKbBFmGyGJ353yCRWo9F7/snXUMrqNvWtMvmDb08PUZ +qxFdyKbjKlhqQgnDvZImZjINXQhVdP+MmNAKpoRq0Tl9 +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIEPDCCAySgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBvjE/MD0GA1UEAww2VMOc +UktUUlVTVCBFbGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sx +c8SxMQswCQYDVQQGEwJUUjEPMA0GA1UEBwwGQW5rYXJhMV0wWwYDVQQKDFRUw5xS +S1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmlsacWfaW0gR8O8dmVubGnEn2kg +SGl6bWV0bGVyaSBBLsWeLiAoYykgS2FzxLFtIDIwMDUwHhcNMDUxMTA3MTAwNzU3 +WhcNMTUwOTE2MTAwNzU3WjCBvjE/MD0GA1UEAww2VMOcUktUUlVTVCBFbGVrdHJv +bmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMQswCQYDVQQGEwJU +UjEPMA0GA1UEBwwGQW5rYXJhMV0wWwYDVQQKDFRUw5xSS1RSVVNUIEJpbGdpIMSw +bGV0acWfaW0gdmUgQmlsacWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWe +LiAoYykgS2FzxLFtIDIwMDUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB +AQCpNn7DkUNMwxmYCMjHWHtPFoylzkkBH3MOrHUTpvqeLCDe2JAOCtFp0if7qnef +J1Il4std2NiDUBd9irWCPwSOtNXwSadktx4uXyCcUHVPr+G1QRT0mJKIx+XlZEdh +R3n9wFHxwZnn3M5q+6+1ATDcRhzviuyV79z/rxAc653YsKpqhRgNF8k+v/Gb0AmJ +Qv2gQrSdiVFVKc8bcLyEVK3BEx+Y9C52YItdP5qtygy/p1Zbj3e41Z55SZI/4PGX +JHpsmxcPbe9TmJEr5A++WXkHeLuXlfSfadRYhwqp48y2WBmfJiGxxFmNskF1wK1p +zpwACPI2/z7woQ8arBT9pmAPAgMBAAGjQzBBMB0GA1UdDgQWBBTZN7NOBf3Zz58S +Fq62iS/rJTqIHDAPBgNVHQ8BAf8EBQMDBwYAMA8GA1UdEwEB/wQFMAMBAf8wDQYJ +KoZIhvcNAQEFBQADggEBAHJglrfJ3NgpXiOFX7KzLXb7iNcX/nttRbj2hWyfIvwq +ECLsqrkw9qtY1jkQMZkpAL2JZkH7dN6RwRgLn7Vhy506vvWolKMiVW4XSf/SKfE4 +Jl3vpao6+XF75tpYHdN0wgH6PmlYX63LaL4ULptswLbcoCb6dxriJNoaN+BnrdFz +gw2lGh1uEpJ+hGIAF728JRhX8tepb1mIvDS3LoV4nZbcFMMsilKbloxSZj2GFotH +uFEJjOp9zYhys2AzsfAKRO8P9Qk3iCQOLGsgOqL6EfJANZxEaGM7rDNvY7wsu/LS +y3Z9fYjYHcgFHW68lKlmjHdxx/qR+i9Rnuk5UrbnBEI= +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIFQTCCAymgAwIBAgICDL4wDQYJKoZIhvcNAQELBQAwUTELMAkGA1UEBhMCVFcx +EjAQBgNVBAoTCVRBSVdBTi1DQTEQMA4GA1UECxMHUm9vdCBDQTEcMBoGA1UEAxMT +VFdDQSBHbG9iYWwgUm9vdCBDQTAeFw0xMjA2MjcwNjI4MzNaFw0zMDEyMzExNTU5 +NTlaMFExCzAJBgNVBAYTAlRXMRIwEAYDVQQKEwlUQUlXQU4tQ0ExEDAOBgNVBAsT +B1Jvb3QgQ0ExHDAaBgNVBAMTE1RXQ0EgR2xvYmFsIFJvb3QgQ0EwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCwBdvI64zEbooh745NnHEKH1Jw7W2CnJfF +10xORUnLQEK1EjRsGcJ0pDFfhQKX7EMzClPSnIyOt7h52yvVavKOZsTuKwEHktSz +0ALfUPZVr2YOy+BHYC8rMjk1Ujoog/h7FsYYuGLWRyWRzvAZEk2tY/XTP3VfKfCh +MBwqoJimFb3u/Rk28OKRQ4/6ytYQJ0lM793B8YVwm8rqqFpD/G2Gb3PpN0Wp8DbH +zIh1HrtsBv+baz4X7GGqcXzGHaL3SekVtTzWoWH1EfcFbx39Eb7QMAfCKbAJTibc +46KokWofwpFFiFzlmLhxpRUZyXx1EcxwdE8tmx2RRP1WKKD+u4ZqyPpcC1jcxkt2 +yKsi2XMPpfRaAok/T54igu6idFMqPVMnaR1sjjIsZAAmY2E2TqNGtz99sy2sbZCi +laLOz9qC5wc0GZbpuCGqKX6mOL6OKUohZnkfs8O1CWfe1tQHRvMq2uYiN2DLgbYP +oA/pyJV/v1WRBXrPPRXAb94JlAGD1zQbzECl8LibZ9WYkTunhHiVJqRaCPgrdLQA +BDzfuBSO6N+pjWxnkjMdwLfS7JLIvgm/LCkFbwJrnu+8vyq8W8BQj0FwcYeyTbcE +qYSjMq+u7msXi7Kx/mzhkIyIqJdIzshNy/MGz19qCkKxHh53L46g5pIOBvwFItIm +4TFRfTLcDwIDAQABoyMwITAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB +/zANBgkqhkiG9w0BAQsFAAOCAgEAXzSBdu+WHdXltdkCY4QWwa6gcFGn90xHNcgL +1yg9iXHZqjNB6hQbbCEAwGxCGX6faVsgQt+i0trEfJdLjbDorMjupWkEmQqSpqsn +LhpNgb+E1HAerUf+/UqdM+DyucRFCCEK2mlpc3INvjT+lIutwx4116KD7+U4x6WF +H6vPNOw/KP4M8VeGTslV9xzU2KV9Bnpv1d8Q34FOIWWxtuEXeZVFBs5fzNxGiWNo +RI2T9GRwoD2dKAXDOXC4Ynsg/eTb6QihuJ49CcdP+yz4k3ZB3lLg4VfSnQO8d57+ +nile98FRYB/e2guyLXW3Q0iT5/Z5xoRdgFlglPx4mI88k1HtQJAH32RjJMtOcQWh +15QaiDLxInQirqWm2BJpTGCjAu4r7NRjkgtevi92a6O2JryPA9gK8kxkRr05YuWW +6zRjESjMlfGt7+/cgFhI6Uu46mWs6fyAtbXIRfmswZ/ZuepiiI7E8UuDEq3mi4TW +nsLrgxifarsbJGAzcMzs9zLzXNl5fe+epP7JI8Mk7hWSsT2RTyaGvWZzJBPqpK5j +wa19hAM8EHiGG3njxPPyBJUgriOCxLM6AGK/5jYk4Ve6xx6QddVfP5VhK8E7zeWz +aGHQRiapIVJpLesux+t3zqY6tQMzT3bR51xUAV3LePTJDL/PEo4XLSNolOer/qmy +KwbQBM0= +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIDezCCAmOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJUVzES +MBAGA1UECgwJVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFU +V0NBIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwODI4MDcyNDMz +WhcNMzAxMjMxMTU1OTU5WjBfMQswCQYDVQQGEwJUVzESMBAGA1UECgwJVEFJV0FO +LUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NBIFJvb3QgQ2VydGlm +aWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB +AQCwfnK4pAOU5qfeCTiRShFAh6d8WWQUe7UREN3+v9XAu1bihSX0NXIP+FPQQeFE +AcK0HMMxQhZHhTMidrIKbw/lJVBPhYa+v5guEGcevhEFhgWQxFnQfHgQsIBct+HH +K3XLfJ+utdGdIzdjp9xCoi2SBBtQwXu4PhvJVgSLL1KbralW6cH/ralYhzC2gfeX +RfwZVzsrb+RH9JlF/h3x+JejiB03HFyP4HYlmlD4oFT/RJB2I9IyxsOrBr/8+7/z +rX2SYgJbKdM1o5OaQ2RgXbL6Mv87BK9NQGr5x+PvI/1ry+UPizgN7gr8/g+YnzAx +3WxSZfmLgb4i4RxYA7qRG4kHAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqOFsmjd6LWvJPelSDGRjjCDWmujANBgkq +hkiG9w0BAQUFAAOCAQEAPNV3PdrfibqHDAhUaiBQkr6wQT25JmSDCi/oQMCXKCeC +MErJk/9q56YAf4lCmtYR5VPOL8zy2gXE/uJQxDqGfczafhAJO5I1KlOy/usrBdls +XebQ79NqZp4VKIV66IIArB6nCWlWQtNoURi+VJq/REG6Sb4gumlc7rh3zc5sH62D +lhh9DrUUOYTxKOkto557HnpyWoOzeW/vtPzQCqVYT0bf+215WfKEIlKuD8z7fDvn +aspHYcN6+NOSBB+4IIThNlQWx0DeO4pz3N/GCUzf7Nr/1FNCocnyYh0igzyXxfkZ +YiesZSLX0zzG5Y6yU8xJzrww/nsOM5D77dIUkR8Hrw== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIICjzCCAhWgAwIBAgIQXIuZxVqUxdJxVt7NiYDMJjAKBggqhkjOPQQDAzCBiDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNl +eSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMT +JVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMjAx +MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgT +Ck5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVUaGUg +VVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlm +aWNhdGlvbiBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQarFRaqflo +I+d61SRvU8Za2EurxtW20eZzca7dnNYMYf3boIkDuAUU7FfO7l0/4iGzzvfUinng +o4N+LZfQYcTxmdwlkWOrfzCjtHDix6EznPO/LlxTsV+zfTJ/ijTjeXmjQjBAMB0G +A1UdDgQWBBQ64QmG1M8ZwpZ2dEl23OA1xmNjmjAOBgNVHQ8BAf8EBAMCAQYwDwYD +VR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjA2Z6EWCNzklwBBHU6+4WMB +zzuqQhFkoJ2UOQIReVx7Hfpkue4WQrO/isIJxOzksU0CMQDpKmFHjFJKS04YcPbW +RNZu9YO6bVi9JNlWSOrvxKJGgYhqOkbRqZtNyWHa0V1Xahg= +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCB +iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl +cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV +BAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAw +MjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNV +BAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU +aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2Vy +dGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK +AoICAQCAEmUXNg7D2wiz0KxXDXbtzSfTTK1Qg2HiqiBNCS1kCdzOiZ/MPans9s/B +3PHTsdZ7NygRK0faOca8Ohm0X6a9fZ2jY0K2dvKpOyuR+OJv0OwWIJAJPuLodMkY +tJHUYmTbf6MG8YgYapAiPLz+E/CHFHv25B+O1ORRxhFnRghRy4YUVD+8M/5+bJz/ +Fp0YvVGONaanZshyZ9shZrHUm3gDwFA66Mzw3LyeTP6vBZY1H1dat//O+T23LLb2 +VN3I5xI6Ta5MirdcmrS3ID3KfyI0rn47aGYBROcBTkZTmzNg95S+UzeQc0PzMsNT +79uq/nROacdrjGCT3sTHDN/hMq7MkztReJVni+49Vv4M0GkPGw/zJSZrM233bkf6 +c0Plfg6lZrEpfDKEY1WJxA3Bk1QwGROs0303p+tdOmw1XNtB1xLaqUkL39iAigmT +Yo61Zs8liM2EuLE/pDkP2QKe6xJMlXzzawWpXhaDzLhn4ugTncxbgtNMs+1b/97l +c6wjOy0AvzVVdAlJ2ElYGn+SNuZRkg7zJn0cTRe8yexDJtC/QV9AqURE9JnnV4ee +UB9XVKg+/XRjL7FQZQnmWEIuQxpMtPAlR1n6BB6T1CZGSlCBst6+eLf8ZxXhyVeE +Hg9j1uliutZfVS7qXMYoCAQlObgOK6nyTJccBz8NUvXt7y+CDwIDAQABo0IwQDAd +BgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rIDZsswDgYDVR0PAQH/BAQDAgEGMA8G +A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAFzUfA3P9wF9QZllDHPF +Up/L+M+ZBn8b2kMVn54CVVeWFPFSPCeHlCjtHzoBN6J2/FNQwISbxmtOuowhT6KO +VWKR82kV2LyI48SqC/3vqOlLVSoGIG1VeCkZ7l8wXEskEVX/JJpuXior7gtNn3/3 +ATiUFJVDBwn7YKnuHKsSjKCaXqeYalltiz8I+8jRRa8YFWSQEg9zKC7F4iRO/Fjs +8PRF/iKz6y+O0tlFYQXBl2+odnKPi4w2r78NBc5xjeambx9spnFixdjQg3IM8WcR +iQycE0xyNN+81XHfqnHd4blsjDwSXWXavVcStkNr/+XeTWYRUc+ZruwXtuhxkYze +Sf7dNXGiFSeUHM9h4ya7b6NnJSFd5t0dCy5oGzuCr+yDZ4XUmFF0sbmZgIn/f3gZ +XHlKYC6SQK5MNyosycdiyA5d9zZbyuAlJQG03RoHnHcAP9Dc1ew91Pq7P8yF1m9/ +qS3fuQL39ZeatTXaw2ewh0qpKJ4jjv9cJ2vhsE/zB+4ALtRZh8tSQZXq9EfX7mRB +VXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGwsAvgnEzDHNb842m1R0aB +L6KCq9NjRHDEjf8tM7qtj3u1cIiuPhnPQCjY/MiQu12ZIvVS5ljFH4gxQ+6IHdfG +jjxDah2nGN59PRbxYvnKkKj9 +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIICPDCCAaUCED9pHoGc8JpK83P/uUii5N0wDQYJKoZIhvcNAQEFBQAwXzELMAkG +A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFz +cyAxIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2 +MDEyOTAwMDAwMFoXDTI4MDgwMjIzNTk1OVowXzELMAkGA1UEBhMCVVMxFzAVBgNV +BAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAxIFB1YmxpYyBQcmlt +YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUAA4GN +ADCBiQKBgQDlGb9to1ZhLZlIcfZn3rmN67eehoAKkQ76OCWvRoiC5XOooJskXQ0f +zGVuDLDQVoQYh5oGmxChc9+0WDlrbsH2FdWoqD+qEgaNMax/sDTXjzRniAnNFBHi +TkVWaR94AoDa3EeRKbs2yWNcxeDXLYd7obcysHswuiovMaruo2fa2wIDAQABMA0G +CSqGSIb3DQEBBQUAA4GBAFgVKTk8d6PaXCUDfGD67gmZPCcQcMgMCeazh88K4hiW +NWLMv5sneYlfycQJ9M61Hd8qveXbhpxoJeUwfLaJFf5n0a3hUKw8fGJLj7qE1xIV +Gx/KXQ/BUpQqEZnae88MNhPVNdwQGVnqlMEAv3WP2fr9dgTbYruQagPZRjXZ+Hxb +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIICPDCCAaUCEDyRMcsf9tAbDpq40ES/Er4wDQYJKoZIhvcNAQEFBQAwXzELMAkG +A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFz +cyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2 +MDEyOTAwMDAwMFoXDTI4MDgwMjIzNTk1OVowXzELMAkGA1UEBhMCVVMxFzAVBgNV +BAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmlt +YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUAA4GN +ADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhE +BarsAx94f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/is +I19wKTakyYbnsZogy1Olhec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0G +CSqGSIb3DQEBBQUAA4GBABByUqkFFBkyCEHwxWsKzH4PIRnN5GfcX6kb5sroc50i +2JhucwNhkcV8sEVAbkSdjbCxlnRhLQ2pRdKkkirWmnWXbj9T/UWZYB2oK0z5XqcJ +2HUw19JlYD1n1khVdWk/kfVIC0dpImmClr7JyDiGSnoscxlIaU5rfGW/D/xwzoiQ +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIDhDCCAwqgAwIBAgIQL4D+I4wOIg9IZxIokYesszAKBggqhkjOPQQDAzCByjEL +MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW +ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2ln +biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp +U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y +aXR5IC0gRzQwHhcNMDcxMTA1MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCByjELMAkG +A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJp +U2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwg +SW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2ln +biBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5 +IC0gRzQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASnVnp8Utpkmw4tXNherJI9/gHm +GUo9FANL+mAnINmDiWn6VMaaGF5VKmTeBvaNSjutEDxlPZCIBIngMGGzrl0Bp3ve +fLK+ymVhAIau2o970ImtTR1ZmkGxvEeA3J5iw/mjgbIwga8wDwYDVR0TAQH/BAUw +AwEB/zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJ +aW1hZ2UvZ2lmMCEwHzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYj +aHR0cDovL2xvZ28udmVyaXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFLMW +kf3upm7ktS5Jj4d4gYDs5bG1MAoGCCqGSM49BAMDA2gAMGUCMGYhDBgmYFo4e1ZC +4Kf8NoRRkSAsdk1DPcQdhCPQrNZ8NQbOzWm9kA3bbEhCHQ6qQgIxAJw9SDkjOVga +FRJZap7v1VmyHVIsmXHNxynfGyphe3HR3vPA5Q06Sqotp9iGKt0uEA== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIEuTCCA6GgAwIBAgIQQBrEZCGzEyEDDrvkEhrFHTANBgkqhkiG9w0BAQsFADCB +vTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL +ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwOCBWZXJp +U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MTgwNgYDVQQDEy9W +ZXJpU2lnbiBVbml2ZXJzYWwgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe +Fw0wODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIG9MQswCQYDVQQGEwJVUzEX +MBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0 +IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9y +IGF1dGhvcml6ZWQgdXNlIG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNh +bCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAx2E3XrEBNNti1xWb/1hajCMj1mCOkdeQmIN65lgZOIzF +9uVkhbSicfvtvbnazU0AtMgtc6XHaXGVHzk8skQHnOgO+k1KxCHfKWGPMiJhgsWH +H26MfF8WIFFE0XBPV+rjHOPMee5Y2A7Cs0WTwCznmhcrewA3ekEzeOEz4vMQGn+H +LL729fdC4uW/h2KJXwBL38Xd5HVEMkE6HnFuacsLdUYI0crSK5XQz/u5QGtkjFdN +/BMReYTtXlT2NJ8IAfMQJQYXStrxHXpma5hgZqTZ79IugvHw7wnqRMkVauIDbjPT +rJ9VAMf2CGqUuV/c4DPxhGD5WycRtPwW8rtWaoAljQIDAQABo4GyMIGvMA8GA1Ud +EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMG0GCCsGAQUFBwEMBGEwX6FdoFsw +WTBXMFUWCWltYWdlL2dpZjAhMB8wBwYFKw4DAhoEFI/l0xqGrI2Oa8PPgGrUSBgs +exkuMCUWI2h0dHA6Ly9sb2dvLnZlcmlzaWduLmNvbS92c2xvZ28uZ2lmMB0GA1Ud +DgQWBBS2d/ppSEefUxLVwuoHMnYH0ZcHGTANBgkqhkiG9w0BAQsFAAOCAQEASvj4 +sAPmLGd75JR3Y8xuTPl9Dg3cyLk1uXBPY/ok+myDjEedO2Pzmvl2MpWRsXe8rJq+ +seQxIcaBlVZaDrHC1LGmWazxY8u4TB1ZkErvkBYoH1quEPuBUDgMbMzxPcP1Y+Oz +4yHJJDnp/RVmRvQbEdBNc6N9Rvk97ahfYtTxP/jgdFcrGJ2BtMQo2pSXpXDrrB2+ +BxHw1dvd5Yzw1TKwg+ZX4o+/vqGqvz0dtdQ46tewXDpPaj+PwGZsY6rp2aQW9IHR +lRQOfc2VNNnSj3BzgXucfr2YYdhFh5iQxeuGMMY1v/D/w1WIg0vvBZIGcfK4mJO3 +7M2CYfE45k+XmCpajQ== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIEvTCCA6WgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBhTELMAkGA1UEBhMCVVMx +IDAeBgNVBAoMF1dlbGxzIEZhcmdvIFdlbGxzU2VjdXJlMRwwGgYDVQQLDBNXZWxs +cyBGYXJnbyBCYW5rIE5BMTYwNAYDVQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMgUm9v +dCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDcxMjEzMTcwNzU0WhcNMjIxMjE0 +MDAwNzU0WjCBhTELMAkGA1UEBhMCVVMxIDAeBgNVBAoMF1dlbGxzIEZhcmdvIFdl +bGxzU2VjdXJlMRwwGgYDVQQLDBNXZWxscyBGYXJnbyBCYW5rIE5BMTYwNAYDVQQD +DC1XZWxsc1NlY3VyZSBQdWJsaWMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkw +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDub7S9eeKPCCGeOARBJe+r +WxxTkqxtnt3CxC5FlAM1iGd0V+PfjLindo8796jE2yljDpFoNoqXjopxaAkH5OjU +Dk/41itMpBb570OYj7OeUt9tkTmPOL13i0Nj67eT/DBMHAGTthP796EfvyXhdDcs +HqRePGj4S78NuR4uNuip5Kf4D8uCdXw1LSLWwr8L87T8bJVhHlfXBIEyg1J55oNj +z7fLY4sR4r1e6/aN7ZVyKLSsEmLpSjPmgzKuBXWVvYSV2ypcm44uDLiBK0HmOFaf +SZtsdvqKXfcBeYF8wYNABf5x/Qw/zE5gCQ5lRxAvAcAFP4/4s0HvWkJ+We/Slwxl +AgMBAAGjggE0MIIBMDAPBgNVHRMBAf8EBTADAQH/MDkGA1UdHwQyMDAwLqAsoCqG +KGh0dHA6Ly9jcmwucGtpLndlbGxzZmFyZ28uY29tL3dzcHJjYS5jcmwwDgYDVR0P +AQH/BAQDAgHGMB0GA1UdDgQWBBQmlRkQ2eihl5H/3BnZtQQ+0nMKajCBsgYDVR0j +BIGqMIGngBQmlRkQ2eihl5H/3BnZtQQ+0nMKaqGBi6SBiDCBhTELMAkGA1UEBhMC +VVMxIDAeBgNVBAoMF1dlbGxzIEZhcmdvIFdlbGxzU2VjdXJlMRwwGgYDVQQLDBNX +ZWxscyBGYXJnbyBCYW5rIE5BMTYwNAYDVQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMg +Um9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHmCAQEwDQYJKoZIhvcNAQEFBQADggEB +ALkVsUSRzCPIK0134/iaeycNzXK7mQDKfGYZUMbVmO2rvwNa5U3lHshPcZeG1eMd +/ZDJPHV3V3p9+N701NX3leZ0bh08rnyd2wIDBSxxSyU+B+NemvVmFymIGjifz6pB +A4SXa5M4esowRBskRDPQ5NHcKDj0E0M1NSljqHyita04pO2t/caaH/+Xc/77szWn +k4bGdpEA5qxRFsQnMlzbc9qlk1eOPm01JghZ1edE13YgY+esE2fDbbFwRnzVlhE9 +iW9dqKHrjQrawx0zbKPqZxmamX9LPYNRKh3KL4YMon4QLSvUFpULB6ouFJJJtylv +2G0xffX8oRAHh84vWdw+WNs= +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIFdjCCA16gAwIBAgIQXmjWEXGUY1BWAGjzPsnFkTANBgkqhkiG9w0BAQUFADBV +MQswCQYDVQQGEwJDTjEaMBgGA1UEChMRV29TaWduIENBIExpbWl0ZWQxKjAoBgNV +BAMTIUNlcnRpZmljYXRpb24gQXV0aG9yaXR5IG9mIFdvU2lnbjAeFw0wOTA4MDgw +MTAwMDFaFw0zOTA4MDgwMTAwMDFaMFUxCzAJBgNVBAYTAkNOMRowGAYDVQQKExFX +b1NpZ24gQ0EgTGltaXRlZDEqMCgGA1UEAxMhQ2VydGlmaWNhdGlvbiBBdXRob3Jp +dHkgb2YgV29TaWduMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAvcqN +rLiRFVaXe2tcesLea9mhsMMQI/qnobLMMfo+2aYpbxY94Gv4uEBf2zmoAHqLoE1U +fcIiePyOCbiohdfMlZdLdNiefvAA5A6JrkkoRBoQmTIPJYhTpA2zDxIIFgsDcScc +f+Hb0v1naMQFXQoOXXDX2JegvFNBmpGN9J42Znp+VsGQX+axaCA2pIwkLCxHC1l2 +ZjC1vt7tj/id07sBMOby8w7gLJKA84X5KIq0VC6a7fd2/BVoFutKbOsuEo/Uz/4M +x1wdC34FMr5esAkqQtXJTpCzWQ27en7N1QhatH/YHGkR+ScPewavVIMYe+HdVHpR +aG53/Ma/UkpmRqGyZxq7o093oL5d//xWC0Nyd5DKnvnyOfUNqfTq1+ezEC8wQjch +zDBwyYaYD8xYTYO7feUapTeNtqwylwA6Y3EkHp43xP901DfA4v6IRmAR3Qg/UDar +uHqklWJqbrDKaiFaafPz+x1wOZXzp26mgYmhiMU7ccqjUu6Du/2gd/Tkb+dC221K +mYo0SLwX3OSACCK28jHAPwQ+658geda4BmRkAjHXqc1S+4RFaQkAKtxVi8QGRkvA +Sh0JWzko/amrzgD5LkhLJuYwTKVYyrREgk/nkR4zw7CT/xH8gdLKH3Ep3XZPkiWv +HYG3Dy+MwwbMLyejSuQOmbp8HkUff6oZRZb9/D0CAwEAAaNCMEAwDgYDVR0PAQH/ +BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFOFmzw7R8bNLtwYgFP6H +EtX2/vs+MA0GCSqGSIb3DQEBBQUAA4ICAQCoy3JAsnbBfnv8rWTjMnvMPLZdRtP1 +LOJwXcgu2AZ9mNELIaCJWSQBnfmvCX0KI4I01fx8cpm5o9dU9OpScA7F9dY74ToJ +MuYhOZO9sxXqT2r09Ys/L3yNWC7F4TmgPsc9SnOeQHrAK2GpZ8nzJLmzbVUsWh2e +JXLOC62qx1ViC777Y7NhRCOjy+EaDveaBk3e1CNOIZZbOVtXHS9dCF4Jef98l7VN +g64N1uajeeAz0JmWAjCnPv/So0M/BVoG6kQC2nz4SNAzqfkHx5Xh9T71XXG68pWp +dIhhWeO/yloTunK0jF02h+mmxTwTv97QRCbut+wucPrXnbes5cVAWubXbHssw1ab +R80LzvobtCHXt2a49CUwi1wNuepnsvRtrtWhnk/Yn+knArAdBtaP4/tIEp9/EaEQ +PkxROpaw0RPxx9gmrjrKkcRpnd8BKWRRb2jaFOwIQZeQjdCygPLPwj2/kWjFgGce +xGATVdVhmVd8upUPYUk6ynW8yQqTP2cOEvIo4jEbwFcW3wh8GcF+Dx+FHgo2fFt+ +J7x6v+Db9NpSvd4MVHAxkUOVyLzwPt0JfjBkUO1/AaQzZ01oT74V77D2AhGiGxMl +OtzCWfHjXEa7ZywCRuoeSKbmW9m1vFGikpbbqsY3Iqb+zCB0oy2pLmvLwIIRIbWT +ee5Ehr7XHuQe+w== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIFWDCCA0CgAwIBAgIQUHBrzdgT/BtOOzNy0hFIjTANBgkqhkiG9w0BAQsFADBG +MQswCQYDVQQGEwJDTjEaMBgGA1UEChMRV29TaWduIENBIExpbWl0ZWQxGzAZBgNV +BAMMEkNBIOayg+mAmuagueivgeS5pjAeFw0wOTA4MDgwMTAwMDFaFw0zOTA4MDgw +MTAwMDFaMEYxCzAJBgNVBAYTAkNOMRowGAYDVQQKExFXb1NpZ24gQ0EgTGltaXRl +ZDEbMBkGA1UEAwwSQ0Eg5rKD6YCa5qC56K+B5LmmMIICIjANBgkqhkiG9w0BAQEF +AAOCAg8AMIICCgKCAgEA0EkhHiX8h8EqwqzbdoYGTufQdDTc7WU1/FDWiD+k8H/r +D195L4mx/bxjWDeTmzj4t1up+thxx7S8gJeNbEvxUNUqKaqoGXqW5pWOdO2XCld1 +9AXbbQs5uQF/qvbW2mzmBeCkTVL829B0txGMe41P/4eDrv8FAxNXUDf+jJZSEExf +v5RxadmWPgxDT74wwJ85dE8GRV2j1lY5aAfMh09Qd5Nx2UQIsYo06Yms25tO4dnk +UkWMLhQfkWsZHWgpLFbE4h4TV2TwYeO5Ed+w4VegG63XX9Gv2ystP9Bojg/qnw+L +NVgbExz03jWhCl3W6t8Sb8D7aQdGctyB9gQjF+BNdeFyb7Ao65vh4YOhn0pdr8yb ++gIgthhid5E7o9Vlrdx8kHccREGkSovrlXLp9glk3Kgtn3R46MGiCWOc76DbT52V +qyBPt7D3h1ymoOQ3OMdc4zUPLK2jgKLsLl3Az+2LBcLmc272idX10kaO6m1jGx6K +yX2m+Jzr5dVjhU1zZmkR/sgO9MHHZklTfuQZa/HpelmjbX7FF+Ynxu8b22/8DU0G +AbQOXDBGVWCvOGU6yke6rCzMRh+yRpY/8+0mBe53oWprfi1tWFxK1I5nuPHa1UaK +J/kR8slC/k7e3x9cxKSGhxYzoacXGKUN5AXlK8IrC6KVkLn9YDxOiT7nnO4fuwEC +AwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O +BBYEFOBNv9ybQV0T6GTwp+kVpOGBwboxMA0GCSqGSIb3DQEBCwUAA4ICAQBqinA4 +WbbaixjIvirTthnVZil6Xc1bL3McJk6jfW+rtylNpumlEYOnOXOvEESS5iVdT2H6 +yAa+Tkvv/vMx/sZ8cApBWNromUuWyXi8mHwCKe0JgOYKOoICKuLJL8hWGSbueBwj +/feTZU7n85iYr83d2Z5AiDEoOqsuC7CsDCT6eiaY8xJhEPRdF/d+4niXVOKM6Cm6 +jBAyvd0zaziGfjk9DgNyp115j0WKWa5bIW4xRtVZjc8VX90xJc/bYNaBRHIpAlf2 +ltTW/+op2znFuCyKGo3Oy+dCMYYFaA6eFN0AkLppRQjbbpCBhqcqBT/mhDn4t/lX +X0ykeVoQDF7Va/81XwVRHmyjdanPUIPTfPRm94KNPQx96N97qA4bLJyuQHCH2u2n +FoJavjVsIE4iYdm8UXrNemHcSxH5/mc0zy4EZmFcV5cjjPOGG0jfKq+nwf/Yjj4D +u9gqsPoUJbJRa4ZDhS4HIxaAjUz7tGM7zMN07RujHv41D198HRaG9Q7DlfEvr10l +O1Hm13ZBONFLAzkopR6RctR9q5czxNM+4Gm2KHmgCY0c0f9BckgG/Jou5yD5m6Le +ie2uPAmvylezkolwQOQvT8Jwg0DXJCxr5wkf09XHwQj02w47HAcLQxGEIYbpgNR1 +2KvxAmLBsX5VYc8T1yaw15zLKYs4SgsOkI26oQ== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIEMDCCA5mgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBxzELMAkGA1UEBhMCVVMx +FzAVBgNVBAgTDk5vcnRoIENhcm9saW5hMR8wHQYDVQQHExZSZXNlYXJjaCBUcmlh +bmdsZSBQYXJrMRYwFAYDVQQKEw1SZWQgSGF0LCBJbmMuMSEwHwYDVQQLExhSZWQg +SGF0IE5ldHdvcmsgU2VydmljZXMxIzAhBgNVBAMTGlJITlMgQ2VydGlmaWNhdGUg +QXV0aG9yaXR5MR4wHAYJKoZIhvcNAQkBFg9yaG5zQHJlZGhhdC5jb20wHhcNMDAw +ODIzMjI0NTU1WhcNMDMwODI4MjI0NTU1WjCBxzELMAkGA1UEBhMCVVMxFzAVBgNV +BAgTDk5vcnRoIENhcm9saW5hMR8wHQYDVQQHExZSZXNlYXJjaCBUcmlhbmdsZSBQ +YXJrMRYwFAYDVQQKEw1SZWQgSGF0LCBJbmMuMSEwHwYDVQQLExhSZWQgSGF0IE5l +dHdvcmsgU2VydmljZXMxIzAhBgNVBAMTGlJITlMgQ2VydGlmaWNhdGUgQXV0aG9y +aXR5MR4wHAYJKoZIhvcNAQkBFg9yaG5zQHJlZGhhdC5jb20wgZ8wDQYJKoZIhvcN +AQEBBQADgY0AMIGJAoGBAMBoKxIw4iEtIsZycVu/F6CTEOmb48mNOy2sxLuVO+DK +VTLclcIQswSyUfvohWEWNKW0HWdcp3f08JLatIuvlZNi82YprsCIt2SEDkiQYPhg +PgB/VN0XpqwY4ELefL6Qgff0BYUKCMzV8p/8JIt3pT3pSKnvDztjo/6mg0zo3At3 +AgMBAAGjggEoMIIBJDAdBgNVHQ4EFgQUVBXNnyz37A0f0qi+TAesiD77mwowgfQG +A1UdIwSB7DCB6YAUVBXNnyz37A0f0qi+TAesiD77mwqhgc2kgcowgccxCzAJBgNV +BAYTAlVTMRcwFQYDVQQIEw5Ob3J0aCBDYXJvbGluYTEfMB0GA1UEBxMWUmVzZWFy +Y2ggVHJpYW5nbGUgUGFyazEWMBQGA1UEChMNUmVkIEhhdCwgSW5jLjEhMB8GA1UE +CxMYUmVkIEhhdCBOZXR3b3JrIFNlcnZpY2VzMSMwIQYDVQQDExpSSE5TIENlcnRp +ZmljYXRlIEF1dGhvcml0eTEeMBwGCSqGSIb3DQEJARYPcmhuc0ByZWRoYXQuY29t +ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAkwGIiGdnkYye0BIU +kHESh1UK8lIbrfLTBx2vcJm7sM2AI8ntK3PpY7HQs4xgxUJkpsGVVpDFNQYDWPWO +K9n5qaAQqZn3FUKSpVDXEQfxAtXgcORVbirOJfhdzQsvEGH49iBCzMOJ+IpPgiQS +zzl/IagsjVKXUsX3X0KlhwlmsMw= +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIID7jCCA1egAwIBAgIBADANBgkqhkiG9w0BAQQFADCBsTELMAkGA1UEBhMCVVMx +FzAVBgNVBAgTDk5vcnRoIENhcm9saW5hMRAwDgYDVQQHEwdSYWxlaWdoMRYwFAYD +VQQKEw1SZWQgSGF0LCBJbmMuMRgwFgYDVQQLEw9SZWQgSGF0IE5ldHdvcmsxIjAg +BgNVBAMTGVJITiBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxITAfBgkqhkiG9w0BCQEW +EnJobi1ub2NAcmVkaGF0LmNvbTAeFw0wMjA5MDUyMDQ1MTZaFw0wNzA5MDkyMDQ1 +MTZaMIGxMQswCQYDVQQGEwJVUzEXMBUGA1UECBMOTm9ydGggQ2Fyb2xpbmExEDAO +BgNVBAcTB1JhbGVpZ2gxFjAUBgNVBAoTDVJlZCBIYXQsIEluYy4xGDAWBgNVBAsT +D1JlZCBIYXQgTmV0d29yazEiMCAGA1UEAxMZUkhOIENlcnRpZmljYXRlIEF1dGhv +cml0eTEhMB8GCSqGSIb3DQEJARYScmhuLW5vY0ByZWRoYXQuY29tMIGfMA0GCSqG +SIb3DQEBAQUAA4GNADCBiQKBgQCzFrfF9blpUR/NtD1wz2BXhaQqp10oIg7sGeKS +90iXpqYfUZWDEY+amKKQ4MtKJBmUqIpLiLQGbM531xU7PM1mg88jHQ28CgzLH8tA ++/PZ/iq0hSx7yaH+849oHfISsaQWGc4PuJqc2bxfSWKylZPOXS7deTzxW6a3orU5 +DY4SMQIDAQABo4IBEjCCAQ4wHQYDVR0OBBYEFH8bZKEuAsWofbjRsYsGnaOpUGOS +MIHeBgNVHSMEgdYwgdOAFH8bZKEuAsWofbjRsYsGnaOpUGOSoYG3pIG0MIGxMQsw +CQYDVQQGEwJVUzEXMBUGA1UECBMOTm9ydGggQ2Fyb2xpbmExEDAOBgNVBAcTB1Jh +bGVpZ2gxFjAUBgNVBAoTDVJlZCBIYXQsIEluYy4xGDAWBgNVBAsTD1JlZCBIYXQg +TmV0d29yazEiMCAGA1UEAxMZUkhOIENlcnRpZmljYXRlIEF1dGhvcml0eTEhMB8G +CSqGSIb3DQEJARYScmhuLW5vY0ByZWRoYXQuY29tggEAMAwGA1UdEwQFMAMBAf8w +DQYJKoZIhvcNAQEEBQADgYEAKE1C5TQi3caGYwR1UmcXRXLyOyErRVlyc/dZNp1X +Q8bclA8O/xNcT1A3hbLkwh81n3T051P7oQa4Oc7kCoZ7XyhdxxGeEqXWuWzpGAnV +8ELnVLWRniOtEnqqcnw5PIP4daR7A5L/KtTFdhkS+rQ7sIkslYwBkA3YugYFYQCs +ldo= +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIID7jCCA1egAwIBAgIBADANBgkqhkiG9w0BAQQFADCBsTELMAkGA1UEBhMCVVMx +FzAVBgNVBAgTDk5vcnRoIENhcm9saW5hMRAwDgYDVQQHEwdSYWxlaWdoMRYwFAYD +VQQKEw1SZWQgSGF0LCBJbmMuMRgwFgYDVQQLEw9SZWQgSGF0IE5ldHdvcmsxIjAg +BgNVBAMTGVJITiBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxITAfBgkqhkiG9w0BCQEW +EnJobi1ub2NAcmVkaGF0LmNvbTAeFw0wMzA4MjkwMjEwNTVaFw0xMzA4MjYwMjEw +NTVaMIGxMQswCQYDVQQGEwJVUzEXMBUGA1UECBMOTm9ydGggQ2Fyb2xpbmExEDAO +BgNVBAcTB1JhbGVpZ2gxFjAUBgNVBAoTDVJlZCBIYXQsIEluYy4xGDAWBgNVBAsT +D1JlZCBIYXQgTmV0d29yazEiMCAGA1UEAxMZUkhOIENlcnRpZmljYXRlIEF1dGhv +cml0eTEhMB8GCSqGSIb3DQEJARYScmhuLW5vY0ByZWRoYXQuY29tMIGfMA0GCSqG +SIb3DQEBAQUAA4GNADCBiQKBgQC/YWPrPYsrRUjmwvt80iEhuOyQk0EwfCyNedUU +6Q5+P+/WCpsKpgJSAS0mlqTtvameqggDwWEKQYDqrnTMYSbQBZFVPmYUoiCz1p1x +DKt3zPTwEbUlM4pOIpoQNmf6EW1Idjof0uNEe4lmvrSF+y+mqhP6mm3JuxjEBK9P +FWmJmwIDAQABo4IBEjCCAQ4wHQYDVR0OBBYEFGlEJwXcLu2l9IHE13hF50Rd+IdH +MIHeBgNVHSMEgdYwgdOAFGlEJwXcLu2l9IHE13hF50Rd+IdHoYG3pIG0MIGxMQsw +CQYDVQQGEwJVUzEXMBUGA1UECBMOTm9ydGggQ2Fyb2xpbmExEDAOBgNVBAcTB1Jh +bGVpZ2gxFjAUBgNVBAoTDVJlZCBIYXQsIEluYy4xGDAWBgNVBAsTD1JlZCBIYXQg +TmV0d29yazEiMCAGA1UEAxMZUkhOIENlcnRpZmljYXRlIEF1dGhvcml0eTEhMB8G +CSqGSIb3DQEJARYScmhuLW5vY0ByZWRoYXQuY29tggEAMAwGA1UdEwQFMAMBAf8w +DQYJKoZIhvcNAQEEBQADgYEAI8nKB59eljmD4E7a3UeEMMrU1TiG+d6Ig8osRyY2 +q/QUHigp3n0QSl6RPlqZBwypLuP7eERJxTLW6HqX/ynQM64munYGfnmXFwxPLSqL +iqxBWa7pxFUtuYjfm3tB+DIu7snAWeIwV143RynALXgz086jK9yE2r87Lku2s7ZO +noA= +-----END CERTIFICATE----- + diff --git a/Sites/pages/libraries/fof/download/adapter/curl.php b/Sites/pages/libraries/fof/download/adapter/curl.php new file mode 100644 index 00000000..70035bb6 --- /dev/null +++ b/Sites/pages/libraries/fof/download/adapter/curl.php @@ -0,0 +1,226 @@ +priority = 110; + $this->supportsFileSize = true; + $this->supportsChunkDownload = true; + $this->name = 'curl'; + $this->isSupported = function_exists('curl_init') && function_exists('curl_exec') && function_exists('curl_close'); + } + + /** + * Download a part (or the whole) of a remote URL and return the downloaded + * data. You are supposed to check the size of the returned data. If it's + * smaller than what you expected you've reached end of file. If it's empty + * you have tried reading past EOF. If it's larger than what you expected + * the server doesn't support chunk downloads. + * + * If this class' supportsChunkDownload returns false you should assume + * that the $from and $to parameters will be ignored. + * + * @param string $url The remote file's URL + * @param integer $from Byte range to start downloading from. Use null for start of file. + * @param integer $to Byte range to stop downloading. Use null to download the entire file ($from is ignored) + * @param array $params Additional params that will be added before performing the download + * + * @return string The raw file data retrieved from the remote URL. + * + * @throws Exception A generic exception is thrown on error + */ + public function downloadAndReturn($url, $from = null, $to = null, array $params = array()) + { + $ch = curl_init(); + + if (empty($from)) + { + $from = 0; + } + + if (empty($to)) + { + $to = 0; + } + + if ($to < $from) + { + $temp = $to; + $to = $from; + $from = $temp; + + unset($temp); + } + + // Default cURL options + $options = array( + CURLOPT_AUTOREFERER => 1, + CURLOPT_SSL_VERIFYPEER => 1, + CURLOPT_SSL_VERIFYHOST => 2, + CURLOPT_SSLVERSION => 0, + CURLOPT_AUTOREFERER => 1, + CURLOPT_URL => $url, + CURLOPT_BINARYTRANSFER => 1, + CURLOPT_RETURNTRANSFER => 1, + CURLOPT_FOLLOWLOCATION => 1, + CURLOPT_CAINFO => __DIR__ . '/cacert.pem', + CURLOPT_HEADERFUNCTION => array($this, 'reponseHeaderCallback') + ); + + if (!(empty($from) && empty($to))) + { + $options[CURLOPT_RANGE] = "$from-$to"; + } + + // Add any additional options: Since they are numeric, we must use the array operator. If the jey exists in both + // arrays, only the first one will be used while the second one will be ignored + $options = $params + $options; + + @curl_setopt_array($ch, $options); + + $this->headers = array(); + + $result = curl_exec($ch); + + $errno = curl_errno($ch); + $errmsg = curl_error($ch); + $http_status = curl_getinfo($ch, CURLINFO_HTTP_CODE); + + if ($result === false) + { + $error = JText::sprintf('LIB_FOF_DOWNLOAD_ERR_CURL_ERROR', $errno, $errmsg); + } + elseif (($http_status >= 300) && ($http_status <= 399) && isset($this->headers['Location']) && !empty($this->headers['Location'])) + { + return $this->downloadAndReturn($this->headers['Location'], $from, $to, $params); + } + elseif ($http_status > 399) + { + $result = false; + $errno = $http_status; + $error = JText::sprintf('LIB_FOF_DOWNLOAD_ERR_HTTPERROR', $http_status); + } + + curl_close($ch); + + if ($result === false) + { + throw new Exception($error, $errno); + } + else + { + return $result; + } + } + + /** + * Get the size of a remote file in bytes + * + * @param string $url The remote file's URL + * + * @return integer The file size, or -1 if the remote server doesn't support this feature + */ + public function getFileSize($url) + { + $result = -1; + + $ch = curl_init(); + + curl_setopt($ch, CURLOPT_AUTOREFERER, 1); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1); + curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); + curl_setopt($ch, CURLOPT_SSLVERSION, 0); + + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_NOBODY, true ); + curl_setopt($ch, CURLOPT_HEADER, true ); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true ); + @curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true ); + @curl_setopt($ch, CURLOPT_CAINFO, __DIR__ . '/cacert.pem'); + + $data = curl_exec($ch); + curl_close($ch); + + if ($data) + { + $content_length = "unknown"; + $status = "unknown"; + $redirection = null; + + if (preg_match( "/^HTTP\/1\.[01] (\d\d\d)/", $data, $matches)) + { + $status = (int)$matches[1]; + } + + if (preg_match( "/Content-Length: (\d+)/", $data, $matches)) + { + $content_length = (int)$matches[1]; + } + + if (preg_match( "/Location: (.*)/", $data, $matches)) + { + $redirection = (int)$matches[1]; + } + + if ($status == 200) + { + $result = $content_length; + } + + if (($status > 300) && ($status <= 308)) + { + if (!empty($redirection)) + { + return $this->getFileSize($redirection); + } + + return -1; + } + } + + return $result; + } + + /** + * Handles the HTTP headers returned by cURL + * + * @param resource $ch cURL resource handle (unused) + * @param string $data Each header line, as returned by the server + * + * @return int The length of the $data string + */ + protected function reponseHeaderCallback(&$ch, &$data) + { + $strlen = strlen($data); + + if (($strlen) <= 2) + { + return $strlen; + } + + if (substr($data, 0, 4) == 'HTTP') + { + return $strlen; + } + + list($header, $value) = explode(': ', trim($data), 2); + + $this->headers[$header] = $value; + + return $strlen; + } +} \ No newline at end of file diff --git a/Sites/pages/libraries/fof/download/adapter/fopen.php b/Sites/pages/libraries/fof/download/adapter/fopen.php new file mode 100644 index 00000000..aa9cb3df --- /dev/null +++ b/Sites/pages/libraries/fof/download/adapter/fopen.php @@ -0,0 +1,123 @@ +priority = 100; + $this->supportsFileSize = false; + $this->supportsChunkDownload = true; + $this->name = 'fopen'; + + // If we are not allowed to use ini_get, we assume that URL fopen is + // disabled. + if (!function_exists('ini_get')) + { + $this->isSupported = false; + } + else + { + $this->isSupported = ini_get('allow_url_fopen'); + } + } + + /** + * Download a part (or the whole) of a remote URL and return the downloaded + * data. You are supposed to check the size of the returned data. If it's + * smaller than what you expected you've reached end of file. If it's empty + * you have tried reading past EOF. If it's larger than what you expected + * the server doesn't support chunk downloads. + * + * If this class' supportsChunkDownload returns false you should assume + * that the $from and $to parameters will be ignored. + * + * @param string $url The remote file's URL + * @param integer $from Byte range to start downloading from. Use null for start of file. + * @param integer $to Byte range to stop downloading. Use null to download the entire file ($from is ignored) + * @param array $params Additional params that will be added before performing the download + * + * @return string The raw file data retrieved from the remote URL. + * + * @throws Exception A generic exception is thrown on error + */ + public function downloadAndReturn($url, $from = null, $to = null, array $params = array()) + { + if (empty($from)) + { + $from = 0; + } + + if (empty($to)) + { + $to = 0; + } + + if ($to < $from) + { + $temp = $to; + $to = $from; + $from = $temp; + + unset($temp); + } + + if (!(empty($from) && empty($to))) + { + $options = array( + 'http' => array( + 'method' => 'GET', + 'header' => "Range: bytes=$from-$to\r\n" + ), + 'ssl' => array( + 'verify_peer' => true, + 'cafile' => __DIR__ . '/cacert.pem', + 'verify_depth' => 5, + ) + ); + + $options = array_merge($options, $params); + + $context = stream_context_create($options); + $result = @file_get_contents($url, false, $context, $from - $to + 1); + } + else + { + $options = array( + 'http' => array( + 'method' => 'GET', + ), + 'ssl' => array( + 'verify_peer' => true, + 'cafile' => __DIR__ . '/cacert.pem', + 'verify_depth' => 5, + ) + ); + + $options = array_merge($options, $params); + + $context = stream_context_create($options); + $result = @file_get_contents($url, false, $context); + } + + if ($result === false) + { + $error = JText::sprintf('LIB_FOF_DOWNLOAD_ERR_HTTPERROR'); + throw new Exception($error, 1); + } + else + { + return $result; + } + } +} \ No newline at end of file diff --git a/Sites/pages/libraries/fof/download/download.php b/Sites/pages/libraries/fof/download/download.php new file mode 100644 index 00000000..3d346b95 --- /dev/null +++ b/Sites/pages/libraries/fof/download/download.php @@ -0,0 +1,495 @@ +isSupported()) + { + continue; + } + + if ($adapter->priority > $priority) + { + $this->adapter = $adapter; + $priority = $adapter->priority; + } + } + + // Load the language strings + FOFPlatform::getInstance()->loadTranslations('lib_f0f'); + } + + /** + * Forces the use of a specific adapter + * + * @param string $className The name of the class or the name of the adapter, e.g. 'FOFDownloadAdapterCurl' or + * 'curl' + */ + public function setAdapter($className) + { + $adapter = null; + + if (class_exists($className, true)) + { + $adapter = new $className; + } + elseif (class_exists('FOFDownloadAdapter' . ucfirst($className))) + { + $className = 'FOFDownloadAdapter' . ucfirst($className); + $adapter = new $className; + } + + if (is_object($adapter) && ($adapter instanceof FOFDownloadInterface)) + { + $this->adapter = $adapter; + } + } + + /** + * Returns the name of the current adapter + * + * @return string + */ + public function getAdapterName() + { + if(is_object($this->adapter)) + { + $class = get_class($this->adapter); + + return strtolower(str_ireplace('FOFDownloadAdapter', '', $class)); + } + + return ''; + } + + /** + * Sets the additional options for the adapter + * + * @param array $options + */ + public function setAdapterOptions(array $options) + { + $this->adapterOptions = $options; + } + + /** + * Returns the additional options for the adapter + * + * @return array + */ + public function getAdapterOptions() + { + return $this->adapterOptions; + } + + /** + * Used to decode the $params array + * + * @param string $key The parameter key you want to retrieve the value for + * @param mixed $default The default value, if none is specified + * + * @return mixed The value for this parameter key + */ + private function getParam($key, $default = null) + { + if (array_key_exists($key, $this->params)) + { + return $this->params[$key]; + } + else + { + return $default; + } + } + + /** + * Download data from a URL and return it + * + * @param string $url The URL to download from + * + * @return bool|string The downloaded data or false on failure + */ + public function getFromURL($url) + { + try + { + return $this->adapter->downloadAndReturn($url, null, null, $this->adapterOptions); + } + catch (Exception $e) + { + return false; + } + } + + /** + * Performs the staggered download of file. The downloaded file will be stored in Joomla!'s temp-path using the + * basename of the URL as a filename + * + * The $params array can have any of the following keys + * url The file being downloaded + * frag Rolling counter of the file fragment being downloaded + * totalSize The total size of the file being downloaded, in bytes + * doneSize How many bytes we have already downloaded + * maxExecTime Maximum execution time downloading file fragments, in seconds + * length How many bytes to download at once + * + * The array returned is in the following format: + * + * status True if there are no errors, false if there are errors + * error A string with the error message if there are errors + * frag The next file fragment to download + * totalSize The total size of the downloaded file in bytes, if the server supports HEAD requests + * doneSize How many bytes have already been downloaded + * percent % of the file already downloaded (if totalSize could be determined) + * localfile The name of the local file, without the path + * + * @param array $params A parameters array, as sent by the user interface + * + * @return array A return status array + */ + public function importFromURL($params) + { + $this->params = $params; + + // Fetch data + $url = $this->getParam('url'); + $localFilename = $this->getParam('localFilename'); + $frag = $this->getParam('frag', -1); + $totalSize = $this->getParam('totalSize', -1); + $doneSize = $this->getParam('doneSize', -1); + $maxExecTime = $this->getParam('maxExecTime', 5); + $runTimeBias = $this->getParam('runTimeBias', 75); + $length = $this->getParam('length', 1048576); + + if (empty($localFilename)) + { + $localFilename = basename($url); + + if (strpos($localFilename, '?') !== false) + { + $paramsPos = strpos($localFilename, '?'); + $localFilename = substr($localFilename, 0, $paramsPos - 1); + } + } + + $tmpDir = JFactory::getConfig()->get('tmp_path', JPATH_ROOT . '/tmp'); + $tmpDir = rtrim($tmpDir, '/\\'); + + // Init retArray + $retArray = array( + "status" => true, + "error" => '', + "frag" => $frag, + "totalSize" => $totalSize, + "doneSize" => $doneSize, + "percent" => 0, + "localfile" => $localFilename + ); + + try + { + $timer = new FOFUtilsTimer($maxExecTime, $runTimeBias); + $start = $timer->getRunningTime(); // Mark the start of this download + $break = false; // Don't break the step + + // Figure out where on Earth to put that file + $local_file = $tmpDir . '/' . $localFilename; + + while (($timer->getTimeLeft() > 0) && !$break) + { + // Do we have to initialize the file? + if ($frag == -1) + { + // Currently downloaded size + $doneSize = 0; + + if (@file_exists($local_file)) + { + @unlink($local_file); + } + + // Delete and touch the output file + $fp = @fopen($local_file, 'wb'); + + if ($fp !== false) + { + @fclose($fp); + } + + // Init + $frag = 0; + + //debugMsg("-- First frag, getting the file size"); + $retArray['totalSize'] = $this->adapter->getFileSize($url); + $totalSize = $retArray['totalSize']; + } + + // Calculate from and length + $from = $frag * $length; + $to = $length + $from - 1; + + // Try to download the first frag + $required_time = 1.0; + + try + { + $result = $this->adapter->downloadAndReturn($url, $from, $to, $this->adapterOptions); + + if ($result === false) + { + throw new Exception(JText::sprintf('LIB_FOF_DOWNLOAD_ERR_COULDNOTDOWNLOADFROMURL', $url), 500); + } + } + catch (Exception $e) + { + $result = false; + $error = $e->getMessage(); + } + + if ($result === false) + { + // Failed download + if ($frag == 0) + { + // Failure to download first frag = failure to download. Period. + $retArray['status'] = false; + $retArray['error'] = $error; + + //debugMsg("-- Download FAILED"); + + return $retArray; + } + else + { + // Since this is a staggered download, consider this normal and finish + $frag = -1; + //debugMsg("-- Import complete"); + $totalSize = $doneSize; + $break = true; + } + } + + // Add the currently downloaded frag to the total size of downloaded files + if ($result) + { + $filesize = strlen($result); + //debugMsg("-- Successful download of $filesize bytes"); + $doneSize += $filesize; + + // Append the file + $fp = @fopen($local_file, 'ab'); + + if ($fp === false) + { + //debugMsg("-- Can't open local file $local_file for writing"); + // Can't open the file for writing + $retArray['status'] = false; + $retArray['error'] = JText::sprintf('LIB_FOF_DOWNLOAD_ERR_COULDNOTWRITELOCALFILE', $local_file); + + return $retArray; + } + + fwrite($fp, $result); + fclose($fp); + + //debugMsg("-- Appended data to local file $local_file"); + + $frag++; + + //debugMsg("-- Proceeding to next fragment, frag $frag"); + + if (($filesize < $length) || ($filesize > $length)) + { + // A partial download or a download larger than the frag size means we are done + $frag = -1; + //debugMsg("-- Import complete (partial download of last frag)"); + $totalSize = $doneSize; + $break = true; + } + } + + // Advance the frag pointer and mark the end + $end = $timer->getRunningTime(); + + // Do we predict that we have enough time? + $required_time = max(1.1 * ($end - $start), $required_time); + + if ($required_time > (10 - $end + $start)) + { + $break = true; + } + + $start = $end; + } + + if ($frag == -1) + { + $percent = 100; + } + elseif ($doneSize <= 0) + { + $percent = 0; + } + else + { + if ($totalSize > 0) + { + $percent = 100 * ($doneSize / $totalSize); + } + else + { + $percent = 0; + } + } + + // Update $retArray + $retArray = array( + "status" => true, + "error" => '', + "frag" => $frag, + "totalSize" => $totalSize, + "doneSize" => $doneSize, + "percent" => $percent, + ); + } + catch (Exception $e) + { + //debugMsg("EXCEPTION RAISED:"); + //debugMsg($e->getMessage()); + $retArray['status'] = false; + $retArray['error'] = $e->getMessage(); + } + + return $retArray; + } + + /** + * This method will crawl a starting directory and get all the valid files + * that will be analyzed by __construct. Then it organizes them into an + * associative array. + * + * @param string $path Folder where we should start looking + * @param array $ignoreFolders Folder ignore list + * @param array $ignoreFiles File ignore list + * + * @return array Associative array, where the `fullpath` key contains the path to the file, + * and the `classname` key contains the name of the class + */ + protected static function getFiles($path, array $ignoreFolders = array(), array $ignoreFiles = array()) + { + $return = array(); + + $files = self::scanDirectory($path, $ignoreFolders, $ignoreFiles); + + // Ok, I got the files, now I have to organize them + foreach ($files as $file) + { + $clean = str_replace($path, '', $file); + $clean = trim(str_replace('\\', '/', $clean), '/'); + + $parts = explode('/', $clean); + + $return[] = array( + 'fullpath' => $file, + 'classname' => 'FOFDownloadAdapter' . ucfirst(basename($parts[0], '.php')) + ); + } + + return $return; + } + + /** + * Recursive function that will scan every directory unless it's in the + * ignore list. Files that aren't in the ignore list are returned. + * + * @param string $path Folder where we should start looking + * @param array $ignoreFolders Folder ignore list + * @param array $ignoreFiles File ignore list + * + * @return array List of all the files + */ + protected static function scanDirectory($path, array $ignoreFolders = array(), array $ignoreFiles = array()) + { + $return = array(); + + $handle = @opendir($path); + + if ( !$handle) + { + return $return; + } + + while (($file = readdir($handle)) !== false) + { + if ($file == '.' || $file == '..') + { + continue; + } + + $fullpath = $path . '/' . $file; + + if ((is_dir($fullpath) && in_array($file, $ignoreFolders)) || (is_file($fullpath) && in_array($file, $ignoreFiles))) + { + continue; + } + + if (is_dir($fullpath)) + { + $return = array_merge(self::scanDirectory($fullpath, $ignoreFolders, $ignoreFiles), $return); + } + else + { + $return[] = $path . '/' . $file; + } + } + + return $return; + } +} \ No newline at end of file diff --git a/Sites/pages/libraries/fof/download/interface.php b/Sites/pages/libraries/fof/download/interface.php new file mode 100644 index 00000000..b5089fa5 --- /dev/null +++ b/Sites/pages/libraries/fof/download/interface.php @@ -0,0 +1,79 @@ +adapter = new FOFEncryptAesOpenssl(); + + if (!$this->adapter->isSupported($phpfunc)) + { + $this->adapter = new FOFEncryptAesMcrypt(); + } + } + else + { + $this->adapter = new FOFEncryptAesMcrypt(); + + if (!$this->adapter->isSupported($phpfunc)) + { + $this->adapter = new FOFEncryptAesOpenssl(); + } + } + + $this->adapter->setEncryptionMode($mode, $strength); + $this->setPassword($key, true); + } + + /** + * Sets the password for this instance. + * + * WARNING: Do not use the legacy mode, it's insecure + * + * @param string $password The password (either user-provided password or binary encryption key) to use + * @param bool $legacyMode True to use the legacy key expansion. We recommend against using it. + */ + public function setPassword($password, $legacyMode = false) + { + $this->key = $password; + + $passLength = strlen($password); + + if (function_exists('mb_strlen')) + { + $passLength = mb_strlen($password, 'ASCII'); + } + + // Legacy mode was doing something stupid, requiring a key of 32 bytes. DO NOT USE LEGACY MODE! + if ($legacyMode && ($passLength != 32)) + { + // Legacy mode: use the sha256 of the password + $this->key = hash('sha256', $password, true); + // We have to trim or zero pad the password (we end up throwing half of it away in Rijndael-128 / AES...) + $this->key = $this->adapter->resizeKey($this->key, $this->adapter->getBlockSize()); + } + } + + /** + * Encrypts a string using AES + * + * @param string $stringToEncrypt The plaintext to encrypt + * @param bool $base64encoded Should I Base64-encode the result? + * + * @return string The cryptotext. Please note that the first 16 bytes of + * the raw string is the IV (initialisation vector) which + * is necessary for decoding the string. + */ + public function encryptString($stringToEncrypt, $base64encoded = true) + { + $blockSize = $this->adapter->getBlockSize(); + $randVal = new FOFEncryptRandval(); + $iv = $randVal->generate($blockSize); + + $key = $this->getExpandedKey($blockSize, $iv); + $cipherText = $this->adapter->encrypt($stringToEncrypt, $key, $iv); + + // Optionally pass the result through Base64 encoding + if ($base64encoded) + { + $cipherText = base64_encode($cipherText); + } + + // Return the result + return $cipherText; + } + + /** + * Decrypts a ciphertext into a plaintext string using AES + * + * @param string $stringToDecrypt The ciphertext to decrypt. The first 16 bytes of the raw string must contain + * the IV (initialisation vector). + * @param bool $base64encoded Should I Base64-decode the data before decryption? + * + * @return string The plain text string + */ + public function decryptString($stringToDecrypt, $base64encoded = true) + { + if ($base64encoded) + { + $stringToDecrypt = base64_decode($stringToDecrypt); + } + + // Extract IV + $iv_size = $this->adapter->getBlockSize(); + $iv = substr($stringToDecrypt, 0, $iv_size); + $key = $this->getExpandedKey($iv_size, $iv); + + // Decrypt the data + $plainText = $this->adapter->decrypt($stringToDecrypt, $key); + + return $plainText; + } + + /** + * Is AES encryption supported by this PHP installation? + * + * @param FOFUtilsPhpfunc $phpfunc + * + * @return boolean + */ + public static function isSupported(FOFUtilsPhpfunc $phpfunc = null) + { + if (!is_object($phpfunc) || !($phpfunc instanceof $phpfunc)) + { + $phpfunc = new FOFUtilsPhpfunc(); + } + + $adapter = new FOFEncryptAesMcrypt(); + + if (!$adapter->isSupported($phpfunc)) + { + $adapter = new FOFEncryptAesOpenssl(); + } + + if (!$adapter->isSupported($phpfunc)) + { + return false; + } + + if (!$phpfunc->function_exists('base64_encode')) + { + return false; + } + + if (!$phpfunc->function_exists('base64_decode')) + { + return false; + } + + if (!$phpfunc->function_exists('hash_algos')) + { + return false; + } + + $algorightms = $phpfunc->hash_algos(); + + if (!in_array('sha256', $algorightms)) + { + return false; + } + + return true; + } + + /** + * @param $blockSize + * @param $iv + * + * @return string + */ + public function getExpandedKey($blockSize, $iv) + { + $key = $this->key; + $passLength = strlen($key); + + if (function_exists('mb_strlen')) + { + $passLength = mb_strlen($key, 'ASCII'); + } + + if ($passLength != $blockSize) + { + $iterations = 1000; + $salt = $this->adapter->resizeKey($iv, 16); + $key = hash_pbkdf2('sha256', $this->key, $salt, $iterations, $blockSize, true); + } + + return $key; + } +} + +if (!function_exists('hash_pbkdf2')) +{ + function hash_pbkdf2($algo, $password, $salt, $count, $length = 0, $raw_output = false) + { + if (!in_array(strtolower($algo), hash_algos())) + { + trigger_error(__FUNCTION__ . '(): Unknown hashing algorithm: ' . $algo, E_USER_WARNING); + } + + if (!is_numeric($count)) + { + trigger_error(__FUNCTION__ . '(): expects parameter 4 to be long, ' . gettype($count) . ' given', E_USER_WARNING); + } + + if (!is_numeric($length)) + { + trigger_error(__FUNCTION__ . '(): expects parameter 5 to be long, ' . gettype($length) . ' given', E_USER_WARNING); + } + + if ($count <= 0) + { + trigger_error(__FUNCTION__ . '(): Iterations must be a positive integer: ' . $count, E_USER_WARNING); + } + + if ($length < 0) + { + trigger_error(__FUNCTION__ . '(): Length must be greater than or equal to 0: ' . $length, E_USER_WARNING); + } + + $output = ''; + $block_count = $length ? ceil($length / strlen(hash($algo, '', $raw_output))) : 1; + + for ($i = 1; $i <= $block_count; $i++) + { + $last = $xorsum = hash_hmac($algo, $salt . pack('N', $i), $password, true); + + for ($j = 1; $j < $count; $j++) + { + $xorsum ^= ($last = hash_hmac($algo, $last, $password, true)); + } + + $output .= $xorsum; + } + + if (!$raw_output) + { + $output = bin2hex($output); + } + + return $length ? substr($output, 0, $length) : $output; + } +} diff --git a/Sites/pages/libraries/fof/encrypt/aes/abstract.php b/Sites/pages/libraries/fof/encrypt/aes/abstract.php new file mode 100644 index 00000000..981f653b --- /dev/null +++ b/Sites/pages/libraries/fof/encrypt/aes/abstract.php @@ -0,0 +1,88 @@ + $size) + { + if (function_exists('mb_substr')) + { + return mb_substr($key, 0, $size, 'ASCII'); + } + + return substr($key, 0, $size); + } + + return $key . str_repeat("\0", ($size - $keyLength)); + } + + /** + * Returns null bytes to append to the string so that it's zero padded to the specified block size + * + * @param string $string The binary string which will be zero padded + * @param int $blockSize The block size + * + * @return string The zero bytes to append to the string to zero pad it to $blockSize + */ + protected function getZeroPadding($string, $blockSize) + { + $stringSize = strlen($string); + + if (function_exists('mb_strlen')) + { + $stringSize = mb_strlen($string, 'ASCII'); + } + + if ($stringSize == $blockSize) + { + return ''; + } + + if ($stringSize < $blockSize) + { + return str_repeat("\0", $blockSize - $stringSize); + } + + $paddingBytes = $stringSize % $blockSize; + + return str_repeat("\0", $blockSize - $paddingBytes); + } +} \ No newline at end of file diff --git a/Sites/pages/libraries/fof/encrypt/aes/interface.php b/Sites/pages/libraries/fof/encrypt/aes/interface.php new file mode 100644 index 00000000..e8edaebe --- /dev/null +++ b/Sites/pages/libraries/fof/encrypt/aes/interface.php @@ -0,0 +1,83 @@ +cipherType = MCRYPT_RIJNDAEL_128; + break; + + case '192': + $this->cipherType = MCRYPT_RIJNDAEL_192; + break; + + case '256': + $this->cipherType = MCRYPT_RIJNDAEL_256; + break; + } + + switch (strtolower($mode)) + { + case 'ecb': + $this->cipherMode = MCRYPT_MODE_ECB; + break; + + default: + case 'cbc': + $this->cipherMode = MCRYPT_MODE_CBC; + break; + } + + } + + public function encrypt($plainText, $key, $iv = null) + { + $iv_size = $this->getBlockSize(); + $key = $this->resizeKey($key, $iv_size); + $iv = $this->resizeKey($iv, $iv_size); + + if (empty($iv)) + { + $randVal = new FOFEncryptRandval(); + $iv = $randVal->generate($iv_size); + } + + $cipherText = mcrypt_encrypt($this->cipherType, $key, $plainText, $this->cipherMode, $iv); + $cipherText = $iv . $cipherText; + + return $cipherText; + } + + public function decrypt($cipherText, $key) + { + $iv_size = $this->getBlockSize(); + $key = $this->resizeKey($key, $iv_size); + $iv = substr($cipherText, 0, $iv_size); + $cipherText = substr($cipherText, $iv_size); + $plainText = mcrypt_decrypt($this->cipherType, $key, $cipherText, $this->cipherMode, $iv); + + return $plainText; + } + + public function isSupported(FOFUtilsPhpfunc $phpfunc = null) + { + if (!is_object($phpfunc) || !($phpfunc instanceof $phpfunc)) + { + $phpfunc = new FOFUtilsPhpfunc(); + } + + if (!$phpfunc->function_exists('mcrypt_get_key_size')) + { + return false; + } + + if (!$phpfunc->function_exists('mcrypt_get_iv_size')) + { + return false; + } + + if (!$phpfunc->function_exists('mcrypt_create_iv')) + { + return false; + } + + if (!$phpfunc->function_exists('mcrypt_encrypt')) + { + return false; + } + + if (!$phpfunc->function_exists('mcrypt_decrypt')) + { + return false; + } + + if (!$phpfunc->function_exists('mcrypt_list_algorithms')) + { + return false; + } + + if (!$phpfunc->function_exists('hash')) + { + return false; + } + + if (!$phpfunc->function_exists('hash_algos')) + { + return false; + } + + $algorightms = $phpfunc->mcrypt_list_algorithms(); + + if (!in_array('rijndael-128', $algorightms)) + { + return false; + } + + if (!in_array('rijndael-192', $algorightms)) + { + return false; + } + + if (!in_array('rijndael-256', $algorightms)) + { + return false; + } + + $algorightms = $phpfunc->hash_algos(); + + if (!in_array('sha256', $algorightms)) + { + return false; + } + + return true; + } + + public function getBlockSize() + { + return mcrypt_get_iv_size($this->cipherType, $this->cipherMode); + } +} \ No newline at end of file diff --git a/Sites/pages/libraries/fof/encrypt/aes/openssl.php b/Sites/pages/libraries/fof/encrypt/aes/openssl.php new file mode 100644 index 00000000..094b1e50 --- /dev/null +++ b/Sites/pages/libraries/fof/encrypt/aes/openssl.php @@ -0,0 +1,172 @@ +openSSLOptions = OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING; + } + + public function setEncryptionMode($mode = 'cbc', $strength = 128) + { + static $availableAlgorithms = null; + static $defaultAlgo = 'aes-128-cbc'; + + if (!is_array($availableAlgorithms)) + { + $availableAlgorithms = openssl_get_cipher_methods(); + + foreach (array('aes-256-cbc', 'aes-256-ecb', 'aes-192-cbc', + 'aes-192-ecb', 'aes-128-cbc', 'aes-128-ecb') as $algo) + { + if (in_array($algo, $availableAlgorithms)) + { + $defaultAlgo = $algo; + break; + } + } + } + + $strength = (int) $strength; + $mode = strtolower($mode); + + if (!in_array($strength, array(128, 192, 256))) + { + $strength = 256; + } + + if (!in_array($mode, array('cbc', 'ebc'))) + { + $mode = 'cbc'; + } + + $algo = 'aes-' . $strength . '-' . $mode; + + if (!in_array($algo, $availableAlgorithms)) + { + $algo = $defaultAlgo; + } + + $this->method = $algo; + } + + public function encrypt($plainText, $key, $iv = null) + { + $iv_size = $this->getBlockSize(); + $key = $this->resizeKey($key, $iv_size); + $iv = $this->resizeKey($iv, $iv_size); + + if (empty($iv)) + { + $randVal = new FOFEncryptRandval(); + $iv = $randVal->generate($iv_size); + } + + $plainText .= $this->getZeroPadding($plainText, $iv_size); + $cipherText = openssl_encrypt($plainText, $this->method, $key, $this->openSSLOptions, $iv); + $cipherText = $iv . $cipherText; + + return $cipherText; + } + + public function decrypt($cipherText, $key) + { + $iv_size = $this->getBlockSize(); + $key = $this->resizeKey($key, $iv_size); + $iv = substr($cipherText, 0, $iv_size); + $cipherText = substr($cipherText, $iv_size); + $plainText = openssl_decrypt($cipherText, $this->method, $key, $this->openSSLOptions, $iv); + + return $plainText; + } + + public function isSupported(FOFUtilsPhpfunc $phpfunc = null) + { + if (!is_object($phpfunc) || !($phpfunc instanceof $phpfunc)) + { + $phpfunc = new FOFUtilsPhpfunc(); + } + + if (!$phpfunc->function_exists('openssl_get_cipher_methods')) + { + return false; + } + + if (!$phpfunc->function_exists('openssl_random_pseudo_bytes')) + { + return false; + } + + if (!$phpfunc->function_exists('openssl_cipher_iv_length')) + { + return false; + } + + if (!$phpfunc->function_exists('openssl_encrypt')) + { + return false; + } + + if (!$phpfunc->function_exists('openssl_decrypt')) + { + return false; + } + + if (!$phpfunc->function_exists('hash')) + { + return false; + } + + if (!$phpfunc->function_exists('hash_algos')) + { + return false; + } + + $algorightms = $phpfunc->openssl_get_cipher_methods(); + + if (!in_array('aes-128-cbc', $algorightms)) + { + return false; + } + + $algorightms = $phpfunc->hash_algos(); + + if (!in_array('sha256', $algorightms)) + { + return false; + } + + return true; + } + + /** + * @return int + */ + public function getBlockSize() + { + return openssl_cipher_iv_length($this->method); + } +} \ No newline at end of file diff --git a/Sites/pages/libraries/fof/encrypt/base32.php b/Sites/pages/libraries/fof/encrypt/base32.php new file mode 100644 index 00000000..768e064d --- /dev/null +++ b/Sites/pages/libraries/fof/encrypt/base32.php @@ -0,0 +1,222 @@ + 0) + { + throw new Exception('Length must be divisible by 8'); + } + + if (!preg_match('/^[01]+$/', $str)) + { + throw new Exception('Only 0\'s and 1\'s are permitted'); + } + + preg_match_all('/.{8}/', $str, $chrs); + $chrs = array_map('bindec', $chrs[0]); + + // I'm just being slack here + array_unshift($chrs, 'C*'); + + return call_user_func_array('pack', $chrs); + } + + /** + * fromBin + * + * Converts a correct binary string to base32 + * + * @param string $str The string of 0's and 1's you want to convert + * + * @return string String encoded as base32 + * + * @throws exception + */ + private function fromBin($str) + { + if (strlen($str) % 8 > 0) + { + throw new Exception('Length must be divisible by 8'); + } + + if (!preg_match('/^[01]+$/', $str)) + { + throw new Exception('Only 0\'s and 1\'s are permitted'); + } + + // Base32 works on the first 5 bits of a byte, so we insert blanks to pad it out + $str = preg_replace('/(.{5})/', '000$1', $str); + + // We need a string divisible by 5 + $length = strlen($str); + $rbits = $length & 7; + + if ($rbits > 0) + { + // Excessive bits need to be padded + $ebits = substr($str, $length - $rbits); + $str = substr($str, 0, $length - $rbits); + $str .= "000$ebits" . str_repeat('0', 5 - strlen($ebits)); + } + + preg_match_all('/.{8}/', $str, $chrs); + $chrs = array_map(array($this, '_mapcharset'), $chrs[0]); + + return join('', $chrs); + } + + /** + * toBin + * + * Accepts a base32 string and returns an ascii binary string + * + * @param string $str The base32 string to convert + * + * @return string Ascii binary string + * + * @throws Exception + */ + private function toBin($str) + { + if (!preg_match('/^[' . self::CSRFC3548 . ']+$/', $str)) + { + throw new Exception('Must match character set'); + } + + // Convert the base32 string back to a binary string + $str = join('', array_map(array($this, '_mapbin'), str_split($str))); + + // Remove the extra 0's we added + $str = preg_replace('/000(.{5})/', '$1', $str); + + // Unpad if nessicary + $length = strlen($str); + $rbits = $length & 7; + + if ($rbits > 0) + { + $str = substr($str, 0, $length - $rbits); + } + + return $str; + } + + /** + * fromString + * + * Convert any string to a base32 string + * This should be binary safe... + * + * @param string $str The string to convert + * + * @return string The converted base32 string + */ + public function encode($str) + { + return $this->fromBin($this->str2bin($str)); + } + + /** + * toString + * + * Convert any base32 string to a normal sctring + * This should be binary safe... + * + * @param string $str The base32 string to convert + * + * @return string The normal string + */ + public function decode($str) + { + $str = strtoupper($str); + + return $this->bin2str($this->tobin($str)); + } + + /** + * _mapcharset + * + * Used with array_map to map the bits from a binary string + * directly into a base32 character set + * + * @param string $str The string of 0's and 1's you want to convert + * + * @return string Resulting base32 character + * + * @access private + */ + private function _mapcharset($str) + { + // Huh! + $x = self::CSRFC3548; + + return $x[bindec($str)]; + } + + /** + * _mapbin + * + * Used with array_map to map the characters from a base32 + * character set directly into a binary string + * + * @param string $chr The caracter to map + * + * @return string String of 0's and 1's + * + * @access private + */ + private function _mapbin($chr) + { + return sprintf('%08b', strpos(self::CSRFC3548, $chr)); + } +} diff --git a/Sites/pages/libraries/fof/encrypt/randval.php b/Sites/pages/libraries/fof/encrypt/randval.php new file mode 100644 index 00000000..5fe13c03 --- /dev/null +++ b/Sites/pages/libraries/fof/encrypt/randval.php @@ -0,0 +1,55 @@ +_timeStep = $timeStep; + $this->_passCodeLength = $passCodeLength; + $this->_secretLength = $secretLength; + $this->_pinModulo = pow(10, $this->_passCodeLength); + + if (is_null($base32)) + { + $this->_base32 = new FOFEncryptBase32; + } + else + { + $this->_base32 = $base32; + } + } + + /** + * Get the time period based on the $time timestamp and the Time Step + * defined. If $time is skipped or set to null the current timestamp will + * be used. + * + * @param int|null $time Timestamp + * + * @return int The time period since the UNIX Epoch + */ + public function getPeriod($time = null) + { + if (is_null($time)) + { + $time = time(); + } + + $period = floor($time / $this->_timeStep); + + return $period; + } + + /** + * Check is the given passcode $code is a valid TOTP generated using secret + * key $secret + * + * @param string $secret The Base32-encoded secret key + * @param string $code The passcode to check + * + * @return boolean True if the code is valid + */ + public function checkCode($secret, $code) + { + $time = $this->getPeriod(); + + for ($i = -1; $i <= 1; $i++) + { + if ($this->getCode($secret, ($time + $i) * $this->_timeStep) == $code) + { + return true; + } + } + + return false; + } + + /** + * Gets the TOTP passcode for a given secret key $secret and a given UNIX + * timestamp $time + * + * @param string $secret The Base32-encoded secret key + * @param int $time UNIX timestamp + * + * @return string + */ + public function getCode($secret, $time = null) + { + $period = $this->getPeriod($time); + $secret = $this->_base32->decode($secret); + + $time = pack("N", $period); + $time = str_pad($time, 8, chr(0), STR_PAD_LEFT); + + $hash = hash_hmac('sha1', $time, $secret, true); + $offset = ord(substr($hash, -1)); + $offset = $offset & 0xF; + + $truncatedHash = $this->hashToInt($hash, $offset) & 0x7FFFFFFF; + $pinValue = str_pad($truncatedHash % $this->_pinModulo, $this->_passCodeLength, "0", STR_PAD_LEFT); + + return $pinValue; + } + + /** + * Extracts a part of a hash as an integer + * + * @param string $bytes The hash + * @param string $start The char to start from (0 = first char) + * + * @return string + */ + protected function hashToInt($bytes, $start) + { + $input = substr($bytes, $start, strlen($bytes) - $start); + $val2 = unpack("N", substr($input, 0, 4)); + + return $val2[1]; + } + + /** + * Returns a QR code URL for easy setup of TOTP apps like Google Authenticator + * + * @param string $user User + * @param string $hostname Hostname + * @param string $secret Secret string + * + * @return string + */ + public function getUrl($user, $hostname, $secret) + { + $url = sprintf("otpauth://totp/%s@%s?secret=%s", $user, $hostname, $secret); + $encoder = "https://chart.googleapis.com/chart?chs=200x200&chld=Q|2&cht=qr&chl="; + $encoderURL = $encoder . urlencode($url); + + return $encoderURL; + } + + /** + * Generates a (semi-)random Secret Key for TOTP generation + * + * @return string + * + * @note Since __DEPLOY_VERSION__ we use the secure method "random_bytes" over the original insecure "rand" function. + * The random_bytes function has been backported to outdated PHP versions by the core shipped library paragonie/random_compat + */ + public function generateSecret() + { + $secret = random_bytes($this->_secretLength); + + $base32 = new FOFEncryptBase32; + + return $this->_base32->encode($secret); + } +} diff --git a/Sites/pages/libraries/fof/form/field.php b/Sites/pages/libraries/fof/form/field.php new file mode 100644 index 00000000..3f6df7b4 --- /dev/null +++ b/Sites/pages/libraries/fof/form/field.php @@ -0,0 +1,38 @@ +static)) + { + $this->static = $this->getStatic(); + } + + return $this->static; + break; + + case 'repeatable': + if (empty($this->repeatable)) + { + $this->repeatable = $this->getRepeatable(); + } + + return $this->repeatable; + break; + + default: + return parent::__get($name); + } + } + + /** + * Get the rendering of this field type for static display, e.g. in a single + * item view (typically a "read" task). + * + * @since 2.0 + * + * @return string The field HTML + */ + public function getStatic() + { + $class = $this->element['class'] ? ' class="' . (string) $this->element['class'] . '"' : ''; + + $params = $this->getOptions(); + + $db = FOFPlatform::getInstance()->getDbo(); + $query = $db->getQuery(true); + + $query->select('a.id AS value, a.title AS text'); + $query->from('#__viewlevels AS a'); + $query->group('a.id, a.title, a.ordering'); + $query->order('a.ordering ASC'); + $query->order($query->qn('title') . ' ASC'); + + // Get the options. + $db->setQuery($query); + $options = $db->loadObjectList(); + + // If params is an array, push these options to the array + if (is_array($params)) + { + $options = array_merge($params, $options); + } + + // If all levels is allowed, push it into the array. + elseif ($params) + { + array_unshift($options, JHtml::_('select.option', '', JText::_('JOPTION_ACCESS_SHOW_ALL_LEVELS'))); + } + + return '' . + htmlspecialchars(FOFFormFieldList::getOptionName($options, $this->value), ENT_COMPAT, 'UTF-8') . + ''; + } + + /** + * Get the rendering of this field type for a repeatable (grid) display, + * e.g. in a view listing many item (typically a "browse" task) + * + * @since 2.0 + * + * @return string The field HTML + */ + public function getRepeatable() + { + $class = $this->element['class'] ? (string) $this->element['class'] : ''; + + $params = $this->getOptions(); + + $db = FOFPlatform::getInstance()->getDbo(); + $query = $db->getQuery(true); + + $query->select('a.id AS value, a.title AS text'); + $query->from('#__viewlevels AS a'); + $query->group('a.id, a.title, a.ordering'); + $query->order('a.ordering ASC'); + $query->order($query->qn('title') . ' ASC'); + + // Get the options. + $db->setQuery($query); + $options = $db->loadObjectList(); + + // If params is an array, push these options to the array + if (is_array($params)) + { + $options = array_merge($params, $options); + } + + // If all levels is allowed, push it into the array. + elseif ($params) + { + array_unshift($options, JHtml::_('select.option', '', JText::_('JOPTION_ACCESS_SHOW_ALL_LEVELS'))); + } + + return '' . + htmlspecialchars(FOFFormFieldList::getOptionName($options, $this->value), ENT_COMPAT, 'UTF-8') . + ''; + } +} diff --git a/Sites/pages/libraries/fof/form/field/actions.php b/Sites/pages/libraries/fof/form/field/actions.php new file mode 100644 index 00000000..4b789988 --- /dev/null +++ b/Sites/pages/libraries/fof/form/field/actions.php @@ -0,0 +1,251 @@ +static)) + { + $this->static = $this->getStatic(); + } + + return $this->static; + break; + + case 'repeatable': + if (empty($this->repeatable)) + { + $this->repeatable = $this->getRepeatable(); + } + + return $this->repeatable; + break; + + default: + return parent::__get($name); + } + } + + /** + * Get the field configuration + * + * @return array + */ + protected function getConfig() + { + // If no custom options were defined let's figure out which ones of the + // defaults we shall use... + $config = array( + 'published' => 1, + 'unpublished' => 1, + 'archived' => 0, + 'trash' => 0, + 'all' => 0, + ); + + $stack = array(); + + if (isset($this->element['show_published'])) + { + $config['published'] = FOFStringUtils::toBool($this->element['show_published']); + } + + if (isset($this->element['show_unpublished'])) + { + $config['unpublished'] = FOFStringUtils::toBool($this->element['show_unpublished']); + } + + if (isset($this->element['show_archived'])) + { + $config['archived'] = FOFStringUtils::toBool($this->element['show_archived']); + } + + if (isset($this->element['show_trash'])) + { + $config['trash'] = FOFStringUtils::toBool($this->element['show_trash']); + } + + if (isset($this->element['show_all'])) + { + $config['all'] = FOFStringUtils::toBool($this->element['show_all']); + } + + return $config; + } + + /** + * Method to get the field options. + * + * @since 2.0 + * + * @return array The field option objects. + */ + protected function getOptions() + { + return null; + } + + /** + * Method to get a + * + * @param string $enabledFieldName Name of the enabled/published field + * + * @return FOFFormFieldPublished Field + */ + protected function getPublishedField($enabledFieldName) + { + $attributes = array( + 'name' => $enabledFieldName, + 'type' => 'published', + ); + + if ($this->element['publish_up']) + { + $attributes['publish_up'] = (string) $this->element['publish_up']; + } + + if ($this->element['publish_down']) + { + $attributes['publish_down'] = (string) $this->element['publish_down']; + } + + foreach ($attributes as $name => $value) + { + if (!is_null($value)) + { + $renderedAttributes[] = $name . '="' . $value . '"'; + } + } + + $publishedXml = new SimpleXMLElement(''); + + $publishedField = new FOFFormFieldPublished($this->form); + + // Pass required objects to the field + $publishedField->item = $this->item; + $publishedField->rowid = $this->rowid; + $publishedField->setup($publishedXml, $this->item->{$enabledFieldName}); + + return $publishedField; + } + + /** + * Get the rendering of this field type for static display, e.g. in a single + * item view (typically a "read" task). + * + * @since 2.0 + * + * @return string The field HTML + */ + public function getStatic() + { + throw new Exception(__CLASS__ . ' cannot be used in single item display forms'); + } + + /** + * Get the rendering of this field type for a repeatable (grid) display, + * e.g. in a view listing many item (typically a "browse" task) + * + * @since 2.0 + * + * @return string The field HTML + */ + public function getRepeatable() + { + if (!($this->item instanceof FOFTable)) + { + throw new Exception(__CLASS__ . ' needs a FOFTable to act upon'); + } + + $config = $this->getConfig(); + + // Initialise + $prefix = ''; + $checkbox = 'cb'; + $publish_up = null; + $publish_down = null; + $enabled = true; + + $html = '
      '; + + // Render a published field + if ($publishedFieldName = $this->item->getColumnAlias('enabled')) + { + if ($config['published'] || $config['unpublished']) + { + // Generate a FOFFormFieldPublished field + $publishedField = $this->getPublishedField($publishedFieldName); + + // Render the publish button + $html .= $publishedField->getRepeatable(); + } + + if ($config['archived']) + { + $archived = $this->item->{$publishedFieldName} == 2 ? true : false; + + // Create dropdown items + $action = $archived ? 'unarchive' : 'archive'; + JHtml::_('actionsdropdown.' . $action, 'cb' . $this->rowid, $prefix); + } + + if ($config['trash']) + { + $trashed = $this->item->{$publishedFieldName} == -2 ? true : false; + + $action = $trashed ? 'untrash' : 'trash'; + JHtml::_('actionsdropdown.' . $action, 'cb' . $this->rowid, $prefix); + } + + // Render dropdown list + if ($config['archived'] || $config['trash']) + { + $html .= JHtml::_('actionsdropdown.render', $this->item->title); + } + } + + $html .= '
      '; + + return $html; + } +} diff --git a/Sites/pages/libraries/fof/form/field/button.php b/Sites/pages/libraries/fof/form/field/button.php new file mode 100644 index 00000000..1f459dbb --- /dev/null +++ b/Sites/pages/libraries/fof/form/field/button.php @@ -0,0 +1,137 @@ +static)) + { + $this->static = $this->getStatic(); + } + + return $this->static; + break; + + case 'repeatable': + if (empty($this->repeatable)) + { + $this->repeatable = $this->getRepeatable(); + } + + return $this->repeatable; + break; + + default: + return parent::__get($name); + } + } + + /** + * Get the rendering of this field type for static display, e.g. in a single + * item view (typically a "read" task). + * + * @since 2.0 + * + * @return string The field HTML + */ + public function getStatic() + { + return $this->getInput(); + } + + /** + * Get the rendering of this field type for a repeatable (grid) display, + * e.g. in a view listing many item (typically a "browse" task) + * + * @since 2.0 + * + * @return string The field HTML + */ + public function getRepeatable() + { + return $this->getInput(); + } + + /** + * Get the rendering of this field type for static display, e.g. in a single + * item view (typically a "read" task). + * + * @since 2.0 + * + * @return string The field HTML + */ + public function getInput() + { + $this->label = ''; + + $allowedElement = array('button', 'a'); + + if (in_array($this->element['htmlelement'], $allowedElement)) + $type = $this->element['htmlelement']; + else + $type = 'button'; + + $text = $this->element['text']; + $class = $this->element['class'] ? (string) $this->element['class'] : ''; + $icon = $this->element['icon'] ? (string) $this->element['icon'] : ''; + $onclick = $this->element['onclick'] ? 'onclick="' . (string) $this->element['onclick'] . '"' : ''; + $url = $this->element['url'] ? 'href="' . $this->parseFieldTags((string) $this->element['url']) . '"' : ''; + $title = $this->element['title'] ? 'title="' . JText::_((string) $this->element['title']) . '"' : ''; + + $this->value = JText::_($text); + + if ($icon) + { + $icon = ''; + } + + return '<' . $type . ' id="' . $this->id . '" class="btn ' . $class . '" ' . + $onclick . $url . $title . '>' . + $icon . + htmlspecialchars($this->value, ENT_COMPAT, 'UTF-8') . + ''; + } + + /** + * Method to get the field title. + * + * @return string The field title. + */ + protected function getTitle() + { + return null; + } +} diff --git a/Sites/pages/libraries/fof/form/field/cachehandler.php b/Sites/pages/libraries/fof/form/field/cachehandler.php new file mode 100644 index 00000000..6b9816b5 --- /dev/null +++ b/Sites/pages/libraries/fof/form/field/cachehandler.php @@ -0,0 +1,102 @@ +static)) + { + $this->static = $this->getStatic(); + } + + return $this->static; + break; + + case 'repeatable': + if (empty($this->repeatable)) + { + $this->repeatable = $this->getRepeatable(); + } + + return $this->repeatable; + break; + + default: + return parent::__get($name); + } + } + + /** + * Get the rendering of this field type for static display, e.g. in a single + * item view (typically a "read" task). + * + * @since 2.0 + * + * @return string The field HTML + */ + public function getStatic() + { + $class = $this->element['class'] ? ' class="' . (string) $this->element['class'] . '"' : ''; + + return '' . + htmlspecialchars(FOFFormFieldList::getOptionName($this->getOptions(), $this->value), ENT_COMPAT, 'UTF-8') . + ''; + } + + /** + * Get the rendering of this field type for a repeatable (grid) display, + * e.g. in a view listing many item (typically a "browse" task) + * + * @since 2.0 + * + * @return string The field HTML + */ + public function getRepeatable() + { + $class = $this->element['class'] ? (string) $this->element['class'] : ''; + + return '' . + htmlspecialchars(FOFFormFieldList::getOptionName($this->getOptions(), $this->value), ENT_COMPAT, 'UTF-8') . + ''; + } +} diff --git a/Sites/pages/libraries/fof/form/field/calendar.php b/Sites/pages/libraries/fof/form/field/calendar.php new file mode 100644 index 00000000..8a7daec9 --- /dev/null +++ b/Sites/pages/libraries/fof/form/field/calendar.php @@ -0,0 +1,212 @@ +static)) + { + $this->static = $this->getStatic(); + } + + return $this->static; + break; + + case 'repeatable': + if (empty($this->repeatable)) + { + $this->repeatable = $this->getRepeatable(); + } + + return $this->repeatable; + break; + + default: + return parent::__get($name); + } + } + + /** + * Get the rendering of this field type for static display, e.g. in a single + * item view (typically a "read" task). + * + * @since 2.0 + * + * @return string The field HTML + */ + public function getStatic() + { + return $this->getCalendar('static'); + } + + /** + * Get the rendering of this field type for a repeatable (grid) display, + * e.g. in a view listing many item (typically a "browse" task) + * + * @since 2.0 + * + * @return string The field HTML + */ + public function getRepeatable() + { + return $this->getCalendar('repeatable'); + } + + /** + * Method to get the calendar input markup. + * + * @param string $display The display to render ('static' or 'repeatable') + * + * @return string The field input markup. + * + * @since 2.1.rc4 + */ + protected function getCalendar($display) + { + // Initialize some field attributes. + $format = $this->element['format'] ? (string) $this->element['format'] : '%Y-%m-%d'; + $class = $this->element['class'] ? (string) $this->element['class'] : ''; + $default = $this->element['default'] ? (string) $this->element['default'] : ''; + + // PHP date doesn't use percentages (%) for the format, but the calendar Javascript + // DOES use it (@see: calendar-uncompressed.js). Therefore we have to convert it. + $formatJS = $format; + $formatPHP = str_replace(array('%', 'H:M:S', 'B'), array('', 'H:i:s', 'F'), $formatJS); + + // Check for empty date values + if (empty($this->value) || $this->value == FOFPlatform::getInstance()->getDbo()->getNullDate() || $this->value == '0000-00-00') + { + $this->value = $default; + } + + // Get some system objects. + $config = FOFPlatform::getInstance()->getConfig(); + $user = JFactory::getUser(); + + // Format date if exists + if (!empty($this->value)) + { + $date = FOFPlatform::getInstance()->getDate($this->value, 'UTC'); + + // If a known filter is given use it. + switch (strtoupper((string) $this->element['filter'])) + { + case 'SERVER_UTC': + // Convert a date to UTC based on the server timezone. + if ((int) $this->value) + { + // Get a date object based on the correct timezone. + $date->setTimezone(new DateTimeZone($config->get('offset'))); + } + break; + + case 'USER_UTC': + // Convert a date to UTC based on the user timezone. + if ((int) $this->value) + { + // Get a date object based on the correct timezone. + $date->setTimezone($user->getTimezone()); + } + break; + + default: + break; + } + + // Transform the date string. + $this->value = $date->format($formatPHP, true, false); + } + + if ($display == 'static') + { + // Build the attributes array. + $attributes = array(); + + if ($this->element['size']) + { + $attributes['size'] = (int) $this->element['size']; + } + + if ($this->element['maxlength']) + { + $attributes['maxlength'] = (int) $this->element['maxlength']; + } + + if ($this->element['class']) + { + $attributes['class'] = (string) $this->element['class']; + } + + if ((string) $this->element['readonly'] == 'true') + { + $attributes['readonly'] = 'readonly'; + } + + if ((string) $this->element['disabled'] == 'true') + { + $attributes['disabled'] = 'disabled'; + } + + if ($this->element['onchange']) + { + $attributes['onchange'] = (string) $this->element['onchange']; + } + + if ($this->required) + { + $attributes['required'] = 'required'; + $attributes['aria-required'] = 'true'; + } + + return JHtml::_('calendar', $this->value, $this->name, $this->id, $formatJS, $attributes); + } + else + { + return '' . + htmlspecialchars($this->value, ENT_COMPAT, 'UTF-8') . + ''; + } + } +} diff --git a/Sites/pages/libraries/fof/form/field/captcha.php b/Sites/pages/libraries/fof/form/field/captcha.php new file mode 100644 index 00000000..4d55b3b9 --- /dev/null +++ b/Sites/pages/libraries/fof/form/field/captcha.php @@ -0,0 +1,93 @@ +static)) + { + $this->static = $this->getStatic(); + } + + return $this->static; + break; + + case 'repeatable': + if (empty($this->repeatable)) + { + $this->repeatable = $this->getRepeatable(); + } + + return $this->repeatable; + break; + + default: + return parent::__get($name); + } + } + + /** + * Get the rendering of this field type for static display, e.g. in a single + * item view (typically a "read" task). + * + * @since 2.0 + * + * @return string The field HTML + */ + public function getStatic() + { + return $this->getInput(); + } + + /** + * Get the rendering of this field type for a repeatable (grid) display, + * e.g. in a view listing many item (typically a "browse" task) + * + * @since 2.0 + * + * @return string The field HTML + */ + public function getRepeatable() + { + return $this->getInput(); + } +} diff --git a/Sites/pages/libraries/fof/form/field/checkbox.php b/Sites/pages/libraries/fof/form/field/checkbox.php new file mode 100644 index 00000000..c8acc646 --- /dev/null +++ b/Sites/pages/libraries/fof/form/field/checkbox.php @@ -0,0 +1,129 @@ +static)) + { + $this->static = $this->getStatic(); + } + + return $this->static; + break; + + case 'repeatable': + if (empty($this->repeatable)) + { + $this->repeatable = $this->getRepeatable(); + } + + return $this->repeatable; + break; + + default: + return parent::__get($name); + } + } + + /** + * Get the rendering of this field type for static display, e.g. in a single + * item view (typically a "read" task). + * + * @since 2.0 + * + * @return string The field HTML + */ + public function getStatic() + { + $class = $this->element['class'] ? ' class="' . (string) $this->element['class'] . '"' : ''; + $value = $this->element['value'] ? (string) $this->element['value'] : '1'; + $disabled = ((string) $this->element['disabled'] == 'true') ? ' disabled="disabled"' : ''; + $onclick = $this->element['onclick'] ? ' onclick="' . (string) $this->element['onclick'] . '"' : ''; + $required = $this->required ? ' required="required" aria-required="true"' : ''; + + if (empty($this->value)) + { + $checked = (isset($this->element['checked'])) ? ' checked="checked"' : ''; + } + else + { + $checked = ' checked="checked"'; + } + + return '' . + '' . + ''; + } + + /** + * Get the rendering of this field type for a repeatable (grid) display, + * e.g. in a view listing many item (typically a "browse" task) + * + * @since 2.0 + * + * @return string The field HTML + */ + public function getRepeatable() + { + $class = $this->element['class'] ? (string) $this->element['class'] : ''; + $value = $this->element['value'] ? (string) $this->element['value'] : '1'; + $disabled = ((string) $this->element['disabled'] == 'true') ? ' disabled="disabled"' : ''; + $onclick = $this->element['onclick'] ? ' onclick="' . (string) $this->element['onclick'] . '"' : ''; + $required = $this->required ? ' required="required" aria-required="true"' : ''; + + if (empty($this->value)) + { + $checked = (isset($this->element['checked'])) ? ' checked="checked"' : ''; + } + else + { + $checked = ' checked="checked"'; + } + + return '' . + '' . + ''; + } +} diff --git a/Sites/pages/libraries/fof/form/field/checkboxes.php b/Sites/pages/libraries/fof/form/field/checkboxes.php new file mode 100644 index 00000000..88023bc7 --- /dev/null +++ b/Sites/pages/libraries/fof/form/field/checkboxes.php @@ -0,0 +1,128 @@ +static)) + { + $this->static = $this->getStatic(); + } + + return $this->static; + break; + + case 'repeatable': + if (empty($this->repeatable)) + { + $this->repeatable = $this->getRepeatable(); + } + + return $this->repeatable; + break; + + default: + return parent::__get($name); + } + } + + /** + * Get the rendering of this field type for static display, e.g. in a single + * item view (typically a "read" task). + * + * @since 2.0 + * + * @return string The field HTML + */ + public function getStatic() + { + return $this->getRepeatable(); + } + + /** + * Get the rendering of this field type for a repeatable (grid) display, + * e.g. in a view listing many item (typically a "browse" task) + * + * @since 2.0 + * + * @return string The field HTML + */ + public function getRepeatable() + { + $class = $this->element['class'] ? (string) $this->element['class'] : $this->id; + $translate = $this->element['translate'] ? (string) $this->element['translate'] : false; + + $html = ''; + foreach ($this->value as $value) { + + $html .= ''; + + if ($translate == true) + { + $html .= JText::_($value); + } + else + { + $html .= $value; + } + + $html .= ''; + } + $html .= ''; + } + + /** + * Get the rendering of this field type for static display, e.g. in a single + * item view (typically a "read" task). + * + * @since 2.0 + * + * @return string The field HTML + */ + public function getInput() + { + // Used for J! 2.5 compatibility + $this->value = !is_array($this->value) ? explode(',', $this->value) : $this->value; + + return parent::getInput(); + } +} diff --git a/Sites/pages/libraries/fof/form/field/components.php b/Sites/pages/libraries/fof/form/field/components.php new file mode 100644 index 00000000..c3b519bd --- /dev/null +++ b/Sites/pages/libraries/fof/form/field/components.php @@ -0,0 +1,238 @@ +static)) + { + $this->static = $this->getStatic(); + } + + return $this->static; + break; + + case 'repeatable': + if (empty($this->repeatable)) + { + $this->repeatable = $this->getRepeatable(); + } + + return $this->repeatable; + break; + + default: + return parent::__get($name); + } + } + + /** + * Get the rendering of this field type for static display, e.g. in a single + * item view (typically a "read" task). + * + * @since 2.1 + * + * @return string The field HTML + */ + public function getStatic() + { + $class = $this->element['class'] ? ' class="' . (string) $this->element['class'] . '"' : ''; + + return '' . + htmlspecialchars(FOFFormFieldList::getOptionName($this->getOptions(), $this->value), ENT_COMPAT, 'UTF-8') . + ''; + } + + /** + * Get the rendering of this field type for a repeatable (grid) display, + * e.g. in a view listing many item (typically a "browse" task) + * + * @since 2.1 + * + * @return string The field HTML + */ + public function getRepeatable() + { + $class = $this->element['class'] ? (string) $this->element['class'] : ''; + + return '' . + htmlspecialchars(FOFFormFieldList::getOptionName($this->getOptions(), $this->value), ENT_COMPAT, 'UTF-8') . + ''; + } + + /** + * Get a list of all installed components and also translates them. + * + * The manifest_cache is used to get the extension names, since JInstaller is also + * translating those names in stead of the name column. Else some of the translations + * fails. + * + * @since 2.1 + * + * @return array An array of JHtml options. + */ + protected function getOptions() + { + $db = FOFPlatform::getInstance()->getDbo(); + + // Check for client_ids override + if ($this->client_ids !== null) + { + $client_ids = $this->client_ids; + } + else + { + $client_ids = $this->element['client_ids']; + } + + $client_ids = explode(',', $client_ids); + + // Calculate client_ids where clause + foreach ($client_ids as &$client_id) + { + $client_id = (int) trim($client_id); + $client_id = $db->q($client_id); + } + + $query = $db->getQuery(true) + ->select( + array( + $db->qn('name'), + $db->qn('element'), + $db->qn('client_id'), + $db->qn('manifest_cache'), + ) + ) + ->from($db->qn('#__extensions')) + ->where($db->qn('type') . ' = ' . $db->q('component')) + ->where($db->qn('client_id') . ' IN (' . implode(',', $client_ids) . ')'); + $db->setQuery($query); + $components = $db->loadObjectList('element'); + + // Convert to array of objects, so we can use sortObjects() + // Also translate component names with JText::_() + $aComponents = array(); + $user = JFactory::getUser(); + + foreach ($components as $component) + { + // Don't show components in the list where the user doesn't have access for + // TODO: perhaps add an option for this + if (!$user->authorise('core.manage', $component->element)) + { + continue; + } + + $oData = (object) array( + 'value' => $component->element, + 'text' => $this->translate($component, 'component') + ); + $aComponents[$component->element] = $oData; + } + + // Reorder the components array, because the alphabetical + // ordering changed due to the JText::_() translation + uasort( + $aComponents, + function ($a, $b) { + return strcasecmp($a->text, $b->text); + } + ); + + return $aComponents; + } + + /** + * Translate a list of objects with JText::_(). + * + * @param array $item The array of objects + * @param string $type The extension type (e.g. component) + * + * @since 2.1 + * + * @return string $text The translated name of the extension + * + * @see administrator/com_installer/models/extension.php + */ + public function translate($item, $type) + { + $platform = FOFPlatform::getInstance(); + + // Map the manifest cache to $item. This is needed to get the name from the + // manifest_cache and NOT from the name column, else some JText::_() translations fails. + $mData = json_decode($item->manifest_cache); + + if ($mData) + { + foreach ($mData as $key => $value) + { + if ($key == 'type') + { + // Ignore the type field + continue; + } + + $item->$key = $value; + } + } + + $lang = $platform->getLanguage(); + + switch ($type) + { + case 'component': + $source = JPATH_ADMINISTRATOR . '/components/' . $item->element; + $lang->load("$item->element.sys", JPATH_ADMINISTRATOR, null, false, false) + || $lang->load("$item->element.sys", $source, null, false, false) + || $lang->load("$item->element.sys", JPATH_ADMINISTRATOR, $lang->getDefault(), false, false) + || $lang->load("$item->element.sys", $source, $lang->getDefault(), false, false); + break; + } + + $text = JText::_($item->name); + + return $text; + } +} diff --git a/Sites/pages/libraries/fof/form/field/editor.php b/Sites/pages/libraries/fof/form/field/editor.php new file mode 100644 index 00000000..8c01e26d --- /dev/null +++ b/Sites/pages/libraries/fof/form/field/editor.php @@ -0,0 +1,97 @@ +static)) + { + $this->static = $this->getStatic(); + } + + return $this->static; + break; + + case 'repeatable': + if (empty($this->repeatable)) + { + $this->repeatable = $this->getRepeatable(); + } + + return $this->repeatable; + break; + + default: + return parent::__get($name); + } + } + + /** + * Get the rendering of this field type for static display, e.g. in a single + * item view (typically a "read" task). + * + * @since 2.0 + * + * @return string The field HTML + */ + public function getStatic() + { + $class = $this->element['class'] ? ' class="' . (string) $this->element['class'] . '"' : ''; + + return '
      ' . $this->value . '
      '; + } + + /** + * Get the rendering of this field type for a repeatable (grid) display, + * e.g. in a view listing many item (typically a "browse" task) + * + * @since 2.0 + * + * @return string The field HTML + */ + public function getRepeatable() + { + $class = $this->element['class'] ? (string) $this->element['class'] : ''; + + return '
      ' . $this->value . '
      '; + } +} diff --git a/Sites/pages/libraries/fof/form/field/email.php b/Sites/pages/libraries/fof/form/field/email.php new file mode 100644 index 00000000..e79ccca2 --- /dev/null +++ b/Sites/pages/libraries/fof/form/field/email.php @@ -0,0 +1,173 @@ +static)) + { + $this->static = $this->getStatic(); + } + + return $this->static; + break; + + case 'repeatable': + if (empty($this->repeatable)) + { + $this->repeatable = $this->getRepeatable(); + } + + return $this->repeatable; + break; + + default: + return parent::__get($name); + } + } + + /** + * Get the rendering of this field type for static display, e.g. in a single + * item view (typically a "read" task). + * + * @since 2.0 + * + * @return string The field HTML + */ + public function getStatic() + { + $class = $this->element['class'] ? ' class="' . (string) $this->element['class'] . '"' : ''; + $dolink = $this->element['show_link'] == 'true'; + $empty_replacement = ''; + + if ($this->element['empty_replacement']) + { + $empty_replacement = (string) $this->element['empty_replacement']; + } + + if (!empty($empty_replacement) && empty($this->value)) + { + $this->value = JText::_($empty_replacement); + } + + $innerHtml = htmlspecialchars($this->value, ENT_COMPAT, 'UTF-8'); + + if ($dolink) + { + $innerHtml = '' . + $innerHtml . ''; + } + + return '' . + $innerHtml . + ''; + } + + /** + * Get the rendering of this field type for a repeatable (grid) display, + * e.g. in a view listing many item (typically a "browse" task) + * + * @since 2.0 + * + * @return string The field HTML + */ + public function getRepeatable() + { + // Initialise + $class = ''; + $show_link = false; + $link_url = ''; + $empty_replacement = ''; + + // Get field parameters + if ($this->element['class']) + { + $class = (string) $this->element['class']; + } + + if ($this->element['show_link'] == 'true') + { + $show_link = true; + } + + if ($this->element['url']) + { + $link_url = $this->element['url']; + } + else + { + $link_url = 'mailto:' . htmlspecialchars($this->value, ENT_COMPAT, 'UTF-8'); + } + + if ($this->element['empty_replacement']) + { + $empty_replacement = (string) $this->element['empty_replacement']; + } + + // Get the (optionally formatted) value + if (!empty($empty_replacement) && empty($this->value)) + { + $this->value = JText::_($empty_replacement); + } + + $value = htmlspecialchars($this->value, ENT_COMPAT, 'UTF-8'); + + // Create the HTML + $html = ''; + + if ($show_link) + { + $html .= ''; + } + + $html .= $value; + + if ($show_link) + { + $html .= ''; + } + + $html .= ''; + + return $html; + } +} diff --git a/Sites/pages/libraries/fof/form/field/groupedbutton.php b/Sites/pages/libraries/fof/form/field/groupedbutton.php new file mode 100644 index 00000000..c6d5b292 --- /dev/null +++ b/Sites/pages/libraries/fof/form/field/groupedbutton.php @@ -0,0 +1,134 @@ +static)) + { + $this->static = $this->getStatic(); + } + + return $this->static; + break; + + case 'repeatable': + if (empty($this->repeatable)) + { + $this->repeatable = $this->getRepeatable(); + } + + return $this->repeatable; + break; + + default: + return parent::__get($name); + } + } + + /** + * Get the rendering of this field type for static display, e.g. in a single + * item view (typically a "read" task). + * + * @since 2.0 + * + * @return string The field HTML + */ + public function getStatic() + { + return $this->getInput(); + } + + /** + * Get the rendering of this field type for a repeatable (grid) display, + * e.g. in a view listing many item (typically a "browse" task) + * + * @since 2.0 + * + * @return string The field HTML + */ + public function getRepeatable() + { + return $this->getInput(); + } + + /** + * Get the rendering of this field type for static display, e.g. in a single + * item view (typically a "read" task). + * + * @since 2.0 + * + * @return string The field HTML + */ + public function getInput() + { + $class = $this->element['class'] ? (string) $this->element['class'] : ''; + + $html = '
      '; + + foreach ($this->element->children() as $option) + { + $renderedAttributes = array(); + + foreach ($option->attributes() as $name => $value) + { + if (!is_null($value)) + { + $renderedAttributes[] = $name . '="' . htmlentities($value) . '"'; + } + } + + $buttonXML = new SimpleXMLElement(''); + $buttonField = new FOFFormFieldButton($this->form); + + // Pass required objects to the field + $buttonField->item = $this->item; + $buttonField->rowid = $this->rowid; + $buttonField->setup($buttonXML, null); + + $html .= $buttonField->getRepeatable(); + } + $html .= '
      '; + + return $html; + } +} diff --git a/Sites/pages/libraries/fof/form/field/groupedlist.php b/Sites/pages/libraries/fof/form/field/groupedlist.php new file mode 100644 index 00000000..dcdba418 --- /dev/null +++ b/Sites/pages/libraries/fof/form/field/groupedlist.php @@ -0,0 +1,185 @@ +static)) + { + $this->static = $this->getStatic(); + } + + return $this->static; + break; + + case 'repeatable': + if (empty($this->repeatable)) + { + $this->repeatable = $this->getRepeatable(); + } + + return $this->repeatable; + break; + + default: + return parent::__get($name); + } + } + + /** + * Get the rendering of this field type for static display, e.g. in a single + * item view (typically a "read" task). + * + * @since 2.0 + * + * @return string The field HTML + */ + public function getStatic() + { + $class = $this->element['class'] ? (string) $this->element['class'] : ''; + + $selected = self::getOptionName($this->getGroups(), $this->value); + + if (is_null($selected)) + { + $selected = array( + 'group' => '', + 'item' => '' + ); + } + + return 'id . '-item" class="fof-groupedlist-item ' . $class . '>' . + htmlspecialchars($selected['item'], ENT_COMPAT, 'UTF-8') . + ''; + } + + /** + * Get the rendering of this field type for a repeatable (grid) display, + * e.g. in a view listing many item (typically a "browse" task) + * + * @since 2.0 + * + * @return string The field HTML + */ + public function getRepeatable() + { + $class = $this->element['class'] ? (string) $this->element['class'] : ''; + + $selected = self::getOptionName($this->getGroups(), $this->value); + + if (is_null($selected)) + { + $selected = array( + 'group' => '', + 'item' => '' + ); + } + + return '' . + htmlspecialchars($selected['group'], ENT_COMPAT, 'UTF-8') . + '' . + '' . + htmlspecialchars($selected['item'], ENT_COMPAT, 'UTF-8') . + ''; + } + + /** + * Gets the active option's label given an array of JHtml options + * + * @param array $data The JHtml options to parse + * @param mixed $selected The currently selected value + * @param string $groupKey Group name + * @param string $optKey Key name + * @param string $optText Value name + * + * @return mixed The label of the currently selected option + */ + public static function getOptionName($data, $selected = null, $groupKey = 'items', $optKey = 'value', $optText = 'text') + { + $ret = null; + + foreach ($data as $dataKey => $group) + { + $label = $dataKey; + $noGroup = is_int($dataKey); + + if (is_array($group)) + { + $subList = $group[$groupKey]; + $label = $group[$optText]; + $noGroup = false; + } + elseif (is_object($group)) + { + // Sub-list is in a property of an object + $subList = $group->$groupKey; + $label = $group->$optText; + $noGroup = false; + } + else + { + throw new RuntimeException('Invalid group contents.', 1); + } + + if ($noGroup) + { + $label = ''; + } + + $match = FOFFormFieldList::getOptionName($data, $selected, $optKey, $optText); + + if (!is_null($match)) + { + $ret = array( + 'group' => $label, + 'item' => $match + ); + break; + } + } + + return $ret; + } +} diff --git a/Sites/pages/libraries/fof/form/field/hidden.php b/Sites/pages/libraries/fof/form/field/hidden.php new file mode 100644 index 00000000..61c8e943 --- /dev/null +++ b/Sites/pages/libraries/fof/form/field/hidden.php @@ -0,0 +1,93 @@ +static)) + { + $this->static = $this->getStatic(); + } + + return $this->static; + break; + + case 'repeatable': + if (empty($this->repeatable)) + { + $this->repeatable = $this->getRepeatable(); + } + + return $this->repeatable; + break; + + default: + return parent::__get($name); + } + } + + /** + * Get the rendering of this field type for static display, e.g. in a single + * item view (typically a "read" task). + * + * @since 2.0 + * + * @return string The field HTML + */ + public function getStatic() + { + return $this->getInput(); + } + + /** + * Get the rendering of this field type for a repeatable (grid) display, + * e.g. in a view listing many item (typically a "browse" task) + * + * @since 2.0 + * + * @return string The field HTML + */ + public function getRepeatable() + { + return $this->getInput(); + } +} diff --git a/Sites/pages/libraries/fof/form/field/image.php b/Sites/pages/libraries/fof/form/field/image.php new file mode 100644 index 00000000..c909453c --- /dev/null +++ b/Sites/pages/libraries/fof/form/field/image.php @@ -0,0 +1,20 @@ +static)) + { + $this->static = $this->getStatic(); + } + + return $this->static; + break; + + case 'repeatable': + if (empty($this->repeatable)) + { + $this->repeatable = $this->getRepeatable(); + } + + return $this->repeatable; + break; + + default: + return parent::__get($name); + } + } + + /** + * Get the rendering of this field type for static display, e.g. in a single + * item view (typically a "read" task). + * + * @since 2.0 + * + * @return string The field HTML + */ + public function getStatic() + { + $imgattr = array( + 'id' => $this->id + ); + + if ($this->element['class']) + { + $imgattr['class'] = (string) $this->element['class']; + } + + if ($this->element['style']) + { + $imgattr['style'] = (string) $this->element['style']; + } + + if ($this->element['width']) + { + $imgattr['width'] = (string) $this->element['width']; + } + + if ($this->element['height']) + { + $imgattr['height'] = (string) $this->element['height']; + } + + if ($this->element['align']) + { + $imgattr['align'] = (string) $this->element['align']; + } + + if ($this->element['rel']) + { + $imgattr['rel'] = (string) $this->element['rel']; + } + + if ($this->element['alt']) + { + $alt = JText::_((string) $this->element['alt']); + } + else + { + $alt = null; + } + + if ($this->element['title']) + { + $imgattr['title'] = JText::_((string) $this->element['title']); + } + + $path = (string) $this->element['directory']; + $path = trim($path, '/' . DIRECTORY_SEPARATOR); + + if ($this->value && file_exists(JPATH_ROOT . '/' . $path . '/' . $this->value)) + { + $src = FOFPlatform::getInstance()->URIroot() . '/' . $path . '/' . $this->value; + } + else + { + $src = ''; + } + + return JHtml::_('image', $src, $alt, $imgattr); + } + + /** + * Get the rendering of this field type for a repeatable (grid) display, + * e.g. in a view listing many item (typically a "browse" task) + * + * @since 2.0 + * + * @return string The field HTML + */ + public function getRepeatable() + { + return $this->getStatic(); + } +} diff --git a/Sites/pages/libraries/fof/form/field/integer.php b/Sites/pages/libraries/fof/form/field/integer.php new file mode 100644 index 00000000..a00e34b3 --- /dev/null +++ b/Sites/pages/libraries/fof/form/field/integer.php @@ -0,0 +1,101 @@ +static)) + { + $this->static = $this->getStatic(); + } + + return $this->static; + break; + + case 'repeatable': + if (empty($this->repeatable)) + { + $this->repeatable = $this->getRepeatable(); + } + + return $this->repeatable; + break; + + default: + return parent::__get($name); + } + } + + /** + * Get the rendering of this field type for static display, e.g. in a single + * item view (typically a "read" task). + * + * @since 2.0 + * + * @return string The field HTML + */ + public function getStatic() + { + $class = $this->element['class'] ? ' class="' . (string) $this->element['class'] . '"' : ''; + + return '' . + htmlspecialchars($this->value, ENT_COMPAT, 'UTF-8') . + ''; + } + + /** + * Get the rendering of this field type for a repeatable (grid) display, + * e.g. in a view listing many item (typically a "browse" task) + * + * @since 2.0 + * + * @return string The field HTML + */ + public function getRepeatable() + { + $class = $this->element['class'] ? (string) $this->element['class'] : ''; + + return '' . + htmlspecialchars(FOFFormFieldList::getOptionName($this->getOptions(), $this->value), ENT_COMPAT, 'UTF-8') . + ''; + } +} diff --git a/Sites/pages/libraries/fof/form/field/language.php b/Sites/pages/libraries/fof/form/field/language.php new file mode 100644 index 00000000..4f822f93 --- /dev/null +++ b/Sites/pages/libraries/fof/form/field/language.php @@ -0,0 +1,122 @@ +static)) + { + $this->static = $this->getStatic(); + } + + return $this->static; + break; + + case 'repeatable': + if (empty($this->repeatable)) + { + $this->repeatable = $this->getRepeatable(); + } + + return $this->repeatable; + break; + + default: + return parent::__get($name); + } + } + + /** + * Method to get the field options. + * + * @since 2.0 + * + * @return array The field option objects. + */ + protected function getOptions() + { + $options = parent::getOptions(); + + $noneoption = $this->element['none'] ? $this->element['none'] : null; + + if ($noneoption) + { + array_unshift($options, JHtml::_('select.option', '*', JText::_($noneoption))); + } + + return $options; + } + + /** + * Get the rendering of this field type for static display, e.g. in a single + * item view (typically a "read" task). + * + * @since 2.0 + * + * @return string The field HTML + */ + public function getStatic() + { + $class = $this->element['class'] ? ' class="' . (string) $this->element['class'] . '"' : ''; + + return '' . + htmlspecialchars(FOFFormFieldList::getOptionName($this->getOptions(), $this->value), ENT_COMPAT, 'UTF-8') . + ''; + } + + /** + * Get the rendering of this field type for a repeatable (grid) display, + * e.g. in a view listing many item (typically a "browse" task) + * + * @since 2.0 + * + * @return string The field HTML + */ + public function getRepeatable() + { + $class = $this->element['class'] ? (string) $this->element['class'] : ''; + + return '' . + htmlspecialchars(FOFFormFieldList::getOptionName($this->getOptions(), $this->value), ENT_COMPAT, 'UTF-8') . + ''; + } +} diff --git a/Sites/pages/libraries/fof/form/field/list.php b/Sites/pages/libraries/fof/form/field/list.php new file mode 100644 index 00000000..043a288f --- /dev/null +++ b/Sites/pages/libraries/fof/form/field/list.php @@ -0,0 +1,383 @@ +static)) + { + $this->static = $this->getStatic(); + } + + return $this->static; + break; + + case 'repeatable': + if (empty($this->repeatable)) + { + $this->repeatable = $this->getRepeatable(); + } + + return $this->repeatable; + break; + + default: + return parent::__get($name); + } + } + + /** + * Get the rendering of this field type for static display, e.g. in a single + * item view (typically a "read" task). + * + * @since 2.0 + * + * @return string The field HTML + */ + public function getStatic() + { + $class = $this->element['class'] ? ' class="' . (string) $this->element['class'] . '"' : ''; + + return '' . + htmlspecialchars(self::getOptionName($this->getOptions(), $this->value), ENT_COMPAT, 'UTF-8') . + ''; + } + + /** + * Get the rendering of this field type for a repeatable (grid) display, + * e.g. in a view listing many item (typically a "browse" task) + * + * @since 2.0 + * + * @return string The field HTML + */ + public function getRepeatable() + { + $show_link = false; + $link_url = ''; + + $class = $this->element['class'] ? (string) $this->element['class'] : ''; + + if ($this->element['show_link'] == 'true') + { + $show_link = true; + } + + if ($this->element['url']) + { + $link_url = $this->element['url']; + } + else + { + $show_link = false; + } + + if ($show_link && ($this->item instanceof FOFTable)) + { + $link_url = $this->parseFieldTags($link_url); + } + else + { + $show_link = false; + } + + $html = ''; + + if ($show_link) + { + $html .= ''; + } + + $html .= htmlspecialchars(self::getOptionName($this->getOptions(), $this->value), ENT_COMPAT, 'UTF-8'); + + if ($show_link) + { + $html .= ''; + } + + $html .= ''; + + return $html; + } + + /** + * Gets the active option's label given an array of JHtml options + * + * @param array $data The JHtml options to parse + * @param mixed $selected The currently selected value + * @param string $optKey Key name + * @param string $optText Value name + * + * @return mixed The label of the currently selected option + */ + public static function getOptionName($data, $selected = null, $optKey = 'value', $optText = 'text') + { + $ret = null; + + foreach ($data as $elementKey => &$element) + { + if (is_array($element)) + { + $key = $optKey === null ? $elementKey : $element[$optKey]; + $text = $element[$optText]; + } + elseif (is_object($element)) + { + $key = $optKey === null ? $elementKey : $element->$optKey; + $text = $element->$optText; + } + else + { + // This is a simple associative array + $key = $elementKey; + $text = $element; + } + + if (is_null($ret)) + { + $ret = $text; + } + elseif ($selected == $key) + { + $ret = $text; + } + } + + return $ret; + } + + /** + * Method to get the field options. + * + * Ordering is disabled by default. You can enable ordering by setting the + * 'order' element in your form field. The other order values are optional. + * + * - order What to order. Possible values: 'name' or 'value' (default = false) + * - order_dir Order direction. Possible values: 'asc' = Ascending or 'desc' = Descending (default = 'asc') + * - order_case_sensitive Order case sensitive. Possible values: 'true' or 'false' (default = false) + * + * @return array The field option objects. + * + * @since Ordering is available since FOF 2.1.b2. + */ + protected function getOptions() + { + // Ordering is disabled by default for backward compatibility + $order = false; + + // Set default order direction + $order_dir = 'asc'; + + // Set default value for case sensitive sorting + $order_case_sensitive = false; + + if ($this->element['order'] && $this->element['order'] !== 'false') + { + $order = $this->element['order']; + } + + if ($this->element['order_dir']) + { + $order_dir = $this->element['order_dir']; + } + + if ($this->element['order_case_sensitive']) + { + // Override default setting when the form element value is 'true' + if ($this->element['order_case_sensitive'] == 'true') + { + $order_case_sensitive = true; + } + } + + // Create a $sortOptions array in order to apply sorting + $i = 0; + $sortOptions = array(); + + foreach ($this->element->children() as $option) + { + $name = JText::alt(trim((string) $option), preg_replace('/[^a-zA-Z0-9_\-]/', '_', $this->fieldname)); + + $sortOptions[$i] = new stdClass; + $sortOptions[$i]->option = $option; + $sortOptions[$i]->value = $option['value']; + $sortOptions[$i]->name = $name; + $i++; + } + + // Only order if it's set + if ($order) + { + jimport('joomla.utilities.arrayhelper'); + FOFUtilsArray::sortObjects($sortOptions, $order, $order_dir == 'asc' ? 1 : -1, $order_case_sensitive, false); + } + + // Initialise the options + $options = array(); + + // Get the field $options + foreach ($sortOptions as $sortOption) + { + $option = $sortOption->option; + $name = $sortOption->name; + + // Only add
      \n"; // Closes joomla-version div + } + + /** + * Loads the validation script for an edit form + * + * @param FOFForm &$form The form we are rendering + * + * @return void + */ + protected function loadValidationScript(FOFForm &$form) + { + $message = $form->getView()->escape(JText::_('JGLOBAL_VALIDATION_FORM_FAILED')); + + $js = <<getDocument(); + + if ($document instanceof JDocument) + { + $document->addScriptDeclaration($js); + } + } + + /** + * Renders the submenu (link bar) + * + * @param string $view The active view name + * @param string $task The current task + * @param FOFInput $input The input object + * @param array $config Extra configuration variables for the toolbar + * + * @return void + */ + protected function renderLinkbar($view, $task, $input, $config = array()) + { + $style = 'classic'; + + if (array_key_exists('linkbar_style', $config)) + { + $style = $config['linkbar_style']; + } + + if (!version_compare(JVERSION, '3.0', 'ge')) + { + $style = 'classic'; + } + + switch ($style) + { + case 'joomla': + $this->renderLinkbar_joomla($view, $task, $input); + break; + + case 'classic': + default: + $this->renderLinkbar_classic($view, $task, $input); + break; + } + } + + /** + * Renders the submenu (link bar) in FOF's classic style, using a Bootstrapped + * tab bar. + * + * @param string $view The active view name + * @param string $task The current task + * @param FOFInput $input The input object + * @param array $config Extra configuration variables for the toolbar + * + * @return void + */ + protected function renderLinkbar_classic($view, $task, $input, $config = array()) + { + if (FOFPlatform::getInstance()->isCli()) + { + return; + } + + // Do not render a submenu unless we are in the the admin area + $toolbar = FOFToolbar::getAnInstance($input->getCmd('option', 'com_foobar'), $config); + $renderFrontendSubmenu = $toolbar->getRenderFrontendSubmenu(); + + if (!FOFPlatform::getInstance()->isBackend() && !$renderFrontendSubmenu) + { + return; + } + + $links = $toolbar->getLinks(); + + if (!empty($links)) + { + echo "
        \n"; + + foreach ($links as $link) + { + $dropdown = false; + + if (array_key_exists('dropdown', $link)) + { + $dropdown = $link['dropdown']; + } + + if ($dropdown) + { + echo "'; + + echo ''; + + if ($link['icon']) + { + echo ""; + } + + echo $link['name']; + echo ''; + echo ''; + + echo "\n
          "; + + foreach ($link['items'] as $item) + { + echo ""; + + if ($item['icon']) + { + echo ""; + } + + if ($item['link']) + { + echo "" . $item['name'] . ""; + } + else + { + echo $item['name']; + } + + echo ""; + } + + echo "
        \n"; + } + else + { + echo ""; + + if ($link['icon']) + { + echo ""; + } + + if ($link['link']) + { + echo "" . $link['name'] . ""; + } + else + { + echo $link['name']; + } + } + + echo "\n"; + } + + echo "
      \n"; + } + } + + /** + * Renders the submenu (link bar) using Joomla!'s style. On Joomla! 2.5 this + * is a list of bar separated links, on Joomla! 3 it's a sidebar at the + * left-hand side of the page. + * + * @param string $view The active view name + * @param string $task The current task + * @param FOFInput $input The input object + * @param array $config Extra configuration variables for the toolbar + * + * @return void + */ + protected function renderLinkbar_joomla($view, $task, $input, $config = array()) + { + // On command line don't do anything + if (FOFPlatform::getInstance()->isCli()) + { + return; + } + + // Do not render a submenu unless we are in the the admin area + $toolbar = FOFToolbar::getAnInstance($input->getCmd('option', 'com_foobar'), $config); + $renderFrontendSubmenu = $toolbar->getRenderFrontendSubmenu(); + + if (!FOFPlatform::getInstance()->isBackend() && !$renderFrontendSubmenu) + { + return; + } + + $this->renderLinkbarItems($toolbar); + } + + /** + * do the rendering job for the linkbar + * + * @param FOFToolbar $toolbar A toolbar object + * + * @return void + */ + protected function renderLinkbarItems($toolbar) + { + $links = $toolbar->getLinks(); + + if (!empty($links)) + { + foreach ($links as $link) + { + JHtmlSidebar::addEntry($link['name'], $link['link'], $link['active']); + + $dropdown = false; + + if (array_key_exists('dropdown', $link)) + { + $dropdown = $link['dropdown']; + } + + if ($dropdown) + { + foreach ($link['items'] as $item) + { + JHtmlSidebar::addEntry('– ' . $item['name'], $item['link'], $item['active']); + } + } + } + } + } + + /** + * Renders the toolbar buttons + * + * @param string $view The active view name + * @param string $task The current task + * @param FOFInput $input The input object + * @param array $config Extra configuration variables for the toolbar + * + * @return void + */ + protected function renderButtons($view, $task, $input, $config = array()) + { + if (FOFPlatform::getInstance()->isCli()) + { + return; + } + + // Do not render buttons unless we are in the the frontend area and we are asked to do so + $toolbar = FOFToolbar::getAnInstance($input->getCmd('option', 'com_foobar'), $config); + $renderFrontendButtons = $toolbar->getRenderFrontendButtons(); + + // Load main backend language, in order to display toolbar strings + // (JTOOLBAR_BACK, JTOOLBAR_PUBLISH etc etc) + FOFPlatform::getInstance()->loadTranslations('joomla'); + + if (FOFPlatform::getInstance()->isBackend() || !$renderFrontendButtons) + { + return; + } + + $bar = JToolbar::getInstance('toolbar'); + $items = $bar->getItems(); + + $substitutions = array( + 'icon-32-new' => 'icon-plus', + 'icon-32-publish' => 'icon-eye-open', + 'icon-32-unpublish' => 'icon-eye-close', + 'icon-32-delete' => 'icon-trash', + 'icon-32-edit' => 'icon-edit', + 'icon-32-copy' => 'icon-th-large', + 'icon-32-cancel' => 'icon-remove', + 'icon-32-back' => 'icon-circle-arrow-left', + 'icon-32-apply' => 'icon-ok', + 'icon-32-save' => 'icon-hdd', + 'icon-32-save-new' => 'icon-repeat', + ); + + if(isset(JFactory::getApplication()->JComponentTitle)) + { + $title = JFactory::getApplication()->JComponentTitle; + } + else + { + $title = ''; + } + + $html = array(); + $actions = array(); + + // For BC we have to use the same id we're using inside other renderers (FOFHeaderHolder) + //$html[] = '
      '; + + $html[] = '
      '; + $html[] = '
      '.$title.'
      '; + $html[] = '
      '; + + foreach ($items as $node) + { + $type = $node[0]; + $button = $bar->loadButtonType($type); + + if ($button !== false) + { + if (method_exists($button, 'fetchId')) + { + $id = call_user_func_array(array(&$button, 'fetchId'), $node); + } + else + { + $id = null; + } + + $action = call_user_func_array(array(&$button, 'fetchButton'), $node); + $action = str_replace('class="toolbar"', 'class="toolbar btn"', $action); + $action = str_replace('', '', $action); + $action = str_replace(array_keys($substitutions), array_values($substitutions), $action); + $actions[] = $action; + } + } + + $html = array_merge($html, $actions); + $html[] = '
      '; + $html[] = '
      '; + + echo implode("\n", $html); + } + + /** + * Renders a FOFForm for a Browse view and returns the corresponding HTML + * + * @param FOFForm &$form The form to render + * @param FOFModel $model The model providing our data + * @param FOFInput $input The input object + * + * @return string The HTML rendering of the form + */ + protected function renderFormBrowse(FOFForm &$form, FOFModel $model, FOFInput $input) + { + $html = ''; + + JHtml::_('behavior.multiselect'); + + // Joomla! 3.0+ support + if (version_compare(JVERSION, '3.0', 'ge')) + { + JHtml::_('bootstrap.tooltip'); + JHtml::_('dropdown.init'); + JHtml::_('formbehavior.chosen', 'select'); + $view = $form->getView(); + $order = $view->escape($view->getLists()->order); + $html .= << + Joomla.orderTable = function() { + table = document.getElementById("sortTable"); + direction = document.getElementById("directionTable"); + order = table.options[table.selectedIndex].value; + if (order != '$order') + { + dirn = 'asc'; + } + else { + dirn = direction.options[direction.selectedIndex].value; + } + Joomla.tableOrdering(order, dirn); + }; + + +HTML; + } + else + { + JHtml::_('behavior.tooltip'); + } + + // Getting all header row elements + $headerFields = $form->getHeaderset(); + + // Get form parameters + $show_header = $form->getAttribute('show_header', 1); + $show_filters = $form->getAttribute('show_filters', 1); + $show_pagination = $form->getAttribute('show_pagination', 1); + $norows_placeholder = $form->getAttribute('norows_placeholder', ''); + + // Joomla! 3.0 sidebar support + + if (version_compare(JVERSION, '3.0', 'gt')) + { + $form_class = ''; + + if ($show_filters) + { + JHtmlSidebar::setAction("index.php?option=" . + $input->getCmd('option') . "&view=" . + FOFInflector::pluralize($input->getCmd('view')) + ); + } + + // Reorder the fields with ordering first + $tmpFields = array(); + $i = 1; + + foreach ($headerFields as $tmpField) + { + if ($tmpField instanceof FOFFormHeaderOrdering) + { + $tmpFields[0] = $tmpField; + } + + else + { + $tmpFields[$i] = $tmpField; + } + + $i++; + } + + $headerFields = $tmpFields; + ksort($headerFields, SORT_NUMERIC); + } + else + { + $form_class = 'class="form-horizontal"'; + } + + // Pre-render the header and filter rows + $header_html = ''; + $filter_html = ''; + $sortFields = array(); + + if ($show_header || $show_filters) + { + foreach ($headerFields as $headerField) + { + $header = $headerField->header; + $filter = $headerField->filter; + $buttons = $headerField->buttons; + $options = $headerField->options; + $sortable = $headerField->sortable; + $tdwidth = $headerField->tdwidth; + + // Under Joomla! < 3.0 we can't have filter-only fields + + if (version_compare(JVERSION, '3.0', 'lt') && empty($header)) + { + continue; + } + + // If it's a sortable field, add to the list of sortable fields + + if ($sortable) + { + $sortFields[$headerField->name] = JText::_($headerField->label); + } + + // Get the table data width, if set + + if (!empty($tdwidth)) + { + $tdwidth = 'width="' . $tdwidth . '"'; + } + else + { + $tdwidth = ''; + } + + if (!empty($header)) + { + $header_html .= "\t\t\t\t\t" . PHP_EOL; + $header_html .= "\t\t\t\t\t\t" . $header; + $header_html .= "\t\t\t\t\t" . PHP_EOL; + } + + if (version_compare(JVERSION, '3.0', 'ge')) + { + // Joomla! 3.0 or later + if (!empty($filter)) + { + $filter_html .= '\n"; + + if (!empty($buttons)) + { + $filter_html .= '
      ' . "\n"; + $filter_html .= "\t$buttons\n"; + $filter_html .= '
      ' . "\n"; + } + } + elseif (!empty($options)) + { + $label = $headerField->label; + + JHtmlSidebar::addFilter( + '- ' . JText::_($label) . ' -', (string) $headerField->name, + JHtml::_( + 'select.options', + $options, + 'value', + 'text', + $model->getState($headerField->name, ''), true + ) + ); + } + } + else + { + // Joomla! 2.5 + $filter_html .= "\t\t\t\t\t" . PHP_EOL; + + if (!empty($filter)) + { + $filter_html .= "\t\t\t\t\t\t$filter" . PHP_EOL; + + if (!empty($buttons)) + { + $filter_html .= '
      ' . PHP_EOL; + $filter_html .= "\t\t\t\t\t\t$buttons" . PHP_EOL; + $filter_html .= '
      ' . PHP_EOL; + } + } + elseif (!empty($options)) + { + $label = $headerField->label; + $emptyOption = JHtml::_('select.option', '', '- ' . JText::_($label) . ' -'); + array_unshift($options, $emptyOption); + $attribs = array( + 'onchange' => 'document.adminForm.submit();' + ); + $filter = JHtml::_('select.genericlist', $options, $headerField->name, $attribs, 'value', 'text', $headerField->value, false, true); + $filter_html .= "\t\t\t\t\t\t$filter" . PHP_EOL; + } + + $filter_html .= "\t\t\t\t\t" . PHP_EOL; + } + } + } + + // Start the form + $filter_order = $form->getView()->getLists()->order; + $filter_order_Dir = $form->getView()->getLists()->order_Dir; + $actionUrl = FOFPlatform::getInstance()->isBackend() ? 'index.php' : JUri::root().'index.php'; + + if (FOFPlatform::getInstance()->isFrontend() && ($input->getCmd('Itemid', 0) != 0)) + { + $itemid = $input->getCmd('Itemid', 0); + $uri = new JUri($actionUrl); + + if ($itemid) + { + $uri->setVar('Itemid', $itemid); + } + + $actionUrl = JRoute::_($uri->toString()); + } + + $html .= '
      ' . PHP_EOL; + + if (version_compare(JVERSION, '3.0', 'ge')) + { + // Joomla! 3.0+ + // Get and output the sidebar, if present + $sidebar = JHtmlSidebar::render(); + + if ($show_filters && !empty($sidebar)) + { + $html .= '
      ' . "\n"; + $html .= "\t$sidebar\n"; + $html .= "
      \n"; + $html .= '
      ' . "\n"; + } + else + { + $html .= '
      ' . "\n"; + } + + // Render header search fields, if the header is enabled + + if ($show_header) + { + $html .= "\t" . '
      ' . "\n"; + $html .= "$filter_html\n"; + + if ($show_pagination) + { + // Render the pagination rows per page selection box, if the pagination is enabled + $html .= "\t" . '
      ' . "\n"; + $html .= "\t\t" . '' . "\n"; + $html .= "\t\t" . $model->getPagination()->getLimitBox() . "\n"; + $html .= "\t" . '
      ' . "\n"; + } + + if (!empty($sortFields)) + { + // Display the field sort order + $asc_sel = ($view->getLists()->order_Dir == 'asc') ? 'selected="selected"' : ''; + $desc_sel = ($view->getLists()->order_Dir == 'desc') ? 'selected="selected"' : ''; + $html .= "\t" . '
      ' . "\n"; + $html .= "\t\t" . '' . "\n"; + $html .= "\t\t" . '' . "\n"; + $html .= "\t" . '
      ' . "\n\n"; + + // Display the sort fields + $html .= "\t" . '
      ' . "\n"; + $html .= "\t\t" . '' . "\n"; + $html .= "\t\t" . '' . "\n"; + $html .= "\t" . '
      ' . "\n"; + } + + $html .= "\t
      \n\n"; + $html .= "\t" . '
      ' . "\n\n"; + } + } + + // Start the table output + $html .= "\t\t" . '' . PHP_EOL; + + // Open the table header region if required + + if ($show_header || ($show_filters && version_compare(JVERSION, '3.0', 'lt'))) + { + $html .= "\t\t\t" . PHP_EOL; + } + + // Render the header row, if enabled + + if ($show_header) + { + $html .= "\t\t\t\t" . PHP_EOL; + $html .= $header_html; + $html .= "\t\t\t\t" . PHP_EOL; + } + + // Render filter row if enabled + + if ($show_filters && version_compare(JVERSION, '3.0', 'lt')) + { + $html .= "\t\t\t\t"; + $html .= $filter_html; + $html .= "\t\t\t\t"; + } + + // Close the table header region if required + + if ($show_header || ($show_filters && version_compare(JVERSION, '3.0', 'lt'))) + { + $html .= "\t\t\t" . PHP_EOL; + } + + // Loop through rows and fields, or show placeholder for no rows + $html .= "\t\t\t" . PHP_EOL; + $fields = $form->getFieldset('items'); + $num_columns = count($fields); + $items = $model->getItemList(); + + if ($count = count($items)) + { + $m = 1; + + foreach ($items as $i => $item) + { + $table_item = $model->getTable(); + $table_item->reset(); + $table_item->bind($item); + + $form->bind($item); + + $m = 1 - $m; + $class = 'row' . $m; + + $html .= "\t\t\t\t" . PHP_EOL; + + $fields = $form->getFieldset('items'); + + // Reorder the fields to have ordering first + if (version_compare(JVERSION, '3.0', 'gt')) + { + $tmpFields = array(); + $j = 1; + + foreach ($fields as $tmpField) + { + if ($tmpField instanceof FOFFormFieldOrdering) + { + $tmpFields[0] = $tmpField; + } + + else + { + $tmpFields[$j] = $tmpField; + } + + $j++; + } + + $fields = $tmpFields; + ksort($fields, SORT_NUMERIC); + } + + foreach ($fields as $field) + { + $field->rowid = $i; + $field->item = $table_item; + $labelClass = $field->labelClass ? $field->labelClass : $field->labelclass; // Joomla! 2.5/3.x use different case for the same name + $class = $labelClass ? 'class ="' . $labelClass . '"' : ''; + $html .= "\t\t\t\t\t' . PHP_EOL; + } + + $html .= "\t\t\t\t" . PHP_EOL; + } + } + elseif ($norows_placeholder) + { + $html .= "\t\t\t\t\n"; + } + + $html .= "\t\t\t" . PHP_EOL; + + // Render the pagination bar, if enabled, on J! 2.5 + if ($show_pagination && version_compare(JVERSION, '3.0', 'lt')) + { + $pagination = $model->getPagination(); + $html .= "\t\t\t" . PHP_EOL; + $html .= "\t\t\t\t\n"; + $html .= "\t\t\t" . PHP_EOL; + } + + // End the table output + $html .= "\t\t" . '
      " . $field->getRepeatable() . '
      "; + $html .= JText::_($norows_placeholder); + $html .= "
      "; + + if (($pagination->total > 0)) + { + $html .= $pagination->getListFooter(); + } + + $html .= "
      ' . PHP_EOL; + + // Render the pagination bar, if enabled, on J! 3.0+ + + if ($show_pagination && version_compare(JVERSION, '3.0', 'ge')) + { + $html .= $model->getPagination()->getListFooter(); + } + + // Close the wrapper element div on Joomla! 3.0+ + + if (version_compare(JVERSION, '3.0', 'ge')) + { + $html .= "
      \n"; + } + + $html .= "\t" . '' . PHP_EOL; + $html .= "\t" . '' . PHP_EOL; + $html .= "\t" . '' . PHP_EOL; + $html .= "\t" . '' . PHP_EOL; + + // The id field is required in Joomla! 3 front-end to prevent the pagination limit box from screwing it up. Huh!! + + if (version_compare(JVERSION, '3.0', 'ge') && FOFPlatform::getInstance()->isFrontend()) + { + $html .= "\t" . '' . PHP_EOL; + } + + $html .= "\t" . '' . PHP_EOL; + $html .= "\t" . '' . PHP_EOL; + $html .= "\t" . '' . PHP_EOL; + $html .= "\t" . '' . PHP_EOL; + + $html .= "\t" . '' . PHP_EOL; + + // End the form + $html .= '' . PHP_EOL; + + return $html; + } + + /** + * Renders a FOFForm for a Read view and returns the corresponding HTML + * + * @param FOFForm &$form The form to render + * @param FOFModel $model The model providing our data + * @param FOFInput $input The input object + * + * @return string The HTML rendering of the form + */ + protected function renderFormRead(FOFForm &$form, FOFModel $model, FOFInput $input) + { + $html = $this->renderFormRaw($form, $model, $input, 'read'); + + return $html; + } + + /** + * Renders a FOFForm for an Edit view and returns the corresponding HTML + * + * @param FOFForm &$form The form to render + * @param FOFModel $model The model providing our data + * @param FOFInput $input The input object + * + * @return string The HTML rendering of the form + */ + protected function renderFormEdit(FOFForm &$form, FOFModel $model, FOFInput $input) + { + // Get the key for this model's table + $key = $model->getTable()->getKeyName(); + $keyValue = $model->getId(); + + $html = ''; + + $validate = strtolower($form->getAttribute('validate')); + + if (in_array($validate, array('true', 'yes', '1', 'on'))) + { + JHtml::_('behavior.formvalidation'); + $class = ' form-validate'; + $this->loadValidationScript($form); + } + else + { + $class = ''; + } + + // Check form enctype. Use enctype="multipart/form-data" to upload binary files in your form. + $template_form_enctype = $form->getAttribute('enctype'); + + if (!empty($template_form_enctype)) + { + $enctype = ' enctype="' . $form->getAttribute('enctype') . '" '; + } + else + { + $enctype = ''; + } + + // Check form name. Use name="yourformname" to modify the name of your form. + $formname = $form->getAttribute('name'); + + if (empty($formname)) + { + $formname = 'adminForm'; + } + + // Check form ID. Use id="yourformname" to modify the id of your form. + $formid = $form->getAttribute('name'); + + if (empty($formid)) + { + $formid = 'adminForm'; + } + + // Check if we have a custom task + $customTask = $form->getAttribute('customTask'); + + if (empty($customTask)) + { + $customTask = ''; + } + + // Get the form action URL + $actionUrl = FOFPlatform::getInstance()->isBackend() ? 'index.php' : JUri::root().'index.php'; + + if (FOFPlatform::getInstance()->isFrontend() && ($input->getCmd('Itemid', 0) != 0)) + { + $itemid = $input->getCmd('Itemid', 0); + $uri = new JUri($actionUrl); + + if ($itemid) + { + $uri->setVar('Itemid', $itemid); + } + + $actionUrl = JRoute::_($uri->toString()); + } + + $html .= '
      ' . PHP_EOL; + $html .= "\t" . '' . PHP_EOL; + $html .= "\t" . '' . PHP_EOL; + $html .= "\t" . '' . PHP_EOL; + $html .= "\t" . '' . PHP_EOL; + + $html .= "\t" . '' . PHP_EOL; + + $html .= $this->renderFormRaw($form, $model, $input, 'edit'); + $html .= '
      '; + + return $html; + } + + /** + * Renders a raw FOFForm and returns the corresponding HTML + * + * @param FOFForm &$form The form to render + * @param FOFModel $model The model providing our data + * @param FOFInput $input The input object + * @param string $formType The form type e.g. 'edit' or 'read' + * + * @return string The HTML rendering of the form + */ + protected function renderFormRaw(FOFForm &$form, FOFModel $model, FOFInput $input, $formType) + { + $html = ''; + $tabHtml = array(); + + // Do we have a tabbed form? + $isTabbed = $form->getAttribute('tabbed', '0'); + $isTabbed = in_array($isTabbed, array('true', 'yes', 'on', '1')); + + foreach ($form->getFieldsets() as $fieldset) + { + if ($isTabbed && $this->isTabFieldset($fieldset)) + { + continue; + } + elseif ($isTabbed && isset($fieldset->innertab)) + { + $inTab = $fieldset->innertab; + } + else + { + $inTab = '__outer'; + } + + $tabHtml[$inTab][] = $this->renderFieldset($fieldset, $form, $model, $input, $formType, false); + } + + // If the form is tabbed, render the tabs bars + if ($isTabbed) + { + $html .= '' . "\n\n
      " . PHP_EOL; + + foreach ($form->getFieldsets() as $fieldset) + { + if (!$this->isTabFieldset($fieldset)) + { + continue; + } + + $html .= $this->renderFieldset($fieldset, $form, $model, $input, $formType, false, $tabHtml); + } + + $html .= "
      \n"; + } + + if (isset($tabHtml['__outer'])) + { + $html .= implode('', $tabHtml['__outer']); + } + + return $html; + } + + /** + * Renders a raw fieldset of a FOFForm and returns the corresponding HTML + * + * @param stdClass &$fieldset The fieldset to render + * @param FOFForm &$form The form to render + * @param FOFModel $model The model providing our data + * @param FOFInput $input The input object + * @param string $formType The form type e.g. 'edit' or 'read' + * @param boolean $showHeader Should I render the fieldset's header? + * + * @return string The HTML rendering of the fieldset + */ + protected function renderFieldset(stdClass &$fieldset, FOFForm &$form, FOFModel $model, FOFInput $input, $formType, $showHeader = true, &$innerHtml = null) + { + $html = ''; + + $fields = $form->getFieldset($fieldset->name); + + if (isset($fieldset->class)) + { + $class = 'class="' . $fieldset->class . '"'; + } + else + { + $class = ''; + } + + if (isset($innerHtml[$fieldset->name])) + { + $innerclass = isset($fieldset->innerclass) ? ' class="' . $fieldset->innerclass . '"' : ''; + + $html .= "\t" . '
      ' . PHP_EOL; + $html .= "\t\t" . '' . PHP_EOL; + } + else + { + $html .= "\t" . '
      ' . PHP_EOL; + } + + $isTabbedFieldset = $this->isTabFieldset($fieldset); + + if (isset($fieldset->label) && !empty($fieldset->label) && !$isTabbedFieldset) + { + $html .= "\t\t" . '

      ' . JText::_($fieldset->label) . '

      ' . PHP_EOL; + } + + foreach ($fields as $field) + { + $groupClass = $form->getFieldAttribute($field->fieldname, 'groupclass', '', $field->group); + + // Auto-generate label and description if needed + // Field label + $title = $form->getFieldAttribute($field->fieldname, 'label', '', $field->group); + $emptylabel = $form->getFieldAttribute($field->fieldname, 'emptylabel', false, $field->group); + + if (empty($title) && !$emptylabel) + { + $model->getName(); + $title = strtoupper($input->get('option') . '_' . $model->getName() . '_' . $field->id . '_LABEL'); + } + + // Field description + $description = $form->getFieldAttribute($field->fieldname, 'description', '', $field->group); + + /** + * The following code is backwards incompatible. Most forms don't require a description in their form + * fields. Having to use emptydescription="1" on each one of them is an overkill. Removed. + */ + /* + $emptydescription = $form->getFieldAttribute($field->fieldname, 'emptydescription', false, $field->group); + if (empty($description) && !$emptydescription) + { + $description = strtoupper($input->get('option') . '_' . $model->getName() . '_' . $field->id . '_DESC'); + } + */ + + if ($formType == 'read') + { + $inputField = $field->static; + } + elseif ($formType == 'edit') + { + $inputField = $field->input; + } + + if (empty($title)) + { + $html .= "\t\t\t" . $inputField . PHP_EOL; + + if (!empty($description) && $formType == 'edit') + { + $html .= "\t\t\t\t" . ''; + $html .= JText::_($description) . '' . PHP_EOL; + } + } + else + { + $html .= "\t\t\t" . '
      ' . PHP_EOL; + $html .= $this->renderFieldsetLabel($field, $form, $title); + $html .= "\t\t\t\t" . '
      ' . PHP_EOL; + $html .= "\t\t\t\t\t" . $inputField . PHP_EOL; + + if (!empty($description)) + { + $html .= "\t\t\t\t" . ''; + $html .= JText::_($description) . '' . PHP_EOL; + } + + $html .= "\t\t\t\t" . '
      ' . PHP_EOL; + $html .= "\t\t\t" . '
      ' . PHP_EOL; + } + } + + if (isset($innerHtml[$fieldset->name])) + { + $html .= "\t\t" . '
      ' . PHP_EOL; + $html .= implode('', $innerHtml[$fieldset->name]) . PHP_EOL; + $html .= "\t" . '
      ' . PHP_EOL; + } + else + { + $html .= "\t" . '
      ' . PHP_EOL; + } + + return $html; + } + + /** + * Renders a label for a fieldset. + * + * @param object $field The field of the label to render + * @param FOFForm &$form The form to render + * @param string $title The title of the label + * + * @return string The rendered label + */ + protected function renderFieldsetLabel($field, FOFForm &$form, $title) + { + $html = ''; + + $labelClass = $field->labelClass ? $field->labelClass : $field->labelclass; // Joomla! 2.5/3.x use different case for the same name + $required = $field->required; + + $tooltip = $form->getFieldAttribute($field->fieldname, 'tooltip', '', $field->group); + + if (!empty($tooltip)) + { + if (version_compare(JVERSION, '3.0', 'ge')) + { + static $loadedTooltipScript = false; + + if (!$loadedTooltipScript) + { + $js = <<getDocument(); + + if ($document instanceof JDocument) + { + $document->addScriptDeclaration($js); + } + + $loadedTooltipScript = true; + } + + $tooltipText = '' . JText::_($title) . '
      ' . JText::_($tooltip); + + $html .= "\t\t\t\t" . '