Zend Framework: Coding by Convention - Part 2

A number of components sometimes accept strings or arrays as parameter. Developers coming from statically typed languages might cringe a bit, but this is really just about taking advantage of the flexibility of the language. With flexibility comes freedom and complexity, so having an established convention helps quite a bit.

One component that makes extensive use of accepting both strings and arrays is Zend_Db_Select. When building queries, it allows you to specify parameter either way:

// SELECT username FROM users WHERE id = 1
$select->from('users', 'username')->where('id = ?', 1);

// Same query again, with array syntax
$select->from(array('users'), array('username'))->where('id = ?', 1);

This can make for much more readable queries when things become more complex:

class Friendships extends Zend_Db_Table_Abstract
{

    /**
     * Select users suggested as friends
     *
     * Algorithm picks out your friends' friends that you don't already
     * have added to your list, but which at least $threshold friends have in common.
     *
     * @param string $useruuid Avatar's UUID
     * @param int $threshold How many friends must have the person in common
     * @return Zend_Db_Table_Rowset_Abstract
     */
    public function getSuggested($useruuid, $threshold = 4,
                                 $page = null, $itemsPerPage = null)
    {

        $select = $this->select()
            ->setIntegrityCheck(false)

            // friends
            ->from(array('f' => $this->_name),
                   array()) // no columns
            ->where('f.useruuid = ? AND f.dateaccepted IS NOT NULL', $useruuid)

            // friends' friends that aren't me
            ->join(array('ff' => $this->_name),
                   'f.frienduuid = ff.useruuid AND ' .
            	   'ff.frienduuid != f.useruuid AND ' .
                   'ff.dateaccepted IS NOT NULL',
                   array()) // no columns

            ->join(array('u' => 'users'),
                   'ff.frienduuid = u.uuid',
                   array('*'))

            // my friends again (left joined)
            ->joinLeft(array('mf' => $this->_name),
                       'ff.frienduuid = mf.frienduuid AND ' .
                       'mf.useruuid = f.useruuid AND ' .
                   	   'mf.dateaccepted IS NOT NULL',
                       array()) // no columns

            // filter my friends' friends that aren't my friends
            ->where('mf.frienduuid IS NULL')

            ->group('ff.frienduuid') // group by suggested friends
            ->having('COUNT(f.frienduuid) >= ?', $threshold)
            ->order('COUNT(f.frienduuid) DESC');

        if ($page !== null or $itemsPerPage !== null) {
        	$select->limitPage($page, $itemsPerPage);
        }

        return $this->fetchAll($select);
    }

}
This entry was posted in PHP, Zend Framework. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>