Post->find('next', array( * 'id' => 1, * ... * )); */ class FindNextBehavior extends ModelBehavior { public $defaultSettings = array( 'findType' => 'next', ); public function setup($Model, $config = array()) { $this->settings[$Model->alias] = Set::merge($this->defaultSettings, $config); $this->mapMethods = array( sprintf('/^_find%s$/', ucfirst($this->settings[$Model->alias]['findType'])) => '__findNext', ); $Model->_findMethods[$this->settings[$Model->alias]['findType']] = true; } public function __findNext($Model, $method, $state, $query, $results = array()) { if ($state == 'before') { if (!array_key_exists('value', $query)) { throw new Exception(__d('findNext', 'query must contain value for findNext: ', true) . var_export($query, true)); } $field = isset($query['field']) ? $field : $Model->alias . '.' . $Model->primaryKey; unset($query['field']); $greaterQuery = Set::merge($query, array( 'conditions' => array( "$field >" => $query['value'], ), )); $greaterExists = $Model->find('count', $greaterQuery); if (!$greaterExists) { $littlerQuery = Set::merge($query, array( 'conditions' => array( "$field <" => $query['value'], ), )); $query = $littlerQuery; } else { $query = $greaterQuery; } unset($query['value']); $query['order'] = array( $field => 'ASC', ); return $Model->_findFirst($state, $query, $results); } elseif ($state == 'after') { return $Model->_findFirst($state, $query, $results); } } }