Sticky Behavior

March 27th, 2010

This is a sticky behavior. It will cause the models it is attached to to remember the user’s last inputted value. In other words, the last value the user selected will be the default value the next time around the user fills out the form

It’s not perfectly reusable unless you follow the same naming standards as I do, so you may need to modify one or two lines of code (like the relation)

It designed for a multi-user application where users have their own stickies

Table:

CREATE TABLE IF NOT EXISTS `sticky` (
  `user_id` int(11) NOT NULL,
  `name` varchar(255) NOT NULL,
  `lastValue` varchar(255) NOT NULL,
  PRIMARY KEY (`user_id`,`name`)
);

Sticky Model

<?php
class Sticky extends CActiveRecord
{
	/**
	 * The followings are the available columns in table 'sticky':
	 * @var integer $user_id
	 * @var string $name
	 * @var string $lastValue
	 */
 
	/**
	 * Returns the static model of the specified AR class.
	 * @return CActiveRecord the static model class
	 */
	public static function model($className=__CLASS__)
	{
		return parent::model($className);
	}
 
	/**
	 * @return string the associated database table name
	 */
	public function tableName()
	{
		return 'sticky';
	}
 
	/**
	* @param int $user_id
	* @param string $name
	* @return Sticky (may be a new record if none found in database)
	*/
	public static function getSticky($user_id, $name) {
		$stickyAR = self::model()->findByPk(array('user_id'=>$user_id, 'name'=>$name));
 
		if ($stickyAR===null) {
			$stickyAR = new Sticky;
			$stickyAR->user_id = $user_id;
			$stickyAR->name = $name;
		}
		return $stickyAR;
	}
 
 
	/**
	 * THIS IS NOT NEEDED (but hey I'm going to leave it)
	 * @return array relational rules.
	 */
	public function relations()
	{
		return array(
			'user' => array(self::BELONGS_TO, 'User', 'user_id'),
		);
	}
}

Behavior

<?php
class StickyBehavior extends CActiveRecordBehavior
{
	/**
	* @var array array('stickyAttribute1', 'stickyAttribute2', ..)
	*/
	public $stickies = array();
 
	protected $stickyARS = array();
 
	/**
	* May need to modify
	* Gets the user id of the sticky.  Each user has his own stickies
	*/
	protected function getUserId() {
		return Yii::app()->user->id;	
	}
 
	/**
	* Handles filling attributes with stickies
	* Only executes on NEW records
	*/
	public function afterConstruct($event) {
		foreach ($this->stickies as $stickyAttribute) {
			$stickyName = $this->getStickyName($stickyAttribute);
			$stickyAR = Sticky::getSticky($this->getUserId(), $stickyName);
			if (!$stickyAR->getIsNewRecord())
				$this->owner->$stickyAttribute = $stickyAR->lastValue;
 
			$this->stickyARS[$stickyAttribute] = $stickyAR;
		}
	}
 
	/**
	* Updates the sticky value
	* Only does this for NEW RECORDS.  This seemed to make more sense to me,
	* but other people may want to change this
	*/
	public function afterSave($event) {
		if (!$this->owner->getIsNewRecord())
			return;
		foreach ($this->stickies as $stickyAttribute) {
			$stickyAR = $this->stickyARS[$stickyAttribute];
 
			$stickyAR->lastValue = $this->owner->$stickyAttribute;
			$stickyAR->save();
		}
	}
 
	/**
	* Gets the sticky name as stored in the database (prefixes attribute name with the model name)
	* 
	* @param string stickyAttribute
	*/
	protected function getStickyName($stickyAttribute) {
		return get_class($this->owner).'.'.$stickyAttribute;
	}
}

Example of attachment to model

<?php
	public function behaviors() {
		return array(
			'sticky'=>array(
				'class'=>'application.models.StickyBehavior',
				'stickies'=>array('gym_id'),
			),
		);
	}

There is also a forum thread

Enjoy!

Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • Technorati
  • Reddit
  • RSS
  • Twitter

Categories: Uncategorized

Leave a comment

Leave a comment


eight × 9 =

Feed

http://php-thoughts.cubedwater.com / Sticky Behavior