1, 'limit' => 20), (array)$settings); $this->Controller = $collection->getController(); parent::__construct($collection, $settings); } /** * Handles automatic pagination of model records. * * @param mixed $object Model to paginate (e.g: model instance, or 'Model', or 'Model.InnerModel') * @param mixed $scope Conditions to use while paginating * @param array $whitelist List of allowed options for paging * @return array Model query results */ public function paginate($object = null, $scope = array(), $whitelist = array()) { if (is_array($object)) { $whitelist = $scope; $scope = $object; $object = null; } $assoc = null; if (is_string($object)) { $assoc = null; if (strpos($object, '.') !== false) { list($object, $assoc) = pluginSplit($object); } if ($assoc && isset($this->Controller->{$object}->{$assoc})) { $object = $this->Controller->{$object}->{$assoc}; } elseif ( $assoc && isset($this->Controller->{$this->Controller->modelClass}) && isset($this->Controller->{$this->Controller->modelClass}->{$assoc} )) { $object = $this->Controller->{$this->Controller->modelClass}->{$assoc}; } elseif (isset($this->Controller->{$object})) { $object = $this->Controller->{$object}; } elseif ( isset($this->Controller->{$this->Controller->modelClass}) && isset($this->Controller->{$this->Controller->modelClass}->{$object} )) { $object = $this->Controller->{$this->Controller->modelClass}->{$object}; } } elseif (empty($object) || $object === null) { if (isset($this->Controller->{$this->Controller->modelClass})) { $object = $this->Controller->{$this->Controller->modelClass}; } else { $className = null; $name = $this->Controller->uses[0]; if (strpos($this->Controller->uses[0], '.') !== false) { list($name, $className) = explode('.', $this->Controller->uses[0]); } if ($className) { $object = $this->Controller->{$className}; } else { $object = $this->Controller->{$name}; } } } if (!is_object($object)) { throw new MissingModelException($object); } $options = array_merge( $this->Controller->request->params, $this->Controller->request->query, $this->Controller->passedArgs ); if (isset($this->settings[$object->alias])) { $defaults = $this->settings[$object->alias]; } else { $defaults = $this->settings; } if (isset($options['show'])) { $options['limit'] = $options['show']; } if (isset($options['sort'])) { $direction = null; if (isset($options['direction'])) { $direction = strtolower($options['direction']); } if ($direction != 'asc' && $direction != 'desc') { $direction = 'asc'; } $options['order'] = array($options['sort'] => $direction); } if (!empty($options['order']) && is_array($options['order'])) { $alias = $object->alias ; $key = $field = key($options['order']); if (strpos($key, '.') !== false) { list($alias, $field) = explode('.', $key); } $value = $options['order'][$key]; unset($options['order'][$key]); if ($object->hasField($field)) { $options['order'][$alias . '.' . $field] = $value; } elseif ($object->hasField($field, true)) { $options['order'][$field] = $value; } elseif (isset($object->{$alias}) && $object->{$alias}->hasField($field)) { $options['order'][$alias . '.' . $field] = $value; } } $vars = array('fields', 'order', 'limit', 'page', 'recursive'); $keys = array_keys($options); $count = count($keys); for ($i = 0; $i < $count; $i++) { if (!in_array($keys[$i], $vars, true)) { unset($options[$keys[$i]]); } if (empty($whitelist) && ($keys[$i] === 'fields' || $keys[$i] === 'recursive')) { unset($options[$keys[$i]]); } elseif (!empty($whitelist) && !in_array($keys[$i], $whitelist)) { unset($options[$keys[$i]]); } } $conditions = $fields = $order = $limit = $page = $recursive = null; if (!isset($defaults['conditions'])) { $defaults['conditions'] = array(); } $type = 'all'; if (isset($defaults[0])) { $type = $defaults[0]; unset($defaults[0]); } $options = array_merge(array('page' => 1, 'limit' => 20), $defaults, $options); $options['limit'] = (int) $options['limit']; if (empty($options['limit']) || $options['limit'] < 1) { $options['limit'] = 1; } extract($options); if (is_array($scope) && !empty($scope)) { $conditions = array_merge($conditions, $scope); } elseif (is_string($scope)) { $conditions = array($conditions, $scope); } if ($recursive === null) { $recursive = $object->recursive; } $extra = array_diff_key($defaults, compact( 'conditions', 'fields', 'order', 'limit', 'page', 'recursive' )); if ($type !== 'all') { $extra['type'] = $type; } if (method_exists($object, 'paginateCount')) { $count = $object->paginateCount($conditions, $recursive, $extra); } else { $parameters = compact('conditions'); if ($recursive != $object->recursive) { $parameters['recursive'] = $recursive; } $count = $object->find('count', array_merge($parameters, $extra)); } $pageCount = intval(ceil($count / $limit)); if ($page === 'last' || $page >= $pageCount) { $options['page'] = $page = $pageCount; } elseif (intval($page) < 1) { $options['page'] = $page = 1; } $page = $options['page'] = (integer)$page; if (method_exists($object, 'paginate')) { $results = $object->paginate( $conditions, $fields, $order, $limit, $page, $recursive, $extra ); } else { $parameters = compact('conditions', 'fields', 'order', 'limit', 'page'); if ($recursive != $object->recursive) { $parameters['recursive'] = $recursive; } $results = $object->find($type, array_merge($parameters, $extra)); } $paging = array( 'page' => $page, 'current' => count($results), 'count' => $count, 'prevPage' => ($page > 1), 'nextPage' => ($count > ($page * $limit)), 'pageCount' => $pageCount, 'defaults' => array_merge(array('limit' => 20, 'step' => 1), $defaults), 'options' => $options ); if (!isset($this->Controller->request['paging'])) { $this->Controller->request['paging'] = array(); } $this->Controller->request['paging'] = array_merge( (array)$this->Controller->request['paging'], array($object->alias => $paging) ); if (!in_array('Paginator', $this->Controller->helpers) && !array_key_exists('Paginator', $this->Controller->helpers)) { $this->Controller->helpers[] = 'Paginator'; } return $results; } }