PHP Classes

File: buscador_inc.php

Recommend this page to a friend!
  Classes of Patricio Cardó   Buscador   buscador_inc.php   Download  
File: buscador_inc.php
Role: Class source
Content type: text/plain
Description: class file
Class: Buscador
Crawl and search files and Web pages
Author: By
Last change: abrir_url method was fixed to open within security environments
Date: 13 years ago
Size: 17,872 bytes
 

Contents

Class file image Download
<?php class buscador{ // para definirlo durante el contructor public $convertir_enlace = "convertir_enlace_inc.php"; public $xhtml_parte = "xhtml_parte_inc.php"; public $bd = array(); // archivo con la función para buscar en base de datos private $extensor = array(); /* matriz de objetos para abrir archivos cada elemento es: "extensión del archivo"=> array( "src"=>"archivo donde se encuentra la clase", "func"=>"nombre de la función que devuelve html o texto plano" "args"=>argumento adicional al objeto de búsqueda para pasar a la func ) */ // para configurar una vez creado el objeto public $largo = 64; // número de caracteres en cada línea public $num_lineas = 2; public $pre_resalte = "<strong>"; public $post_resalte = "</strong>"; public $archivos = array(); // archivos donde buscar public $puntajes = array("title"=>5,"h1"=>4,"h2"=>3,"h3"=>2); public $excepto = array(); // lista de archivos y directorios a evitar public $admitidos = array("php","html"); /* lista de extensiones en las que se buscan, ordenadas según prioridad para la simplificación de resultados */ public $basepost = false; // generados por las funciones public $enl = false; // objeto de la clase convertir_enlace public $dom = false; // objeto de la clase xhtml_parte public $con = array(); // lista de frases a encontrar public $sin = array(); // lista de frases que hacen omitir a los resultados public $resultados = array(); public $log = array(); private $patron_i = ""; // expresión regular para $con private $patron_e = ""; // expresión regular para $sin function traslog(){ if($this->enl->log){ foreach($this->enl->log as $entry){ $this->log[] = $entry; } } if($this->dom->log){ foreach($this->dom->log as $entry){ $this->log[] = $entry; } } } function buscador(){ // cargar el objeto convertir_enlace // cargar los objetos para abrir distintas extensiones // incorporar archivo de clase y archivo que llama a $excepto // arg: url de clase convertir_enlace, url de clase xhtml_parte[, objeto de búsqueda en base de datos[, matriz de extensores]] $this->convertir_enlace = (func_num_args()>0)?func_get_arg(0):$this->convertir_enlace; $this->xhtml_parte = (func_num_args()>1)?func_get_arg(1):$this->xhtml_parte; if($this->incluir($this->convertir_enlace) && $this->incluir($this->xhtml_parte)){ $this->enl = new convertir_enlace($_SERVER["PHP_SELF"]); $this->dom = new xhtml_parte(); if(func_num_args()>2){ $bd = func_get_arg(2); if(is_array($bd) && isset($bd["func"]) && isset($bd["src"])){ if($this->incluir($bd["src"])){ $this->bd = $bd; } }else{ $this->log[] = 'buscador->bd must be an array like: array("src"=>"dbsearch.php","func"=>"dbsearchin"), where dbsearchin is a function which first argument is buscador object.'; } }; $this->extensor = (func_num_args()>3)?func_get_arg(3):$this->extensor; if(is_array($this->extensor)){ foreach($this->extensor as $ext=>$dat){ if(isset($dat["src"],$dat["func"])){ if(!$this->incluir($dat["src"]) || !function_exists($dat["func"])){ $this->log[] = "source file or function does not exists for extension ".$ext; unset($this->extensor[$ext]); } }else{ $this->log[] = "source file and function name must be setted for each extension manager"; } } }else{ $this->log[] = "extensor must be an array"; } }else{ return false; } } function incluir(){ if(func_num_args()>0){ $archivo = func_get_arg(0); if(file_exists($archivo)){ include_once($archivo); $rtrn = true; }else{ $error = "'".$archivo."' does not exists"; $this->log[] = $error; $rtrn = false; } }else{ $error = "archivo argument has not been defined"; $this->log[] = $error; $rtrn = false; } return $rtrn; } function discriminar(){ // separa frases positivas, negativas e indicadores especiales // arg: cadena if(func_num_args()>0){ $criterio = " ".func_get_arg(0)." "; $re_1 = '%\s(\x27[^\x27]+?\x27|\x22[^\x22]+?\x22|-|filetype:(\w+)|\S+)\s%ims'; if(preg_match_all($re_1,$criterio,$frases)){ $con = true; foreach($frases[1] as $k=>$fras){ if($frases[2][$k]!=""){ $this->admitidos = $frases[2][$k]; }elseif($fras=="-"){ $con = false; }else{ $frase = htmlentities($fras,ENT_NOQUOTES); if($con){ $this->patron_i .= (count($this->con)==0)?'':'|'; $this->patron_i .= '\b'.preg_quote($fras,'%');// las palabras deben comenzar en ocurrencias $this->con[] = preg_replace('%^[\x22\x27]|[\x22\x27]$%ms','',$frase); }else{ $this->patron_e .= (count($this->sin)==0)?'':'|'; $this->patron_e .= '\b'.$$this->excluidos.'\b';// las ocurrencias deben coincidir con la palabra $this->sin[] = preg_replace('%^[\x22\x27]|[\x22\x27]$%ms','',$frase); } } } $rtrn = true; }else{ $rtrn = false; $this->log[] = $criterio." no parece un criterio de b&uacute;squeda"; } }else{ $rtrn = false; $this->log[] = "Debe definirse criterio en discriminar(\$criterio)"; } return $rtrn; } function recorrer(){ // genera lista de rutas desde el directorio $actual_dir = (func_num_args()>0 && is_string(func_get_arg(0)))? $this->enl->desde_url(func_get_arg(0)):$this->enl->este["ruta"] ; if(is_dir($actual_dir)){ $dir = dir($actual_dir); if(count($this->admitidos)==0){ $this->log[]="there must be at least one extension to search on directoy; it may be declared throught ". "buscador->adimitidos or throught 'filetype:' at search criteria"; $rtrn = false; }else{ $actual_dir = preg_replace('%/$%','',$actual_dir); while(false!==($entrada=$dir->read())){ $ruta = $actual_dir."/".$entrada; if(!in_array($ruta,$this->excepto) && !in_array($entrada,$this->excepto) && $entrada != "." && $entrada != ".."){ if(is_file($ruta)){ $exten = preg_replace('%^.+\.(\w+)(?:[\?#].*)?$%ims','$1',$entrada); if(in_array($exten, $this->admitidos)){ $this->archivos[] = $this->enl->desde_ruta($ruta); } }elseif(is_dir($ruta)){ $this->log[] = "<br />Intentando entrar al directorio: ".$ruta; $this->recorrer($ruta); } } } } }else{ $this->log[] = $actual_dir." is not a valid directory"; } } function abrir_url(){ // obtener el texto de una url mediante get o post // arg: url/archivo, get/post if(func_num_args()>0){ $url = func_get_arg(0); $argum = (func_num_args()>1 )?func_get_arg(1):false; if (ini_get('allow_url_fopen') == '1') { // '1' if($argum && is_array($argum)){ $argumentos = http_build_query($argum); $opts = array('http' =>array( 'method' => 'POST', 'header' => 'Content-type: application/x-www-form-urlencoded', 'content' => $argumentos ) ); }else{ $opts = array('http' =>array('method' => 'GET')); } $context = stream_context_create($opts); $content = @file_get_contents($url,false,$context); if($content === false){ $content = ""; $this->log = "content of ".$url." cannot be getted"; } } else { $parsedUrl = parse_url($url); $host = $parsedUrl['host']; $path = (isset($parsedUrl['path']))?$parsedUrl['path']:'/'; $path .= (isset($parsedUrl['query']))?'?' . $parsedUrl['query']:''; $port = (isset($parsedUrl['port']))?$parsedUrl['port']:80; $timeout = 10; $content = ""; $fp = @fsockopen($host, $port, $errno, $errstr, $timeout); if (!$fp) { $$this->log[] = "$errstr ($errno) @ ".$url; $content = ""; } else { if($argum && is_array($argum)){ $metodo = "POST"; $argumentos = http_build_query($argum); $largocont = "Content-length: ".strlen($argumentos)."\r\n\r\n"; }else{ $metodo = "GET"; $argumentos = ""; $largocont = "Content-length: ".$_SERVER["HTTP_CONTENT_LENGTH"]."\r\n\r\n"; } $out = "$metodo /$path HTTP/1.1\r\n". "Accept: ".$_SERVER["HTTP_ACCEPT"]."\r\n". "Accept-Language: ".$_SERVER["HTTP_ACCEPT_LANGUAGE"]."\r\n". "Host: ".$_SERVER["HTTP_HOST"]."\r\n". "Referer: ".$_SERVER["HTTP_REFERER"]."\r\n". "Cookie: ".$_SERVER["HTTP_COOKIE"]."\r\n". "User-Agent: ".$_SERVER["HTTP_USER_AGENT"]."\r\n". "Content-type: ".$_SERVER["HTTP_CONTENT_TYPE"]."\r\n". "Accept-Encoding: ".$_SERVER["HTTP_ACCEPT_ENCODING"]."\r\n". "Accept-Charset: ".$_SERVER["HTTP_ACCEPT_CHARSET"]."\r\n". "Keep-Alive: ".$_SERVER["HTTP_KEEP_ALIVE"]."\r\n". "Connection: ".$_SERVER["HTTP_CONNECTION"]."\r\n". $largocont. $argumentos; fwrite($fp, $out); while (!feof($fp)) { $content .= fgets($fp, 128); } fclose( $fp ); $pos = strpos($content, "\r\n\r\n"); $content = substr($content, $pos + 4); } } $rtrn = $content; }else{ $this->log[] = "no argument for url in abrir_url"; $rtrn = false; } return $rtrn; } function oraciones(){ if(func_num_args()>0){ $texto = strip_tags(func_get_arg(0)); if(strlen($texto)<$this->largo){ $rtrn = $texto; }else{ $ll = 0; $frass = array(); foreach($this->con as $terio){ $pos = 0; $leng = strlen($terio); while($this->largo> ($leng + $pos)){ $pos = stripos($texto,$terio,($pos+$leng)); if($pos===false){ break; }else{ $frass[$pos]= $terio; } } } $lineas = ""; ksort($frass); $largotexto = strlen($texto); while($largotexto>$this->largo && $ll<$this->num_lineas){ $largo = strlen($texto); $maximo = 0; $actual = reset($frass); $pos = key($frass); if($pos+$this->largo > $largotexto){ $orac = substr($texto,-$this->largo); }else{ $orac = substr($texto,$pos,$this->largo); } while(next($frass)!==false){ $limite = $pos+$this->largo; $dens = 1; $it = 0; if(key($frass) < $limite){ $dens = 2; while(next($frass)!==false){ if(key($frass) < $limite){ $dens ++; }else{ break; } $it++; } for($i=0;$i<$it;$i++){ $actual = prev($frass); } } if($dens>$maximo){ $maximo=$dens; $orac = substr($texto,$pos,$this->largo); } $pos = key($frass); } $texto = str_replace($orac,'',$texto); $ll++; $lineas .= ($lineas)?"<br />":""; $lineas .= $orac; } $lineas = preg_replace('%\s+%ms',' ',$lineas); $lineas = preg_replace('%'.$this->patron_i.'%ims',$this->pre_resalte.'$0'.$this->post_resalte,$lineas); $rtrn = $lineas; } }else{ $this->log[] = "content is needed at oraciones(\$content)"; $rtrn = false; } return $rtrn; // redacta las oraciones a mostrar } function calidad(){ // dado el contenido, dar puntaje según $con y $puntajes if(func_num_args()>0){ $contenido = func_get_arg(0); $puntaje = 0; $encontrados = 0; $titulo = ""; if(is_string($contenido)){ if(strlen($contenido)>4){ $cont = strip_tags($contenido); /* */ if($this->patron_e == "" || !preg_match('%'.$this->patron_e.'%ims',$cont)){ $texto = $contenido; foreach($this->puntajes as $tag=>$pun){ $tags = $this->dom->etiquetas($texto,$tag,'*','*','nido'); foreach($tags as $t=>$c){ if(isset($c[2]) && preg_match_all('%'.$this->patron_i.'%ims',$c[2],$ma)){ $encontrados += count($ma); $puntaje += $pun * $encontrados; } } $texto = $this->dom->eliminar(false,$contenido,$tag); } $cont2 = strip_tags($texto);; if(preg_match_all('%'.$this->patron_i.'%ims',$cont2,$ma)){ $encontrados += count($ma); $puntaje += $encontrados; $titu = $this->dom->etiquetas($contenido,"title",false,false,'cont'); if(count($titu) > 0 && $titu[0] !=""){ $titulo = $titu[0]; } } } } $rtrn = array("puntaje"=>$puntaje,"encontrados"=>$encontrados,"titulo"=>$titulo); }else{ $this->log[] = "content must be a string at calidad(\$content)"; $rtrn = false; } }else{ $this->log[] = "content is needed at calidad(\$content)"; $rtrn = false; } return $rtrn; } function barrer(){ // uno a uno los archivos, revisar si existen. // Si son html abrirlos, si no convertirlos // Buscar que no estén los $sin // Ponderar según calidad() if(is_array($this->archivos)){ $rtrn = true; foreach($this->archivos as $archivo){ if(is_string($archivo)){ $file = $archivo; $param = false; }elseif(is_array($archivo) && isset($archivo[0]) && is_string($archivo[0]) && isset($archivo[1]) && is_array($archivo[1])){ $file = $archivo[0]; $param = $archivo[1]; }else{ $this->log[] = "wrong item definition at ".var_export($archivo,true); $file = false; } if($file){ $url = $this->enl->desde_ruta($file); $exten = preg_replace('%^.+\.(\w+)(?:[\?#].*)?$%ims','$1',$url); $contenido = $this->abrir_url($url,$param); if(array_key_exists($exten,$this->extensor)){ if(isset($this->extensor[$exten]["args"])){ $contenido = call_user_func($this->extensor[$exten]["func"], $contenido,$this,$this->extensor[$exten]["args"]); }else{ $contenido = call_user_func($this->extensor[$exten]["func"],$contenido,$this); } } $calidad = $this->calidad($contenido); if(is_array($calidad) && $calidad["encontrados"] > 0){ $calidad["titulo"] = ($calidad["titulo"]!="")?$calidad["titulo"]:$url; $calidad["oraciones"] = $this->oraciones($contenido); $calidad["url"] = $url; $this->resultados[]=$calidad; } } } }else{ $this->log[] = "\$buscador->archivos must be an array of string with url or ". "array with url and an array of arguments for post data"; $rtrn = false; } return $rtrn; } function por_enlaces(){ // permitiría moverse por los vínculos que hay en los documentos, de manera de sólo indicar el dominio y que busque allí if(func_num_args()>0){ $contenido = func_get_arg(0); } } function en_matriz($sin,$titulo,$orac){ $rtrn = false; foreach($this->resultados as $k=>$v){ if($k!=$sin && $v["titulo"]==$titulo && $v["oraciones"]==$orac){ $rtrn = true; break; } } return $rtrn; } function ordenar(){ $titulo = array(); $oraciones = array(); $url = array(); $puntaje = array(); $encont = array(); foreach ($this->resultados as $key => $row) { $titulo[$key] = $row['titulo']; $oraciones[$key] = $row['oraciones']; $url[$key] = $row['url']; $puntaje[$key] = $row['puntaje']; $encont[$key] = $row['encontrados']; } array_multisort($puntaje,SORT_DESC,$encont,SORT_DESC,$titulo,SORT_ASC,$oraciones, SORT_ASC, $url); $matriz = array(); foreach ($puntaje as $key => $row) { $matriz[]=array('titulo'=>$titulo[$key], 'oraciones'=>$oraciones[$key], 'url'=>$url[$key], 'puntaje'=>$puntaje[$key], 'encontrados'=>$encont[$key] ); } return $matriz; } function simplificar(){ // elimina las redundancias cuando encuentra por ej. html y un php que lo abre foreach($this->resultados as $kr=>$res){ foreach($this->resultados as $k=>$v){ if($k!=$kr && $v["titulo"]==$res["titulo"] && $v["oraciones"]==$res["orac"]){ $nombarch1 = basename($res["url"]); $exten1 = substr($nombarch1,strrpos(".",$nombarch1)); $nombarch2 = basename($v["url"]); $exten2 = substr($nombarch2,strrpos(".",$nombarch2)); // si la extensión primera está después en prioridad que la extensión segunda if(in_array($exten1,$this->admitidos) && in_array($exten2,$this->admitidos) && array_search($exten1,$this->admitidos) > array_search($exten2,$this->admitidos)){ unset($this->resultados[$kr]); }else{ unset($this->resultados[$k]); } } } } } function buscar(){ // argumentos: criterio, recorrer_directorio, simplificar if(func_num_args()>0){ $criterio = func_get_arg(0); if($this->discriminar($criterio)){ $recorr = (func_num_args()>1 && func_get_arg(1))?func_get_arg(1):false; if(is_string($recorr)){ $this->recorrer($recorr); }elseif($recorr){ $this->recorrer(); } $rtrn = array(); if(count($this->archivos)>0){ $this->barrer(); } if(isset($this->bd["func"]) && function_exists($this->bd["func"])){ $bdres = call_user_func($this->bd["func"],$this); if(is_array($bdres)){ $this->resultados = array_merge($this->resultados, $bdres); } } $rtrn = $this->resultados; }else{ $rtrn = false; } }else{ $rtrn = false; } $this->traslog(); return $rtrn; } } ?>