<?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>Stereo Interactive &#38; Design &#187; Propel</title>
	<atom:link href="http://stereointeractive.com/blog/tag/propel/feed/" rel="self" type="application/rss+xml" />
	<link>http://stereointeractive.com/blog</link>
	<description>Development Blog</description>
	<lastBuildDate>Wed, 07 Jul 2010 19:16:20 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Propel criteria on custom columns (with addAsColumn)</title>
		<link>http://stereointeractive.com/blog/2009/07/21/propel-criteria-on-custom-columns-with-addascolumn/</link>
		<comments>http://stereointeractive.com/blog/2009/07/21/propel-criteria-on-custom-columns-with-addascolumn/#comments</comments>
		<pubDate>Tue, 21 Jul 2009 22:06:01 +0000</pubDate>
		<dc:creator>Scott Meves</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Propel]]></category>

		<guid isPermaLink="false">http://stereointeractive.com/blog/?p=256</guid>
		<description><![CDATA[This still trips me up. If you are using propel criteria objects and want to add a condition on a custom column, you have to do a bit of trickery to get it working just right.  
Let&#8217;s say you want to add a custom column to your query, let&#8217;s say &#8220;points remaining&#8221; for the [...]]]></description>
			<content:encoded><![CDATA[<p>This still trips me up. If you are using propel criteria objects and want to add a condition on a custom column, you have to do a bit of trickery to get it working just right.  <span id="more-256"></span></p>
<p>Let&#8217;s say you want to add a custom column to your query, let&#8217;s say &#8220;points remaining&#8221; for the sake of example.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">  <span class="re0">$c</span><span class="sy0">-&gt;</span><span class="me1">addAsColumn</span><span class="br0">&#40;</span><span class="st_h">'points_remaining'</span><span class="sy0">,</span> <span class="st_h">'('</span><span class="sy0">.</span>UserPointsPeer<span class="sy0">::</span><span class="me2">TOTAL_POINTS</span><span class="sy0">.</span><span class="st_h">' - '</span><span class="sy0">.</span>UserPointsPeer<span class="sy0">::</span><span class="me2">POINTS_EARNED</span><span class="sy0">.</span><span class="st_h">')'</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div>

<p>And now you want to limit your query to just users who have a certain number of points remaining. Since this is on a custom column, you have to use the <code>addHaving()</code> method. This gets a bit more tricky because when adding criteria based on custom columns, Propel wants to generate criterion objects using column names which include the column&#8217;s table name and dot separator. So, we have to rely on the <code>Criteria::CUSTOM</code> functionality. No doubt this is a hack and it completely circumvents any built-in query escaping that is <strong>essential</strong>, but if you are careful about sanitizing your input, you can do the following. Note this code sample assumes that <code>$pointsFilter['from']</code> and <code>$pointsFilter['to']</code> contain the GET or POST input parameters for use in your query:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span class="co1">// first version where we want to fetch a custom column</span>
<span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy0">!</span><span class="kw3">empty</span><span class="br0">&#40;</span><span class="re0">$pointsFilter</span><span class="br0">&#91;</span><span class="st_h">'from'</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
  <span class="re0">$pointsFilter</span><span class="br0">&#91;</span><span class="st_h">'from'</span><span class="br0">&#93;</span> <span class="sy0">=</span> <span class="br0">&#40;</span>int<span class="br0">&#41;</span> <span class="re0">$pointsFilter</span><span class="br0">&#91;</span><span class="st_h">'from'</span><span class="br0">&#93;</span><span class="sy0">;</span>
  <span class="re0">$criterion</span> <span class="sy0">=</span> <span class="re0">$c</span><span class="sy0">-&gt;</span><span class="me1">getNewCriterion</span><span class="br0">&#40;</span>UserPointsPeer<span class="sy0">::</span><span class="me2">ID</span><span class="sy0">,</span> <span class="st_h">'points_remaining &gt;= '</span><span class="sy0">.</span><span class="re0">$pointsFilter</span><span class="br0">&#91;</span><span class="st_h">'from'</span><span class="br0">&#93;</span><span class="sy0">,</span> Criteria<span class="sy0">::</span><span class="me2">CUSTOM</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="br0">&#125;</span>
&nbsp;
<span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy0">!</span><span class="kw3">empty</span><span class="br0">&#40;</span><span class="re0">$pointsFilter</span><span class="br0">&#91;</span><span class="st_h">'to'</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
  <span class="re0">$pointsFilter</span><span class="br0">&#91;</span><span class="st_h">'to'</span><span class="br0">&#93;</span> <span class="sy0">=</span> <span class="br0">&#40;</span>int<span class="br0">&#41;</span> <span class="re0">$pointsFilter</span><span class="br0">&#91;</span><span class="st_h">'to'</span><span class="br0">&#93;</span><span class="sy0">;</span>
  <span class="kw1">if</span> <span class="br0">&#40;</span><span class="kw3">isset</span><span class="br0">&#40;</span><span class="re0">$criterion</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
    <span class="re0">$criterion</span><span class="sy0">-&gt;</span><span class="me1">addAnd</span><span class="br0">&#40;</span><span class="re0">$c</span><span class="sy0">-&gt;</span><span class="me1">getNewCriterion</span><span class="br0">&#40;</span>UserPointsPeer<span class="sy0">::</span><span class="me2">ID</span><span class="sy0">,</span> <span class="st_h">'points_remaining &lt;= '</span><span class="sy0">.</span><span class="re0">$pointsFilter</span><span class="br0">&#91;</span><span class="st_h">'to'</span><span class="br0">&#93;</span><span class="sy0">,</span> Criteria<span class="sy0">::</span><span class="me2">CUSTOM</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span>
  <span class="br0">&#125;</span> <span class="kw1">else</span> <span class="br0">&#123;</span>
    <span class="re0">$criterion</span> <span class="sy0">=</span> <span class="re0">$c</span><span class="sy0">-&gt;</span><span class="me1">getNewCriterion</span><span class="br0">&#40;</span>UserPointsPeer<span class="sy0">::</span><span class="me2">ID</span><span class="sy0">,</span> <span class="st_h">'points_remaining &lt;= '</span><span class="sy0">.</span><span class="re0">$pointsFilter</span><span class="br0">&#91;</span><span class="st_h">'to'</span><span class="br0">&#93;</span><span class="sy0">,</span> Criteria<span class="sy0">::</span><span class="me2">CUSTOM</span><span class="br0">&#41;</span><span class="sy0">;</span>
  <span class="br0">&#125;</span>
<span class="br0">&#125;</span>
&nbsp;
<span class="kw1">if</span> <span class="br0">&#40;</span><span class="kw3">isset</span><span class="br0">&#40;</span><span class="re0">$criterion</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
  <span class="re0">$c</span><span class="sy0">-&gt;</span><span class="me1">addHaving</span><span class="br0">&#40;</span><span class="re0">$criterion</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="br0">&#125;</span></pre></div></div>

<p>Note that we have to use <code>addHaving()</code> to add our condition to our custom column.</p>
<p>If you don&#8217;t need to retrieve the custom column in your query but still want to limit your results on that criteria, you can use the <code>add()</code> method, but you have to change it up a bit:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span class="co1">// second version without adding a custom column</span>
<span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy0">!</span><span class="kw3">empty</span><span class="br0">&#40;</span><span class="re0">$pointsFilter</span><span class="br0">&#91;</span><span class="st_h">'from'</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
  <span class="re0">$pointsFilter</span><span class="br0">&#91;</span><span class="st_h">'from'</span><span class="br0">&#93;</span> <span class="sy0">=</span> <span class="br0">&#40;</span>int<span class="br0">&#41;</span> <span class="re0">$pointsFilter</span><span class="br0">&#91;</span><span class="st_h">'from'</span><span class="br0">&#93;</span><span class="sy0">;</span>
  <span class="re0">$criterion</span> <span class="sy0">=</span> <span class="re0">$c</span><span class="sy0">-&gt;</span><span class="me1">getNewCriterion</span><span class="br0">&#40;</span>
    UserPointsPeer<span class="sy0">::</span><span class="me2">ID</span><span class="sy0">,</span> <span class="co1">// can be any column in your table, really</span>
    <span class="st_h">'('</span><span class="sy0">.</span>CurriculumPeer<span class="sy0">::</span><span class="me2">TOTAL_POINTS</span><span class="sy0">.</span><span class="st_h">' - '</span><span class="sy0">.</span>UserPointsPeer<span class="sy0">::</span><span class="me2">POINTS_EARNED</span><span class="sy0">.</span><span class="st_h">') &gt;= '</span><span class="sy0">.</span><span class="re0">$pointsFilter</span><span class="br0">&#91;</span><span class="st_h">'from'</span><span class="br0">&#93;</span><span class="sy0">,</span> 
    Criteria<span class="sy0">::</span><span class="me2">CUSTOM</span>
  <span class="br0">&#41;</span><span class="sy0">;</span>
<span class="br0">&#125;</span>
&nbsp;
<span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy0">!</span><span class="kw3">empty</span><span class="br0">&#40;</span><span class="re0">$pointsFilter</span><span class="br0">&#91;</span><span class="st_h">'to'</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
  <span class="re0">$pointsFilter</span><span class="br0">&#91;</span><span class="st_h">'to'</span><span class="br0">&#93;</span> <span class="sy0">=</span> <span class="br0">&#40;</span>int<span class="br0">&#41;</span> <span class="re0">$pointsFilter</span><span class="br0">&#91;</span><span class="st_h">'to'</span><span class="br0">&#93;</span><span class="sy0">;</span>
  <span class="re0">$pointsFilterToCriterion</span> <span class="sy0">=</span> <span class="re0">$c</span><span class="sy0">-&gt;</span><span class="me1">getNewCriterion</span><span class="br0">&#40;</span>
    UserPointsPeer<span class="sy0">::</span><span class="me2">ID</span><span class="sy0">,</span> 
    <span class="st_h">'('</span><span class="sy0">.</span>CurriculumPeer<span class="sy0">::</span><span class="me2">TOTAL_POINTS</span><span class="sy0">.</span><span class="st_h">' - '</span><span class="sy0">.</span>UserPointsPeer<span class="sy0">::</span><span class="me2">POINTS_EARNED</span><span class="sy0">.</span><span class="st_h">') &lt;= '</span><span class="sy0">.</span><span class="re0">$pointsFilter</span><span class="br0">&#91;</span><span class="st_h">'to'</span><span class="br0">&#93;</span><span class="sy0">,</span>
    Criteria<span class="sy0">::</span><span class="me2">CUSTOM</span>
  <span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
  <span class="kw1">if</span> <span class="br0">&#40;</span><span class="kw3">isset</span><span class="br0">&#40;</span><span class="re0">$criterion</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
    <span class="re0">$criterion</span><span class="sy0">-&gt;</span><span class="me1">addAnd</span><span class="br0">&#40;</span><span class="re0">$pointsFilterToCriterion</span><span class="br0">&#41;</span><span class="sy0">;</span>
  <span class="br0">&#125;</span> <span class="kw1">else</span> <span class="br0">&#123;</span>
    <span class="re0">$criterion</span> <span class="sy0">=</span> <span class="re0">$pointsFilterToCriterion</span><span class="sy0">;</span>
  <span class="br0">&#125;</span>
<span class="br0">&#125;</span>
&nbsp;
<span class="kw1">if</span> <span class="br0">&#40;</span><span class="kw3">isset</span><span class="br0">&#40;</span><span class="re0">$criterion</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
  <span class="re0">$c</span><span class="sy0">-&gt;</span><span class="me1">add</span><span class="br0">&#40;</span><span class="re0">$criterion</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="br0">&#125;</span></pre></div></div>

<p>Note that in this example I&#8217;m typecasting our input parameters are integers, but you could mysql_real_escape_string() or any other sanitizing method you like.</p>
]]></content:encoded>
			<wfw:commentRss>http://stereointeractive.com/blog/2009/07/21/propel-criteria-on-custom-columns-with-addascolumn/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Symfony Propel Enum types</title>
		<link>http://stereointeractive.com/blog/2009/03/14/symfony-propel-enum-types/</link>
		<comments>http://stereointeractive.com/blog/2009/03/14/symfony-propel-enum-types/#comments</comments>
		<pubDate>Sat, 14 Mar 2009 19:46:13 +0000</pubDate>
		<dc:creator>Scott Meves</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Propel]]></category>
		<category><![CDATA[Symfony]]></category>

		<guid isPermaLink="false">http://stereointeractive.com/blog/?p=210</guid>
		<description><![CDATA[Propel does not support enum column types in its schemas, since the enum type is not support across all database types. There are a few ways around this.
1) Use another table to list the enum options. Pros: most flexible. Works nicely within symfony. Cons: means more joins in your queries. 
2) Use enum anyway. You [...]]]></description>
			<content:encoded><![CDATA[<p>Propel does not support enum column types in its schemas, since the enum type is not support across all database types. There are a few ways around this.<span id="more-210"></span></p>
<p>1) Use another table to list the enum options. Pros: most flexible. Works nicely within symfony. Cons: means more joins in your queries. </p>
<p>2) Use enum anyway. You can add custom column types using a little known trick in your schema:</p>
<pre class="code" type="php">
status:
  id:
  name: { type: varchar, sqltype:enum, size: "'inactive','active'", default: inactive }
</pre>
<p>Pros: You get your enum. Cons: Not very portable, a bit of a hack.</p>
<p>3) Simulate an enum column using your model. I typically end up doing this for columns that have a finite number of defined options *that will not change*. Pros: Fast. Cons: Not as flexible as optino 1. Example:</p>
<pre class="code" type="php">

class UserProfilePeer extends BaseUserProfilePeer
{
  static protected $USER_TYPE_INTEGERS = array('student', 'supervisor', 'coordinator', 'researcher', 'admin');
  static protected $USER_TYPE_VALUES = null;

  /**
   * Returns a user type label from an index value.
   *
   * @param integer $index
   * @return string user type label
   * @author Scott Meves
   */
  static public function getUserTypeFromIndex($index)
  {
    return self::$USER_TYPE_INTEGERS[$index];
  }

  /**
   * Returns the user type index from a string value
   *
   * @param string $value
   * @return integer $index
   * @author Scott Meves
   */
  static public function getUserTypeFromValue($value)
  {
    if (!self::$USER_TYPE_VALUES)
    {
      self::$USER_TYPE_VALUES = array_flip(self::$USER_TYPE_INTEGERS);
    }

    $values = strtolower($value);

    if (!isset(self::$USER_TYPE_VALUES[$value]))
    {
      throw new PropelException(sprintf('User type cannot take "%s" as a value', $value));
    }

    return self::$USER_TYPE_VALUES[strtolower($value)];
  }

  public static function getUserTypeOptions()
  {
    return self::$USER_TYPE_INTEGERS;
  }
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://stereointeractive.com/blog/2009/03/14/symfony-propel-enum-types/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Uploading a file with Symfony 1.2</title>
		<link>http://stereointeractive.com/blog/2009/01/23/uploading-a-file-with-symfony-12/</link>
		<comments>http://stereointeractive.com/blog/2009/01/23/uploading-a-file-with-symfony-12/#comments</comments>
		<pubDate>Fri, 23 Jan 2009 21:42:12 +0000</pubDate>
		<dc:creator>Scott Meves</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Propel]]></category>
		<category><![CDATA[Symfony]]></category>

		<guid isPermaLink="false">http://stereointeractive.com/blog/?p=137</guid>
		<description><![CDATA[This post explains how to use the symfony 1.2 forms framework to handle a file upload. ]]></description>
			<content:encoded><![CDATA[<p>There is a post hidden within the symfony documentation that discusses how to upload a file using the new forms framework within symfony 1.2. If you are curious about the best way to handle file uploads, it&#8217;s worth reading this <a href="http://www.symfony-project.org/tutorial/1_2/whats-new#Forms">What&#8217;s New in Symfony 1.2</a> post first, and then come back here for a quick summary of how this works.</p>
<p>Let&#8217;s say you would like to allow users to upload PDF files to your site. You store data related to these file uploads in an &#8220;article&#8221; table in your database. This table has a column named &#8220;file&#8221; that stores the file name of the uploaded pdf.</p>
<p>The symfony forms framework will generate the basic (and not so basic) code to get you started. If you haven&#8217;t yet generated your form classes yet, you can do so with the command:</p>
<p><span id="more-137"></span></p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">.<span class="sy0">/</span>symfony propel:build-forms</pre></div></div>

<p>Now navigate to lib/form/ArticleForm.class.php. To convert the file column to a file input field, we do the following:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span class="kw2">class</span> ArtistResumeForm <span class="kw2">extends</span> BaseArtistResumeForm
<span class="br0">&#123;</span>
  <span class="kw2">public</span> <span class="kw2">function</span> configure<span class="br0">&#40;</span><span class="br0">&#41;</span>
  <span class="br0">&#123;</span>
    <span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">widgetSchema</span><span class="br0">&#91;</span><span class="st_h">'file'</span><span class="br0">&#93;</span>        <span class="sy0">=</span> <span class="kw2">new</span> sfWidgetFormInputFile<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
    <span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">validatorSchema</span><span class="br0">&#91;</span><span class="st_h">'file'</span><span class="br0">&#93;</span>     <span class="sy0">=</span> <span class="kw2">new</span> sfValidatorFile<span class="br0">&#40;</span><span class="kw3">array</span><span class="br0">&#40;</span><span class="st_h">'path'</span> <span class="sy0">=&gt;</span> sfConfig<span class="sy0">::</span><span class="me2">get</span><span class="br0">&#40;</span><span class="st_h">'sf_upload_dir'</span><span class="br0">&#41;</span><span class="sy0">.</span><span class="st_h">'/articles'</span><span class="sy0">,</span> <span class="st_h">'required'</span> <span class="sy0">=&gt;</span> <span class="kw4">false</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span>
  <span class="br0">&#125;</span>
<span class="br0">&#125;</span></pre></div></div>

<p>Now, whenever you call $form->save(), your files will automatically be uploaded to the server, and the field &#8220;file&#8221; in your propel object will be updated with the new file name so you can easily retrieve it later. </p>
<p>If you are interested in getting this to work with embedded forms, check out this other post on <a href="http://stereointeractive.com/blog/2008/12/23/symfony-12-upload-a-file-inside-an-embedded-form/">uploading files within embedded forms with symfony 1.2</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://stereointeractive.com/blog/2009/01/23/uploading-a-file-with-symfony-12/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Propel Transactions with Symfony</title>
		<link>http://stereointeractive.com/blog/2008/02/29/propel-transactions-with-symfony/</link>
		<comments>http://stereointeractive.com/blog/2008/02/29/propel-transactions-with-symfony/#comments</comments>
		<pubDate>Fri, 29 Feb 2008 18:45:18 +0000</pubDate>
		<dc:creator>Scott Meves</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Propel]]></category>
		<category><![CDATA[Symfony]]></category>

		<guid isPermaLink="false">http://stereointeractive.com/blog/2008/02/29/propel-transactions-with-symfony/</guid>
		<description><![CDATA[It&#8217;s easy to create transactions with Propel. This can be very useful when you are deleting rows from your database from multiple tables, and want to do an &#8220;all or nothing&#8221; approach so that things don&#8217;t get messy. In this example, we want to delete an event from our database, however this event may have [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s easy to create transactions with Propel. This can be very useful when you are deleting rows from your database from multiple tables, and want to do an &#8220;all or nothing&#8221; approach so that things don&#8217;t get messy. <span id="more-73"></span>In this example, we want to delete an event from our database, however this event may have related rows in the user_favorite_event table, and we&#8217;d be unable to delete the event without getting a foreign key constraint error from the database. So, we first delete all the user favorites, and then delete the event. If the first query fails, we&#8217;ll rollback the deletion of the user_favorite_event rows.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span class="re0">$con</span> <span class="sy0">=</span> Propel<span class="sy0">::</span><span class="me2">getConnection</span><span class="br0">&#40;</span>EventPeer<span class="sy0">::</span><span class="me2">DATABASE_NAME</span><span class="br0">&#41;</span><span class="sy0">;</span>
try <span class="br0">&#123;</span>
	<span class="re0">$con</span><span class="sy0">-&gt;</span><span class="me1">begin</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
	UserFavoriteEventPeer<span class="sy0">::</span><span class="me2">deleteAllForEvent</span><span class="br0">&#40;</span><span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">getId</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span>
	EventPeer<span class="sy0">::</span><span class="me2">doDelete</span><span class="br0">&#40;</span><span class="re0">$this</span><span class="sy0">,</span> <span class="re0">$con</span><span class="br0">&#41;</span><span class="sy0">;</span>
	<span class="re0">$con</span><span class="sy0">-&gt;</span><span class="me1">commit</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="br0">&#125;</span> catch <span class="br0">&#40;</span>PropelException <span class="re0">$e</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
	<span class="re0">$con</span><span class="sy0">-&gt;</span><span class="me1">rollback</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
	throw <span class="re0">$e</span><span class="sy0">;</span>
<span class="br0">&#125;</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://stereointeractive.com/blog/2008/02/29/propel-transactions-with-symfony/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Propel Criteria Left Join: using addJoin() and addAlias() to join a table twice</title>
		<link>http://stereointeractive.com/blog/2008/01/24/propel-criteria-left-join-using-addjoin-and-addalias-to-join-a-table-twice/</link>
		<comments>http://stereointeractive.com/blog/2008/01/24/propel-criteria-left-join-using-addjoin-and-addalias-to-join-a-table-twice/#comments</comments>
		<pubDate>Thu, 24 Jan 2008 21:48:16 +0000</pubDate>
		<dc:creator>Scott Meves</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Propel]]></category>
		<category><![CDATA[Symfony]]></category>

		<guid isPermaLink="false">http://blog.stereodevelopment.com/2008/01/24/propel-criteria-left-join-using-addjoin-and-addalias-to-join-a-table-twice/</guid>
		<description><![CDATA[Here is a way to do left join on two columns in a table that both were foreign keys in the same table using Propel. This might happen if for example you have a table with a parent_id and a child_id in a nested set that both refer to the same table, or as an [...]]]></description>
			<content:encoded><![CDATA[<p>Here is a way to do left join on two columns in a table that both were foreign keys in the same table using Propel. This might happen if for example you have a table with a parent_id and a child_id in a nested set that both refer to the same table, or as an example you have a table &#8220;documentation&#8221; and each documentation can be categorized into a main category and a sub category.</p>
<p>What happens when you want to do a left join in your documentation query, so that if present both the related category and sub_category objects get included in the results?</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span class="re0">$c</span><span class="sy0">-&gt;</span><span class="me1">addJoin</span><span class="br0">&#40;</span>DocumentationPeer<span class="sy0">::</span><span class="me2">CATEGORY</span><span class="sy0">,</span> CategoryPeer<span class="sy0">::</span><span class="me2">ID</span><span class="sy0">,</span> Criteria<span class="sy0">::</span><span class="me2">LEFT_JOIN</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="re0">$c</span><span class="sy0">-&gt;</span><span class="me1">addJoin</span><span class="br0">&#40;</span>DocumentationPeer<span class="sy0">::</span><span class="me2">SUB_CATEGORY</span><span class="sy0">,</span> CategoryPeer<span class="sy0">::</span><span class="me2">alias</span><span class="br0">&#40;</span><span class="st_h">'c2'</span><span class="sy0">,</span> CategoryPeer<span class="sy0">::</span><span class="me2">ID</span><span class="br0">&#41;</span><span class="sy0">,</span> Criteria<span class="sy0">::</span><span class="me2">LEFT_JOIN</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="re0">$c</span><span class="sy0">-&gt;</span><span class="me1">addAlias</span><span class="br0">&#40;</span><span class="st_h">'c2'</span><span class="sy0">,</span> CategoryPeer<span class="sy0">::</span><span class="me2">TABLE_NAME</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div>

<p>Done and done!</p>
]]></content:encoded>
			<wfw:commentRss>http://stereointeractive.com/blog/2008/01/24/propel-criteria-left-join-using-addjoin-and-addalias-to-join-a-table-twice/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>symfony propel-load-data</title>
		<link>http://stereointeractive.com/blog/2008/01/14/symfony-propel-load-data/</link>
		<comments>http://stereointeractive.com/blog/2008/01/14/symfony-propel-load-data/#comments</comments>
		<pubDate>Mon, 14 Jan 2008 19:55:26 +0000</pubDate>
		<dc:creator>Scott Meves</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[Propel]]></category>
		<category><![CDATA[Symfony]]></category>

		<guid isPermaLink="false">http://blog.stereodevelopment.com/2008/01/14/symfony-propel-load-data/</guid>
		<description><![CDATA[Loading data from fixtures can be extremely useful to pre-populate your database so you have something to test and code with. I frequently use the propel-load-data task in two ways, the first when altering the schema, and the second to add some new data on top of whats in the database.
This will rebuild your db [...]]]></description>
			<content:encoded><![CDATA[<p>Loading data from fixtures can be extremely useful to pre-populate your database so you have something to test and code with. I frequently use the propel-load-data task in two ways, the first when altering the schema, and the second to add some new data on top of whats in the database.</p>
<p>This will rebuild your db and model from schema.yml, insert the new structure into your db, and load data from the fixtures in /data/fixtures:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span class="sy0">./</span>symfony propel<span class="sy0">-</span>build<span class="sy0">-</span>all<span class="sy0">-</span>load frontend</pre></div></div>

<p>To load in additional data from a specific fixture file, you can use this command:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span class="sy0">./</span>symfony propel<span class="sy0">-</span>load<span class="sy0">-</span>data frontend dev data<span class="sy0">/</span>fixtures<span class="sy0">/</span><span class="br0">&#91;</span>filename<span class="br0">&#93;</span><span class="sy0">.</span>yml append</pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://stereointeractive.com/blog/2008/01/14/symfony-propel-load-data/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Propel Set Distinct: setDistinct()</title>
		<link>http://stereointeractive.com/blog/2007/12/13/propel-set-distinct-setdistinct/</link>
		<comments>http://stereointeractive.com/blog/2007/12/13/propel-set-distinct-setdistinct/#comments</comments>
		<pubDate>Thu, 13 Dec 2007 05:54:03 +0000</pubDate>
		<dc:creator>Scott Meves</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[Propel]]></category>
		<category><![CDATA[Symfony]]></category>

		<guid isPermaLink="false">http://blog.stereodevelopment.com/2007/12/13/propel-set-distinct-setdistinct/</guid>
		<description><![CDATA[Propel&#8217;s use of the Criteria class has many unknown features documented deep within the propel API. One of my favorites is setDistinct(), which will add the DISTINCT keyword into the start of your query. This is very useful when you want to create a select menu that presents a list of pre-existing values for a [...]]]></description>
			<content:encoded><![CDATA[<p>Propel&#8217;s use of the Criteria class has many unknown features documented deep within the <a href="http://propel.phpdb.org/docs/api/current/runtime/propel-util/Criteria.html#methodsetDistinct">propel API</a>. One of my favorites is setDistinct(), which will add the DISTINCT keyword into the start of your query. This is very useful when you want to create a select menu that presents a list of pre-existing values for a column in your database. <span id="more-62"></span></p>
<p>In this example, I wanted to create a select menu to use as a filter in the admin generator within symfony. We have a <code>category</code> table, and the categories are themselves have a &#8220;type&#8221; column, which is a plain text field that contains the &#8220;type&#8221; of category, like documentation, podcasts or faqs. To create a nice drop down with these options, we want to select all of the distinct values of the &#8220;type&#8221; column in this table. We can accomplish this easily with a Criteria object. Check it out:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span class="co1">// from our CategoryPeer class</span>
<span class="kw2">public</span> static <span class="kw2">function</span> getTypes<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
  <span class="re0">$c</span> <span class="sy0">=</span> <span class="kw2">new</span> Criteria<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
  <span class="re0">$c</span><span class="sy0">-&gt;</span><span class="me1">addSelectColumn</span><span class="br0">&#40;</span><span class="kw2">self</span><span class="sy0">::</span><span class="me2">TYPE</span><span class="br0">&#41;</span><span class="sy0">;</span>
  <span class="re0">$c</span><span class="sy0">-&gt;</span><span class="me1">setDistinct</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
  <span class="re0">$c</span><span class="sy0">-&gt;</span><span class="me1">addAscendingOrderByColumn</span><span class="br0">&#40;</span><span class="kw2">self</span><span class="sy0">::</span><span class="me2">TYPE</span><span class="br0">&#41;</span><span class="sy0">;</span>
  <span class="re0">$rs</span> <span class="sy0">=</span> BasePeer<span class="sy0">::</span><span class="me2">doSelect</span><span class="br0">&#40;</span><span class="re0">$c</span><span class="br0">&#41;</span><span class="sy0">;</span>
  <span class="re0">$types</span> <span class="sy0">=</span> <span class="kw3">array</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
  <span class="kw1">while</span> <span class="br0">&#40;</span><span class="re0">$rs</span><span class="sy0">-&gt;</span><span class="me1">next</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
    <span class="re0">$types</span><span class="br0">&#91;</span><span class="br0">&#93;</span> <span class="sy0">=</span> <span class="re0">$rs</span><span class="sy0">-&gt;</span><span class="me1">getString</span><span class="br0">&#40;</span><span class="nu0">1</span><span class="br0">&#41;</span><span class="sy0">;</span>
  <span class="br0">&#125;</span>
&nbsp;
  <span class="kw1">return</span> <span class="kw3">array_combine</span><span class="br0">&#40;</span><span class="re0">$types</span><span class="sy0">,</span> <span class="re0">$types</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="br0">&#125;</span></pre></div></div>

<p>This ends up generating the following SQL statement:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">DISTINCT category<span class="sy0">.</span>TYPE<span class="sy0">,</span> UPPER<span class="br0">&#40;</span>category<span class="sy0">.</span>TYPE<span class="br0">&#41;</span> FROM category ORDER BY UPPER<span class="br0">&#40;</span>category<span class="sy0">.</span>TYPE<span class="br0">&#41;</span> ASC</pre></div></div>

<p>Perfect!</p>
]]></content:encoded>
			<wfw:commentRss>http://stereointeractive.com/blog/2007/12/13/propel-set-distinct-setdistinct/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Propel Queries using Custom SQL, Peer Classes, and Criterion Objects</title>
		<link>http://stereointeractive.com/blog/2007/06/12/propel-queries-using-custom-sql-peer-classes-and-criterion-objects/</link>
		<comments>http://stereointeractive.com/blog/2007/06/12/propel-queries-using-custom-sql-peer-classes-and-criterion-objects/#comments</comments>
		<pubDate>Tue, 12 Jun 2007 17:06:17 +0000</pubDate>
		<dc:creator>Scott Meves</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[Propel]]></category>
		<category><![CDATA[Symfony]]></category>

		<guid isPermaLink="false">http://blog.stereodevelopment.com/2007/06/12/propel-queries-using-custom-sql-peer-classes-and-criterion-objects/</guid>
		<description><![CDATA[Propel provides many ways to generate queries. Here are a few of the more common methods.
Perhaps the easiest way for newcomers to Propel are custom  queries written using standard SQL.

$con = Propel::getConnection&#40;DATABASE_NAME&#41;;
$sql = &#34;SELECT books.* FROM books 
    WHERE NOT EXISTS (SELECT id FROM review WHERE book_id = book.id)&#34;;
$stmt = $con-&#62;createStatement&#40;&#41;;
$rs [...]]]></description>
			<content:encoded><![CDATA[<p>Propel provides many ways to generate queries. Here are a few of the more common methods.</p>
<p>Perhaps the easiest way for newcomers to Propel are custom  queries written using standard SQL.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span class="re0">$con</span> <span class="sy0">=</span> Propel<span class="sy0">::</span><span class="me2">getConnection</span><span class="br0">&#40;</span>DATABASE_NAME<span class="br0">&#41;</span><span class="sy0">;</span>
<span class="re0">$sql</span> <span class="sy0">=</span> <span class="st0">&quot;SELECT books.* FROM books 
    WHERE NOT EXISTS (SELECT id FROM review WHERE book_id = book.id)&quot;</span><span class="sy0">;</span>
<span class="re0">$stmt</span> <span class="sy0">=</span> <span class="re0">$con</span><span class="sy0">-&gt;</span><span class="me1">createStatement</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="re0">$rs</span> <span class="sy0">=</span> <span class="re0">$stmt</span><span class="sy0">-&gt;</span><span class="me1">executeQuery</span><span class="br0">&#40;</span><span class="re0">$sql</span><span class="sy0">,</span> ResultSet<span class="sy0">::</span><span class="me2">FETCHMODE_NUM</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="re0">$books</span> <span class="sy0">=</span> BookPeer<span class="sy0">::</span><span class="me2">populateObjects</span><span class="br0">&#40;</span><span class="re0">$rs</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div>

<p>Another method would be to use the <em>peer class</em> to gain some more flexibility in case down the line you decide to change your column names. For this we will use the <strong>PrepareStatement()</strong> method. This example also returns specific data from the query rather than entire propel objects.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span class="kw2">public</span> <span class="kw2">function</span> getTotals<span class="br0">&#40;</span><span class="re0">$banner_id</span> <span class="sy0">=</span> <span class="kw4">NULL</span><span class="sy0">,</span> <span class="re0">$letter</span> <span class="sy0">=</span> <span class="kw4">NULL</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
	<span class="re0">$con</span> <span class="sy0">=</span> Propel<span class="sy0">::</span><span class="me2">getConnection</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
	<span class="re0">$sql</span> <span class="sy0">=</span> <span class="st0">&quot;SELECT SUM(&quot;</span><span class="sy0">.</span>LetterBannerPeer<span class="sy0">::</span><span class="me2">VIEWS</span><span class="sy0">.</span><span class="st0">&quot;) AS view_total,
		SUM(&quot;</span><span class="sy0">.</span>LetterBannerPeer<span class="sy0">::</span><span class="me2">CLICKS</span><span class="sy0">.</span><span class="st0">&quot;) AS click_total
		FROM &quot;</span><span class="sy0">.</span>LetterBannerPeer<span class="sy0">::</span><span class="me2">TABLE_NAME</span><span class="sy0">.</span><span class="st0">&quot;
		WHERE &quot;</span><span class="sy0">.</span>LetterBannerPeer<span class="sy0">::</span><span class="me2">LETTER</span><span class="sy0">.</span><span class="st0">&quot; = ?
		AND &quot;</span><span class="sy0">.</span>LetterBannerPeer<span class="sy0">::</span><span class="me2">REGION_ID</span><span class="sy0">.</span><span class="st0">&quot; = ?
		GROUP BY (&quot;</span><span class="sy0">.</span>LetterBannerPeer<span class="sy0">::</span><span class="me2">LETTER</span><span class="sy0">.</span><span class="st0">&quot;)&quot;</span><span class="sy0">;</span>
&nbsp;
	<span class="re0">$stmt</span> <span class="sy0">=</span> <span class="re0">$con</span><span class="sy0">-&gt;</span><span class="me1">PrepareStatement</span><span class="br0">&#40;</span><span class="re0">$sql</span><span class="br0">&#41;</span><span class="sy0">;</span>
	<span class="re0">$stmt</span><span class="sy0">-&gt;</span><span class="me1">setString</span><span class="br0">&#40;</span><span class="nu0">1</span><span class="sy0">,</span> <span class="re0">$letter</span><span class="br0">&#41;</span><span class="sy0">;</span>
	<span class="re0">$stmt</span><span class="sy0">-&gt;</span><span class="me1">setInt</span><span class="br0">&#40;</span><span class="nu0">2</span><span class="sy0">,</span> REGION_ID<span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
	<span class="re0">$rs</span> <span class="sy0">=</span> <span class="re0">$stmt</span><span class="sy0">-&gt;</span><span class="me1">executeQuery</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
	<span class="kw1">while</span> <span class="br0">&#40;</span><span class="re0">$rs</span><span class="sy0">-&gt;</span><span class="me1">next</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
		<span class="re0">$totals</span><span class="br0">&#91;</span><span class="st_h">'views'</span><span class="br0">&#93;</span> <span class="sy0">=</span> <span class="re0">$rs</span><span class="sy0">-&gt;</span><span class="me1">getInt</span><span class="br0">&#40;</span><span class="st_h">'view_total'</span><span class="br0">&#41;</span><span class="sy0">;</span>
		<span class="re0">$totals</span><span class="br0">&#91;</span><span class="st_h">'clicks'</span><span class="br0">&#93;</span> <span class="sy0">=</span> <span class="re0">$rs</span><span class="sy0">-&gt;</span><span class="me1">getInt</span><span class="br0">&#40;</span><span class="st_h">'click_total'</span><span class="br0">&#41;</span><span class="sy0">;</span>
	<span class="br0">&#125;</span>
	<span class="kw1">return</span> <span class="re0">$totals</span><span class="sy0">;</span>
<span class="br0">&#125;</span></pre></div></div>

<p>Notice how anytime you want to insert actual values into the query, you put in a <strong>?</strong> (question mark) as a place holder which is then automatically escaped for the query by calling the <code>$stmt->setString($position, $value)</code> function.</p>
<p>For our third example we will use the Criterion Object. This function returns a propel object.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span class="kw2">public</span> static <span class="kw2">function</span> getResponseTypes<span class="br0">&#40;</span><span class="re0">$message_type_id</span><span class="br0">&#41;</span>
<span class="br0">&#123;</span>
	<span class="re0">$c</span> <span class="sy0">=</span> <span class="kw2">new</span> Criteria<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
	<span class="re0">$c</span><span class="sy0">-&gt;</span><span class="me1">addJoin</span><span class="br0">&#40;</span>MessageTypePeer<span class="sy0">::</span><span class="me2">ID</span><span class="sy0">,</span> 
		MessageTypeResponsePeer<span class="sy0">::</span><span class="me2">RESPONSE_TYPE_ID</span><span class="sy0">,</span> Criteria<span class="sy0">::</span><span class="me2">LEFT_JOIN</span><span class="br0">&#41;</span><span class="sy0">;</span>
	<span class="co1">// think of a Criterion object as one 'XX=YY' within the WHERE clause</span>
	<span class="re0">$cton1</span> <span class="sy0">=</span> <span class="re0">$c</span><span class="sy0">-&gt;</span><span class="me1">getNewCriterion</span><span class="br0">&#40;</span>
		MessageTypeResponsePeer<span class="sy0">::</span><span class="me2">MESSAGE_TYPE_ID</span><span class="sy0">,</span> <span class="re0">$message_type_id</span>
	<span class="br0">&#41;</span><span class="sy0">;</span>
	<span class="re0">$cton2</span> <span class="sy0">=</span> <span class="re0">$c</span><span class="sy0">-&gt;</span><span class="me1">getNewCriterion</span><span class="br0">&#40;</span>
		MessageTypePeer<span class="sy0">::</span><span class="me2">NAME</span><span class="sy0">,</span> <span class="st_h">'general'</span>
	<span class="br0">&#41;</span><span class="sy0">;</span>
	<span class="re0">$cton1</span><span class="sy0">-&gt;</span><span class="me1">addOr</span><span class="br0">&#40;</span><span class="re0">$cton2</span><span class="br0">&#41;</span><span class="sy0">;</span>  <span class="co1">// combine them into one (XX=YY OR AA=BB) clause</span>
	<span class="re0">$c</span><span class="sy0">-&gt;</span><span class="me1">add</span><span class="br0">&#40;</span><span class="re0">$cton1</span><span class="br0">&#41;</span><span class="sy0">;</span> 		<span class="co1">// add to Criteria</span>
&nbsp;
	<span class="kw1">return</span> MessageTypePeer<span class="sy0">::</span><span class="me2">doSelect</span><span class="br0">&#40;</span><span class="re0">$c</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="br0">&#125;</span></pre></div></div>

<p>The <code>Criteria</code> object provides some other useful functions for generating queries. This is a great example of how to use <code>addAsColumn()</code>, <code>addGroupByColumn()</code>, and <code>addDescendingOrderByColumn()</code>.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span class="re0">$c</span> <span class="sy0">=</span> <span class="kw2">new</span> Criteria<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="re0">$c</span><span class="sy0">-&gt;</span><span class="me1">addJoin</span><span class="br0">&#40;</span>BookPeer<span class="sy0">::</span><span class="me2">ID</span><span class="sy0">,</span> FavoriteBookPeer<span class="sy0">::</span><span class="me2">BOOK_ID</span><span class="sy0">,</span> Criteria<span class="sy0">::</span><span class="me2">LEFT_JOIN</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="re0">$c</span><span class="sy0">-&gt;</span><span class="me1">addAsColumn</span><span class="br0">&#40;</span><span class="st_h">'cnt'</span><span class="sy0">,</span> <span class="st_h">'COUNT('</span><span class="sy0">.</span>FavoriteBookPeer<span class="sy0">::</span><span class="me2">BOOK_ID</span><span class="sy0">.</span><span class="st_h">')'</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="re0">$c</span><span class="sy0">-&gt;</span><span class="me1">addGroupByColumn</span><span class="br0">&#40;</span>BookPeer<span class="sy0">::</span><span class="me2">ID</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="re0">$c</span><span class="sy0">-&gt;</span><span class="me1">addDescendingOrderByColumn</span><span class="br0">&#40;</span><span class="st_h">'cnt'</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="re0">$book</span> <span class="sy0">=</span> BookPeer<span class="sy0">::</span><span class="me2">doSelect</span><span class="br0">&#40;</span><span class="re0">$c</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div>

<p>If you want to use a criteria object but only select certain columns, you can do something like this:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span class="re0">$c</span> <span class="sy0">=</span> <span class="kw2">new</span> Criteria<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="re0">$c</span><span class="sy0">-&gt;</span><span class="me1">clearSelectColumns</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
<span class="re0">$c</span><span class="sy0">-&gt;</span><span class="me1">addSelectColumn</span><span class="br0">&#40;</span><span class="kw2">self</span><span class="sy0">::</span><span class="me2">PAYABLE_TO</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="re0">$c</span><span class="sy0">-&gt;</span><span class="me1">add</span><span class="br0">&#40;</span><span class="kw2">self</span><span class="sy0">::</span><span class="me2">ID</span><span class="sy0">,</span> <span class="re0">$id</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
<span class="re0">$rs</span> <span class="sy0">=</span> <span class="kw2">self</span><span class="sy0">::</span><span class="me2">doSelectRS</span><span class="br0">&#40;</span><span class="re0">$c</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="re0">$payable_to</span> <span class="sy0">=</span> <span class="kw4">false</span><span class="sy0">;</span>
<span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$rs</span><span class="sy0">-&gt;</span><span class="me1">next</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
  <span class="re0">$payable_to</span> <span class="sy0">=</span> <span class="re0">$rs</span><span class="sy0">-&gt;</span><span class="me1">getInt</span><span class="br0">&#40;</span><span class="nu0">1</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="br0">&#125;</span></pre></div></div>

<p>If you want to do a subselect, you can use <code>Criteria::CUSTOM</code>.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span class="re0">$c</span> <span class="sy0">=</span> <span class="kw2">new</span> Criteria<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="re0">$subSelect</span> <span class="sy0">=</span> <span class="st0">&quot;users.user_type_id IN (
    SELECT
          user_type.ID
    FROM
          user_type
    WHERE
         user_type.name = 'public'
    )&quot;</span><span class="sy0">;</span>
<span class="re0">$c</span><span class="sy0">-&gt;</span><span class="me1">add</span><span class="br0">&#40;</span>UserPeer<span class="sy0">::</span><span class="me2">USER_TYPE_ID</span><span class="sy0">,</span> <span class="re0">$subSelect</span><span class="sy0">,</span> Criteria<span class="sy0">::</span><span class="me2">CUSTOM</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="re0">$publicUsers</span> <span class="sy0">=</span> UserPeer<span class="sy0">::</span><span class="me2">doSelect</span><span class="br0">&#40;</span><span class="re0">$c</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div>

<p>You of course could rewrite that query using JOINS if you thought that was too messy.</p>
<p>This custom criterion type is also useful when you want to compare two fields from the same table.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span class="re0">$c</span> <span class="sy0">=</span> <span class="kw2">new</span> Criteria<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="re0">$c</span><span class="sy0">-&gt;</span><span class="me1">add</span><span class="br0">&#40;</span>MyTablePeer<span class="sy0">::</span><span class="me2">COL1</span><span class="sy0">,</span> MyTablePeer<span class="sy0">::</span><span class="me2">COL1</span><span class="sy0">.</span><span class="st_h">'&gt;='</span><span class="sy0">.</span>MyTablePeer<span class="sy0">::</span><span class="me2">COL2</span><span class="sy0">,</span> Criteria<span class="sy0">::</span><span class="me2">CUSTOM</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div>

<p>Take a look at snippets <a href="http://www.symfony-project.org/snippets/snippet/75">75</a> and <a href="http://www.symfony-project.org/snippets/snippet/53">53</a> for more information.</p>
]]></content:encoded>
			<wfw:commentRss>http://stereointeractive.com/blog/2007/06/12/propel-queries-using-custom-sql-peer-classes-and-criterion-objects/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>Left Joins with multiple conditions using Propel Criteria</title>
		<link>http://stereointeractive.com/blog/2007/05/12/left-joins-with-multiple-conditions-using-propel-criteria/</link>
		<comments>http://stereointeractive.com/blog/2007/05/12/left-joins-with-multiple-conditions-using-propel-criteria/#comments</comments>
		<pubDate>Sat, 12 May 2007 22:29:04 +0000</pubDate>
		<dc:creator>Scott Meves</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[Propel]]></category>
		<category><![CDATA[Symfony]]></category>

		<guid isPermaLink="false">http://blog.stereodevelopment.com/?p=11</guid>
		<description><![CDATA[Symfony by default uses Propel for its ORM. Although Propel supports supports custom SQL I have learned how to take advantage of the built-in Criteria class to help construct queries. As described in the Propel trac,
 &#8230;its database neutrality and logical simplicity make it a good choice for expressing many common queries; however, for a [...]]]></description>
			<content:encoded><![CDATA[<p>Symfony by default uses <a href="http://propel.phpdb.org/trac/" title="Propel" target="_blank">Propel</a> for its ORM. Although Propel supports supports <a href="http://propel.phpdb.org/trac/wiki/Users/Documentation/1.2/BasicCRUD#UsingCustomSQL" title="Custom SQL with Propel" target="_blank">custom SQL</a> I have learned how to take advantage of the built-in <em>Criteria</em> class to help construct queries. As described in the Propel trac,</p>
<blockquote><p> &#8230;its database neutrality and logical simplicity make it a good choice for expressing many common queries; however, for a very complex query, it may prove more effective (and less painful) to simply use a custom SQL query to hydrate your Propel objects. <em>(<a href="http://propel.phpdb.org/trac/wiki/Users/Documentation/1.2/BasicCRUD#QueryingtheDatabase" title="propel trac" target="_blank">propel trac</a>)</em></p></blockquote>
<p>In building a complex search system for a client, I benefited greatly from being able to add and remove columns and conditions to a criteria object on the fly without having to worry about the actual SQL syntax. However, eventually I hit a wall when I needed to add a left join using multiple columns. Adding left joins to a criteria object is typically done like this:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span class="re0">$c</span> <span class="sy0">=</span> <span class="kw2">new</span> Criteria<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="re0">$c</span><span class="sy0">-&gt;</span><span class="me1">addJoin</span><span class="br0">&#40;</span>TABLE_A<span class="sy0">::</span><span class="me2">ID</span><span class="sy0">,</span> TABLE_B<span class="sy0">::</span><span class="me2">ID</span><span class="sy0">,</span> Criteria<span class="sy0">::</span><span class="me2">LEFT_JOIN</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="coMULTI">/* equivalent to: &quot;...left join TABLE_B ON (TABLE_A.ID=TABLE_B.ID)&quot; */</span></pre></div></div>

<p>However, this syntax does not support a join with multiple conditions, so you can&#8217;t produce something like this:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span class="sy0">...</span>left <span class="kw3">join</span> TABLE_B ON <span class="br0">&#40;</span>TABLE_A<span class="sy0">.</span>ID<span class="sy0">=</span>TABLE_B<span class="sy0">.</span>ID AND TABLE_B<span class="sy0">.</span>VALUE <span class="sy0">&amp;</span>gt<span class="sy0">;</span> <span class="nu0">100</span><span class="br0">&#41;</span></pre></div></div>

<p>In playing around quite a bit and examining the source code, I realized you could hack the addJoin method call and trick it into adding the extra column for you. The addJoin method actually is creating a new <em>Join</em> object that has a left and right column definition as defined in the method call. These are used to build the join condition:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span class="re0">$condition</span> <span class="sy0">=</span> <span class="re0">$join</span><span class="sy0">-&gt;</span><span class="me1">getLeftColumn</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="sy0">.</span> <span class="st_h">'='</span> <span class="sy0">.</span> <span class="re0">$join</span><span class="sy0">-&gt;</span><span class="me1">getRightColumn</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div>

<p>(<em>see the <a href="http://propel.phpdb.org/docs/api/current/runtime//__filesource/fsource_propel.util__utilBasePeer.php.html#a677">source</a></em>)</p>
<p>So, if you add the extra columns to the RightColumn like so:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span class="re0">$c</span><span class="sy0">-&gt;</span><span class="me1">addJoin</span><span class="br0">&#40;</span>TABLE_A<span class="sy0">::</span><span class="me2">ID</span><span class="sy0">,</span> TABLE_B<span class="sy0">::</span><span class="me2">ID</span><span class="sy0">.</span><span class="st_h">' AND '</span><span class="sy0">.</span>TABLE_B<span class="sy0">::</span><span class="me2">VALUE</span><span class="sy0">.</span><span class="st_h">' &gt; 0'</span><span class="sy0">,</span> Criteria<span class="sy0">::</span><span class="me2">LEFT_JOIN</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div>

<p>the generated SQL will yield something like this:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span class="sy0">...</span>LEFT <span class="kw3">JOIN</span> TABLE_B ON <span class="br0">&#40;</span>TABLE_A<span class="sy0">.</span>ID <span class="sy0">=</span> TABLE_B<span class="sy0">.</span>ID AND TABLE_B<span class="sy0">.</span>VALUE <span class="sy0">&gt;</span> <span class="nu0">0</span><span class="br0">&#41;</span></pre></div></div>

<p>Although it&#8217;s a hack and it may not work under all conditions, so far it has been a suitable workaround.</p>
]]></content:encoded>
			<wfw:commentRss>http://stereointeractive.com/blog/2007/05/12/left-joins-with-multiple-conditions-using-propel-criteria/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
	</channel>
</rss>
