Yii Framework Forum: Sticky behavior - Yii Framework Forum

Jump to content

Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

Sticky behavior for remembering the "last value"

#1 User is offline   jonah 

  • Advanced Member
  • Yii
  • Group: Yii Dev Team
  • Posts: 733
  • Joined: 27-November 08
  • Location:California (US)

Posted 27 March 2010 - 02:16 PM

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
	public function behaviors() {
		return array(
			'sticky'=>array(
				'class'=>'application.models.StickyBehavior',
				'stickies'=>array('gym_id'),
			),
		);
	}

http://php-thoughts.cubedwater.com - my bloggings about Yii
1

#2 User is offline   Dana 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 245
  • Joined: 18-February 10
  • Location:Florida, USA

Posted 29 March 2010 - 04:14 PM

This is a great, thank you! I was able to use it easily and quickly by simply updating the getUserId method.

Very minor typo that you may want to correct for anyone using the code above -- "class Stickybehavior extends CActiveRecordbehavior" <-- should be CActiveRecordBehavior

Edit: Odd -- must be a forum issue. It automatically changes that to a lowercase B in RecordBehavior. So I guess it's just a note to anyone copying that they need to correct that in their copy.
0

#3 User is offline   Mike 

  • Elite Member
  • PipPipPipPipPip
  • Yii
  • Group: Members
  • Posts: 3,017
  • Joined: 06-October 08
  • Location:Upper Palatinate

Posted 30 March 2010 - 01:40 AM

View PostDana, on 29 March 2010 - 04:14 PM, said:

Edit: Odd -- must be a forum issue. It automatically changes that to a lowercase B in Recordbehavior. So I guess it's just a note to anyone copying that they need to correct that in their copy.


Yeah, it's a known bug. Meanwhile i'm not sure anymore, if the change of forum software some time ago really was worth all the new issues that came with it.
0

Share this topic:


Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users