<?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>El Blog del Antonio &#187; PHP</title>
	<atom:link href="http://www.ramirezcobos.com/tag/php/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.ramirezcobos.com</link>
	<description>Programming Web with PHP, CSS, Javascript and ∞</description>
	<lastBuildDate>Wed, 28 Dec 2011 18:26:45 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>EScriptBoost Extension for Yii</title>
		<link>http://www.ramirezcobos.com/2011/12/07/escriptboost-extension-for-yii/</link>
		<comments>http://www.ramirezcobos.com/2011/12/07/escriptboost-extension-for-yii/#comments</comments>
		<pubDate>Wed, 07 Dec 2011 16:07:10 +0000</pubDate>
		<dc:creator>Antonio Ramirez</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Yii]]></category>
		<category><![CDATA[Extension]]></category>
		<guid isPermaLink="false">http://www.ramirezcobos.com/?p=996</guid>
		<description><![CDATA[Introduction
Probably a lot of you would wonder why, having so many good extensions related to minifying/compressing/packing your javascript code and your css files at the Yii Extensions Repository, here comes this guy offering us another solution.
I did check out all the extension in our  [...]]]></description>
			<content:encoded><![CDATA[<h2>Introduction</h2>
<p><a href="http://www.ramirezcobos.com/2010/10/28/how-to-use-jqueryslidemenu-with-yii%e2%80%99s-cmenu/yii/" rel="attachment wp-att-612"><img src="http://www.ramirezcobos.com/wp-content/uploads/2010/10/Yii.png" alt="Yii Framework" title="Yii Framework" width="160" height="160" class="alignright size-full wp-image-612" /></a>Probably a lot of you would wonder why, having so many good extensions related to minifying/compressing/packing your javascript code and your css files at the <a href="http://www.yiiframework.com/extensions/" title="Yii Extensions Repository" target="_blank">Yii Extensions Repository</a>, here comes this guy offering us another solution.</p>
<p>I did check out all the extension in our repository, just to name some of them:</p>
<ul>
<li><a href="http://www.yiiframework.com/extension/clientscriptpacker">clientscriptpacker</a></li>
<li><a href="http://www.yiiframework.com/extension/dynamicres/">dynamicres</a></li>
<li><a href="http://www.yiiframework.com/extension/minscript/">minscript</a></li>
</ul>
<p>All of them are great, but none were filling the requirements we had. I did not have any issue compressing all our files as our team, will use the YUI compressor jar file to create our compressed javascript versions and then use the wonderful mapping features of CClientScript. The issue was with the assets of external, or own developed, extensions and the javascript code that, even Yii own widgets, were writing to the POS_BEGIN, POS_END, POS_HEAD, POS_LOAD, POS_READY positions. Thats exactly what this library is doing: allowing Yii coders to minify those scripts.</p>
<div>I have created a GitHub repository for those willing to contribute on any of the extensions I created. Please, check the link at the bottom of this wiki.</p>
</div>
<h2>Library</h2>
<p>The library comes with three flavors:</p>
<ul>
<li>EScriptBoost Component</li>
<li>EClientScriptBoost Extension</li>
<li>AssetManagerBoost Extension</li>
</ul>
<h3>EScriptBoost Component</h3>
<p>This is a very easy to use component to compress your Javascript or CSS code at your will. The minifiers used are:</p>
<ul>
<li>For CSS- <a title="CssMin" href="http://code.google.com/p/cssmin/">CssMin</a> and <a title="CssMinify" href="http://code.google.com/p/minify/">CssMinify</a> (with CssCompressor and CssUriRewriter classes that you can also use independently)</li>
<li>For JS- <a title="JsMin" href="http://code.google.com/p/jsmin-php/">JsMin</a>, <a title="JsMinPlus" href="http://crisp.tweakblogs.net/blog/cat/716">JsMinPlus</a> and <a title="JavaScriptPacker" href="http://dean.edwards.name/packer/usage/">JavaScriptPacker</a></li>
</ul>
<p><strong><em>Usage</em></strong></p>
<div>
<div>
<pre class="brush: php; title: ; notranslate">
// this is a very simple example <img src='http://www.ramirezcobos.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />
// we use cache as we do not want to
// compress/minify all the time our
// script
$js = Yii::app()-&gt;cache-&gt;get('scriptID');
if(!$js)
{
     $cacheDuration = 30;
     $js = &lt;&lt;&lt;EOD
     // my long and uncompressed code here
EOD;
     // $js = EScriptBoost::packJs($js);
     // $js = EScriptBoost::minifyJs($js, EScriptBoost::JS_MIN_PLUS);
     $js = EScriptBoost::minifyJs($js, EScriptBoost::JS_MIN);
     // see Cache guide for more options | dependencies
     Yii::app()-&gt;cache-&gt;set('scriptID', $cacheDuration);
}
Yii::app()-&gt;clientScript-&gt;registerScript('scriptID', $js);
</pre>
</div>
</div>
<p>That was troublesome right? No worries, if you don&#8217;t really care about using JS_MIN, or JS_MIN_PLUS, you can use its helper function <strong>registerScript</strong>, it will handle all of the above automatically:</p>
<div>
<div>
<pre class="brush: php; title: ; notranslate">
$js = &lt;&lt;&lt;EOD
    // my long and uncompressed code here
EOD;
EScriptBoost::registerScript('scriptID', $js);
</pre>
</div>
</div>
<h3>EClientScriptBoost Extension</h3>
<p><strong>EScriptBoost</strong> was good for the javascript code written by me but what about the ones written by Yii widgets?<strong>EClientScriptBoost</strong> was developed to solve that:</p>
<p><strong><em>Usage</em></strong></p>
<p>On your main.php config file:</p>
<div>
<div>
<pre class="brush: php; title: ; notranslate">
'import' =&gt; array(
// ... other configuration settings on main.php
// ... importing the folder where scriptboost is
    'application.extensions.scriptboost.*',
// ... more configuration settings
    ),
// ... other configuration settings on main.php
'components' =&gt; array(
     'clientScript' =&gt; array(
// ... assuming you have previously imported the folder
//     where EClientScriptBoost is
         'class'=&gt;'EClientScriptBoost',
         'cacheDuration'=&gt;30,
// ... more configuration settings
</pre>
</div>
</div>
<p>Done! now, every time you or other component on your application will be minified and cached as you specify on your cache settings. Easy right?</p>
<h3 id="hh4">EAssetManagerBoost Extension</h3>
<p>But there was one more challenge to solve. Some extensions, widgets, etc, do publish a whole bunch of files in our assets that are not minified. This is where <strong>EAssetManagerBoost</strong> comes handy.</p>
<p>This extension does only minify javascript/css files, and also makes sure that the, about to be compressed, file do not match any of its $minifiedExtensionFlags so minified/compressed files are not processed at all.</p>
<p><strong><em>Usage</em></strong></p>
<p>Make sure you have deleted your previous assets folder contents.</p>
<div>
<div>
<pre class="brush: php; title: ; notranslate">
'import' =&gt; array(
// ... other configuration settings on main.php
// ... importing the folder where scriptboost is
    'application.extensions.scriptboost.*',
// ... more configuration settings
    ),
// ... other configuration settings on main.php
'components' =&gt; array(
    'assetManager' =&gt; array(
// ... assuming you have previously imported the folder
      'class' =&gt; 'EAssetManagerBoost',
      'minifiedExtensionFlags'=&gt;array('min.js','minified.js','packed.js')
        ),
// ... more configuration settings
</pre>
</div>
</div>
<p><strong><em>Important Note</em></strong> There is a small drawback to use EAssetManagerBoost and is that, the first time your application is requested, it will take a bit of time as it will go throughout all your asset files to be published and minify them.</p>
<h2>Resources</h2>
<ul>
<li><a href="https://github.com/tonydspaniard/Yii-extensions">GitHub repository</a></li>
<li><a href="http://www.ramirezcobos.com/">Project page</a></li>
<li><a href="http://code.google.com/p/minify/">Minify Google Code Project</a></li>
<li><a title="JsMinPlus" href="http://crisp.tweakblogs.net/blog/cat/716">JsMinPlus page</a></li>
<li><a title="CssMin" href="http://code.google.com/p/cssmin/">CssMin</a></li>
<li><a href="http://www.yiiframework.com/forum/index.php?/topic/26550-extension-escriptboost/page__pid__127736#entry127736">Forum Post</a></li>
</ul>
<p><center><br />
<script type="text/javascript"><!--
google_ad_client = "pub-7060132287364604";
/* 468x60, creado 16/03/10 */
google_ad_slot = "9029910384";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script><br />
</center></p>
<a href="http://twitter.com/?status=RT%20%40%3A%20EScriptBoost%20Extension%20for%20Yii%20-%20El%20Blog%20del%20Antonio%20http%3A%2F%2Fwww.ramirezcobos.com%2F2011%2F12%2F07%2Fescriptboost-extension-for-yii%2F" class="tweet-this" ><img src="http://www.ramirezcobos.com/wp-content/plugins/simple-tweet/img/tweet.gif" title="Tweet this!" alt="Tweet this!" />Tweet this!</a>]]></content:encoded>
			<wfw:commentRss>http://www.ramirezcobos.com/2011/12/07/escriptboost-extension-for-yii/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Avoiding duplicate script download when using CActiveForm on Ajax calls</title>
		<link>http://www.ramirezcobos.com/2011/09/11/avoiding-duplicate-script-download-when-using-cactiveform-on-ajax-calls/</link>
		<comments>http://www.ramirezcobos.com/2011/09/11/avoiding-duplicate-script-download-when-using-cactiveform-on-ajax-calls/#comments</comments>
		<pubDate>Sun, 11 Sep 2011 08:23:49 +0000</pubDate>
		<dc:creator>Antonio Ramirez</dc:creator>
				<category><![CDATA[Ajax]]></category>
		<category><![CDATA[How To]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Yii]]></category>
		<category><![CDATA[CActiveForm]]></category>
		<guid isPermaLink="false">http://www.ramirezcobos.com/?p=895</guid>
		<description><![CDATA[
Introduction
Sometimes the active form we wish to use to edit/add a new element on our database is too small and we believe that is much better to use an AJAX&#8217;ed dialog/slide form rather than reloading the page to just display one or two fields.
The only thing required is simple, we just need to  [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.ramirezcobos.com/2010/10/28/how-to-use-jqueryslidemenu-with-yii%e2%80%99s-cmenu/yii/" rel="attachment wp-att-612"><img src="http://www.ramirezcobos.com/wp-content/uploads/2010/10/Yii.png" alt="Yii Framework" title="Yii Framework" width="160" height="160" class="alignright size-full wp-image-612" /></a><br />
<h3>Introduction</h3>
<p>Sometimes the active form we wish to use to edit/add a new element on our database is too small and we believe that is much better to use an AJAX&#8217;ed dialog/slide form rather than reloading the page to just display one or two fields.</p>
<p>The only thing required is simple, we just need to create a view that will be partially rendered by a call to a controller (using renderPartial) and make sure that we process output -setting to true the parameter on the function. Everything will work as expected but&#8230;</p>
<h3>The issue</h3>
<p>If we open firebug (firefox), or developer tools (chrome), or whatever the tool you use in order to see the XmlHttpRequest object calls and resources downloaded, you will see that every time we do call the controller to display the active form, different Yii &#8220;core JS&#8221; files keeps being downloaded to the client. The JS files downloaded depends on your code but there are at least jquery.js, jquery-ui.js and jquery.yiiactiveform.js.</p>
<h3>The solution</h3>
<p>The solution is a bit tricky but simple. We need to pre-render the jquery.yiiactiveform.js on the view where we are going to place the AJAX functionality (the button that opens the modal dialog or slides/shows a layer with AJAX&#8217;ed form contents). For example, on index.php view file:</p>
<pre class="brush: php; title: ; notranslate">
cs()-&gt;registerCoreScript('yiiactiveform');
</pre>
<p>Now, I assume that you have created your function to display the AJAX&#8217;ed active form and its contents are returned by a call to a controller&#8217;s action that will partially render a view. This is what we have to do in our action:</p>
<pre class="brush: php; title: ; notranslate">
// Just before rendering the view that
// has our activeform
Yii::app()-&gt;clientScript-&gt;corePackages = array();
</pre>
<p>It is very important that we set corePackages to array() instead of null, as setting it to null will make CClientScript to reload the packages.php file (located in framework/web/js/) and we won&#8217;t stop the duplication of the script.</p>
<p>And that&#8217;s it, everything is working as it should.</p>
<p><center><br />
<script type="text/javascript"><!--
google_ad_client = "pub-7060132287364604";
/* 468x60, creado 16/03/10 */
google_ad_slot = "9029910384";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script><br />
</center></p>
<a href="http://twitter.com/?status=RT%20%40%3A%20Avoiding%20duplicate%20script%20download%20when%20using%20CActiveForm%20on%20Ajax%20calls%20-%20El%20Blog%20del%20Antonio%20http%3A%2F%2Fwww.ramirezcobos.com%2F2011%2F09%2F11%2Favoiding-duplicate-script-download-when-using-cactiveform-on-ajax-calls%2F" class="tweet-this" ><img src="http://www.ramirezcobos.com/wp-content/plugins/simple-tweet/img/tweet.gif" title="Tweet this!" alt="Tweet this!" />Tweet this!</a>]]></content:encoded>
			<wfw:commentRss>http://www.ramirezcobos.com/2011/09/11/avoiding-duplicate-script-download-when-using-cactiveform-on-ajax-calls/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Offertutti</title>
		<link>http://www.ramirezcobos.com/2011/07/28/offertutti/</link>
		<comments>http://www.ramirezcobos.com/2011/07/28/offertutti/#comments</comments>
		<pubDate>Thu, 28 Jul 2011 11:56:37 +0000</pubDate>
		<dc:creator>Antonio Ramirez</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Portfolio]]></category>
		<guid isPermaLink="false">http://www.ramirezcobos.com/?p=886</guid>
		<description><![CDATA[Coupon aggregator site I worked for. Duties I had for the company:
Consulting
CSS redesign
XML feeds development -Automation with PHP
RSS development and automatic marketing integration with Twitter and Facebook
&#160;
Even though was not a Yii-job, I am more than happy to promote www.offertutti.com  [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.ramirezcobos.com/2011/07/28/offertutti/screen-shot-2011-07-28-at-1-40-13-pm/" rel="attachment wp-att-887"><img class="alignright size-medium wp-image-887" title="Offertutti" src="http://www.ramirezcobos.com/wp-content/uploads/2011/07/Screen-Shot-2011-07-28-at-1.40.13-PM-300x223.png" alt="" width="300" height="223" /></a>Coupon aggregator site I worked for. Duties I had for the company:</p>
<ul>
<li>Consulting</li>
<li>CSS redesign</li>
<li>XML feeds development -Automation with PHP</li>
<li>RSS development and automatic marketing integration with Twitter and Facebook</li>
</ul>
<p>&nbsp;</p>
<p>Even though was not a Yii-job, I am more than happy to promote <a title="Offertutti" href="http://www.offertutti.com">www.offertutti.com</a> here as one of the most pleasant jobs I have ever had in my, already long -gosh how time pass, coding career.</p>
<p>The job was quite challenging, as any site developed by companies from certain countries, but managed to fulfill most of their expectations. Even though I am currently in the middle of a dream project, it continues to be a pleasure to help them out every now and then.</p>
<p>New design is coming&#8230;</p>
<a href="http://twitter.com/?status=RT%20%40%3A%20Offertutti%20-%20El%20Blog%20del%20Antonio%20http%3A%2F%2Fwww.ramirezcobos.com%2F2011%2F07%2F28%2Foffertutti%2F" class="tweet-this" ><img src="http://www.ramirezcobos.com/wp-content/plugins/simple-tweet/img/tweet.gif" title="Tweet this!" alt="Tweet this!" />Tweet this!</a>]]></content:encoded>
			<wfw:commentRss>http://www.ramirezcobos.com/2011/07/28/offertutti/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Custom Autocomplete Display and Value Submission</title>
		<link>http://www.ramirezcobos.com/2011/07/14/custom-autocomplete-display-and-value-submission/</link>
		<comments>http://www.ramirezcobos.com/2011/07/14/custom-autocomplete-display-and-value-submission/#comments</comments>
		<pubDate>Thu, 14 Jul 2011 22:03:23 +0000</pubDate>
		<dc:creator>Antonio Ramirez</dc:creator>
				<category><![CDATA[How To]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Yii]]></category>
		<guid isPermaLink="false">http://www.ramirezcobos.com/?p=879</guid>
		<description><![CDATA[
Introduction
How many of us has wondered how to create an autocomplete that will display the names of a related models but do require the id of that selected name to be submitted for model creation/update?
I was looking around wiki and found that was no approach as the one I did so I guessed this  [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.ramirezcobos.com/2010/10/28/how-to-use-jqueryslidemenu-with-yii%e2%80%99s-cmenu/yii/" rel="attachment wp-att-612"><img src="http://www.ramirezcobos.com/wp-content/uploads/2010/10/Yii.png" alt="Yii Framework" title="Yii Framework" width="160" height="160" class="alignright size-full wp-image-612" /></a><br />
<h2>Introduction</h2>
<p>How many of us has wondered how to create an autocomplete that will display the names of a related models but do require the id of that selected name to be submitted for model creation/update?</p>
<p>I was looking around wiki and found that was no approach as the one I did so I guessed this is worth to write.</p>
<h2>Requirements</h2>
<p>For our example, I want to be able to:</p>
<ul>
<li>Have an autocomplete field in our form</li>
<li>Once user selects an item in the dropdown list and fill a hidden box with the id of the selected item for submission</li>
</ul>
<h2>Making the right choice</h2>
<p>To setup the autocomplete was a very straight forward operation, but I couldn&#8217;t figure out how to get values from a custom JSON response and then fill the correspondent hidden fields.</p>
<p><a title="CAutoComplete" href="http://www.yiiframework.com/doc/api/1.1/CAutoComplete" target="_blank">CAutoComplete</a> does has a way to do it, but I wanted to use <a title="CJuiAutoComplete" href="http://www.yiiframework.com/doc/api/1.1/CJuiAutoComplete" target="_blank">CJuiAutoComplete</a> to get all the cool features of its JQuery Ui and by looking at his code there was no method chain, something that is required to work with custom JSON responses as we need to override some methods.</p>
<h2>My Solution</h2>
<p>After doing some research I decided to:</p>
<ol>
<li>extend from <a title="CJuiAutocomplete" href="http://www.yiiframework.com/doc/api/1.1/CJuiAutoComplete" target="_blank">CJuiAutoComplete</a></li>
<li>include the required property for method chain and modify its &#8216;run&#8217; function</li>
<li>then initialize the newly created property with the javascript functions that handle my custom JSON</li>
</ol>
<h3>Extending from CJuiAutoComplete and make required modifications</h3>
<p>Very simple, we are going to add a methodChain property and modify the run function to include it (zii is not a major concern to Yii, but main developers should think about this minor change).</p>
<pre class="brush: php; title: ; notranslate">
class myAutoComplete extends CJuiAutoComplete
{
    /**
     * @var string the chain of method calls that would be appended at the end of the autocomplete constructor.
     * For example, &quot;.result(function(...){})&quot; would cause the specified js function to execute
     * when the user selects an option.
     */
    public $methodChain;
    /**
     * Run this widget.
     * This method registers necessary javascript and renders the needed HTML code.
     */
    public function run()
    {
        list($name,$id)=$this-&gt;resolveNameID();
        if(isset($this-&gt;htmlOptions['id']))
            $id=$this-&gt;htmlOptions['id'];
        else
            $this-&gt;htmlOptions['id']=$id;
        if(isset($this-&gt;htmlOptions['name']))
            $name=$this-&gt;htmlOptions['name'];
        if($this-&gt;hasModel())
            echo CHtml::activeTextField($this-&gt;model,$this-&gt;attribute,$this-&gt;htmlOptions);
        else
            echo CHtml::textField($name,$this-&gt;value,$this-&gt;htmlOptions);
        if($this-&gt;sourceUrl!==null)
            $this-&gt;options['source']=CHtml::normalizeUrl($this-&gt;sourceUrl);
        else
            $this-&gt;options['source']=$this-&gt;source;
        $options=CJavaScript::encode($this-&gt;options);
        $js = &quot;jQuery('#{$id}').autocomplete($options){$this-&gt;methodChain};&quot;;
        $cs = Yii::app()-&gt;getClientScript();
        $cs-&gt;registerScript(__CLASS__.'#'.$id, $js);
    }
}
</pre>
<h2>Using our widget</h2>
<p>Now that we have our beautiful widget that handles method chain in our Autocomplete, let&#8217;s assume a couple of things:</p>
<ul>
<li>We saved our class onto a folder in our application -ie protected/extensions</li>
<li>We have a hidden INPUT HTML element with model&#8217;s attribute_id</li>
<li>We have created an action on our testController named autocomplete that returns a JSON object on the following format:</li>
</ul>
<pre class="brush: php; title: ; notranslate">
// This function will echo a JSON object
// on this format:
// [{id:id, name: 'name'}]
public function actionAutocomplete(){
      $res = array();
      $term = Yii::app()-&gt;getRequest()-&gt;getParam('term', false);
      if ($term)
      {
         // test table is for the sake of this example
         $sql = 'SELECT id, name FROM {{test}} where LCASE(name) LIKE :name';
         $cmd = Yii::app()-&gt;db-&gt;createCommand($sql);
         $cmd-&gt;bindValue(&quot;:name&quot;,&quot;%&quot;.strtolower($term).&quot;%&quot;, PDO::PARAM_STR);
         $res = $cmd-&gt;queryAll();
      }
      echo CJSON::encode($res);
      Yii::app()-&gt;end();
}
</pre>
<p>We have everything, let&#8217;s use our widget in our view:</p>
<pre class="brush: php; title: ; notranslate">
// REMEMBER, we have a hidden
// input HTML element with model's attribute_id
&lt;?php echo $form-&gt;hiddenField($model, 'attribute_id'); ?&gt;
&lt;?php
// ext is a shortcut for application.extensions
$this-&gt;widget('ext.myAutoComplete', array(
    'name' =&gt; 'test_autocomplete',
    'source' =&gt; $this-&gt;createUrl('test/autocomplete'),
// attribute_value is a custom property that returns the
// name of our related object -ie return $model-&gt;related_model-&gt;name
    'value' =&gt; $model-&gt;isNewRecord ? '': $model-&gt;attribute_value,
    'options' =&gt; array(
        'minChars'=&gt;3,
        'autoFill'=&gt;false,
        'focus'=&gt; 'js:function( event, ui ) {
            $( &quot;#test_autocomplete&quot; ).val( ui.item.name );
            return false;
        }',
        'select'=&gt;'js:function( event, ui ) {
            $(&quot;#'.CHtml::activeId($model,'attribute_id').'&quot;)
            .val(ui.item.id);
            return false;
        }'
     ),
    'htmlOptions'=&gt;array('class'=&gt;'input-1', 'autocomplete'=&gt;'off'),
    'methodChain'=&gt;'.data( &quot;autocomplete&quot; )._renderItem = function( ul, item ) {
        return $( &quot;&lt;li&gt;&lt;/li&gt;&quot; )
            .data( &quot;item.autocomplete&quot;, item )
            .append( &quot;&lt;a&gt;&quot; + item.name +  &quot;&lt;/a&gt;&quot; )
            .appendTo( ul );
    };'
));
?&gt;
</pre>
<p>Done! Just make sure that when you do submit your form, you get the value from the hidden field instead of the autocomplete element <img src='http://www.ramirezcobos.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h2>Final Notes</h2>
<p>I do not know if there are other ways of doing the same thing (apart from pure Javascript) to have the same results. If you know, with CJuiAutoComplete widget, let us know here.</p>
<p>Hope you find this useful.</p>
<p>Cheers</p>
<a href="http://twitter.com/?status=RT%20%40%3A%20Custom%20Autocomplete%20Display%20and%20Value%20Submission%20-%20El%20Blog%20del%20Antonio%20http%3A%2F%2Fwww.ramirezcobos.com%2F2011%2F07%2F14%2Fcustom-autocomplete-display-and-value-submission%2F" class="tweet-this" ><img src="http://www.ramirezcobos.com/wp-content/plugins/simple-tweet/img/tweet.gif" title="Tweet this!" alt="Tweet this!" />Tweet this!</a>]]></content:encoded>
			<wfw:commentRss>http://www.ramirezcobos.com/2011/07/14/custom-autocomplete-display-and-value-submission/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Implementing a User Level Access System</title>
		<link>http://www.ramirezcobos.com/2011/04/20/implementing-a-user-level-access-system/</link>
		<comments>http://www.ramirezcobos.com/2011/04/20/implementing-a-user-level-access-system/#comments</comments>
		<pubDate>Wed, 20 Apr 2011 19:23:35 +0000</pubDate>
		<dc:creator>Antonio Ramirez</dc:creator>
				<category><![CDATA[How To]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Yii]]></category>
		<category><![CDATA[Tutorial]]></category>
		<guid isPermaLink="false">http://www.ramirezcobos.com/?p=853</guid>
		<description><![CDATA[
I would like to explain this time how easy is to implement a level access system with Yii framework.
Please note that this article is a simple example and good security should be taken into account when we play with authentication systems.
Step 1: Setting Up
a. Include a field on your user&#8217;s table  [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.ramirezcobos.com/2010/10/28/how-to-use-jqueryslidemenu-with-yii%e2%80%99s-cmenu/yii/" rel="attachment wp-att-612"><img src="http://www.ramirezcobos.com/wp-content/uploads/2010/10/Yii.png" alt="Yii Framework" title="Yii Framework" width="160" height="160" class="alignright size-full wp-image-612" /></a></p>
<p>I would like to explain this time how easy is to implement a level access system with Yii framework.</p>
<p>Please note that this article is a simple example and good security should be taken into account when we play with authentication systems.</p>
<h3>Step 1: Setting Up</h3>
<p>a. <strong>Include a field on your user&#8217;s table named, </strong>yep you guessed<strong>, level</strong><br />
b. <strong>Create an object &#8216;LevelLookUp&#8217; </strong>that will tell us who is who on this system</p>
<pre class="brush: php; title: ; notranslate">
class LevelLookUp{
      const MEMBER = 0;
      const ADMIN  = 2;
      // For CGridView, CListView Purposes
      public static function getLabel( $level ){
          if($level == self::MEMBER)
             return 'Member';
          if($level == self::ADMIN)
             return 'Administrator';
          return false;
      }
      // for dropdown lists purposes
      public static function getLevelList(){
          return array(
                 self::MEMBER=&gt;'Member',
                 self::ADMIN=&gt;'Administrator');
	}
}
</pre>
<p>c.<strong>Modifying UserIdentity</strong> so we can store the user Model id on authentication, as CWebUser&#8217;s default id is set to the user Model&#8217;s username:</p>
<pre class="brush: php; title: ; notranslate">
class UserIdentity extends CUserIdentity
{
	private $_id;
	/**
	 * Authenticates a user.
	 * @return boolean whether authentication succeeds.
	 */
	public function authenticate()
	{
		$username = strtolower($this-&gt;username);
                // from database... change to suite your authentication criteria
		$user = User::model()-&gt;find('LOWER(username)=?', array($username));
		if($user===null)
			$this-&gt;errorCode=self::ERROR_USERNAME_INVALID;
		else if(!$user-&gt;validatePassword($this-&gt;password))
			$this-&gt;errorCode = self::ERROR_PASSWORD_INVALID;
		else{
			$this-&gt;_id = $user-&gt;id;
			$this-&gt;username = $user-&gt;username;
			$this-&gt;errorCode = self::ERROR_NONE;
		}
		return $this-&gt;errorCode == self::ERROR_NONE;
	}
	public function getId()
	{
		return $this-&gt;_id;
	}
}
</pre>
<p>d. <strong>Modify CWebUser&#8217;s application</strong> in order to hold the &#8216;level&#8217; property. We are going to call it EWebUser and will extend from CWebUser, and save it on protected/components to be loaded automatically by our default&#8217;s configuration file.</p>
<pre class="brush: php; title: ; notranslate">
class EWebUser extends CWebUser{
    protected $_model;
    function isAdmin(){
        $user = $this-&gt;loadUser();
        if ($user)
           return $user-&gt;level==LevelLookUp::ADMIN;
        return false;
    }
    // Load user model.
    protected function loadUser()
    {
        if ( $this-&gt;_model === null ) {
                $this-&gt;_model = User::model()-&gt;findByPk( $this-&gt;id );
        }
        return $this-&gt;_model;
    }
}
</pre>
<p>e. <strong>Modify our main.php</strong> config file (this file is in protected/config folder)</p>
<pre class="brush: php; title: ; notranslate">
// go to the 'user' section
// application components
	'components'=&gt;array(
		'user'=&gt;array(
                        // There you go, use our 'extended' version
			'class'=&gt;'application.components.EWebUser',
			// enable cookie-based authentication
			'allowAutoLogin'=&gt;true,
		),
</pre>
<h3>Step 2: Putting everything together</h3>
<p>Now that we know, who logged, we could easily find out if it is just a member or an administrator and render the elements by checking the level as simple as this:</p>
<pre class="brush: php; title: ; notranslate">
// for normal content
if(Yii::app()-&gt;user-&gt;isAdmin())
     echo 'Is administrator';
// for CMenus
$this-&gt;widget('zii.widgets.CMenu',array(
    array('label'=&gt;'Categories',
           'url'=&gt;array('/category/index'),
           'visible'=&gt;(Yii::app()-&gt;user-&gt;isAdmin()),
     //... More stuff
     //...
// for data chuncks
&lt;?php if(Yii::app()-&gt;user-&gt;isAdmin():?&gt;
&lt;b&gt;My HTML&lt;/b&gt;
&lt;?php endif;?&gt;
// for access rules
return array(
      array('allow',
        'actions'=&gt;array('create','delete','update'),
        'expression'=&gt;'$user-&gt;isAdmin()'
      ),
// ...
</pre>
<p><center><br />
<script type="text/javascript"><!--
google_ad_client = "pub-7060132287364604";
/* 468x60, creado 16/03/10 */
google_ad_slot = "9029910384";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script><br />
</center></p>
<a href="http://twitter.com/?status=RT%20%40%3A%20Implementing%20a%20User%20Level%20Access%20System%20-%20El%20Blog%20del%20Antonio%20http%3A%2F%2Fwww.ramirezcobos.com%2F2011%2F04%2F20%2Fimplementing-a-user-level-access-system%2F" class="tweet-this" ><img src="http://www.ramirezcobos.com/wp-content/plugins/simple-tweet/img/tweet.gif" title="Tweet this!" alt="Tweet this!" />Tweet this!</a>]]></content:encoded>
			<wfw:commentRss>http://www.ramirezcobos.com/2011/04/20/implementing-a-user-level-access-system/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>EGMaps 2.0 News: Layers, Polygons and Rectangles</title>
		<link>http://www.ramirezcobos.com/2011/03/24/egmaps-2-0-news-layers-polygons-and-rectangles/</link>
		<comments>http://www.ramirezcobos.com/2011/03/24/egmaps-2-0-news-layers-polygons-and-rectangles/#comments</comments>
		<pubDate>Thu, 24 Mar 2011 08:45:08 +0000</pubDate>
		<dc:creator>Antonio Ramirez</dc:creator>
				<category><![CDATA[How To]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Yii]]></category>
		<category><![CDATA[EGMap]]></category>
		<category><![CDATA[News]]></category>
		<guid isPermaLink="false">http://www.ramirezcobos.com/?p=831</guid>
		<description><![CDATA[The new version of EGMaps 2.0 is about to see the light. In the meantime new features have been included and are available through the SVN source at google&#8217;s code. Even though we are planning many more features, the following  are the list of the newly inserted features of the Yii extension till  [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_834" class="wp-caption alignright" style="width: 310px"><a rel="attachment wp-att-834" href="http://www.ramirezcobos.com/2011/03/24/egmaps-2-0-news-layers-polygons-and-rectangles/captura-de-pantalla-2011-03-24-a-las-09-41-48/"><img class="size-medium wp-image-834" title="Circles and Rectangles" src="http://www.ramirezcobos.com/wp-content/uploads/2011/03/Captura-de-pantalla-2011-03-24-a-las-09.41.48-300x177.png" alt="" width="300" height="177" /></a><p class="wp-caption-text">Overlays</p></div>
<p>The new version of EGMaps 2.0 is about to see the light. In the meantime new features have been included and are available <a href="http://code.google.com/p/egmap/source/checkout">through the SVN source at google&#8217;s code</a>. Even though we are planning many more features, the following  are the list of the newly inserted features of the Yii extension till date:</p>
<ul>
<li>Polygons (committer <a href="http://www.yiiframework.com/forum/index.php?/user/14177-matt-kay/">Matthias Kay</a>)</li>
<li>Rectangles</li>
<li>Circles</li>
<li>Bicycling Layer</li>
<li>Traffic Layer</li>
<li>Panoramio Layer</li>
</ul>
<h3>Polygon Example</h3>
<pre class="brush: php; title: ; notranslate">
Yii::import('ext.egmap.*');
$gMap = new EGMap();
$gMap-&gt;setWidth(588);
$gMap-&gt;setHeight(345);
$gMap-&gt;zoom = 3;
$gMap-&gt;mapTypeControlOptions = array(
 'position'=&gt; EGMapControlPosition::RIGHT_TOP,
 'style'=&gt;EGMap::MAPTYPECONTROL_STYLE_DROPDOWN_MENU
);
$gMap-&gt;setCenter(34.04924594193164, -118.24104309082031);
$coords = array();
$coords[] = new EGMapCoord(25.774252, -80.190262);
$coords[] = new EGMapCoord(18.466465, -66.118292);
$coords[] = new EGMapCoord(32.321384, -64.75737);
$coords[] = new EGMapCoord(25.774252, -80.190262);
$polygon = new EGMapPolygon($coords);
$gMap-&gt;addPolygon($polygon);
$gMap-&gt;centerOnPolygons();
$gMap-&gt;zoomOnPolygons(0.1);
$gMap-&gt;renderMap(array(),'en','ES');
</pre>
<h3>Circle and Rectangle Example</h3>
<pre class="brush: php; title: ; notranslate">
Yii::import('ext.egmap.*');
$gMap = new EGMap();
$gMap-&gt;setWidth(588);
$gMap-&gt;setHeight(345);
$gMap-&gt;zoom = 3;
$gMap-&gt;mapTypeControlOptions = array(
 'position'=&gt; EGMapControlPosition::RIGHT_TOP,
 'style'=&gt;EGMap::MAPTYPECONTROL_STYLE_DROPDOWN_MENU
);
$gMap-&gt;setCenter(34.04924594193164, -118.24104309082031);
$circle = new EGMapCircle(new EGMapCoord(34.04924594193164, -118.24104309082031));
$circle-&gt;radius = 300000;
// we can even attach info windows to the overlay!
$circle-&gt;addHtmlInfoWindow(new EGMapInfoWindow('Hey! I am a circlel!'));
$gMap-&gt;addCircle($circle);
$bounds = new EGMapBounds(new EGMapCoord(25.774252, -80.190262),new EGMapCoord(32.321384, -64.75737) );
$rec = new EGMapRectangle($bounds);
$rec-&gt;addHtmlInfoWindow(new EGMapInfoWindow('Hey! I am a rectangle!'));
$gMap-&gt;addRectangle($rec);
$gMap-&gt;renderMap(array(),'en','ES');
</pre>
<h3>Panoramio Layer Example</h3>
<pre class="brush: php; title: ; notranslate">
$gMap = new EGMap();
$gMap-&gt;setWidth(588);
$gMap-&gt;setHeight(345);
$gMap-&gt;zoom = 3;
$gMap-&gt;mapTypeControlOptions = array(
 'position'=&gt; EGMapControlPosition::RIGHT_TOP,
 'style'=&gt;EGMap::MAPTYPECONTROL_STYLE_DROPDOWN_MENU
);
$gMap-&gt;setCenter(34.04924594193164, -118.24104309082031);
// we can also use the same way TRAFFIC and BICYCLING layers
$gMap-&gt;setLayer(new EGMapLayer(EGMapLayer::PANORAMIO));
$gMap-&gt;renderMap(array(),'en','ES');
</pre>
<p>The extension has also been updated its reverse geocoding (committer <a href="http://www.yiiframework.com/forum/index.php?/user/6867-say-ten/">Say_Ten</a>).</p>
<p>Please, remember that in order to work with the above examples you require to download the svn source from the google code, not the zipped package on Yii&#8217;s repository. The extension will be updated when we reach the following goals:</p>
<ul>
<li>Elevation Paths</li>
<li>Polylines</li>
<li>Ground Overlays</li>
<li>Animations</li>
<li>Map Styling</li>
</ul>
<p>&nbsp;<br />
<script type="text/javascript"><!--
google_ad_client = "pub-7060132287364604";
/* 468x60, creado 16/03/10 */
google_ad_slot = "9029910384";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></p>
<p>&nbsp;</p>
<a href="http://twitter.com/?status=RT%20%40%3A%20EGMaps%202.0%20News%3A%20Layers%2C%20Polygons%20and%20Rectangles%20-%20El%20Blog%20del%20Antonio%20http%3A%2F%2Fwww.ramirezcobos.com%2F2011%2F03%2F24%2Fegmaps-2-0-news-layers-polygons-and-rectangles%2F" class="tweet-this" ><img src="http://www.ramirezcobos.com/wp-content/plugins/simple-tweet/img/tweet.gif" title="Tweet this!" alt="Tweet this!" />Tweet this!</a>]]></content:encoded>
			<wfw:commentRss>http://www.ramirezcobos.com/2011/03/24/egmaps-2-0-news-layers-polygons-and-rectangles/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>How to use a Widget as an Action Provider</title>
		<link>http://www.ramirezcobos.com/2011/02/17/how-to-use-a-widget-as-an-action-provider/</link>
		<comments>http://www.ramirezcobos.com/2011/02/17/how-to-use-a-widget-as-an-action-provider/#comments</comments>
		<pubDate>Thu, 17 Feb 2011 20:20:38 +0000</pubDate>
		<dc:creator>Antonio Ramirez</dc:creator>
				<category><![CDATA[How To]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Yii]]></category>
		<guid isPermaLink="false">http://www.ramirezcobos.com/?p=818</guid>
		<description><![CDATA[At the Yii forum there a good question about this matter, and most of us where curious on how this feature actually works.
As usual in the API docs it was clearly written but sometimes the text just sounds like a test for a car driver license. Nevertheless, after creating a test scenario, I found  [...]]]></description>
			<content:encoded><![CDATA[<p><a rel="attachment wp-att-612" href="http://www.ramirezcobos.com/2010/10/28/how-to-use-jqueryslidemenu-with-yii%e2%80%99s-cmenu/yii/"><img class="alignright size-full wp-image-612" title="Yii Framework" src="http://www.ramirezcobos.com/wp-content/uploads/2010/10/Yii.png" alt="Yii Framework" width="160" height="160" /></a>At the <a href="http://www.yiiframework.com/forum/index.php?/topic/16357-how-to-use-widget-as-action-provider/page__pid__81325#entry81325">Yii forum there a good question</a> about this matter, and most of us where curious on how this feature actually works.</p>
<p>As usual in the API docs it was clearly written but sometimes the text just sounds like a test for a car driver license. Nevertheless, after creating a test scenario, I found the solution and this is article is to show you exactly how this is done.</p>
<h3>Why would I need an action provider?</h3>
<p>Well, imagine you have lots of general actions that could be shared among controllers. It is true that by setting the actions() function to point to the external CAction classes files but just imagine that those functions are encapsulated by just a class (a widget in this case) and<a href="http://www.yiiframework.com/doc/api/1.1/CController#actions-detail"> you just need a line of code</a> to import all of its actions.</p>
<h3>First Step: Create your Action</h3>
<p>For the sake of the article we creating an action named getData that supposed to be shared among the whole project and saved with the name <strong>getData.php</strong> on our <strong>protected/components/actions</strong> folder.</p>
<pre class="brush: php; title: ; notranslate">
&lt;?php
class getData extends CAction{
	public function run(){
		echo 'HELLO WORLD';
	}
}
</pre>
<h3>Second Step: configure the Widget</h3>
<p>To transform a Widget into an action provider is quite easy (once you know of course). The only thing we need to do is to set the <strong>static method actions()</strong>. As you will see on the following code, we name the action as <strong>GetData</strong> and that is the action that will be called in our route. We are going to save the following widget in our <strong>protected/components/</strong> folder with the name <strong>testProvider.php.</strong></p>
<pre class="brush: php; title: ; notranslate">
class testProvider extends CWidget{
	public static function actions(){
		return array(
                   // naming the action and pointing to the location
                   // where the external action class is
		   'GetData'=&gt;'application.components.actions.getData',
		);
	}
}
</pre>
<h3>Step 3: Configure our Controller</h3>
<p>Finally we set our controller&#8217;s <strong>actions()</strong> function to point to our actions provider.</p>
<pre class="brush: php; title: ; notranslate">
// This function is in this example
// on SiteController
public function actions()
{
        return array(
        // test. is the prefix we are going to use
        // for all action within the actionProvider class
        // we point to the location where the provider
        // is
	'test.'=&gt;'application.components.testProvider',
	);
}
</pre>
<p>Now we can call the action as controllerID/actionPrefix.actionID</p>
<pre class="brush: php; title: ; notranslate">
index.php?site/test.GetData
</pre>
<p><center><br />
<a href="http://www.amazon.com/gp/product/1847199585/ref=as_li_tf_tl?ie=UTF8&#038;tag=ibizapirates-20&#038;linkCode=as2&#038;camp=1789&#038;creative=9325&#038;creativeASIN=1847199585">Agile Web Application Development with Yii 1.1 and PHP5</a><img src="http://www.assoc-amazon.com/e/ir?t=ibizapirates-20&#038;l=as2&#038;o=1&#038;a=1847199585" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /><br />
</center></p>
<p><center><br />
<script type="text/javascript"><!--
google_ad_client = "pub-7060132287364604";
/* 468x60, creado 16/03/10 */
google_ad_slot = "9029910384";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script><br />
</center></p>
<a href="http://twitter.com/?status=RT%20%40%3A%20How%20to%20use%20a%20Widget%20as%20an%20Action%20Provider%20-%20El%20Blog%20del%20Antonio%20http%3A%2F%2Fwww.ramirezcobos.com%2F2011%2F02%2F17%2Fhow-to-use-a-widget-as-an-action-provider%2F" class="tweet-this" ><img src="http://www.ramirezcobos.com/wp-content/plugins/simple-tweet/img/tweet.gif" title="Tweet this!" alt="Tweet this!" />Tweet this!</a>]]></content:encoded>
			<wfw:commentRss>http://www.ramirezcobos.com/2011/02/17/how-to-use-a-widget-as-an-action-provider/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Yii News: Query Caching</title>
		<link>http://www.ramirezcobos.com/2011/02/15/yii-news-query-caching/</link>
		<comments>http://www.ramirezcobos.com/2011/02/15/yii-news-query-caching/#comments</comments>
		<pubDate>Tue, 15 Feb 2011 17:41:54 +0000</pubDate>
		<dc:creator>Antonio Ramirez</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Yii]]></category>
		<category><![CDATA[News]]></category>
		<guid isPermaLink="false">http://www.ramirezcobos.com/?p=814</guid>
		<description><![CDATA[Starting from version 1.1.7 Yii Framework will include a really great feature: query caching. This new feature is built on top of data caching, query caching stores the result of a DB query in cache and may thus save the DB query execution time if the same query is requested in future, as the  [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.ramirezcobos.com/2010/10/28/how-to-use-jqueryslidemenu-with-yii%e2%80%99s-cmenu/yii/" rel="attachment wp-att-612"><img src="http://www.ramirezcobos.com/wp-content/uploads/2010/10/Yii.png" alt="Yii Framework" title="Yii Framework" width="160" height="160" class="alignright size-full wp-image-612" /></a>Starting from version 1.1.7 Yii Framework will include a really great feature: query caching. This new feature is built on top of data caching, query caching stores the result of a DB query in cache and may thus save the DB query execution time if the same query is requested in future, as the result can be directly served from the cache -<em>After this, I truly would like to see some proper benchmarks versus other frameworks out there on query requests</em>.</p>
<h3>Using Query Caching with DAO</h3>
<p>We need to use CDbConnection::cache() method in order to perform DB queries. The following example specifies that the query results should remain valid in cache for 1000 seconds. If we execute the same lines of code within the next 100 seconds one more time, the query results will be returned from cache without executing the SQL statement again.</p>
<pre class="brush: php; title: ; notranslate">
$sql = 'SELECT * FROM tbl_post LIMIT 20';
$rows = Yii::app()-&gt;db-&gt;cache(1000)-&gt;createCommand($sql)-&gt;queryAll();
</pre>
<p>We can also specify a cache dependency for the cached query result so if there is any changes to the table, then we can invalidate the query results. In the next code, we create a dependency which checks the maximum `update_time` of all records in a table. If the value has any change, it means the table data is changed and we should invalidate the query cache.</p>
<pre class="brush: php; title: ; notranslate">
$sql = 'SELECT * FROM tbl_post LIMIT 20';
$dependency = new CDbCacheDependency('SELECT MAX(update_time) FROM tbl_post');
$rows = Yii::app()-&gt;db-&gt;cache(1000, $dependency)-&gt;createCommand($sql)-&gt;queryAll();
</pre>
<h3>Using Query Caching with CActiveRecord</h3>
<p>This new feature can also be used with CActiveRecord</p>
<pre class="brush: php; title: ; notranslate">
$posts = Post::model()-&gt;cache(1000)-&gt;findAll();
// query caching can also be used with relations
$posts = Post::model()-&gt;cache(1000)-&gt;with('author')-&gt;findAll();
</pre>
<p>If you wish to have a look at this cool feature, go and grab the SVN repository on google: <a href="http://code.google.com/p/yii/source/checkout">http://code.google.com/p/yii/source/checkout</a></p>
<p><center><br />
<script type="text/javascript"><!--
google_ad_client = "pub-7060132287364604";
/* 468x60, creado 16/03/10 */
google_ad_slot = "9029910384";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script><br />
</center></p>
<a href="http://twitter.com/?status=RT%20%40%3A%20Yii%20News%3A%20Query%20Caching%20%20-%20El%20Blog%20del%20Antonio%20http%3A%2F%2Fwww.ramirezcobos.com%2F2011%2F02%2F15%2Fyii-news-query-caching%2F" class="tweet-this" ><img src="http://www.ramirezcobos.com/wp-content/plugins/simple-tweet/img/tweet.gif" title="Tweet this!" alt="Tweet this!" />Tweet this!</a>]]></content:encoded>
			<wfw:commentRss>http://www.ramirezcobos.com/2011/02/15/yii-news-query-caching/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>A Reverse Geolocator Tool with EGMap 2.0 Extension</title>
		<link>http://www.ramirezcobos.com/2011/02/05/a-reverse-geolocator-tool-with-egmap-2-0-extension/</link>
		<comments>http://www.ramirezcobos.com/2011/02/05/a-reverse-geolocator-tool-with-egmap-2-0-extension/#comments</comments>
		<pubDate>Sat, 05 Feb 2011 17:12:04 +0000</pubDate>
		<dc:creator>Antonio Ramirez</dc:creator>
				<category><![CDATA[How To]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Tools]]></category>
		<category><![CDATA[Yii]]></category>
		<category><![CDATA[EGMap]]></category>
		<guid isPermaLink="false">http://www.ramirezcobos.com/?p=797</guid>
		<description><![CDATA[I have been requested to create an article about a reverse geolocator tool, that is a tool to find out the latitude and longitude of a location, to include on our CMS, and here it is.
Styling, Javascript and HTML
First of all, we are going to write the HTML that will work with this example, it  [...]]]></description>
			<content:encoded><![CDATA[<p><a rel="attachment wp-att-800" href="http://www.ramirezcobos.com/2011/02/05/a-reverse-geolocator-tool-with-egmap-2-0-extension/reverse-geolocator-egmap-yii/"><img class="alignright size-medium wp-image-800" title="Reverse-geolocator-EGMap-Yii" src="http://www.ramirezcobos.com/wp-content/uploads/2011/02/Reverse-geolocator-EGMap-Yii-300x280.png" alt="" width="300" height="280" /></a>I have been requested to create an article about a reverse geolocator tool, that is a tool to find out the latitude and longitude of a location, to include on our CMS, and here it is.</p>
<h3>Styling, Javascript and HTML</h3>
<p>First of all, we are going to write the HTML that will work with this example, it won&#8217;t styled as the example picture displayed, which is the tool I created for a project I am working now, but don&#8217;t you worry as this article will provide you with the scripts and routines to create your own.</p>
<p>Write the following style on the HEAD section of your HTML page:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;style&gt;
  div#map {
    position: relative;
  }
  div#crosshair {
    position: absolute;
/*
     the top will be half of the width of the map
     less 50% of its size more or less
     to center the image correctly on the map
*/
    top: 192px;
    height: 19px;
    width: 19px;
    left: 50%;
    margin-left: -8px;
    display: block;
/* we are going to borrow a crosshair gif from google */
    background: url(http://gmaps-samples-v3.googlecode.com/svn/trunk/geocoder/crosshair.gif);
    background-position: center center;
    background-repeat: no-repeat;
}
&lt;/style&gt;
</pre>
<p>Now, some Javascript functions that will allow us to get the information from the map</p>
<pre class="brush: jscript; title: ; notranslate">
&lt;script type=&quot;text/javascript&quot;&gt;
  //
  // function to get the latitude and longitude
  // and place them on the test fields
  function setLatLngToClass(){
	if(document.getElementById('test_latitude'))
	 	document.getElementById('test_latitude').value = map.getCenter().lat();
	if(document.getElementById('test_longitude'))
		document.getElementById('test_longitude').value = map.getCenter().lng();
  }
  //
  // function to get Centered Latitude and Longitude points
  function getCenterLatLngText() {
    return '(' + map.getCenter().lat() +', '+ map.getCenter().lng() +')';
  }
  //
  // function to call when the center of the map
  // has changed. Center information will be
  // collected and displayed on the document
  // elements
  function centerChanged() {
    centerChangedLast = new Date();
    var latlng = getCenterLatLngText();
    document.getElementById('latlng').innerHTML = latlng;
    document.getElementById('formatedAddress').innerHTML = '';
    currentReverseGeocodeResponse = null;
  }
  //
  // Collects reverse center location
  function reverseGeocode() {
    reverseGeocodedLast = new Date();
    geocoder.geocode({latLng:map.getCenter()},reverseGeocodeResult);
  }
  //
  // Displays collected reverse geocoded results
  // and displays them on document elements
  function reverseGeocodeResult(results, status) {
    currentReverseGeocodeResponse = results;
    if(status == 'OK') {
      if(results.length == 0) {
        document.getElementById('formatedAddress').innerHTML = 'None';
      } else {
        document.getElementById('formatedAddress').innerHTML = results[0].formatted_address;
      }
    } else {
      document.getElementById('formatedAddress').innerHTML = 'Error';
    }
  }
  //
  // geocodes the address inserted
  function geocode() {
    var address = document.getElementById(&quot;address&quot;).value;
    geocoder.geocode({
      'address': address,
      'partialmatch': true}, geocodeResult);
  }
  function geocodeResult(results, status) {
    if (status == 'OK' &amp;&amp; results.length &gt; 0) {
      map.fitBounds(results[0].geometry.viewport);
    } else {
      alert(&quot;Geocode was not successful for the following reason: &quot; + status);
    }
  }
 //
 // adds marker to the center of the map
  function addMarkerAtCenter() {
    var marker = new google.maps.Marker({
        position: map.getCenter(),
        map: map
    });
    var text = 'Lat/Lng: ' + getCenterLatLngText();
    if(currentReverseGeocodeResponse) {
      var addr = '';
      if(currentReverseGeocodeResponse.size == 0) {
        addr = 'None';
      } else {
        addr = currentReverseGeocodeResponse[0].formatted_address;
      }
      text = text + '&lt;br&gt;' + 'address: &lt;br&gt;' + addr;
    }
    var infowindow = new google.maps.InfoWindow({ content: text });
    google.maps.event.addListener(marker, 'click', function() {
      infowindow.open(map,marker);
    });
  }
&lt;/script&gt;
</pre>
<p>Our HTML on this example will be the following one:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;body style=&quot;background:white&quot;&gt;
&lt;div class=&quot;form&quot;&gt;
Find by address:
 &lt;input type=&quot;text&quot; id=&quot;address&quot; style=&quot;width:300px&quot;/&gt;
 &lt;button type=&quot;button&quot; class=&quot;small&quot;onclick=&quot;geocode()&quot;&gt;Go to Address&lt;/button&gt;
  &lt;ul&gt;
     &lt;li&gt;Lat/Lng:&amp;nbsp;&lt;span id=&quot;latlng&quot;&gt;&lt;/span&gt;&lt;/li&gt;
     &lt;li&gt;Address:&amp;nbsp;&lt;span id=&quot;formatedAddress&quot;&gt;&lt;/span&gt;&lt;/li&gt;
     &lt;li&gt;Zoom Level:&amp;nbsp;&lt;span id=&quot;zoom_level&quot;&gt;&lt;?php echo $zoom;?&gt;&lt;/span&gt;&lt;/li&gt;
 &lt;/ul&gt;
&lt;/div&gt;
&lt;div id=&quot;map&quot;&gt;
    &lt;div id=&quot;map_canvas&quot; style=&quot;width:100%; height:400px&quot;&gt;&lt;/div&gt;
    &lt;div id=&quot;crosshair&quot;&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;overflow:hidden;width:100%;text-align:right&quot;&gt;
&lt;button type=&quot;button&quot; class=&quot;small&quot; onclick=&quot;setLatLngToClass()&quot;&gt;Set Latitude &amp; Longitude&lt;/button&gt;
&lt;button type=&quot;button&quot; class=&quot;small&quot; onclick=&quot;addMarkerAtCenter()&quot;&gt;Add Marker at Center&lt;/button&gt;
&lt;/div&gt;
&lt;hr&gt;
Latitude: &lt;input id=&quot;test_latitude&quot; value=&quot;&quot;/&gt; Longitude: &lt;input id=&quot;test_longitude&quot; value=&quot;&quot;/&gt;
&lt;/hr&gt;
&lt;/body&gt;
</pre>
<h3>Using EGMap 2.0 Extension</h3>
<p>Finally, we are going to use EGMap 2.0 extension to automate the rest of the tasks to render our map.</p>
<pre class="brush: php; title: ; notranslate">
Yii::import('ext.gmaps.*');
// center the map
// wherever you want
$latitude = 39.72098197183251;
$longitude = 2.9115524999999964;
$zoom = 8;
$gMap = new EGMap();
$gMap-&gt;setJsName('map');
$gMap-&gt;width = '100%';
$gMap-&gt;height = '400';
$gMap-&gt;setCenter($latitude, $longitude);
$gMap-&gt;zoom = 8;
$gMap-&gt;addGlobalVariable('geocoder');
$gMap-&gt;addGlobalVariable('centerChangedLast');
$gMap-&gt;addGlobalVariable('reverseGeocodedLast');
$gMap-&gt;addGlobalVariable('currentReversGeocodeResponse');
$gMap-&gt;addEvent(
     new EGMapEvent(
             'zoom_changed',
             'document.getElementById(&quot;zoom_level&quot;).innerHTML = map.getZoom();'));
$gMap-&gt;addEvent(new EGMapEvent('center_changed','centerChanged',false));
$gEvent = new EGMapEvent('dblclick','map.setZoom(map.getZoom() +1)');
$gMap-&gt;appendMapTo('#map_canvas');
$gMap-&gt;renderMap(array(
    'geocoder = new google.maps.Geocoder();',
    $gEvent-&gt;getDomEventJs('crosshair'),
    'reverseGeocodedLast= new Date();',
    'centerChagedLast = new Date();',
    'setInterval(function(){
        if((new Date()).getSeconds() - centerChangedLast.getSeconds() &gt; 1) {
        if(reverseGeocodedLast.getTime() &lt; centerChangedLast.getTime())
          reverseGeocode();
      }
    },1000);',
    'centerChanged();'
));
</pre>
<h3>Important</h3>
<p>If you are going to run this example, please be aware that in order to display it properly in a controller, all of the above have to be the content of a layout, otherwise, if you are using renderPartial (that you can), make sure you force to true the parameter &#8216;processOutput&#8217; of the mentioned function (ie $this-&gt;renderPartial(&#8216;view&#8217;,null,false,true) )</p>
<p><center><br />
<script type="text/javascript"><!--
google_ad_client = "pub-7060132287364604";
/* 468x60, creado 16/03/10 */
google_ad_slot = "9029910384";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script><br />
</center></p>
<a href="http://twitter.com/?status=RT%20%40%3A%20A%20Reverse%20Geolocator%20Tool%20with%20EGMap%202.0%20Extension%20-%20El%20Blog%20del%20Antonio%20http%3A%2F%2Fwww.ramirezcobos.com%2F2011%2F02%2F05%2Fa-reverse-geolocator-tool-with-egmap-2-0-extension%2F" class="tweet-this" ><img src="http://www.ramirezcobos.com/wp-content/plugins/simple-tweet/img/tweet.gif" title="Tweet this!" alt="Tweet this!" />Tweet this!</a>]]></content:encoded>
			<wfw:commentRss>http://www.ramirezcobos.com/2011/02/05/a-reverse-geolocator-tool-with-egmap-2-0-extension/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>EGMap Google Maps Extension for Yii</title>
		<link>http://www.ramirezcobos.com/2010/12/22/egmap-google-maps-extension-for-yii/</link>
		<comments>http://www.ramirezcobos.com/2010/12/22/egmap-google-maps-extension-for-yii/#comments</comments>
		<pubDate>Wed, 22 Dec 2010 18:38:34 +0000</pubDate>
		<dc:creator>Antonio Ramirez</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Tools]]></category>
		<category><![CDATA[Yii]]></category>
		<category><![CDATA[Extension]]></category>
		<guid isPermaLink="false">http://www.ramirezcobos.com/?p=740</guid>
		<description><![CDATA[
Introduction
I had to develop a Google maps extension for my current personal project and I did some research in order not to re-invent the wheel.
The best of them all was a Symphony plugin developed by Fabrice Bernhard. I didn&#8217;t want to create a wrapper so I decided to modify its code -in some  [...]]]></description>
			<content:encoded><![CDATA[<p><a rel="attachment wp-att-612" href="http://www.ramirezcobos.com/2010/10/28/how-to-use-jqueryslidemenu-with-yii%e2%80%99s-cmenu/yii/"><img class="alignright size-full wp-image-612" title="Yii Framework" src="http://www.ramirezcobos.com/wp-content/uploads/2010/10/Yii.png" alt="Yii Framework" width="160" height="160" /></a></p>
<h3>Introduction</h3>
<p>I had to develop a Google maps extension for my current personal project and I did some research in order not to re-invent the wheel.</p>
<p>The best of them all was a <a title="sfEasyGMailPlugin" href="http://www.symfony-project.org/plugins/sfEasyGMapPlugin">Symphony plugin developed by Fabrice Bernhard</a>. I didn&#8217;t want to create a wrapper so I decided to modify its code -in some cases rewriting the whole class, in order to create a full Extension built with Yii.</p>
<p>The features of this extension are very large to explain, therefore I will concentrate my next posts to fully explain by example the wonders of this extension.</p>
<h3>Requirements</h3>
<p>Developed with latest stable version of Yii (1.5)</p>
<h3>Usage</h3>
<p>Unzip its contents and place the <em>gmaps</em> folder into your protected/extensions folder.</p>
<h3>A Reallly Easy Example</h3>
<p>Displaying a Marker with an Info window.</p>
<p>Note: This example was written in a <strong>view file</strong>.</p>
<pre class="brush: php; title: ; notranslate">
    // import the library
    Yii::import('ext.gmaps.*');
    $gMap = new EGMap();
    $gMap-&gt;setZoom(13);
    $gMap-&gt;setCenter(39.721089311812094, 2.91165944519042);
    // Create GMapInfoWindow
    $info_window = new EGMapInfoWindow('&lt;div&gt;I was living here as a kid!&lt;/div&gt;');
    // Create marker
    $marker = new EGMapMarker(39.721089311812094, 2.91165944519042, array('title' =&gt; '&quot;My Town&quot;'));
    $marker-&gt;addHtmlInfoWindow($info_window);
    $gMap-&gt;addMarker($marker);
    $gMap-&gt;renderMap();
</pre>
<p><strong>Result</strong><br />
<a href="http://www.ramirezcobos.com/wp-content/uploads/2010/12/Captura-de-pantalla-2010-12-22-a-las-19.26.10.png"><img class="alignleft size-medium wp-image-741" title="EGMap Example 1" src="http://www.ramirezcobos.com/wp-content/uploads/2010/12/Captura-de-pantalla-2010-12-22-a-las-19.26.10-300x297.png" alt="" width="300" height="297" /></a></p>
<div style="clear:both">&nbsp;</div>
<h3>Resources</h3>
<p><a href="http://www.yiiframework.com/extension/egmap/">Download the Extension</a><br />
<a href="http://www.yiiframework.com/forum/index.php?/topic/14445-egmap-google-maps-extension">Bug Reports &amp; Positive Feedback</a></p>
<p><center><br />
<script type="text/javascript"><!--
google_ad_client = "pub-7060132287364604";
/* 468x60, creado 16/03/10 */
google_ad_slot = "9029910384";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script><br />
</center></p>
<a href="http://twitter.com/?status=RT%20%40%3A%20EGMap%20Google%20Maps%20Extension%20for%20Yii%20-%20El%20Blog%20del%20Antonio%20http%3A%2F%2Fwww.ramirezcobos.com%2F2010%2F12%2F22%2Fegmap-google-maps-extension-for-yii%2F" class="tweet-this" ><img src="http://www.ramirezcobos.com/wp-content/plugins/simple-tweet/img/tweet.gif" title="Tweet this!" alt="Tweet this!" />Tweet this!</a>]]></content:encoded>
			<wfw:commentRss>http://www.ramirezcobos.com/2010/12/22/egmap-google-maps-extension-for-yii/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
	</channel>
</rss>

<!-- Served from: www.ramirezcobos.com @ 2012-02-06 17:13:07 by W3 Total Cache -->
