From 315a26f68248cba7eeae6c0cb3e9d72f570a372f Mon Sep 17 00:00:00 2001 From: Vladimir Kolesnikov Date: Sun, 8 Dec 2013 07:20:21 +0200 Subject: [PATCH 1/2] Fix #1654 --- ext/paginator/adapter/model.c | 59 +++++++++++++++-------------------- 1 file changed, 26 insertions(+), 33 deletions(-) diff --git a/ext/paginator/adapter/model.c b/ext/paginator/adapter/model.c index 1852ac510e5..0ebe9c5c63e 100644 --- a/ext/paginator/adapter/model.c +++ b/ext/paginator/adapter/model.c @@ -105,7 +105,7 @@ PHP_METHOD(Phalcon_Paginator_Adapter_Model, setCurrentPage){ PHP_METHOD(Phalcon_Paginator_Adapter_Model, getPaginate){ zval *z_one, *z_zero, *show, *config, *items, *page_number = NULL; - zval *n, *page, *last_show_page, *start, *last_page; + zval *rowcount, *page, *last_show_page, *start, *last_page; zval *possible_pages = NULL, *total_pages, *page_items; zval *valid = NULL, *current = NULL, *maximum_pages, *next = NULL, *additional_page; zval *before = NULL, *remainder, *pages_total = NULL; @@ -118,24 +118,21 @@ PHP_METHOD(Phalcon_Paginator_Adapter_Model, getPaginate){ show = phalcon_fetch_nproperty_this(this_ptr, SL("_limitRows"), PH_NOISY_CC); config = phalcon_fetch_nproperty_this(this_ptr, SL("_config"), PH_NOISY_CC); - page_number = phalcon_fetch_nproperty_this(this_ptr, SL("_page"), PH_NOISY_CC); + PHALCON_OBS_VAR(page_number); + phalcon_read_property_this(&page_number, this_ptr, SL("_page"), PH_NOISY_CC); + i_show = (Z_TYPE_P(show) == IS_LONG) ? Z_LVAL_P(show) : phalcon_get_intval(show); PHALCON_OBS_VAR(items); phalcon_array_fetch_string(&items, config, SL("data"), PH_NOISY); - if (Z_TYPE_P(page_number) == IS_NULL) { + if (Z_TYPE_P(page_number) == IS_NULL || PHALCON_LT(show, z_zero)) { PHALCON_CPY_WRT_CTOR(page_number, z_one); } - if (PHALCON_LT(show, z_zero)) { - PHALCON_THROW_EXCEPTION_STR(phalcon_paginator_exception_ce, "The start page number is zero or less"); - return; - } - - PHALCON_INIT_VAR(n); - phalcon_fast_count(n, items TSRMLS_CC); + PHALCON_INIT_VAR(rowcount); + phalcon_fast_count(rowcount, items TSRMLS_CC); PHALCON_INIT_VAR(page); object_init(page); @@ -147,7 +144,7 @@ PHP_METHOD(Phalcon_Paginator_Adapter_Model, getPaginate){ mul_function(start, show, last_show_page TSRMLS_CC); PHALCON_INIT_VAR(last_page); - sub_function(last_page, n, z_one TSRMLS_CC); + sub_function(last_page, rowcount, z_one TSRMLS_CC); PHALCON_INIT_VAR(possible_pages); div_function(possible_pages, last_page, show TSRMLS_CC); @@ -162,22 +159,20 @@ PHP_METHOD(Phalcon_Paginator_Adapter_Model, getPaginate){ return; } - if (!zend_is_true(page_number)) { - PHALCON_CPY_WRT_CTOR(page_number, z_one); - } - PHALCON_INIT_VAR(page_items); array_init(page_items); - if (PHALCON_GT(n, z_zero)) { + if (PHALCON_GT(rowcount, z_zero)) { /** * Seek to the desired position */ - if (PHALCON_LE(start, n)) { + if (PHALCON_LT(start, rowcount)) { phalcon_call_method_p1_noret(items, "seek", start); } else { - phalcon_call_method_p1_noret(items, "seek", z_one); + phalcon_call_method_noret(items, "rewind"); PHALCON_CPY_WRT_CTOR(page_number, z_one); + PHALCON_CPY_WRT_CTOR(last_page, z_zero); + PHALCON_CPY_WRT_CTOR(start, z_zero); } /** @@ -205,21 +200,19 @@ PHP_METHOD(Phalcon_Paginator_Adapter_Model, getPaginate){ PHALCON_INIT_VAR(maximum_pages); phalcon_add_function(maximum_pages, start, show TSRMLS_CC); - if (PHALCON_LT(maximum_pages, n)) { + if (PHALCON_LT(maximum_pages, rowcount)) { PHALCON_INIT_VAR(next); phalcon_add_function(next, page_number, z_one TSRMLS_CC); + } else if (PHALCON_IS_EQUAL(maximum_pages, rowcount)) { + PHALCON_CPY_WRT(next, rowcount); } else { - if (PHALCON_IS_EQUAL(maximum_pages, n)) { - PHALCON_CPY_WRT(next, n); - } else { - div_function(possible_pages, n, show TSRMLS_CC); - - PHALCON_INIT_VAR(additional_page); - phalcon_add_function(additional_page, possible_pages, z_one TSRMLS_CC); - - PHALCON_INIT_NVAR(next); - ZVAL_LONG(next, phalcon_get_intval(additional_page)); - } + div_function(possible_pages, rowcount, show TSRMLS_CC); + + PHALCON_INIT_VAR(additional_page); + phalcon_add_function(additional_page, possible_pages, z_one TSRMLS_CC); + + PHALCON_INIT_NVAR(next); + ZVAL_LONG(next, phalcon_get_intval(additional_page)); } if (PHALCON_GT(next, total_pages)) { @@ -239,10 +232,10 @@ PHP_METHOD(Phalcon_Paginator_Adapter_Model, getPaginate){ phalcon_update_property_zval(page, SL("current"), page_number TSRMLS_CC); PHALCON_INIT_VAR(remainder); - mod_function(remainder, n, show TSRMLS_CC); + mod_function(remainder, rowcount, show TSRMLS_CC); PHALCON_INIT_NVAR(possible_pages); - div_function(possible_pages, n, show TSRMLS_CC); + div_function(possible_pages, rowcount, show TSRMLS_CC); if (!PHALCON_IS_LONG(remainder, 0)) { PHALCON_INIT_NVAR(next); phalcon_add_function(next, possible_pages, z_one TSRMLS_CC); @@ -255,7 +248,7 @@ PHP_METHOD(Phalcon_Paginator_Adapter_Model, getPaginate){ phalcon_update_property_zval(page, SL("last"), pages_total TSRMLS_CC); phalcon_update_property_zval(page, SL("total_pages"), pages_total TSRMLS_CC); - phalcon_update_property_zval(page, SL("total_items"), n TSRMLS_CC); + phalcon_update_property_zval(page, SL("total_items"), rowcount TSRMLS_CC); RETURN_CTOR(page); } From 84374c06f0623770a5a4b9941d55fe24dc9a4e88 Mon Sep 17 00:00:00 2001 From: Vladimir Kolesnikov Date: Sun, 8 Dec 2013 07:24:34 +0200 Subject: [PATCH 2/2] Test case for #1654 --- ext/tests/issue-1654.phpt | 136 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 ext/tests/issue-1654.phpt diff --git a/ext/tests/issue-1654.phpt b/ext/tests/issue-1654.phpt new file mode 100644 index 00000000000..4a07ec48f75 --- /dev/null +++ b/ext/tests/issue-1654.phpt @@ -0,0 +1,136 @@ +--TEST-- +Incorrect results from Phalcon\Paginator\Adapter\Model - https://github.com/phalcon/cphalcon/issues/1654 +--SKIPIF-- + +--FILE-- +items = $page->items[0]; // Because Resultsets are weird and advance the current position in valid() not in next() + print_r($page); +} + +class Test implements SeekableIterator, Countable +{ + private $data = array( + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + ); + + private $pos = 0; + + public function seek($pos) + { + $this->pos = $pos; + } + + public function rewind() + { + $this->pos = 0; + } + + public function current() + { + return $this->data[$this->pos]; + } + + public function key() + { + return $this->pos; + } + + public function next() + { + ++$this->pos; + } + + public function valid() + { + return isset($this->data[$this->pos]); + } + + public function count() + { + return count($this->data); + } +} + +$config = array( + 'limit' => 5, + 'page' => 1, + 'data' => new Test(), +); + +$pager = new \Phalcon\Paginator\Adapter\Model($config); +for ($page=1; $page<=6; ++$page) { + dump_page($pager->setCurrentPage($page)->getPaginate()); +} +?> +--EXPECT-- +stdClass Object +( + [items] => 0 + [next] => 2 + [first] => 1 + [before] => 1 + [current] => 1 + [last] => 4 + [total_pages] => 4 + [total_items] => 20 +) +stdClass Object +( + [items] => 5 + [next] => 3 + [first] => 1 + [before] => 1 + [current] => 2 + [last] => 4 + [total_pages] => 4 + [total_items] => 20 +) +stdClass Object +( + [items] => 10 + [next] => 4 + [first] => 1 + [before] => 2 + [current] => 3 + [last] => 4 + [total_pages] => 4 + [total_items] => 20 +) +stdClass Object +( + [items] => 15 + [next] => 4 + [first] => 1 + [before] => 3 + [current] => 4 + [last] => 4 + [total_pages] => 4 + [total_items] => 20 +) +stdClass Object +( + [items] => 0 + [next] => 2 + [first] => 1 + [before] => 1 + [current] => 1 + [last] => 4 + [total_pages] => 4 + [total_items] => 20 +) +stdClass Object +( + [items] => 0 + [next] => 2 + [first] => 1 + [before] => 1 + [current] => 1 + [last] => 4 + [total_pages] => 4 + [total_items] => 20 +)