Zend_Pagination adapter for Propel

Like recently proposed by Jason Eisenmenger, I’ve written a Zend_Pagination adapter for Propel.

It uses the DbFinder symfony plugin (formerly sfPropelFinder) which mimics Doctrine’s way of performing queries. The strictlyPHP_Propel_Finder used below is just a wrapper around that plugin.

Please note: it can certainly be improved (and I’m not sure the Zend Framework coding standards are met).

class strictlyPHP_Paginator_Adapter_Propel implements
Zend_Paginator_Adapter_Interface
{
    /**
     * @var strictlyPHP_Propel_Finder
     */
    protected $_finder;

    /**
     * @var Criteria
     */
    protected $_criteria;

    /**
     * @var int
     */
    protected $_count;

    /**
     * Constructor
     * @param strictlyPHP_Propel_Finder $finder
     */
    public function __construct($finder)
    {
        $this->_finder = $finder;
        $this->_criteria = $finder->getCriteria();
    }

    /**
     * Get count
     * @return int
     */
    public function count()
    {
         if ($this->_count === null) {
             $this->_finder->setCriteria($this->_criteria);
            $this->_count = $this->_finder->count();
         }

        return $this->_count;
    }

    /**
     * Get items
     * @param int $pageNumber
     * @param int $itemCountPerPage
     * @return array
     */
    public function getItems($pageNumber, $itemCountPerPage)
    {
        $criteria = clone $this->_criteria;
        $criteria->setOffset($pageNumber);
        $criteria->setLimit($itemCountPerPage);
        return $this->_finder->setCriteria($criteria)->find();
    }
}

Zend_Log wrapper for Propel

Although Doctrine has its advantages, I still like Propel. It does its job and it does it fairly well.
If you integrate Propel with Zend Framework, you basically only need a Zend_Log wrapper that implements the BasicLogger interface Propel requires. This lets you use Zend_Log as the only log class in your application instead of creating one especially for Propel.

/**
 * Wrapper for Zend_Log for use as Propel log
 * @author Sam Hauglustaine
 */
class strictlyPHP_Propel_Log extends Zend_Log implements BasicLogger
{
    /**
     * Log
     * @var Zend_Log
     */
    private $_log;

    /**
     * Constructor
     * @param Zend_Log $log
     */
    public function __construct(Zend_Log $log) {
        $this->_log = $log;
    }

    /**
     * Log message of specified severity
     * @param string $message
     * @param int $severity
     */
    public function log($message, $severity = null) {
        $this->_log->log($message, $severity);
    }

    public function emergency($message) {
        $this->log($message, Zend_Log::EMERG);
    }
    public function alert($message) {
        $this->log($message, Zend_Log::ALERT);
    }
    public function crit($message) {
        $this->log($message, Zend_Log::CRIT);
    }
    public function err($message) {
        $this->log($message, Zend_Log::ERR);
    }
    public function warning($message) {
        $this->log($message, Zend_Log::WARN);
    }
    public function notice($message) {
        $this->log($message, Zend_Log::NOTICE);
    }
    public function info($message) {
        $this->log($message, Zend_Log::INFO);
    }
    public function debug($message) {
        $this->log($message, Zend_Log::DEBUG);
    }
}

(the Zend_Log priority constants nicely match their Propel equivalents.)
You then need to extend the main Propel class to do the wrapping:

/**
 * Wrapper for Propel
 * @author Sam Hauglustaine
 */
class strictlyPHP_Propel extends Propel
{
    /**
     * Set Propel log (required)
     * @param mixed $log
     * @return void
     */
    public static function setLog($log)
    {
        if($log instanceof Zend_Log)
            $log = new strictlyPHP_Propel_Log($log);

        parent::setLogger($log);
    }
}

That’s all. You can then call your Propel wrapper’s static methods in your bootstrap or a front controller plugin (I implemented that last option for a brand new project, a directory for stallion owners):

strictlyPHP_Propel::setLog($myLog);
strictlyPHP_Propel::init($myConfig);

Of course the bigger part is using the Propel class generator itself but that’s something for another post.