<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>HirdWeb &#187; queries</title>
	<atom:link href="http://www.hirdweb.com/tag/queries/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.hirdweb.com</link>
	<description>Another Blog clogging up the already crowded internet</description>
	<lastBuildDate>Wed, 28 Jul 2010 16:05:05 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Queries using CakePHP find()</title>
		<link>http://www.hirdweb.com/2008/08/18/queries-using-cakephp-find/</link>
		<comments>http://www.hirdweb.com/2008/08/18/queries-using-cakephp-find/#comments</comments>
		<pubDate>Mon, 18 Aug 2008 17:51:09 +0000</pubDate>
		<dc:creator>stephen</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[cakePHP]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[queries]]></category>

		<guid isPermaLink="false">http://www.hirdweb.com/?p=35</guid>
		<description><![CDATA[CakePHP now has deprecated some queries. The findALL, findCount, etc etc etc. This now uses the find() method for all of these, and has a basic syntax for this. If it is basic, why blog about it then? Good question. The documentation is there in the API, and is there in the Cookbook, it took [...]]]></description>
			<content:encoded><![CDATA[<p>CakePHP now has deprecated some queries. The findALL, findCount, etc etc etc. This now uses the find() method for all of these, and has a basic syntax for this. If it is basic, why blog about it then? Good question. The documentation is there in the <a href="http://api.cakephp.org/class_model.html#e60758f27fa8486a063b8cc424bad741">API</a>, and is there in the <a href="http://book.cakephp.org/view/73/retrieving-your-data">Cookbook</a>, it took me some time to really get a good idea on an applicable example and took many times of &#8220;trial and error&#8221; to help me get along. Because finding is good, and will give you all the information you need, if it is a simple, 1 table find. If you need to query two or three tables, how does this work. So this will go into those as well. </p>
<p>The basic idea of find, as listed by the API is this:</p>
<pre>
find(
	array $conditions,
	array $fields,
	string $order,
	int $recursive
);
</pre>
<p>This will find one record based on conditions, return the desired fields (or all of them if nothing is specified), order the results, and go so many levels deep (-1 for just the current table).<br />
<span id="more-35"></span></p>
<p>To get all the results instead of just one field, you would follow this:</p>
<pre>
find(
	string $notation_find,
	array(
		array $conditions,
		array $fields,
		string $order,
		int $recursive
	)
);
</pre>
<p>To find just one record, you need to use the first method, to find all records or a specific &#8220;notation&#8221; find, you would use the second method. The list of some of the &#8220;notations&#8221; are listed below:<br />
all<br />
neighbors<br />
list<br />
count<br />
threaded</p>
<p>So to use examples of this, lets say we have a &#8220;forum&#8221; area of a site, where it reads from a User table, a Forum table and a Post table. We have three tables, and we need to find certain things:</p>
<ol>
<li>The current Forum information (1 record, 1 table only)</li>
<li>The current number of posts in a forum (1 table, count)</li>
<li>The last post, and who posted it, in the selected forum (3 tables, 1 record, certain fields)</li>
<li>All posts in a forum topic, paginate results (3 tables, all records on specific conditions, certain fields)</li>
</ol>
<p>The way these tables (Forums, Posts and Users) relate to each other is by use of table-name_id (user_id, forum_id, post_id). User can have many posts, post belongs to a user, post belongs to a forum, forum has many posts. Now we need to do a simple query to get current forum info. I am doing this all in a forums_controller.php file. These can be a myriad of different function names, but each function would always be looking for some type of input. <em>NOTE: fields are arbitrary to this example. You can have as many or as little fields needed. </em></p>
<p>1. The current Forum information (1 record, 1 table only)</p>
<pre>
$forums = $this->Forum->find(
	array('Forum.forum_id' => $id),
	array('Forum.forum_id', 'Forum.forum_name', 'Forum.description', 'Forum.created'),
	null,
	-1
);
</pre>
<p>This grabs the current, or selected forum (passing in the $id from the function parameters), grabbing four fields from the table, no need to sort 1 record, and I only want this table&#8217;s data. This would return something like:</p>
<pre>
Array(
	[Forum] => Array(
		[forum_id] => 1
		[forum_name] => Sample Forum
		[description] => A Forum to discuss anything, upcoming and past.
		[created] => 2008-07-23 20:15:41
	)
)
</pre>
<p>2. The current number of posts in a forum (1 table -Posts-, count)</p>
<pre>
$post_count = $this->Post->find(
	'count',
	array(
		'conditions' => array('forum_id' => $id),
		'recursive' => -1
	)
);
</pre>
<p>With using count, there is no need to get fields or sort order, all we really need to do is get the conditions set, which are: all posts with the selected forum_id value. This returns a number of the records returned. Let&#8217;s say for this example it returned 12. </p>
<p>3. The last post, and who posted it, in the selected forum (3 tables -Users Posts Forums- , 1 record, certain fields)<br />
For this we can do a trick in the query, instead of getting just all the records, or the last entered one, we could try this:</p>
<pre>
$lastP = $this->Post->find(
	array('Post.forum_id' => $id), //array of conditions
	array('Post.created', 'User.username', 'Post.parent_topic', 'Post.title', 'Post.post_id', 'Forum.forum_name'), //array of field names
	'Post.created DESC', //string or array defining order
	-1, //int recursive level
	1 //int number of records to return
);
</pre>
<p>This is going to query the tables, where these conditions are met, order them descending order, and then return 1 record, the first one, which will be the last entry made in the table with that forum_id. Now we get into the &#8220;meat&#8221; of this thing. </p>
<p>4. All posts in a forum topic, paginate results (3 tables, all records on specific conditions, certain fields)</p>
<pre>
// Get the parent post
$parent = $this->Post->find(
	array('Post.post_id' => $id),
	array('Post.post_id', 'Post.forum_id', 'Post.title', 'Post.details', 'Post.created', 'User.username', 'User.avatar', 'User.biography', 'User.created', 'Forum.name'),
	'Post.created DESC',
	0
);
</pre>
<p>In this example, and as <a href="http://www.hirdweb.com/2008/08/04/custom-pagination-in-cakephp/">previously noted in my earlier blog posts</a>, the &#8220;Topic&#8221; is an entry in the Posts table, and all replies to that post reside in the same table, but reference that post_id as the parent_topic value. So the first thing I do is get this &#8220;Topic&#8221; information. I do some checks on this (which is outside the scope of this entry). Then I am ready to grab the replies to this topic, and then paginate the results. Since I already referenced the controller to use the paginator, I need to make a call to the paginator, and I need to apply a condition to it:</p>
<pre>
// grab all of the posts for this parent topic, and get the parent topic in the pagintor
$cond = array( 'OR' =>array( 'Post.parent_topic' => $id, 'Post.post_id' => $id ) );
$this->set( 'posts', $this->paginate( "Post", $cond ) );
</pre>
<p>One of the important things to note in this query, is the use of the $cond variable. I set this to use an &#8220;OR&#8221; clause. If nothing is specified, then the find() or paginator() assumes it is an &#8220;AND&#8221; clause, which is not the case here. So I set the conditions to look for the the $id value in either the post_id or the parent_topic columns. Be sure to check out the Cookbook for more information on complex queries. </p>
<p>But that is about it. Real world examples in use today using the new find() methods. The best part about these, is that with a little tweak here or there, you can have queries do what you want them to do, with little coding needed to accomplish the task. </p>

<!-- Wordpress Connect Modules v1.05 -->]]></content:encoded>
			<wfw:commentRss>http://www.hirdweb.com/2008/08/18/queries-using-cakephp-find/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>
