diff --git a/app/webroot/css/cake.generic.css b/app/webroot/css/cake.generic.css index 196532b7f..76eafb5f5 100644 --- a/app/webroot/css/cake.generic.css +++ b/app/webroot/css/cake.generic.css @@ -182,6 +182,13 @@ div.paging div.disabled { color: #ddd; display: inline; } +div.paging span { +} +div.paging span.current { + color: #000; +} +div.paging span a { +} /* Scaffold View */ dl { @@ -312,7 +319,7 @@ p.error { font-size: 120%; line-height: 140%; padding: 0.8em; - margin: 1em 0; + margin: 1em 0; } p.error em { color: #000; diff --git a/cake/console/libs/templates/skel/webroot/css/cake.generic.css b/cake/console/libs/templates/skel/webroot/css/cake.generic.css index a0e0207fd..f687b43fc 100644 --- a/cake/console/libs/templates/skel/webroot/css/cake.generic.css +++ b/cake/console/libs/templates/skel/webroot/css/cake.generic.css @@ -183,6 +183,13 @@ div.paging div.disabled { color: #ddd; display: inline; } +div.paging span { +} +div.paging span.current { + color: #000; +} +div.paging span a { +} /* Scaffold View */ dl { diff --git a/cake/libs/view/helpers/paginator.php b/cake/libs/view/helpers/paginator.php index 8ab46805f..9c4c936df 100644 --- a/cake/libs/view/helpers/paginator.php +++ b/cake/libs/view/helpers/paginator.php @@ -217,7 +217,7 @@ class PaginatorHelper extends AppHelper { if (empty($key)) { $key = $title; - $title = Inflector::humanize(preg_replace('/_id$/', '', $title)); + $title = __(Inflector::humanize(preg_replace('/_id$/', '', $title)), true); } $dir = 'asc'; @@ -423,19 +423,25 @@ class PaginatorHelper extends AppHelper { } /** * Returns a set of numbers for the paged result set - * uses a modulus to decide how many numbers to show on each side of the current page (defautl: 8) + * uses a modulus to decide how many numbers to show on each side of the current page (default: 8) * - * @param mixed $options Options for the counter string. See #options for list of keys. + * @param mixed $options Options for the numbers, (before, after, model, modulus, separator) * @return string numbers string. */ function numbers($options = array()) { + if ($options === true) { + $options = array( + 'before' => ' | ', 'after' => ' | ', + 'first' => 'first', 'last' => 'last', + ); + } + $options = array_merge( array( - 'before'=> null, - 'after'=> null, + 'before'=> null, 'after'=> null, 'model' => $this->defaultModel(), - 'modulus' => '8', - 'separator' => ' | ' + 'modulus' => '8', 'separator' => ' | ', + 'first' => null, 'last' => null, ), (array)$options); @@ -445,22 +451,22 @@ class PaginatorHelper extends AppHelper { if ($params['pageCount'] <= 1) { return false; } - $before = $options['before']; - unset($options['before']); - $after = $options['after']; - unset($options['after']); - $modulus = $options['modulus']; - unset($options['modulus']); + extract($options); + unset($options['before'], $options['after'], $options['model'], $options['modulus'], $options['separator'], $options['first'], $options['last']); - $separator = $options['separator']; - unset($options['separator']); - - $out = $before; + $out = ''; if ($modulus && $params['pageCount'] > $modulus) { $half = intval($modulus / 2); $end = $params['page'] + $half; + + if($first && $end > (int)$first) { + $out .= $this->first($first); + } + + $out .= $before; + if ($end > $params['pageCount']) { $end = $params['pageCount']; } @@ -470,33 +476,128 @@ class PaginatorHelper extends AppHelper { $end = $params['page'] + ($modulus - $params['page']) + 1; } for ($i = $start; $i < $params['page']; $i++) { - $out .= $this->link($i, array('page' => $i), $options) . $separator; + $out .= '' . $this->link($i, array('page' => $i), $options) . '' . $separator; } - $out .= $params['page'] . $separator; + $out .= '' . $params['page'] . '' . $separator; $start = $params['page'] + 1; for ($i = $start; $i < $end; $i++) { - $out .= $this->link($i, array('page' => $i), $options) . $separator; + $out .= '' .$this->link($i, array('page' => $i), $options) . ''. $separator; } if ($end != $params['page']) { - $out .= $this->link($i, array('page' => $end), $options); + $out .= '' .$this->link($i, array('page' => $end), $options) . ''; } + + $out .= $after; + + if($last && $end < $params['pageCount'] - (int)$last) { + $out .= $this->last($last); + } + } else { for ($i = 1; $i <= $params['pageCount']; $i++) { if ($i == $params['page']) { - $out .= $i; + $out .= '' . $i . ''; } else { - $out .= $this->link($i, array('page' => $i), $options); + $out .= '' .$this->link($i, array('page' => $i), $options) . ''; } if($i != $params['pageCount']) { $out .= $separator; } } } - $out .= $after; + return $this->output($out); } +/** + * Returns a first or set of numbers for the first pages + * + * @param mixed $first if string use as label for the link, if numeric print page numbers + * @param mixed $options + * @return string numbers string. + */ + function first($first = '<< first', $options = array()) { + $options = array_merge( + array( + 'after'=> null, + 'model' => $this->defaultModel(), + 'separator' => ' | ', + ), + (array)$options); + + $params = array_merge(array('page'=> 1), (array)$this->params($options['model'])); + unset($options['model']); + + if ($params['pageCount'] <= 1) { + return false; + } + extract($options); + unset($options['after'], $options['model'], $options['separator']); + + $out = ''; + + if (is_int($first) && $params['page'] > $first) { + if ($after === null) { + $after = '...'; + } + for ($i = 1; $i <= $first; $i++) { + $out .= '' . $this->link($i, array('page' => $i), $options) . ''; + if($i != $first) { + $out .= $separator; + } + } + $out .= $after; + } elseif ($params['page'] > 1) { + $out = '' . $this->link($first, array('page' => 1), $options) . '' . $after; + } + return $out; + } +/** + * Returns a last or set of numbers for the last pages + * + * @param mixed $last if string use as label for the link, if numeric print page numbers + * @param mixed $options + * @return string numbers string. + */ + function last($last = 'last >>', $options = array()) { + $options = array_merge( + array( + 'before'=> null, + 'model' => $this->defaultModel(), + 'separator' => ' | ', + ), + (array)$options); + + $params = array_merge(array('page'=> 1), (array)$this->params($options['model'])); + unset($options['model']); + + if ($params['pageCount'] <= 1) { + return false; + } + + extract($options); + unset($options['before'], $options['model'], $options['separator']); + + $out = ''; + $lower = $params['pageCount'] - $last + 1; + + if (is_int($last) && $params['page'] < $lower) { + if ($before === null) { + $before = '...'; + } + for ($i = $lower; $i <= $params['pageCount']; $i++) { + $out .= '' . $this->link($i, array('page' => $i), $options) . ''; + if($i != $params['pageCount']) { + $out .= $separator; + } + } + $out = $before . $out; + } elseif ($params['page'] < $params['pageCount']) { + $out = $before . '' . $this->link($last, array('page' => $params['pageCount']), $options) . ''; + } + return $out; + } } ?> \ No newline at end of file diff --git a/cake/tests/cases/libs/view/helpers/paginator.test.php b/cake/tests/cases/libs/view/helpers/paginator.test.php index 2fe52b90c..31e8ee049 100644 --- a/cake/tests/cases/libs/view/helpers/paginator.test.php +++ b/cake/tests/cases/libs/view/helpers/paginator.test.php @@ -171,9 +171,85 @@ class PaginatorTest extends UnitTestCase { $this->assertPattern('/\/direction:desc/', $result); } + function testNumbers() { + $this->Paginator->params['paging'] = array('Client' => array( + 'page' => 8, 'current' => 3, 'count' => 30, 'prevPage' => false, 'nextPage' => 2, 'pageCount' => 15, + 'defaults' => array('limit' => 3, 'step' => 1, 'order' => array('Client.name' => 'DESC'), 'conditions' => array()), + 'options' => array('page' => 1, 'limit' => 3, 'order' => array('Client.name' => 'DESC'), 'conditions' => array())) + ); + $result = $this->Paginator->numbers(); + $expected = '4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12'; + $this->assertEqual($result, $expected); + + + $result = $this->Paginator->numbers(true); + $expected = 'first | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | last'; + $this->assertEqual($result, $expected); + + $this->Paginator->params['paging'] = array('Client' => array( + 'page' => 1, 'current' => 3, 'count' => 30, 'prevPage' => false, 'nextPage' => 2, 'pageCount' => 15, + 'defaults' => array('limit' => 3, 'step' => 1, 'order' => array('Client.name' => 'DESC'), 'conditions' => array()), + 'options' => array('page' => 1, 'limit' => 3, 'order' => array('Client.name' => 'DESC'), 'conditions' => array())) + ); + $result = $this->Paginator->numbers(); + $expected = '1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9'; + $this->assertEqual($result, $expected); + + $this->Paginator->params['paging'] = array('Client' => array( + 'page' => 14, 'current' => 3, 'count' => 30, 'prevPage' => false, 'nextPage' => 2, 'pageCount' => 15, + 'defaults' => array('limit' => 3, 'step' => 1, 'order' => array('Client.name' => 'DESC'), 'conditions' => array()), + 'options' => array('page' => 1, 'limit' => 3, 'order' => array('Client.name' => 'DESC'), 'conditions' => array())) + ); + $result = $this->Paginator->numbers(); + $expected = '7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15'; + $this->assertEqual($result, $expected); + + $this->Paginator->params['paging'] = array('Client' => array( + 'page' => 1, 'current' => 3, 'count' => 30, 'prevPage' => false, 'nextPage' => 2, 'pageCount' => 15, + 'defaults' => array('limit' => 3, 'step' => 1, 'order' => array('Client.name' => 'DESC'), 'conditions' => array()), + 'options' => array('page' => 1, 'limit' => 3, 'order' => array('Client.name' => 'DESC'), 'conditions' => array())) + ); + + $result = $this->Paginator->first(); + $expected = ''; + $this->assertEqual($result, $expected); + + + $this->Paginator->params['paging'] = array('Client' => array( + 'page' => 4, 'current' => 3, 'count' => 30, 'prevPage' => false, 'nextPage' => 2, 'pageCount' => 15, + 'defaults' => array('limit' => 3, 'step' => 1, 'order' => array('Client.name' => 'DESC'), 'conditions' => array()), + 'options' => array('page' => 1, 'limit' => 3, 'order' => array('Client.name' => 'DESC'), 'conditions' => array())) + ); + + $result = $this->Paginator->first(); + $expected = '<< first'; + $this->assertEqual($result, $expected); + + + $result = $this->Paginator->last(); + $expected = 'last >>'; + $this->assertEqual($result, $expected); + + $result = $this->Paginator->last(1); + $expected = '...15'; + $this->assertEqual($result, $expected); + + $result = $this->Paginator->last(2); + $expected = '...14 | 15'; + $this->assertEqual($result, $expected); + + $this->Paginator->params['paging'] = array('Client' => array( + 'page' => 15, 'current' => 3, 'count' => 30, 'prevPage' => false, 'nextPage' => 2, 'pageCount' => 15, + 'defaults' => array('limit' => 3, 'step' => 1, 'order' => array('Client.name' => 'DESC'), 'conditions' => array()), + 'options' => array('page' => 1, 'limit' => 3, 'order' => array('Client.name' => 'DESC'), 'conditions' => array())) + ); + $result = $this->Paginator->last(); + $expected = ''; + $this->assertEqual($result, $expected); + } + function tearDown() { unset($this->Paginator); } } - ?> \ No newline at end of file