PHP Classes
Icontem

File: relevant_search.php


  Search   All class groups All class groups   Latest entries Latest entries   Top 10 charts Top 10 charts   Newsletter Newsletter   Blog Blog   Forums Forums   Help FAQ Help FAQ  
  Login   Register  
Recommend this page to a friend! ReTweet ReTweet Stumble It! Stumble It! Bookmark in del.icio.us Bookmark in del.icio.us
  Classes of Andrey Nikishaev  >  Relevant Search in MySQL  >  relevant_search.php  
File: relevant_search.php
Role: Class source
Content type: text/plain
Description: class
Class: Relevant Search in MySQL
Compose SQL queries to perform database searches
 

Contents

Class file image Download
<?php

/**
 * Relevant Search
 * 
 */
ini_set('display_errors'1);
class 
RelevantSearch {
    
public $return=array();
    
public $db;
    
public $type;
    
public $generalQ=array();
    
public $restriction=array();
    
public $searchParams=array();
    
public $select=array();
    
public $tables=array();
    
public $links=array();
    
public $addedTables=array();
    
/**
     * Making connection with DB, setting UTF-8 relation 
     * and deafault General params relation type
     *
     * @param array $dbopt
     */
    
public function __construct($dbopt) {    
        
$this->db = new PDO("mysql:host=".$dbopt['host'].";dbname=".$dbopt['dbname'], $dbopt['login'], $dbopt['pass']);
        
$this->db->exec('SET NAMES UTF8');
        
$this->type='or';
    }
    
/**
     * Adding table to the search query
     *
     * @param string $name - table name
     * @param string $as - synonym of table
     */
    
public function addTable($name,$as) {
        
$this->tables[]=array("name"=>$name,"as"=>$as);
        
$this->addedTables[]=$as;
    }
    
/**
     * Add field wich will be selected for output
     *
     * @param string $base    - table name
     * @param mixed $name    - column name
     */
    
public function addSelect($base,$name) {
        if(
is_array($name)) {
            foreach(
$name as $el) {
                if(!
array_key_exists($base.".".$el,$this->select))
                
$this->select[$base.".".$el]=$base.".".$el." ".$base."_".$el;
            }
        } 
    }
    
/**
     * Add link between tables
     *
     * @param string $base1 - table1 where linking (where linking condition is placed)
     * @param string $link1 - column in table1 wich linked
     * @param string $base2    - table2 with what linking
     * @param string $link2    - column in table2 wich linked
     */
    
public function addLink($base1,$link1,$base2,$link2) {
        
$this->links[$base1]=$base1.".".$link1."=".$base2.".".$link2;
    }
    
/**
     * Adding Restriction to search
     *
     * @param string $table - table name
     * @param string $name    - column name
     * @param string $oper    - operator
     * @param string $value    - value
     * @param bool $date    - make date transformation
     * @param bool $date_format    - date format
     */
    
public function addRestriction($table,$name,$oper,$value,$date=false,$date_format="") {
        switch(
$oper) {
            case 
">":
                
$this->restriction[$table][]="$table.$name>$value";
                break;
            case 
"<":
                
$this->restriction[$table][]="$table.$name<$value";
                break;
            case 
"<=":
                
$this->restriction[$table][]="$table.$name<=$value";
                break;
            case 
">=":
                
$this->restriction[$table][]="$table.$name>=$value";
                break;
            case 
"=":
                
$this->restriction[$table][]="$table.$name='$value'";
                break;
            case 
"!=":
                
$this->restriction[$table][]="$table.$name!='$value'";
                break;
            case 
"like":
                
$this->restriction[$table][]="$table.$name like '".trim($value)."%'";
                break;
            case 
"between":
                if(
$date) {
                    
$this->restriction[$table][]="$table.$name between '".date($date_format,strtotime(trim($value[0])))."' and '".date($date_format,strtotime(trim($value[1])))."'";
                } else {
                    
$this->restriction[$table][]="$table.$name between '".trim($value[0])."' and '".trim($value[1])."'";
                }
                break;
        }
        
    }
    
/**
     * Adding General Search param
     *
     * @param string $table - table name
     * @param string $name    - column name
     * @param string $oper    - operator
     * @param string $value    - value
     * @param float $rate    - relevant rate
     * @param bool $date    - make date transformation
     * @param bool $date_format    - date format
     */
    
public function addGeneral($table,$name,$oper,$value,$rate,$date=false,$date_format="") {        
        
$false=false;
        if(!
is_array($value) && $date$value=date($date_format,strtotime(trim($value)));
        switch(
$oper) {
            case 
">":
                
$this->generalQ[]="$table.$name>$value";
                break;
            case 
"<":
                
$this->generalQ[]="$table.$name<$value";
                break;
            case 
"<=":
                
$this->generalQ[]="$table.$name<=$value";
                break;
            case 
">=":
                
$this->generalQ[]="$table.$name>=$value";
                break;
            case 
"=":
                
$this->generalQ[]="$table.$name='$value'";
                break;
            case 
"!=":
                
$this->generalQ[]="$table.$name!='$value'";
                break;
            case 
"like":
                
$this->generalQ[]="$table.$name like '".trim($value)."%'";
                break;
            case 
"between":
                if(
$date) {
                    
$this->generalQ[]="$table.$name between '".date($date_format,strtotime(trim($value[0])))."' and '".date($date_format,strtotime(trim($value[1])))."'";
                } else {
                    
$this->generalQ[]="$table.$name between '".trim($value[0])."' and '".trim($value[1])."'";
                }
                break;
            default:
                
$false=true;
                break;        
        }
        if(!
$false) {
            
$this->addSelect($table,array($name));
            
$this->searchParams[$table."_".$name][]=array($oper,$value,$rate,$date);
        }
    }
    
/**
     * Adding Bonus Search param
     *
     * @param string $table - table name
     * @param string $name    - column name
     * @param string $oper    - operator
     * @param string $value    - value
     */
    
public function addSecondary($table,$name,$oper,$value,$rate,$date=false) {
        
$this->addSelect($table,array($name));
        
$this->searchParams[$table."_".$name][]=array($oper,$value,$rate,$date);
    }
    
/**
     * Setting type of relation between General Search params
     *
     * @param string $type - 'or' or 'and'
     */
    
public function setType($type) {
        
$this->type=$type;
    }
    
/**
     * Make query and sort it by relevantion
     *
     * @return array - array of fetched query data sorted by relevantion
     */
    
public function make() {
    
$first=array_shift($this->tables);
        
$FROM=$first["name"]." ".$first["as"];
        
$JOINS='';        
        foreach(
$this->tables as $table) {
            
$RESTRICT=(count($this->restriction[$table['as']])>0)?" and (".implode(" and ",$this->restriction[$table['as']]).")":"";
            if(
strlen($RESTRICT)>0) {$JOIN=" JOIN ";} else {$JOIN=" LEFT JOIN ";}
            
$JOINS.=$JOIN.$table['name']." ".$table['as']." on (".$this->links[$table['as']].$RESTRICT.")";    
        }
        
$sql=
        
"        
        SELECT DISTINCT "
.implode(",",$this->select)." from ".$FROM.$JOINS."
        WHERE
        ( "
.implode(" ".$this->type." ",$this->generalQ)." )
        "
;
        
$query=$this->db->query($sql);
        
$res=$query->fetchAll();
        
$this->doRelevant($res);
        
krsort($this->return);
        return 
$this->return;
    }
    
/**
     * Sort fetched query by relevantion
     *
     * @param array $data - fetched query data
     */
    
private function doRelevant($data) {
        foreach(
$data as $el) {
            
$rel=0;
            foreach(
$this->searchParams as $k=>$v) {
                foreach(
$v as $val) {
                    switch(
$val[0]) {
                        case 
">":
                            if(
$el[$k]>$val[1]) $rel+=$val[2];
                            break;
                        case 
"<":
                            if(
$el[$k]<$val[1]) $rel+=$val[2];
                            break;
                        case 
"<=":
                            if(
$el[$k]<=$val[1]) $rel+=$val[2];
                            break;
                        case 
">=":
                            if(
$el[$k]>=$val[1]) $rel+=$val[2];
                            break;
                        case 
"=":
                            if(
$el[$k]==$val[1]) $rel+=$val[2];
                            break;
                        case 
"!=":
                            if(
$el[$k]!=$val[1]) $rel+=$val[2];
                            break;
                        case 
"like":
                            if(
mb_eregi("^".$val[1]."",trim($el[$k]))) $rel+=$val[2];
                            break;
                        case 
"between":
                            if(
$val[3]) {
                            if(
strtotime($el[$k])>=strtotime(trim($val[1][0])) &&  strtotime($el[$k])<=strtotime(trim($val[1][1]))) $rel+=$val[2];
                            } else {
                                if(
$el[$k]>=trim($val[1][0]) &&  $el[$k]<=trim($val[1][1])) $rel+=$val[2];
                            }
                            break;
                        
                    }        
                }    
            }
            
$this->return[(string)$rel][]=$el;
        }
    }
    
}
/**
 * Search
 * 
 */
class Search extends RelevantSearch {
    
    
public $tableData=array();
    
public $linked_to_table=array();
    
/**
     * Set DB connect params and tables info 
     *
     * @param array $dbopt - db params
     * @param array $tables - array of tables information
     */
    
public function __construct($dbopt,$tables) {
        
parent::__construct($dbopt);
        
$this->tableData=$tables;
    }
    
/**
     * Join the table to the search
     *
     * @param string $table - table name with linking table like "table_linked_to.table"
     */
    
public function Join($table) {
        if(
eregi("\.",$table)){
            
$tabls=explode(".",$table);
            
$this->addTable($this->tableData[$tabls[1]]['name'],$tabls[1]);
            if(
strlen($tabls[0])>0) {    
                
$this->linked_to_table[$tabls[1]]=$tabls[0];
            }
        } else {
            
$this->addTable($this->tableData[$table]['name'],$table);
        }
        
    }
    
/**
     * Run search query
     *
     * @return array - sorted array of data sorted by relevant desc
     */
    
public function find() {
        foreach(
$this->addedTables as $table) {
            
$this->addSelect($table,$this->tableData[$table]['out']);
            if(
array_key_exists($table,$this->linked_to_table)) {
                
$this->addLink(
                
$table,
                
$this->tableData[$table]["links"][$this->linked_to_table[$table]]['local'],
                
$this->linked_to_table[$table],
                
$this->tableData[$table]["links"][$this->linked_to_table[$table]]['foreign']
                );
            }
        }
        
        return 
$this->make();
    }
    
    
    
    
}

 
  Advertise on this site Advertise on this site   Site map Site map   Statistics Statistics   Site tips Site tips   Privacy policy Privacy policy   Contact Contact  

For more information send a message to :
info at phpclasses dot org.
Copyright (c) Icontem 1999-2009 PHP Classes - PHP Class Scripts
  PHP Book Reviews - Reviews of books and other products