Facebook Fanpage


  • Enviar formulario con ajax jquery

    En el siguiente ejemplo, os mostraré como enviar un formulario vía AJAX, este proceso facilitará las consultas necesarias a PHP, todo ello...
  • Descifrando la Seguridad: El Fascinante Mundo de los Criptosistemas de Clave Pública

    Entrada 1: La Revolución de la Criptografía Asimétrica¿Alguna vez te has preguntado cómo puedes enviar información confidencial a través de internet...
  • Cómo configurar un servidor FTP sobre CentOS 7

    Instalación y puesta en marcha de vsftpd Instalar vsftpd en CentOS 7 es sencillo, en esta versión todavía se sigue usando Yum, el gestor de...
  • Oracle Dumpdir – Import, Export y el uso de Directorios.

    Oracle Dumpdir  Import, Export y el uso de Directorios. Cuando tenemos diferentes objetos de la base, ya sea una tabla, datos, etc y...
  • Solución a ORA-65096: invalid common user or role name en Oracle

    Solución a ORA-65096: invalid common user or role name en Oracle Hola a todos, hoy explicaré como solucionar un problema común en Oracle al...
  • Asignar permisos correctos a carpetas 755 y ficheros 644 de forma masiva

    Asignar permisos correctos a carpetas 755 y ficheros 644 de forma masiva Por defecto, en el FTP de una web los permisos deben ser los siguientes:...
  • Publicar aplicación WAR/JSP/SERVLET/TOMCAT/MYSQL en servidor dedicado/vps cPanel

    Publicar aplicación war con conexión a mysql.1. Ingresar al cPanel2. En la opción "Mysql Bases de datos", crear una base de datos, un usuario de...
  • Generar jar con NetBeans incluyendo Bibliotecas Externas Java

    Hola amigos, después de buscar un poco acerca de como incluir las librerías que utilizamos en nuestros proyectos Java...
  • Subir imagen al servidor con Yii Framework y eliminar imagenes del servidor

    En esta ocacion les traigo la manera de como subir imagenes al servidor y una ves subidas las imagenes como eliminarlas del servidor, este ejemplo es...
  • crear host virtual

    Cómo crear un VirtualHost en ubuntu y apache En este post veremos qué es y cómo crear un virtual host utilizando ubuntu y apache. ¿Qué es un...
  • Enviar formulario con ajax jquery

    En el siguiente ejemplo, os mostraré como enviar un formulario vía AJAX, este proceso facilitará las consultas necesarias a PHP, todo ello...
  • Descifrando la Seguridad: El Fascinante Mundo de los Criptosistemas de Clave Pública

    Entrada 1: La Revolución de la Criptografía Asimétrica¿Alguna vez te has preguntado cómo puedes enviar información confidencial a través de internet...
Previous Next

viernes, 25 de enero de 2013

crear buscador en tii framework

pagina oficial : http://www.yiiframework.com/wiki/248/adding-search-to-yii-blog-example-using-zend-lucene/

Introduction 

For this tutorial I will add a search to the blog demo. The search would be based on Zend Lucene.

Requirements and Preparation 

  • Yii framework - I will work with the current version yii-1.1.8.r3324 extract the archive in your server...
  • Now go to your yii-1.1.8.r3324\demos\blog\protected directory and create there a vendors directory In vendors directory you should put Zend Framework library, For this you will need to download it After downloading copy the Zend directory that inside library (with Zend directory inside) to vendors Should look like this now (I copied only Search directory...):
  • add under runtime directory, a new one call it search, it will be used for the index files that Zend Lucene will create. Make sure it is writable!

Step 1 - adding the search form 

For this we will create a widget or if to be more specific a CPortlet! The most simple way is go to your components directory, create SearchBlock.php file And copy inside code from tag cloud. change class name to SearchBlock. Now lets insert it ! Go to views/layouts/column2.php add this, abouve the TagCloud widget
<?php
      $this->widget('SearchBlock', array(
      )); 
?>
after saving you will see 2 tag coulds in your main blog page... lets now edit it and change it to some search form
Now lets change the SearchBlog widget code...
<?php
 
Yii::import('zii.widgets.CPortlet');
 
class SearchBlock extends CPortlet
{
    public $title='Search';
 
    protected function renderContent()
    {
           echo CHtml::beginForm(array('search/search'), 'get', array('style'=> 'inline')) .
        CHtml::textField('q', '', array('placeholder'=> 'search...','style'=>'width:140px;')) .
        CHtml::submitButton('Go!',array('style'=>'width:30px;')) .
        CHtml::endForm('');
    }
}
It will look like this:

Creating SearchController 

Now lets add a SearchController
<?php
class SearchController extends Controller
{
    /**
     * @var string index dir as alias path from <b>application.</b>  , default to <b>runtime.search</b>
     */
    private $_indexFiles = 'runtime.search';
    /**
     * (non-PHPdoc)
     * @see CController::init()
     */
    public function init(){
        Yii::import('application.vendors.*');
        require_once('Zend/Search/Lucene.php');
        parent::init(); 
    }
 
    public function actionCreate()
    {
    }
 
    public function actionSearch()
    {
    }
}
As you can see in the init method we import Zend from vendors and we require the Search Lucene
It has two actions Search and Create For this tutorial I don't need more... but you can add update for example to update the search index ( of course you should implement it) etc.
It is a time to mention the documentation for Zend Lucene Here To do more advanced stuff, you will need to learn it
Also the api for the Lucene class

Creating Search Index 

This is an example of blog array after AR findAll
'id' => '2'
'title' => 'A Test Post'
'content' => 'a lot of text'
'tags' => 'test'
'status' => '2'
'create_time' => '1230952187'
'update_time' => '1230952187'
'author_id' => '1'
This is how we create the index:
/**
     * Search index creation
     */
    public function actionCreate()
    {
        $index = new Zend_Search_Lucene(Yii::getPathOfAlias('application.' . $this->_indexFiles), true);
 
        $posts = Post::model()->findAll();
        foreach($posts as $post){
            $doc = new Zend_Search_Lucene_Document();
 
            $doc->addField(Zend_Search_Lucene_Field::Text('title',
                                          CHtml::encode($post->title), 'utf-8')
            );
 
            $doc->addField(Zend_Search_Lucene_Field::Text('link',
                                            CHtml::encode($post->url)
                                                , 'utf-8')
            );   
 
            $doc->addField(Zend_Search_Lucene_Field::Text('content',
                                          CHtml::encode($post->content)
                                          , 'utf-8')
            );
 
 
            $index->addDocument($doc);
        }
        $index->commit();
        echo 'Lucene index created';
    }
First I found all the posts with Post::model()->findAll(); and than I added post to search index one by one, his content title and link fields
Now you should navigate to http://localhost/yii-1.1.8.r3324/demos/blog/index.php/search/create And you will see "Lucene index created"

Doing the search 

public function actionSearch()
    {
        $this->layout='column2';
         if (($term = Yii::app()->getRequest()->getParam('q', null)) !== null) {
            $index = new Zend_Search_Lucene(Yii::getPathOfAlias('application.' . $this->_indexFiles));
            $results = $index->find($term);
            $query = Zend_Search_Lucene_Search_QueryParser::parse($term);       
 
            $this->render('search', compact('results', 'term', 'query'));
        }
    }

Creating the view 

Create views/search/search.php add there
<?php
$this->pageTitle=Yii::app()->name . ' - Search results';
$this->breadcrumbs=array(
    'Search Results',
);
?>
 
<h3>Search Results for: "<?php echo CHtml::encode($term); ?>"</h3>
<?php if (!empty($results)): ?>
                <?php foreach($results as $result): 
?>                  
                    <p>Title: <?php echo $query->highlightMatches(CHtml::encode($result->title)); ?></p>
                    <p>Link: <?php echo CHtml::link($query->highlightMatches(CHtml::encode($result->link)), CHtml::encode($result->link)); ?></p>
                    <p>Content: <?php echo $query->highlightMatches(CHtml::encode($result->content)); ?></p>
                    <hr/>
                <?php endforeach; ?>
 
            <?php else: ?>
                <p class="error">No results matched your search terms.</p>
            <?php endif; ?>
As you can see because I passed to the view the $query, I can use Zend's highlightMatches ...
(if your search results not in english, you might have some encoding issues with highlightMatches, so you might consider using your own highlighter for greater flexibility and encoding issues free)
Also I created a real link from the linked I passed and created via $doc->addField(Zend_Search_Lucene_Field::Text('link' ...
And thats it try to search the word "it" And you will get:

Conclusion 

Now we are done, we have our search working... As you noticed I don't explained a lot about Zend Lucene itself... So you should look at the links I gave, and try to learn about it more!

Additional Links 

  1. larry ulman's artice about Zend Lucene
  2. Zend Lucene documentation
  3. Good article 1
  4. Good article 2
  5. Good articles 3

Bonus: Pagination with CPagination 

As some one here added in the comment, pagination can be a little tricky... You need to do some calculations by yourself...
Actually it is always a dilemma if to give you find the trick yourself, or give it to you directly...
There is a very big danger if you always get the answers for your problem from others... because in real time job, no one will do the job for you...
So this is how it would look with CPagination, after you figure out how to do the pagination of the result yourself:
(The page limit is 3 per page) 
So dont continue reading, until you spend some time thinking about it and trying your self!
Add to search
$pages = new CPagination(count($results));
$currentPage = Yii::app()->getRequest()->getQuery('page', 1);
$pages->pageSize = 3;
In the view change the foreach view with for
<?php for($i = $currentPage * $pages->pageSize - $pages->pageSize, $end = $currentPage * $pages->pageSize; $i<$end;$i++):
?>                  
                    <p>Title: <?php echo $query->highlightMatches(CHtml::encode($results[$i]->title)); ?></p>
                    <p>Link: <?php echo CHtml::link($query->highlightMatches(CHtml::encode($results[$i]->link)), CHtml::encode($results[$i]->link)); ?></p>
                    <p>Content: <?php echo $query->highlightMatches(CHtml::encode($results[$i]->content)); ?></p>
                    <hr/>
                <?php endfor; ?>
and add after this
<?php $this->widget('CLinkPager', array(
    'pages' => $pages,
)) ?>
It is not perfect, but it is the start. The problems you should think about are: what to do if some one tries to access page number 40 ? now it will throw error 500
What will happen if you have 2 pages, but only 4 records? You will get undefind ofsset errors...
Consider this as homework ;-)
p.s. don't forget to add some blog posts or you will have nothing to paginate ;-)

Another pagination solution 

Actually if you want it pass between pages via ajax, and don't handle the offset issues etc. ( it is easy but... we still most likly want ajax)
So you can consider doing the pagination via CArrayDataProvider You have there example http://www.yiiframework.com/doc/api/1.1/CArrayDataProvider Just pass the result array than you can create CListView with some basic view for search result element, and you are done... CArrayDataProvider will do all the dirty work for you!

0 comentarios:

Publicar un comentario