Search feature to CakePHP blog example
Hello everybody!
First of all I assume that you have read and tried the blog example form documentation http://book.cakephp.org/view/219/blog).
Setup
So to get things started, we need to download seachable behavior from (http://code.google.com/p/searchable-behaviour-for-cakephp). Then we copy the archive contents to the /app folder. To complete the installation process there is one more thing to do: create the search table. So we run the following sql code:
CREATE TABLE `search_index` (
`id` int(11) NOT NULL auto_increment,
`association_key` int(11) NOT NULL,
`model` varchar(128) collate utf8_unicode_ci NOT NULL,
`data` longtext collate utf8_unicode_ci NOT NULL,
`created` datetime NOT NULL,
`modified` datetime NOT NULL,
PRIMARY KEY (`id`),
KEY `association_key` (`association_key`,`model`),
FULLTEXT KEY `data` (`data`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
So we are set up now, ready to add our nice search feature!
The actual search
First we need to add the searchable behavior to Post model.
Model Class:
<?php
<?php
// app/models/post.php
class Post extends AppModel
{
var $name = 'Post';
var $actsAs = array ('Searchable');
var $validate = array(
'title' => array(
'rule' => array('minLength', 1)
),
'body' => array(
'rule' => array('minLength', 1)
)
);
}
?>
?>
To be able to search, we need to place a search box somewhere. Add the following snippet of code just after the page heading.
<?php
echo $form->create("Post",array('action' => 'search'));
echo $form->input("q", array('label' => 'Search for'));
echo $form->end("Search");
?>
We need to define the search action in our post controller.
<?php
function search() {
$this->set('results',$this->Post->search($this->data['Post']['q']));
}
?>
Finally we create the view for search results (which is just a slightly modified version of posts index):
View Template:
<?php // app/views/posts/search.ctp ?>
<h1>Blog posts</h1>
<?php
echo $form->create("Post",array('action' => 'search'));
echo $form->input("q", array('label' => 'Search for'));
echo $form->end("Search");
?>
<p><?php echo $html->link("Add Post", "/posts/add"); ?>
<table>
<tr>
<th>Id</th>
<th>Title</th>
<th>Action</th>
<th>Created</th>
</tr>
<!-- Here's where we loop through our $results array, printing out post info -->
<?php foreach ($results as $post): ?>
<tr>
<td><?php echo $post['Post']['id']; ?></td>
<td>
<?php echo $html->link($post['Post']['title'],'/posts/view/'.$post['Post']['id']);?>
</td>
<td>
<?php echo $html->link(
'Delete',
"/posts/delete/{$post['Post']['id']}",
null,
'Are you sure?'
)?>
<?php echo $html->link('Edit', '/posts/edit/'.$post['Post']['id']);?>
</td>
<td><?php echo $post['Post']['created']; ?></td>
</tr>
<?php endforeach; ?>
</table>
That's it! You now have a blog with a fully featured search engine.
For other ways of using the searchable behavior, check the project page on Google Code (http://code.google.com/p/searchable-behaviour-for-cakephp).








'You are not authorized to access this location'.
So i'm guessing it's a possibility my authorization system is faulty, but I don't really know where to look to fix it. Could someone please give me some advice and what the search function is actually accessing. e.g. post Model and post controller
Thanks in advance for your help
I did all the steps mentioned and i get this error when debug is 1
"Missing Database Tables"
Can anyone guide me on this.
Thanks
Kevin
I'm new to CakePHP and I'm trying to use this behaviour but I'm having some problems:
1- My Users table has the password attribute and this behaviour allow other users to search for passwords XD well they are hashed but I think this isn't a good ideia can I change that?
2- When I use saveAll only the last one saved goes to search_index table is there anyway to change this? :(
3- When I edit something on my models I can't search that field anymore what must I do? :/
Thanks,
Bruno Sampaio
I have following models - Brand and Product. I need to index both of them. Generally it works well, but...
When I use them in different controller with this initialization:
$uses = array('Brand', 'Product', ...)
it always index only brand name, but product name not; both are saved ok. and if I remove 'Brand' from $uses, it starts indexing 'Product'
anybody knows what this is?? how to solve it? cake bug? or behavior bug?
Thanks, help appreciated.
Tomas
Adding
var $recursive = 1;to the SearchIndex model fixed the problem.Undefined index: User [APP/models/behaviors/searchable.php, line 77] Invalid argument supplied for foreach() [APP/models/behaviors/searchable.php, line 78] SQL Error: 1048: Column 'association_key' cannot be null [CORE/cake/libs/model/datasources/dbo_source.php, line 525] Query: INSERT INTO `search_index` (`model`, `association_key`, `data`, `modified`, `created`) VALUES ('User', NULL, '', '2010-02-28 12:04:11', '2010-02-28 12:04:11')
Query: INSERT INTO `search_index` (`model`, `association_key`, `data`, `modified`, `created`) VALUES ('User', NULL, '', '2010-02-28 12:04:11', '2010-02-28 12:04:11')
Cannot modify header information - headers already sent by (output started at /home/xxx/example.com/cake/basics.php:307) [CORE/cake/libs/controller/controller.php, line 644]
So from what I can tell when I add a post something with the user model is conflicting with my add posts function. I would expect to see the query values start with the 'Post' model then the post id and then some data.
Is there something I need to do when using this behavior on two different models?
association_key id database is set to be "not null". I recomend you to change your indexData() function in every model to return 'false' if variable you want to index is null or not set - in my example I do index only 'Brand Name';
my example:
function indexData() {
if(isset($this->data['Brand']['name'])){
return $this->data['Brand']['name'];
}else {
return false;
}
}
For those who are getting empty results sets, I've just realised that it's because the search code creates an index table for itself, which it populates as you add and modify pages on the site. This means that any pages which were on the site when you added the search code won't be searched on - so you'll need to modify them or add new ones.
There are some functions below for having all existing data added into the search index.
http://code.google.com/p/searchable-behaviour-for-cakephp/issues/detail?id=1
<?php$this->set('results',$this->Post->search($this->data['Post']['q']));
?>
to this:
<?php
$this->set('results',$this->Post->search($this->data['Post']['q'], array('recursive' => 2)));
?>
As you can see, you can use the same options for "find" method as second parameter for search method.
In this example you will obtain the associated data to your Post model, in the result you will have 3 models (SearchIndex, Post and a associated model to post)
=).
great tutorial, thanks!
http://bakery.cakephp.org/articles/view/search-feature-to-cakephp-blog-example http://code.google.com/p/searchable-behaviour-for-cakephp/ but to no avail. basically i have table or a set of tables with appropriate associations among them. each table have an id and other related fields. some of the tables are admin, profile, country, state etc i have worked with the provided examples but it is returning an empty search_index table?. and i have some questions:
1. what is this association key? is it some kind of id of the tables we need to search?
2. there is a field association key provided in the tables but it has a different datatype in the two examples. why and which one would be correct.
3. what procedure should i employ to make the search work?
4. what customizations do i need to put in?
5. table: admin - id, fname(e.g 1,rahul)
state - id,admin_id (e.g 1,1)
locality - id, admin_id (e.g 1,1)
how do i get search for rahul in state-1 and locality-1 and how to search from associted tables of admin?
6. moreover after this text search feature i'm looking for a dropdown search feature using ajax. it would provide results after filtering the country, state, locality dropdown menus. please provide some tutorials, or elements, behaviour, plugins. any kind of help would be highly appreciable.
thanx & regards
rahul
My index.ctp table matches the search.ctp table. Do I need to add more fields to the search_index table? The foreach section in search reads:Warning (512): SQL Error: 1064: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'search' at line 1 [CORE\cake\libs\model\datasources\dbo_source.php, line 524]
Warning (2): Invalid argument supplied for foreach() [APP\views\posts\search.ctp, line 26]
<?php foreach ($results as $post): ?>
<tr>
<td><?php echo $post['Post']['id']; ?></td>
<td><?php echo $post['Post']['moveout']; ?></td>
<td><?php echo $post['Post']['movein']; ?></td>
<td><?php echo $html->link($post['Post']['address'],'/posts/view/'.$post['Post']['id']);?></td>
<td><?php echo $post['Post']['rsl']; ?></td>
<td><?php echo $post['Post']['notes']; ?></td>
<td><?php echo $post['Post']['created']; ?></td>
<td><?php echo $post['Post']['modified']; ?></td>
<td><?php echo $html->link(
'Delete',
"/posts/delete/{$post['Post']['id']}",
null,
'Are you sure?'
)?>
<?php echo $html->link('Edit', '/posts/edit/'.$post['Post']['id']);?>
</td>
</tr>
<?php endforeach; ?>
Any help would be extremely appreciated and thanks for writing this tutorial in the first place!
Any ideas why?
This tutorial does not discuss indexing Current data. To do that please visit:
http://code.google.com/p/searchable-behaviour-for-cakephp/issues/detail?id=1
The second post has a nice example of how to index your current data. Just change the models you want indexed. Execute the page. Voila.
Query: search
Warning: SQL Error: 1064: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'search' at line 1 in /home/jb/Desktop/cakeblog/cake/libs/model/datasources/dbo_source.php on line 439
Fatal error: Call to undefined method FormHelper::create() in /home/jb/Desktop/cakeblog/app/views/posts/search.ctp on line 4
The example above doesn't search the associated tables.
e.g .. suppose i have 2 tables as
1.listings - id,user_id (e.g 1,1)
2. users - id,name (e.g 1,abhishek)
Now if am looking for all listings by abhishek .. how do i do that search
Thanks in advance
Regards
Abhishek
How do i fetch data from associated tables. One more thing.. when i edit a record does the search index table get updated automatically ...
Regards
Abhishek Jain
Error: The requested address '/posts/search' was not found on this server.
edit: I found that setting debug level to 2 removes the error and instead i get the same null string error previously mentioned. Although the posted solution is poorly documented for newbies as well.
edit again: For those running into the same issue: I found the _index() function the solution is referring to as part of the downloaded searchable.php file stored under models/behaviours on line 70.
I read and practise all this tutorial's steps carrefully and double check it before being sure that search return nothing. I appreciate this, It looks useful way to set search machine on our web specially for cakephp programmer, but in fact the search return nothing.
Is there anybody having success with this? please let me know if there's something wrong or should be fixed in this tutorial.
really thank for you all who make this tutorial more clear and usefull
I can also write a tutorial that doesn't do what it's suppose to do (i.e. teach) but, like this article, it would not have been useful.
Here ends my bitter frustrated rant.
You're spamming. This is a tutorial about a search feature to cake, not a general help site. Try not to be so selfish (reading three comments above this, you would have seen this same answer). Go to http://groups.google.com/group/cake-php and ask there, possibly with something better than 'I don't know how to install cakephp'.
i've an little Question
I tried to understand the add.ctp from blog tutorial,
so i tried to implement it by myself
/app/views/posts/edit.ctp
How can i get the 2 Inputfields side by side not about each other. Is it a thing from the css?<h1>Edit Post</h1>
<?php
echo $form->create('Post', array('action' => 'edit'));
echo $form->input('title');
echo $form->input('body', array('rows' => '3'));
echo $form->input('id', array('type'=>'hidden'));
echo $form->end('Save Post');
?>
Many greetings
Marcus Radisch
Ok, now the problem is that you're spamming this tutorial: your question doesn't have anything to do with the subject of the tutorial. Go to http://groups.google.com/group/cake-php and ask the questions there.
But just because I'm nice: $form->input() is very thorough: it creates a div, a label and the input field. Try using just $form->text() and $form->textarea().
thanks a lot for the great help. My Question is now, i have an DB-Table with 2 Columns. How can i great an searchindex over the Table?
many greatings
Marcus Radisch
I understand you're not familiar with English, and that's not a problem. What is a problem is that you don't give us enough information to help you.
If you say 'I have a table with two columns, how can I get a searchindex', I'll answer 'read the tutorial and follow the instructions'. After all, they worked for me. Please say in detail what you've done, where you got stuck. 'It doesn't work' is not a good report.
Cheers
Adriano.
can everyone help me? I have added an Bug for this component under this link->http://code.google.com/p/searchable-behaviour-for-cakephp/issues/detail?id=9 Until this moment i don't found any solution
Many greeting
marcus radisch
now i tried it with the official Blog Tutorial, but there is no way it doesnt search. Can every help me a little bit
many greetings
Marcus Radisch
Try reading this link: http://code.google.com/p/searchable-behaviour-for-cakephp/issues/detail?id=2
I tried ist, but there is no change is the result search engine doesn't search.
Whats the reason? I' don't know. Do you have any ideas?
i've tried it with my own application(a very very simple dictionary) I implemented directly to this docu...
But the searchreslut is always empty....
What i have to do that the result is correct.
my translation DB is
CREATE TABLE translates (
id int(10) unsigned NOT NULL auto_increment,
language1 varchar(255) NOT NULL,
language2 varchar(255) NOT NULL,
created datetime default NULL,
modified datetime default NULL,
PRIMARY KEY (id)
);
The search_index is the same...
Can erveryone help me. If i search then is no error message...
Thanks
Many greetings
Marcus Radisch
Example:
I have a 'paintings' table (not the actual table/class name) that hasMany 'titles'. I'd like to search for one of the 'titles' (bonus points if that search can be done from the 'painting' views) and that the returned list showed the link to the actual 'painting', not to the 'title'.
I understand it's a lot to ask, so thanks in advance for _any_ help.
You say that «By default all varchar, char and text fields are indexed.»
But this is not true because getColumnTypes will say varchar is 'string'
$columns = $this->model->getColumnTypes();
so just add
if (isset($columns[$key]) && in_array($columns[$key],array('string','text','varchar','char'))) {...}
Thanks for the behavior, great work :D
Comments are closed for articles over a year old