<?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>Jonah's Thoughts &#187; Enhancement</title>
	<atom:link href="http://php-thoughts.cubedwater.com/category/enhancement/feed/" rel="self" type="application/rss+xml" />
	<link>http://php-thoughts.cubedwater.com</link>
	<description>On PHP and things related</description>
	<lastBuildDate>Mon, 21 Jun 2010 01:38:44 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Safe attributes tip</title>
		<link>http://php-thoughts.cubedwater.com/2009/safe-attributes-tip/</link>
		<comments>http://php-thoughts.cubedwater.com/2009/safe-attributes-tip/#comments</comments>
		<pubDate>Fri, 20 Feb 2009 00:35:12 +0000</pubDate>
		<dc:creator>Jonah</dc:creator>
				<category><![CDATA[Enhancement]]></category>
		<category><![CDATA[Yii]]></category>
		<category><![CDATA[scenarios]]></category>

		<guid isPermaLink="false">http://php-thoughts.cubedwater.com/?p=163</guid>
		<description><![CDATA[<link rel="stylesheet" type="text/css" href="/wp-content/plugins/syntax.css" />In my last two posts [1, 2] I explained how to define scenario-based validation rules and safe attributes.  Something I have noted is that whenever I end up specifying an attribute as &#8220;required&#8221; in the validation rules(), I also always end up specifying it as &#8220;safe&#8221; in safeAttributes() under the same scenario.  This [...]]]></description>
			<content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="/wp-content/plugins/syntax.css" /><p>In my last two posts [<a href="http://php-thoughts.cubedwater.com/2009/validation-scenarios/">1</a>, <a href="http://php-thoughts.cubedwater.com/2009/safe-attribute-scenarios/">2</a>] I explained how to define scenario-based validation rules and safe attributes.  Something I have noted is that whenever I end up specifying an attribute as &#8220;required&#8221; in the validation rules(), I also always end up specifying it as &#8220;safe&#8221; in safeAttributes() under the same scenario.  This got me thinking &#8211; is it possible that every &#8220;required&#8221; attribute must also be &#8220;safe&#8221; on a given scenario?  The answer to that seems to be yes.  So I thought, why be redundant?  So I went about the task of teaching Yii that all &#8220;required&#8221; attributes are also &#8220;safe&#8221;.  It seems the most elegant way to do this is by extending getSafeAttributeNames() in your model. So that&#8217;s what I did.  Now, I&#8217;ll share with you.  Just drop this code in any model that you would like to have this behavior.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span class="kw2">&lt;?php</span>
<span class="coMULTI">/*
* I extended this method so that yii will &quot;automagically&quot; understand that
* 'required' attributes (in the given scenario) are also 'safe'.  This way,
* when defining 'safe' attributes in the safeAttributes() method, you can
* neglect to define attributes as safe that you have already defined at &quot;required&quot;
* in your rules() method.  This basically saves typing (and in some cases stupid
* mistakes), which I am always a fan of.  This method could be moved to another model
* from which other models like this could inherit from if you wish.
* 
* You should NOT call this method directly but it is used by Yii internally
*/</span>
<span class="kw2">public</span> <span class="kw2">function</span> getSafeAttributeNames<span class="br0">&#40;</span><span class="re0">$scenario</span><span class="sy0">=</span><span class="st_h">''</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
	<span class="re0">$safe</span> <span class="sy0">=</span> parent<span class="sy0">::</span><span class="me2">getSafeAttributeNames</span><span class="br0">&#40;</span><span class="re0">$scenario</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
	<span class="kw1">foreach</span> <span class="br0">&#40;</span><span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">validators</span> <span class="kw1">as</span> <span class="re0">$validator</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
		<span class="kw1">if</span> <span class="br0">&#40;</span><span class="br0">&#40;</span><span class="kw3">get_class</span><span class="br0">&#40;</span><span class="re0">$validator</span><span class="br0">&#41;</span> <span class="sy0">!=</span> <span class="st_h">'CRequiredValidator'</span><span class="br0">&#41;</span> <span class="sy0">||</span> <span class="sy0">!</span><span class="re0">$validator</span><span class="sy0">-&gt;</span><span class="me1">applyTo</span><span class="br0">&#40;</span><span class="re0">$scenario</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="kw1">continue</span><span class="sy0">;</span>
		<span class="re0">$safe</span> <span class="sy0">=</span> <span class="kw3">array_merge</span><span class="br0">&#40;</span><span class="re0">$safe</span><span class="sy0">,</span> <span class="re0">$validator</span><span class="sy0">-&gt;</span><span class="me1">attributes</span><span class="br0">&#41;</span><span class="sy0">;</span>
	<span class="br0">&#125;</span>
	<span class="kw1">return</span> <span class="kw3">array_unique</span><span class="br0">&#40;</span><span class="re0">$safe</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="br0">&#125;</span></pre></div></div>

<p>Enjoy if you wish and give feedback.</p>
<p>One thing to worry about is speed however.  Every time this method is called, it loops through all the validators.  If you have a <em>lot</em> of validation rules this could be unwanted.  On the other hand, yii only checks the safe attributes on CModel::setAttributes(), which is generally only called on requests with submitted POST data (e.g. forms, and users don&#8217;t often expect those pages to be lightning fast).  Anyways, I&#8217;m making this code snipped sound slower than it actually is.  It might be interesting to check how many times this method is called on a given request.</p>
]]></content:encoded>
			<wfw:commentRss>http://php-thoughts.cubedwater.com/2009/safe-attributes-tip/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
