Example #1
0
 /**
  * Method to get a DatabaseQuery object for retrieving the data set from a database.
  *
  * @return  DatabaseQuery  A DatabaseQuery object to retrieve the data set.
  *
  * @since   1.0
  */
 protected function getListQuery()
 {
     $db = $this->getDb();
     $query = $db->getQuery(true);
     $query->select(array('id', 'username'));
     $query->from('#__users');
     $filter = $this->state->get('filter.search-user');
     if ($filter) {
         // Clean filter variable
         $filter = $db->quote('%' . $db->escape(StringHelper::strtolower($filter), true) . '%', false);
         $query->where($db->quoteName('username') . ' LIKE ' . $filter);
     }
     return $query;
 }
Example #2
0
 /**
  * This method processes a string and replaces all accented UTF-8 characters by unaccented
  * ASCII-7 "equivalents", whitespaces are replaced by hyphens and the string is lowercase.
  *
  * @param   string  $string    String to process
  * @param   string  $language  Language to transilterate to
  *
  * @return  string  Processed string
  *
  * @since   11.1
  */
 public static function stringURLSafe($string, $language = '')
 {
     // Remove any '-' from the string since they will be used as concatenaters
     $str = str_replace('-', ' ', $string);
     // Transliterate on the language requested (fallback to current language if not specified)
     $lang = $language == '' || $language == '*' ? JFactory::getLanguage() : JLanguage::getInstance($language);
     $str = $lang->transliterate($str);
     // Trim white spaces at beginning and end of alias and make lowercase
     $str = trim(StringHelper::strtolower($str));
     // Remove any duplicate whitespace, and ensure all characters are alphanumeric
     $str = preg_replace('/(\\s|[^A-Za-z0-9\\-])+/', '-', $str);
     // Trim dashes at beginning and end of alias
     $str = trim($str, '-');
     return $str;
 }
Example #3
0
 /**
  * Sets an inflected word in the cache.
  *
  * @param   string  $singular  The singular form of the word.
  * @param   string  $plural    The plural form of the word. If omitted, it is assumed the singular and plural are identical.
  *
  * @return  void
  *
  * @since   1.0
  */
 private function setCache($singular, $plural = null)
 {
     $singular = StringHelper::strtolower($singular);
     if ($plural === null) {
         $plural = $singular;
     } else {
         $plural = StringHelper::strtolower($plural);
     }
     $this->cache[$singular] = $plural;
 }
Example #4
0
 /**
  * Method to tokenize a text string.
  *
  * @param   string   $input   The input to tokenize.
  * @param   string   $lang    The language of the input.
  * @param   boolean  $phrase  Flag to indicate whether input could be a phrase. [optional]
  *
  * @return  array  An array of FinderIndexerToken objects.
  *
  * @since   2.5
  */
 public static function tokenize($input, $lang, $phrase = false)
 {
     static $cache;
     $store = StringHelper::strlen($input) < 128 ? md5($input . '::' . $lang . '::' . $phrase) : null;
     // Check if the string has been tokenized already.
     if ($store && isset($cache[$store])) {
         return $cache[$store];
     }
     $tokens = array();
     $quotes = html_entity_decode('&#8216;&#8217;&#39;', ENT_QUOTES, 'UTF-8');
     // Get the simple language key.
     $lang = static::getPrimaryLanguage($lang);
     /*
      * Parsing the string input into terms is a multi-step process.
      *
      * Regexes:
      *  1. Remove everything except letters, numbers, quotes, apostrophe, plus, dash, period, and comma.
      *  2. Remove plus, dash, period, and comma characters located before letter characters.
      *  3. Remove plus, dash, period, and comma characters located after other characters.
      *  4. Remove plus, period, and comma characters enclosed in alphabetical characters. Ungreedy.
      *  5. Remove orphaned apostrophe, plus, dash, period, and comma characters.
      *  6. Remove orphaned quote characters.
      *  7. Replace the assorted single quotation marks with the ASCII standard single quotation.
      *  8. Remove multiple space characters and replaces with a single space.
      */
     $input = StringHelper::strtolower($input);
     $input = preg_replace('#[^\\pL\\pM\\pN\\p{Pi}\\p{Pf}\'+-.,]+#mui', ' ', $input);
     $input = preg_replace('#(^|\\s)[+-.,]+([\\pL\\pM]+)#mui', ' $1', $input);
     $input = preg_replace('#([\\pL\\pM\\pN]+)[+-.,]+(\\s|$)#mui', '$1 ', $input);
     $input = preg_replace('#([\\pL\\pM]+)[+.,]+([\\pL\\pM]+)#muiU', '$1 $2', $input);
     $input = preg_replace('#(^|\\s)[\'+-.,]+(\\s|$)#mui', ' ', $input);
     $input = preg_replace('#(^|\\s)[\\p{Pi}\\p{Pf}]+(\\s|$)#mui', ' ', $input);
     $input = preg_replace('#[' . $quotes . ']+#mui', '\'', $input);
     $input = preg_replace('#\\s+#mui', ' ', $input);
     $input = StringHelper::trim($input);
     // Explode the normalized string to get the terms.
     $terms = explode(' ', $input);
     /*
      * If we have Unicode support and are dealing with Chinese text, Chinese
      * has to be handled specially because there are not necessarily any spaces
      * between the "words". So, we have to test if the words belong to the Chinese
      * character set and if so, explode them into single glyphs or "words".
      */
     if ($lang === 'zh') {
         // Iterate through the terms and test if they contain Chinese.
         for ($i = 0, $n = count($terms); $i < $n; $i++) {
             $charMatches = array();
             $charCount = preg_match_all('#[\\p{Han}]#mui', $terms[$i], $charMatches);
             // Split apart any groups of Chinese characters.
             for ($j = 0; $j < $charCount; $j++) {
                 $tSplit = StringHelper::str_ireplace($charMatches[0][$j], '', $terms[$i], false);
                 if (!empty($tSplit)) {
                     $terms[$i] = $tSplit;
                 } else {
                     unset($terms[$i]);
                 }
                 $terms[] = $charMatches[0][$j];
             }
         }
         // Reset array keys.
         $terms = array_values($terms);
     }
     /*
      * If we have to handle the input as a phrase, that means we don't
      * tokenize the individual terms and we do not create the two and three
      * term combinations. The phrase must contain more than one word!
      */
     if ($phrase === true && count($terms) > 1) {
         // Create tokens from the phrase.
         $tokens[] = new FinderIndexerToken($terms, $lang);
     } else {
         // Create tokens from the terms.
         for ($i = 0, $n = count($terms); $i < $n; $i++) {
             $tokens[] = new FinderIndexerToken($terms[$i], $lang);
         }
         // Create two and three word phrase tokens from the individual words.
         for ($i = 0, $n = count($tokens); $i < $n; $i++) {
             // Setup the phrase positions.
             $i2 = $i + 1;
             $i3 = $i + 2;
             // Create the two word phrase.
             if ($i2 < $n && isset($tokens[$i2])) {
                 // Tokenize the two word phrase.
                 $token = new FinderIndexerToken(array($tokens[$i]->term, $tokens[$i2]->term), $lang, $lang === 'zh' ? '' : ' ');
                 $token->derived = true;
                 // Add the token to the stack.
                 $tokens[] = $token;
             }
             // Create the three word phrase.
             if ($i3 < $n && isset($tokens[$i3])) {
                 // Tokenize the three word phrase.
                 $token = new FinderIndexerToken(array($tokens[$i]->term, $tokens[$i2]->term, $tokens[$i3]->term), $lang, $lang === 'zh' ? '' : ' ');
                 $token->derived = true;
                 // Add the token to the stack.
                 $tokens[] = $token;
             }
         }
     }
     if ($store) {
         $cache[$store] = count($tokens) > 1 ? $tokens : array_shift($tokens);
         return $cache[$store];
     } else {
         return count($tokens) > 1 ? $tokens : array_shift($tokens);
     }
 }
Example #5
0
 /**
  * This method implements unicode slugs instead of transliteration.
  *
  * @param   string  $string  String to process
  *
  * @return  string  Processed string
  *
  * @since   1.0
  */
 public static function stringUrlUnicodeSlug($string)
 {
     // Replace double byte whitespaces by single byte (East Asian languages)
     $str = preg_replace('/\\xE3\\x80\\x80/', ' ', $string);
     // Remove any '-' from the string as they will be used as concatenator.
     // Would be great to let the spaces in but only Firefox is friendly with this
     $str = str_replace('-', ' ', $str);
     // Replace forbidden characters by whitespaces
     $str = preg_replace('#[:\\#\\*"@+=;!><&\\.%()\\]\\/\'\\\\|\\[]#', " ", $str);
     // Delete all '?'
     $str = str_replace('?', '', $str);
     // Trim white spaces at beginning and end of alias and make lowercase
     $str = trim(StringHelper::strtolower($str));
     // Remove any duplicate whitespace and replace whitespaces by hyphens
     $str = preg_replace('#\\x20+#', '-', $str);
     return $str;
 }
Example #6
0
 /**
  * Function to convert a sef route to an internal URI
  *
  * @param   JUri  &$uri  The sef URI
  *
  * @return  string  Internal URI
  *
  * @since   3.2
  * @deprecated  4.0  Attach your logic as rule to the main parse stage
  */
 protected function parseSefRoute(&$uri)
 {
     $route = $uri->getPath();
     // Remove the suffix
     if ($this->app->get('sef_suffix')) {
         if ($suffix = pathinfo($route, PATHINFO_EXTENSION)) {
             $route = str_replace('.' . $suffix, '', $route);
         }
     }
     // Get the variables from the uri
     $vars = $uri->getQuery(true);
     // Handle an empty URL (special case)
     if (empty($route)) {
         // If route is empty AND option is set in the query, assume it's non-sef url, and parse apropriately
         if (isset($vars['option']) || isset($vars['Itemid'])) {
             return $this->parseRawRoute($uri);
         }
         $item = $this->menu->getDefault($this->app->getLanguage()->getTag());
         // If user not allowed to see default menu item then avoid notices
         if (is_object($item)) {
             // Set the information in the request
             $vars = $item->query;
             // Get the itemid
             $vars['Itemid'] = $item->id;
             // Set the active menu item
             $this->menu->setActive($vars['Itemid']);
             $this->setVars($vars);
         }
         return $vars;
     }
     // Parse the application route
     $segments = explode('/', $route);
     if (count($segments) > 1 && $segments[0] == 'component') {
         $vars['option'] = 'com_' . $segments[1];
         $vars['Itemid'] = null;
         $route = implode('/', array_slice($segments, 2));
     } else {
         // Get menu items.
         $items = $this->menu->getMenu();
         $found = false;
         $route_lowercase = StringHelper::strtolower($route);
         $lang_tag = $this->app->getLanguage()->getTag();
         // Iterate through all items and check route matches.
         foreach ($items as $item) {
             if ($item->route && StringHelper::strpos($route_lowercase . '/', $item->route . '/') === 0 && $item->type != 'menulink') {
                 // Usual method for non-multilingual site.
                 if (!$this->app->getLanguageFilter()) {
                     // Exact route match. We can break iteration because exact item was found.
                     if ($item->route == $route_lowercase) {
                         $found = $item;
                         break;
                     }
                     // Partial route match. Item with highest level takes priority.
                     if (!$found || $found->level < $item->level) {
                         $found = $item;
                     }
                 } elseif ($item->language == '*' || $item->language == $lang_tag) {
                     // Exact route match.
                     if ($item->route == $route_lowercase) {
                         $found = $item;
                         // Break iteration only if language is matched.
                         if ($item->language == $lang_tag) {
                             break;
                         }
                     }
                     // Partial route match. Item with highest level or same language takes priority.
                     if (!$found || $found->level < $item->level || $item->language == $lang_tag) {
                         $found = $item;
                     }
                 }
             }
         }
         if (!$found) {
             $found = $this->menu->getDefault($lang_tag);
         } else {
             $route = substr($route, strlen($found->route));
             if ($route) {
                 $route = substr($route, 1);
             }
         }
         if ($found) {
             $vars['Itemid'] = $found->id;
             $vars['option'] = $found->component;
         }
     }
     // Set the active menu item
     if (isset($vars['Itemid'])) {
         $this->menu->setActive($vars['Itemid']);
     }
     // Set the variables
     $this->setVars($vars);
     // Parse the component route
     if (!empty($route) && isset($this->_vars['option'])) {
         $segments = explode('/', $route);
         if (empty($segments[0])) {
             array_shift($segments);
         }
         // Handle component route
         $component = preg_replace('/[^A-Z0-9_\\.-]/i', '', $this->_vars['option']);
         if (count($segments)) {
             $crouter = $this->getComponentRouter($component);
             $vars = $crouter->parse($segments);
             $this->setVars($vars);
         }
     } else {
         // Set active menu item
         if ($item = $this->menu->getActive()) {
             $vars = $item->query;
         }
     }
     return $vars;
 }
Example #7
0
 /**
  * Transliterate function
  *
  * This method processes a string and replaces all accented UTF-8 characters by unaccented
  * ASCII-7 "equivalents".
  *
  * @param   string  $string  The string to transliterate.
  *
  * @return  string  The transliteration of the string.
  *
  * @since   11.1
  */
 public function transliterate($string)
 {
     if ($this->transliterator !== null) {
         return call_user_func($this->transliterator, $string);
     }
     $string = JLanguageTransliterate::utf8_latin_to_ascii($string);
     $string = StringHelper::strtolower($string);
     return $string;
 }
Example #8
0
 /**
  * Method to get the table of contents
  *
  * @return  array  Table of contents
  */
 public function &getToc()
 {
     if (!is_null($this->toc)) {
         return $this->toc;
     }
     // Get vars
     $lang_tag = $this->getLangTag();
     $help_search = $this->getHelpSearch();
     // New style - Check for a TOC JSON file
     if (file_exists(JPATH_BASE . '/help/' . $lang_tag . '/toc.json')) {
         $data = json_decode(file_get_contents(JPATH_BASE . '/help/' . $lang_tag . '/toc.json'));
         // Loop through the data array
         foreach ($data as $key => $value) {
             $this->toc[$key] = JText::_('COM_ADMIN_HELP_' . $value);
         }
         // Sort the Table of Contents
         asort($this->toc);
         return $this->toc;
     }
     // Get Help files
     jimport('joomla.filesystem.folder');
     $files = JFolder::files(JPATH_BASE . '/help/' . $lang_tag, '\\.xml$|\\.html$');
     $this->toc = array();
     foreach ($files as $file) {
         $buffer = file_get_contents(JPATH_BASE . '/help/' . $lang_tag . '/' . $file);
         if (!preg_match('#<title>(.*?)</title>#', $buffer, $m)) {
             continue;
         }
         $title = trim($m[1]);
         if (!$title) {
             continue;
         }
         // Translate the page title
         $title = JText::_($title);
         // Strip the extension
         $file = preg_replace('#\\.xml$|\\.html$#', '', $file);
         if ($help_search && StringHelper::strpos(StringHelper::strtolower(strip_tags($buffer)), StringHelper::strtolower($help_search)) === false) {
             continue;
         }
         // Add an item in the Table of Contents
         $this->toc[$file] = $title;
     }
     // Sort the Table of Contents
     asort($this->toc);
     return $this->toc;
 }
Example #9
0
 /**
  * Common function to process the filters for a query based on the model state
  *
  * @param   DatabaseQuery  $query  DatabaseQuery object
  *
  * @return  DatabaseQuery
  *
  * @since   1.0
  */
 private function processStateFilter(DatabaseQuery $query)
 {
     $db = $this->getDb();
     $filter = $this->getProject()->project_id;
     if ($filter) {
         $query->where($db->quoteName('a.project_id') . ' = ' . (int) $filter);
     }
     $filter = $this->state->get('filter.search');
     if ($filter) {
         $query = $this->processSearchFilter($query, $filter);
     }
     $filter = $this->state->get('filter.status');
     if ($filter) {
         $query->where($db->quoteName('a.status') . ' = ' . (int) $filter);
     }
     $filter = $this->state->get('filter.state');
     // State == 2 means "all".
     if (is_numeric($filter) && 2 != $filter) {
         $query->where($db->quoteName('s.closed') . ' = ' . (int) $filter);
     }
     $filter = $this->state->get('filter.priority');
     if ($filter) {
         $query->where($db->quoteName('a.priority') . ' = ' . (int) $filter);
     }
     $filter = $this->state->get('filter.user');
     if ($filter && is_numeric($filter)) {
         $username = $this->state->get('username');
         switch ($filter) {
             case 1:
                 $query->where($db->quoteName('a.opened_by') . ' = ' . $db->quote($username));
                 break;
             case 2:
                 // Join over the activities.
                 $query->join('LEFT', '#__activities AS ac ON a.issue_number = ac.issue_number');
                 $query->where($db->quoteName('ac.user') . ' = ' . $db->quote($username));
                 $query->where($db->quoteName('ac.project_id') . ' = ' . (int) $this->getProject()->project_id);
                 $query->group('a.issue_number');
                 break;
         }
     }
     $filter = $this->state->get('filter.created_by');
     if ($filter) {
         // Clean filter variable
         $filter = $db->quote('%' . $db->escape(StringHelper::strtolower($filter), true) . '%', false);
         $query->where($db->quoteName('a.opened_by') . ' LIKE ' . $filter);
     }
     $filter = $this->state->get('filter.category');
     if ($filter && is_numeric($filter)) {
         $categoryModel = new CategoryModel($db);
         // If the category filter equals -1, that means we want issues without category.
         if ($filter == -1) {
             $issues = $categoryModel->getIssueIdsWithCategory();
         } else {
             $issues = $categoryModel->getIssueIdsByCategory($filter);
         }
         if ($issues != null) {
             $issueId = array();
             foreach ($issues as $issue) {
                 $issueId[] = $issue->issue_id;
             }
             $issueId = implode(', ', $issueId);
         } else {
             $issueId = 0;
         }
         // Handle the no category filter
         if ($filter == -1) {
             $query->where($db->quoteName('a.id') . ' NOT IN (' . $issueId . ')');
         } else {
             $query->where($db->quoteName('a.id') . ' IN (' . $issueId . ')');
         }
     }
     $filter = $this->state->get('filter.label');
     if ($filter && is_numeric($filter)) {
         $query->where('FIND_IN_SET(' . $filter . ', ' . $db->quoteName('a.labels') . ')');
     }
     $filter = $this->state->get('filter.tests');
     if ($filter && is_numeric($filter)) {
         // Common query elements
         $query->leftJoin($db->quoteName('#__issues_tests', 'it') . 'ON a.id = it.item_id')->where($db->quoteName('a.has_code') . ' = 1')->group('a.issue_number');
         switch ($filter) {
             case 1:
                 $query->where($db->quoteName('it.result') . ' = 1')->having('COUNT(it.item_id) = 1');
                 break;
             case 2:
                 $query->where($db->quoteName('it.result') . ' = 1')->having('COUNT(it.item_id) > 1');
                 break;
             case 3:
                 $query->having('COUNT(it.item_id) = 0');
                 break;
         }
     }
     $filter = $this->state->get('filter.easytest');
     if ($filter && is_numeric($filter)) {
         $query->where($db->quoteName('a.easy') . ' = ' . (int) $filter);
     }
     return $query;
 }
Example #10
0
 /**
  * Get an item by alias
  *
  * @param   string  $alias  The alias of the category
  *
  * @return  object
  *
  * @since 1.0
  */
 public function getByAlias($alias = '')
 {
     $db = $this->getDb();
     $query = $db->getQuery(true);
     $projectId = $this->getProject()->project_id;
     $query->select('*')->from('#__issues_categories')->where($db->quoteName('project_id') . '=' . $projectId);
     $filter = new InputFilter();
     $alias = $filter->clean($alias, 'cmd');
     if ($alias) {
         $alias = $db->quote('%' . $db->escape(StringHelper::strtolower($alias), true) . '%', false);
         $query->where($db->quoteName('alias') . ' LIKE ' . $alias);
     }
     $item = $db->setQuery($query)->loadObject();
     return $item;
 }
Example #11
0
 /**
  * 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;
     while ($wordfound === false && $pos < $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) {
         return ($pos > 0 ? '...&#160;' : '') . StringHelper::substr($text, $pos, $chunk_size) . '&#160;...';
     } else {
         if (($wordpos = @StringHelper::strpos($text, ' ', $length)) !== false) {
             return StringHelper::substr($text, 0, $wordpos) . '&#160;...';
         } else {
             return StringHelper::substr($text, 0, $length);
         }
     }
 }
Example #12
0
 /**
  * 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();
     $filter = JFilterInput::getInstance();
     $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
         // 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());
 }
Example #13
0
 /**
  * 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 = StringHelper::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('&#8216;&#8217;&#39;', 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) ? $modifier : 'before';
                     }
                     break;
                     // Handle a taxonomy branch filter.
                 // 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)) {
                             // 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 = StringHelper::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('#\\"([^"]+)\\"#mi', $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 (StringHelper::trim(StringHelper::substr($input, 0, $pos))) {
                     $terms = array_merge($terms, explode(' ', StringHelper::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 = StringHelper::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.
                             // 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.
                             // 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 (!empty($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)) {
             // Get the operator mode.
             $op = array_search($terms[$i + 1], $operators);
             // Handle the AND operator.
             if ($op === 'AND' && 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 = 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)) !== false) {
                     unset($phrases[$pk]);
                 }
                 if (($pk = array_search($terms[$i + 2], $phrases)) !== false) {
                     unset($phrases[$pk]);
                 }
                 // Remove the processed terms.
                 unset($terms[$i]);
                 unset($terms[$i + 1]);
                 unset($terms[$i + 2]);
                 // Adjust the loop.
                 $i += 2;
                 continue;
             } 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 (count($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 (count($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)) !== false) {
                     unset($phrases[$pk]);
                 }
                 if (($pk = array_search($terms[$i + 2], $phrases)) !== false) {
                     unset($phrases[$pk]);
                 }
                 // Remove the processed terms.
                 unset($terms[$i]);
                 unset($terms[$i + 1]);
                 unset($terms[$i + 2]);
                 // Adjust the loop.
                 $i += 2;
                 continue;
             }
         } elseif (isset($terms[$i + 1]) && array_search($terms[$i], $operators) === '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 (count($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)) !== false) {
                 unset($phrases[$pk]);
             }
             // Remove the processed terms.
             unset($terms[$i]);
             unset($terms[$i + 1]);
             // Adjust the loop.
             $i++;
             continue;
         } elseif (isset($terms[$i + 1]) && array_search($terms[$i], $operators) === '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 (count($other->matches)) {
                 $this->excluded[] = $other;
             } else {
                 $this->ignored[] = $other;
             }
             // Remove the processed phrase if possible.
             if (($pk = array_search($terms[$i + 1], $phrases)) !== false) {
                 unset($phrases[$pk]);
             }
             // Remove the processed terms.
             unset($terms[$i]);
             unset($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)) !== false) {
             unset($terms[$pk]);
         }
         // Remove the processed phrase.
         unset($phrases[$i]);
     }
     /*
      * Handle any remaining tokens using the standard processing mechanism.
      */
     if (!empty($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 : true : false;
             // Add the token to the appropriate stack.
             if (count($token->matches) || $token->required) {
                 $this->included[] = $token;
                 $this->highlight = array_merge($this->highlight, array_keys($token->matches));
             } else {
                 $this->ignored[] = $token;
             }
         }
     }
     return true;
 }
Example #14
0
    /**
     * 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, ' . '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,' . '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'));
        // Process an Archived Article layout
        if ($this->getState('filter.published') == 2) {
            // If badcats is not null, this means that the article is inside an archived category
            // In this case, the state is set to 2 to indicate Archived (even if the article state is Published)
            $query->select($this->getState('list.select', 'CASE WHEN badcats.id is null THEN a.state ELSE 2 END AS state'));
        } else {
            /*
            Process non-archived layout
            If badcats is not null, this means that the article is inside an unpublished category
            In this case, the state is set to 0 to indicate Unpublished (even if the article state is Published)
            */
            $query->select($this->getState('list.select', 'CASE WHEN badcats.id is not null THEN 0 ELSE a.state END AS state'));
        }
        $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->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->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')->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');
        }
        // Join to check for category published state in parent categories up the tree
        $query->select('c.published, CASE WHEN badcats.id is null THEN c.published ELSE 0 END AS parents_published');
        $subquery = 'SELECT cat.id as id FROM #__categories AS cat JOIN #__categories AS parent ';
        $subquery .= 'ON cat.lft BETWEEN parent.lft AND parent.rgt ';
        $subquery .= 'WHERE parent.extension = ' . $db->quote('com_content');
        if ($this->getState('filter.published') == 2) {
            // Find any up-path categories that are archived
            // If any up-path categories are archived, include all children in archived layout
            $subquery .= ' AND parent.published = 2 GROUP BY cat.id ';
            // Set effective state to archived if up-path category is archived
            $publishedWhere = 'CASE WHEN badcats.id is null THEN a.state ELSE 2 END';
        } else {
            // Find any up-path categories that are not published
            // If all categories are published, badcats.id will be null, and we just use the article state
            $subquery .= ' AND parent.published != 1 GROUP BY cat.id ';
            // Select state to unpublished if up-path category is unpublished
            $publishedWhere = 'CASE WHEN badcats.id is null THEN a.state ELSE 0 END';
        }
        $query->join('LEFT OUTER', '(' . $subquery . ') AS badcats ON badcats.id = c.id');
        // Filter by access level.
        if ($access = $this->getState('filter.access')) {
            $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)) {
            // Use article state if badcats.id is null, otherwise, force 0 for unpublished
            $query->where($publishedWhere . ' = ' . (int) $published);
        } elseif (is_array($published)) {
            $published = ArrayHelper::toInteger($published);
            $published = implode(',', $published);
            // Use article state if badcats.id is null, otherwise, force 0 for unpublished
            $query->where($publishedWhere . ' 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 = ArrayHelper::toInteger($authorId);
            $authorId = implode(',', $authorId);
            if ($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 . ' >= DATE_SUB(' . $nowDate . ', INTERVAL ' . $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);
            $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 '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 tag.
        $tagId = $this->getState('filter.tag');
        if (!empty($tagId) && is_numeric($tagId)) {
            $query->where($db->quoteName('tagmap.tag_id') . ' = ' . (int) $tagId)->join('LEFT', $db->quoteName('#__contentitem_tag_map', 'tagmap') . ' ON ' . $db->quoteName('tagmap.content_item_id') . ' = ' . $db->quoteName('a.id') . ' AND ' . $db->quoteName('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;
    }
 /**
  * Import locations from TXT or XML file.
  * The TXT file comes from geodata.org
  * The XML file is generated by the current extension ( Crowdfunding )
  *
  * @param string $file    A path to file
  * @param array  $options
  */
 public function importLocations($file, array $options)
 {
     $ext = StringHelper::strtolower(JFile::getExt($file));
     if (strcmp($ext, 'xml') === 0) {
         $this->importLocationsXml($file, $options);
     } else {
         // Import from file.
         $this->importLocationsTxt($file, $options);
     }
 }
Example #16
0
 *
 * @copyright   Copyright (C) 2005 - 2016 Open Source Matters, Inc. All rights reserved.
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */
defined('_JEXEC') or die;
use Joomla\String\StringHelper;
// Get the mime type class.
$mime = !empty($this->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;
    // Find the position of the search term
    $pos = $term_length ? StringHelper::strpos(StringHelper::strtolower($this->result->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($this->result->description, ' ', $start > 0 ? $start - 1 : 0);
    $start = $space && $space < $pos ? $space + 1 : $start;
    $description = JHtml::_('string.truncate', StringHelper::substr($this->result->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));
}
?>

<li>