Skip to content

Instantly share code, notes, and snippets.

@ericclemmons
Created June 15, 2009 20:35
Show Gist options
  • Save ericclemmons/130312 to your computer and use it in GitHub Desktop.
Save ericclemmons/130312 to your computer and use it in GitHub Desktop.
Add "findBy" magic method to Zend_Db_Table objects
<?php
/**
* My_Db_Table
*
* Adds "findBy" magic method to Zend_Db_Table objects
*
* @author Eric Clemmons
**/
class My_Db_Table extends Zend_Db_Table
{
/**
* Inflector to transpose "ColumNames" into "column_names"
*
* @var Zend_Filter_Inflector
**/
protected $_inflector;
/**
* Last fetched rowset for future queries
*
* @var Zend_Db_Table_Rowset
**/
protected $_lastRowset;
/**
* Delimiters for "where" clauses. Last piece of glue is the default ("and")
*
* @var Array
**/
protected $_glue = array('or', 'and');
/**
* Initializes the inflector & actual table name ("posts" -> "wp_posts")
*
* @return void
**/
public function __construct()
{
$this->_initInflector();
$this->_name = WORDPRESS_TABLE_PREFIX . $this->_name;
parent::__construct();
}
/**
* Sets up CamelCaseToUnderscore+StringToLower inflector
*
* @return void
**/
public function _initInflector()
{
$this->_inflector = new Zend_Filter_Inflector(':name');
$this->_inflector->setRules(array(
':name' => array('Word_CamelCaseToUnderscore', 'StringToLower')
));
}
/**
* Sets up {$model}->findByColumName functions with optional And/Or clauses
*
* e.g. findByPostId(1)
* Row where "post_id" is equal to "1".
*
* findByTagAndCategory('css', 'html')
* Rows where both "tag" and "category" is "css" and "html", respectively.
*
* findByTagOrCategory('css', 'html')
* Rows where "tag" is "css" or "category" is "html"
*
* @return Zend_Db_Table_Rowset
*/
public function __call($method, $args)
{
if (is_callable($this, $method)) {
return call_user_func(array($this, $method));
}
preg_match('/^findBy([\w]+)$/', $method, $matches);
$columns = array();
foreach ($this->_glue as $glue) {
if (strpos($matches[1], ucfirst($glue)) !== false) {
break;
}
}
foreach (explode(ucfirst($glue), $matches[1]) as $index => $column) {
$columnName = $this->_inflector->filter(array('name' => $column));
$columns[$columnName] = $args[$index];
}
return $this->findBy($columns, $glue);
}
/**
* Concatenates columns & defined values based on "glue" delimiter
*
* @return Zend_Db_Table_Rowset
**/
public function findBy($columns, $glue = 'and')
{
$select = $this->select();
foreach($columns as $column => $criteria) {
$where = ($glue === 'or')
? "orWhere"
: "where";
$select = $select->{$where}("$column = ?", $criteria);
}
$this->_lastRowset = $this->fetchAll($select);
return $this->_lastRowset;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment