Question

I have a User.php model, DbTable/User.php model and UserMapper.php file as described in the Zend Documentation.

The mapper has a fetchAll(), find($id), getDbTable(), save() and setDbTable()

If I want to add the following functions:

  1. function doesUsernameExistAlready($username) {return a boolean}
  2. function findByUsername($username) {return a $user}
  3. function activateUser($user) {just activate a $user}

To follow best practices of Zend, where should the 3 functions be added? Should they be added to UserMapper.php or User.php? Or do they belong in the controller (UserController)?

For findByUsername, how do I write a function that will search my User table for a username? In my case username's are email addresses and unique (as defined in MySQL).

Was it helpful?

Solution

@drew010 as usual is correct, put these functions in your mapper. Honestly these all could probably be put in an abstract or base mapper so the functionality is availalbe to all of your mappers.

you could easily create a function recordExists() in your mapper and just pass the table and column as arguments:

  //you can either pass in the table name or have it be a property
  public function recordExists($table = null, $column) {
      //The table syntax may change depending on the scope
        $table = $this->_tableName;
        $exists = new Zend_Validate_Db_RecordExists(array(
        'table' => $table,
        'field' => $column
        )):

    return $exists;
    }

for a findBy() method I like to pass 3 variables to the method and then use fetchAll() to return an array of objects. That way if the column returns one row or fifty rows I handle the output the same way.

    /**
     * findByColumn() returns an array of rows selected
     * by column name and column value.
     * Optional orderBy value, pass $order as string ie 'id ASC'.
     *
     * @param string $column
     * @param string $value
     * @param string $order
     * @return array returns an array of objects
     */
public function findByColumn($column, $value, $order = NULL) {
        $select = $this->_getGateway()->select();
        $select->where("$column = ?", $value);
        if (!is_null($order)) {
            $select->order($order);
        }
        $result = $this->_getGateway()->fetchAll($select);
        $entities = array();
        foreach ($result as $row) {
            //create objects
            $entity = $this->createEntity($row);
            $entities[] = $entity;
        }
        return $entities;
    }

as for your last question you could activate a a record really simply by fetching the row and then saving just the switch, I presume your setting a flag or boolean of some type type to activate the record. This one will probably need to go in the concrete UserMapper as I find that with the method I use to save records a base save() method doesn't always work.

 //you'll set the activate switch when the user object is instantiated
    public function activate(Application_Model_User $user) {
        if (!is_null($user->id)) {
            $select = $this->_getGateway()->select();
            $select->where('id = ?', $user->id);
            $row = $this->_getGateway()->fetchRow($select);
            $row->activate = $user->activate;
            //This is the cool thing about save(), you can change as many or few columns as you need.
           $row->save()
        return $row;  
        } else {
           //handle error, as we only want to be able to change an existing user.
        }

    }

This may be more then you needed, still I hope it helps.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top