Managing constants easily

You are viewing revision #1 of this wiki article.
This version may not be up to date with the latest version.
You may want to view the differences to the latest version.

next (#2) »

  1. Problem
  2. Usage example
  3. Conclusion

Problem

For time to time i have models with constants (basicly status constants) which i use in diferent places and if these constant changes, i have to change mentions of constant in code elsewhere.

getConstants()

For this small problem i am using function getConstants().

public function getConstants($token,$objectClass) {
	    $tokenLen = strlen($token);

	    $reflection = new ReflectionClass($objectClass); //php built-in 
	    $allConstants = $reflection->getConstants(); //constants as array

	    $tokenConstants = array(); 
	    foreach($allConstants as $name => $val) {
	        if ( substr($name,0,$tokenLen) != $token ) continue;
	        $tokenConstants[ $val ] = $val;
	    }

	    return $tokenConstants;
	}

Usage example

To add this function for every ActiveRecord class extend CActiveRecord

class ActiveRecord extends CActiveRecord {

   	/*
	    Get class constants by token.
	    If you set constants with same prefix, like:
		MY_STATUS_1
		MY_STATUS_2
		MY_STATUS_3

	    , you can get it by calling
	    Class::getConstants('MY');
	    or
	    Class::getConstants('MY_STATUS');
	*/
	public function getConstants($token,$objectClass) {
	    $tokenLen = strlen($token);

	    $reflection = new ReflectionClass($objectClass); //php built-in 
	    $allConstants = $reflection->getConstants(); //constants as array

	    $tokenConstants = array(); 
	    foreach($allConstants as $name => $val) {
		if ( substr($name,0,$tokenLen) != $token ) continue;
		$tokenConstants[ $val ] = $val;
	    }
	    return $tokenConstants;
	}

}

After that extend new models with ActiveRecord class (not CActiveRecord)

class Media extends ActiveRecord {
     const TYPE_MUSIC = 'music';
     const TYPE_VIDEO = 'video';
     const TYPE_DOC = 'document';

     const STATUS_ACTIVE = 'active';
     const STATUS_REMOVED = 'removed';

    //...
}

and use self::getConstants() in models rules definitions, methods or outside model

class Media extends ActiveRecord {
//..
     public function rules()
     {
           return array(
                   array('type', 'in','range' => self::getConstants('TYPE_',__CLASS__)),
           );
     }
//..
    public function getStatuses() {
        return self::getConstants('STATUS_',__CLASS__);
    }
    public function getTypes() {
        return self::getConstants('TYPE_',__CLASS__);
    }

}

Somewhere else

print_r( Media::getConstants('STATUS_','Media') ); 
//or create Media method and use simplified
print_r( Media::getStatuses() ); 

Conclusion

Of course you don't need this if you have model with only two constants. It's more handy if you got tons of them.

Thanks and please leave comment if you have something to say.