Thursday, December 16, 2010

Published ES3 Extension

Just published an extension on the Yii framework site for interacting with Amazon S3. It's very nerve wreaking to share an Extension for some reason, so I've just never posted one before.

http://www.yiiframework.com/extension/es3/

Pretty basic but quite handy if you use their services and need to push content to them. Hopefully this one will be useful!

Forum for questions/comments/concerns is here: http://www.yiiframework.com/forum/index.php?/topic/14265-extension-es3/


The extension is a simple Yii wrapper for the extremely effective S3 class created by Donovan Schönknecht which can be found here: http://undesigned.org.za/2007/10/22/amazon-s3-php-class

Tuesday, November 9, 2010

Posting Multiple of the Same model within a form

Recently, I was asked about posting multiple models of the same class within a form and how that can be accomplished.

The solution is to override the default name values for the form items to allow them to be presented in an array format, then in the controller, process each array item for the Class.

Lets say that I have a set of user bookmarks (Bookmark), and I want them to be able to update all the bookmarks from a single administrative page. This is a little rough, but it should explain the concept clearly:

Friday, October 29, 2010

Publishing to alternate assets directory

Sometimes, it's not possible to use the standard 'assets' directory for publishing assets. After struggling with this for a while, I discovered that the solution is, as is typical with Yii, even simpler than I could have hoped for.

Tuesday, September 7, 2010

Action paramater binding in Yii 1.1.4

The new Yii 1.1.4 contains numerous improvements. One that I wasn't clear on from the changelog was  the line saying "automatic action parameter binding" for $_GET values.  This is a very subtle way of saying that they've made it much easier to handle some of the 'grunt work' for actions that work with multiple $_GET variables.


http://www.yiiframework.com/doc/guide/basics.controller#action-parameter-binding

Quite simply pass in the name of the $_GET variables to the controller action method as parameters, including any default value you would like applied if they did not specify a value. 

Easily looked over, but very nice addition to the framework!!

Saturday, August 7, 2010

Using Controller Filters

So, I'm sure by now everyone's used the very familiar "accessControl" filter, but so much of that happens behind the scenes. This post goes into how to create your own filters and how they can be useful.

Information about how to set up filters can be found here: http://www.yiiframework.com/doc/guide/basics.controller#filter

The method-based implementation of the filters is extremely straight forward, simply add the method to the controller in the form of public function filterXYZ( $c ) then add XYZ to your array of filters:

Thursday, June 24, 2010

Adding Foreign Keys Manually

Using MyISAM tables (in MySQL), I'm unable to set foreign keys in the database. However, I'm working with several tables which utilize foreign key type relationships. The problem was how to get Yii to recognize those relationships properly.

This one took me a while to figure out. With the help of the experts over at the Yii Forums, I was able to put together this solution.

Tuesday, June 22, 2010

Saving encrypted passwords for new users

When using PASSWORD() encrypted passwords for users, I need to save the encrypted version when the file is created or when the password is changed. However, I don't want it to run the encryption every time the file is saved if it's pulled in the encrypted value already.

Putting the job of encrypting the password on the User model, I've added an encryptPassword() function to the model, which can be called by the controller after it receives the post data as such:

public function encryptPassword()
{
    $p = $this->userpass;
    $this->userpass = new CDbExpression('PASSWORD(:up)', array(':up'=>$p));
}

And modify the actionCreate as such:
...
$model->attributes = $_POST['User']; // existing line
if ( $model->validate()){    
   $model->encryptPassword();
   if ( $model->save( false )){   // modify existing line to pass in false param
      // .. existing code here
   }
} 
- OR -
To automate the process, alter the User model further by adding:
protected function beforeSave()
{
  if ( $this->isNewRecord )
     $this->encryptPassword();
  return parent::beforeSave();
}

Then, if you have a change password form, you can handle it in the same fashion.

Thursday, June 10, 2010

Yii User Authentication using MySQL PASSWORD()

This is a pretty simple thing, but it hitched me up for a while, so I thought it worth sharing/recording the solution.

If you use passwords stored with the MySQL PASSWORD() function, the suggested methods of authentication with UserIdentity need to be tweaked.

There are two ways that I have come up with to run the comparison. The first way is more secure, as it doesn't ever send the encrypted password back through the connection, but the second way allows you a more specific 'user found, but password is wrong' error.

Wednesday, May 12, 2010

Using Gii

This feature is new to the 1.1.2 release of Yii. I finally had a chance to look at it today, and I'm quite impressed thus far. This module allows for web access to the old yiic shell commands, and is extremely straight forward and easy to use. It shows you previews of the files to be generated, including whether the file is new or overwriting an existing file. It comes with 5 default Generators: Controller, crud, Form, Model and Module.

To use it, you need to first enable it in your config for the site. Be sure to note that it's only set to work on a localhost by default, so if you need to use it on a remote machine make sure to enter in your IP to the IP filters array.  Also note that if you're configured for path urls, you're going to have to modify the settings there as directed in the guide.

The link to the guide for Gii is here:
http://www.yiiframework.com/doc/guide/topics.gii

Wednesday, April 14, 2010

LoginRequired and Ajax Updates

My Issue:
If my user session times out while an access restricted page is visible (say I left it open overnight), and the user then clicks on a button that performs an ajax call, the login required display appears within the div that the ajax update should happen in, rather than replacing the entire current page.

Potential Solutions:
Option 1) Extend the CWebUser and override the loginRequired() function to check for $request->isAjaxRequest (this would then need to redirect to a page which causes a javascript redirect)

Option 2) Modify the Site actionLogin to check the request type and render a different page which causes a javascript redirect.

Option 2 is the least invasive method, so I am going to go with that option and see how things work out ;)

Site Note: Could override the controller->redirect method, but I don't want to necessarily block all redirects -- I can forsee needing to have one ajax view action redirect to another ajax view action. If the controller override was used, it would have to be done on every controller - hardly efficient.

Wednesday, March 31, 2010

Posting with multiple models

I spent a good bit of time trying to figure out how to render multiple models in a form and have them each validate properly.

Knowing the solution, it seems quite obvious, but it took a while to track down the proper syntax.

In this example I have a custom CForm which contains a few different $model properties, in addition to the base form data.

To call the validation on multiple models in the form, simply modify any calls of
CActiveForm::validate($model);
to use an array of models as the first parameter as such:
CActiveForm::validate( array($model, $model->subModel, $model->subModel2) );

Friday, March 26, 2010

Themes for Mobile

Just an 'aha' or a 'well duh' moment (depending on how you look at it), but I realized today that I could set up a theme for 'mobile' friendly display.

So, I create my new mobile theme and adjust the views accordingly.

Then in my index.php I run a check for known mobile browsers against the $_SERVER['HTTP_USER_AGENT'] and if found, I set $config to /protected/config/mobile.php instead of main.php

Primary difference being the theme set, though I imagine I might add a few other differences over time.

Thursday, March 25, 2010

ActiveDataProvider w/ Scopes!

http://www.yiiframework.com/extension/active-data-provider-with-scopes/

Very easy to install!!

Scopes allow you to predefine filters for the record set and apply them and chain them without having to rewrite the conditions.
(Guide to named scopes)

i.e., in the model:
   public function scopes(){
       return array(
           'enabled'=>array(
               'condition'=>'isEnabled=1',
           ),
           'newest'=>array(
               'order'=>'dateAdded DESC',
               'limit'=>5 
           ),
       );
   }

This extension simply allows you to use the same functionality with the DataProviders.

Simply import the EActiveDataProvider from the extensions directory.
Then, in the $criteria, I simply add the scope and call EActiveDataProvider instead of CActiveDataProvider.

The REALLY nice thing about the scopes is that if the business logic needs to change at some point, I can do so at a single point of entry -vs- customized criteria scattered around.

Yii and Themes

In the face of a total site redesign today, I realized I should begin using the themes features of Yii. This is where some of the true beauty of MVC comes into play.

Without a custom theme set up, the theme will default to the views in the /protected/views/ directory. Once you set up a theme, whenever it cannot find a specific view in the theme directory, it will go back to the default in the /protected/views/ directory and check there.

This is the guide reference on themes: http://www.yiiframework.com/doc/guide/topics.theming

Thursday, March 18, 2010

Custom Behavior Example/Test

Ok, so I originally thought I should write a widget for this, then I realized that this was a good example of a behavior that should be attachable to multiple components.

I want to give the ability for the page to trim a string if it's over a given length, and return the truncated string with an ellipsis or other marker. A quick search through the yii documentation/forums did not find anything already built that would do this (though I did find one article in polish that had a function for doing truncation ;) Alas, I do not read Polish).

I'm adding this link to the list of items to read on behaviors in Yii:
http://www.yiiframework.com/doc/guide/extension.use#behavior

Events & Behaviors in Yii - Initial Notes

This one is a work in progress as I try to figure out how to use this aspect correctly. This are my "notes" from reading these documents.

I'm basing this on the following two document references:
http://www.yiiframework.com/doc/cookbook/44
http://www.yiiframework.com/doc/guide/basics.component (section on events)

Wednesday, March 17, 2010

Yii Authentication via database

Yii has a wonderful AuthManager built in, but it's a little confusing to use so many people end up creating their own. This one drove me a little nuts for a bit, so I thought it would be a good place to start.   For the purposes here, I'm going to assume you've already added a db setting to your main Controller. For more information on how to do that, read here.

This is the starting point for today's adventure: http://www.yiiframework.com/doc/guide/topics.auth

The article above walks you through adjusting the UserIdentity (found in /protected/components/UserIdentity.php ) to pull information from a database table for users, override the ID of the UserIdentity class and set up some basic authentication rules, but you have to read between the lines to get it all complete.

Exploring Yii

I've lately been exploring the Yii framework for PHP and I'm very much a fan of it. However, the documentation can be less than helpful most of the time. So, I've decided to start writing down my thoughts and observations as I go through it in the hopes that it will help others in similar situations.

Information on the framework can be found here: http://www.yiiframework.com/

I do not profess to be a Yii expert in the least, I'm a novice and these are novice observations to help others who also have trouble reading between the lines of the Yii documentation.  I may throw in some more advanced items in the future, but for now, it is what it is.

And off we go...