Skip to content

Instantly share code, notes, and snippets.

@andriasang
Created August 7, 2012 06:50
Show Gist options
  • Save andriasang/3282474 to your computer and use it in GitHub Desktop.
Save andriasang/3282474 to your computer and use it in GitHub Desktop.
/*
* Base class for configurable classes
* Based off a class that was included with the Solarium library
* This new version lets you declare defaults which are inherited down the inheritance tree
*
* All classes extending this class are configurable using the constructor or setOption calls.
*
*/
class Configurable
{
/**
* Default options
* This can be freely redefined in subclasses. Parent class items will be carried over and rewritten
* if there's a new definition in the subclass
*
* Make sure the subclass definition is also static
*
* @var array
*/
protected static $_defaults = array(
);
/**
* Created from defaults and passed options
* This should only be modified and accessed through {@link setOption()}, {@link setOptions()}, {@link getOption()}, and {@link getOptions()}
*
* @var array
*/
private $_options = array(
);
/**
* Constructor
*
* If options are passed they will be merged with {@link $_defaults} using
* the {@link setOptions()} method.
*
* After handling the options the {@link _init()} method is called.
*
* @param array|Zend_Config $options
* @return void
*/
public function __construct($options = null)
{
$this->setOptions($options);
$this->_init();
}
/**
* getDefaults
*
* Climbs up the inheritance tree, merging {@link $_defaults}
* uses late static binding to get the $_defaults value for sub classes
*
* @return Array
*/
protected static function _getDefaults () {
// if no $_defaults is specified for this class, use an empty array
if (static::$_defaults)
$defaults = static::$_defaults;
else
$defaults = Array();
// stop when you've reached the Configurable class
if (get_called_class() != "Configurable") {
// this will get the parent class of the current class as you climb up the inheritance tree
$parent = get_parent_class(get_called_class());
// this ordering for array_merge will ensure that subclass defaults overwrite parent class defaults
$defaults = array_merge ($parent::_getDefaults(), $defaults);
}
return $defaults;
}
/**
* Set options
*
* If $options is an object it will be converted into an array by called
* it's toArray method. This is compatible with the Zend_Config classes in
* Zend Framework, but can also easily be implemented in any other object.
*
* @throws Exception
* @param array|Zend_Config $options
*
* @return void
*/
public function setOptions ($options)
{
if (null !== $options) {
// first convert to array if needed
if (!is_array($options)) {
if (is_object($options)) {
$options = $options->toArray();
} else {
throw new Exception('Options must be an array or a Zend_Config object');
}
}
// combine the passed options with the defaults
$defaults = $this->_getDefaults();
$this->_options = array_merge($defaults, $options);
} else {
// if no options specified, just return the defaults as is
$this->_options = $this->_getDefaults();
}
}
/**
* Initialization hook
*
* Can be used by classes for special behaviour. For instance some options
* have extra setup work in their 'set' method that also need to be called
* when the option is passed as a constructor argument.
*
* This hook is called by the constructor after saving the constructor
* arguments in {@link $_options}
*
* @internal This empty implementation can optionally be implemented in
* descending classes. It's not an abstract method on purpose, there are
* many cases where no initialization is needed.
*
* @return void
*/
protected function _init()
{
}
/**
* Set an option
* Returns Configurable for chaining
*
* @param string $name
* @param mixed $value
* @return Configurable
*/
protected function setOption($name, $value)
{
$this->_options[$name] = $value;
return $this;
}
/**
* Get an option value by name
*
* If the option is empty or not set a NULL value will be returned.
*
* @param string $name
* @return mixed
*/
public function getOption($name)
{
if (isset($this->_options[$name])) {
return $this->_options[$name];
} else {
return null;
}
}
/**
* Get all options
*
* @return array
*/
public function getOptions()
{
return $this->_options;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment