<?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/"
	xmlns:series="http://unfoldingneurons.com/"
	>

<channel>
	<title>Larry Ullman&#039;s Blog</title>
	<atom:link href="http://blog.dmcinsights.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.dmcinsights.com</link>
	<description>flotsam and jetsam abounds</description>
	<lastBuildDate>Tue, 31 Aug 2010 15:16:13 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=abc</generator>
		<item>
		<title>&#8220;Effortless E-Commerce with PHP and MySQL&#8221; Book Available Online</title>
		<link>http://blog.dmcinsights.com/2010/08/31/effortless-e-commerce-with-php-and-mysql-book-available-online/</link>
		<comments>http://blog.dmcinsights.com/2010/08/31/effortless-e-commerce-with-php-and-mysql-book-available-online/#comments</comments>
		<pubDate>Tue, 31 Aug 2010 15:16:13 +0000</pubDate>
		<dc:creator>Larry</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[book]]></category>
		<category><![CDATA[e-commerce]]></category>

		<guid isPermaLink="false">http://blog.dmcinsights.com/?p=1260</guid>
		<description><![CDATA[My forthcoming &#8220;Effortless E-Commerce with PHP and MySQL&#8221; book is now available to read via Safari Books Online. Through the Rough Cuts series, you can read this book as I write it, and even provide feedback that could affect the final text. I just completed Chapter 9, which means there are two more chapters left [...]]]></description>
			<content:encoded><![CDATA[<p>My forthcoming &#8220;Effortless E-Commerce with PHP and MySQL&#8221; book is now <a href="http://my.safaribooksonline.com/9780321678805">available to read via Safari Books Online</a>. Through the Rough Cuts series, you can read this book as I write it, and even provide feedback that could affect the final text. I just completed Chapter 9, which means there are two more chapters left in the third part of the book. It looks like Part IV of the book will have two chapters as well. I&#8217;m hoping to wrap up the first draft of the book over the next two weeks.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.dmcinsights.com/2010/08/31/effortless-e-commerce-with-php-and-mysql-book-available-online/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MySQL Stored Procedures</title>
		<link>http://blog.dmcinsights.com/2010/08/26/mysql-stored-procedures/</link>
		<comments>http://blog.dmcinsights.com/2010/08/26/mysql-stored-procedures/#comments</comments>
		<pubDate>Thu, 26 Aug 2010 14:05:54 +0000</pubDate>
		<dc:creator>Larry</dc:creator>
				<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://blog.dmcinsights.com/?p=1241</guid>
		<description><![CDATA[In the book I&#8217;m currently writing, &#8220;Effortless E-Commerce with PHP and MySQL&#8221;, I&#8217;m using stored procedures for one of the two e-commerce sites being developed. Stored procedures, in case you&#8217;re not familiar with them, are blocks of code stored in the database. You can kind of think of them like defining your own functions in [...]]]></description>
			<content:encoded><![CDATA[<p>In the book I&#8217;m currently writing, &#8220;Effortless E-Commerce with PHP and MySQL&#8221;, I&#8217;m using <em>stored procedures</em> for one of the two e-commerce sites being developed. Stored procedures, in case you&#8217;re not familiar with them, are blocks of code stored in the database. You can kind of think of them like defining your own functions in PHP, although I have to be careful in saying that as MySQL also supports <em>stored functions</em>, which are different in usage than stored procedures, but the premises are similar.</p>
<p>I&#8217;m using stored procedures for two reasons. First, they&#8217;re more secure, as they hide database details and create an interface that makes it impossible for hackers to adversely manipulate the database. Stored procedures also use a different permissions system, which is an added security benefit. Second, in the book&#8217;s example site, I use somewhat of an MVC (Model-View-Controller) approach, separating the data (MySQL), the visual interface (HTML), and the logic (PHP). (To be clear, the site does this without using Object-Oriented Programming or a framework.) The MVC design creates very clean, autonomous files (for example, there&#8217;s not an iota of HTML in the PHP scripts and the only queries run are along the lines of <strong>CALL stored_procedure_name()</strong>). Furthermore, the MVC-based site should scale well, as you can throw server resources at just the parts that need the most help. You can also apply specific caching techniques to each part of the equation.</p>
<p>I first wrote about stored procedures in the second edition of my <em>MySQL: Visual QuickStart Guide</em>, published in 2006, so some extra research was in order on what has changed since then. Along with the MySQL manual, I read a fair amount of <a href="http://www.amazon.com/MySQL-Stored-Procedure-Programming-Harrison/dp/0596100892/ref=sr_1_1?s=books&amp;ie=UTF8&amp;qid=1282664517&amp;sr=1-1">MySQL Stored Procedure Programming by Guy Harrison and Steven Feuerstein</a>. It&#8217;s a good book that I&#8217;d easily recommend (although it also came out in 2006). One of the book&#8217;s strengths is that, in the process of discussing stored procedures, it does an excellent job of explaining some of the internals as to how MySQL works. This includes discussions of optimizing any SQL query you might use, whether inside of a stored procedure or not (because the first way to optimize a stored procedure is to optimize the queries it runs).</p>
<p>I was also pleasantly surprised to find how efficiently stored procedures execute in today&#8217;s version of MySQL. Stored procedures were notoriously slow when they were first added to MySQL in version 5. But in tests on my computer (running MySQL 5.1.37), stored procedures executed from the command line often ran ten times faster than the procedure&#8217;s queries on their own. This is due to how MySQL caches stored procedures, no doubt. When the procedures were run from PHP scripts, the performance difference was even greater (in part because there&#8217;s less actual data for the PHP script to send to the database). So along with improved security and data separation, stored procedures today can offer a significant performance benefit.</p>
<p>This all comes at a cost, of course. Stored procedures put a lot more load on the database. Generally I&#8217;m an advocate of using the database server as much as you can, but you&#8217;d have to be aware of the potential that the database server becomes the bottleneck in your Web site. Second, to create and execute stored procedures, you&#8217;ll need a MySQL user with permission to do so.</p>
<p>If you&#8217;re not familiar with stored procedures, check out the MySQL manual, the aforementioned book, or search online. Or if you wait a couple of months, you can see them in action in my new e-commerce book!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.dmcinsights.com/2010/08/26/mysql-stored-procedures/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>MySQL :: Using the New MySQL Query Profiler</title>
		<link>http://blog.dmcinsights.com/2010/08/24/mysql-using-the-new-mysql-query-profiler/</link>
		<comments>http://blog.dmcinsights.com/2010/08/24/mysql-using-the-new-mysql-query-profiler/#comments</comments>
		<pubDate>Tue, 24 Aug 2010 14:30:31 +0000</pubDate>
		<dc:creator>Larry</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[benchmark]]></category>
		<category><![CDATA[performance]]></category>

		<guid isPermaLink="false">http://blog.dmcinsights.com/?p=1244</guid>
		<description><![CDATA[I&#8217;m in the process of writing my latest book, &#8220;Effortless E-commerce with PHP and MySQL&#8221;, and as part of the process of writing any book, there&#8217;s lots of research involved. I want to check that I&#8217;m saying the right technical things (of course), but I also want to make sure that I&#8217;m doing things in [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m in the process of writing my latest book, &#8220;Effortless E-commerce with PHP and MySQL&#8221;, and as part of the process of writing any book, there&#8217;s lots of research involved. I want to check that I&#8217;m saying the right technical things (of course), but I also want to make sure that I&#8217;m doing things in an optimal way, that I&#8217;m using all the features and resources available to me, that I&#8217;ve reflected any recent changes in technology, etc. During this process, I just came across this article on MySQL&#8217;s SQL Profiler: <a href="http://dev.mysql.com/tech-resources/articles/using-new-query-profiler.html">Using the New MySQL Query Profiler</a>. I was looking for the best way to time the execution of various queries (specifically to compare straight SQL with stored procedures) when I saw this, and I was glad I did.</p>
<p>I&#8217;ll leave it up to you to read the full article, but the gist of it is that if you&#8217;re using MySQL 5.0.37 or greater and using the command-line mysql interface, you can enable profiling to see exact performance numbers for the queries you run. You can even see the nitty-gritty details: everything MySQL does to run the query, how long each step takes, and even what CPU or memory usage was required.</p>
<p>Between the SQL Profiler and the EXPLAIN the command, you can quickly improve how efficiently your SQL commands execute, which will improve the performance of your Web application as a whole. And, in a surprising result, I found that the stored procedures I created ran much, much faster than straight SQL (this was on MySQL 5.1.37). Clearly MySQL has been taking great strides to improve the performance of stored procedures, which used to be notoriously inefficient.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.dmcinsights.com/2010/08/24/mysql-using-the-new-mysql-query-profiler/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>First Example from &#8220;Effortless E-commerce with PHP and MySQL&#8221; Online</title>
		<link>http://blog.dmcinsights.com/2010/08/14/first-example-from-effortless-e-commerce-with-php-and-mysql-online/</link>
		<comments>http://blog.dmcinsights.com/2010/08/14/first-example-from-effortless-e-commerce-with-php-and-mysql-online/#comments</comments>
		<pubDate>Sat, 14 Aug 2010 14:36:57 +0000</pubDate>
		<dc:creator>Larry</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[book]]></category>
		<category><![CDATA[e-commerce]]></category>
		<category><![CDATA[ecommerce]]></category>

		<guid isPermaLink="false">http://blog.dmcinsights.com/?p=1237</guid>
		<description><![CDATA[For those of you interested in my forthcoming &#8220;Effortless E-commerce with PHP and MySQL&#8221; book, you can now look at the first example site at http://ecom1.dmcinsights.com. This project is covered in Part II of the book (four chapters total) and demonstrates: Selling access to content (i.e., selling virtual products) User management Content management via administrative [...]]]></description>
			<content:encoded><![CDATA[<p>For those of you interested in my forthcoming &#8220;Effortless E-commerce with PHP and MySQL&#8221; book, you can now look at the first example site at <a href="http://ecom1.dmcinsights.com">http://ecom1.dmcinsights.com</a>. This project is covered in Part II of the book (four chapters total) and demonstrates:</p>
<ul>
<li>Selling access to content (i.e., selling virtual products)</li>
<li>User management</li>
<li>Content management via administrative pages</li>
<li>Using PayPal&#8217;s Website Payments Standard system</li>
</ul>
<p>There are instructions on the site for how you can access it and you can even download all the source code. There&#8217;s a form on every page through which you can ask questions or post comments. I welcome any and all feedback you may have!</p>
<p>I&#8217;m currently developing the second example site now, and will also make that publicly available when it&#8217;s ready. Thanks!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.dmcinsights.com/2010/08/14/first-example-from-effortless-e-commerce-with-php-and-mysql-online/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Newsletter #30 Sent!</title>
		<link>http://blog.dmcinsights.com/2010/08/12/newsletter-30-sent/</link>
		<comments>http://blog.dmcinsights.com/2010/08/12/newsletter-30-sent/#comments</comments>
		<pubDate>Thu, 12 Aug 2010 15:51:45 +0000</pubDate>
		<dc:creator>Larry</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[about]]></category>
		<category><![CDATA[book]]></category>
		<category><![CDATA[newsletter]]></category>
		<category><![CDATA[writing]]></category>

		<guid isPermaLink="false">http://blog.dmcinsights.com/?p=1235</guid>
		<description><![CDATA[The latest newsletter went out today. If you are not subscribed to receive it, you can read it online at http://www.dmcinsights.com/newsletter.php?n=30.]]></description>
			<content:encoded><![CDATA[<p>The latest newsletter went out today. If you are not subscribed to receive it, you can read it online at <a href="http://www.dmcinsights.com/newsletter.php?n=30">http://www.dmcinsights.com/newsletter.php?n=30</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.dmcinsights.com/2010/08/12/newsletter-30-sent/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Apple&#8217;s Pro Tips</title>
		<link>http://blog.dmcinsights.com/2010/08/12/apples-pro-tips/</link>
		<comments>http://blog.dmcinsights.com/2010/08/12/apples-pro-tips/#comments</comments>
		<pubDate>Thu, 12 Aug 2010 06:27:46 +0000</pubDate>
		<dc:creator>Larry</dc:creator>
				<category><![CDATA[Mac OS X]]></category>

		<guid isPermaLink="false">http://blog.dmcinsights.com/?p=1215</guid>
		<description><![CDATA[For the casual and serious Mac user alike, Apple has posted on their Web site an exhaustive list of tips. There&#8217;s probably about 100 or more mini-articles there, covering everything from burning CDs to taking screenshots to working with fonts to&#8230; You could spend an afternoon looking at them all and learn quite a bit [...]]]></description>
			<content:encoded><![CDATA[<p>For the casual and serious Mac user alike, Apple has posted on their Web site an <a href="http://www.apple.com/pro/tips/">exhaustive list of tips</a>. There&#8217;s probably about 100 or more mini-articles there, covering everything from burning CDs to taking screenshots to working with fonts to&#8230; You could spend an afternoon looking at them all and learn quite a bit in the process.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.dmcinsights.com/2010/08/12/apples-pro-tips/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Handling Related Models in Yii Forms</title>
		<link>http://blog.dmcinsights.com/2010/08/10/handling-related-models-in-yii-forms/</link>
		<comments>http://blog.dmcinsights.com/2010/08/10/handling-related-models-in-yii-forms/#comments</comments>
		<pubDate>Tue, 10 Aug 2010 16:40:11 +0000</pubDate>
		<dc:creator>Larry</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[form]]></category>
		<category><![CDATA[mvc]]></category>
		<category><![CDATA[yii]]></category>

		<guid isPermaLink="false">http://blog.dmcinsights.com/?p=1225</guid>
		<description><![CDATA[Normally two Models in an MVC architecture are related to each other, such as Employees and Departments (to use the classic example), where each employee is in one department and each department has multiple employees. Although Yii does a great job of auto-generating most of the code you need, including the form used to create [...]]]></description>
			<content:encoded><![CDATA[<p>Normally two Models in an MVC architecture are related to each other, such as Employees and Departments (to use the classic example), where each employee is in one department and each department has multiple employees. Although Yii does a great job of auto-generating most of the code you need, including the form used to create and update a Model, the Yii-generated form won&#8217;t properly represent the related Model. In this post I&#8217;ll walk you through what you need to do to make your forms work properly for related Models.<span id="more-1225"></span></p>
<p>Looking at the employees example, you would likely have a <strong>departmentId</strong> value in the <strong>Employees</strong> table: a foreign key (FK) to store the <strong>id value</strong> from the <strong>Departments</strong> table, thereby representing the department that the employee is in. That&#8217;s perfect. The form generated by Yii, though, will create a text input for creating and updating the employee&#8217;s department:</p>
<pre>&lt;div&gt;
 &lt;?php echo CHtml::activeLabelEx($model,'departmentId'); ?&gt;
 &lt;?php echo CHtml::activeTextField($model,'departmentId'); ?&gt;
 &lt;?php echo CHtml::error($model,'departmentId'); ?&gt;
 &lt;/div&gt;</pre>
<p>That&#8217;s not appropriate, of course. The department value for the employee must be a number and you can&#8217;t expect the user to know the primary key numbers of the different departments. It&#8217;d be most appropriate to turn that text input into a drop-down menu. That&#8217;s not hard to do:</p>
<pre>&lt;div&gt;
&lt;?php echo $form-&gt;labelEx($model,'departmentId'); ?&gt;
&lt;?php echo $form-&gt;dropDownList($model, 'departmentId', CHtml::listData(
Departments::model()-&gt;findAll(), 'id', 'name'),
array('prompt' =&gt; 'Select a Department')
); ?&gt;
&lt;?php echo $form-&gt;error($model,'departmentId'); ?&gt;
&lt;/div&gt;</pre>
<p>And that&#8217;s all you need to do to get this to work. The <strong>dropDownList()</strong> method creates a SELECT menu. It&#8217;s associated with the <strong>departmentId</strong> attribute of this Model. The drop-down menu&#8217;s data has to come from <strong>CHtml::listData()</strong>. That part of the code says to fetch every Department, and to use the department&#8217;s <strong>id</strong> value for the menu value and its <strong>name</strong> value for the visible label. The final argument indicates a default prompt to give the menu. Since the <strong>Employees</strong> Model has a <strong>departmentId</strong> attribute, the framework will be able to handle errors, pre-select the right value on an update, and so forth. If you change the attribute label for <strong>departmentId</strong> in <strong>protected/models/Employees.php</strong>, you can make the prompt say &#8220;Department&#8221; instead. No problem.</p>
<p>A more complicated situation exists when there&#8217;s a many-to-many relationship between two Models, such as <strong>Posts</strong> and <strong>Categories</strong>, in a blog site. Because of the many-to-many relationship between these two, neither <strong>Posts</strong> nor <strong>Categories</strong> would have a foreign key to the other. Instead, a <em>junction</em> table (and Model) would be used. Let&#8217;s call that <strong>PostsCategories</strong>. The table itself would only need two columns: <strong>postId</strong> and<strong> categoryId</strong>.For each category that a post is associated with, there would be a record in this table.</p>
<p>On the form for adding (or updating) a blog post, you&#8217;d need to be able to select multiple <strong>Categories</strong>:</p>
<pre>&lt;div&gt;
&lt;?php echo $form-&gt;labelEx($model,'categories'); ?&gt;
&lt;?php echo $form-&gt;dropDownList($model, 'categories', CHtml::listData(
Categories::model()-&gt;findAll(), 'id', 'category'), array('multiple'=&gt;'multiple', 'size'=&gt;5)
); ?&gt;
&lt;?php echo $form-&gt;error($model,'categories'); ?&gt;
&lt;/div&gt;</pre>
<p>That <strong>dropDownList()</strong> method will create a drop-down of size 5 (five items will be shown), populated using the list of <strong>Categories</strong>, and the user will be able to select multiple options. If you were to run this code, though, you&#8217;d get an error as <strong>Posts</strong> doesn&#8217;t have a <strong>categories</strong> attribute. But that&#8217;s easy to change&#8230;</p>
<p>In the Model definition, you identify the relationship to other Models within the <strong>relations()</strong> method. The relationship between <strong>Posts</strong> and <strong>PostsCategories</strong> could be represented as:</p>
<pre>// protected/models/Posts
public function relations() {
    return array(
        'categories' =&gt; array(self::HAS_MANY, 'Categories', 'postId')
    );
}</pre>
<p>Now <strong>Posts</strong> has a <strong>categories</strong> attribute, meaning that the above form code will work. In fact, you can also add <strong>categories</strong> to the <strong>attributeLabels()</strong> array to give this relationship a new label that would be used in the form. You can even add a rule to make sure this part of the form validates. This is an important enough concept that I want to repeat it: <span style="text-decoration: underline;">when you create a relation, that relation becomes an attribute of the Model</span>.</p>
<p>In order for the creation of a new <strong>Post</strong> to work, you&#8217;ll need to update the Controller to handle the <strong>PostsCategories</strong>. Within the <strong>actionCreate()</strong> method (of <strong>PostsController</strong>), after the <strong>Post</strong> has been saved, loop through each category and add that record to <strong>PostsCategories</strong>. The beginning of <strong>actionCreate()</strong> would look like:</p>
<pre>public function actionCreate() {
    $model=new Posts;
    if(isset($_POST['Posts'])) {
        $model-&gt;attributes=$_POST['Posts'];
        if($model-&gt;save()) {
            foreach ($_POST['Posts']['categories'] as $categoryId) {
                $postCategory = new PostsCategories;
                $postCategory-&gt;postId = $model-&gt;id;
                $postCategory-&gt;categoryId = $categoryId;
                if (!$postCategory-&gt;save()) print_r($postCategory-&gt;errors);
            }</pre>
<p>Now, when a new <strong>Post</strong> is created, one new record is created in <strong>PostsCategories</strong> for each selected category.</p>
<p>We&#8217;re almost done getting this working, except we now need to think about the update process. There are two problems with what we&#8217;ve got so far: getting the form to select existing <strong>PostsCategories</strong> and handling updates of <strong>PostsCategories</strong>. The form has already been created and populated, but to get it to indicate existing selections, we need to pass along the <strong>PostsCategories</strong> values. You might think that you can just fetch all the <strong>PostsCategories</strong> records where <strong>postId</strong> equals the Model&#8217;s <strong>id</strong> (in other words, perform a <strong>with(&#8216;PostsCategories&#8217;)-&gt;</strong> retrieval), but you can&#8217;t. For the drop-down menu in the form to preselect the right values, the form needs to access an <em>array of values</em>, not an array of objects. To achieve that, add some code to the <strong>loadModel()</strong> method of the <strong>PostsController</strong>. This method is called for the update, delete, and view actions and just returns a single Model. The Model is loaded using:</p>
<pre>$this-&gt;_model=Posts::model()-&gt;findbyPk($_GET['id']);</pre>
<p>After that, within the <strong>loadModel()</strong> method, you can add this code to fetch the associated <strong>PostsCategories</strong>:</p>
<pre>$criteria=new CDbCriteria;
$criteria-&gt;condition='postId=:postId';
$criteria-&gt;select = 'categoryId';
$criteria-&gt;params=array(':postId'=&gt;$_GET['id']);
$postCategories = PostsCategories::model()-&gt;findAll($criteria);</pre>
<p>That code selects all of the <strong>categoryId</strong> values from <strong>PostsCategorgies</strong> where the <strong>postId</strong> value equals this post&#8217;s <strong>id</strong>. Next, we need to turn those results into an array:</p>
<pre>$categories = array();
foreach ($postCategories as $category) {
    $categories[] = $category-&gt;categoryId;
}</pre>
<p>Now, <strong>$categories</strong> is an array of numeric values, one for each category associated with the post. Just add this to the loaded Model:</p>
<pre>$this-&gt;_model-&gt;categories = $categories;</pre>
<p>And now the form will automatically select the existing categories for this post.</p>
<p>The final step is to update the <strong>PostsCategories</strong> when the form is submitted (and the post is updated). This could be tricky, because the user could add or remove categories, or make no changes to the categories at all. The easiest way to handle all possibilities is to clear out the existing values (for this post) in the <strong>PostsCategories</strong> table, and then add them in anew. To do that, in <strong>actionUpdate()</strong> of the <strong>PostsController</strong>, you would have:</p>
<pre>if($model-&gt;save()) {
    $criteria=new CDbCriteria;
    $criteria-&gt;condition='postId=:postId';
    $criteria-&gt;params=array(':postId'=&gt;$model-&gt;id);
    PostsCategories::model()-&gt;deleteAll($criteria);</pre>
<p>Then you use the same foreach loop as in <strong>actionCreate()</strong> to repopulate the table.</p>
<p>And that&#8217;s it. It takes a little thought getting all this going but these changes seem to work fine for me and I haven&#8217;t come up with a simpler solution yet. I hope this helps you with your next Yii-based project. As always, thanks for reading and let me know if you have any questions or comments.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.dmcinsights.com/2010/08/10/handling-related-models-in-yii-forms/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>100 Incredibly Useful &amp; Free Mac Apps &#124; Mac.AppStorm</title>
		<link>http://blog.dmcinsights.com/2010/08/06/100-incredibly-useful-free-mac-apps-mac-appstorm/</link>
		<comments>http://blog.dmcinsights.com/2010/08/06/100-incredibly-useful-free-mac-apps-mac-appstorm/#comments</comments>
		<pubDate>Sat, 07 Aug 2010 00:31:53 +0000</pubDate>
		<dc:creator>Larry</dc:creator>
				<category><![CDATA[Mac OS X]]></category>

		<guid isPermaLink="false">http://blog.dmcinsights.com/?p=1183</guid>
		<description><![CDATA[I&#8217;ve recently StumbledUpon just about the best list of free Mac software I&#8217;ve ever seen: 100 Incredibly Useful &#38; Free Mac Apps by Mac.AppStorm. Very well organized, this list includes many apps that I&#8217;ve not heard of but have since added to my computer. If you scroll through the comments, you&#8217;ll find some more recommendations, [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve recently StumbledUpon just about the best list of free Mac software I&#8217;ve ever seen: <a href="http://mac.appstorm.net/roundups/100-incredibly-useful-free-mac-apps/">100 Incredibly Useful &amp; Free Mac Apps by Mac.AppStorm</a>. Very well organized, this list includes many apps that I&#8217;ve not heard of but have since added to my computer. If you scroll through the comments, you&#8217;ll find some more recommendations, including several strong recommendations for <a href="http://www.alfredapp.com/">Alfred</a>, as a QuickSilver replacement (as much as I loved QuickSilver, I&#8217;ve since returned to using <a href="http://www.obdev.at/products/launchbar/index.html">LaunchBar</a>, as QuickSilver isn&#8217;t quite reliable on Snow Leopard).</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.dmcinsights.com/2010/08/06/100-incredibly-useful-free-mac-apps-mac-appstorm/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>&#8220;Effortless E-commerce with PHP and MySQL&#8221; Update</title>
		<link>http://blog.dmcinsights.com/2010/08/03/effortless-e-commerce-with-php-and-mysql-update/</link>
		<comments>http://blog.dmcinsights.com/2010/08/03/effortless-e-commerce-with-php-and-mysql-update/#comments</comments>
		<pubDate>Tue, 03 Aug 2010 13:40:01 +0000</pubDate>
		<dc:creator>Larry</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[book]]></category>
		<category><![CDATA[e-commerce]]></category>

		<guid isPermaLink="false">http://blog.dmcinsights.com/?p=1219</guid>
		<description><![CDATA[For the past couple of weeks I&#8217;ve been working full-bore on my next book, titled &#8220;Effortless E-commerce with PHP and MySQL&#8221; (the name has changed slightly since its original), which is why I haven&#8217;t been able to post much on the blog. I&#8217;m currently working on Chapter 5 , which is the penultimate chapter for [...]]]></description>
			<content:encoded><![CDATA[<p>For the past couple of weeks I&#8217;ve been working full-bore on my next book, titled &#8220;Effortless E-commerce with PHP and MySQL&#8221; (the name has changed slightly since its original), which is why I haven&#8217;t been able to post much on the blog. I&#8217;m currently working on Chapter 5 , which is the penultimate chapter for the first of the two e-commerce examples being developed. Here&#8217;s how the first six chapters are shaping up:</p>
<p>Part 1: Fundamentals</p>
<p>Chapter 1: Getting Started</p>
<ul>
<li>Identifying Your Business Goals</li>
<li>Researching Legal Issues</li>
<li>Choosing Web Technologies</li>
<li>Selecting a Web Host</li>
<li>Using a Payment System</li>
<li>The Development Process</li>
</ul>
<p>Chapter 2: Security Fundamentals</p>
<ul>
<li>Security Theory</li>
<li>PCI Requirements</li>
<li>Server Security</li>
<li>Using Secure Transactions</li>
<li>Common Vulnerabilities</li>
</ul>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;</p>
<p>Part 2: Selling Virtual Products</p>
<p>Chapter 3: First Site: Structure and Design</p>
<ul>
<li>Database Design</li>
<li>Server Organization</li>
<li>Connecting to the Database</li>
<li>The Config File</li>
<li>The HTML Template</li>
</ul>
<p>Chapter 4: User Accounts</p>
<ul>
<li>Defining Helper Functions</li>
<li>Registration</li>
<li>Logging In</li>
<li>Logging Out</li>
<li>Managing Passwords</li>
<li>Improving the Security</li>
</ul>
<p>Chapter 5: Managing Site Content</p>
<ul>
<li>Creating an Administrator</li>
<li>Adding Pages</li>
<li>Displaying Page Content</li>
<li>Adding PDFs</li>
<li>Displaying PDF Content</li>
<li>Recommended Alterations</li>
</ul>
<p>Chapter 6: Using PayPal</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;</p>
<p>Chapter 1 is an overview of the process along with tips for making certain decisions, such as hosting. Chapter 2 is generally a big-picture look at security, along with what primary decisions (e.g., hosting, certificate types) you&#8217;ll need to make. At the end of the chapter, I discuss the most common server vulnerabilities and attacks and how you go about preventing those. Although the chapter is really about an approach to security, it has some exact recommendations as well. More specific security techniques are demonstrated throughout the rest of the book.</p>
<p>In Chapters 3-6, you&#8217;re creating a entire site for selling access to online content, in both HTML and PDF formats. You&#8217;ll learn some ways to automate processes and effectively separate out bits of code to make the site easy to maintain. I don&#8217;t do anything fancy with the HTML templates, the PHP, or the MySQL, but there&#8217;s some great application of those technologies (in other words, you&#8217;ll learn a lot but won&#8217;t be overwhelmed with stuff like Smarty, OOP, etc.).</p>
<p>In Chapter 4 I created some really great helper functions. I even impressed myself with their usefulness and simplicity. The chapter also handles passwords and form validation in very secure ways. Chapter 4 concludes with some other ways you can heighten the security of the system, when you deem that appropriate. Chapter 4, User Accounts, may be something you&#8217;re familiar with overall (perhaps from another book of mine), but I think I&#8217;ve added enough new ideas here to still give you some value for reading it.</p>
<p>In Chapter 5 you learn how to add content to the site. There are two types. For the first, you can add HTML content using a WYSIWYG editor, that I show you how to integrate. For the second, you can upload PDFs. The PDFs will only be served through a proxy script so that a user must be logged in (with an account that hasn&#8217;t expired) to access them. The chapter wraps with discussions of about six different features you could add to the site, almost all intended to make it a better site for the potential customers. Although I don&#8217;t walk through the every add-on in complete detail, you&#8217;ll see what other tables you&#8217;d need to create, what SQL commands might be involved, and how the PHP code would work. I like this addition to the chapter and hope you will, too.</p>
<p>Chapter 6 integrates PayPal. You&#8217;ll learn a bit about how PayPal works and what its strengths and weaknesses are. Then you&#8217;ll use PayPal&#8217;s sandbox to test your site and see what you need to do to take the site live.</p>
<p>Next week I&#8217;ll be starting on Part 3 of the book, in which you&#8217;ll create an online site that sells coffee (beans, not brewed). I choose coffee as a product for a couple of reasons. First, I love coffee. Second, it&#8217;s an example of a physical product that must be shipped, that has inventory, and that also has permutations&#8211;size, roast, whole beans/ground&#8211;without being too, too complicated.</p>
<p>So that&#8217;s where things stand. Thanks for your interest in the book and please share any questions and comments you may have!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.dmcinsights.com/2010/08/03/effortless-e-commerce-with-php-and-mysql-update/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Yahoo!&#8217;s Design Pattern Library</title>
		<link>http://blog.dmcinsights.com/2010/07/27/yahoos-design-pattern-library/</link>
		<comments>http://blog.dmcinsights.com/2010/07/27/yahoos-design-pattern-library/#comments</comments>
		<pubDate>Tue, 27 Jul 2010 16:27:47 +0000</pubDate>
		<dc:creator>Larry</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[tools]]></category>
		<category><![CDATA[ui]]></category>

		<guid isPermaLink="false">http://blog.dmcinsights.com/?p=1213</guid>
		<description><![CDATA[Recently, and I can&#8217;t remember why, I came across Yahoo!&#8217;s Design Pattern Library. Just like a programming design pattern describes, in code, an accepted way of handling a specific task, this library has almost 60 (at this time) examples for how to layout and handle common visual elements. The patterns are organized by category: layout, [...]]]></description>
			<content:encoded><![CDATA[<p>Recently, and I can&#8217;t remember why, I came across <a href="http://developer.yahoo.com/ypatterns/">Yahoo!&#8217;s Design Pattern Library</a>. Just like a programming design pattern describes, in code, an accepted way of handling a specific task, this library has almost 60 (at this time) examples for how to layout and handle common visual elements.</p>
<p>The patterns are organized by category: layout, navigation, selection, rich interaction, and social. For example, there&#8217;s a pattern for showing the availability of a person (like you&#8217;d see in IM) and another for how breadcrumbs should be used. Mostly the patterns are descriptions of what you should do, based upon what&#8217;s best for the end user. Many of the patterns do have links to code examples, although those will often make use of the <a href="http://developer.yahoo.com/yui/">Yahoo! User Interface library</a>.</p>
<p>Part of the design pattern library is a <a href="http://developer.yahoo.com/ypatterns/about/stencils/">stencil kit</a>, available for OmniGraffle (the program I use), Adobe Illustrator, Visio, and other applications. Using this kit you can quickly create a mock-up of the user interface. And being Yahoo!, all of this is available for free.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.dmcinsights.com/2010/07/27/yahoos-design-pattern-library/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
