Location: PHPKode > projects > Knowledge Box > knowledgebox/classes/searchClass.php
<?php

  /*
   * Free IT Foundation
   * Free Technology Serving Knowledge
   * http://www.free-it-foundation.org
   * 
   * This file is part of Knowledge Box.
   * 
   * Knowledge Box 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 3 of the License, or
   * (at your option) any later version.
   * 
   * Knowledge Box 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 Knowledge Box.  If not, see <http://www.gnu.org/licenses/>.
   */


  /*
   * class
   * KBModuleSearch
   */
  class KBModuleSearch
  {

    /*
     * constructor
     */
    function KBModuleSearch ()
    {
      // void
    }    

    /*
     * getLastEntries ()
     */
    function getLastEntries ($base_id, $limit = KB_CONFIG_DEFAULT_LASTENTRIES, $contributor = false)
    {
      if ($contributor)
        return KBModuleEntry::getEntriesByBase ($base_id, $limit);
      else
        return KBModuleEntry::getVisibleEntriesByBase ($base_id, $limit);
    }
    
    /*
     * getResults ()
     */
    function getResults ($base_id, $keywords, $text = '', $field_id = -1, $contributor = false)
    {
      $results = array ();
      $relationsPerKeywords = array ();
      $entries = array ();
      $real_entries = array ();

      if (empty ($keywords))
        $real_entries = KBModuleSearch::getLastEntries ($base_id, -1, $contributor);

      else
      {
        // iterate over keywords
        foreach ($keywords as $keyword_id)
        {
          // relations
          $relations = KBModuleRelation::getRelationsByKeyword ($keyword_id);

          // init
          $relationsPerKeywords [$keyword_id] = array ();

          // iterate over relations
          foreach ($relations as $relation)
            $relationsPerKeywords [$keyword_id][$relation->getEntryId ()] = $keyword_id . '-' . $relation->getEntryId ();
        }

        // sort
        sort ($relationsPerKeywords);
      
        // intersect relations per keywords
        for ($i = 0; $i < count ($relationsPerKeywords); $i++)
        {
          $relations = $relationsPerKeywords [$i];

          if ($i == 0)
            $entries = $relations;

          else {
            // interset keys
            //php5: $entries = array_intersect_key ($entries, $relations);

            foreach ($entries as $key => $v) {
              if (!array_key_exists ($key, $relations))
                unset ($entries [$key]);
            }
          }
        }

        // by default, sort entries by key in reverse order
        krsort ($entries);
  
        // load entries
        foreach ($entries as $key => $void)
        {
          $entry = new KBModuleEntry ();
          $entry->load ($key);
          
          // is visible
          if ($contributor || (!$contributor && $entry->isVisible ()))
            $real_entries [] = $entry;
        }
      }

      // iterate
      foreach ($real_entries as $entry)
      {
        // if there's something to search and we don't find 
        // it in the entry name, search in the substances for it 
    	  if (strlen ($text) > 0)
        {
          // check in name
          $found = $field_id > 0 ? false : stripos ($entry->getName (), $text) !== false;

          // if we must only search in name stop here
          if ($field_id == 0 && !$found)
            continue;

          if ($field_id != -1 || !$found)
          {
            // search in the other fields
 		        $substances = KBModuleSubstance::getSubstancesByEntry ($entry->getId ());
		        foreach ($substances as $substance)
		        {
              $field = new KBModuleField ();
			        $field->load ($substance->getFieldId ());

              if ($field_id != -1 && $field->getId () != $field_id)
                  continue;

              switch ($field->getType ())
              {
                case KB_FIELD_TEXT:
                case KB_FIELD_HTML:
                case KB_FIELD_EMAIL:
                {
              	 if (stripos ($substance->getTextValue (), $text) !== false)
                    $found = true;
                  break;
                }
                case KB_FIELD_LINK:
                {
              	 if (stripos ($substance->getTextValue (), $text) !== false || stripos ($substance->getInformation (), $text) !== false)
                    $found = true;
                  break;
                }
                case KB_FIELD_FILE:
                {
                	if (stripos ($substance->getInformation (), $text) !== false)
                    $found = true;
                  break;
                }
                case KB_FIELD_DATE:
                {
                  // config
                  $configDateFormat = KBModuleConfig::getConfig ($entry->getBaseId (), KB_CONFIG_PROPERTY_DATEFORMAT);
                  $configDateSeparator = KBModuleConfig::getConfig ($entry->getBaseId (), KB_CONFIG_PROPERTY_DATESEPARATOR);
                
                  // search a range?
                  if (stripos ($text, ' to ') > 0)
                  {

                    // split dates
                    $dates = explode (' to ', $text);

                    // two dates
                    if (count ($dates) != 2)
                      break;

                    // clean input
                    $from = trim ($dates [0]);
                    $to = trim ($dates [1]);

                    // unformatted
                    $dateFrom = unformatDateAsInConfig ($from, $configDateFormat, $configDateSeparator);
                    $dateTo = unformatDateAsInConfig ($to, $configDateFormat, $configDateSeparator);

                    // check
                    if ((int) $substance->getTextValue () >= $dateFrom && (int) $substance->getTextValue () <= $dateTo)
                      $found = true;
                    break;
                  
                  // specific date
                  } else {

                    // unformatted
                    $date = unformatDateAsInConfig (trim ($text), $configDateFormat, $configDateSeparator);

                    // parts
                    if (stripos ($substance->getTextValue (), $date) !== false)
                      $found = true;
                    break;
                  }
                }
              }

              // found it, don't check in the other substances
              if ($found)
                break;
        	  }
          }

          // not found, skip keyword
          if (!$found)
            continue;
		    }

        $results [] = $entry;
      }
      
      // return
      return $results;
    }
    
    /*
     * getPaginatedResults ()
     */
    function getPaginatedResults ($entries, $index = 0, $pagination = KB_CONFIG_DEFAULT_RESULTS)
    {
      // prepare
      $paginated = array ();

      // pagination
      if ($pagination > 0)
      {
        for ($i = $index * $pagination; $i < ($index+1) * $pagination; $i++)
        {
          $entry = $entries [$i];
          
          if (is_object ($entry))
            $paginated [] = $entry;
        }
          
        // return paginated
        return $paginated;
      }

      // return results
      return $entries;
    }
    
    /*
     * getTotalPages ()
     */
    function getTotalPages ($entries, $pagination = KB_CONFIG_DEFAULT_RESULTS)
    {
      if ($pagination < 1)
        return 1;

      // count entries
      $elements = count ($entries);

      // get pages
      $pages = (int) ($elements / $pagination);

      // crumbs
      $crumbs = $elements % $pagination;
      
      return $crumbs > 0 ? $pages + 1 : $pages;
    }

    /*
     * makeSortUrl ()
     */
    function makeSortUrl ($element_id, $direction)
    {
      // get current url
      $url = urldecode ($_SERVER ['REQUEST_URI']);

      // cleanup what was used
      $url = preg_replace ('/[?&](sort|dir|inx)=[^&]*/', '', $url);

      // rebuild url
      $url .= (strpos ($url, '?') === false) ? '?' : '&';
      $url .= 'sort=' . $element_id;
      $url .= '&dir=' . $direction;
      $url .= '&inx=0';

      return $url;
    }

    /*
     * getElements ()
     */
    function getElements ($base_id)
    {
      return KBModuleElement::getElementsByBase ($base_id);
    }

  }
  // end of class


  /*
   * stripos ()
   * class helper method
   */
  if (!function_exists ("stripos"))
  {
    function stripos($str, $needle, $offset = 0)
    {
      return strpos(strtolower($str), strtolower($needle), $offset);
    }
  }

  /*
   * sortEntries ()
   * class helper method
   */
  function sortEntries ($a, $b)
  {
    $element_id = $_SESSION [KB_SEARCH_SORT_FIELD];
    $direction  = $_SESSION [KB_SEARCH_SORT_DIR];

    $element = new KBModuleElement ();
    $element->load ($element_id);
  
    $entry_a = ($direction == 'asc') ? $a : $b;
    $entry_b = ($direction == 'asc') ? $b : $a;
  
    // switch on element type
    switch ($element->getType ())
    {
      case KB_ELEMENT_ENTRY:
      {
        return strcasecmp ($entry_a->getName (), $entry_b->getName ());
        break;
      }
      case KB_ELEMENT_FIELD:
      {
        // get field
        $field = new KBModuleField ();
        $field->load ($element->getResourceId ());
    
        // get substance
        $substance_a = KBModuleSubstance::getSubstance ($entry_a->getId (), $field->getId ());
        $substance_b = KBModuleSubstance::getSubstance ($entry_b->getId (), $field->getId ());
      
        // switch field type
        switch ($field->getType ())
        {
          case KB_FIELD_TEXT:
          case KB_FIELD_EMAIL:
          case KB_FIELD_DATE:
          {
            return strcasecmp ($substance_a->getTextValue (), $substance_b->getTextValue ());
            break;
          }
          case KB_FIELD_FILE:
          case KB_FIELD_LINK:
          {
            return strcasecmp ($substance_a->getInformation (), $substance_b->getInformation ());
            break;
          }
        }
      }
      case KB_ELEMENT_KEYWORDS:
      {
        // get relations
        $relations_a = KBModuleRelation::getRelationsByEntry ($entry_a->getId ());
        $relations_b = KBModuleRelation::getRelationsByEntry ($entry_b->getId ());
      
        // get group
        $group = new KBModuleGroup ();
        $group->load ($element->getResourceId ());
            
        // get keywords
        $keywords = KBModuleKeyword::getKeywordsByGroup ($group->getId ());
        
        // init
        $key_a = '';
        $key_b = '';
        
        // keywords
        foreach ($keywords as $keyword)
        {
          // relations entry a
          foreach ($relations_a as $relation) {
            if ($keyword->getId () == $relation->getKeywordId ())
              $key_a .= $keyword->getName () . ' ; ';
          }
          
          // relations entry b
          foreach ($relations_b as $relation) {
            if ($keyword->getId () == $relation->getKeywordId ())
              $key_b .= $keyword->getName () . ' ; ';
          }
        }
        
        return strcasecmp ($key_a, $key_b);
      }
      case KB_ELEMENT_AGGREGATION:
      {
        // get relations
        $relations_a = KBModuleRelation::getRelationsByEntry ($entry_a->getId ());
        $relations_b = KBModuleRelation::getRelationsByEntry ($entry_b->getId ());
      
        // groups
        $groups = KBModuleGroup::getGroupsByBase ($element->getBaseId ());

        // init
        $key_a = '';
        $key_b = '';
        
        // iterate groups
        foreach ($groups as $group)
        {            
          // get keywords
          $keywords = KBModuleKeyword::getKeywordsByGroup ($group->getId ());
        
          // keywords
          foreach ($keywords as $keyword)
          {
            // relations entry a
            foreach ($relations_a as $relation) {
              if ($keyword->getId () == $relation->getKeywordId ())
                $key_a .= $keyword->getName () . ' ; ';
            }
          
            // relations entry b
            foreach ($relations_b as $relation) {
              if ($keyword->getId () == $relation->getKeywordId ())
                $key_b .= $keyword->getName () . ' ; ';
            }
          }
        }

        return strcasecmp ($key_a, $key_b);
      }
    }

    return 0;       
  }

?>
Return current item: Knowledge Box