diff --git a/lib/Cake/Controller/Component/Auth/BaseAuthenticate.php b/lib/Cake/Controller/Component/Auth/BaseAuthenticate.php index aee2f6cc7..77629ee39 100644 --- a/lib/Cake/Controller/Component/Auth/BaseAuthenticate.php +++ b/lib/Cake/Controller/Component/Auth/BaseAuthenticate.php @@ -27,6 +27,7 @@ abstract class BaseAuthenticate { * * - `fields` The fields to use to identify a user by. * - `userModel` The model name of the User, defaults to User. + * - `userFields` Array of fields to retrieve from User model, null to retrieve all. Defaults to null. * - `scope` Additional conditions to use when looking up and authenticating users, * i.e. `array('User.is_active' => 1).` * - `recursive` The value of the recursive key passed to find(). Defaults to 0. @@ -43,6 +44,7 @@ abstract class BaseAuthenticate { 'password' => 'password' ), 'userModel' => 'User', + 'userFields' => null, 'scope' => array(), 'recursive' => 0, 'contain' => null, @@ -105,9 +107,15 @@ abstract class BaseAuthenticate { $conditions = array_merge($conditions, $this->settings['scope']); } + $userFields = $this->settings['userFields']; + if ($password !== null && $userFields !== null) { + $userFields[] = $model . '.' . $fields['password']; + } + $result = ClassRegistry::init($userModel)->find('first', array( 'conditions' => $conditions, 'recursive' => $this->settings['recursive'], + 'fields' => $userFields, 'contain' => $this->settings['contain'], )); if (empty($result[$model])) { diff --git a/lib/Cake/Controller/Component/Auth/DigestAuthenticate.php b/lib/Cake/Controller/Component/Auth/DigestAuthenticate.php index c40f4096d..068a7c09c 100644 --- a/lib/Cake/Controller/Component/Auth/DigestAuthenticate.php +++ b/lib/Cake/Controller/Component/Auth/DigestAuthenticate.php @@ -60,6 +60,7 @@ class DigestAuthenticate extends BasicAuthenticate { * * - `fields` The fields to use to identify a user by. * - `userModel` The model name of the User, defaults to User. + * - `userFields` Array of fields to retrieve from User model, null to retrieve all. Defaults to null. * - `scope` Additional conditions to use when looking up and authenticating users, * i.e. `array('User.is_active' => 1).` * - `recursive` The value of the recursive key passed to find(). Defaults to 0. @@ -78,6 +79,7 @@ class DigestAuthenticate extends BasicAuthenticate { 'password' => 'password' ), 'userModel' => 'User', + 'userFields' => null, 'scope' => array(), 'recursive' => 0, 'contain' => null, diff --git a/lib/Cake/Test/Case/Controller/Component/Auth/BasicAuthenticateTest.php b/lib/Cake/Test/Case/Controller/Component/Auth/BasicAuthenticateTest.php index cd337cf08..c4402a7f7 100644 --- a/lib/Cake/Test/Case/Controller/Component/Auth/BasicAuthenticateTest.php +++ b/lib/Cake/Test/Case/Controller/Component/Auth/BasicAuthenticateTest.php @@ -36,7 +36,7 @@ class BasicAuthenticateTest extends CakeTestCase { * * @var array */ - public $fixtures = array('core.user', 'core.auth_user'); + public $fixtures = array('core.user', 'core.auth_user', 'core.article'); /** * setup @@ -197,6 +197,80 @@ class BasicAuthenticateTest extends CakeTestCase { $this->assertEquals($expected, $result); } +/** + * test contain success + * + * @return void + */ + public function testAuthenticateContainSuccess() { + $User = ClassRegistry::init('User'); + $User->bindModel(array('hasMany' => array('Article'))); + $User->Behaviors->load('Containable'); + $this->auth->settings['contain'] = 'Article'; + $request = new CakeRequest('posts/index', false); + $request->addParams(array('pass' => array(), 'named' => array())); + + $_SERVER['PHP_AUTH_USER'] = 'mariano'; + $_SERVER['PHP_AUTH_PW'] = 'password'; + + $result = $this->auth->authenticate($request, $this->response); + $expected = array( + 'id' => 1, + 'user_id' => 1, + 'title' => 'First Article', + 'body' => 'First Article Body', + 'published' => 'Y', + 'created' => '2007-03-18 10:39:23', + 'updated' => '2007-03-18 10:41:31' + ); + $this->assertEquals($expected, $result['Article'][0]); + } + +/** + * test userFields success + * + * @return void + */ + public function testAuthenticateUserFieldsSuccess() { + $this->auth->settings['userFields'] = array('id', 'user'); + $request = new CakeRequest('posts/index', false); + $request->addParams(array('pass' => array(), 'named' => array())); + + $_SERVER['PHP_AUTH_USER'] = 'mariano'; + $_SERVER['PHP_AUTH_PW'] = 'password'; + + $result = $this->auth->authenticate($request, $this->response); + $expected = array( + 'id' => 1, + 'user' => 'mariano', + ); + $this->assertEquals($expected, $result); + } + +/** + * test userFields and related models success + * + * @return void + */ + public function testAuthenticateUserFieldsRelatedModelsSuccess() { + $User = ClassRegistry::init('User'); + $User->bindModel(array('hasOne' => array('Article'))); + $this->auth->settings['recursive'] = 0; + $this->auth->settings['userFields'] = array('Article.id', 'Article.title'); + $request = new CakeRequest('posts/index', false); + $request->addParams(array('pass' => array(), 'named' => array())); + + $_SERVER['PHP_AUTH_USER'] = 'mariano'; + $_SERVER['PHP_AUTH_PW'] = 'password'; + + $result = $this->auth->authenticate($request, $this->response); + $expected = array( + 'id' => 1, + 'title' => 'First Article', + ); + $this->assertEquals($expected, $result['Article']); + } + /** * test scope failure. * diff --git a/lib/Cake/Test/Case/View/Helper/PaginatorHelperTest.php b/lib/Cake/Test/Case/View/Helper/PaginatorHelperTest.php index bbada6605..eb574b63e 100644 --- a/lib/Cake/Test/Case/View/Helper/PaginatorHelperTest.php +++ b/lib/Cake/Test/Case/View/Helper/PaginatorHelperTest.php @@ -2763,4 +2763,110 @@ class PaginatorHelperTest extends CakeTestCase { $expected = '0 of 1'; $this->assertEquals($expected, $result); } + +/** + * Verify that no next and prev links are created for single page results + * + * @return void + */ + public function testMetaPage0() { + $this->Paginator->request['paging'] = array( + 'Article' => array( + 'page' => 1, + 'prevPage' => false, + 'nextPage' => false, + 'pageCount' => 1, + ) + ); + $expected = ''; + $result = $this->Paginator->meta(); + $this->assertSame($expected, $result); + } + +/** + * Verify that page 1 only has a next link + * + * @return void + */ + public function testMetaPage1() { + $this->Paginator->request['paging'] = array( + 'Article' => array( + 'page' => 1, + 'prevPage' => false, + 'nextPage' => true, + 'pageCount' => 2, + 'options' => array(), + 'paramType' => 'querystring' + ) + ); + $expected = ''; + $result = $this->Paginator->meta(); + $this->assertSame($expected, $result); + } + +/** + * Verify that the method will append to a block + * + * @return void + */ + public function testMetaPage1InlineFalse() { + $this->Paginator->request['paging'] = array( + 'Article' => array( + 'page' => 1, + 'prevPage' => false, + 'nextPage' => true, + 'pageCount' => 2, + 'options' => array(), + 'paramType' => 'querystring' + ) + ); + $expected = ''; + $this->Paginator->meta(array('block' => true)); + $result = $this->View->fetch('meta'); + $this->assertSame($expected, $result); + } + +/** + * Verify that the last page only has a prev link + * + * @return void + */ + public function testMetaPage1Last() { + $this->Paginator->request['paging'] = array( + 'Article' => array( + 'page' => 2, + 'prevPage' => true, + 'nextPage' => false, + 'pageCount' => 2, + 'options' => array(), + 'paramType' => 'querystring' + ) + ); + $expected = ''; + $result = $this->Paginator->meta(); + $this->assertSame($expected, $result); + } + +/** + * Verify that a page in the middle has both links + * + * @return void + */ + public function testMetaPage10Last() { + $this->Paginator->request['paging'] = array( + 'Article' => array( + 'page' => 5, + 'prevPage' => true, + 'nextPage' => true, + 'pageCount' => 10, + 'options' => array(), + 'paramType' => 'querystring' + ) + ); + $expected = ''; + $expected .= ''; + $result = $this->Paginator->meta(); + $this->assertSame($expected, $result); + } + } diff --git a/lib/Cake/View/Helper/PaginatorHelper.php b/lib/Cake/View/Helper/PaginatorHelper.php index ccbcc4794..43c29a14f 100644 --- a/lib/Cake/View/Helper/PaginatorHelper.php +++ b/lib/Cake/View/Helper/PaginatorHelper.php @@ -958,4 +958,50 @@ class PaginatorHelper extends AppHelper { return $out; } +/** + * Returns the meta-links for a paginated result set. + * + * `echo $this->Paginator->meta();` + * + * Echos the links directly, will output nothing if there is neither a previous nor next page. + * + * `$this->Paginator->meta(array('block' => true));` + * + * Will append the output of the meta function to the named block - if true is passed the "meta" + * block is used. + * + * ### Options: + * + * - `model` The model to use defaults to PaginatorHelper::defaultModel() + * - `block` The block name to append the output to, or false/absenst to return as a string + * + * @param array $options Array of options + * @return string|null Meta links + */ + public function meta($options = array()) { + $model = isset($options['model']) ? $options['model'] : null; + $params = $this->params($model); + $links = array(); + if ($this->hasPrev()) { + $links[] = $this->Html->meta(array( + 'rel' => 'prev', + 'link' => $this->url(array('page' => $params['page'] - 1), true) + )); + } + if ($this->hasNext()) { + $links[] = $this->Html->meta(array( + 'rel' => 'next', + 'link' => $this->url(array('page' => $params['page'] + 1), true) + )); + } + $out = implode($links); + if (empty($options['block'])) { + return $out; + } + if ($options['block'] === true) { + $options['block'] = __FUNCTION__; + } + $this->_View->append($options['block'], $out); + } + }